Loading drivers/power/supply/qti_battery_charger.c +70 −15 Original line number Diff line number Diff line Loading @@ -234,7 +234,11 @@ struct battery_chg_dev { struct notifier_block reboot_notifier; u32 thermal_fcc_ua; u32 restrict_fcc_ua; u32 last_fcc_ua; u32 usb_icl_ua; bool restrict_chg_en; /* To track the driver initialization status */ bool initialized; }; static const int battery_prop_map[BATT_PROP_MAX] = { Loading Loading @@ -421,14 +425,6 @@ static void battery_chg_notify_enable(struct battery_chg_dev *bcdev) pr_err("Failed to enable notification rc=%d\n", rc); } static void battery_chg_subsys_up_work(struct work_struct *work) { struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev, subsys_up_work); battery_chg_notify_enable(bcdev); } static void battery_chg_state_cb(void *priv, enum pmic_glink_state state) { struct battery_chg_dev *bcdev = priv; Loading Loading @@ -636,6 +632,11 @@ static void battery_chg_update_usb_type_work(struct work_struct *work) return; } /* Reset usb_icl_ua whenever USB adapter type changes */ if (pst->prop[USB_ADAP_TYPE] != POWER_SUPPLY_USB_TYPE_SDP && pst->prop[USB_ADAP_TYPE] != POWER_SUPPLY_USB_TYPE_PD) bcdev->usb_icl_ua = 0; pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]); switch (pst->prop[USB_ADAP_TYPE]) { Loading Loading @@ -720,6 +721,12 @@ static int battery_chg_callback(void *priv, void *data, size_t len) pr_debug("owner: %u type: %u opcode: %#x len: %zu\n", hdr->owner, hdr->type, hdr->opcode, len); if (!bcdev->initialized) { pr_debug("Driver initialization failed: Dropping glink callback message: state %d\n", bcdev->state); return 0; } if (hdr->opcode == BC_NOTIFY_IND) handle_notification(bcdev, data, len); else Loading Loading @@ -811,8 +818,10 @@ static int usb_psy_set_icl(struct battery_chg_dev *bcdev, u32 prop_id, int val) int rc; rc = read_property_id(bcdev, pst, USB_ADAP_TYPE); if (rc < 0) if (rc < 0) { pr_err("Failed to read prop USB_ADAP_TYPE, rc=%d\n", rc); return rc; } /* Allow this only for SDP or USB_PD and not for other charger types */ if (pst->prop[USB_ADAP_TYPE] != POWER_SUPPLY_USB_TYPE_SDP && Loading @@ -831,8 +840,12 @@ static int usb_psy_set_icl(struct battery_chg_dev *bcdev, u32 prop_id, int val) temp = UINT_MAX; rc = write_property_id(bcdev, pst, prop_id, temp); if (!rc) if (rc < 0) { pr_err("Failed to set ICL (%u uA) rc=%d\n", temp, rc); } else { pr_debug("Set ICL to %u\n", temp); bcdev->usb_icl_ua = temp; } return rc; } Loading Loading @@ -946,10 +959,12 @@ static int __battery_psy_set_charge_current(struct battery_chg_dev *bcdev, rc = write_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], BATT_CHG_CTRL_LIM, fcc_ua); if (rc < 0) if (rc < 0) { pr_err("Failed to set FCC %u, rc=%d\n", fcc_ua, rc); else } else { pr_debug("Set FCC to %u uA\n", fcc_ua); bcdev->last_fcc_ua = fcc_ua; } return rc; } Loading Loading @@ -1128,6 +1143,38 @@ static int battery_chg_init_psy(struct battery_chg_dev *bcdev) return 0; } static void battery_chg_subsys_up_work(struct work_struct *work) { struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev, subsys_up_work); int rc; battery_chg_notify_enable(bcdev); /* * Give some time after enabling notification so that USB adapter type * information can be obtained properly which is essential for setting * USB ICL. */ msleep(200); if (bcdev->last_fcc_ua) { rc = __battery_psy_set_charge_current(bcdev, bcdev->last_fcc_ua); if (rc < 0) pr_err("Failed to set FCC (%u uA), rc=%d\n", bcdev->last_fcc_ua, rc); } if (bcdev->usb_icl_ua) { rc = usb_psy_set_icl(bcdev, USB_INPUT_CURR_LIMIT, bcdev->usb_icl_ua); if (rc < 0) pr_err("Failed to set ICL(%u uA), rc=%d\n", bcdev->usb_icl_ua, rc); } } static int wireless_fw_send_firmware(struct battery_chg_dev *bcdev, const struct firmware *fw) { Loading Loading @@ -1695,8 +1742,11 @@ static int battery_chg_parse_dt(struct battery_chg_dev *bcdev) len = rc; rc = read_property_id(bcdev, pst, BATT_CHG_CTRL_LIM_MAX); if (rc < 0) if (rc < 0) { pr_err("Failed to read prop BATT_CHG_CTRL_LIM_MAX, rc=%d\n", rc); return rc; } prev = pst->prop[BATT_CHG_CTRL_LIM_MAX]; Loading Loading @@ -1827,13 +1877,16 @@ static int battery_chg_probe(struct platform_device *pdev) return rc; } bcdev->initialized = true; bcdev->reboot_notifier.notifier_call = battery_chg_ship_mode; bcdev->reboot_notifier.priority = 255; register_reboot_notifier(&bcdev->reboot_notifier); rc = battery_chg_parse_dt(bcdev); if (rc < 0) if (rc < 0) { dev_err(dev, "Failed to parse dt rc=%d\n", rc); goto error; } bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA; platform_set_drvdata(pdev, bcdev); Loading @@ -1846,7 +1899,7 @@ static int battery_chg_probe(struct platform_device *pdev) bcdev->battery_class.class_groups = battery_class_groups; rc = class_register(&bcdev->battery_class); if (rc < 0) { pr_err("Failed to create battery_class rc=%d\n", rc); dev_err(dev, "Failed to create battery_class rc=%d\n", rc); goto error; } Loading @@ -1856,6 +1909,8 @@ static int battery_chg_probe(struct platform_device *pdev) return 0; error: bcdev->initialized = false; complete(&bcdev->ack); pmic_glink_unregister_client(bcdev->client); unregister_reboot_notifier(&bcdev->reboot_notifier); return rc; Loading Loading
drivers/power/supply/qti_battery_charger.c +70 −15 Original line number Diff line number Diff line Loading @@ -234,7 +234,11 @@ struct battery_chg_dev { struct notifier_block reboot_notifier; u32 thermal_fcc_ua; u32 restrict_fcc_ua; u32 last_fcc_ua; u32 usb_icl_ua; bool restrict_chg_en; /* To track the driver initialization status */ bool initialized; }; static const int battery_prop_map[BATT_PROP_MAX] = { Loading Loading @@ -421,14 +425,6 @@ static void battery_chg_notify_enable(struct battery_chg_dev *bcdev) pr_err("Failed to enable notification rc=%d\n", rc); } static void battery_chg_subsys_up_work(struct work_struct *work) { struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev, subsys_up_work); battery_chg_notify_enable(bcdev); } static void battery_chg_state_cb(void *priv, enum pmic_glink_state state) { struct battery_chg_dev *bcdev = priv; Loading Loading @@ -636,6 +632,11 @@ static void battery_chg_update_usb_type_work(struct work_struct *work) return; } /* Reset usb_icl_ua whenever USB adapter type changes */ if (pst->prop[USB_ADAP_TYPE] != POWER_SUPPLY_USB_TYPE_SDP && pst->prop[USB_ADAP_TYPE] != POWER_SUPPLY_USB_TYPE_PD) bcdev->usb_icl_ua = 0; pr_debug("usb_adap_type: %u\n", pst->prop[USB_ADAP_TYPE]); switch (pst->prop[USB_ADAP_TYPE]) { Loading Loading @@ -720,6 +721,12 @@ static int battery_chg_callback(void *priv, void *data, size_t len) pr_debug("owner: %u type: %u opcode: %#x len: %zu\n", hdr->owner, hdr->type, hdr->opcode, len); if (!bcdev->initialized) { pr_debug("Driver initialization failed: Dropping glink callback message: state %d\n", bcdev->state); return 0; } if (hdr->opcode == BC_NOTIFY_IND) handle_notification(bcdev, data, len); else Loading Loading @@ -811,8 +818,10 @@ static int usb_psy_set_icl(struct battery_chg_dev *bcdev, u32 prop_id, int val) int rc; rc = read_property_id(bcdev, pst, USB_ADAP_TYPE); if (rc < 0) if (rc < 0) { pr_err("Failed to read prop USB_ADAP_TYPE, rc=%d\n", rc); return rc; } /* Allow this only for SDP or USB_PD and not for other charger types */ if (pst->prop[USB_ADAP_TYPE] != POWER_SUPPLY_USB_TYPE_SDP && Loading @@ -831,8 +840,12 @@ static int usb_psy_set_icl(struct battery_chg_dev *bcdev, u32 prop_id, int val) temp = UINT_MAX; rc = write_property_id(bcdev, pst, prop_id, temp); if (!rc) if (rc < 0) { pr_err("Failed to set ICL (%u uA) rc=%d\n", temp, rc); } else { pr_debug("Set ICL to %u\n", temp); bcdev->usb_icl_ua = temp; } return rc; } Loading Loading @@ -946,10 +959,12 @@ static int __battery_psy_set_charge_current(struct battery_chg_dev *bcdev, rc = write_property_id(bcdev, &bcdev->psy_list[PSY_TYPE_BATTERY], BATT_CHG_CTRL_LIM, fcc_ua); if (rc < 0) if (rc < 0) { pr_err("Failed to set FCC %u, rc=%d\n", fcc_ua, rc); else } else { pr_debug("Set FCC to %u uA\n", fcc_ua); bcdev->last_fcc_ua = fcc_ua; } return rc; } Loading Loading @@ -1128,6 +1143,38 @@ static int battery_chg_init_psy(struct battery_chg_dev *bcdev) return 0; } static void battery_chg_subsys_up_work(struct work_struct *work) { struct battery_chg_dev *bcdev = container_of(work, struct battery_chg_dev, subsys_up_work); int rc; battery_chg_notify_enable(bcdev); /* * Give some time after enabling notification so that USB adapter type * information can be obtained properly which is essential for setting * USB ICL. */ msleep(200); if (bcdev->last_fcc_ua) { rc = __battery_psy_set_charge_current(bcdev, bcdev->last_fcc_ua); if (rc < 0) pr_err("Failed to set FCC (%u uA), rc=%d\n", bcdev->last_fcc_ua, rc); } if (bcdev->usb_icl_ua) { rc = usb_psy_set_icl(bcdev, USB_INPUT_CURR_LIMIT, bcdev->usb_icl_ua); if (rc < 0) pr_err("Failed to set ICL(%u uA), rc=%d\n", bcdev->usb_icl_ua, rc); } } static int wireless_fw_send_firmware(struct battery_chg_dev *bcdev, const struct firmware *fw) { Loading Loading @@ -1695,8 +1742,11 @@ static int battery_chg_parse_dt(struct battery_chg_dev *bcdev) len = rc; rc = read_property_id(bcdev, pst, BATT_CHG_CTRL_LIM_MAX); if (rc < 0) if (rc < 0) { pr_err("Failed to read prop BATT_CHG_CTRL_LIM_MAX, rc=%d\n", rc); return rc; } prev = pst->prop[BATT_CHG_CTRL_LIM_MAX]; Loading Loading @@ -1827,13 +1877,16 @@ static int battery_chg_probe(struct platform_device *pdev) return rc; } bcdev->initialized = true; bcdev->reboot_notifier.notifier_call = battery_chg_ship_mode; bcdev->reboot_notifier.priority = 255; register_reboot_notifier(&bcdev->reboot_notifier); rc = battery_chg_parse_dt(bcdev); if (rc < 0) if (rc < 0) { dev_err(dev, "Failed to parse dt rc=%d\n", rc); goto error; } bcdev->restrict_fcc_ua = DEFAULT_RESTRICT_FCC_UA; platform_set_drvdata(pdev, bcdev); Loading @@ -1846,7 +1899,7 @@ static int battery_chg_probe(struct platform_device *pdev) bcdev->battery_class.class_groups = battery_class_groups; rc = class_register(&bcdev->battery_class); if (rc < 0) { pr_err("Failed to create battery_class rc=%d\n", rc); dev_err(dev, "Failed to create battery_class rc=%d\n", rc); goto error; } Loading @@ -1856,6 +1909,8 @@ static int battery_chg_probe(struct platform_device *pdev) return 0; error: bcdev->initialized = false; complete(&bcdev->ack); pmic_glink_unregister_client(bcdev->client); unregister_reboot_notifier(&bcdev->reboot_notifier); return rc; Loading