qpnp-fg-gen3: add support to configure and handle delta battery temperature

Battery temperature delta configuration can be used to know the
battery temperature change. There is an interrupt associated
with this configuration which can be used to update the battery
health of the device.

Change-Id: Ic55b9bb34ac9912f88dab6a11ec365814b525ca2
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
Subbaraman Narayanamurthy 2016-09-26 11:27:24 -07:00
parent 03451c8892
commit 21005fbb17
3 changed files with 72 additions and 0 deletions

View file

@ -210,6 +210,12 @@ First Level Node - FG Gen3 device
0 - No hysteresis
1,2,3 - Value in Celsius.
- qcom,fg-batt-temp-delta
Usage: optional
Value type: <u32>
Definition: Battery temperature delta interrupt threshold. Possible
values are: 2, 4, 6 and 10. Unit is in Kelvin.
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================

View file

@ -194,6 +194,7 @@ struct fg_dt_props {
int cl_max_cap_limit;
int cl_min_cap_limit;
int jeita_hyst_temp;
int batt_temp_delta;
};
/* parameters from battery profile */
@ -261,6 +262,8 @@ struct fg_chip {
int status;
int charge_done;
int last_soc;
int last_batt_temp;
int health;
bool profile_available;
bool profile_loaded;
bool battery_missing;

View file

@ -771,6 +771,27 @@ static inline void get_temp_setpoint(int threshold, u8 *val)
*val = DIV_ROUND_CLOSEST((threshold + 30) * 10, 5);
}
static inline void get_batt_temp_delta(int delta, u8 *val)
{
switch (delta) {
case 2:
*val = BTEMP_DELTA_2K;
break;
case 4:
*val = BTEMP_DELTA_4K;
break;
case 6:
*val = BTEMP_DELTA_6K;
break;
case 10:
*val = BTEMP_DELTA_10K;
break;
default:
*val = BTEMP_DELTA_2K;
break;
};
}
static int fg_set_esr_timer(struct fg_chip *chip, int cycles, bool charging,
int flags)
{
@ -1849,6 +1870,14 @@ static int fg_hw_init(struct fg_chip *chip)
}
}
get_batt_temp_delta(chip->dt.batt_temp_delta, &val);
rc = fg_masked_write(chip, BATT_INFO_BATT_TMPR_INTR(chip),
CHANGE_THOLD_MASK, val);
if (rc < 0) {
pr_err("Error in writing batt_temp_delta, rc=%d\n", rc);
return rc;
}
return 0;
}
@ -1902,8 +1931,33 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
{
struct fg_chip *chip = data;
union power_supply_propval prop = {0, };
int rc, batt_temp;
fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
rc = fg_get_battery_temp(chip, &batt_temp);
if (rc < 0) {
pr_err("Error in getting batt_temp\n");
return IRQ_HANDLED;
}
if (!is_charger_available(chip)) {
chip->last_batt_temp = batt_temp;
return IRQ_HANDLED;
}
power_supply_get_property(chip->batt_psy, POWER_SUPPLY_PROP_HEALTH,
&prop);
chip->health = prop.intval;
if (chip->last_batt_temp != batt_temp) {
chip->last_batt_temp = batt_temp;
power_supply_changed(chip->batt_psy);
}
if (abs(chip->last_batt_temp - batt_temp) > 30)
pr_warn("Battery temperature last:%d current: %d\n",
chip->last_batt_temp, batt_temp);
return IRQ_HANDLED;
}
@ -2013,6 +2067,7 @@ static struct fg_irq_info fg_irqs[FG_IRQ_MAX] = {
[BATT_TEMP_DELTA_IRQ] = {
.name = "batt-temp-delta",
.handler = fg_delta_batt_temp_irq_handler,
.wakeable = true,
},
[BATT_MISSING_IRQ] = {
.name = "batt-missing",
@ -2116,6 +2171,8 @@ static int fg_register_interrupts(struct fg_chip *chip)
#define DEFAULT_CL_MAX_DEC_DECIPERC 100
#define DEFAULT_CL_MIN_LIM_DECIPERC 0
#define DEFAULT_CL_MAX_LIM_DECIPERC 0
#define BTEMP_DELTA_LOW 2
#define BTEMP_DELTA_HIGH 10
static int fg_parse_dt(struct fg_chip *chip)
{
struct device_node *child, *revid_node, *node = chip->dev->of_node;
@ -2353,6 +2410,12 @@ static int fg_parse_dt(struct fg_chip *chip)
else
chip->dt.jeita_hyst_temp = temp;
rc = of_property_read_u32(node, "qcom,fg-batt-temp-delta", &temp);
if (rc < 0)
chip->dt.batt_temp_delta = -EINVAL;
else if (temp > BTEMP_DELTA_LOW && temp <= BTEMP_DELTA_HIGH)
chip->dt.batt_temp_delta = temp;
return 0;
}