Loading drivers/power/supply/qti_battery_charger.c +226 −4 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #define WLS_FW_PREPARE_TIME_MS 300 #define WLS_FW_WAIT_TIME_MS 500 #define WLS_FW_BUF_SIZE 128 #define DEFAULT_RESTRICT_FCC_UA 1000000 enum psy_type { PSY_TYPE_BATTERY, Loading Loading @@ -100,6 +101,9 @@ enum usb_property_id { USB_ADAP_TYPE, USB_MOISTURE_DET_EN, USB_MOISTURE_DET_STS, USB_TEMP, USB_REAL_TYPE, USB_TYPEC_COMPLIANT, USB_PROP_MAX, }; Loading @@ -114,6 +118,12 @@ enum wireless_property_id { WLS_PROP_MAX, }; enum { QTI_POWER_SUPPLY_USB_TYPE_HVDCP = 0x80, QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3, QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3P5, }; struct battery_charger_set_notify_msg { struct pmic_glink_hdr hdr; u32 battery_id; Loading Loading @@ -214,6 +224,7 @@ struct battery_chg_dev { int num_thermal_levels; atomic_t state; struct work_struct subsys_up_work; struct work_struct usb_type_work; int fake_soc; bool block_tx; bool ship_mode_en; Loading @@ -221,6 +232,9 @@ struct battery_chg_dev { bool wls_fw_update_reqd; u32 wls_fw_version; struct notifier_block reboot_notifier; u32 thermal_fcc_ua; u32 restrict_fcc_ua; bool restrict_chg_en; }; static const int battery_prop_map[BATT_PROP_MAX] = { Loading Loading @@ -256,6 +270,7 @@ static const int usb_prop_map[USB_PROP_MAX] = { [USB_CURR_MAX] = POWER_SUPPLY_PROP_CURRENT_MAX, [USB_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, [USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE, [USB_TEMP] = POWER_SUPPLY_PROP_TEMP, }; static const int wls_prop_map[WLS_PROP_MAX] = { Loading @@ -266,6 +281,17 @@ static const int wls_prop_map[WLS_PROP_MAX] = { [WLS_CURR_MAX] = POWER_SUPPLY_PROP_CURRENT_MAX, }; /* Standard usb_type definitions similar to power_supply_sysfs.c */ static const char * const power_supply_usb_type_text[] = { "Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD", "PD_DRP", "PD_PPS", "BrickID" }; /* Custom usb_type definitions */ static const char * const qc_power_supply_usb_type_text[] = { "HVDCP", "HVDCP_3", "HVDCP_3P5" }; static int battery_chg_fw_write(struct battery_chg_dev *bcdev, void *data, int len) { Loading Loading @@ -595,6 +621,54 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data, complete(&bcdev->ack); } static struct power_supply_desc usb_psy_desc; static void battery_chg_update_usb_type_work(struct work_struct *work) { struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev, usb_type_work); struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; int rc; rc = read_property_id(bcdev, pst, USB_ADAP_TYPE); if (rc < 0) { pr_err("Failed to read USB_ADAP_TYPE rc=%d\n", rc); return; } pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]); switch (pst->prop[USB_ADAP_TYPE]) { case POWER_SUPPLY_USB_TYPE_SDP: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB; break; case POWER_SUPPLY_USB_TYPE_DCP: case POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID: case QTI_POWER_SUPPLY_USB_TYPE_HVDCP: case QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3: case QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3P5: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_DCP; break; case POWER_SUPPLY_USB_TYPE_CDP: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_CDP; break; case POWER_SUPPLY_USB_TYPE_ACA: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_ACA; break; case POWER_SUPPLY_USB_TYPE_C: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_TYPE_C; break; case POWER_SUPPLY_USB_TYPE_PD: case POWER_SUPPLY_USB_TYPE_PD_DRP: case POWER_SUPPLY_USB_TYPE_PD_PPS: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_PD; break; default: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB; break; } } static void handle_notification(struct battery_chg_dev *bcdev, void *data, size_t len) { Loading @@ -615,6 +689,7 @@ static void handle_notification(struct battery_chg_dev *bcdev, void *data, break; case BC_USB_STATUS_GET: pst = &bcdev->psy_list[PSY_TYPE_USB]; schedule_work(&bcdev->usb_type_work); break; case BC_WLS_STATUS_GET: pst = &bcdev->psy_list[PSY_TYPE_WLS]; Loading Loading @@ -707,6 +782,28 @@ static const struct power_supply_desc wls_psy_desc = { .property_is_writeable = wls_psy_prop_is_writeable, }; static const char *get_usb_type_name(u32 usb_type) { u32 i; if (usb_type >= QTI_POWER_SUPPLY_USB_TYPE_HVDCP && usb_type <= QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3P5) { for (i = 0; i < ARRAY_SIZE(qc_power_supply_usb_type_text); i++) { if (i == (usb_type - QTI_POWER_SUPPLY_USB_TYPE_HVDCP)) return qc_power_supply_usb_type_text[i]; } return "Unknown"; } for (i = 0; i < ARRAY_SIZE(power_supply_usb_type_text); i++) { if (i == usb_type) return power_supply_usb_type_text[i]; } return "Unknown"; } static int usb_psy_set_icl(struct battery_chg_dev *bcdev, u32 prop_id, int val) { struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; Loading Loading @@ -758,6 +855,8 @@ static int usb_psy_get_prop(struct power_supply *psy, return rc; pval->intval = pst->prop[prop_id]; if (prop == POWER_SUPPLY_PROP_TEMP) pval->intval = DIV_ROUND_CLOSEST((int)pval->intval, 10); return 0; } Loading Loading @@ -806,6 +905,7 @@ static enum power_supply_property usb_props[] = { POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_USB_TYPE, POWER_SUPPLY_PROP_TEMP, }; static enum power_supply_usb_type usb_psy_supported_types[] = { Loading @@ -821,7 +921,7 @@ static enum power_supply_usb_type usb_psy_supported_types[] = { POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID, }; static const struct power_supply_desc usb_psy_desc = { static struct power_supply_desc usb_psy_desc = { .name = "usb", .type = POWER_SUPPLY_TYPE_USB, .properties = usb_props, Loading @@ -833,6 +933,26 @@ static const struct power_supply_desc usb_psy_desc = { .property_is_writeable = usb_psy_prop_is_writeable, }; static int __battery_psy_set_charge_current(struct battery_chg_dev *bcdev, u32 fcc_ua) { int rc; if (bcdev->restrict_chg_en) fcc_ua = min_t(u32, fcc_ua, bcdev->thermal_fcc_ua); else fcc_ua = bcdev->thermal_fcc_ua; rc = write_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], BATT_CHG_CTRL_LIM, fcc_ua); if (rc < 0) pr_err("Failed to set FCC %u, rc=%d\n", fcc_ua, rc); else pr_debug("Set FCC to %u uA\n", fcc_ua); return rc; } static int battery_psy_set_charge_current(struct battery_chg_dev *bcdev, int val) { Loading @@ -852,11 +972,10 @@ static int battery_psy_set_charge_current(struct battery_chg_dev *bcdev, fcc_ua = bcdev->thermal_levels[val]; rc = write_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], BATT_CHG_CTRL_LIM, fcc_ua); rc = __battery_psy_set_charge_current(bcdev, fcc_ua); if (!rc) { bcdev->curr_thermal_level = val; pr_debug("Set FCC to %u uA\n", fcc_ua); bcdev->thermal_fcc_ua = fcc_ua; } return rc; Loading Loading @@ -1232,6 +1351,102 @@ static ssize_t wireless_fw_update_store(struct class *c, } static CLASS_ATTR_WO(wireless_fw_update); static ssize_t usb_typec_compliant_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; int rc; rc = read_property_id(bcdev, pst, USB_TYPEC_COMPLIANT); if (rc < 0) return rc; return scnprintf(buf, PAGE_SIZE, "%d\n", (int)pst->prop[USB_TYPEC_COMPLIANT]); } static CLASS_ATTR_RO(usb_typec_compliant); static ssize_t usb_real_type_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; int rc; rc = read_property_id(bcdev, pst, USB_REAL_TYPE); if (rc < 0) return rc; return scnprintf(buf, PAGE_SIZE, "%s\n", get_usb_type_name(pst->prop[USB_REAL_TYPE])); } static CLASS_ATTR_RO(usb_real_type); static ssize_t restrict_cur_store(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); int rc; u32 val; if (kstrtou32(buf, 0, &val) || val > bcdev->thermal_fcc_ua) return -EINVAL; if (bcdev->restrict_chg_en) { rc = __battery_psy_set_charge_current(bcdev, val); if (rc < 0) return rc; } bcdev->restrict_fcc_ua = val; return count; } static ssize_t restrict_cur_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); return scnprintf(buf, PAGE_SIZE, "%u\n", bcdev->restrict_fcc_ua); } static CLASS_ATTR_RW(restrict_cur); static ssize_t restrict_chg_store(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); int rc; bool val; if (kstrtobool(buf, &val)) return -EINVAL; bcdev->restrict_chg_en = val; rc = __battery_psy_set_charge_current(bcdev, bcdev->restrict_fcc_ua); if (rc < 0) return rc; return count; } static ssize_t restrict_chg_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); return scnprintf(buf, PAGE_SIZE, "%d\n", bcdev->restrict_chg_en); } static CLASS_ATTR_RW(restrict_chg); static ssize_t fake_soc_store(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { Loading Loading @@ -1417,6 +1632,10 @@ static struct attribute *battery_class_attrs[] = { &class_attr_wireless_fw_force_update.attr, &class_attr_wireless_fw_version.attr, &class_attr_ship_mode_en.attr, &class_attr_restrict_chg.attr, &class_attr_restrict_cur.attr, &class_attr_usb_real_type.attr, &class_attr_usb_typec_compliant.attr, NULL, }; ATTRIBUTE_GROUPS(battery_class); Loading Loading @@ -1512,6 +1731,7 @@ static int battery_chg_parse_dt(struct battery_chg_dev *bcdev) } bcdev->num_thermal_levels = len; bcdev->thermal_fcc_ua = pst->prop[BATT_CHG_CTRL_LIM_MAX]; return 0; } Loading Loading @@ -1583,6 +1803,7 @@ static int battery_chg_probe(struct platform_device *pdev) init_completion(&bcdev->fw_buf_ack); init_completion(&bcdev->fw_update_ack); INIT_WORK(&bcdev->subsys_up_work, battery_chg_subsys_up_work); INIT_WORK(&bcdev->usb_type_work, battery_chg_update_usb_type_work); atomic_set(&bcdev->state, PMIC_GLINK_STATE_UP); bcdev->dev = dev; Loading @@ -1609,6 +1830,7 @@ static int battery_chg_probe(struct platform_device *pdev) if (rc < 0) goto error; bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA; platform_set_drvdata(pdev, bcdev); bcdev->fake_soc = -EINVAL; rc = battery_chg_init_psy(bcdev); Loading Loading
drivers/power/supply/qti_battery_charger.c +226 −4 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #define WLS_FW_PREPARE_TIME_MS 300 #define WLS_FW_WAIT_TIME_MS 500 #define WLS_FW_BUF_SIZE 128 #define DEFAULT_RESTRICT_FCC_UA 1000000 enum psy_type { PSY_TYPE_BATTERY, Loading Loading @@ -100,6 +101,9 @@ enum usb_property_id { USB_ADAP_TYPE, USB_MOISTURE_DET_EN, USB_MOISTURE_DET_STS, USB_TEMP, USB_REAL_TYPE, USB_TYPEC_COMPLIANT, USB_PROP_MAX, }; Loading @@ -114,6 +118,12 @@ enum wireless_property_id { WLS_PROP_MAX, }; enum { QTI_POWER_SUPPLY_USB_TYPE_HVDCP = 0x80, QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3, QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3P5, }; struct battery_charger_set_notify_msg { struct pmic_glink_hdr hdr; u32 battery_id; Loading Loading @@ -214,6 +224,7 @@ struct battery_chg_dev { int num_thermal_levels; atomic_t state; struct work_struct subsys_up_work; struct work_struct usb_type_work; int fake_soc; bool block_tx; bool ship_mode_en; Loading @@ -221,6 +232,9 @@ struct battery_chg_dev { bool wls_fw_update_reqd; u32 wls_fw_version; struct notifier_block reboot_notifier; u32 thermal_fcc_ua; u32 restrict_fcc_ua; bool restrict_chg_en; }; static const int battery_prop_map[BATT_PROP_MAX] = { Loading Loading @@ -256,6 +270,7 @@ static const int usb_prop_map[USB_PROP_MAX] = { [USB_CURR_MAX] = POWER_SUPPLY_PROP_CURRENT_MAX, [USB_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, [USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE, [USB_TEMP] = POWER_SUPPLY_PROP_TEMP, }; static const int wls_prop_map[WLS_PROP_MAX] = { Loading @@ -266,6 +281,17 @@ static const int wls_prop_map[WLS_PROP_MAX] = { [WLS_CURR_MAX] = POWER_SUPPLY_PROP_CURRENT_MAX, }; /* Standard usb_type definitions similar to power_supply_sysfs.c */ static const char * const power_supply_usb_type_text[] = { "Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD", "PD_DRP", "PD_PPS", "BrickID" }; /* Custom usb_type definitions */ static const char * const qc_power_supply_usb_type_text[] = { "HVDCP", "HVDCP_3", "HVDCP_3P5" }; static int battery_chg_fw_write(struct battery_chg_dev *bcdev, void *data, int len) { Loading Loading @@ -595,6 +621,54 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data, complete(&bcdev->ack); } static struct power_supply_desc usb_psy_desc; static void battery_chg_update_usb_type_work(struct work_struct *work) { struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev, usb_type_work); struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; int rc; rc = read_property_id(bcdev, pst, USB_ADAP_TYPE); if (rc < 0) { pr_err("Failed to read USB_ADAP_TYPE rc=%d\n", rc); return; } pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]); switch (pst->prop[USB_ADAP_TYPE]) { case POWER_SUPPLY_USB_TYPE_SDP: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB; break; case POWER_SUPPLY_USB_TYPE_DCP: case POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID: case QTI_POWER_SUPPLY_USB_TYPE_HVDCP: case QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3: case QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3P5: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_DCP; break; case POWER_SUPPLY_USB_TYPE_CDP: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_CDP; break; case POWER_SUPPLY_USB_TYPE_ACA: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_ACA; break; case POWER_SUPPLY_USB_TYPE_C: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_TYPE_C; break; case POWER_SUPPLY_USB_TYPE_PD: case POWER_SUPPLY_USB_TYPE_PD_DRP: case POWER_SUPPLY_USB_TYPE_PD_PPS: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB_PD; break; default: usb_psy_desc.type = POWER_SUPPLY_TYPE_USB; break; } } static void handle_notification(struct battery_chg_dev *bcdev, void *data, size_t len) { Loading @@ -615,6 +689,7 @@ static void handle_notification(struct battery_chg_dev *bcdev, void *data, break; case BC_USB_STATUS_GET: pst = &bcdev->psy_list[PSY_TYPE_USB]; schedule_work(&bcdev->usb_type_work); break; case BC_WLS_STATUS_GET: pst = &bcdev->psy_list[PSY_TYPE_WLS]; Loading Loading @@ -707,6 +782,28 @@ static const struct power_supply_desc wls_psy_desc = { .property_is_writeable = wls_psy_prop_is_writeable, }; static const char *get_usb_type_name(u32 usb_type) { u32 i; if (usb_type >= QTI_POWER_SUPPLY_USB_TYPE_HVDCP && usb_type <= QTI_POWER_SUPPLY_USB_TYPE_HVDCP_3P5) { for (i = 0; i < ARRAY_SIZE(qc_power_supply_usb_type_text); i++) { if (i == (usb_type - QTI_POWER_SUPPLY_USB_TYPE_HVDCP)) return qc_power_supply_usb_type_text[i]; } return "Unknown"; } for (i = 0; i < ARRAY_SIZE(power_supply_usb_type_text); i++) { if (i == usb_type) return power_supply_usb_type_text[i]; } return "Unknown"; } static int usb_psy_set_icl(struct battery_chg_dev *bcdev, u32 prop_id, int val) { struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; Loading Loading @@ -758,6 +855,8 @@ static int usb_psy_get_prop(struct power_supply *psy, return rc; pval->intval = pst->prop[prop_id]; if (prop == POWER_SUPPLY_PROP_TEMP) pval->intval = DIV_ROUND_CLOSEST((int)pval->intval, 10); return 0; } Loading Loading @@ -806,6 +905,7 @@ static enum power_supply_property usb_props[] = { POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, POWER_SUPPLY_PROP_USB_TYPE, POWER_SUPPLY_PROP_TEMP, }; static enum power_supply_usb_type usb_psy_supported_types[] = { Loading @@ -821,7 +921,7 @@ static enum power_supply_usb_type usb_psy_supported_types[] = { POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID, }; static const struct power_supply_desc usb_psy_desc = { static struct power_supply_desc usb_psy_desc = { .name = "usb", .type = POWER_SUPPLY_TYPE_USB, .properties = usb_props, Loading @@ -833,6 +933,26 @@ static const struct power_supply_desc usb_psy_desc = { .property_is_writeable = usb_psy_prop_is_writeable, }; static int __battery_psy_set_charge_current(struct battery_chg_dev *bcdev, u32 fcc_ua) { int rc; if (bcdev->restrict_chg_en) fcc_ua = min_t(u32, fcc_ua, bcdev->thermal_fcc_ua); else fcc_ua = bcdev->thermal_fcc_ua; rc = write_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], BATT_CHG_CTRL_LIM, fcc_ua); if (rc < 0) pr_err("Failed to set FCC %u, rc=%d\n", fcc_ua, rc); else pr_debug("Set FCC to %u uA\n", fcc_ua); return rc; } static int battery_psy_set_charge_current(struct battery_chg_dev *bcdev, int val) { Loading @@ -852,11 +972,10 @@ static int battery_psy_set_charge_current(struct battery_chg_dev *bcdev, fcc_ua = bcdev->thermal_levels[val]; rc = write_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], BATT_CHG_CTRL_LIM, fcc_ua); rc = __battery_psy_set_charge_current(bcdev, fcc_ua); if (!rc) { bcdev->curr_thermal_level = val; pr_debug("Set FCC to %u uA\n", fcc_ua); bcdev->thermal_fcc_ua = fcc_ua; } return rc; Loading Loading @@ -1232,6 +1351,102 @@ static ssize_t wireless_fw_update_store(struct class *c, } static CLASS_ATTR_WO(wireless_fw_update); static ssize_t usb_typec_compliant_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; int rc; rc = read_property_id(bcdev, pst, USB_TYPEC_COMPLIANT); if (rc < 0) return rc; return scnprintf(buf, PAGE_SIZE, "%d\n", (int)pst->prop[USB_TYPEC_COMPLIANT]); } static CLASS_ATTR_RO(usb_typec_compliant); static ssize_t usb_real_type_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB]; int rc; rc = read_property_id(bcdev, pst, USB_REAL_TYPE); if (rc < 0) return rc; return scnprintf(buf, PAGE_SIZE, "%s\n", get_usb_type_name(pst->prop[USB_REAL_TYPE])); } static CLASS_ATTR_RO(usb_real_type); static ssize_t restrict_cur_store(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); int rc; u32 val; if (kstrtou32(buf, 0, &val) || val > bcdev->thermal_fcc_ua) return -EINVAL; if (bcdev->restrict_chg_en) { rc = __battery_psy_set_charge_current(bcdev, val); if (rc < 0) return rc; } bcdev->restrict_fcc_ua = val; return count; } static ssize_t restrict_cur_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); return scnprintf(buf, PAGE_SIZE, "%u\n", bcdev->restrict_fcc_ua); } static CLASS_ATTR_RW(restrict_cur); static ssize_t restrict_chg_store(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); int rc; bool val; if (kstrtobool(buf, &val)) return -EINVAL; bcdev->restrict_chg_en = val; rc = __battery_psy_set_charge_current(bcdev, bcdev->restrict_fcc_ua); if (rc < 0) return rc; return count; } static ssize_t restrict_chg_show(struct class *c, struct class_attribute *attr, char *buf) { struct battery_chg_dev *bcdev = container_of(c, struct battery_chg_dev, battery_class); return scnprintf(buf, PAGE_SIZE, "%d\n", bcdev->restrict_chg_en); } static CLASS_ATTR_RW(restrict_chg); static ssize_t fake_soc_store(struct class *c, struct class_attribute *attr, const char *buf, size_t count) { Loading Loading @@ -1417,6 +1632,10 @@ static struct attribute *battery_class_attrs[] = { &class_attr_wireless_fw_force_update.attr, &class_attr_wireless_fw_version.attr, &class_attr_ship_mode_en.attr, &class_attr_restrict_chg.attr, &class_attr_restrict_cur.attr, &class_attr_usb_real_type.attr, &class_attr_usb_typec_compliant.attr, NULL, }; ATTRIBUTE_GROUPS(battery_class); Loading Loading @@ -1512,6 +1731,7 @@ static int battery_chg_parse_dt(struct battery_chg_dev *bcdev) } bcdev->num_thermal_levels = len; bcdev->thermal_fcc_ua = pst->prop[BATT_CHG_CTRL_LIM_MAX]; return 0; } Loading Loading @@ -1583,6 +1803,7 @@ static int battery_chg_probe(struct platform_device *pdev) init_completion(&bcdev->fw_buf_ack); init_completion(&bcdev->fw_update_ack); INIT_WORK(&bcdev->subsys_up_work, battery_chg_subsys_up_work); INIT_WORK(&bcdev->usb_type_work, battery_chg_update_usb_type_work); atomic_set(&bcdev->state, PMIC_GLINK_STATE_UP); bcdev->dev = dev; Loading @@ -1609,6 +1830,7 @@ static int battery_chg_probe(struct platform_device *pdev) if (rc < 0) goto error; bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA; platform_set_drvdata(pdev, bcdev); bcdev->fake_soc = -EINVAL; rc = battery_chg_init_psy(bcdev); Loading