aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWenyou Yang <wenyou.yang@atmel.com>2016-08-25 03:19:52 -0400
committerSebastian Reichel <sre@kernel.org>2016-08-31 10:46:54 -0400
commit1f0ba4067af4bda55b7304e74fc20a245912b728 (patch)
tree42ae5b0c2505c18adb90897d87255ef086c235b1
parent6b021fc91038201ed44e99ae32b6a93c6e8be1f4 (diff)
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>
-rw-r--r--drivers/power/supply/act8945a_charger.c86
1 files changed, 70 insertions, 16 deletions
diff --git a/drivers/power/supply/act8945a_charger.c b/drivers/power/supply/act8945a_charger.c
index af006680dd5c..a6bbaff5483e 100644
--- a/drivers/power/supply/act8945a_charger.c
+++ b/drivers/power/supply/act8945a_charger.c
@@ -94,16 +94,24 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val)
94 state &= APCH_STATE_CSTATE; 94 state &= APCH_STATE_CSTATE;
95 state >>= APCH_STATE_CSTATE_SHIFT; 95 state >>= APCH_STATE_CSTATE_SHIFT;
96 96
97 if (state == APCH_STATE_CSTATE_EOC) { 97 switch (state) {
98 case APCH_STATE_CSTATE_PRE:
99 case APCH_STATE_CSTATE_FAST:
100 *val = POWER_SUPPLY_STATUS_CHARGING;
101 break;
102 case APCH_STATE_CSTATE_EOC:
98 if (status & APCH_STATUS_CHGDAT) 103 if (status & APCH_STATUS_CHGDAT)
99 *val = POWER_SUPPLY_STATUS_FULL; 104 *val = POWER_SUPPLY_STATUS_FULL;
100 else 105 else
106 *val = POWER_SUPPLY_STATUS_CHARGING;
107 break;
108 case APCH_STATE_CSTATE_DISABLED:
109 default:
110 if (!(status & APCH_STATUS_INDAT))
111 *val = POWER_SUPPLY_STATUS_DISCHARGING;
112 else
101 *val = POWER_SUPPLY_STATUS_NOT_CHARGING; 113 *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
102 } else if ((state == APCH_STATE_CSTATE_FAST) || 114 break;
103 (state == APCH_STATE_CSTATE_PRE)) {
104 *val = POWER_SUPPLY_STATUS_CHARGING;
105 } else {
106 *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
107 } 115 }
108 116
109 return 0; 117 return 0;
@@ -112,7 +120,11 @@ static int act8945a_get_charger_state(struct regmap *regmap, int *val)
112static int act8945a_get_charge_type(struct regmap *regmap, int *val) 120static int act8945a_get_charge_type(struct regmap *regmap, int *val)
113{ 121{
114 int ret; 122 int ret;
115 unsigned int state; 123 unsigned int status, state;
124
125 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
126 if (ret < 0)
127 return ret;
116 128
117 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state); 129 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
118 if (ret < 0) 130 if (ret < 0)
@@ -129,9 +141,15 @@ static int act8945a_get_charge_type(struct regmap *regmap, int *val)
129 *val = POWER_SUPPLY_CHARGE_TYPE_FAST; 141 *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
130 break; 142 break;
131 case APCH_STATE_CSTATE_EOC: 143 case APCH_STATE_CSTATE_EOC:
144 *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
145 break;
132 case APCH_STATE_CSTATE_DISABLED: 146 case APCH_STATE_CSTATE_DISABLED:
133 default: 147 default:
134 *val = POWER_SUPPLY_CHARGE_TYPE_NONE; 148 if (!(status & APCH_STATUS_INDAT))
149 *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
150 else
151 *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
152 break;
135 } 153 }
136 154
137 return 0; 155 return 0;
@@ -140,20 +158,45 @@ static int act8945a_get_charge_type(struct regmap *regmap, int *val)
140static int act8945a_get_battery_health(struct regmap *regmap, int *val) 158static int act8945a_get_battery_health(struct regmap *regmap, int *val)
141{ 159{
142 int ret; 160 int ret;
143 unsigned int status; 161 unsigned int status, state, config;
144 162
145 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status); 163 ret = regmap_read(regmap, ACT8945A_APCH_STATUS, &status);
146 if (ret < 0) 164 if (ret < 0)
147 return ret; 165 return ret;
148 166
149 if (!(status & APCH_STATUS_TEMPDAT)) 167 ret = regmap_read(regmap, ACT8945A_APCH_CFG, &config);
150 *val = POWER_SUPPLY_HEALTH_OVERHEAT; 168 if (ret < 0)
151 else if (!(status & APCH_STATUS_INDAT)) 169 return ret;
152 *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 170
153 else if (status & APCH_STATUS_TIMRDAT) 171 ret = regmap_read(regmap, ACT8945A_APCH_STATE, &state);
154 *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 172 if (ret < 0)
155 else 173 return ret;
174
175 state &= APCH_STATE_CSTATE;
176 state >>= APCH_STATE_CSTATE_SHIFT;
177
178 switch (state) {
179 case APCH_STATE_CSTATE_DISABLED:
180 if (config & APCH_CFG_SUSCHG) {
181 *val = POWER_SUPPLY_HEALTH_UNKNOWN;
182 } else if (status & APCH_STATUS_INDAT) {
183 if (!(status & APCH_STATUS_TEMPDAT))
184 *val = POWER_SUPPLY_HEALTH_OVERHEAT;
185 else if (status & APCH_STATUS_TIMRDAT)
186 *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
187 else
188 *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
189 } else {
190 *val = POWER_SUPPLY_HEALTH_GOOD;
191 }
192 break;
193 case APCH_STATE_CSTATE_PRE:
194 case APCH_STATE_CSTATE_FAST:
195 case APCH_STATE_CSTATE_EOC:
196 default:
156 *val = POWER_SUPPLY_HEALTH_GOOD; 197 *val = POWER_SUPPLY_HEALTH_GOOD;
198 break;
199 }
157 200
158 return 0; 201 return 0;
159} 202}
@@ -224,7 +267,9 @@ static int act8945a_charger_config(struct device *dev,
224 u32 pre_time_out; 267 u32 pre_time_out;
225 u32 input_voltage_threshold; 268 u32 input_voltage_threshold;
226 int chglev_pin; 269 int chglev_pin;
270 int ret;
227 271
272 unsigned int tmp;
228 unsigned int value = 0; 273 unsigned int value = 0;
229 274
230 if (!np) { 275 if (!np) {
@@ -232,6 +277,15 @@ static int act8945a_charger_config(struct device *dev,
232 return -EINVAL; 277 return -EINVAL;
233 } 278 }
234 279
280 ret = regmap_read(regmap, ACT8945A_APCH_CFG, &tmp);
281 if (ret)
282 return ret;
283
284 if (tmp & APCH_CFG_SUSCHG) {
285 value |= APCH_CFG_SUSCHG;
286 dev_info(dev, "have been suspended\n");
287 }
288
235 chglev_pin = of_get_named_gpio_flags(np, 289 chglev_pin = of_get_named_gpio_flags(np,
236 "active-semi,chglev-gpios", 0, &flags); 290 "active-semi,chglev-gpios", 0, &flags);
237 291