]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
power: bq2419x: configure input voltage when charger cable connected
authorVenkat Reddy Talla <vreddytalla@nvidia.com>
Thu, 11 Sep 2014 04:50:54 +0000 (10:20 +0530)
committerDhiren Parmar <dparmar@nvidia.com>
Thu, 9 Oct 2014 07:26:47 +0000 (00:26 -0700)
configure input voltage limit based on battery soc immediately
after connecting charger cable to device.

Bug 1516392

Change-Id: I6e365abf58cf66c7993836194ac49edb5f7ea90f
Signed-off-by: Venkat Reddy Talla <vreddytalla@nvidia.com>
Reviewed-on: http://git-master/r/542719
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
drivers/power/battery-charger-gauge-comm.c
drivers/power/bq2419x-charger.c
include/linux/power/battery-charger-gauge-comm.h

index 2bb4a8cbb1bf03ae3d7a9052694e505666e9b749..04440b85bfe1ee1b25b282d674666599d014165a 100644 (file)
@@ -349,6 +349,28 @@ int battery_gauge_record_snapshot_values(struct battery_gauge_dev *bg_dev,
 }
 EXPORT_SYMBOL_GPL(battery_gauge_record_snapshot_values);
 
+int battery_gauge_get_battery_soc(struct battery_charger_dev *bc_dev)
+{
+       struct battery_gauge_dev *bg_dev;
+       int ret = 0;
+
+       if (!bc_dev)
+               return -EINVAL;
+
+       mutex_lock(&charger_gauge_list_mutex);
+
+       list_for_each_entry(bg_dev, &gauge_list, list) {
+               if (bg_dev->cell_id != bc_dev->cell_id)
+                       continue;
+               if (bg_dev->ops && bg_dev->ops->get_battery_soc)
+                       ret = bg_dev->ops->get_battery_soc(bg_dev);
+       }
+
+       mutex_unlock(&charger_gauge_list_mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(battery_gauge_get_battery_soc);
+
 int battery_gauge_report_battery_soc(struct battery_gauge_dev *bg_dev,
                                        int battery_soc)
 {
index 2559e98c27ee4f3b2491dea0417e87c083f1e6ca..f6f0367773752a11c10109ba54fa40e89bb4002f 100644 (file)
@@ -404,12 +404,60 @@ static int bq2419x_disable_otg_mode(struct bq2419x_chip *bq2419x)
        return ret;
 }
 
+static int bq2419x_charger_input_voltage_configure(
+               struct battery_charger_dev *bc_dev, int battery_soc)
+{
+       struct bq2419x_chip *bq2419x = battery_charger_get_drvdata(bc_dev);
+       struct bq2419x_charger_platform_data *chg_pdata;
+       u32 input_voltage_limit = 0;
+       int ret;
+       int i;
+       int vreg;
+
+       chg_pdata = bq2419x->charger_pdata;
+       if (!bq2419x->cable_connected || !chg_pdata->n_soc_profile)
+               return 0;
+
+       for (i = 0; i < chg_pdata->n_soc_profile; ++i) {
+               if (battery_soc < chg_pdata->soc_range[i]) {
+                       if (chg_pdata->input_voltage_soc_limit)
+                               input_voltage_limit =
+                                       chg_pdata->input_voltage_soc_limit[i];
+                       break;
+               }
+       }
+
+       if (!input_voltage_limit)
+               return 0;
+
+       /*Configure input voltage limit */
+       vreg = bq2419x_val_to_reg(input_voltage_limit,
+                       BQ2419X_INPUT_VINDPM_OFFSET, 80, 4, 0);
+       if (bq2419x->last_input_voltage == vreg)
+               return 0;
+
+       dev_info(bq2419x->dev, "Changing VINDPM to soc:voltage:vreg %d:%d:%d\n",
+                       battery_soc, input_voltage_limit, vreg);
+
+       ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
+                               BQ2419X_INPUT_VINDPM_MASK,
+                               (vreg << 3));
+       if (ret < 0) {
+               dev_err(bq2419x->dev, "INPUT_VOLTAGE update failed %d\n", ret);
+               return ret;
+       }
+       bq2419x->last_input_voltage = vreg;
+
+       return 0;
+}
+
 static int bq2419x_configure_charging_current(struct bq2419x_chip *bq2419x,
        int in_current_limit)
 {
        int val = 0;
        int ret = 0;
        int floor = 0;
+       int battery_soc = 0;
 
        /* Clear EN_HIZ */
        if (!bq2419x->emulate_input_disconnected) {
@@ -446,6 +494,14 @@ static int bq2419x_configure_charging_current(struct bq2419x_chip *bq2419x,
                udelay(BQ2419x_CHARGING_CURRENT_STEP_DELAY_US);
        }
        bq2419x->in_current_limit = in_current_limit;
+
+       if (bq2419x->charger_pdata->n_soc_profile) {
+               battery_soc = battery_gauge_get_battery_soc(bq2419x->bc_dev);
+               if (battery_soc > 0)
+                       bq2419x_charger_input_voltage_configure(
+                               bq2419x->bc_dev, battery_soc);
+       }
+
        return ret;
 }
 
@@ -1379,54 +1435,6 @@ static int bq2419x_charging_restart(struct battery_charger_dev *bc_dev)
        return ret;
 }
 
-static int bq2419x_charger_input_voltage_configure(
-               struct battery_charger_dev *bc_dev, int battery_soc)
-{
-       struct bq2419x_chip *bq2419x = battery_charger_get_drvdata(bc_dev);
-       struct bq2419x_charger_platform_data *chg_pdata;
-       u32 input_voltage_limit = 0;
-       int ret;
-       int i;
-       int vreg;
-
-       chg_pdata = bq2419x->charger_pdata;
-       if (!bq2419x->cable_connected || !chg_pdata->n_soc_profile)
-               return 0;
-
-       for (i = 0; i < chg_pdata->n_soc_profile; ++i) {
-               if (battery_soc <= chg_pdata->soc_range[i]) {
-                       if (chg_pdata->input_voltage_soc_limit)
-                               input_voltage_limit =
-                                       chg_pdata->input_voltage_soc_limit[i];
-                       break;
-               }
-       }
-
-       if (!input_voltage_limit)
-               return 0;
-
-
-       /*Configure input voltage limit */
-       vreg = bq2419x_val_to_reg(input_voltage_limit,
-                       BQ2419X_INPUT_VINDPM_OFFSET, 80, 4, 0);
-       if (bq2419x->last_input_voltage == vreg)
-               return 0;
-
-       dev_info(bq2419x->dev, "Changing VINDPM to soc:voltage:vreg %d:%d:%d\n",
-                       battery_soc, input_voltage_limit, vreg);
-
-       ret = regmap_update_bits(bq2419x->regmap, BQ2419X_INPUT_SRC_REG,
-                               BQ2419X_INPUT_VINDPM_MASK,
-                               (vreg << 3));
-       if (ret < 0) {
-               dev_err(bq2419x->dev, "INPUT_VOLTAGE update failed %d\n", ret);
-               return ret;
-       }
-       bq2419x->last_input_voltage = vreg;
-
-       return 0;
-}
-
 static struct battery_charging_ops bq2419x_charger_bci_ops = {
        .get_charging_status = bq2419x_charger_get_status,
        .restart_charging = bq2419x_charging_restart,
index cf0df7c4c2c843c2d1db62f2e976c3405389566e..931cd43b6ca2b9c0f9df059081b5f0569f10a2f0 100644 (file)
@@ -40,6 +40,7 @@ struct battery_gauge_ops {
                                enum battery_charger_status status);
        int (*set_current_broadcast) (struct battery_gauge_dev *bg_device);
        int (*get_battery_temp)(void);
+       int (*get_battery_soc)(struct battery_gauge_dev *bg_device);
 };
 
 struct battery_charging_ops {
@@ -112,5 +113,6 @@ int battery_gauge_get_adjusted_soc(struct battery_gauge_dev *bg_dev,
                int min_soc, int max_soc, int actual_soc_semi);
 int battery_gauge_report_battery_soc(struct battery_gauge_dev *bg_dev,
                int battery_soc);
+int battery_gauge_get_battery_soc(struct battery_charger_dev *bc_dev);
 
 #endif /* _LINUX_POWER_BATTERY_CHARGER_GAUGE_COMM_H */