mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
power: supply: act8945a_charger: Improve state handling
When get the property, first check the charger state machine, then check the status bit to decide what value is assigned to the corresponding property. Retain the SUSCHG bit of REG 0x71 when configure the timers to avoid losting the charger suspending info after boot. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Sebastian Reichel <sre@kernel.org>
This commit is contained in:
parent
6b021fc910
commit
1f0ba4067a
@ -94,16 +94,24 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val)
|
||||
state &= APCH_STATE_CSTATE;
|
||||
state >>= APCH_STATE_CSTATE_SHIFT;
|
||||
|
||||
if (state == APCH_STATE_CSTATE_EOC) {
|
||||
switch (state) {
|
||||
case APCH_STATE_CSTATE_PRE:
|
||||
case APCH_STATE_CSTATE_FAST:
|
||||
*val = POWER_SUPPLY_STATUS_CHARGING;
|
||||
break;
|
||||
case APCH_STATE_CSTATE_EOC:
|
||||
if (status & APCH_STATUS_CHGDAT)
|
||||
*val = POWER_SUPPLY_STATUS_FULL;
|
||||
else
|
||||
*val = POWER_SUPPLY_STATUS_CHARGING;
|
||||
break;
|
||||
case APCH_STATE_CSTATE_DISABLED:
|
||||
default:
|
||||
if (!(status & APCH_STATUS_INDAT))
|
||||
*val = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
else
|
||||
*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
} else if ((state == APCH_STATE_CSTATE_FAST) ||
|
||||
(state == APCH_STATE_CSTATE_PRE)) {
|
||||
*val = POWER_SUPPLY_STATUS_CHARGING;
|
||||
} else {
|
||||
*val = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -112,7 +120,11 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val)
|
||||
static int act8945a_get_charge_type(struct regmap *regmap, int *val)
|
||||
{
|
||||
int ret;
|
||||
unsigned int state;
|
||||
unsigned int status, state;
|
||||
|
||||
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
|
||||
if (ret < 0)
|
||||
@ -129,9 +141,15 @@ static int act8945a_get_charge_type(struct regmap *regmap, int *val)
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_FAST;
|
||||
break;
|
||||
case APCH_STATE_CSTATE_EOC:
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
|
||||
break;
|
||||
case APCH_STATE_CSTATE_DISABLED:
|
||||
default:
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
|
||||
if (!(status & APCH_STATUS_INDAT))
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_NONE;
|
||||
else
|
||||
*val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -140,20 +158,45 @@ static int act8945a_get_charge_type(struct regmap *regmap, int *val)
|
||||
static int act8945a_get_battery_health(struct regmap *regmap, int *val)
|
||||
{
|
||||
int ret;
|
||||
unsigned int status;
|
||||
unsigned int status, state, config;
|
||||
|
||||
ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (!(status & APCH_STATUS_TEMPDAT))
|
||||
*val = POWER_SUPPLY_HEALTH_OVERHEAT;
|
||||
else if (!(status & APCH_STATUS_INDAT))
|
||||
*val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
|
||||
else if (status & APCH_STATUS_TIMRDAT)
|
||||
*val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
|
||||
else
|
||||
ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
state &= APCH_STATE_CSTATE;
|
||||
state >>= APCH_STATE_CSTATE_SHIFT;
|
||||
|
||||
switch (state) {
|
||||
case APCH_STATE_CSTATE_DISABLED:
|
||||
if (config & APCH_CFG_SUSCHG) {
|
||||
*val = POWER_SUPPLY_HEALTH_UNKNOWN;
|
||||
} else if (status & APCH_STATUS_INDAT) {
|
||||
if (!(status & APCH_STATUS_TEMPDAT))
|
||||
*val = POWER_SUPPLY_HEALTH_OVERHEAT;
|
||||
else if (status & APCH_STATUS_TIMRDAT)
|
||||
*val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
|
||||
else
|
||||
*val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
|
||||
} else {
|
||||
*val = POWER_SUPPLY_HEALTH_GOOD;
|
||||
}
|
||||
break;
|
||||
case APCH_STATE_CSTATE_PRE:
|
||||
case APCH_STATE_CSTATE_FAST:
|
||||
case APCH_STATE_CSTATE_EOC:
|
||||
default:
|
||||
*val = POWER_SUPPLY_HEALTH_GOOD;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -224,7 +267,9 @@ static int act8945a_charger_config(struct device *dev,
|
||||
u32 pre_time_out;
|
||||
u32 input_voltage_threshold;
|
||||
int chglev_pin;
|
||||
int ret;
|
||||
|
||||
unsigned int tmp;
|
||||
unsigned int value = 0;
|
||||
|
||||
if (!np) {
|
||||
@ -232,6 +277,15 @@ static int act8945a_charger_config(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_read(regmap, ACT8945A_APCH_CFG, &tmp);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (tmp & APCH_CFG_SUSCHG) {
|
||||
value |= APCH_CFG_SUSCHG;
|
||||
dev_info(dev, "have been suspended\n");
|
||||
}
|
||||
|
||||
chglev_pin = of_get_named_gpio_flags(np,
|
||||
"active-semi,chglev-gpios", 0, &flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user