Loading drivers/power/supply/qcom/battery.c +19 −9 Original line number Diff line number Diff line Loading @@ -930,11 +930,17 @@ static int pl_determine_initial_status(struct pl_data *chip) } #define DEFAULT_RESTRICTED_CURRENT_UA 1000000 static int pl_init(void) int qcom_batt_init(void) { struct pl_data *chip; int rc = 0; /* initialize just once */ if (the_chip) { pr_err("was initialized earlier Failing now\n"); return -EINVAL; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; Loading Loading @@ -1014,7 +1020,9 @@ static int pl_init(void) goto unreg_notifier; } return rc; the_chip = chip; return 0; unreg_notifier: power_supply_unreg_notifier(&chip->nb); Loading @@ -1031,21 +1039,23 @@ cleanup: return rc; } static void pl_deinit(void) void qcom_batt_deinit(void) { struct pl_data *chip = the_chip; if (chip == NULL) return; cancel_work_sync(&chip->status_change_work); cancel_delayed_work_sync(&chip->pl_taper_work); cancel_work_sync(&chip->pl_disable_forever_work); power_supply_unreg_notifier(&chip->nb); destroy_votable(chip->pl_awake_votable); destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); wakeup_source_unregister(chip->pl_ws); the_chip = NULL; kfree(chip); } module_init(pl_init); module_exit(pl_deinit) MODULE_DESCRIPTION(""); MODULE_LICENSE("GPL v2"); drivers/power/supply/qcom/battery.h 0 → 100644 +17 −0 Original line number Diff line number Diff line /* Copyright (c) 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __BATTERY_H #define __BATTERY_H int qcom_batt_init(void); void qcom_batt_deinit(void); #endif /* __BATTERY_H */ drivers/power/supply/qcom/qpnp-smb2.c +1 −1 Original line number Diff line number Diff line Loading @@ -677,7 +677,7 @@ static int smb2_usb_main_get_prop(struct power_supply *psy, rc = smblib_get_prop_fcc_delta(chg, val); break; case POWER_SUPPLY_PROP_CURRENT_MAX: val->intval = get_effective_result(chg->usb_icl_votable); rc = smblib_get_icl_current(chg, &val->intval); break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); Loading drivers/power/supply/qcom/smb-lib.c +118 −12 Original line number Diff line number Diff line Loading @@ -19,10 +19,11 @@ #include <linux/qpnp/qpnp-revid.h> #include <linux/input/qpnp-power-on.h> #include <linux/irq.h> #include <linux/pmic-voter.h> #include "smb-lib.h" #include "smb-reg.h" #include "battery.h" #include "storm-watch.h" #include <linux/pmic-voter.h> #define smblib_err(chg, fmt, ...) \ pr_err("%s: %s: " fmt, chg->name, \ Loading Loading @@ -813,6 +814,28 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) return rc; } static int get_sdp_current(struct smb_charger *chg, int *icl_ua) { int rc; u8 icl_options; bool usb3 = false; rc = smblib_read(chg, USBIN_ICL_OPTIONS_REG, &icl_options); if (rc < 0) { smblib_err(chg, "Couldn't get ICL options rc=%d\n", rc); return rc; } usb3 = (icl_options & CFG_USB3P0_SEL_BIT); if (icl_options & USB51_MODE_BIT) *icl_ua = usb3 ? USBIN_900MA : USBIN_500MA; else *icl_ua = usb3 ? USBIN_150MA : USBIN_100MA; return rc; } int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { int rc = 0; Loading Loading @@ -890,6 +913,48 @@ enable_icl_changed_interrupt: return rc; } int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) { int rc = 0; u8 load_cfg; bool override; union power_supply_propval pval; rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc); return rc; } if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't get SDP ICL rc=%d\n", rc); return rc; } } else { rc = smblib_read(chg, USBIN_LOAD_CFG_REG, &load_cfg); if (rc < 0) { smblib_err(chg, "Couldn't get load cfg rc=%d\n", rc); return rc; } override = load_cfg & ICL_OVERRIDE_AFTER_APSD_BIT; if (!override) return INT_MAX; /* override is set */ rc = smblib_get_charge_param(chg, &chg->param.usb_icl, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't get HC ICL rc=%d\n", rc); return rc; } } return 0; } /********************* * VOTABLE CALLBACKS * *********************/ Loading Loading @@ -3088,12 +3153,28 @@ static void smblib_micro_usb_plugin(struct smb_charger *chg, bool vbus_rising) } } static void smblib_typec_usb_plugin(struct smb_charger *chg, bool vbus_rising) void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) { int rc; u8 stat; bool vbus_rising; rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read USB_INT_RT_STS rc=%d\n", rc); return; } vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); if (vbus_rising) smblib_cc2_sink_removal_exit(chg); else smblib_cc2_sink_removal_enter(chg); power_supply_changed(chg->usb_psy); smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", vbus_rising ? "attached" : "detached"); } #define PL_DELAY_MS 30000 Loading Loading @@ -3152,8 +3233,6 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) if (chg->micro_usb_mode) smblib_micro_usb_plugin(chg, vbus_rising); else smblib_typec_usb_plugin(chg, vbus_rising); power_supply_changed(chg->usb_psy); smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", Loading @@ -3166,6 +3245,9 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data) struct smb_charger *chg = irq_data->parent_data; mutex_lock(&chg->lock); if (chg->pd_hard_reset) smblib_usb_plugin_hard_reset_locked(chg); else smblib_usb_plugin_locked(chg); mutex_unlock(&chg->lock); return IRQ_HANDLED; Loading Loading @@ -4187,26 +4269,30 @@ static int smblib_create_votables(struct smb_charger *chg) int rc = 0; chg->fcc_votable = find_votable("FCC"); if (!chg->fcc_votable) { rc = -EPROBE_DEFER; if (chg->fcc_votable == NULL) { rc = -EINVAL; smblib_err(chg, "Couldn't find FCC votable rc=%d\n", rc); return rc; } chg->fv_votable = find_votable("FV"); if (!chg->fv_votable) { rc = -EPROBE_DEFER; if (chg->fv_votable == NULL) { rc = -EINVAL; smblib_err(chg, "Couldn't find FV votable rc=%d\n", rc); return rc; } chg->usb_icl_votable = find_votable("USB_ICL"); if (!chg->usb_icl_votable) { rc = -EPROBE_DEFER; rc = -EINVAL; smblib_err(chg, "Couldn't find USB_ICL votable rc=%d\n", rc); return rc; } chg->pl_disable_votable = find_votable("PL_DISABLE"); if (!chg->pl_disable_votable) { rc = -EPROBE_DEFER; if (chg->pl_disable_votable == NULL) { rc = -EINVAL; smblib_err(chg, "Couldn't find votable PL_DISABLE rc=%d\n", rc); return rc; } vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); Loading Loading @@ -4390,6 +4476,14 @@ int smblib_init(struct smb_charger *chg) case PARALLEL_MASTER: chg->qnovo_fcc_ua = -EINVAL; chg->qnovo_fv_uv = -EINVAL; rc = qcom_batt_init(); if (rc < 0) { smblib_err(chg, "Couldn't init qcom_batt_init rc=%d\n", rc); return rc; } rc = smblib_create_votables(chg); if (rc < 0) { smblib_err(chg, "Couldn't create votables rc=%d\n", Loading Loading @@ -4421,8 +4515,20 @@ int smblib_deinit(struct smb_charger *chg) { switch (chg->mode) { case PARALLEL_MASTER: cancel_work_sync(&chg->bms_update_work); cancel_work_sync(&chg->rdstd_cc2_detach_work); cancel_delayed_work_sync(&chg->hvdcp_detect_work); cancel_delayed_work_sync(&chg->step_soc_req_work); cancel_delayed_work_sync(&chg->clear_hdc_work); cancel_work_sync(&chg->otg_oc_work); cancel_work_sync(&chg->vconn_oc_work); cancel_delayed_work_sync(&chg->otg_ss_done_work); cancel_delayed_work_sync(&chg->icl_change_work); cancel_delayed_work_sync(&chg->pl_enable_work); cancel_work_sync(&chg->legacy_detection_work); power_supply_unreg_notifier(&chg->nb); smblib_destroy_votables(chg); qcom_batt_deinit(); break; case PARALLEL_SLAVE: break; Loading drivers/power/supply/qcom/smb-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -493,6 +493,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_dp_dm(struct smb_charger *chg, int val); int smblib_rerun_aicl(struct smb_charger *chg); int smblib_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua); int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua); int smblib_init(struct smb_charger *chg); Loading Loading
drivers/power/supply/qcom/battery.c +19 −9 Original line number Diff line number Diff line Loading @@ -930,11 +930,17 @@ static int pl_determine_initial_status(struct pl_data *chip) } #define DEFAULT_RESTRICTED_CURRENT_UA 1000000 static int pl_init(void) int qcom_batt_init(void) { struct pl_data *chip; int rc = 0; /* initialize just once */ if (the_chip) { pr_err("was initialized earlier Failing now\n"); return -EINVAL; } chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; Loading Loading @@ -1014,7 +1020,9 @@ static int pl_init(void) goto unreg_notifier; } return rc; the_chip = chip; return 0; unreg_notifier: power_supply_unreg_notifier(&chip->nb); Loading @@ -1031,21 +1039,23 @@ cleanup: return rc; } static void pl_deinit(void) void qcom_batt_deinit(void) { struct pl_data *chip = the_chip; if (chip == NULL) return; cancel_work_sync(&chip->status_change_work); cancel_delayed_work_sync(&chip->pl_taper_work); cancel_work_sync(&chip->pl_disable_forever_work); power_supply_unreg_notifier(&chip->nb); destroy_votable(chip->pl_awake_votable); destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); wakeup_source_unregister(chip->pl_ws); the_chip = NULL; kfree(chip); } module_init(pl_init); module_exit(pl_deinit) MODULE_DESCRIPTION(""); MODULE_LICENSE("GPL v2");
drivers/power/supply/qcom/battery.h 0 → 100644 +17 −0 Original line number Diff line number Diff line /* Copyright (c) 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __BATTERY_H #define __BATTERY_H int qcom_batt_init(void); void qcom_batt_deinit(void); #endif /* __BATTERY_H */
drivers/power/supply/qcom/qpnp-smb2.c +1 −1 Original line number Diff line number Diff line Loading @@ -677,7 +677,7 @@ static int smb2_usb_main_get_prop(struct power_supply *psy, rc = smblib_get_prop_fcc_delta(chg, val); break; case POWER_SUPPLY_PROP_CURRENT_MAX: val->intval = get_effective_result(chg->usb_icl_votable); rc = smblib_get_icl_current(chg, &val->intval); break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); Loading
drivers/power/supply/qcom/smb-lib.c +118 −12 Original line number Diff line number Diff line Loading @@ -19,10 +19,11 @@ #include <linux/qpnp/qpnp-revid.h> #include <linux/input/qpnp-power-on.h> #include <linux/irq.h> #include <linux/pmic-voter.h> #include "smb-lib.h" #include "smb-reg.h" #include "battery.h" #include "storm-watch.h" #include <linux/pmic-voter.h> #define smblib_err(chg, fmt, ...) \ pr_err("%s: %s: " fmt, chg->name, \ Loading Loading @@ -813,6 +814,28 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) return rc; } static int get_sdp_current(struct smb_charger *chg, int *icl_ua) { int rc; u8 icl_options; bool usb3 = false; rc = smblib_read(chg, USBIN_ICL_OPTIONS_REG, &icl_options); if (rc < 0) { smblib_err(chg, "Couldn't get ICL options rc=%d\n", rc); return rc; } usb3 = (icl_options & CFG_USB3P0_SEL_BIT); if (icl_options & USB51_MODE_BIT) *icl_ua = usb3 ? USBIN_900MA : USBIN_500MA; else *icl_ua = usb3 ? USBIN_150MA : USBIN_100MA; return rc; } int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { int rc = 0; Loading Loading @@ -890,6 +913,48 @@ enable_icl_changed_interrupt: return rc; } int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua) { int rc = 0; u8 load_cfg; bool override; union power_supply_propval pval; rc = smblib_get_prop_typec_mode(chg, &pval); if (rc < 0) { smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc); return rc; } if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || chg->micro_usb_mode) && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { rc = get_sdp_current(chg, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't get SDP ICL rc=%d\n", rc); return rc; } } else { rc = smblib_read(chg, USBIN_LOAD_CFG_REG, &load_cfg); if (rc < 0) { smblib_err(chg, "Couldn't get load cfg rc=%d\n", rc); return rc; } override = load_cfg & ICL_OVERRIDE_AFTER_APSD_BIT; if (!override) return INT_MAX; /* override is set */ rc = smblib_get_charge_param(chg, &chg->param.usb_icl, icl_ua); if (rc < 0) { smblib_err(chg, "Couldn't get HC ICL rc=%d\n", rc); return rc; } } return 0; } /********************* * VOTABLE CALLBACKS * *********************/ Loading Loading @@ -3088,12 +3153,28 @@ static void smblib_micro_usb_plugin(struct smb_charger *chg, bool vbus_rising) } } static void smblib_typec_usb_plugin(struct smb_charger *chg, bool vbus_rising) void smblib_usb_plugin_hard_reset_locked(struct smb_charger *chg) { int rc; u8 stat; bool vbus_rising; rc = smblib_read(chg, USBIN_BASE + INT_RT_STS_OFFSET, &stat); if (rc < 0) { smblib_err(chg, "Couldn't read USB_INT_RT_STS rc=%d\n", rc); return; } vbus_rising = (bool)(stat & USBIN_PLUGIN_RT_STS_BIT); if (vbus_rising) smblib_cc2_sink_removal_exit(chg); else smblib_cc2_sink_removal_enter(chg); power_supply_changed(chg->usb_psy); smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", vbus_rising ? "attached" : "detached"); } #define PL_DELAY_MS 30000 Loading Loading @@ -3152,8 +3233,6 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) if (chg->micro_usb_mode) smblib_micro_usb_plugin(chg, vbus_rising); else smblib_typec_usb_plugin(chg, vbus_rising); power_supply_changed(chg->usb_psy); smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", Loading @@ -3166,6 +3245,9 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data) struct smb_charger *chg = irq_data->parent_data; mutex_lock(&chg->lock); if (chg->pd_hard_reset) smblib_usb_plugin_hard_reset_locked(chg); else smblib_usb_plugin_locked(chg); mutex_unlock(&chg->lock); return IRQ_HANDLED; Loading Loading @@ -4187,26 +4269,30 @@ static int smblib_create_votables(struct smb_charger *chg) int rc = 0; chg->fcc_votable = find_votable("FCC"); if (!chg->fcc_votable) { rc = -EPROBE_DEFER; if (chg->fcc_votable == NULL) { rc = -EINVAL; smblib_err(chg, "Couldn't find FCC votable rc=%d\n", rc); return rc; } chg->fv_votable = find_votable("FV"); if (!chg->fv_votable) { rc = -EPROBE_DEFER; if (chg->fv_votable == NULL) { rc = -EINVAL; smblib_err(chg, "Couldn't find FV votable rc=%d\n", rc); return rc; } chg->usb_icl_votable = find_votable("USB_ICL"); if (!chg->usb_icl_votable) { rc = -EPROBE_DEFER; rc = -EINVAL; smblib_err(chg, "Couldn't find USB_ICL votable rc=%d\n", rc); return rc; } chg->pl_disable_votable = find_votable("PL_DISABLE"); if (!chg->pl_disable_votable) { rc = -EPROBE_DEFER; if (chg->pl_disable_votable == NULL) { rc = -EINVAL; smblib_err(chg, "Couldn't find votable PL_DISABLE rc=%d\n", rc); return rc; } vote(chg->pl_disable_votable, PL_INDIRECT_VOTER, true, 0); Loading Loading @@ -4390,6 +4476,14 @@ int smblib_init(struct smb_charger *chg) case PARALLEL_MASTER: chg->qnovo_fcc_ua = -EINVAL; chg->qnovo_fv_uv = -EINVAL; rc = qcom_batt_init(); if (rc < 0) { smblib_err(chg, "Couldn't init qcom_batt_init rc=%d\n", rc); return rc; } rc = smblib_create_votables(chg); if (rc < 0) { smblib_err(chg, "Couldn't create votables rc=%d\n", Loading Loading @@ -4421,8 +4515,20 @@ int smblib_deinit(struct smb_charger *chg) { switch (chg->mode) { case PARALLEL_MASTER: cancel_work_sync(&chg->bms_update_work); cancel_work_sync(&chg->rdstd_cc2_detach_work); cancel_delayed_work_sync(&chg->hvdcp_detect_work); cancel_delayed_work_sync(&chg->step_soc_req_work); cancel_delayed_work_sync(&chg->clear_hdc_work); cancel_work_sync(&chg->otg_oc_work); cancel_work_sync(&chg->vconn_oc_work); cancel_delayed_work_sync(&chg->otg_ss_done_work); cancel_delayed_work_sync(&chg->icl_change_work); cancel_delayed_work_sync(&chg->pl_enable_work); cancel_work_sync(&chg->legacy_detection_work); power_supply_unreg_notifier(&chg->nb); smblib_destroy_votables(chg); qcom_batt_deinit(); break; case PARALLEL_SLAVE: break; Loading
drivers/power/supply/qcom/smb-lib.h +1 −0 Original line number Diff line number Diff line Loading @@ -493,6 +493,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override); int smblib_dp_dm(struct smb_charger *chg, int val); int smblib_rerun_aicl(struct smb_charger *chg); int smblib_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua); int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua); int smblib_init(struct smb_charger *chg); Loading