Lines Matching +full:charge +full:- +full:current +full:- +full:limit +full:- +full:mapping

1 // SPDX-License-Identifier: GPL-2.0-only
21 #include <linux/extcon-provider.h>
34 #define BQ24190_REG_POC 0x01 /* Power-On Configuration */
51 #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
58 #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
70 #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
79 #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
153 * reads return the current value. In order to return the fault status
182 * The tables below provide a 2-way mapping for the value that goes in
183 * the register field and the real-world value that it represents.
185 * number at that index in the array is the real-world value that it
225 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
237 return i - 1; in bq24190_find_idx()
246 ret = i2c_smbus_read_byte_data(bdi->client, reg); in bq24190_read()
256 return i2c_smbus_write_byte_data(bdi->client, reg, data); in bq24190_write()
304 v = (v >= tbl_size) ? (tbl_size - 1) : v; in bq24190_get_field_val()
358 /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
413 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl); in bq24190_sysfs_init_attrs() local
415 for (i = 0; i < limit; i++) in bq24190_sysfs_init_attrs()
418 bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */ in bq24190_sysfs_init_attrs()
424 int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl); in bq24190_sysfs_field_lookup() local
426 for (i = 0; i < limit; i++) in bq24190_sysfs_field_lookup()
430 if (i >= limit) in bq24190_sysfs_field_lookup()
446 info = bq24190_sysfs_field_lookup(attr->attr.name); in bq24190_sysfs_show()
448 return -EINVAL; in bq24190_sysfs_show()
450 ret = pm_runtime_get_sync(bdi->dev); in bq24190_sysfs_show()
454 ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v); in bq24190_sysfs_show()
460 pm_runtime_mark_last_busy(bdi->dev); in bq24190_sysfs_show()
461 pm_runtime_put_autosuspend(bdi->dev); in bq24190_sysfs_show()
475 info = bq24190_sysfs_field_lookup(attr->attr.name); in bq24190_sysfs_store()
477 return -EINVAL; in bq24190_sysfs_store()
483 ret = pm_runtime_get_sync(bdi->dev); in bq24190_sysfs_store()
485 pm_runtime_put_noidle(bdi->dev); in bq24190_sysfs_store()
489 ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v); in bq24190_sysfs_store()
493 pm_runtime_mark_last_busy(bdi->dev); in bq24190_sysfs_store()
494 pm_runtime_put_autosuspend(bdi->dev); in bq24190_sysfs_store()
506 ret = pm_runtime_get_sync(bdi->dev); in bq24190_set_charge_mode()
508 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); in bq24190_set_charge_mode()
509 pm_runtime_put_noidle(bdi->dev); in bq24190_set_charge_mode()
517 pm_runtime_mark_last_busy(bdi->dev); in bq24190_set_charge_mode()
518 pm_runtime_put_autosuspend(bdi->dev); in bq24190_set_charge_mode()
539 ret = pm_runtime_get_sync(bdi->dev); in bq24190_vbus_is_enabled()
541 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret); in bq24190_vbus_is_enabled()
542 pm_runtime_put_noidle(bdi->dev); in bq24190_vbus_is_enabled()
550 pm_runtime_mark_last_busy(bdi->dev); in bq24190_vbus_is_enabled()
551 pm_runtime_put_autosuspend(bdi->dev); in bq24190_vbus_is_enabled()
564 .of_match = "usb-otg-vbus",
580 struct bq24190_platform_data *pdata = bdi->dev->platform_data; in bq24190_register_vbus_regulator()
585 cfg.dev = bdi->dev; in bq24190_register_vbus_regulator()
586 if (pdata && pdata->regulator_init_data) in bq24190_register_vbus_regulator()
587 cfg.init_data = pdata->regulator_init_data; in bq24190_register_vbus_regulator()
591 reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg); in bq24190_register_vbus_regulator()
594 dev_err(bdi->dev, "Can't register regulator: %d\n", ret); in bq24190_register_vbus_regulator()
615 bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >> in bq24190_set_config()
632 if (bdi->sys_min) { in bq24190_set_config()
633 v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9 in bq24190_set_config()
642 if (bdi->iprechg) { in bq24190_set_config()
643 v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11 in bq24190_set_config()
652 if (bdi->iterm) { in bq24190_set_config()
653 v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11 in bq24190_set_config()
667 int ret, limit = 100; in bq24190_register_reset() local
673 * { PROPERTY_ENTRY_BOOL("disable-reset"), ... }; in bq24190_register_reset()
680 if (device_property_read_bool(bdi->dev, "disable-reset")) in bq24190_register_reset()
704 } while (--limit); in bq24190_register_reset()
706 return -EIO; in bq24190_register_reset()
724 /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */ in bq24190_charger_get_charge_type()
739 val->intval = type; in bq24190_charger_get_charge_type()
752 * the bq24190 manual, the trickle charge could be less than the in bq24190_charger_set_charge_type()
753 * termination current so it recommends turning off the termination in bq24190_charger_set_charge_type()
760 switch (val->intval) { in bq24190_charger_set_charge_type()
775 return -EINVAL; in bq24190_charger_set_charge_type()
805 mutex_lock(&bdi->f_reg_lock); in bq24190_charger_get_health()
806 v = bdi->f_reg; in bq24190_charger_get_health()
807 mutex_unlock(&bdi->f_reg_lock); in bq24190_charger_get_health()
830 * This could be over-voltage or under-voltage in bq24190_charger_get_health()
833 * when its really under-voltage, just return in bq24190_charger_get_health()
841 case 0x3: /* Charge Safety Timer Expiration */ in bq24190_charger_get_health()
845 health = -1; in bq24190_charger_get_health()
849 * This could be over-current or over-voltage but there's in bq24190_charger_get_health()
852 * even if it was over-current. in bq24190_charger_get_health()
859 val->intval = health; in bq24190_charger_get_health()
882 val->intval = pg_stat && !batfet_disable; in bq24190_charger_get_online()
932 val->intval = ++v * 128 * 1000; in bq24190_charger_get_precharge()
948 val->intval = ++v * 128 * 1000; in bq24190_charger_get_charge_term()
971 /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */ in bq24190_charger_get_current()
975 val->intval = curr; in bq24190_charger_get_current()
982 int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1; in bq24190_charger_get_current_max()
984 val->intval = bq24190_ccc_ichg_values[idx]; in bq24190_charger_get_current_max()
992 int ret, curr = val->intval; in bq24190_charger_set_current()
1022 val->intval = voltage; in bq24190_charger_get_voltage()
1029 int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1; in bq24190_charger_get_voltage_max()
1031 val->intval = bq24190_cvc_vreg_values[idx]; in bq24190_charger_get_voltage_max()
1041 ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval); in bq24190_charger_set_voltage()
1057 val->intval = iinlimit; in bq24190_charger_get_iinlimit()
1068 ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval); in bq24190_charger_set_iinlimit()
1077 dev_dbg(bdi->dev, "prop: %d\n", psp); in bq24190_charger_get_property()
1079 ret = pm_runtime_get_sync(bdi->dev); in bq24190_charger_get_property()
1121 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; in bq24190_charger_get_property()
1125 val->strval = bdi->model_name; in bq24190_charger_get_property()
1129 val->strval = BQ24190_MANUFACTURER; in bq24190_charger_get_property()
1133 ret = -ENODATA; in bq24190_charger_get_property()
1136 pm_runtime_mark_last_busy(bdi->dev); in bq24190_charger_get_property()
1137 pm_runtime_put_autosuspend(bdi->dev); in bq24190_charger_get_property()
1149 dev_dbg(bdi->dev, "prop: %d\n", psp); in bq24190_charger_set_property()
1151 ret = pm_runtime_get_sync(bdi->dev); in bq24190_charger_set_property()
1175 ret = -EINVAL; in bq24190_charger_set_property()
1178 pm_runtime_mark_last_busy(bdi->dev); in bq24190_charger_set_property()
1179 pm_runtime_put_autosuspend(bdi->dev); in bq24190_charger_set_property()
1206 power_supply_set_input_current_limit_from_supplier(bdi->charger); in bq24190_input_current_limit_work()
1209 /* Sync the input-current-limit with our parent supply (if we have one) */
1215 * The Power-Good detection may take up to 220ms, sometimes in bq24190_charger_external_power_changed()
1219 * too low default 500mA iinlim. Delay setting the input-current-limit in bq24190_charger_external_power_changed()
1222 queue_delayed_work(system_wq, &bdi->input_current_limit_work, in bq24190_charger_external_power_changed()
1245 "main-battery",
1249 .name = "bq24190-charger",
1267 mutex_lock(&bdi->f_reg_lock); in bq24190_battery_get_status()
1268 chrg_fault = bdi->f_reg; in bq24190_battery_get_status()
1269 mutex_unlock(&bdi->f_reg_lock); in bq24190_battery_get_status()
1280 * - there is no good power source; in bq24190_battery_get_status()
1281 * - there is a charge fault. in bq24190_battery_get_status()
1295 case 0x1: /* Pre-charge */ in bq24190_battery_get_status()
1299 case 0x3: /* Charge Termination Done */ in bq24190_battery_get_status()
1303 ret = -EIO; in bq24190_battery_get_status()
1308 val->intval = status; in bq24190_battery_get_status()
1319 mutex_lock(&bdi->f_reg_lock); in bq24190_battery_get_health()
1320 v = bdi->f_reg; in bq24190_battery_get_health()
1321 mutex_unlock(&bdi->f_reg_lock); in bq24190_battery_get_health()
1348 val->intval = health; in bq24190_battery_get_health()
1364 val->intval = !batfet_disable; in bq24190_battery_get_online()
1373 BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval); in bq24190_battery_set_online()
1389 val->intval = temp; in bq24190_battery_get_temp_alert_max()
1400 ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval); in bq24190_battery_set_temp_alert_max()
1409 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); in bq24190_battery_get_property()
1410 dev_dbg(bdi->dev, "prop: %d\n", psp); in bq24190_battery_get_property()
1412 ret = pm_runtime_get_sync(bdi->dev); in bq24190_battery_get_property()
1427 /* Could be Li-on or Li-polymer but no way to tell which */ in bq24190_battery_get_property()
1428 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; in bq24190_battery_get_property()
1435 val->intval = POWER_SUPPLY_SCOPE_SYSTEM; in bq24190_battery_get_property()
1439 ret = -ENODATA; in bq24190_battery_get_property()
1442 pm_runtime_mark_last_busy(bdi->dev); in bq24190_battery_get_property()
1443 pm_runtime_put_autosuspend(bdi->dev); in bq24190_battery_get_property()
1455 dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n"); in bq24190_battery_set_property()
1456 dev_dbg(bdi->dev, "prop: %d\n", psp); in bq24190_battery_set_property()
1458 ret = pm_runtime_get_sync(bdi->dev); in bq24190_battery_set_property()
1470 ret = -EINVAL; in bq24190_battery_set_property()
1473 pm_runtime_mark_last_busy(bdi->dev); in bq24190_battery_set_property()
1474 pm_runtime_put_autosuspend(bdi->dev); in bq24190_battery_set_property()
1506 .name = "bq24190-battery",
1521 ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled); in bq24190_configure_usb_otg()
1523 dev_err(bdi->dev, "Can't set extcon state to %d: %d\n", in bq24190_configure_usb_otg()
1540 dev_err(bdi->dev, "Can't read SS reg: %d\n", ret); in bq24190_check_status()
1548 dev_err(bdi->dev, "Can't read F reg: %d\n", ret); in bq24190_check_status()
1558 if (f_reg != bdi->f_reg) { in bq24190_check_status()
1559 dev_warn(bdi->dev, in bq24190_check_status()
1560 "Fault: boost %d, charge %d, battery %d, ntc %d\n", in bq24190_check_status()
1566 mutex_lock(&bdi->f_reg_lock); in bq24190_check_status()
1567 if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f)) in bq24190_check_status()
1569 if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f)) in bq24190_check_status()
1571 bdi->f_reg = f_reg; in bq24190_check_status()
1572 mutex_unlock(&bdi->f_reg_lock); in bq24190_check_status()
1575 if (ss_reg != bdi->ss_reg) { in bq24190_check_status()
1577 * The device is in host mode so when PG_STAT goes from 1->0 in bq24190_check_status()
1580 if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) && in bq24190_check_status()
1587 dev_err(bdi->dev, "Can't access ISC reg: %d\n", in bq24190_check_status()
1591 if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss)) in bq24190_check_status()
1593 if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss)) in bq24190_check_status()
1595 bdi->ss_reg = ss_reg; in bq24190_check_status()
1599 power_supply_changed(bdi->charger); in bq24190_check_status()
1602 if (alert_battery && bdi->battery) in bq24190_check_status()
1603 power_supply_changed(bdi->battery); in bq24190_check_status()
1605 dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg); in bq24190_check_status()
1613 bdi->irq_event = true; in bq24190_irq_handler_thread()
1614 error = pm_runtime_get_sync(bdi->dev); in bq24190_irq_handler_thread()
1616 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); in bq24190_irq_handler_thread()
1617 pm_runtime_put_noidle(bdi->dev); in bq24190_irq_handler_thread()
1621 pm_runtime_mark_last_busy(bdi->dev); in bq24190_irq_handler_thread()
1622 pm_runtime_put_autosuspend(bdi->dev); in bq24190_irq_handler_thread()
1623 bdi->irq_event = false; in bq24190_irq_handler_thread()
1647 dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v); in bq24190_hw_init()
1648 return -ENODEV; in bq24190_hw_init()
1659 return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); in bq24190_hw_init()
1664 const char * const s = "ti,system-minimum-microvolt"; in bq24190_get_config()
1668 if (device_property_read_u32(bdi->dev, s, &v) == 0) { in bq24190_get_config()
1672 bdi->sys_min = v; in bq24190_get_config()
1674 dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v); in bq24190_get_config()
1677 if (bdi->dev->of_node && in bq24190_get_config()
1678 !power_supply_get_battery_info(bdi->charger, &info)) { in bq24190_get_config()
1682 bdi->iprechg = v; in bq24190_get_config()
1684 dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n", in bq24190_get_config()
1690 bdi->iterm = v; in bq24190_get_config()
1692 dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n", in bq24190_get_config()
1702 struct i2c_adapter *adapter = client->adapter; in bq24190_probe()
1703 struct device *dev = &client->dev; in bq24190_probe()
1710 return -ENODEV; in bq24190_probe()
1716 return -ENOMEM; in bq24190_probe()
1719 bdi->client = client; in bq24190_probe()
1720 bdi->dev = dev; in bq24190_probe()
1721 strncpy(bdi->model_name, id->name, I2C_NAME_SIZE); in bq24190_probe()
1722 mutex_init(&bdi->f_reg_lock); in bq24190_probe()
1723 bdi->f_reg = 0; in bq24190_probe()
1724 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ in bq24190_probe()
1725 INIT_DELAYED_WORK(&bdi->input_current_limit_work, in bq24190_probe()
1730 if (client->irq <= 0) { in bq24190_probe()
1732 return -EINVAL; in bq24190_probe()
1735 bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable); in bq24190_probe()
1736 if (IS_ERR(bdi->edev)) in bq24190_probe()
1737 return PTR_ERR(bdi->edev); in bq24190_probe()
1739 ret = devm_extcon_dev_register(dev, bdi->edev); in bq24190_probe()
1758 charger_cfg.of_node = dev->of_node; in bq24190_probe()
1761 bdi->charger = power_supply_register(dev, &bq24190_charger_desc, in bq24190_probe()
1763 if (IS_ERR(bdi->charger)) { in bq24190_probe()
1765 ret = PTR_ERR(bdi->charger); in bq24190_probe()
1771 if (!device_property_read_bool(dev, "omit-battery-class")) { in bq24190_probe()
1773 bdi->battery = power_supply_register(dev, &bq24190_battery_desc, in bq24190_probe()
1775 if (IS_ERR(bdi->battery)) { in bq24190_probe()
1777 ret = PTR_ERR(bdi->battery); in bq24190_probe()
1794 ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg); in bq24190_probe()
1798 bdi->initialized = true; in bq24190_probe()
1800 ret = devm_request_threaded_irq(dev, client->irq, NULL, in bq24190_probe()
1803 "bq24190-charger", bdi); in bq24190_probe()
1813 enable_irq_wake(client->irq); in bq24190_probe()
1821 if (!IS_ERR_OR_NULL(bdi->battery)) in bq24190_probe()
1822 power_supply_unregister(bdi->battery); in bq24190_probe()
1823 power_supply_unregister(bdi->charger); in bq24190_probe()
1837 error = pm_runtime_get_sync(bdi->dev); in bq24190_remove()
1839 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); in bq24190_remove()
1840 pm_runtime_put_noidle(bdi->dev); in bq24190_remove()
1844 if (bdi->battery) in bq24190_remove()
1845 power_supply_unregister(bdi->battery); in bq24190_remove()
1846 power_supply_unregister(bdi->charger); in bq24190_remove()
1848 pm_runtime_put_sync(bdi->dev); in bq24190_remove()
1849 pm_runtime_dont_use_autosuspend(bdi->dev); in bq24190_remove()
1850 pm_runtime_disable(bdi->dev); in bq24190_remove()
1860 if (!bdi->initialized) in bq24190_runtime_suspend()
1863 dev_dbg(bdi->dev, "%s\n", __func__); in bq24190_runtime_suspend()
1873 if (!bdi->initialized) in bq24190_runtime_resume()
1876 if (!bdi->irq_event) { in bq24190_runtime_resume()
1877 dev_dbg(bdi->dev, "checking events on possible wakeirq\n"); in bq24190_runtime_resume()
1890 error = pm_runtime_get_sync(bdi->dev); in bq24190_pm_suspend()
1892 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); in bq24190_pm_suspend()
1893 pm_runtime_put_noidle(bdi->dev); in bq24190_pm_suspend()
1899 pm_runtime_mark_last_busy(bdi->dev); in bq24190_pm_suspend()
1900 pm_runtime_put_autosuspend(bdi->dev); in bq24190_pm_suspend()
1912 bdi->f_reg = 0; in bq24190_pm_resume()
1913 bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */ in bq24190_pm_resume()
1915 error = pm_runtime_get_sync(bdi->dev); in bq24190_pm_resume()
1917 dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error); in bq24190_pm_resume()
1918 pm_runtime_put_noidle(bdi->dev); in bq24190_pm_resume()
1923 bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg); in bq24190_pm_resume()
1926 pm_runtime_mark_last_busy(bdi->dev); in bq24190_pm_resume()
1927 pm_runtime_put_autosuspend(bdi->dev); in bq24190_pm_resume()
1931 power_supply_changed(bdi->charger); in bq24190_pm_resume()
1932 if (bdi->battery) in bq24190_pm_resume()
1933 power_supply_changed(bdi->battery); in bq24190_pm_resume()
1973 .name = "bq24190-charger",