summaryrefslogtreecommitdiff
path: root/drivers/power
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2014-03-10 20:35:55 +0530
committerLaxman Dewangan <ldewangan@nvidia.com>2014-03-10 23:30:20 -0700
commit8e7e2cd4a10afd419fb62fa7e5d2ee59d7d4a907 (patch)
tree7175a92e94a0771bd0ec914c03d0d07973c32571 /drivers/power
parentba1f77b23afc102a4c35a1e8a81e9d6a05f65505 (diff)
power: bq2419x: add thermal support for charging voltage
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
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/bq2419x-charger.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/drivers/power/bq2419x-charger.c b/drivers/power/bq2419x-charger.c
index c9bbbeb67cd0..78e3a5719a1a 100644
--- a/drivers/power/bq2419x-charger.c
+++ b/drivers/power/bq2419x-charger.c
@@ -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)
@@ -1287,8 +1319,31 @@ static struct bq2419x_platform_data *bq2419x_dt_parse(struct i2c_client *client)
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: