]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
power: bq2419x: add thermal support for charging voltage
authorLaxman Dewangan <ldewangan@nvidia.com>
Mon, 10 Mar 2014 15:05:55 +0000 (20:35 +0530)
committerLaxman Dewangan <ldewangan@nvidia.com>
Tue, 11 Mar 2014 06:30:20 +0000 (23:30 -0700)
The maximum charging voltage depends on the battery temperature.
Add DT porperty and mechanims to set different charging voltage
for different temperature.

bug 1472161

Change-Id: Ia6fa3ee84cfd1f9ad8359e8249ffb268330f90cf
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/379575
GVS: Gerrit_Virtual_Submit

Documentation/devicetree/bindings/power/bq2419x-charger.txt
drivers/power/bq2419x-charger.c
include/linux/power/bq2419x-charger.h

index b47812c66097bb3d35c52d4987199570955ea8af..71816ce693e761bbf2a6db1ccd173d386d7225e5 100644 (file)
@@ -27,12 +27,19 @@ Optional properties:
                             will be disabled.
 - rtc-alarm-time          : Time setting in seconds for the rtc alarm timer
                             which wakes the board up for charging after shutdown.
+
 - ti,temp-range: List of temperatures in degC for thermal profiling.
 - ti,charge-current-limit: List of fast charging current limit in mA for
                thermal profiling.
-       The value is provided as
+               this property is deprecated. Instead use the property name as
+               ti,charge-thermal-current-limit.
+- ti,charge-thermal-voltage-limit: List of charging voltage limit in mV for
+               thermal profiling.
+
+       The values are provided as
        ti,temp-range = <15 60>;
        ti,charge-current-limit = <2048 5200>;
+       ti,charge-thermal-voltage-limit = <4200 4300>;
 
        This will set chargign current limit to
                2048 for <= 15 degC and
index c9bbbeb67cd0cc8edb91f73c0b7f59f7f8d20f02..78e3a5719a1a0a1299a962ef808b453317561225 100644 (file)
@@ -1065,10 +1065,11 @@ static int bq2419x_charger_thermal_configure(
        struct bq2419x_chip *bq2419x = battery_charger_get_drvdata(bc_dev);
        struct bq2419x_charger_platform_data *chg_pdata;
        int fast_charge_current = 0;
+       u32 charge_voltage_limit = 0;
        int ichg;
        int ret;
        int i;
-       int curr_ichg;
+       int curr_ichg, vreg;
 
        chg_pdata = bq2419x->charger_pdata;
        if (!bq2419x->cable_connected || !chg_pdata->n_temp_profile)
@@ -1084,6 +1085,9 @@ static int bq2419x_charger_thermal_configure(
        for (i = 0; i < chg_pdata->n_temp_profile; ++i) {
                if (temp <= chg_pdata->temp_range[i]) {
                        fast_charge_current = chg_pdata->chg_current_limit[i];
+                       if (chg_pdata->chg_thermal_voltage_limit)
+                               charge_voltage_limit =
+                                       chg_pdata->chg_thermal_voltage_limit[i];
                        break;
                }
        }
@@ -1109,6 +1113,23 @@ static int bq2419x_charger_thermal_configure(
                dev_err(bq2419x->dev, "CHRG_CTRL_REG update failed %d\n", ret);
                return ret;
        }
+
+       if (!charge_voltage_limit)
+               return 0;
+
+       /* Charge voltage limit */
+       vreg = bq2419x_val_to_reg(charge_voltage_limit,
+                       BQ2419X_CHARGE_VOLTAGE_OFFSET, 16, 6, 1);
+       bq2419x->chg_voltage_control.mask = BQ2419X_CHG_VOLT_LIMIT_MASK;
+       bq2419x->chg_voltage_control.val = vreg << 2;
+       ret = regmap_update_bits(bq2419x->regmap, BQ2419X_VOLT_CTRL_REG,
+                               bq2419x->chg_voltage_control.mask,
+                               bq2419x->chg_voltage_control.val);
+       if (ret < 0) {
+               dev_err(bq2419x->dev, "VOLT_CTRL_REG update failed %d\n", ret);
+               return ret;
+       }
+
        return 0;
 }
 
@@ -1159,7 +1180,7 @@ static struct bq2419x_platform_data *bq2419x_dt_parse(struct i2c_client *client)
 
        batt_reg_node = of_find_node_by_name(np, "charger");
        if (batt_reg_node) {
-               int temp_range_len, chg_current_lim_len;
+               int temp_range_len, chg_current_lim_len, chg_voltage_lim_len;
                int wdt_timeout;
                int chg_restart_time;
                int temp_polling_time;
@@ -1258,6 +1279,11 @@ static struct bq2419x_platform_data *bq2419x_dt_parse(struct i2c_client *client)
                                        "ti,temp-range");
                chg_current_lim_len = of_property_count_u32(batt_reg_node,
                                        "ti,charge-current-limit");
+               if (!chg_current_lim_len)
+                       chg_current_lim_len = of_property_count_u32(batt_reg_node,
+                                       "ti,charge-thermal-current-limit");
+               chg_voltage_lim_len = of_property_count_u32(batt_reg_node,
+                                       "ti,charge-thermal-voltage-limit");
                if (temp_range_len < 0)
                        goto skip_therm_profile;
 
@@ -1267,6 +1293,12 @@ static struct bq2419x_platform_data *bq2419x_dt_parse(struct i2c_client *client)
                        goto skip_therm_profile;
                }
 
+               if (chg_voltage_lim_len && (temp_range_len != chg_voltage_lim_len)) {
+                       dev_info(&client->dev,
+                               "thermal profile data is not correct\n");
+                       goto skip_therm_profile;
+               }
+
                chg_pdata->temp_range = devm_kzalloc(&client->dev,
                                sizeof(u32) * temp_range_len, GFP_KERNEL);
                if (!chg_pdata->temp_range)
@@ -1286,9 +1318,32 @@ static struct bq2419x_platform_data *bq2419x_dt_parse(struct i2c_client *client)
                                "ti,charge-current-limit",
                                chg_pdata->chg_current_limit,
                                temp_range_len);
+               if (ret < 0)
+                       ret = of_property_read_u32_array(batt_reg_node,
+                               "ti,charge-thermal-current-limit",
+                                       chg_pdata->chg_current_limit,
+                                       temp_range_len);
+               if (ret < 0)
+                       return ERR_PTR(ret);
+
+               if (!chg_voltage_lim_len)
+                       goto skip_thermal_volt_profle;
+
+               chg_pdata->chg_thermal_voltage_limit =
+                                       devm_kzalloc(&client->dev,
+                                       sizeof(u32) * temp_range_len,
+                                       GFP_KERNEL);
+               if (!chg_pdata->chg_thermal_voltage_limit)
+                       return ERR_PTR(-ENOMEM);
+
+               ret = of_property_read_u32_array(batt_reg_node,
+                               "ti,charge-thermal-voltage-limit",
+                               chg_pdata->chg_thermal_voltage_limit,
+                               temp_range_len);
                if (ret < 0)
                        return ERR_PTR(ret);
 
+skip_thermal_volt_profle:
                chg_pdata->n_temp_profile = temp_range_len;
 
 skip_therm_profile:
index 19de230058f37b7039d57f1d733b139470ec830e..128d2a1e74c113bf76d2312bb2bb06c3868b53ad 100644 (file)
@@ -148,6 +148,7 @@ struct bq2419x_charger_platform_data {
        int n_temp_profile;
        u32 *temp_range;
        u32 *chg_current_limit;
+       u32 *chg_thermal_voltage_limit;
 };
 
 /*