power: pm8921-charger: implement thermal mitigation
Implement thermal mitigation in the charger driver. The userspace
daemon can get the battery temperature from
/sys/class/power_supply/battery/temp
and set the mitigation levels on
/sys/module/pm8921_charger/parameters/thermal_mitigation
The battery driver supports 4 levels [0 through 3]. O being normal
and 3 being extreme thermal mitigation.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index acd7974..98eb5b5 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -3339,6 +3339,13 @@
.keymap_data = &keymap_data_sim,
};
+static int pm8921_therm_mitigation[] = {
+ 1100,
+ 700,
+ 600,
+ 325,
+};
+
static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
.safety_time = 180,
.update_time = 1,
@@ -3349,11 +3356,13 @@
.cool_temp = 10,
.warm_temp = 40,
.temp_check_period = 1,
- .max_bat_chg_current = 400,
+ .max_bat_chg_current = 1100,
.cool_bat_chg_current = 350,
.warm_bat_chg_current = 350,
.cool_bat_voltage = 4100,
.warm_bat_voltage = 4100,
+ .thermal_mitigation = pm8921_therm_mitigation,
+ .thermal_levels = ARRAY_SIZE(pm8921_therm_mitigation),
};
static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 867795b..1b76401 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -198,9 +198,12 @@
int trkl_current;
int weak_current;
int vin_min;
+ int *thermal_mitigation;
+ int thermal_levels;
};
static int charging_disabled;
+static int thermal_mitigation;
static struct pm8921_chg_chip *the_chip;
@@ -1490,6 +1493,47 @@
module_param_call(disabled, set_disable_status_param, param_get_uint,
&charging_disabled, 0644);
+/**
+ * set_thermal_mitigation_level -
+ *
+ * Internal function to control battery charging current to reduce
+ * temperature
+ */
+static int set_therm_mitigation_level(const char *val, struct kernel_param *kp)
+{
+ int ret;
+ struct pm8921_chg_chip *chip = the_chip;
+
+ ret = param_set_int(val, kp);
+ if (ret) {
+ pr_err("error setting value %d\n", ret);
+ return ret;
+ }
+
+ if (!chip) {
+ pr_err("called before init\n");
+ return -EINVAL;
+ }
+
+ if (!chip->thermal_mitigation) {
+ pr_err("no thermal mitigation\n");
+ return -EINVAL;
+ }
+
+ if (thermal_mitigation < 0
+ || thermal_mitigation >= chip->thermal_levels) {
+ pr_err("out of bound level selected\n");
+ return -EINVAL;
+ }
+
+ ret = pm_chg_ibatmax_set(chip,
+ chip->thermal_mitigation[thermal_mitigation]);
+ return ret;
+}
+module_param_call(thermal_mitigation, set_therm_mitigation_level,
+ param_get_uint,
+ &thermal_mitigation, 0644);
+
static void free_irqs(struct pm8921_chg_chip *chip)
{
int i;
@@ -1995,6 +2039,8 @@
chip->trkl_current = pdata->trkl_current;
chip->weak_current = pdata->weak_current;
chip->vin_min = pdata->vin_min;
+ chip->thermal_mitigation = pdata->thermal_mitigation;
+ chip->thermal_levels = pdata->thermal_levels;
rc = pm8921_chg_hw_init(chip);
if (rc) {
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index fa891d8..4b74f85 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -60,6 +60,9 @@
* @vin_min: the input voltage regulation point (mV) - if the
* voltage falls below this, the charger reduces charge
* current or stop charging temporarily
+ * @thermal_mitigation: the array of charge currents to use as temperature
+ * increases
+ * @thermal_levels: the number of thermal mitigation levels supported
*
*/
struct pm8921_charger_platform_data {
@@ -87,6 +90,8 @@
int trkl_current;
int weak_current;
int vin_min;
+ int *thermal_mitigation;
+ int thermal_levels;
};
enum pm8921_charger_source {