OSDN Git Service

smb-lib: account for Jeita while distributing FCC
authorAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Wed, 20 Jul 2016 23:54:55 +0000 (16:54 -0700)
committerAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Wed, 20 Jul 2016 23:54:55 +0000 (16:54 -0700)
The master charger has built in Jeita compensation where it reduces
FCC when the battery is in cool/warm Jeita threshold. This skews
the distribution of FCC between master and slave in parallel
configuration.

Fix this by checking if soft Jeita is active. If so reduce the requested
fcc so that master and slave get reduced share. However, since master
is reducing its FCC, add the reduction again to its share so the net
FCC on master is as per the distribution.

This also calls to handle the battery temperature change interrupt and
redistribute FCC.

Change-Id: I413cc0231a9125422efc71ed67717921af939959
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
drivers/power/qcom-charger/qpnp-smb2.c
drivers/power/qcom-charger/smb-lib.c
drivers/power/qcom-charger/smb-lib.h

index ad00a98..541e40a 100644 (file)
@@ -108,6 +108,13 @@ static struct smb_params v1_params = {
                .max_u  = 3000000,
                .step_u = 25000,
        },
+       .jeita_cc_comp          = {
+               .name   = "jeita fcc reduction",
+               .reg    = JEITA_CCCOMP_CFG_REG,
+               .min_u  = 0,
+               .max_u  = 1575000,
+               .step_u = 25000,
+       },
 };
 
 struct smb_dt_props {
@@ -722,49 +729,49 @@ struct smb2_irq_info {
 
 static struct smb2_irq_info smb2_irqs[] = {
 /* CHARGER IRQs */
-       { "chg-error",                  smblib_handle_debug },
-       { "chg-state-change",           smblib_handle_chg_state_change, true },
-       { "step-chg-state-change",      smblib_handle_debug },
-       { "step-chg-soc-update-fail",   smblib_handle_debug },
+       { "chg-error",                  smblib_handle_debug },
+       { "chg-state-change",           smblib_handle_chg_state_change, true },
+       { "step-chg-state-change",      smblib_handle_debug },
+       { "step-chg-soc-update-fail",   smblib_handle_debug },
        { "step-chg-soc-update-request", smblib_handle_debug },
 /* OTG IRQs */
-       { "otg-fail",                   smblib_handle_debug },
-       { "otg-overcurrent",            smblib_handle_debug },
-       { "otg-oc-dis-sw-sts",          smblib_handle_debug },
-       { "testmode-change-detect",     smblib_handle_debug },
+       { "otg-fail",                   smblib_handle_debug },
+       { "otg-overcurrent",            smblib_handle_debug },
+       { "otg-oc-dis-sw-sts",          smblib_handle_debug },
+       { "testmode-change-detect",     smblib_handle_debug },
 /* BATTERY IRQs */
-       { "bat-temp",                   smblib_handle_batt_psy_changed },
-       { "bat-ocp",                    smblib_handle_batt_psy_changed },
-       { "bat-ov",                     smblib_handle_batt_psy_changed },
-       { "bat-low",                    smblib_handle_batt_psy_changed },
-       { "bat-therm-or-id-missing",    smblib_handle_batt_psy_changed },
-       { "bat-terminal-missing",       smblib_handle_batt_psy_changed },
+       { "bat-temp",                   smblib_handle_batt_temp_changed },
+       { "bat-ocp",                    smblib_handle_batt_psy_changed },
+       { "bat-ov",                     smblib_handle_batt_psy_changed },
+       { "bat-low",                    smblib_handle_batt_psy_changed },
+       { "bat-therm-or-id-missing",    smblib_handle_batt_psy_changed },
+       { "bat-terminal-missing",       smblib_handle_batt_psy_changed },
 /* USB INPUT IRQs */
-       { "usbin-collapse",             smblib_handle_debug },
-       { "usbin-lt-3p6v",              smblib_handle_debug },
-       { "usbin-uv",                   smblib_handle_debug },
-       { "usbin-ov",                   smblib_handle_debug },
-       { "usbin-plugin",               smblib_handle_usb_plugin,       true },
-       { "usbin-src-change",           smblib_handle_usb_source_change, true },
-       { "usbin-icl-change",           smblib_handle_icl_change,       true },
+       { "usbin-collapse",             smblib_handle_debug },
+       { "usbin-lt-3p6v",              smblib_handle_debug },
+       { "usbin-uv",                   smblib_handle_debug },
+       { "usbin-ov",                   smblib_handle_debug },
+       { "usbin-plugin",               smblib_handle_usb_plugin,       true },
+       { "usbin-src-change",           smblib_handle_usb_source_change, true },
+       { "usbin-icl-change",           smblib_handle_icl_change,       true },
        { "type-c-change",              smblib_handle_usb_typec_change, true },
 /* DC INPUT IRQs */
-       { "dcin-collapse",              smblib_handle_debug },
-       { "dcin-lt-3p6v",               smblib_handle_debug },
-       { "dcin-uv",                    smblib_handle_debug },
-       { "dcin-ov",                    smblib_handle_debug },
-       { "dcin-plugin",                smblib_handle_debug },
-       { "div2-en-dg",                 smblib_handle_debug },
-       { "dcin-icl-change",            smblib_handle_debug },
+       { "dcin-collapse",              smblib_handle_debug },
+       { "dcin-lt-3p6v",               smblib_handle_debug },
+       { "dcin-uv",                    smblib_handle_debug },
+       { "dcin-ov",                    smblib_handle_debug },
+       { "dcin-plugin",                smblib_handle_debug },
+       { "div2-en-dg",                 smblib_handle_debug },
+       { "dcin-icl-change",            smblib_handle_debug },
 /* MISCELLANEOUS IRQs */
-       { "wdog-snarl",                 NULL },
-       { "wdog-bark",                  NULL },
-       { "aicl-fail",                  smblib_handle_debug },
-       { "aicl-done",                  smblib_handle_debug },
-       { "high-duty-cycle",            smblib_handle_debug },
-       { "input-current-limiting",     smblib_handle_debug },
-       { "temperature-change",         smblib_handle_debug },
-       { "switcher-power-ok",          smblib_handle_debug },
+       { "wdog-snarl",                 NULL },
+       { "wdog-bark",                  NULL },
+       { "aicl-fail",                  smblib_handle_debug },
+       { "aicl-done",                  smblib_handle_debug },
+       { "high-duty-cycle",            smblib_handle_debug },
+       { "input-current-limiting",     smblib_handle_debug },
+       { "temperature-change",         smblib_handle_debug },
+       { "switcher-power-ok",          smblib_handle_debug },
 };
 
 static int smb2_get_irq_index_byname(const char *irq_name)
index 57919ee..d7776a1 100644 (file)
@@ -85,10 +85,36 @@ unlock:
 static void smblib_fcc_split_ua(struct smb_charger *chg, int total_fcc,
                        int *master_ua, int *slave_ua)
 {
+       int rc, cc_reduction_ua = 0;
        int master_percent = min(max(*chg->pl.master_percent, 0), 100);
+       union power_supply_propval pval = {0, };
+
+       /*
+        * if master_percent is 0, s/w will configure master's fcc to zero and
+        * slave's fcc to the max. However since master's fcc is zero it
+        * disables its own charging and as a result the slave's charging is
+        * disabled via the fault line.
+        */
+
+       rc = smblib_get_prop_batt_health(chg, &pval);
+       if (rc == 0) {
+               if (pval.intval == POWER_SUPPLY_HEALTH_WARM
+                       || pval.intval == POWER_SUPPLY_HEALTH_COOL) {
+                       rc = smblib_get_charge_param(chg,
+                                       &chg->param.jeita_cc_comp,
+                                       &cc_reduction_ua);
+                       if (rc < 0) {
+                               dev_err(chg->dev, "Could not get jeita comp, rc=%d\n",
+                                       rc);
+                               cc_reduction_ua = 0;
+                       }
+               }
+       }
 
+       total_fcc = max(0, total_fcc - cc_reduction_ua);
        *master_ua = (total_fcc * master_percent) / 100;
        *slave_ua = (total_fcc - *master_ua) * chg->pl.taper_percent / 100;
+       *master_ua += cc_reduction_ua;
 }
 
 /********************
@@ -1253,6 +1279,16 @@ irqreturn_t smblib_handle_chg_state_change(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+irqreturn_t smblib_handle_batt_temp_changed(int irq, void *data)
+{
+       struct smb_irq_data *irq_data = data;
+       struct smb_charger *chg = irq_data->parent_data;
+
+       rerun_election(chg->fcc_votable);
+       power_supply_changed(chg->batt_psy);
+       return IRQ_HANDLED;
+}
+
 irqreturn_t smblib_handle_batt_psy_changed(int irq, void *data)
 {
        struct smb_irq_data *irq_data = data;
index 1ee4945..2e35e1e 100644 (file)
@@ -68,6 +68,7 @@ struct smb_params {
        struct smb_chg_param    dc_icl_div2_mid_lv;
        struct smb_chg_param    dc_icl_div2_mid_hv;
        struct smb_chg_param    dc_icl_div2_hv;
+       struct smb_chg_param    jeita_cc_comp;
 };
 
 struct parallel_params {
@@ -150,6 +151,7 @@ int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev);
 
 irqreturn_t smblib_handle_debug(int irq, void *data);
 irqreturn_t smblib_handle_chg_state_change(int irq, void *data);
+irqreturn_t smblib_handle_batt_temp_changed(int irq, void *data);
 irqreturn_t smblib_handle_batt_psy_changed(int irq, void *data);
 irqreturn_t smblib_handle_usb_psy_changed(int irq, void *data);
 irqreturn_t smblib_handle_usb_plugin(int irq, void *data);