From eae9df7833c367f963c6666e114e0429e9d1f8f0 Mon Sep 17 00:00:00 2001 From: Abhijeet Dharmapurikar Date: Mon, 24 Apr 2017 13:33:07 -0700 Subject: [PATCH] qpnp-smb2: report main charger's share in its current_max Currently main power supply reports the value of the input current limit set on the usb path. This is incorrect, it should report its own share. When parallel is disabled, it will end up reporting a value close to current limit, rounded by 25mA steps. Note that it should report INT_MAX when there is no limit set on the ICL - the case for hvdcp chargers. CRs-Fixed: 2037898 Change-Id: I9859f3d759644a08c6f762e929c471a41b1cdf8f Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/supply/qcom/qpnp-smb2.c | 2 +- drivers/power/supply/qcom/smb-lib.c | 64 +++++++++++++++++++++++++++ drivers/power/supply/qcom/smb-lib.h | 1 + 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 8855a1c74e0b..ef0da676be3c 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -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); diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 2d33ab502365..d73f45f4714d 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -813,6 +813,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; @@ -890,6 +912,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 * *********************/ diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index b0d84f014b0d..2eeb71662867 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -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);