1 #define pr_fmt(x) KBUILD_MODNAME ": " x "\n"
2
3 #include <linux/kernel.h>
4 #include <linux/module.h>
5 #include <linux/init.h>
6 #include <linux/slab.h>
7 #include <linux/interrupt.h>
8 #include <linux/device.h>
9 #include <linux/mutex.h>
10 #include <linux/param.h>
11 #include <linux/jiffies.h>
12 #include <linux/platform_device.h>
13 #include <linux/power_supply.h>
14 #include <linux/fs.h>
15 #include <linux/ktime.h>
16 #include <linux/of.h>
17 #include <linux/timekeeping.h>
18 #include <linux/types.h>
19 #include <linux/string.h>
20 #include <asm/irq.h>
21 #include <linux/cdev.h>
22 #include <linux/delay.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/gpio/consumer.h>
25 #include <linux/kthread.h>
26 #include <linux/freezer.h>
27 #include <linux/err.h>
28 #include "power/axp2101.h"
29 #include "axp803_charger.h"
30
31 struct axp803_bat_power {
32 char *name;
33 struct device *dev;
34 struct axp_config_info dts_info;
35 struct regmap *regmap;
36 struct power_supply *bat_supply;
37 struct delayed_work bat_supply_mon;
38 };
39
40 static bool charger_debug;
41
axp803_get_bat_health(struct axp803_bat_power * bat_power)42 static int axp803_get_bat_health(struct axp803_bat_power *bat_power)
43 {
44 unsigned int reg_value;
45 int ret = 0;
46
47 ret = regmap_read(bat_power->regmap, AXP803_MODE_CHGSTATUS, ®_value);
48 if (reg_value & AXP803_FAULT_LOG_BATINACT)
49 return POWER_SUPPLY_HEALTH_DEAD;
50 else if (reg_value & AXP803_FAULT_LOG_OVER_TEMP)
51 return POWER_SUPPLY_HEALTH_OVERHEAT;
52 else if (reg_value & AXP803_FAULT_LOG_COLD)
53 return POWER_SUPPLY_HEALTH_COLD;
54 else
55 return POWER_SUPPLY_HEALTH_GOOD;
56 }
57
axp803_vbat_to_mV(unsigned int reg)58 static inline int axp803_vbat_to_mV(unsigned int reg)
59 {
60 return ((int)(((reg >> 8) << 4) | (reg & 0x000F))) * 1100 / 1000;
61 }
62
axp803_get_vbat(struct axp803_bat_power * bat_power)63 static int axp803_get_vbat(struct axp803_bat_power *bat_power)
64 {
65 unsigned char temp_val[2];
66 unsigned int res;
67 int ret = 0;
68
69 ret = regmap_bulk_read(bat_power->regmap, AXP803_VBATH_RES, temp_val, 2);
70 if (ret < 0)
71 return ret;
72
73 res = (temp_val[0] << 8) | temp_val[1];
74
75 return axp803_vbat_to_mV(res);
76 }
77
axp803_icharge_to_mA(unsigned int reg)78 static inline int axp803_icharge_to_mA(unsigned int reg)
79 {
80 return (int)(((reg >> 8) << 4) | (reg & 0x000F));
81 }
82
axp803_get_ibat(struct axp803_bat_power * bat_power)83 static int axp803_get_ibat(struct axp803_bat_power *bat_power)
84 {
85 unsigned char tmp[2];
86 unsigned int res;
87
88 regmap_bulk_read(bat_power->regmap, AXP803_IBATH_REG, tmp, 2);
89 res = (tmp[0] << 8) | tmp[1];
90
91 return axp803_icharge_to_mA(res);
92 }
93
axp803_get_disibat(struct axp803_bat_power * bat_power)94 static int axp803_get_disibat(struct axp803_bat_power *bat_power)
95 {
96 unsigned char tmp[2];
97 unsigned int dis_res;
98
99 regmap_bulk_read(bat_power->regmap, AXP803_DISIBATH_REG, tmp, 2);
100 dis_res = (tmp[0] << 8) | tmp[1];
101
102 return axp803_icharge_to_mA(dis_res);
103 }
104
axp803_set_bat_chg_cur(struct axp803_bat_power * bat_power,int cur)105 static int axp803_set_bat_chg_cur(struct axp803_bat_power *bat_power, int cur)
106 {
107 uint8_t tmp = 0;
108 struct regmap *map = bat_power->regmap;
109
110 if (cur == 0)
111 regmap_update_bits(map, AXP803_CHARGE1, 0x80, 0x00);
112 else
113 regmap_update_bits(map, AXP803_CHARGE1, 0x80, 0x80);
114
115 if (cur >= 200 && cur <= 2800) {
116 tmp = (cur - 200) / 200;
117 regmap_update_bits(map, AXP803_CHARGE1, 0x0f, tmp);
118 } else if (cur < 200) {
119 regmap_update_bits(map, AXP803_CHARGE1, 0x0f, 0x00);
120 } else {
121 regmap_update_bits(map, AXP803_CHARGE1, 0x0f, 0x0d);
122 }
123
124 return 0;
125 }
126
axp803_get_rest_cap(struct axp803_bat_power * bat_power)127 static int axp803_get_rest_cap(struct axp803_bat_power *bat_power)
128 {
129 unsigned char temp_val[2];
130 unsigned int reg_value;
131 int batt_max_cap, coulumb_counter;
132 int rest_vol = 0;
133 int ocv_vol = 0;
134 int rdc = 0;
135 int ret = 0;
136
137 int charging = 0;
138 int ocv_pct = 0;
139 int coul_pct = 0;
140 int ac_valid = 0;
141 int usb_valid = 0;
142 static int pre_rest_vol, invalid_count;
143
144 struct axp_config_info *axp_config = &bat_power->dts_info;
145
146 ret = regmap_read(bat_power->regmap, AXP803_CAP, ®_value);
147 if (ret)
148 return ret;
149
150 if (reg_value & 0x80) {
151 rest_vol = (int)(reg_value & 0x7F);
152 pre_rest_vol = rest_vol;
153 invalid_count = 0;
154 } else {
155 rest_vol = pre_rest_vol;
156 invalid_count++;
157
158 if (invalid_count == 30) {
159 invalid_count = 0;
160 rest_vol = 100;
161 }
162
163 return rest_vol;
164 }
165
166 /* read chatging status */
167 ret = regmap_read(bat_power->regmap, AXP803_MODE_CHGSTATUS, ®_value);
168 if (ret)
169 return ret;
170 charging = (reg_value & (1 << 6)) ? 1 : 0;
171
172 /* read adaptor valid status */
173 ret = regmap_read(bat_power->regmap, AXP803_STATUS, ®_value);
174 if (ret)
175 return ret;
176 ac_valid = (reg_value & (1 << 6)) ? 1 : 0;
177
178 ret = regmap_read(bat_power->regmap, AXP803_STATUS, ®_value);
179 if (ret)
180 return ret;
181 usb_valid = (reg_value & (1 << 4)) ? 1 : 0;
182
183 /* read ocv percentage */
184 ret = regmap_read(bat_power->regmap, AXP803_OCV_PERCENT, ®_value);
185 if (ret)
186 return ret;
187 if (reg_value & 0x80)
188 ocv_pct = (int)(reg_value & 0x7F);
189
190 /* read coul percentage */
191 ret = regmap_read(bat_power->regmap, AXP803_COU_PERCENT, ®_value);
192 if (ret)
193 return ret;
194 if (reg_value & 0x80)
195 coul_pct = (int)(reg_value & 0x7F);
196
197 if (ocv_pct == 100 && charging == 0 && rest_vol == 99
198 && (ac_valid == 1 || usb_valid == 1)) {
199
200 ret = regmap_read(bat_power->regmap, AXP803_COULOMB_CTL, ®_value);
201 if (ret)
202 return ret;
203 regmap_write(bat_power->regmap, AXP803_COULOMB_CTL, (reg_value & 0x7f));
204 regmap_write(bat_power->regmap, AXP803_COULOMB_CTL, (reg_value | 0x80));
205 rest_vol = 100;
206 }
207 if (ocv_pct == 100 && coul_pct == 100 && axp_config->ocv_coulumb_100 == 1) {
208 rest_vol = 100;
209 }
210
211 ret = regmap_bulk_read(bat_power->regmap, AXP803_COUCNT0, temp_val, 2);
212 if (ret < 0)
213 return ret;
214 coulumb_counter = (((temp_val[0] & 0x7f) << 8) + temp_val[1])
215 * 1456 / 1000;
216
217 ret = regmap_bulk_read(bat_power->regmap, AXP803_BATCAP0, temp_val, 2);
218 if (ret < 0)
219 return ret;
220 batt_max_cap = (((temp_val[0] & 0x7f) << 8) + temp_val[1])
221 * 1456 / 1000;
222
223 if (charger_debug) {
224 ret = regmap_bulk_read(bat_power->regmap, AXP803_OCVBATH_RES, temp_val, 2);
225 if (ret < 0)
226 return ret;
227 ocv_vol = ((temp_val[0] << 4) | (temp_val[1] & 0xF)) * 1100 / 1000;
228
229 ret = regmap_bulk_read(bat_power->regmap, AXP803_RDC0, temp_val, 2);
230 if (ret < 0)
231 return ret;
232 rdc = (((temp_val[0] & 0x1f) << 8) + temp_val[1]) * 10742 / 10000;
233
234 pr_debug("calc_info: ocv_vol:%d rdc:%d coulumb_counter:%d batt_max_cap:%d\n",
235 ocv_vol, rdc, coulumb_counter, batt_max_cap);
236 }
237
238 return rest_vol;
239 }
240
axp_vts_to_mV(u16 reg)241 static inline int axp_vts_to_mV(u16 reg)
242 {
243 return ((int)(((reg >> 8) << 4) | (reg & 0x000F))) * 800 / 1000;
244 }
245
axp_vts_to_temp(int data,const struct axp_config_info * axp_config)246 static inline int axp_vts_to_temp(int data,
247 const struct axp_config_info *axp_config)
248 {
249 int temp;
250
251 if (data < 80 || !axp_config->pmu_bat_temp_enable)
252 return 30;
253 else if (data < axp_config->pmu_bat_temp_para16)
254 return 80;
255 else if (data <= axp_config->pmu_bat_temp_para15) {
256 temp = 70 + (axp_config->pmu_bat_temp_para15-data)*10/
257 (axp_config->pmu_bat_temp_para15-axp_config->pmu_bat_temp_para16);
258 } else if (data <= axp_config->pmu_bat_temp_para14) {
259 temp = 60 + (axp_config->pmu_bat_temp_para14-data)*10/
260 (axp_config->pmu_bat_temp_para14-axp_config->pmu_bat_temp_para15);
261 } else if (data <= axp_config->pmu_bat_temp_para13) {
262 temp = 55 + (axp_config->pmu_bat_temp_para13-data)*5/
263 (axp_config->pmu_bat_temp_para13-axp_config->pmu_bat_temp_para14);
264 } else if (data <= axp_config->pmu_bat_temp_para12) {
265 temp = 50 + (axp_config->pmu_bat_temp_para12-data)*5/
266 (axp_config->pmu_bat_temp_para12-axp_config->pmu_bat_temp_para13);
267 } else if (data <= axp_config->pmu_bat_temp_para11) {
268 temp = 45 + (axp_config->pmu_bat_temp_para11-data)*5/
269 (axp_config->pmu_bat_temp_para11-axp_config->pmu_bat_temp_para12);
270 } else if (data <= axp_config->pmu_bat_temp_para10) {
271 temp = 40 + (axp_config->pmu_bat_temp_para10-data)*5/
272 (axp_config->pmu_bat_temp_para10-axp_config->pmu_bat_temp_para11);
273 } else if (data <= axp_config->pmu_bat_temp_para9) {
274 temp = 30 + (axp_config->pmu_bat_temp_para9-data)*10/
275 (axp_config->pmu_bat_temp_para9-axp_config->pmu_bat_temp_para10);
276 } else if (data <= axp_config->pmu_bat_temp_para8) {
277 temp = 20 + (axp_config->pmu_bat_temp_para8-data)*10/
278 (axp_config->pmu_bat_temp_para8-axp_config->pmu_bat_temp_para9);
279 } else if (data <= axp_config->pmu_bat_temp_para7) {
280 temp = 10 + (axp_config->pmu_bat_temp_para7-data)*10/
281 (axp_config->pmu_bat_temp_para7-axp_config->pmu_bat_temp_para8);
282 } else if (data <= axp_config->pmu_bat_temp_para6) {
283 temp = 5 + (axp_config->pmu_bat_temp_para6-data)*5/
284 (axp_config->pmu_bat_temp_para6-axp_config->pmu_bat_temp_para7);
285 } else if (data <= axp_config->pmu_bat_temp_para5) {
286 temp = 0 + (axp_config->pmu_bat_temp_para5-data)*5/
287 (axp_config->pmu_bat_temp_para5-axp_config->pmu_bat_temp_para6);
288 } else if (data <= axp_config->pmu_bat_temp_para4) {
289 temp = -5 + (axp_config->pmu_bat_temp_para4-data)*5/
290 (axp_config->pmu_bat_temp_para4-axp_config->pmu_bat_temp_para5);
291 } else if (data <= axp_config->pmu_bat_temp_para3) {
292 temp = -10 + (axp_config->pmu_bat_temp_para3-data)*5/
293 (axp_config->pmu_bat_temp_para3-axp_config->pmu_bat_temp_para4);
294 } else if (data <= axp_config->pmu_bat_temp_para2) {
295 temp = -15 + (axp_config->pmu_bat_temp_para2-data)*5/
296 (axp_config->pmu_bat_temp_para2-axp_config->pmu_bat_temp_para3);
297 } else if (data <= axp_config->pmu_bat_temp_para1) {
298 temp = -25 + (axp_config->pmu_bat_temp_para1-data)*10/
299 (axp_config->pmu_bat_temp_para1-axp_config->pmu_bat_temp_para2);
300 } else
301 temp = -25;
302 return temp;
303 }
304
axp803_get_bat_temp(struct axp803_bat_power * bat_power)305 static int axp803_get_bat_temp(struct axp803_bat_power *bat_power)
306 {
307 unsigned char temp_val[2];
308 unsigned short ts_res;
309 int bat_temp_mv, bat_temp;
310 int ret = 0;
311
312 struct axp_config_info *axp_config = &bat_power->dts_info;
313
314 ret = regmap_bulk_read(bat_power->regmap, AXP803_VTS_RES, temp_val, 2);
315 if (ret < 0)
316 return ret;
317
318 ts_res = ((unsigned short) temp_val[0] << 8) | temp_val[1];
319 bat_temp_mv = axp_vts_to_mV(ts_res);
320 bat_temp = axp_vts_to_temp(bat_temp_mv, axp_config);
321
322 pr_debug("bat_temp: %d\n", bat_temp);
323
324 return bat_temp;
325 }
326
axp803_bat_get_max_voltage(struct axp803_bat_power * bat_power)327 static int axp803_bat_get_max_voltage(struct axp803_bat_power *bat_power)
328 {
329 int ret, reg;
330 int val = 0;
331
332 ret = regmap_read(bat_power->regmap, AXP803_CHARGE1, ®);
333 if (ret)
334 return ret;
335
336 switch (reg & AXP803_CHRG_CTRL1_TGT_VOLT) {
337 case AXP803_CHRG_CTRL1_TGT_4_1V:
338 val = 4100000;
339 break;
340 case AXP803_CHRG_CTRL1_TGT_4_15V:
341 val = 4150000;
342 break;
343 case AXP803_CHRG_CTRL1_TGT_4_2V:
344 val = 4200000;
345 break;
346 case AXP803_CHRG_CTRL1_TGT_4_35V:
347 val = 4350000;
348 break;
349 default:
350 return -EINVAL;
351 }
352
353 return val;
354 }
355
axp803_get_bat_status(struct power_supply * psy,union power_supply_propval * val)356 static int axp803_get_bat_status(struct power_supply *psy,
357 union power_supply_propval *val)
358 {
359 bool bat_det, bat_charging;
360 bool ac_valid, vbus_valid;
361 unsigned int rest_vol;
362 unsigned int reg_value;
363 int ret;
364
365 struct axp803_bat_power *bat_power = power_supply_get_drvdata(psy);
366
367 ret = regmap_read(bat_power->regmap, AXP803_MODE_CHGSTATUS, ®_value);
368 if (ret)
369 return ret;
370 bat_det = !!(reg_value & AXP803_CHGSTATUS_BAT_PST_VALID) &&
371 !!(reg_value & AXP803_CHGSTATUS_BAT_PRESENT);
372 bat_charging = !!(reg_value & AXP803_CHGSTATUS_BAT_CHARGING);
373
374 ret = regmap_read(bat_power->regmap, AXP803_STATUS, ®_value);
375 if (ret)
376 return ret;
377 ac_valid = !!(reg_value & AXP803_STATUS_AC_USED);
378 vbus_valid = !!(reg_value & AXP803_STATUS_VBUS_USED);
379
380 rest_vol = axp803_get_rest_cap(bat_power);
381
382 if (ac_valid || vbus_valid) {
383 if (bat_det) {
384 if (rest_vol == 100)
385 val->intval = POWER_SUPPLY_STATUS_FULL;
386 else if (bat_charging)
387 val->intval = POWER_SUPPLY_STATUS_CHARGING;
388 else
389 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
390 } else {
391 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
392 }
393 } else {
394 ret = regmap_read(bat_power->regmap, AXP803_MODE_CHGSTATUS, ®_value);
395 if (ret)
396 return ret;
397 bat_det = !!(reg_value & AXP803_CHGSTATUS_BAT_PRESENT);
398 if (bat_det)
399 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
400 else
401 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
402 }
403
404 return 0;
405 }
406
407 static enum power_supply_property axp803_bat_props[] = {
408 POWER_SUPPLY_PROP_MODEL_NAME,
409 POWER_SUPPLY_PROP_STATUS,
410 POWER_SUPPLY_PROP_PRESENT,
411 POWER_SUPPLY_PROP_ONLINE,
412 POWER_SUPPLY_PROP_HEALTH,
413 POWER_SUPPLY_PROP_TECHNOLOGY,
414 POWER_SUPPLY_PROP_CHARGE_COUNTER,
415 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
416 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
417 POWER_SUPPLY_PROP_VOLTAGE_NOW,
418 POWER_SUPPLY_PROP_CURRENT_NOW,
419 POWER_SUPPLY_PROP_CHARGE_FULL,
420 POWER_SUPPLY_PROP_CAPACITY,
421 POWER_SUPPLY_PROP_TEMP,
422 POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
423 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
424 POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN,
425 POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX,
426 };
427
axp803_bat_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)428 static int axp803_bat_get_property(struct power_supply *psy,
429 enum power_supply_property psp,
430 union power_supply_propval *val)
431 {
432 int ret = 0;
433 unsigned int reg_value;
434 unsigned char temp_val[2];
435 struct axp803_bat_power *bat_power = power_supply_get_drvdata(psy);
436
437 switch (psp) {
438 case POWER_SUPPLY_PROP_MODEL_NAME:
439 val->strval = psy->desc->name;
440 break;
441 case POWER_SUPPLY_PROP_STATUS:
442 ret = axp803_get_bat_status(psy, val);
443 break;
444 case POWER_SUPPLY_PROP_HEALTH:
445 val->intval = axp803_get_bat_health(bat_power);
446 break;
447 case POWER_SUPPLY_PROP_TECHNOLOGY:
448 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
449 break;
450 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
451 ret = regmap_bulk_read(bat_power->regmap, AXP803_COUCNT0, temp_val, 2);
452 if (ret < 0)
453 return ret;
454 val->intval = (((temp_val[0] & 0x7f) << 8) + temp_val[1]) * 1456;
455 break;
456 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
457 val->intval = axp803_bat_get_max_voltage(bat_power);
458 break;
459 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
460 ret = regmap_read(bat_power->regmap, AXP803_VOFF_SET, ®_value);
461 if (ret)
462 return ret;
463 val->intval = 2600000 + 100000 * (reg_value & AXP803_V_OFF_MASK);
464 break;
465 case POWER_SUPPLY_PROP_ONLINE:
466 ret = regmap_read(bat_power->regmap, AXP803_STATUS, ®_value);
467 if (ret)
468 return ret;
469 val->intval = !(reg_value & AXP803_STATUS_BAT_CUR_DIRCT);
470 break;
471 case POWER_SUPPLY_PROP_PRESENT:
472 ret = regmap_read(bat_power->regmap, AXP803_MODE_CHGSTATUS, ®_value);
473 if (ret)
474 return ret;
475 val->intval = (reg_value & AXP803_CHGSTATUS_BAT_PRESENT) >> 5;
476 break;
477 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
478 val->intval = axp803_get_vbat(bat_power) * 1000;
479 break;
480 case POWER_SUPPLY_PROP_CURRENT_NOW:
481 val->intval = (axp803_get_ibat(bat_power)
482 - axp803_get_disibat(bat_power)) * 1000;
483 break;
484 case POWER_SUPPLY_PROP_CHARGE_FULL:
485 ret = regmap_bulk_read(bat_power->regmap, AXP803_BATCAP0, temp_val, 2);
486 if (ret < 0)
487 return ret;
488 val->intval = (((temp_val[0] & 0x7f) << 8) + temp_val[1]) * 1456;
489 break;
490 case POWER_SUPPLY_PROP_CAPACITY:
491 val->intval = axp803_get_rest_cap(bat_power);
492 break;
493 case POWER_SUPPLY_PROP_TEMP:
494 val->intval = axp803_get_bat_temp(bat_power) * 10;
495 break;
496 case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
497 ret = bat_power->dts_info.pmu_bat_shutdown_ltf;
498 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
499 if (!bat_power->dts_info.pmu_bat_temp_enable)
500 val->intval = -200000;
501 break;
502 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
503 ret = bat_power->dts_info.pmu_bat_shutdown_htf;
504 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
505 if (!bat_power->dts_info.pmu_bat_temp_enable)
506 val->intval = 200000;
507 break;
508 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
509 ret = bat_power->dts_info.pmu_bat_charge_ltf;
510 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
511 if (!bat_power->dts_info.pmu_bat_temp_enable)
512 val->intval = -200000;
513 break;
514 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
515 ret = bat_power->dts_info.pmu_bat_charge_htf;
516 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
517 if (!bat_power->dts_info.pmu_bat_temp_enable)
518 val->intval = 200000;
519 break;
520 default:
521 return -EINVAL;
522 }
523 return ret;
524 }
525
526 static const struct power_supply_desc axp803_bat_desc = {
527 .name = "axp803-battery",
528 .type = POWER_SUPPLY_TYPE_BATTERY,
529 .get_property = axp803_bat_get_property,
530 .properties = axp803_bat_props,
531 .num_properties = ARRAY_SIZE(axp803_bat_props),
532 };
533
axp803_bat_power_init(struct axp803_bat_power * bat_power)534 static int axp803_bat_power_init(struct axp803_bat_power *bat_power)
535 {
536 unsigned char ocv_cap[32];
537 unsigned int val;
538 int cur_coulomb_counter, rdc;
539 int rest_pct;
540 int i;
541 int update_min_times[8] = {30, 60, 120, 164, 0, 5, 10, 20};
542 int ocv_cou_adjust_time[4] = {60, 120, 15, 30};
543
544 struct axp_config_info *axp_config = &bat_power->dts_info;
545 struct regmap *map = bat_power->regmap;
546
547 if (axp_config->pmu_init_chgend_rate == 10)
548 val = 0;
549 else
550 val = 1;
551 val <<= 4;
552 regmap_update_bits(map, AXP803_CHARGE1, 0x10, val);
553
554 if (axp_config->pmu_init_chg_pretime < 40)
555 axp_config->pmu_init_chg_pretime = 40;
556
557 if (axp_config->pmu_init_chg_csttime < 360)
558 axp_config->pmu_init_chg_csttime = 360;
559
560 val = ((((axp_config->pmu_init_chg_pretime - 40) / 10) << 6)
561 | ((axp_config->pmu_init_chg_csttime - 360) / 120));
562 regmap_update_bits(map, AXP803_CHARGE2, 0xc2, val);
563
564 /* adc set */
565 val = AXP803_ADC_BATVOL_ENABLE | AXP803_ADC_BATCUR_ENABLE;
566 if (axp_config->pmu_bat_temp_enable != 0)
567 val = val | AXP803_ADC_TSVOL_ENABLE;
568 regmap_update_bits(map, AXP803_ADC_EN,
569 AXP803_ADC_BATVOL_ENABLE
570 | AXP803_ADC_BATCUR_ENABLE
571 | AXP803_ADC_TSVOL_ENABLE,
572 val);
573
574 regmap_read(map, AXP803_ADC_SPEED_SET, &val);
575 switch (axp_config->pmu_init_adc_freq / 100) {
576 case 1:
577 val &= ~(0x3 << 4);
578 break;
579 case 2:
580 val &= ~(0x3 << 4);
581 val |= 0x1 << 4;
582 break;
583 case 4:
584 val &= ~(0x3 << 4);
585 val |= 0x2 << 4;
586 break;
587 case 8:
588 val |= 0x3 << 4;
589 break;
590 default:
591 break;
592 }
593
594 if (axp_config->pmu_bat_temp_enable != 0)
595 val &= (~(0x1 << 2));
596 regmap_write(map, AXP803_ADC_SPEED_SET, val);
597
598 /* bat para */
599 regmap_write(map, AXP803_WARNING_LEVEL,
600 ((axp_config->pmu_battery_warning_level1 - 5) << 4)
601 + axp_config->pmu_battery_warning_level2);
602
603 /* set target voltage */
604 if (axp_config->pmu_init_chgvol < 4150) {
605 val = 0;
606 } else if (axp_config->pmu_init_chgvol < 4200) {
607 val = 1;
608 } else if (axp_config->pmu_init_chgvol < 4350) {
609 val = 2;
610 } else {
611 val = 3;
612 }
613 val <<= 5;
614 regmap_update_bits(map, AXP803_CHARGE1, 0x60, val);
615
616 ocv_cap[0] = axp_config->pmu_bat_para1;
617 ocv_cap[1] = axp_config->pmu_bat_para2;
618 ocv_cap[2] = axp_config->pmu_bat_para3;
619 ocv_cap[3] = axp_config->pmu_bat_para4;
620 ocv_cap[4] = axp_config->pmu_bat_para5;
621 ocv_cap[5] = axp_config->pmu_bat_para6;
622 ocv_cap[6] = axp_config->pmu_bat_para7;
623 ocv_cap[7] = axp_config->pmu_bat_para8;
624 ocv_cap[8] = axp_config->pmu_bat_para9;
625 ocv_cap[9] = axp_config->pmu_bat_para10;
626 ocv_cap[10] = axp_config->pmu_bat_para11;
627 ocv_cap[11] = axp_config->pmu_bat_para12;
628 ocv_cap[12] = axp_config->pmu_bat_para13;
629 ocv_cap[13] = axp_config->pmu_bat_para14;
630 ocv_cap[14] = axp_config->pmu_bat_para15;
631 ocv_cap[15] = axp_config->pmu_bat_para16;
632 ocv_cap[16] = axp_config->pmu_bat_para17;
633 ocv_cap[17] = axp_config->pmu_bat_para18;
634 ocv_cap[18] = axp_config->pmu_bat_para19;
635 ocv_cap[19] = axp_config->pmu_bat_para20;
636 ocv_cap[20] = axp_config->pmu_bat_para21;
637 ocv_cap[21] = axp_config->pmu_bat_para22;
638 ocv_cap[22] = axp_config->pmu_bat_para23;
639 ocv_cap[23] = axp_config->pmu_bat_para24;
640 ocv_cap[24] = axp_config->pmu_bat_para25;
641 ocv_cap[25] = axp_config->pmu_bat_para26;
642 ocv_cap[26] = axp_config->pmu_bat_para27;
643 ocv_cap[27] = axp_config->pmu_bat_para28;
644 ocv_cap[28] = axp_config->pmu_bat_para29;
645 ocv_cap[29] = axp_config->pmu_bat_para30;
646 ocv_cap[30] = axp_config->pmu_bat_para31;
647 ocv_cap[31] = axp_config->pmu_bat_para32;
648 regmap_bulk_write(map, AXP803_OCVCAP, ocv_cap, 32);
649
650 /* Init CHGLED function */
651 if (axp_config->ocv_coulumb_100 == 1) {
652 rest_pct = axp803_get_rest_cap(bat_power);
653 if (rest_pct == 100)
654 regmap_update_bits(map, AXP803_OFF_CTL, 0x08, 0x00); /* disable CHGLED when force 100 */
655 else {
656 if (axp_config->pmu_chgled_func)
657 regmap_update_bits(map, AXP803_OFF_CTL, 0x08, 0x08); /* by charger */
658 else
659 regmap_update_bits(map, AXP803_OFF_CTL, 0x08, 0x00); /* drive MOTO */
660 }
661 } else {
662 if (axp_config->pmu_chgled_func)
663 regmap_update_bits(map, AXP803_OFF_CTL, 0x08, 0x08); /* by charger */
664 else
665 regmap_update_bits(map, AXP803_OFF_CTL, 0x08, 0x00); /* drive MOTO */
666 }
667
668 /* set CHGLED Indication Type */
669 if (axp_config->pmu_chgled_type)
670 regmap_update_bits(map, AXP803_CHARGE2, 0x10, 0x10); /* Type B */
671 else
672 regmap_update_bits(map, AXP803_CHARGE2, 0x10, 0x00); /* Type A */
673
674 /* Init battery capacity correct function */
675 if (axp_config->pmu_batt_cap_correct)
676 regmap_update_bits(map, AXP803_COULOMB_CTL, 0x20, 0x20);
677 else
678 regmap_update_bits(map, AXP803_COULOMB_CTL, 0x20, 0x00);
679
680 /* Init battery regulator enable or not when charge finish */
681 if (axp_config->pmu_chg_end_on_en)
682 regmap_update_bits(map, AXP803_CHARGE2, 0x20, 0x20);
683 else
684 regmap_update_bits(map, AXP803_CHARGE2, 0x20, 0x00);
685
686 if (axp_config->pmu_batdeten)
687 regmap_update_bits(map, AXP803_OFF_CTL, 0x40, 0x40);
688 else
689 regmap_update_bits(map, AXP803_OFF_CTL, 0x40, 0x00);
690
691 /* RDC initial */
692 regmap_read(map, AXP803_RDC0, &val);
693 if ((axp_config->pmu_battery_rdc) && (!(val & 0x40))) {
694 rdc = (axp_config->pmu_battery_rdc * 10000 + 5371) / 10742;
695 regmap_write(map, AXP803_RDC0, ((rdc >> 8) & 0x1F)|0x80);
696 regmap_write(map, AXP803_RDC1, rdc & 0x00FF);
697 }
698
699 regmap_read(map, AXP803_BATCAP0, &val);
700 if ((axp_config->pmu_battery_cap) && (!(val & 0x80))) {
701 cur_coulomb_counter = axp_config->pmu_battery_cap
702 * 1000 / 1456;
703 regmap_write(map, AXP803_BATCAP0, ((cur_coulomb_counter >> 8) | 0x80));
704 regmap_write(map, AXP803_BATCAP1, cur_coulomb_counter & 0x00FF);
705 } else if (!axp_config->pmu_battery_cap) {
706 regmap_write(map, AXP803_BATCAP0, 0x00);
707 regmap_write(map, AXP803_BATCAP1, 0x00);
708 }
709
710 /*
711 * As datasheet decripted:
712 * TS_VOL = reg_value * 16 * 10K * 80ua
713 */
714 if (axp_config->pmu_bat_temp_enable == 1) {
715 regmap_write(map, AXP803_VLTF_CHARGE,
716 axp_config->pmu_bat_charge_ltf * 10 / 128);
717 regmap_write(map, AXP803_VHTF_CHARGE,
718 axp_config->pmu_bat_charge_htf * 10 / 128);
719 regmap_write(map, AXP803_VLTF_WORK,
720 axp_config->pmu_bat_shutdown_ltf * 10 / 128);
721 regmap_write(map, AXP803_VHTF_WORK,
722 axp_config->pmu_bat_shutdown_htf * 10 / 128);
723 }
724
725 if (axp_config->pmu_ocv_en == 0) {
726 pr_warn("axp803 ocv must be enabled\n");
727 axp_config->pmu_ocv_en = 1;
728 }
729 if (axp_config->pmu_init_bc_en == 1) {
730 regmap_update_bits(map, AXP803_BC_CTL, 0x01, 0x01);
731 } else {
732 regmap_update_bits(map, AXP803_BC_CTL, 0x01, 0x00);
733 }
734
735 if (axp_config->pmu_cou_en == 1) {
736 /* use ocv and cou */
737 regmap_update_bits(map, AXP803_COULOMB_CTL, 0x80, 0x80);
738 regmap_update_bits(map, AXP803_COULOMB_CTL, 0x40, 0x40);
739 } else if (axp_config->pmu_cou_en == 0) {
740 /* only use ocv */
741 regmap_update_bits(map, AXP803_COULOMB_CTL, 0x80, 0x80);
742 regmap_update_bits(map, AXP803_COULOMB_CTL, 0x40, 0x00);
743 }
744
745 for (i = 0; i < ARRAY_SIZE(update_min_times); i++) {
746 if (update_min_times[i] == axp_config->pmu_update_min_time)
747 break;
748 }
749 regmap_update_bits(map, AXP803_ADJUST_PARA, 0x07, i);
750 for (i = 0; i < ARRAY_SIZE(ocv_cou_adjust_time); i++) {
751 if (ocv_cou_adjust_time[i] == axp_config->pmu_ocv_cou_adjust_time)
752 break;
753 }
754 i <<= 6;
755 regmap_update_bits(map, AXP803_ADJUST_PARA1, 0xc0, i);
756
757 axp803_set_bat_chg_cur(bat_power, axp_config->pmu_runtime_chgcur);
758
759 return 0;
760 }
761
axp803_bat_power_irq(int irq,void * data)762 static irqreturn_t axp803_bat_power_irq(int irq, void *data)
763 {
764 struct axp803_bat_power *bat_power = data;
765
766 power_supply_changed(bat_power->bat_supply);
767
768 return IRQ_HANDLED;
769 }
770
771 enum axp803_bat_power_virqs {
772 AXP803_VIRQ_CHAST,
773 AXP803_VIRQ_CHAOV,
774 AXP803_VIRQ_BATIN,
775 AXP803_VIRQ_BATRE,
776 AXP803_VIRQ_BATINWORK,
777 AXP803_VIRQ_BATOVWORK,
778 AXP803_VIRQ_BATINCHG,
779 AXP803_VIRQ_BATOVCHG,
780 AXP803_VIRQ_LOWN2,
781 AXP803_VIRQ_LOWN1,
782
783 AXP803_BAT_VIRQ_MAX_VIRQ,
784 };
785
786 static struct axp_interrupts axp803_bat_irq[] = {
787 [AXP803_VIRQ_CHAST] = {"charging", axp803_bat_power_irq},
788 [AXP803_VIRQ_CHAOV] = {"charge over", axp803_bat_power_irq},
789 [AXP803_VIRQ_BATIN] = {"bat in", axp803_bat_power_irq},
790 [AXP803_VIRQ_BATRE] = {"bat out", axp803_bat_power_irq},
791 [AXP803_VIRQ_BATINWORK] = {"bat untemp work", axp803_bat_power_irq},
792 [AXP803_VIRQ_BATOVWORK] = {"bat ovtemp work", axp803_bat_power_irq},
793 [AXP803_VIRQ_BATINCHG] = {"bat untemp chg", axp803_bat_power_irq},
794 [AXP803_VIRQ_BATOVCHG] = {"bat ovtemp chg", axp803_bat_power_irq},
795 [AXP803_VIRQ_LOWN2] = {"low warning2", axp803_bat_power_irq},
796 [AXP803_VIRQ_LOWN1] = {"low warning1", axp803_bat_power_irq},
797 };
798
axp803_bat_power_monitor(struct work_struct * work)799 static void axp803_bat_power_monitor(struct work_struct *work)
800 {
801 int rest_pct;
802 unsigned int reg_value, reg_value1;
803 int ocv_pct, col_pct;
804
805 struct axp803_bat_power *bat_power =
806 container_of(work, typeof(*bat_power), bat_supply_mon.work);
807
808 struct axp_config_info *axp_config = &bat_power->dts_info;
809
810 power_supply_changed(bat_power->bat_supply);
811
812 rest_pct = axp803_get_rest_cap(bat_power);
813
814 /* force CHGLED disable when percentage is 100%, and turn on by else */
815 if (axp_config->ocv_coulumb_100 == 1) {
816 if (rest_pct == 100)
817 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x00); /* disable CHGLED */
818 else {
819 if (axp_config->pmu_chgled_func)
820 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x08); /* by charger */
821 else
822 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x00); /* drive MOTO */
823 }
824 }
825
826 /* force DISCHARGEING when percentage is 100%, and turn on when 99% */
827 regmap_read(bat_power->regmap, AXP803_OCV_PERCENT, ®_value);
828 if (reg_value & 0x80)
829 ocv_pct = (int)(reg_value & 0x7F);
830 else
831 ocv_pct = 0;
832
833 regmap_read(bat_power->regmap, AXP803_COU_PERCENT, ®_value);
834 if (reg_value & 0x80)
835 col_pct = (int)(reg_value & 0x7F);
836 else
837 col_pct = 0;
838
839 regmap_read(bat_power->regmap, AXP803_STATUS, ®_value);
840 reg_value &= 0x24;
841 regmap_read(bat_power->regmap, AXP803_MODE_CHGSTATUS, ®_value1);
842 reg_value1 &= 0x32;
843 if (reg_value == 36 || reg_value == 32 || reg_value == 4) {
844 if (ocv_pct == 100 && col_pct == 100) {
845 rest_pct = 100;
846 regmap_read(bat_power->regmap, AXP803_CAP, ®_value);
847 reg_value &= 0x7F;
848 reg_value |= rest_pct;
849 regmap_write(bat_power->regmap, AXP803_CAP, reg_value); /* rest_pct == 100 */
850 regmap_read(bat_power->regmap, AXP803_OCV_PERCENT, ®_value);
851 reg_value &= 0x7F;
852 reg_value |= 100;
853 regmap_write(bat_power->regmap, AXP803_OCV_PERCENT, reg_value);/* ocv_pct == 100 */
854 regmap_read(bat_power->regmap, AXP803_COU_PERCENT, ®_value);
855 reg_value &= 0x7F;
856 reg_value |= 100;
857 regmap_write(bat_power->regmap, AXP803_COU_PERCENT, reg_value);/* col_pct == 100 */
858 regmap_update_bits(bat_power->regmap, AXP803_CHARGE1, 0x80, 0x00); /* discharge */
859 } else if (rest_pct <= 99) {
860 regmap_update_bits(bat_power->regmap, AXP803_CHARGE1, 0x80, 0x80); /* charge */
861 }
862 } else if (reg_value1) {
863 regmap_update_bits(bat_power->regmap, AXP803_CHARGE1, 0x80, 0x80); /* charge */
864 }
865
866 /* debug info */
867 if (unlikely(axp_debug_mask & AXP_CHG)) {
868
869 unsigned char temp_val[2];
870 unsigned int tmp;
871 unsigned int col_ctl_reg;
872 int ic_temp, vbat, ocv_vol;
873 int charge_ibat, dis_ibat, ibat;
874 int ocv_pct, col_pct;
875 int rdc, batt_max_cap, coulumb_counter;
876 bool bat_cur_dir, usb_det, ac_det, ext_valid;
877
878 regmap_bulk_read(bat_power->regmap, AXP803_INTTEMP, temp_val, 2);
879 tmp = (temp_val[0] << 4) + (temp_val[1] & 0x0F);
880 ic_temp = (int)(tmp * 1063 / 10000 - 2667 / 10);
881
882 vbat = axp803_get_vbat(bat_power);
883
884 charge_ibat = axp803_get_ibat(bat_power);
885 dis_ibat = axp803_get_disibat(bat_power);
886 ibat = charge_ibat - dis_ibat;
887
888 regmap_bulk_read(bat_power->regmap, AXP803_OCVBATH_RES, temp_val, 2);
889 ocv_vol = ((temp_val[0] << 4) | (temp_val[1] & 0xF)) * 1100 / 1000;
890
891 rest_pct = axp803_get_rest_cap(bat_power);
892
893 regmap_read(bat_power->regmap, AXP803_OCV_PERCENT, ®_value);
894 if (reg_value & 0x80)
895 ocv_pct = (int)(reg_value & 0x7F);
896 else
897 ocv_pct = 0;
898
899 regmap_read(bat_power->regmap, AXP803_COU_PERCENT, ®_value);
900 if (reg_value & 0x80)
901 col_pct = (int)(reg_value & 0x7F);
902 else
903 col_pct = 0;
904
905 regmap_bulk_read(bat_power->regmap, AXP803_RDC0, temp_val, 2);
906 rdc = (((temp_val[0] & 0x1f) << 8) + temp_val[1]) * 10742 / 10000;
907
908 regmap_bulk_read(bat_power->regmap, AXP803_BATCAP0, temp_val, 2);
909 batt_max_cap = (((temp_val[0] & 0x7f) << 8) + temp_val[1])
910 * 1456 / 1000;
911
912 regmap_bulk_read(bat_power->regmap, AXP803_COUCNT0, temp_val, 2);
913 coulumb_counter = (((temp_val[0] & 0x7f) << 8) + temp_val[1])
914 * 1456 / 1000;
915
916 regmap_read(bat_power->regmap, AXP803_STATUS, ®_value);
917 bat_cur_dir = (reg_value & 0x04) ? 1 : 0;
918 ac_det = (reg_value & 0x80) ? 1 : 0;
919 usb_det = (reg_value & 0x20) ? 1 : 0;
920 ext_valid = ac_det || usb_det;
921
922 regmap_read(bat_power->regmap, AXP803_COULOMB_CTL, ®_value);
923 col_ctl_reg = reg_value;
924
925 printk("ic_temp = %d\n", ic_temp);
926 printk("vbat = %d\n", vbat);
927 printk("ibat = %d\n", ibat);
928 printk("charge_ibat = %d\n", charge_ibat);
929 printk("dis_ibat = %d\n", dis_ibat);
930 printk("ocv = %d\n", ocv_vol);
931 printk("rest_vol = %d\n", rest_pct);
932 printk("rdc = %d\n", rdc);
933 printk("batt_max_cap = %d\n", batt_max_cap);
934 printk("coulumb_counter = %d\n", coulumb_counter);
935 printk("AXP803_COULOMB_CTL = 0x%x\n", col_ctl_reg);
936 printk("ocv_percentage = %d\n", ocv_pct);
937 printk("col_percentage = %d\n", col_pct);
938 printk("bat_current_direction = %d\n", bat_cur_dir);
939 printk("ext_valid = %d\n", ext_valid);
940 }
941
942 schedule_delayed_work(&bat_power->bat_supply_mon, msecs_to_jiffies(10 * 1000));
943 }
944
axp803_bat_power_dt_parse(struct axp803_bat_power * bat_power)945 static int axp803_bat_power_dt_parse(struct axp803_bat_power *bat_power)
946 {
947 struct axp_config_info *axp_config = &bat_power->dts_info;
948 struct device_node *node = bat_power->dev->of_node;
949
950 if (!of_device_is_available(node)) {
951 pr_err("%s: failed\n", __func__);
952 return -1;
953 }
954
955 AXP_OF_PROP_READ(pmu_battery_rdc, BATRDC);
956 AXP_OF_PROP_READ(pmu_battery_cap, 4000);
957 AXP_OF_PROP_READ(pmu_batdeten, 1);
958 AXP_OF_PROP_READ(pmu_chg_ic_temp, 0);
959 AXP_OF_PROP_READ(pmu_runtime_chgcur, INTCHGCUR / 1000);
960 AXP_OF_PROP_READ(pmu_suspend_chgcur, 1200);
961 AXP_OF_PROP_READ(pmu_shutdown_chgcur, 1200);
962 AXP_OF_PROP_READ(pmu_init_chgvol, INTCHGVOL / 1000);
963 AXP_OF_PROP_READ(pmu_init_chgend_rate, INTCHGENDRATE);
964 AXP_OF_PROP_READ(pmu_init_chg_enabled, 1);
965 AXP_OF_PROP_READ(pmu_init_bc_en, 0);
966 AXP_OF_PROP_READ(pmu_init_adc_freq, INTADCFREQ);
967 AXP_OF_PROP_READ(pmu_init_adcts_freq, INTADCFREQC);
968 AXP_OF_PROP_READ(pmu_init_chg_pretime, INTCHGPRETIME);
969 AXP_OF_PROP_READ(pmu_init_chg_csttime, INTCHGCSTTIME);
970 AXP_OF_PROP_READ(pmu_batt_cap_correct, 1);
971 AXP_OF_PROP_READ(pmu_chg_end_on_en, 0);
972 AXP_OF_PROP_READ(ocv_coulumb_100, 0);
973 AXP_OF_PROP_READ(pmu_bat_para1, OCVREG0);
974 AXP_OF_PROP_READ(pmu_bat_para2, OCVREG1);
975 AXP_OF_PROP_READ(pmu_bat_para3, OCVREG2);
976 AXP_OF_PROP_READ(pmu_bat_para4, OCVREG3);
977 AXP_OF_PROP_READ(pmu_bat_para5, OCVREG4);
978 AXP_OF_PROP_READ(pmu_bat_para6, OCVREG5);
979 AXP_OF_PROP_READ(pmu_bat_para7, OCVREG6);
980 AXP_OF_PROP_READ(pmu_bat_para8, OCVREG7);
981 AXP_OF_PROP_READ(pmu_bat_para9, OCVREG8);
982 AXP_OF_PROP_READ(pmu_bat_para10, OCVREG9);
983 AXP_OF_PROP_READ(pmu_bat_para11, OCVREGA);
984 AXP_OF_PROP_READ(pmu_bat_para12, OCVREGB);
985 AXP_OF_PROP_READ(pmu_bat_para13, OCVREGC);
986 AXP_OF_PROP_READ(pmu_bat_para14, OCVREGD);
987 AXP_OF_PROP_READ(pmu_bat_para15, OCVREGE);
988 AXP_OF_PROP_READ(pmu_bat_para16, OCVREGF);
989 AXP_OF_PROP_READ(pmu_bat_para17, OCVREG10);
990 AXP_OF_PROP_READ(pmu_bat_para18, OCVREG11);
991 AXP_OF_PROP_READ(pmu_bat_para19, OCVREG12);
992 AXP_OF_PROP_READ(pmu_bat_para20, OCVREG13);
993 AXP_OF_PROP_READ(pmu_bat_para21, OCVREG14);
994 AXP_OF_PROP_READ(pmu_bat_para22, OCVREG15);
995 AXP_OF_PROP_READ(pmu_bat_para23, OCVREG16);
996 AXP_OF_PROP_READ(pmu_bat_para24, OCVREG17);
997 AXP_OF_PROP_READ(pmu_bat_para25, OCVREG18);
998 AXP_OF_PROP_READ(pmu_bat_para26, OCVREG19);
999 AXP_OF_PROP_READ(pmu_bat_para27, OCVREG1A);
1000 AXP_OF_PROP_READ(pmu_bat_para28, OCVREG1B);
1001 AXP_OF_PROP_READ(pmu_bat_para29, OCVREG1C);
1002 AXP_OF_PROP_READ(pmu_bat_para30, OCVREG1D);
1003 AXP_OF_PROP_READ(pmu_bat_para31, OCVREG1E);
1004 AXP_OF_PROP_READ(pmu_bat_para32, OCVREG1F);
1005 AXP_OF_PROP_READ(pmu_pwroff_vol, 3300);
1006 AXP_OF_PROP_READ(pmu_pwron_vol, 2900);
1007 AXP_OF_PROP_READ(pmu_battery_warning_level1, 15);
1008 AXP_OF_PROP_READ(pmu_battery_warning_level2, 0);
1009 AXP_OF_PROP_READ(pmu_restvol_adjust_time, 30);
1010 AXP_OF_PROP_READ(pmu_ocv_cou_adjust_time, 60);
1011 AXP_OF_PROP_READ(pmu_chgled_func, 0);
1012 AXP_OF_PROP_READ(pmu_chgled_type, 0);
1013 AXP_OF_PROP_READ(pmu_bat_temp_enable, 0);
1014 AXP_OF_PROP_READ(pmu_bat_charge_ltf, 0xA5);
1015 AXP_OF_PROP_READ(pmu_bat_charge_htf, 0x1F);
1016 AXP_OF_PROP_READ(pmu_bat_shutdown_ltf, 0xFC);
1017 AXP_OF_PROP_READ(pmu_bat_shutdown_htf, 0x16);
1018 AXP_OF_PROP_READ(pmu_bat_temp_para1, 0);
1019 AXP_OF_PROP_READ(pmu_bat_temp_para2, 0);
1020 AXP_OF_PROP_READ(pmu_bat_temp_para3, 0);
1021 AXP_OF_PROP_READ(pmu_bat_temp_para4, 0);
1022 AXP_OF_PROP_READ(pmu_bat_temp_para5, 0);
1023 AXP_OF_PROP_READ(pmu_bat_temp_para6, 0);
1024 AXP_OF_PROP_READ(pmu_bat_temp_para7, 0);
1025 AXP_OF_PROP_READ(pmu_bat_temp_para8, 0);
1026 AXP_OF_PROP_READ(pmu_bat_temp_para9, 0);
1027 AXP_OF_PROP_READ(pmu_bat_temp_para10, 0);
1028 AXP_OF_PROP_READ(pmu_bat_temp_para11, 0);
1029 AXP_OF_PROP_READ(pmu_bat_temp_para12, 0);
1030 AXP_OF_PROP_READ(pmu_bat_temp_para13, 0);
1031 AXP_OF_PROP_READ(pmu_bat_temp_para14, 0);
1032 AXP_OF_PROP_READ(pmu_bat_temp_para15, 0);
1033 AXP_OF_PROP_READ(pmu_bat_temp_para16, 0);
1034 AXP_OF_PROP_READ(pmu_bat_unused, 0);
1035 AXP_OF_PROP_READ(power_start, 0);
1036 AXP_OF_PROP_READ(pmu_ocv_en, 1);
1037 AXP_OF_PROP_READ(pmu_cou_en, 1);
1038 AXP_OF_PROP_READ(pmu_update_min_time, UPDATEMINTIME);
1039
1040 axp_config->wakeup_bat_in =
1041 of_property_read_bool(node, "wakeup_bat_in");
1042 axp_config->wakeup_bat_out =
1043 of_property_read_bool(node, "wakeup_bat_out");
1044 axp_config->wakeup_bat_charging =
1045 of_property_read_bool(node, "wakeup_bat_charging");
1046 axp_config->wakeup_bat_charge_over =
1047 of_property_read_bool(node, "wakeup_bat_charge_over");
1048 axp_config->wakeup_low_warning1 =
1049 of_property_read_bool(node, "wakeup_low_warning1");
1050 axp_config->wakeup_low_warning2 =
1051 of_property_read_bool(node, "wakeup_low_warning2");
1052 axp_config->wakeup_bat_untemp_work =
1053 of_property_read_bool(node, "wakeup_bat_untemp_work");
1054 axp_config->wakeup_bat_ovtemp_work =
1055 of_property_read_bool(node, "wakeup_bat_ovtemp_work");
1056 axp_config->wakeup_untemp_chg =
1057 of_property_read_bool(node, "wakeup_bat_untemp_chg");
1058 axp_config->wakeup_ovtemp_chg =
1059 of_property_read_bool(node, "wakeup_bat_ovtemp_chg");
1060
1061 return 0;
1062 }
1063
axp803_bat_power_probe(struct platform_device * pdev)1064 static int axp803_bat_power_probe(struct platform_device *pdev)
1065 {
1066 struct axp20x_dev *axp_dev = dev_get_drvdata(pdev->dev.parent);
1067 struct power_supply_config psy_cfg = {};
1068 struct axp803_bat_power *bat_power;
1069 int i, irq;
1070 int ret = 0;
1071
1072 if (!axp_dev->irq) {
1073 pr_err("can not register axp803 bat without irq\n");
1074 return -EINVAL;
1075 }
1076
1077 bat_power = devm_kzalloc(&pdev->dev, sizeof(*bat_power), GFP_KERNEL);
1078 if (!bat_power) {
1079 pr_err("axp803 bat power alloc failed\n");
1080 ret = -ENOMEM;
1081 return ret;
1082 }
1083
1084 bat_power->name = "axp803-bat-power";
1085 bat_power->dev = &pdev->dev;
1086 bat_power->regmap = axp_dev->regmap;
1087
1088 platform_set_drvdata(pdev, bat_power);
1089
1090 ret = axp803_bat_power_dt_parse(bat_power);
1091 if (ret) {
1092 pr_err("%s parse device tree err\n", __func__);
1093 ret = -EINVAL;
1094 return ret;
1095 }
1096
1097 ret = axp803_bat_power_init(bat_power);
1098 if (ret < 0) {
1099 pr_err("axp210x init bat fail!\n");
1100 ret = -ENODEV;
1101 return ret;
1102 }
1103
1104 psy_cfg.of_node = pdev->dev.of_node;
1105 psy_cfg.drv_data = bat_power;
1106
1107 bat_power->bat_supply = devm_power_supply_register(bat_power->dev,
1108 &axp803_bat_desc, &psy_cfg);
1109
1110 if (IS_ERR(bat_power->bat_supply)) {
1111 pr_err("axp803 failed to register bat power\n");
1112 ret = PTR_ERR(bat_power->bat_supply);
1113 return ret;
1114 }
1115
1116 for (i = 0; i < ARRAY_SIZE(axp803_bat_irq); i++) {
1117 irq = platform_get_irq_byname(pdev, axp803_bat_irq[i].name);
1118 if (irq < 0) {
1119 dev_warn(&pdev->dev, "No IRQ for %s: %d\n",
1120 axp803_bat_irq[i].name, irq);
1121 continue;
1122 }
1123 irq = regmap_irq_get_virq(axp_dev->regmap_irqc, irq);
1124 ret = devm_request_any_context_irq(&pdev->dev, irq,
1125 axp803_bat_irq[i].isr, 0,
1126 axp803_bat_irq[i].name, bat_power);
1127 if (ret < 0)
1128 dev_warn(&pdev->dev, "Error requesting %s IRQ %d: %d\n",
1129 axp803_bat_irq[i].name, irq, ret);
1130
1131 dev_dbg(&pdev->dev, "Requested %s IRQ %d: %d\n",
1132 axp803_bat_irq[i].name, irq, ret);
1133
1134 /* we use this variable to suspend irq */
1135 axp803_bat_irq[i].irq = irq;
1136 }
1137
1138
1139 INIT_DELAYED_WORK(&bat_power->bat_supply_mon, axp803_bat_power_monitor);
1140 schedule_delayed_work(&bat_power->bat_supply_mon, msecs_to_jiffies(10 * 1000));
1141
1142 return 0;
1143 }
1144
axp803_bat_power_remove(struct platform_device * pdev)1145 static int axp803_bat_power_remove(struct platform_device *pdev)
1146 {
1147 struct axp803_bat_power *bat_power = platform_get_drvdata(pdev);
1148
1149 cancel_delayed_work_sync(&bat_power->bat_supply_mon);
1150
1151 return 0;
1152 }
1153
axp_irq_set(unsigned int irq,bool enable)1154 static inline void axp_irq_set(unsigned int irq, bool enable)
1155 {
1156 if (enable)
1157 enable_irq(irq);
1158 else
1159 disable_irq(irq);
1160 }
1161
axp803_bat_virq_dts_set(struct axp803_bat_power * bat_power,bool enable)1162 static void axp803_bat_virq_dts_set(struct axp803_bat_power *bat_power, bool enable)
1163 {
1164 struct axp_config_info *dts_info = &bat_power->dts_info;
1165
1166 if (!dts_info->wakeup_bat_in)
1167 axp_irq_set(axp803_bat_irq[AXP803_VIRQ_BATIN].irq,
1168 enable);
1169 if (!dts_info->wakeup_bat_out)
1170 axp_irq_set(axp803_bat_irq[AXP803_VIRQ_BATRE].irq,
1171 enable);
1172 if (!dts_info->wakeup_bat_charging)
1173 axp_irq_set(axp803_bat_irq[AXP803_VIRQ_CHAST].irq,
1174 enable);
1175 if (!dts_info->wakeup_bat_charge_over)
1176 axp_irq_set(axp803_bat_irq[AXP803_VIRQ_CHAOV].irq,
1177 enable);
1178 if (!dts_info->wakeup_low_warning1)
1179 axp_irq_set(axp803_bat_irq[AXP803_VIRQ_LOWN1].irq,
1180 enable);
1181 if (!dts_info->wakeup_low_warning2)
1182 axp_irq_set(axp803_bat_irq[AXP803_VIRQ_LOWN2].irq,
1183 enable);
1184 if (!dts_info->wakeup_bat_untemp_work)
1185 axp_irq_set(
1186 axp803_bat_irq[AXP803_VIRQ_BATINWORK].irq,
1187 enable);
1188 if (!dts_info->wakeup_bat_ovtemp_work)
1189 axp_irq_set(
1190 axp803_bat_irq[AXP803_VIRQ_BATOVWORK].irq,
1191 enable);
1192 if (!dts_info->wakeup_untemp_chg)
1193 axp_irq_set(
1194 axp803_bat_irq[AXP803_VIRQ_BATINCHG].irq,
1195 enable);
1196 if (!dts_info->wakeup_ovtemp_chg)
1197 axp_irq_set(
1198 axp803_bat_irq[AXP803_VIRQ_BATOVCHG].irq,
1199 enable);
1200 }
1201
axp803_bat_power_shutdown(struct platform_device * pdev)1202 static void axp803_bat_power_shutdown(struct platform_device *pdev)
1203 {
1204 struct axp803_bat_power *bat_power = platform_get_drvdata(pdev);
1205
1206 axp803_set_bat_chg_cur(bat_power, bat_power->dts_info.pmu_shutdown_chgcur);
1207 }
1208
1209
axp803_bat_power_suspend(struct platform_device * pdev,pm_message_t state)1210 static int axp803_bat_power_suspend(struct platform_device *pdev, pm_message_t state)
1211 {
1212 int rest_pct;
1213
1214 struct axp803_bat_power *bat_power = platform_get_drvdata(pdev);
1215 struct axp_config_info *axp_config = &bat_power->dts_info;
1216
1217 rest_pct = axp803_get_rest_cap(bat_power);
1218
1219 /* force CHGLED disable when percentage is 100%, and turn on by else */
1220 if (axp_config->ocv_coulumb_100 == 1) {
1221 if (rest_pct == 100)
1222 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x00); /* disable CHGLED */
1223 else {
1224 if (axp_config->pmu_chgled_func)
1225 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x08); /* by charger */
1226 else
1227 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x00); /* drive MOTO */
1228 }
1229 }
1230
1231 axp803_set_bat_chg_cur(bat_power, bat_power->dts_info.pmu_suspend_chgcur);
1232
1233 axp803_bat_virq_dts_set(bat_power, false);
1234
1235 return 0;
1236 }
1237
axp803_bat_power_resume(struct platform_device * pdev)1238 static int axp803_bat_power_resume(struct platform_device *pdev)
1239 {
1240 int rest_pct;
1241
1242 struct axp803_bat_power *bat_power = platform_get_drvdata(pdev);
1243 struct axp_config_info *axp_config = &bat_power->dts_info;
1244
1245 power_supply_changed(bat_power->bat_supply);
1246
1247 rest_pct = axp803_get_rest_cap(bat_power);
1248
1249 /* force CHGLED disable when percentage is 100%, and turn on by else */
1250 if (axp_config->ocv_coulumb_100 == 1) {
1251 if (rest_pct == 100)
1252 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x00); /* disable CHGLED */
1253 else {
1254 if (axp_config->pmu_chgled_func)
1255 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x08); /* by charger */
1256 else
1257 regmap_update_bits(bat_power->regmap, AXP803_OFF_CTL, 0x08, 0x00); /* drive MOTO */
1258 }
1259 }
1260
1261 axp803_set_bat_chg_cur(bat_power, bat_power->dts_info.pmu_runtime_chgcur);
1262
1263 axp803_bat_virq_dts_set(bat_power, true);
1264
1265 return 0;
1266 }
1267
1268 static const struct of_device_id axp803_bat_power_match[] = {
1269 {
1270 .compatible = "x-powers,axp803-battery-power-supply",
1271 .data = (void *)AXP803_ID,
1272 }, { /* sentinel */ }
1273 };
1274 MODULE_DEVICE_TABLE(of, axp803_bat_power_match);
1275
1276 static struct platform_driver axp803_bat_power_driver = {
1277 .driver = {
1278 .name = "axp803-battery-power-supply",
1279 .of_match_table = axp803_bat_power_match,
1280 },
1281 .probe = axp803_bat_power_probe,
1282 .remove = axp803_bat_power_remove,
1283 .shutdown = axp803_bat_power_shutdown,
1284 .suspend = axp803_bat_power_suspend,
1285 .resume = axp803_bat_power_resume,
1286 };
1287
1288 module_platform_driver(axp803_bat_power_driver);
1289
1290 MODULE_AUTHOR("wangxiaoliang <wangxiaoliang@x-powers.com>");
1291 MODULE_DESCRIPTION("axp803 bat power driver");
1292 MODULE_LICENSE("GPL");
1293