OSDN Git Service

qpnp: smb-lib: move usb_icl_votable to battery library
authorAshay Jaiswal <ashayj@codeaurora.org>
Wed, 22 Mar 2017 17:48:51 +0000 (23:18 +0530)
committerAshay Jaiswal <ashayj@codeaurora.org>
Wed, 5 Apr 2017 04:32:46 +0000 (10:02 +0530)
Move usb_icl_votable creation and it's callback in the
battery.c file, in preparation for an upcoming change where
usb_icl_votable callback will be able to
disable parallel charger when a low input current
request is set.

The new callback uses CURRENT_MAX property to be set on main
psy to set the ICL limit of primary charger.

The limit setting code in main charger path where the votable
call resides currently relies a lot on client being present or not.
Since the votable is being moved away, it won't have information
about the client. So use the current parameter of INT_MAX to
indicate no clients present.

Also it could be that main psy is not instantiated by the time first
icl vote comes in. Ensure that we rerun_election on usb_icl_votable
the instant main psy is seen.

CRs-Fixed: 2014572
Change-Id: Ie449af086ed9218b40ea83158b69e8f8e73edda3
Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
drivers/power/supply/qcom/battery.c
drivers/power/supply/qcom/qpnp-smb2.c
drivers/power/supply/qcom/smb-lib.c
drivers/power/supply/qcom/smb-lib.h

index 0c80c8b..99a5f48 100644 (file)
@@ -49,6 +49,7 @@ struct pl_data {
        struct votable          *pl_disable_votable;
        struct votable          *pl_awake_votable;
        struct votable          *hvdcp_hw_inov_dis_votable;
+       struct votable          *usb_icl_votable;
        struct work_struct      status_change_work;
        struct work_struct      pl_disable_forever_work;
        struct delayed_work     pl_taper_work;
@@ -487,6 +488,25 @@ static int pl_fv_vote_callback(struct votable *votable, void *data,
        return 0;
 }
 
+static int usb_icl_vote_callback(struct votable *votable, void *data,
+                       int icl_ua, const char *client)
+{
+       struct pl_data *chip = data;
+       union power_supply_propval pval = {0, };
+
+       if (!chip->main_psy)
+               return 0;
+
+       if (client == NULL)
+               icl_ua = INT_MAX;
+
+       pval.intval = icl_ua;
+       return power_supply_set_property(chip->main_psy,
+                               POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, &pval);
+
+       return 0;
+}
+
 static void pl_disable_forever_work(struct work_struct *work)
 {
        struct pl_data *chip = container_of(work,
@@ -596,13 +616,15 @@ static int pl_awake_vote_callback(struct votable *votable,
 
 static bool is_main_available(struct pl_data *chip)
 {
-       if (!chip->main_psy)
-               chip->main_psy = power_supply_get_by_name("main");
+       if (chip->main_psy)
+               return true;
 
-       if (!chip->main_psy)
-               return false;
+       chip->main_psy = power_supply_get_by_name("main");
 
-       return true;
+       if (chip->main_psy)
+               rerun_election(chip->usb_icl_votable);
+
+       return !!chip->main_psy;
 }
 
 static bool is_batt_available(struct pl_data *chip)
@@ -855,6 +877,14 @@ static int pl_init(void)
                goto destroy_votable;
        }
 
+       chip->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN,
+                                       usb_icl_vote_callback,
+                                       chip);
+       if (IS_ERR(chip->usb_icl_votable)) {
+               rc = PTR_ERR(chip->usb_icl_votable);
+               goto destroy_votable;
+       }
+
        chip->pl_disable_votable = create_votable("PL_DISABLE", VOTE_SET_ANY,
                                        pl_disable_vote_callback,
                                        chip);
@@ -909,6 +939,7 @@ destroy_votable:
        destroy_votable(chip->pl_disable_votable);
        destroy_votable(chip->fv_votable);
        destroy_votable(chip->fcc_votable);
+       destroy_votable(chip->usb_icl_votable);
 release_wakeup_source:
        wakeup_source_unregister(chip->pl_ws);
 cleanup:
index 0a0f1de..77e21a7 100644 (file)
@@ -616,6 +616,7 @@ static enum power_supply_property smb2_usb_main_props[] = {
        POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
        POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
        POWER_SUPPLY_PROP_FCC_DELTA,
+       POWER_SUPPLY_PROP_CURRENT_MAX,
        /*
         * TODO move the TEMP and TEMP_MAX properties here,
         * and update the thermal balancer to look here
@@ -653,6 +654,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
        case POWER_SUPPLY_PROP_FCC_DELTA:
                rc = smblib_get_prop_fcc_delta(chg, val);
                break;
+       case POWER_SUPPLY_PROP_CURRENT_MAX:
+               val->intval = get_effective_result(chg->usb_icl_votable);
+               break;
        default:
                pr_debug("get prop %d is not supported in usb-main\n", psp);
                rc = -EINVAL;
@@ -683,6 +687,9 @@ static int smb2_usb_main_set_prop(struct power_supply *psy,
        case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
                rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval);
                break;
+       case POWER_SUPPLY_PROP_CURRENT_MAX:
+               rc = smblib_set_icl_current(chg, val->intval);
+               break;
        default:
                pr_err("set prop %d is not supported\n", psp);
                rc = -EINVAL;
index 8c7665e..5e1300c 100644 (file)
@@ -798,29 +798,12 @@ static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count)
        return 0;
 }
 
-/*********************
- * VOTABLE CALLBACKS *
- *********************/
-
-static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
-                       int suspend, const char *client)
-{
-       struct smb_charger *chg = data;
-
-       /* resume input if suspend is invalid */
-       if (suspend < 0)
-               suspend = 0;
-
-       return smblib_set_dc_suspend(chg, (bool)suspend);
-}
-
 #define USBIN_25MA     25000
 #define USBIN_100MA    100000
 #define USBIN_150MA    150000
 #define USBIN_500MA    500000
 #define USBIN_900MA    900000
 
-
 static int set_sdp_current(struct smb_charger *chg, int icl_ua)
 {
        int rc;
@@ -859,20 +842,18 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua)
        return rc;
 }
 
-static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
-                       int icl_ua, const char *client)
+int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
 {
-       struct smb_charger *chg = data;
        int rc = 0;
        bool override;
        union power_supply_propval pval;
 
        /* suspend and return if 25mA or less is requested */
-       if (client && (icl_ua < USBIN_25MA))
+       if (icl_ua < USBIN_25MA)
                return smblib_set_usb_suspend(chg, true);
 
        disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq);
-       if (!client)
+       if (icl_ua == INT_MAX)
                goto override_suspend_config;
 
        rc = smblib_get_prop_typec_mode(chg, &pval);
@@ -901,7 +882,7 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
 override_suspend_config:
        /* determine if override needs to be enforced */
        override = true;
-       if (client == NULL) {
+       if (icl_ua == INT_MAX) {
                /* remove override if no voters - hw defaults is desired */
                override = false;
        } else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
@@ -939,6 +920,22 @@ enable_icl_changed_interrupt:
        return rc;
 }
 
+/*********************
+ * VOTABLE CALLBACKS *
+ *********************/
+
+static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data,
+                       int suspend, const char *client)
+{
+       struct smb_charger *chg = data;
+
+       /* resume input if suspend is invalid */
+       if (suspend < 0)
+               suspend = 0;
+
+       return smblib_set_dc_suspend(chg, (bool)suspend);
+}
+
 static int smblib_dc_icl_vote_callback(struct votable *votable, void *data,
                        int icl_ua, const char *client)
 {
@@ -4217,6 +4214,12 @@ static int smblib_create_votables(struct smb_charger *chg)
                return rc;
        }
 
+       chg->usb_icl_votable = find_votable("USB_ICL");
+       if (!chg->usb_icl_votable) {
+               rc = -EPROBE_DEFER;
+               return rc;
+       }
+
        chg->pl_disable_votable = find_votable("PL_DISABLE");
        if (!chg->pl_disable_votable) {
                rc = -EPROBE_DEFER;
@@ -4233,14 +4236,6 @@ static int smblib_create_votables(struct smb_charger *chg)
                return rc;
        }
 
-       chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN,
-                                       smblib_usb_icl_vote_callback,
-                                       chg);
-       if (IS_ERR(chg->usb_icl_votable)) {
-               rc = PTR_ERR(chg->usb_icl_votable);
-               return rc;
-       }
-
        chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN,
                                        smblib_dc_icl_vote_callback,
                                        chg);
index e3ab3d5..2b09a5b 100644 (file)
@@ -492,6 +492,7 @@ int smblib_icl_override(struct smb_charger *chg, bool override);
 int smblib_set_icl_reduction(struct smb_charger *chg, int reduction_ua);
 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_init(struct smb_charger *chg);
 int smblib_deinit(struct smb_charger *chg);