Lines Matching +full:trickle +full:- +full:charge +full:- +full:current +full:- +full:microamp
1 // SPDX-License-Identifier: GPL-2.0-only
23 #include <dt-bindings/power/summit,smb347-charger.h>
26 #define SMB3XX_SOFT_TEMP_COMPENSATE_DEFAULT -1
29 #define SMB3XX_TEMP_USE_DEFAULT -273
34 * reloaded from non-volatile registers after POR.
131 * struct smb347_charger - smb347 charger instance
140 * @max_charge_current: maximum current (in uA) the battery can be charged
142 * @pre_charge_current: current (in uA) to use in pre-charging phase
143 * @termination_current: current (in uA) used to determine when the
146 * pre-charge to fast charge mode
147 * @mains_current_limit: maximum input current drawn from AC/DC input (in uA)
148 * @usb_hc_current_limit: maximum input high current (in uA) drawn from USB
150 * @chip_temp_threshold: die temperature where device starts limiting charge
151 * current [%100 - %130] (in degree C)
152 * @soft_cold_temp_limit: soft cold temperature limit [%0 - %15] (in degree C),
154 * @soft_hot_temp_limit: soft hot temperature limit [%40 - %55] (in degree C),
156 * @hard_cold_temp_limit: hard cold temperature limit [%-5 - %10] (in degree C),
158 * @hard_hot_temp_limit: hard hot temperature limit [%50 - %65] (in degree C),
163 * @charge_current_compensation: current (in uA) for charging compensation
164 * current when temperature hits soft limits
183 * If zero value is given in any of the current and voltage values, the
225 /* Fast charge current in uA */
234 /* Pre-charge current in uA */
241 /* Termination current in uA */
251 /* Input current limit in uA */
261 /* Charge current compensation in uA */
268 /* Convert register value to current using lookup table */
272 return -EINVAL; in hw_to_current()
276 /* Convert current to register value using lookup table */
284 return i > 0 ? i - 1 : -EINVAL; in current_to_hw()
288 * smb347_update_ps_status - refreshes the power source status
302 ret = regmap_read(smb->regmap, IRQSTAT_E, &val); in smb347_update_ps_status()
310 if (smb->use_mains) in smb347_update_ps_status()
312 if (smb->use_usb) in smb347_update_ps_status()
315 ret = smb->mains_online != dc || smb->usb_online != usb; in smb347_update_ps_status()
316 smb->mains_online = dc; in smb347_update_ps_status()
317 smb->usb_online = usb; in smb347_update_ps_status()
323 * smb347_is_ps_online - returns whether input power source is connected
333 return smb->usb_online || smb->mains_online; in smb347_is_ps_online()
337 * smb347_charging_status - returns status of charging
341 * %1 means pre-charging, %2 fast-charging and %3 taper-charging.
351 ret = regmap_read(smb->regmap, STAT_C, &val); in smb347_charging_status()
362 if (smb->enable_control != SMB3XX_CHG_ENABLE_SW) { in smb347_charging_set()
363 dev_dbg(smb->dev, "charging enable/disable in SW disabled\n"); in smb347_charging_set()
367 if (smb->charging_enabled != enable) { in smb347_charging_set()
368 ret = regmap_update_bits(smb->regmap, CMD_A, CMD_A_CHG_ENABLED, in smb347_charging_set()
371 smb->charging_enabled = enable; in smb347_charging_set()
399 dev_err(smb->dev, "failed to enable charging\n"); in smb347_start_stop_charging()
403 dev_err(smb->dev, "failed to disable charging\n"); in smb347_start_stop_charging()
411 unsigned int id = smb->id; in smb347_set_charge_current()
414 if (smb->max_charge_current) { in smb347_set_charge_current()
416 smb->max_charge_current); in smb347_set_charge_current()
420 ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT, in smb347_set_charge_current()
427 if (smb->pre_charge_current) { in smb347_set_charge_current()
429 smb->pre_charge_current); in smb347_set_charge_current()
433 ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT, in smb347_set_charge_current()
440 if (smb->termination_current) { in smb347_set_charge_current()
442 smb->termination_current); in smb347_set_charge_current()
446 ret = regmap_update_bits(smb->regmap, CFG_CHARGE_CURRENT, in smb347_set_charge_current()
457 unsigned int id = smb->id; in smb347_set_current_limits()
460 if (smb->mains_current_limit) { in smb347_set_current_limits()
462 smb->mains_current_limit); in smb347_set_current_limits()
466 ret = regmap_update_bits(smb->regmap, CFG_CURRENT_LIMIT, in smb347_set_current_limits()
473 if (smb->usb_hc_current_limit) { in smb347_set_current_limits()
475 smb->usb_hc_current_limit); in smb347_set_current_limits()
479 ret = regmap_update_bits(smb->regmap, CFG_CURRENT_LIMIT, in smb347_set_current_limits()
492 if (smb->pre_to_fast_voltage) { in smb347_set_voltage_limits()
493 ret = smb->pre_to_fast_voltage; in smb347_set_voltage_limits()
496 ret = clamp_val(ret, 2400000, 3000000) - 2400000; in smb347_set_voltage_limits()
499 ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE, in smb347_set_voltage_limits()
506 if (smb->max_charge_voltage) { in smb347_set_voltage_limits()
507 ret = smb->max_charge_voltage; in smb347_set_voltage_limits()
510 ret = clamp_val(ret, 3500000, 4500000) - 3500000; in smb347_set_voltage_limits()
513 ret = regmap_update_bits(smb->regmap, CFG_FLOAT_VOLTAGE, in smb347_set_voltage_limits()
524 unsigned int id = smb->id; in smb347_set_temp_limits()
529 if (smb->chip_temp_threshold) { in smb347_set_temp_limits()
530 val = smb->chip_temp_threshold; in smb347_set_temp_limits()
533 val = clamp_val(val, 100, 130) - 100; in smb347_set_temp_limits()
536 ret = regmap_update_bits(smb->regmap, CFG_OTG, in smb347_set_temp_limits()
543 if (smb->soft_cold_temp_limit != SMB3XX_TEMP_USE_DEFAULT) { in smb347_set_temp_limits()
544 val = smb->soft_cold_temp_limit; in smb347_set_temp_limits()
551 ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, in smb347_set_temp_limits()
560 if (smb->soft_hot_temp_limit != SMB3XX_TEMP_USE_DEFAULT) { in smb347_set_temp_limits()
561 val = smb->soft_hot_temp_limit; in smb347_set_temp_limits()
563 val = clamp_val(val, 40, 55) - 40; in smb347_set_temp_limits()
566 ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, in smb347_set_temp_limits()
575 if (smb->hard_cold_temp_limit != SMB3XX_TEMP_USE_DEFAULT) { in smb347_set_temp_limits()
576 val = smb->hard_cold_temp_limit; in smb347_set_temp_limits()
578 val = clamp_val(val, -5, 10) + 5; in smb347_set_temp_limits()
583 ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, in smb347_set_temp_limits()
592 if (smb->hard_hot_temp_limit != SMB3XX_TEMP_USE_DEFAULT) { in smb347_set_temp_limits()
593 val = smb->hard_hot_temp_limit; in smb347_set_temp_limits()
595 val = clamp_val(val, 50, 65) - 50; in smb347_set_temp_limits()
598 ret = regmap_update_bits(smb->regmap, CFG_TEMP_LIMIT, in smb347_set_temp_limits()
612 * current and/or voltage depending on the configuration. in smb347_set_temp_limits()
618 ret = regmap_update_bits(smb->regmap, CFG_THERM, in smb347_set_temp_limits()
624 if (smb->suspend_on_hard_temp_limit) { in smb347_set_temp_limits()
625 ret = regmap_update_bits(smb->regmap, CFG_SYSOK, in smb347_set_temp_limits()
631 if (smb->soft_temp_limit_compensation != in smb347_set_temp_limits()
633 val = smb->soft_temp_limit_compensation & 0x3; in smb347_set_temp_limits()
635 ret = regmap_update_bits(smb->regmap, CFG_THERM, in smb347_set_temp_limits()
641 ret = regmap_update_bits(smb->regmap, CFG_THERM, in smb347_set_temp_limits()
648 if (smb->charge_current_compensation) { in smb347_set_temp_limits()
650 smb->charge_current_compensation); in smb347_set_temp_limits()
654 ret = regmap_update_bits(smb->regmap, CFG_OTG, in smb347_set_temp_limits()
665 * smb347_set_writable - enables/disables writing to non-volatile registers
668 * You can enable/disable writing to the non-volatile configuration
675 return regmap_update_bits(smb->regmap, CMD_A, CMD_A_ALLOW_WRITE, in smb347_set_writable()
709 if (!smb->use_usb) { in smb347_hw_init()
710 ret = regmap_update_bits(smb->regmap, CMD_A, in smb347_hw_init()
718 * If configured by platform data, we enable hardware Auto-OTG in smb347_hw_init()
721 ret = regmap_update_bits(smb->regmap, CFG_OTHER, CFG_OTHER_RID_MASK, in smb347_hw_init()
722 smb->use_usb_otg ? CFG_OTHER_RID_ENABLED_AUTO_OTG : 0); in smb347_hw_init()
731 switch (smb->enable_control) { in smb347_hw_init()
743 ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_CTRL_MASK, in smb347_hw_init()
749 ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_APSD_IRQ, 0); in smb347_hw_init()
774 ret = regmap_read(smb->regmap, STAT_C, &stat_c); in smb347_interrupt()
776 dev_warn(smb->dev, "reading STAT_C failed\n"); in smb347_interrupt()
780 ret = regmap_read(smb->regmap, IRQSTAT_C, &irqstat_c); in smb347_interrupt()
782 dev_warn(smb->dev, "reading IRQSTAT_C failed\n"); in smb347_interrupt()
786 ret = regmap_read(smb->regmap, IRQSTAT_D, &irqstat_d); in smb347_interrupt()
788 dev_warn(smb->dev, "reading IRQSTAT_D failed\n"); in smb347_interrupt()
792 ret = regmap_read(smb->regmap, IRQSTAT_E, &irqstat_e); in smb347_interrupt()
794 dev_warn(smb->dev, "reading IRQSTAT_E failed\n"); in smb347_interrupt()
803 dev_err(smb->dev, "charging stopped due to charger error\n"); in smb347_interrupt()
804 if (smb->use_mains) in smb347_interrupt()
805 power_supply_changed(smb->mains); in smb347_interrupt()
806 if (smb->use_usb) in smb347_interrupt()
807 power_supply_changed(smb->usb); in smb347_interrupt()
812 * If we reached the termination current the battery is charged and in smb347_interrupt()
818 if (smb->use_mains) in smb347_interrupt()
819 power_supply_changed(smb->mains); in smb347_interrupt()
820 if (smb->use_usb) in smb347_interrupt()
821 power_supply_changed(smb->usb); in smb347_interrupt()
823 dev_dbg(smb->dev, "going to HW maintenance mode\n"); in smb347_interrupt()
828 * If we got a charger timeout INT that means the charge in smb347_interrupt()
829 * full is not detected with in charge timeout value. in smb347_interrupt()
832 dev_dbg(smb->dev, "total Charge Timeout INT received\n"); in smb347_interrupt()
835 dev_warn(smb->dev, "charging stopped due to timeout\n"); in smb347_interrupt()
836 if (smb->use_mains) in smb347_interrupt()
837 power_supply_changed(smb->mains); in smb347_interrupt()
838 if (smb->use_usb) in smb347_interrupt()
839 power_supply_changed(smb->usb); in smb347_interrupt()
850 if (smb->use_mains) in smb347_interrupt()
851 power_supply_changed(smb->mains); in smb347_interrupt()
852 if (smb->use_usb) in smb347_interrupt()
853 power_supply_changed(smb->usb); in smb347_interrupt()
871 * - under voltage in smb347_irq_set()
872 * - termination current reached in smb347_irq_set()
873 * - charger timeout in smb347_irq_set()
874 * - charger error in smb347_irq_set()
876 ret = regmap_update_bits(smb->regmap, CFG_FAULT_IRQ, 0xff, in smb347_irq_set()
881 ret = regmap_update_bits(smb->regmap, CFG_STATUS_IRQ, 0xff, in smb347_irq_set()
887 ret = regmap_update_bits(smb->regmap, CFG_PIN, CFG_PIN_EN_CHARGER_ERROR, in smb347_irq_set()
909 ret = devm_request_threaded_irq(smb->dev, client->irq, NULL, in smb347_irq_init()
911 client->name, smb); in smb347_irq_init()
923 ret = regmap_update_bits(smb->regmap, CFG_STAT, in smb347_irq_init()
927 client->irq = 0; in smb347_irq_init()
935 * Returns the constant charge current programmed
940 unsigned int id = smb->id; in get_const_charge_current()
945 return -ENODATA; in get_const_charge_current()
947 ret = regmap_read(smb->regmap, STAT_B, &v); in get_const_charge_current()
952 * The current value is composition of FCC and PCC values in get_const_charge_current()
968 * Returns the constant charge voltage programmed
977 return -ENODATA; in get_const_charge_voltage()
979 ret = regmap_read(smb->regmap, STAT_A, &v); in get_const_charge_voltage()
998 if (psy->desc->type == POWER_SUPPLY_TYPE_USB) { in smb347_get_charging_status()
999 if (!smb->usb_online) in smb347_get_charging_status()
1002 if (!smb->mains_online) in smb347_get_charging_status()
1006 ret = regmap_read(smb->regmap, STAT_C, &val); in smb347_get_charging_status()
1020 * set to charging if battery is in pre-charge, in smb347_get_charging_status()
1021 * fast charge or taper charging mode. in smb347_get_charging_status()
1027 * charge, fast charge or taper charging mode AND in smb347_get_charging_status()
1055 val->intval = ret; in smb347_get_property_locked()
1059 if (psy->desc->type == POWER_SUPPLY_TYPE_USB) { in smb347_get_property_locked()
1060 if (!smb->usb_online) in smb347_get_property_locked()
1061 return -ENODATA; in smb347_get_property_locked()
1063 if (!smb->mains_online) in smb347_get_property_locked()
1064 return -ENODATA; in smb347_get_property_locked()
1068 * We handle trickle and pre-charging the same, and taper in smb347_get_property_locked()
1073 val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; in smb347_get_property_locked()
1076 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; in smb347_get_property_locked()
1079 val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; in smb347_get_property_locked()
1085 if (psy->desc->type == POWER_SUPPLY_TYPE_USB) in smb347_get_property_locked()
1086 val->intval = smb->usb_online; in smb347_get_property_locked()
1088 val->intval = smb->mains_online; in smb347_get_property_locked()
1095 val->intval = ret; in smb347_get_property_locked()
1102 val->intval = ret; in smb347_get_property_locked()
1106 return -EINVAL; in smb347_get_property_locked()
1117 struct i2c_client *client = to_i2c_client(smb->dev); in smb347_get_property()
1120 disable_irq(client->irq); in smb347_get_property()
1122 enable_irq(client->irq); in smb347_get_property()
1180 struct device *dev = smb->dev; in smb347_dt_parse_dev_info()
1182 smb->soft_temp_limit_compensation = in smb347_dt_parse_dev_info()
1186 * pre-initialize the values. See smb347_get_battery_info() below. in smb347_dt_parse_dev_info()
1188 smb->soft_cold_temp_limit = SMB3XX_TEMP_USE_DEFAULT; in smb347_dt_parse_dev_info()
1189 smb->hard_cold_temp_limit = SMB3XX_TEMP_USE_DEFAULT; in smb347_dt_parse_dev_info()
1190 smb->soft_hot_temp_limit = SMB3XX_TEMP_USE_DEFAULT; in smb347_dt_parse_dev_info()
1191 smb->hard_hot_temp_limit = SMB3XX_TEMP_USE_DEFAULT; in smb347_dt_parse_dev_info()
1194 device_property_read_u32(dev, "summit,fast-voltage-threshold-microvolt", in smb347_dt_parse_dev_info()
1195 &smb->pre_to_fast_voltage); in smb347_dt_parse_dev_info()
1196 device_property_read_u32(dev, "summit,mains-current-limit-microamp", in smb347_dt_parse_dev_info()
1197 &smb->mains_current_limit); in smb347_dt_parse_dev_info()
1198 device_property_read_u32(dev, "summit,usb-current-limit-microamp", in smb347_dt_parse_dev_info()
1199 &smb->usb_hc_current_limit); in smb347_dt_parse_dev_info()
1202 device_property_read_u32(dev, "summit,chip-temperature-threshold-celsius", in smb347_dt_parse_dev_info()
1203 &smb->chip_temp_threshold); in smb347_dt_parse_dev_info()
1204 device_property_read_u32(dev, "summit,soft-compensation-method", in smb347_dt_parse_dev_info()
1205 &smb->soft_temp_limit_compensation); in smb347_dt_parse_dev_info()
1206 device_property_read_u32(dev, "summit,charge-current-compensation-microamp", in smb347_dt_parse_dev_info()
1207 &smb->charge_current_compensation); in smb347_dt_parse_dev_info()
1210 smb->use_mains = device_property_read_bool(dev, "summit,enable-mains-charging"); in smb347_dt_parse_dev_info()
1211 smb->use_usb = device_property_read_bool(dev, "summit,enable-usb-charging"); in smb347_dt_parse_dev_info()
1212 smb->use_usb_otg = device_property_read_bool(dev, "summit,enable-otg-charging"); in smb347_dt_parse_dev_info()
1215 device_property_read_u32(dev, "summit,enable-charge-control", in smb347_dt_parse_dev_info()
1216 &smb->enable_control); in smb347_dt_parse_dev_info()
1225 if (smb->mains) in smb347_get_battery_info()
1226 supply = smb->mains; in smb347_get_battery_info()
1228 supply = smb->usb; in smb347_get_battery_info()
1231 if (err == -ENXIO || err == -ENODEV) in smb347_get_battery_info()
1236 if (info.constant_charge_current_max_ua != -EINVAL) in smb347_get_battery_info()
1237 smb->max_charge_current = info.constant_charge_current_max_ua; in smb347_get_battery_info()
1239 if (info.constant_charge_voltage_max_uv != -EINVAL) in smb347_get_battery_info()
1240 smb->max_charge_voltage = info.constant_charge_voltage_max_uv; in smb347_get_battery_info()
1242 if (info.precharge_current_ua != -EINVAL) in smb347_get_battery_info()
1243 smb->pre_charge_current = info.precharge_current_ua; in smb347_get_battery_info()
1245 if (info.charge_term_current_ua != -EINVAL) in smb347_get_battery_info()
1246 smb->termination_current = info.charge_term_current_ua; in smb347_get_battery_info()
1249 smb->soft_cold_temp_limit = info.temp_alert_min; in smb347_get_battery_info()
1252 smb->soft_hot_temp_limit = info.temp_alert_max; in smb347_get_battery_info()
1255 smb->hard_cold_temp_limit = info.temp_min; in smb347_get_battery_info()
1258 smb->hard_hot_temp_limit = info.temp_max; in smb347_get_battery_info()
1261 if (smb->hard_cold_temp_limit != SMB3XX_TEMP_USE_DEFAULT || in smb347_get_battery_info()
1262 smb->hard_hot_temp_limit != SMB3XX_TEMP_USE_DEFAULT) in smb347_get_battery_info()
1263 smb->suspend_on_hard_temp_limit = true; in smb347_get_battery_info()
1277 .name = "smb347-mains",
1285 .name = "smb347-usb",
1296 struct device *dev = &client->dev; in smb347_probe()
1302 return -ENOMEM; in smb347_probe()
1303 smb->dev = &client->dev; in smb347_probe()
1304 smb->id = id->driver_data; in smb347_probe()
1308 if (!smb->use_mains && !smb->use_usb) in smb347_probe()
1309 return -EINVAL; in smb347_probe()
1311 smb->regmap = devm_regmap_init_i2c(client, &smb347_regmap); in smb347_probe()
1312 if (IS_ERR(smb->regmap)) in smb347_probe()
1313 return PTR_ERR(smb->regmap); in smb347_probe()
1316 mains_usb_cfg.of_node = dev->of_node; in smb347_probe()
1317 if (smb->use_mains) { in smb347_probe()
1318 smb->mains = devm_power_supply_register(dev, &smb347_mains_desc, in smb347_probe()
1320 if (IS_ERR(smb->mains)) in smb347_probe()
1321 return PTR_ERR(smb->mains); in smb347_probe()
1324 if (smb->use_usb) { in smb347_probe()
1325 smb->usb = devm_power_supply_register(dev, &smb347_usb_desc, in smb347_probe()
1327 if (IS_ERR(smb->usb)) in smb347_probe()
1328 return PTR_ERR(smb->usb); in smb347_probe()
1343 if (client->irq) { in smb347_probe()
1360 if (client->irq) in smb347_remove()