power: pm8921-charger: config cold/hot threshold
Pmic 8921, has configurable hot and cold battery thresholds as
percent of VREF_THERM. Provide means to configure these via
platform data.
One has to set the config values in the charger platform data defined
in the board file.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 257ad35..109ad4a 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -174,48 +174,50 @@
*
*/
struct pm8921_chg_chip {
- struct device *dev;
- unsigned int usb_present;
- unsigned int dc_present;
- unsigned int usb_charger_current;
- unsigned int max_bat_chg_current;
- unsigned int pmic_chg_irq[PM_CHG_MAX_INTS];
- unsigned int safety_time;
- unsigned int ttrkl_time;
- unsigned int update_time;
- unsigned int max_voltage;
- unsigned int min_voltage;
- unsigned int cool_temp;
- unsigned int warm_temp;
- unsigned int temp_check_period;
- unsigned int cool_bat_chg_current;
- unsigned int warm_bat_chg_current;
- unsigned int cool_bat_voltage;
- unsigned int warm_bat_voltage;
- unsigned int resume_voltage;
- unsigned int term_current;
- unsigned int vbat_channel;
- unsigned int batt_temp_channel;
- unsigned int batt_id_channel;
- struct power_supply usb_psy;
- struct power_supply dc_psy;
- struct power_supply batt_psy;
- struct dentry *dent;
- struct bms_notify bms_notify;
+ struct device *dev;
+ unsigned int usb_present;
+ unsigned int dc_present;
+ unsigned int usb_charger_current;
+ unsigned int max_bat_chg_current;
+ unsigned int pmic_chg_irq[PM_CHG_MAX_INTS];
+ unsigned int safety_time;
+ unsigned int ttrkl_time;
+ unsigned int update_time;
+ unsigned int max_voltage;
+ unsigned int min_voltage;
+ unsigned int cool_temp;
+ unsigned int warm_temp;
+ unsigned int temp_check_period;
+ unsigned int cool_bat_chg_current;
+ unsigned int warm_bat_chg_current;
+ unsigned int cool_bat_voltage;
+ unsigned int warm_bat_voltage;
+ unsigned int resume_voltage;
+ unsigned int term_current;
+ unsigned int vbat_channel;
+ unsigned int batt_temp_channel;
+ unsigned int batt_id_channel;
+ struct power_supply usb_psy;
+ struct power_supply dc_psy;
+ struct power_supply batt_psy;
+ struct dentry *dent;
+ struct bms_notify bms_notify;
DECLARE_BITMAP(enabled_irqs, PM_CHG_MAX_INTS);
- struct work_struct battery_id_valid_work;
- int64_t batt_id_min;
- int64_t batt_id_max;
- int trkl_voltage;
- int weak_voltage;
- int trkl_current;
- int weak_current;
- int vin_min;
- int *thermal_mitigation;
- int thermal_levels;
- struct delayed_work update_heartbeat_work;
- struct delayed_work eoc_work;
- struct wake_lock eoc_wake_lock;
+ struct work_struct battery_id_valid_work;
+ int64_t batt_id_min;
+ int64_t batt_id_max;
+ int trkl_voltage;
+ int weak_voltage;
+ int trkl_current;
+ int weak_current;
+ int vin_min;
+ int *thermal_mitigation;
+ int thermal_levels;
+ struct delayed_work update_heartbeat_work;
+ struct delayed_work eoc_work;
+ struct wake_lock eoc_wake_lock;
+ enum pm8921_chg_cold_thr cold_thr;
+ enum pm8921_chg_hot_thr hot_thr;
};
static int charging_disabled;
@@ -637,6 +639,34 @@
temp);
}
+#define PM8921_CHG_BATT_TEMP_THR_COLD BIT(1)
+#define PM8921_CHG_BATT_TEMP_THR_COLD_SHIFT 1
+static int pm_chg_batt_cold_temp_config(struct pm8921_chg_chip *chip,
+ enum pm8921_chg_cold_thr cold_thr)
+{
+ u8 temp;
+
+ temp = cold_thr << PM8921_CHG_BATT_TEMP_THR_COLD_SHIFT;
+ temp = temp & PM8921_CHG_BATT_TEMP_THR_COLD;
+ return pm_chg_masked_write(chip, CHG_CNTRL_2,
+ PM8921_CHG_BATT_TEMP_THR_COLD,
+ temp);
+}
+
+#define PM8921_CHG_BATT_TEMP_THR_HOT BIT(0)
+#define PM8921_CHG_BATT_TEMP_THR_HOT_SHIFT 0
+static int pm_chg_batt_hot_temp_config(struct pm8921_chg_chip *chip,
+ enum pm8921_chg_hot_thr hot_thr)
+{
+ u8 temp;
+
+ temp = hot_thr << PM8921_CHG_BATT_TEMP_THR_HOT_SHIFT;
+ temp = temp & PM8921_CHG_BATT_TEMP_THR_HOT;
+ return pm_chg_masked_write(chip, CHG_CNTRL_2,
+ PM8921_CHG_BATT_TEMP_THR_HOT,
+ temp);
+}
+
static int64_t read_battery_id(struct pm8921_chg_chip *chip)
{
int rc;
@@ -2097,6 +2127,18 @@
}
}
+ rc = pm_chg_batt_cold_temp_config(chip, chip->cold_thr);
+ if (rc) {
+ pr_err("Failed to set cold config %d rc=%d\n",
+ chip->cold_thr, rc);
+ }
+
+ rc = pm_chg_batt_hot_temp_config(chip, chip->hot_thr);
+ if (rc) {
+ pr_err("Failed to set hot config %d rc=%d\n",
+ chip->hot_thr, rc);
+ }
+
/* Workarounds for die 1.1 and 1.0 */
if (pm8xxx_get_revision(chip->dev->parent) < PM8XXX_REVISION_8921_2p0) {
pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST2, 0xF1);
@@ -2320,6 +2362,9 @@
chip->thermal_mitigation = pdata->thermal_mitigation;
chip->thermal_levels = pdata->thermal_levels;
+ chip->cold_thr = pdata->cold_thr;
+ chip->hot_thr = pdata->hot_thr;
+
rc = pm8921_chg_hw_init(chip);
if (rc) {
pr_err("couldn't init hardware rc=%d\n", rc);
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index 613e57a..9f98656 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -23,6 +23,16 @@
unsigned int batt_id_channel;
};
+enum pm8921_chg_cold_thr {
+ PM_SMBC_BATT_TEMP_COLD_THR__LOW,
+ PM_SMBC_BATT_TEMP_COLD_THR__HIGH
+};
+
+enum pm8921_chg_hot_thr {
+ PM_SMBC_BATT_TEMP_HOT_THR__LOW,
+ PM_SMBC_BATT_TEMP_HOT_THR__HIGH
+};
+
/**
* struct pm8921_charger_platform_data -
* @safety_time: max charging time in minutes
@@ -63,7 +73,14 @@
* @thermal_mitigation: the array of charge currents to use as temperature
* increases
* @thermal_levels: the number of thermal mitigation levels supported
- *
+ * @cold_thr: if high battery will be cold when VBAT_THERM goes above
+ * 80% of VREF_THERM (typically 1.8volts), if low the
+ * battery will be considered cold if VBAT_THERM goes above
+ * 70% of VREF_THERM. Hardware defaults to low.
+ * @hot_thr: if high the battery will be considered hot when the
+ * VBAT_THERM goes below 35% of VREF_THERM, if low the
+ * battery will be considered hot when VBAT_THERM goes
+ * below 25% of VREF_THERM. Hardware defaults to low.
*/
struct pm8921_charger_platform_data {
struct pm8xxx_charger_core_data charger_cdata;
@@ -92,6 +109,8 @@
int vin_min;
int *thermal_mitigation;
int thermal_levels;
+ enum pm8921_chg_cold_thr cold_thr;
+ enum pm8921_chg_hot_thr hot_thr;
};
enum pm8921_charger_source {