Skip to content

Commit

Permalink
power: supply: act8945a_charger: Improve state handling
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Fengguang Wu <[email protected]>
Signed-off-by: Sebastian Reichel <[email protected]>
  • Loading branch information
wenyouya authored and sre committed Aug 31, 2016
1 parent 6b021fc commit 1f0ba40
Showing 1 changed file with 70 additions and 16 deletions.
86 changes: 70 additions & 16 deletions drivers/power/supply/act8945a_charger.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -224,14 +267,25 @@ 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) {
dev_err(dev, "no charger of node\n");
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);

Expand Down

0 comments on commit 1f0ba40

Please sign in to comment.