Lines Matching +full:cm +full:- +full:poll +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-only
7 * during suspend-to-mem.
23 #include <linux/power/charger-manager.h>
35 { "USB-HOST", EXTCON_USB_HOST },
40 { "FAST-CHARGER", EXTCON_CHG_USB_FAST },
41 { "SLOW-CHARGER", EXTCON_CHG_USB_SLOW },
49 { "CHARGE-DOWNSTREAM", EXTCON_CHG_USB_CDP },
78 /* About in-suspend (suspend-again) monitoring */
92 * is_batt_present - See if the battery presents in place.
93 * @cm: the Charger Manager representing the battery.
95 static bool is_batt_present(struct charger_manager *cm) in is_batt_present() argument
102 switch (cm->desc->battery_present) { in is_batt_present()
109 psy = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in is_batt_present()
120 for (i = 0; cm->desc->psy_charger_stat[i]; i++) { in is_batt_present()
122 cm->desc->psy_charger_stat[i]); in is_batt_present()
124 dev_err(cm->dev, "Cannot find power supply \"%s\"\n", in is_batt_present()
125 cm->desc->psy_charger_stat[i]); in is_batt_present()
144 * is_ext_pwr_online - See if an external power source is attached to charge
145 * @cm: the Charger Manager representing the battery.
151 static bool is_ext_pwr_online(struct charger_manager *cm) in is_ext_pwr_online() argument
159 for (i = 0; cm->desc->psy_charger_stat[i]; i++) { in is_ext_pwr_online()
160 psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]); in is_ext_pwr_online()
162 dev_err(cm->dev, "Cannot find power supply \"%s\"\n", in is_ext_pwr_online()
163 cm->desc->psy_charger_stat[i]); in is_ext_pwr_online()
180 * get_batt_uV - Get the voltage level of the battery
181 * @cm: the Charger Manager representing the battery.
187 static int get_batt_uV(struct charger_manager *cm, int *uV) in get_batt_uV() argument
193 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in get_batt_uV()
195 return -ENODEV; in get_batt_uV()
208 * is_charging - Returns true if the battery is being charged.
209 * @cm: the Charger Manager representing the battery.
211 static bool is_charging(struct charger_manager *cm) in is_charging() argument
219 if (!is_batt_present(cm)) in is_charging()
223 for (i = 0; cm->desc->psy_charger_stat[i]; i++) { in is_charging()
225 if (cm->emergency_stop) in is_charging()
227 if (!cm->charger_enabled) in is_charging()
230 psy = power_supply_get_by_name(cm->desc->psy_charger_stat[i]); in is_charging()
232 dev_err(cm->dev, "Cannot find power supply \"%s\"\n", in is_charging()
233 cm->desc->psy_charger_stat[i]); in is_charging()
237 /* 2. The charger should be online (ext-power) */ in is_charging()
241 dev_warn(cm->dev, "Cannot read ONLINE value from %s\n", in is_charging()
242 cm->desc->psy_charger_stat[i]); in is_charging()
259 dev_warn(cm->dev, "Cannot read STATUS value from %s\n", in is_charging()
260 cm->desc->psy_charger_stat[i]); in is_charging()
277 * is_full_charged - Returns true if the battery is fully charged.
278 * @cm: the Charger Manager representing the battery.
280 static bool is_full_charged(struct charger_manager *cm) in is_full_charged() argument
282 struct charger_desc *desc = cm->desc; in is_full_charged()
290 if (!is_batt_present(cm)) in is_full_charged()
293 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in is_full_charged()
298 if (desc->fullbatt_uV > 0) { in is_full_charged()
299 ret = get_batt_uV(cm, &uV); in is_full_charged()
302 if (cm->battery_status == POWER_SUPPLY_STATUS_FULL in is_full_charged()
303 && desc->fullbatt_vchkdrop_uV) in is_full_charged()
304 uV += desc->fullbatt_vchkdrop_uV; in is_full_charged()
305 if (uV >= desc->fullbatt_uV) in is_full_charged()
310 if (desc->fullbatt_full_capacity > 0) { in is_full_charged()
316 if (!ret && val.intval > desc->fullbatt_full_capacity) { in is_full_charged()
323 if (desc->fullbatt_soc > 0) { in is_full_charged()
328 if (!ret && val.intval >= desc->fullbatt_soc) { in is_full_charged()
340 * is_polling_required - Return true if need to continue polling for this CM.
341 * @cm: the Charger Manager representing the battery.
343 static bool is_polling_required(struct charger_manager *cm) in is_polling_required() argument
345 switch (cm->desc->polling_mode) { in is_polling_required()
351 return is_ext_pwr_online(cm); in is_polling_required()
353 return is_charging(cm); in is_polling_required()
355 dev_warn(cm->dev, "Incorrect polling_mode (%d)\n", in is_polling_required()
356 cm->desc->polling_mode); in is_polling_required()
363 * try_charger_enable - Enable/Disable chargers altogether
364 * @cm: the Charger Manager representing the battery.
369 * power source exists) except when CM needs to disable chargers forcibly
372 static int try_charger_enable(struct charger_manager *cm, bool enable) in try_charger_enable() argument
375 struct charger_desc *desc = cm->desc; in try_charger_enable()
378 if (enable == cm->charger_enabled) in try_charger_enable()
382 if (cm->emergency_stop) in try_charger_enable()
383 return -EAGAIN; in try_charger_enable()
389 cm->charging_start_time = ktime_to_ms(ktime_get()); in try_charger_enable()
390 cm->charging_end_time = 0; in try_charger_enable()
392 for (i = 0 ; i < desc->num_charger_regulators ; i++) { in try_charger_enable()
393 if (desc->charger_regulators[i].externally_control) in try_charger_enable()
396 err = regulator_enable(desc->charger_regulators[i].consumer); in try_charger_enable()
398 dev_warn(cm->dev, "Cannot enable %s regulator\n", in try_charger_enable()
399 desc->charger_regulators[i].regulator_name); in try_charger_enable()
405 * of battery after full-batt. in try_charger_enable()
407 cm->charging_start_time = 0; in try_charger_enable()
408 cm->charging_end_time = ktime_to_ms(ktime_get()); in try_charger_enable()
410 for (i = 0 ; i < desc->num_charger_regulators ; i++) { in try_charger_enable()
411 if (desc->charger_regulators[i].externally_control) in try_charger_enable()
414 err = regulator_disable(desc->charger_regulators[i].consumer); in try_charger_enable()
416 dev_warn(cm->dev, "Cannot disable %s regulator\n", in try_charger_enable()
417 desc->charger_regulators[i].regulator_name); in try_charger_enable()
422 * Abnormal battery state - Stop charging forcibly, in try_charger_enable()
425 for (i = 0; i < desc->num_charger_regulators; i++) { in try_charger_enable()
427 desc->charger_regulators[i].consumer)) { in try_charger_enable()
429 desc->charger_regulators[i].consumer); in try_charger_enable()
430 dev_warn(cm->dev, "Disable regulator(%s) forcibly\n", in try_charger_enable()
431 desc->charger_regulators[i].regulator_name); in try_charger_enable()
437 cm->charger_enabled = enable; in try_charger_enable()
443 * check_charging_duration - Monitor charging/discharging duration
444 * @cm: the Charger Manager representing the battery.
447 * cm stop charging to prevent overcharge/overheat. If discharging
449 * attached, after full-batt, cm start charging to maintain fully
452 static int check_charging_duration(struct charger_manager *cm) in check_charging_duration() argument
454 struct charger_desc *desc = cm->desc; in check_charging_duration()
459 if (!desc->charging_max_duration_ms && in check_charging_duration()
460 !desc->discharging_max_duration_ms) in check_charging_duration()
463 if (cm->charger_enabled) { in check_charging_duration()
464 duration = curr - cm->charging_start_time; in check_charging_duration()
466 if (duration > desc->charging_max_duration_ms) { in check_charging_duration()
467 dev_info(cm->dev, "Charging duration exceed %ums\n", in check_charging_duration()
468 desc->charging_max_duration_ms); in check_charging_duration()
471 } else if (cm->battery_status == POWER_SUPPLY_STATUS_NOT_CHARGING) { in check_charging_duration()
472 duration = curr - cm->charging_end_time; in check_charging_duration()
474 if (duration > desc->discharging_max_duration_ms) { in check_charging_duration()
475 dev_info(cm->dev, "Discharging duration exceed %ums\n", in check_charging_duration()
476 desc->discharging_max_duration_ms); in check_charging_duration()
484 static int cm_get_battery_temperature_by_psy(struct charger_manager *cm, in cm_get_battery_temperature_by_psy() argument
490 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in cm_get_battery_temperature_by_psy()
492 return -ENODEV; in cm_get_battery_temperature_by_psy()
502 static int cm_get_battery_temperature(struct charger_manager *cm, in cm_get_battery_temperature() argument
507 if (!cm->desc->measure_battery_temp) in cm_get_battery_temperature()
508 return -ENODEV; in cm_get_battery_temperature()
511 if (cm->tzd_batt) { in cm_get_battery_temperature()
512 ret = thermal_zone_get_temp(cm->tzd_batt, temp); in cm_get_battery_temperature()
519 /* if-else continued from CONFIG_THERMAL */ in cm_get_battery_temperature()
520 ret = cm_get_battery_temperature_by_psy(cm, temp); in cm_get_battery_temperature()
526 static int cm_check_thermal_status(struct charger_manager *cm) in cm_check_thermal_status() argument
528 struct charger_desc *desc = cm->desc; in cm_check_thermal_status()
532 ret = cm_get_battery_temperature(cm, &temp); in cm_check_thermal_status()
539 dev_err(cm->dev, "Failed to get battery temperature\n"); in cm_check_thermal_status()
543 upper_limit = desc->temp_max; in cm_check_thermal_status()
544 lower_limit = desc->temp_min; in cm_check_thermal_status()
546 if (cm->emergency_stop) { in cm_check_thermal_status()
547 upper_limit -= desc->temp_diff; in cm_check_thermal_status()
548 lower_limit += desc->temp_diff; in cm_check_thermal_status()
558 cm->emergency_stop = ret; in cm_check_thermal_status()
564 * cm_get_target_status - Check current status and get next target status.
565 * @cm: the Charger Manager representing the battery.
567 static int cm_get_target_status(struct charger_manager *cm) in cm_get_target_status() argument
569 if (!is_ext_pwr_online(cm)) in cm_get_target_status()
572 if (cm_check_thermal_status(cm)) { in cm_get_target_status()
574 if (check_charging_duration(cm)) in cm_get_target_status()
579 switch (cm->battery_status) { in cm_get_target_status()
582 if (check_charging_duration(cm)) in cm_get_target_status()
586 if (is_full_charged(cm)) in cm_get_target_status()
599 * _cm_monitor - Monitor the temperature and return true for exceptions.
600 * @cm: the Charger Manager representing the battery.
605 static bool _cm_monitor(struct charger_manager *cm) in _cm_monitor() argument
609 target = cm_get_target_status(cm); in _cm_monitor()
611 try_charger_enable(cm, (target == POWER_SUPPLY_STATUS_CHARGING)); in _cm_monitor()
613 if (cm->battery_status != target) { in _cm_monitor()
614 cm->battery_status = target; in _cm_monitor()
615 power_supply_changed(cm->charger_psy); in _cm_monitor()
618 return (cm->battery_status == POWER_SUPPLY_STATUS_NOT_CHARGING); in _cm_monitor()
622 * cm_monitor - Monitor every battery.
630 struct charger_manager *cm; in cm_monitor() local
634 list_for_each_entry(cm, &cm_list, entry) { in cm_monitor()
635 if (_cm_monitor(cm)) in cm_monitor()
645 * _setup_polling - Setup the next instance of polling.
651 struct charger_manager *cm; in _setup_polling() local
657 list_for_each_entry(cm, &cm_list, entry) { in _setup_polling()
658 if (is_polling_required(cm) && cm->desc->polling_interval_ms) { in _setup_polling()
661 if (min > cm->desc->polling_interval_ms) in _setup_polling()
662 min = cm->desc->polling_interval_ms; in _setup_polling()
675 WARN(cm_wq == NULL, "charger-manager: workqueue not initialized" in _setup_polling()
699 * cm_monitor_poller - The Monitor / Poller.
702 * During non-suspended state, cm_monitor_poller is used to poll and monitor
715 struct charger_manager *cm = power_supply_get_drvdata(psy); in charger_get_property() local
716 struct charger_desc *desc = cm->desc; in charger_get_property()
723 val->intval = cm->battery_status; in charger_get_property()
726 if (cm->emergency_stop == CM_BATT_OVERHEAT) in charger_get_property()
727 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; in charger_get_property()
728 else if (cm->emergency_stop == CM_BATT_COLD) in charger_get_property()
729 val->intval = POWER_SUPPLY_HEALTH_COLD; in charger_get_property()
731 val->intval = POWER_SUPPLY_HEALTH_GOOD; in charger_get_property()
734 if (is_batt_present(cm)) in charger_get_property()
735 val->intval = 1; in charger_get_property()
737 val->intval = 0; in charger_get_property()
740 ret = get_batt_uV(cm, &val->intval); in charger_get_property()
743 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in charger_get_property()
745 ret = -ENODEV; in charger_get_property()
752 return cm_get_battery_temperature(cm, &val->intval); in charger_get_property()
754 if (!is_batt_present(cm)) { in charger_get_property()
756 val->intval = 100; in charger_get_property()
760 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in charger_get_property()
762 ret = -ENODEV; in charger_get_property()
771 if (val->intval > 100) { in charger_get_property()
772 val->intval = 100; in charger_get_property()
775 if (val->intval < 0) in charger_get_property()
776 val->intval = 0; in charger_get_property()
779 if (is_charging(cm)) in charger_get_property()
786 ret = get_batt_uV(cm, &uV); in charger_get_property()
793 if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV && in charger_get_property()
794 !is_charging(cm)) { in charger_get_property()
795 val->intval = 100; in charger_get_property()
801 if (is_ext_pwr_online(cm)) in charger_get_property()
802 val->intval = 1; in charger_get_property()
804 val->intval = 0; in charger_get_property()
808 fuel_gauge = power_supply_get_by_name(cm->desc->psy_fuel_gauge); in charger_get_property()
810 ret = -ENODEV; in charger_get_property()
816 return -EINVAL; in charger_get_property()
851 * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
862 struct charger_manager *cm; in cm_setup_timer() local
868 jiffies_to_msecs(next_polling - jiffies)); in cm_setup_timer()
871 list_for_each_entry(cm, &cm_list, entry) { in cm_setup_timer()
872 /* Skip if polling is not required for this CM */ in cm_setup_timer()
873 if (!is_polling_required(cm) && !cm->emergency_stop) in cm_setup_timer()
876 if (cm->desc->polling_interval_ms == 0) in cm_setup_timer()
878 CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms); in cm_setup_timer()
908 * charger_extcon_work - enable/diable charger according to the state
919 if (cable->attached && cable->min_uA != 0 && cable->max_uA != 0) { in charger_extcon_work()
920 ret = regulator_set_current_limit(cable->charger->consumer, in charger_extcon_work()
921 cable->min_uA, cable->max_uA); in charger_extcon_work()
924 cable->charger->regulator_name, cable->name); in charger_extcon_work()
929 cable->charger->regulator_name, in charger_extcon_work()
930 cable->min_uA, cable->max_uA); in charger_extcon_work()
938 * charger_extcon_notifier - receive the state of charger cable
953 * If cable is attached, cable->attached is true. in charger_extcon_notifier()
955 cable->attached = event; in charger_extcon_notifier()
961 schedule_work(&cable->wq); in charger_extcon_notifier()
967 * charger_extcon_init - register external connector to use it
970 * @cm: the Charger Manager representing the battery.
973 static int charger_extcon_init(struct charger_manager *cm, in charger_extcon_init() argument
984 INIT_WORK(&cable->wq, charger_extcon_work); in charger_extcon_init()
985 cable->nb.notifier_call = charger_extcon_notifier; in charger_extcon_init()
987 cable->extcon_dev = extcon_get_extcon_dev(cable->extcon_name); in charger_extcon_init()
988 if (IS_ERR(cable->extcon_dev)) { in charger_extcon_init()
990 cable->extcon_name, cable->name); in charger_extcon_init()
991 return PTR_ERR(cable->extcon_dev); in charger_extcon_init()
995 if (!strcmp(cable->name, extcon_mapping[i].name)) { in charger_extcon_init()
1001 pr_err("Cannot find cable for type %s", cable->name); in charger_extcon_init()
1002 return -EINVAL; in charger_extcon_init()
1005 cable->extcon_type = extcon_type; in charger_extcon_init()
1007 ret = devm_extcon_register_notifier(cm->dev, cable->extcon_dev, in charger_extcon_init()
1008 cable->extcon_type, &cable->nb); in charger_extcon_init()
1011 cable->extcon_name, cable->name); in charger_extcon_init()
1019 * charger_manager_register_extcon - Register extcon device to receive state
1021 * @cm: the Charger Manager representing the battery.
1028 static int charger_manager_register_extcon(struct charger_manager *cm) in charger_manager_register_extcon() argument
1030 struct charger_desc *desc = cm->desc; in charger_manager_register_extcon()
1037 for (i = 0; i < desc->num_charger_regulators; i++) { in charger_manager_register_extcon()
1038 charger = &desc->charger_regulators[i]; in charger_manager_register_extcon()
1040 charger->consumer = regulator_get(cm->dev, in charger_manager_register_extcon()
1041 charger->regulator_name); in charger_manager_register_extcon()
1042 if (IS_ERR(charger->consumer)) { in charger_manager_register_extcon()
1043 dev_err(cm->dev, "Cannot find charger(%s)\n", in charger_manager_register_extcon()
1044 charger->regulator_name); in charger_manager_register_extcon()
1045 return PTR_ERR(charger->consumer); in charger_manager_register_extcon()
1047 charger->cm = cm; in charger_manager_register_extcon()
1049 for (j = 0; j < charger->num_cables; j++) { in charger_manager_register_extcon()
1050 struct charger_cable *cable = &charger->cables[j]; in charger_manager_register_extcon()
1052 ret = charger_extcon_init(cm, cable); in charger_manager_register_extcon()
1054 dev_err(cm->dev, "Cannot initialize charger(%s)\n", in charger_manager_register_extcon()
1055 charger->regulator_name); in charger_manager_register_extcon()
1058 cable->charger = charger; in charger_manager_register_extcon()
1059 cable->cm = cm; in charger_manager_register_extcon()
1061 event = extcon_get_state(cable->extcon_dev, in charger_manager_register_extcon()
1062 cable->extcon_type); in charger_manager_register_extcon()
1063 charger_extcon_notifier(&cable->nb, in charger_manager_register_extcon()
1078 return sysfs_emit(buf, "%s\n", charger->regulator_name); in charger_name_show()
1088 if (!charger->externally_control) in charger_state_show()
1089 state = regulator_is_enabled(charger->consumer); in charger_state_show()
1100 return sysfs_emit(buf, "%d\n", charger->externally_control); in charger_externally_control_show()
1110 struct charger_manager *cm = charger->cm; in charger_externally_control_store() local
1111 struct charger_desc *desc = cm->desc; in charger_externally_control_store()
1119 ret = -EINVAL; in charger_externally_control_store()
1124 charger->externally_control = 0; in charger_externally_control_store()
1128 for (i = 0; i < desc->num_charger_regulators; i++) { in charger_externally_control_store()
1129 if (&desc->charger_regulators[i] != charger && in charger_externally_control_store()
1130 !desc->charger_regulators[i].externally_control) { in charger_externally_control_store()
1133 * charger-manager in charger_externally_control_store()
1141 if (cm->charger_enabled) { in charger_externally_control_store()
1142 try_charger_enable(charger->cm, false); in charger_externally_control_store()
1143 charger->externally_control = externally_control; in charger_externally_control_store()
1144 try_charger_enable(charger->cm, true); in charger_externally_control_store()
1146 charger->externally_control = externally_control; in charger_externally_control_store()
1149 dev_warn(cm->dev, in charger_externally_control_store()
1150 …"'%s' regulator should be controlled in charger-manager because charger-manager must need at least… in charger_externally_control_store()
1151 charger->regulator_name); in charger_externally_control_store()
1158 * charger_manager_prepare_sysfs - Prepare sysfs entry for each charger
1159 * @cm: the Charger Manager representing the battery.
1162 * user-space. If some development board use one more chargers for charging
1167 * externally_control, this charger isn't controlled from charger-manager and
1170 static int charger_manager_prepare_sysfs(struct charger_manager *cm) in charger_manager_prepare_sysfs() argument
1172 struct charger_desc *desc = cm->desc; in charger_manager_prepare_sysfs()
1179 for (i = 0; i < desc->num_charger_regulators; i++) { in charger_manager_prepare_sysfs()
1180 charger = &desc->charger_regulators[i]; in charger_manager_prepare_sysfs()
1182 name = devm_kasprintf(cm->dev, GFP_KERNEL, "charger.%d", i); in charger_manager_prepare_sysfs()
1184 return -ENOMEM; in charger_manager_prepare_sysfs()
1186 charger->attrs[0] = &charger->attr_name.attr; in charger_manager_prepare_sysfs()
1187 charger->attrs[1] = &charger->attr_state.attr; in charger_manager_prepare_sysfs()
1188 charger->attrs[2] = &charger->attr_externally_control.attr; in charger_manager_prepare_sysfs()
1189 charger->attrs[3] = NULL; in charger_manager_prepare_sysfs()
1191 charger->attr_grp.name = name; in charger_manager_prepare_sysfs()
1192 charger->attr_grp.attrs = charger->attrs; in charger_manager_prepare_sysfs()
1193 desc->sysfs_groups[i] = &charger->attr_grp; in charger_manager_prepare_sysfs()
1195 sysfs_attr_init(&charger->attr_name.attr); in charger_manager_prepare_sysfs()
1196 charger->attr_name.attr.name = "name"; in charger_manager_prepare_sysfs()
1197 charger->attr_name.attr.mode = 0444; in charger_manager_prepare_sysfs()
1198 charger->attr_name.show = charger_name_show; in charger_manager_prepare_sysfs()
1200 sysfs_attr_init(&charger->attr_state.attr); in charger_manager_prepare_sysfs()
1201 charger->attr_state.attr.name = "state"; in charger_manager_prepare_sysfs()
1202 charger->attr_state.attr.mode = 0444; in charger_manager_prepare_sysfs()
1203 charger->attr_state.show = charger_state_show; in charger_manager_prepare_sysfs()
1205 sysfs_attr_init(&charger->attr_externally_control.attr); in charger_manager_prepare_sysfs()
1206 charger->attr_externally_control.attr.name in charger_manager_prepare_sysfs()
1208 charger->attr_externally_control.attr.mode = 0644; in charger_manager_prepare_sysfs()
1209 charger->attr_externally_control.show in charger_manager_prepare_sysfs()
1211 charger->attr_externally_control.store in charger_manager_prepare_sysfs()
1214 if (!desc->charger_regulators[i].externally_control || in charger_manager_prepare_sysfs()
1218 dev_info(cm->dev, "'%s' regulator's externally_control is %d\n", in charger_manager_prepare_sysfs()
1219 charger->regulator_name, charger->externally_control); in charger_manager_prepare_sysfs()
1223 …dev_err(cm->dev, "Cannot register regulator because charger-manager must need at least one charger… in charger_manager_prepare_sysfs()
1224 return -EINVAL; in charger_manager_prepare_sysfs()
1230 static int cm_init_thermal_data(struct charger_manager *cm, in cm_init_thermal_data() argument
1235 struct charger_desc *desc = cm->desc; in cm_init_thermal_data()
1246 cm->desc->measure_battery_temp = true; in cm_init_thermal_data()
1249 if (ret && desc->thermal_zone) { in cm_init_thermal_data()
1250 cm->tzd_batt = in cm_init_thermal_data()
1251 thermal_zone_get_zone_by_name(desc->thermal_zone); in cm_init_thermal_data()
1252 if (IS_ERR(cm->tzd_batt)) in cm_init_thermal_data()
1253 return PTR_ERR(cm->tzd_batt); in cm_init_thermal_data()
1258 cm->desc->measure_battery_temp = true; in cm_init_thermal_data()
1262 if (cm->desc->measure_battery_temp) { in cm_init_thermal_data()
1264 if (!desc->temp_max) in cm_init_thermal_data()
1265 desc->temp_max = CM_DEFAULT_CHARGE_TEMP_MAX; in cm_init_thermal_data()
1266 if (!desc->temp_diff) in cm_init_thermal_data()
1267 desc->temp_diff = CM_DEFAULT_RECHARGE_TEMP_DIFF; in cm_init_thermal_data()
1275 .compatible = "charger-manager",
1284 struct device_node *np = dev->of_node; in of_cm_parse_desc()
1291 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1293 of_property_read_string(np, "cm-name", &desc->psy_name); in of_cm_parse_desc()
1295 of_property_read_u32(np, "cm-poll-mode", &poll_mode); in of_cm_parse_desc()
1296 desc->polling_mode = poll_mode; in of_cm_parse_desc()
1298 of_property_read_u32(np, "cm-poll-interval", in of_cm_parse_desc()
1299 &desc->polling_interval_ms); in of_cm_parse_desc()
1301 of_property_read_u32(np, "cm-fullbatt-vchkdrop-volt", in of_cm_parse_desc()
1302 &desc->fullbatt_vchkdrop_uV); in of_cm_parse_desc()
1303 of_property_read_u32(np, "cm-fullbatt-voltage", &desc->fullbatt_uV); in of_cm_parse_desc()
1304 of_property_read_u32(np, "cm-fullbatt-soc", &desc->fullbatt_soc); in of_cm_parse_desc()
1305 of_property_read_u32(np, "cm-fullbatt-capacity", in of_cm_parse_desc()
1306 &desc->fullbatt_full_capacity); in of_cm_parse_desc()
1308 of_property_read_u32(np, "cm-battery-stat", &battery_stat); in of_cm_parse_desc()
1309 desc->battery_present = battery_stat; in of_cm_parse_desc()
1312 num_chgs = of_property_count_strings(np, "cm-chargers"); in of_cm_parse_desc()
1317 desc->psy_charger_stat = devm_kcalloc(dev, in of_cm_parse_desc()
1321 if (!desc->psy_charger_stat) in of_cm_parse_desc()
1322 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1325 of_property_read_string_index(np, "cm-chargers", in of_cm_parse_desc()
1326 i, &desc->psy_charger_stat[i]); in of_cm_parse_desc()
1329 of_property_read_string(np, "cm-fuel-gauge", &desc->psy_fuel_gauge); in of_cm_parse_desc()
1331 of_property_read_string(np, "cm-thermal-zone", &desc->thermal_zone); in of_cm_parse_desc()
1333 of_property_read_u32(np, "cm-battery-cold", &desc->temp_min); in of_cm_parse_desc()
1334 if (of_property_read_bool(np, "cm-battery-cold-in-minus")) in of_cm_parse_desc()
1335 desc->temp_min *= -1; in of_cm_parse_desc()
1336 of_property_read_u32(np, "cm-battery-hot", &desc->temp_max); in of_cm_parse_desc()
1337 of_property_read_u32(np, "cm-battery-temp-diff", &desc->temp_diff); in of_cm_parse_desc()
1339 of_property_read_u32(np, "cm-charging-max", in of_cm_parse_desc()
1340 &desc->charging_max_duration_ms); in of_cm_parse_desc()
1341 of_property_read_u32(np, "cm-discharging-max", in of_cm_parse_desc()
1342 &desc->discharging_max_duration_ms); in of_cm_parse_desc()
1345 desc->num_charger_regulators = of_get_child_count(np); in of_cm_parse_desc()
1346 if (desc->num_charger_regulators) { in of_cm_parse_desc()
1351 desc->num_charger_regulators, in of_cm_parse_desc()
1355 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1357 desc->charger_regulators = chg_regs; in of_cm_parse_desc()
1359 desc->sysfs_groups = devm_kcalloc(dev, in of_cm_parse_desc()
1360 desc->num_charger_regulators + 1, in of_cm_parse_desc()
1361 sizeof(*desc->sysfs_groups), in of_cm_parse_desc()
1363 if (!desc->sysfs_groups) in of_cm_parse_desc()
1364 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1370 of_property_read_string(child, "cm-regulator-name", in of_cm_parse_desc()
1371 &chg_regs->regulator_name); in of_cm_parse_desc()
1374 chg_regs->num_cables = of_get_child_count(child); in of_cm_parse_desc()
1375 if (chg_regs->num_cables) { in of_cm_parse_desc()
1377 chg_regs->num_cables, in of_cm_parse_desc()
1382 return ERR_PTR(-ENOMEM); in of_cm_parse_desc()
1385 chg_regs->cables = cables; in of_cm_parse_desc()
1389 "cm-cable-name", &cables->name); in of_cm_parse_desc()
1391 "cm-cable-extcon", in of_cm_parse_desc()
1392 &cables->extcon_name); in of_cm_parse_desc()
1394 "cm-cable-min", in of_cm_parse_desc()
1395 &cables->min_uA); in of_cm_parse_desc()
1397 "cm-cable-max", in of_cm_parse_desc()
1398 &cables->max_uA); in of_cm_parse_desc()
1410 if (pdev->dev.of_node) in cm_get_drv_data()
1411 return of_cm_parse_desc(&pdev->dev); in cm_get_drv_data()
1412 return dev_get_platdata(&pdev->dev); in cm_get_drv_data()
1423 struct charger_manager *cm; in charger_manager_probe() local
1432 dev_err(&pdev->dev, "No platform data (desc) found\n"); in charger_manager_probe()
1436 cm = devm_kzalloc(&pdev->dev, sizeof(*cm), GFP_KERNEL); in charger_manager_probe()
1437 if (!cm) in charger_manager_probe()
1438 return -ENOMEM; in charger_manager_probe()
1441 cm->dev = &pdev->dev; in charger_manager_probe()
1442 cm->desc = desc; in charger_manager_probe()
1443 psy_cfg.drv_data = cm; in charger_manager_probe()
1447 cm_timer = devm_kzalloc(cm->dev, sizeof(*cm_timer), GFP_KERNEL); in charger_manager_probe()
1449 return -ENOMEM; in charger_manager_probe()
1457 if (desc->fullbatt_uV == 0) { in charger_manager_probe()
1458 dev_info(&pdev->dev, "Ignoring full-battery voltage threshold as it is not supplied\n"); in charger_manager_probe()
1460 if (!desc->fullbatt_vchkdrop_uV) { in charger_manager_probe()
1461 …dev_info(&pdev->dev, "Disabling full-battery voltage drop checking mechanism as it is not supplied… in charger_manager_probe()
1462 desc->fullbatt_vchkdrop_uV = 0; in charger_manager_probe()
1464 if (desc->fullbatt_soc == 0) { in charger_manager_probe()
1465 …dev_info(&pdev->dev, "Ignoring full-battery soc(state of charge) threshold as it is not supplied\n… in charger_manager_probe()
1467 if (desc->fullbatt_full_capacity == 0) { in charger_manager_probe()
1468 dev_info(&pdev->dev, "Ignoring full-battery full capacity threshold as it is not supplied\n"); in charger_manager_probe()
1471 if (!desc->charger_regulators || desc->num_charger_regulators < 1) { in charger_manager_probe()
1472 dev_err(&pdev->dev, "charger_regulators undefined\n"); in charger_manager_probe()
1473 return -EINVAL; in charger_manager_probe()
1476 if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) { in charger_manager_probe()
1477 dev_err(&pdev->dev, "No power supply defined\n"); in charger_manager_probe()
1478 return -EINVAL; in charger_manager_probe()
1481 if (!desc->psy_fuel_gauge) { in charger_manager_probe()
1482 dev_err(&pdev->dev, "No fuel gauge power supply defined\n"); in charger_manager_probe()
1483 return -EINVAL; in charger_manager_probe()
1487 for (i = 0; desc->psy_charger_stat[i]; i++) { in charger_manager_probe()
1490 psy = power_supply_get_by_name(desc->psy_charger_stat[i]); in charger_manager_probe()
1492 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", in charger_manager_probe()
1493 desc->psy_charger_stat[i]); in charger_manager_probe()
1494 return -ENODEV; in charger_manager_probe()
1499 if (cm->desc->polling_mode != CM_POLL_DISABLE && in charger_manager_probe()
1500 (desc->polling_interval_ms == 0 || in charger_manager_probe()
1501 msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL)) { in charger_manager_probe()
1502 dev_err(&pdev->dev, "polling_interval_ms is too small\n"); in charger_manager_probe()
1503 return -EINVAL; in charger_manager_probe()
1506 if (!desc->charging_max_duration_ms || in charger_manager_probe()
1507 !desc->discharging_max_duration_ms) { in charger_manager_probe()
1508 …dev_info(&pdev->dev, "Cannot limit charging duration checking mechanism to prevent overcharge/over… in charger_manager_probe()
1509 desc->charging_max_duration_ms = 0; in charger_manager_probe()
1510 desc->discharging_max_duration_ms = 0; in charger_manager_probe()
1513 platform_set_drvdata(pdev, cm); in charger_manager_probe()
1515 memcpy(&cm->charger_psy_desc, &psy_default, sizeof(psy_default)); in charger_manager_probe()
1517 if (!desc->psy_name) in charger_manager_probe()
1518 strscpy(cm->psy_name_buf, psy_default.name, in charger_manager_probe()
1519 sizeof(cm->psy_name_buf)); in charger_manager_probe()
1521 strscpy(cm->psy_name_buf, desc->psy_name, in charger_manager_probe()
1522 sizeof(cm->psy_name_buf)); in charger_manager_probe()
1523 cm->charger_psy_desc.name = cm->psy_name_buf; in charger_manager_probe()
1526 properties = devm_kcalloc(&pdev->dev, in charger_manager_probe()
1531 return -ENOMEM; in charger_manager_probe()
1538 /* Find which optional psy-properties are available */ in charger_manager_probe()
1539 fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge); in charger_manager_probe()
1541 dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n", in charger_manager_probe()
1542 desc->psy_fuel_gauge); in charger_manager_probe()
1543 return -ENODEV; in charger_manager_probe()
1565 ret = cm_init_thermal_data(cm, fuel_gauge, properties, &num_properties); in charger_manager_probe()
1567 dev_err(&pdev->dev, "Failed to initialize thermal data\n"); in charger_manager_probe()
1568 cm->desc->measure_battery_temp = false; in charger_manager_probe()
1572 cm->charger_psy_desc.properties = properties; in charger_manager_probe()
1573 cm->charger_psy_desc.num_properties = num_properties; in charger_manager_probe()
1576 ret = charger_manager_prepare_sysfs(cm); in charger_manager_probe()
1578 dev_err(&pdev->dev, in charger_manager_probe()
1582 psy_cfg.attr_grp = desc->sysfs_groups; in charger_manager_probe()
1584 cm->charger_psy = power_supply_register(&pdev->dev, in charger_manager_probe()
1585 &cm->charger_psy_desc, in charger_manager_probe()
1587 if (IS_ERR(cm->charger_psy)) { in charger_manager_probe()
1588 dev_err(&pdev->dev, "Cannot register charger-manager with name \"%s\"\n", in charger_manager_probe()
1589 cm->charger_psy_desc.name); in charger_manager_probe()
1590 return PTR_ERR(cm->charger_psy); in charger_manager_probe()
1594 ret = charger_manager_register_extcon(cm); in charger_manager_probe()
1596 dev_err(&pdev->dev, "Cannot initialize extcon device\n"); in charger_manager_probe()
1602 list_add(&cm->entry, &cm_list); in charger_manager_probe()
1606 * Charger-manager is capable of waking up the system from sleep in charger_manager_probe()
1609 device_init_wakeup(&pdev->dev, true); in charger_manager_probe()
1610 device_set_wakeup_capable(&pdev->dev, false); in charger_manager_probe()
1613 * Charger-manager have to check the charging state right after in charger_manager_probe()
1614 * initialization of charger-manager and then update current charging in charger_manager_probe()
1624 for (i = 0; i < desc->num_charger_regulators; i++) in charger_manager_probe()
1625 regulator_put(desc->charger_regulators[i].consumer); in charger_manager_probe()
1627 power_supply_unregister(cm->charger_psy); in charger_manager_probe()
1634 struct charger_manager *cm = platform_get_drvdata(pdev); in charger_manager_remove() local
1635 struct charger_desc *desc = cm->desc; in charger_manager_remove()
1640 list_del(&cm->entry); in charger_manager_remove()
1646 for (i = 0 ; i < desc->num_charger_regulators ; i++) in charger_manager_remove()
1647 regulator_put(desc->charger_regulators[i].consumer); in charger_manager_remove()
1649 power_supply_unregister(cm->charger_psy); in charger_manager_remove()
1651 try_charger_enable(cm, false); in charger_manager_remove()
1655 { "charger-manager", 0 },
1664 return -EAGAIN; in cm_suspend_noirq()
1672 struct charger_manager *cm; in cm_need_to_awake() local
1678 list_for_each_entry(cm, &cm_list, entry) { in cm_need_to_awake()
1679 if (is_charging(cm)) { in cm_need_to_awake()
1692 return -EBUSY; in cm_suspend_prepare()
1709 struct charger_manager *cm = dev_get_drvdata(dev); in cm_suspend_complete() local
1720 cm_suspend_duration_ms -= ktime_to_ms(remain); in cm_suspend_complete()
1724 _cm_monitor(cm); in cm_suspend_complete()
1726 device_set_wakeup_capable(cm->dev, false); in cm_suspend_complete()
1737 .name = "charger-manager",
1750 return -ENOMEM; in charger_manager_init()