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/irq.h"
7 #include <linux/slab.h>
8 #include <linux/interrupt.h>
9 #include <linux/device.h>
10 #include <linux/mutex.h>
11 #include <linux/param.h>
12 #include <linux/jiffies.h>
13 #include <linux/platform_device.h>
14 #include <linux/power_supply.h>
15 #include <linux/fs.h>
16 #include <linux/kernel.h>
17 #include <linux/ktime.h>
18 #include <linux/of.h>
19 #include <linux/timekeeping.h>
20 #include <linux/types.h>
21 #include <linux/string.h>
22 #include <asm/irq.h>
23 #include <linux/cdev.h>
24 #include <linux/delay.h>
25 #include <linux/pm_runtime.h>
26 #include <linux/kthread.h>
27 #include <linux/freezer.h>
28 #include <linux/err.h>
29 #include "power/axp2101.h"
30
31 #include <linux/err.h>
32 #include "axp2202_charger.h"
33
34
35 struct axp2202_bat_power {
36 char *name;
37 struct device *dev;
38 struct regmap *regmap;
39 struct power_supply *bat_supply;
40 struct delayed_work bat_supply_mon;
41 struct axp_config_info dts_info;
42 };
43
44 static enum power_supply_property axp2202_bat_props[] = {
45 POWER_SUPPLY_PROP_PRESENT,
46 POWER_SUPPLY_PROP_VOLTAGE_NOW,
47 POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
48 POWER_SUPPLY_PROP_STATUS,
49 POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN,
50 POWER_SUPPLY_PROP_TEMP,
51 POWER_SUPPLY_PROP_CAPACITY,
52 POWER_SUPPLY_PROP_TEMP_ALERT_MIN,
53 POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
54 POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN,
55 POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX,
56 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
57 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
58 POWER_SUPPLY_PROP_MANUFACTURER,
59 POWER_SUPPLY_PROP_CAPACITY_LEVEL,
60 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
61 POWER_SUPPLY_PROP_HEALTH,
62 POWER_SUPPLY_PROP_CHARGE_COUNTER,
63 POWER_SUPPLY_PROP_CHARGE_FULL,
64 };
65
axp2202_get_vbat_vol(struct power_supply * ps,union power_supply_propval * val)66 static int axp2202_get_vbat_vol(struct power_supply *ps,
67 union power_supply_propval *val)
68 {
69 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
70 struct regmap *regmap = bat_power->regmap;
71 uint8_t data[2];
72 uint16_t vtemp[3], tempv;
73 int ret = 0;
74 uint8_t i;
75
76 for (i = 0; i < 3; i++) {
77 ret = regmap_bulk_read(regmap, AXP2202_VBAT_H, data, 2);
78 if (ret < 0)
79 return ret;
80
81 vtemp[i] = (((data[0] & GENMASK(5, 0)) << 0x08) | (data[1]));
82 }
83 if (vtemp[0] > vtemp[1]) {
84 tempv = vtemp[0];
85 vtemp[0] = vtemp[1];
86 vtemp[1] = tempv;
87 }
88 if (vtemp[1] > vtemp[2]) {
89 tempv = vtemp[1];
90 vtemp[1] = vtemp[2];
91 vtemp[2] = tempv;
92 }
93 if (vtemp[0] > vtemp[1]) {
94 tempv = vtemp[0];
95 vtemp[0] = vtemp[1];
96 vtemp[1] = tempv;
97 } /* Why three times? */
98 /*incase vtemp[1] exceed AXP2202_VBAT_MAX */
99 if ((vtemp[1] > AXP2202_VBAT_MAX) || (vtemp[1] < AXP2202_VBAT_MIN)) {
100 val->intval = 0;
101 return 0;
102 }
103
104 val->intval = vtemp[1] * 1000;
105
106 return 0;
107 }
108
axp2202_get_bat_health(struct power_supply * ps,union power_supply_propval * val)109 static int axp2202_get_bat_health(struct power_supply *ps,
110 union power_supply_propval *val)
111 {
112 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
113 struct regmap *regmap = bat_power->regmap;
114
115 unsigned int reg_value, reg_value2;
116 int ret = 0;
117
118 ret = regmap_read(regmap, AXP2202_COMM_STAT0, ®_value);
119 ret = regmap_read(regmap, AXP2202_COMM_FAULT, ®_value2);
120
121 if (reg_value & AXP2202_MASK_BAT_STAT) {
122 if (reg_value & AXP2202_MASK_BAT_ACT_STAT)
123 val->intval = POWER_SUPPLY_HEALTH_DEAD;
124 else if (reg_value2 & AXP2202_MASK_BAT_WOT)
125 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
126 else if (reg_value2 & AXP2202_MASK_BAT_WUT)
127 val->intval = POWER_SUPPLY_HEALTH_COLD;
128 else
129 val->intval = POWER_SUPPLY_HEALTH_GOOD;
130 } else {
131 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
132 }
133 return val->intval;
134 }
135
axp_vts_to_temp(int data,const struct axp_config_info * axp_config)136 static inline int axp_vts_to_temp(int data,
137 const struct axp_config_info *axp_config)
138 {
139 int temp;
140
141 if (!axp_config->pmu_bat_temp_enable)
142 return 300;
143 else if (data < axp_config->pmu_bat_temp_para16)
144 return 800;
145 else if (data <= axp_config->pmu_bat_temp_para15) {
146 temp = 700 + (axp_config->pmu_bat_temp_para15-data)*100/
147 (axp_config->pmu_bat_temp_para15-axp_config->pmu_bat_temp_para16);
148 } else if (data <= axp_config->pmu_bat_temp_para14) {
149 temp = 600 + (axp_config->pmu_bat_temp_para14-data)*100/
150 (axp_config->pmu_bat_temp_para14-axp_config->pmu_bat_temp_para15);
151 } else if (data <= axp_config->pmu_bat_temp_para13) {
152 temp = 550 + (axp_config->pmu_bat_temp_para13-data)*50/
153 (axp_config->pmu_bat_temp_para13-axp_config->pmu_bat_temp_para14);
154 } else if (data <= axp_config->pmu_bat_temp_para12) {
155 temp = 500 + (axp_config->pmu_bat_temp_para12-data)*50/
156 (axp_config->pmu_bat_temp_para12-axp_config->pmu_bat_temp_para13);
157 } else if (data <= axp_config->pmu_bat_temp_para11) {
158 temp = 450 + (axp_config->pmu_bat_temp_para11-data)*50/
159 (axp_config->pmu_bat_temp_para11-axp_config->pmu_bat_temp_para12);
160 } else if (data <= axp_config->pmu_bat_temp_para10) {
161 temp = 400 + (axp_config->pmu_bat_temp_para10-data)*50/
162 (axp_config->pmu_bat_temp_para10-axp_config->pmu_bat_temp_para11);
163 } else if (data <= axp_config->pmu_bat_temp_para9) {
164 temp = 300 + (axp_config->pmu_bat_temp_para9-data)*100/
165 (axp_config->pmu_bat_temp_para9-axp_config->pmu_bat_temp_para10);
166 } else if (data <= axp_config->pmu_bat_temp_para8) {
167 temp = 200 + (axp_config->pmu_bat_temp_para8-data)*100/
168 (axp_config->pmu_bat_temp_para8-axp_config->pmu_bat_temp_para9);
169 } else if (data <= axp_config->pmu_bat_temp_para7) {
170 temp = 100 + (axp_config->pmu_bat_temp_para7-data)*100/
171 (axp_config->pmu_bat_temp_para7-axp_config->pmu_bat_temp_para8);
172 } else if (data <= axp_config->pmu_bat_temp_para6) {
173 temp = 50 + (axp_config->pmu_bat_temp_para6-data)*50/
174 (axp_config->pmu_bat_temp_para6-axp_config->pmu_bat_temp_para7);
175 } else if (data <= axp_config->pmu_bat_temp_para5) {
176 temp = 0 + (axp_config->pmu_bat_temp_para5-data)*50/
177 (axp_config->pmu_bat_temp_para5-axp_config->pmu_bat_temp_para6);
178 } else if (data <= axp_config->pmu_bat_temp_para4) {
179 temp = -50 + (axp_config->pmu_bat_temp_para4-data)*50/
180 (axp_config->pmu_bat_temp_para4-axp_config->pmu_bat_temp_para5);
181 } else if (data <= axp_config->pmu_bat_temp_para3) {
182 temp = -100 + (axp_config->pmu_bat_temp_para3-data)*50/
183 (axp_config->pmu_bat_temp_para3-axp_config->pmu_bat_temp_para4);
184 } else if (data <= axp_config->pmu_bat_temp_para2) {
185 temp = -150 + (axp_config->pmu_bat_temp_para2-data)*50/
186 (axp_config->pmu_bat_temp_para2-axp_config->pmu_bat_temp_para3);
187 } else if (data <= axp_config->pmu_bat_temp_para1) {
188 temp = -250 + (axp_config->pmu_bat_temp_para1-data)*100/
189 (axp_config->pmu_bat_temp_para1-axp_config->pmu_bat_temp_para2);
190 } else
191 temp = -250;
192 return temp;
193 }
194
195 /* read temperature */
axp2202_get_temp(struct power_supply * ps,union power_supply_propval * val)196 static int axp2202_get_temp(struct power_supply *ps,
197 union power_supply_propval *val)
198 {
199 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
200 struct regmap *regmap = bat_power->regmap;
201 struct axp_config_info *axp_config = &bat_power->dts_info;
202
203 uint8_t data[2];
204 uint16_t temp;
205 int ret = 0, tmp;
206
207 ret = regmap_update_bits(regmap, AXP2202_ADC_DATA_SEL, 0x03, AXP2202_ADC_TS_SEL); /* ADC channel select */
208 if (ret < 0)
209 return ret;
210 mdelay(1);
211
212 ret = regmap_bulk_read(regmap, AXP2202_ADC_DATA_H, data, 2);
213 if (ret < 0)
214 return ret;
215 temp = (((data[0] & GENMASK(5, 0)) << 0x08) | (data[1]));
216 tmp = temp * 500 / 1000;
217 val->intval = axp_vts_to_temp(tmp, axp_config);
218
219 return 0;
220 }
221
222
axp2202_bat_get_max_voltage(struct power_supply * ps,union power_supply_propval * val)223 static int axp2202_bat_get_max_voltage(struct power_supply *ps,
224 union power_supply_propval *val)
225 {
226 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
227 struct regmap *regmap = bat_power->regmap;
228
229 int ret, reg_value;
230
231 ret = regmap_read(regmap, AXP2202_VTERM_CFG, ®_value);
232 if (ret)
233 return ret;
234
235 switch (reg_value & AXP2202_CHRG_TGT_VOLT) {
236 case AXP2202_CHRG_CTRL1_TGT_4_0V:
237 val->intval = 4000000;
238 break;
239 case AXP2202_CHRG_CTRL1_TGT_4_1V:
240 val->intval = 4100000;
241 break;
242 case AXP2202_CHRG_CTRL1_TGT_4_2V:
243 val->intval = 4200000;
244 break;
245 case AXP2202_CHRG_CTRL1_TGT_4_35V:
246 val->intval = 4350000;
247 break;
248 case AXP2202_CHRG_CTRL1_TGT_4_4V:
249 val->intval = 4400000;
250 break;
251 case AXP2202_CHRG_CTRL1_TGT_5_0V:
252 val->intval = 5000000;
253 break;
254 default:
255 return -EINVAL;
256 }
257
258 return 0;
259 }
260
axp2202_get_ichg(struct power_supply * ps,union power_supply_propval * val)261 static int axp2202_get_ichg(struct power_supply *ps,
262 union power_supply_propval *val)
263 {
264 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
265 struct regmap *regmap = bat_power->regmap;
266
267 uint8_t data[2];
268 uint16_t ichg;
269 int ret = 0;
270
271 ret = regmap_bulk_read(regmap, AXP2202_ICHG_H, data, 2);
272 if (ret < 0)
273 return ret;
274 ichg = (((data[0] & GENMASK(5, 0)) << 8) | (data[1])); /* mA */
275 ichg = ichg / 2;
276 val->intval = ichg;
277
278 return 0;
279 }
280
axp2202_get_soc(struct power_supply * ps,union power_supply_propval * val)281 static int axp2202_get_soc(struct power_supply *ps,
282 union power_supply_propval *val)
283 {
284 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
285 struct regmap *regmap = bat_power->regmap;
286 unsigned int data;
287 int ret = 0;
288
289 ret = regmap_read(regmap, AXP2202_GAUGE_SOC, &data);
290 if (ret < 0)
291 return ret;
292
293 if (data > AXP2202_SOC_MAX)
294 data = AXP2202_SOC_MAX;
295 else if (data < AXP2202_SOC_MIN)
296 data = AXP2202_SOC_MIN;
297
298 val->intval = data;
299
300 return 0;
301 }
302
axp2202_get_charger_count(struct power_supply * ps,union power_supply_propval * val)303 static int axp2202_get_charger_count(struct power_supply *ps,
304 union power_supply_propval *val)
305 {
306 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
307 struct axp_config_info *axp_config = &bat_power->dts_info;
308 unsigned int data;
309
310 data = axp_config->pmu_battery_cap;
311 val->intval = data;
312 return 0;
313 }
314
axp2202_get_charger_count_current(struct power_supply * ps,union power_supply_propval * val)315 static int axp2202_get_charger_count_current(struct power_supply *ps,
316 union power_supply_propval *val)
317 {
318 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
319 struct axp_config_info *axp_config = &bat_power->dts_info;
320 unsigned int data[2];
321 int ret = 0;
322
323 data[0] = axp_config->pmu_battery_cap;
324
325 ret = axp2202_get_soc(ps, val);
326 if (ret < 0)
327 return ret;
328 data[1] = val->intval;
329 data[1] = data[1] * data[0] / 100;
330
331 val->intval = data[1];
332 return 0;
333 }
334
axp2202_get_time2empty(struct power_supply * ps,union power_supply_propval * val)335 static int axp2202_get_time2empty(struct power_supply *ps,
336 union power_supply_propval *val)
337 {
338 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
339 struct regmap *regmap = bat_power->regmap;
340 uint8_t data[2];
341 uint16_t ttemp[3], tempt;
342 int ret = 0;
343 uint8_t i;
344
345 for (i = 0; i < 3; i++) {
346 ret = regmap_bulk_read(regmap, AXP2202_GAUGE_TIME2EMPTY_H, data,
347 2);
348 if (ret < 0)
349 return ret;
350
351 ttemp[i] = ((data[0] << 0x08) | (data[1]));
352 }
353
354 if (ttemp[0] > ttemp[1]) {
355 tempt = ttemp[0];
356 ttemp[0] = ttemp[1];
357 ttemp[1] = tempt;
358 }
359 if (ttemp[1] > ttemp[2]) {
360 tempt = ttemp[1];
361 ttemp[1] = ttemp[2];
362 ttemp[2] = tempt;
363 }
364 if (ttemp[0] > ttemp[1]) {
365 tempt = ttemp[0];
366 ttemp[0] = ttemp[1];
367 ttemp[1] = tempt;
368 }
369
370 val->intval = ttemp[1] * 60;
371
372 return 0;
373 }
374
375
axp2202_get_time2full(struct power_supply * ps,union power_supply_propval * val)376 static int axp2202_get_time2full(struct power_supply *ps,
377 union power_supply_propval *val)
378 {
379 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
380 struct regmap *regmap = bat_power->regmap;
381 uint16_t ttemp[3], tempt;
382 uint8_t data[2];
383 int ret = 0;
384 uint8_t i;
385
386 for (i = 0; i < 3; i++) {
387 ret = regmap_bulk_read(regmap, AXP2202_GAUGE_TIME2FULL_H, data, 2);
388 if (ret < 0)
389 return ret;
390
391 ttemp[i] = ((data[0] << 0x08) | (data[1]));
392 }
393
394 if (ttemp[0] > ttemp[1]) {
395 tempt = ttemp[0];
396 ttemp[0] = ttemp[1];
397 ttemp[1] = tempt;
398 }
399 if (ttemp[1] > ttemp[2]) {
400 tempt = ttemp[1];
401 ttemp[1] = ttemp[2];
402 ttemp[2] = tempt;
403 }
404 if (ttemp[0] > ttemp[1]) {
405 tempt = ttemp[0];
406 ttemp[0] = ttemp[1];
407 ttemp[1] = tempt;
408 }
409
410 val->intval = ttemp[1] * 60;
411
412 return 0;
413 }
414
415
axp2202_get_bat_present(struct power_supply * ps,union power_supply_propval * val)416 static int axp2202_get_bat_present(struct power_supply *ps,
417 union power_supply_propval *val)
418 {
419 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
420 struct regmap *regmap = bat_power->regmap;
421 unsigned int data;
422 int ret;
423
424 ret = regmap_read(regmap, AXP2202_COMM_STAT0, &data);
425 if (ret < 0) {
426 dev_dbg(&ps->dev, "error read AXP2202_COM_STAT1\n");
427 return ret;
428 }
429
430 if (data & AXP2202_MASK_BAT_STAT)
431 val->intval = 1;
432 else
433 val->intval = 0;
434 return 0;
435 }
436
437
438
439
axp2202_get_bat_status(struct power_supply * ps,union power_supply_propval * val)440 static int axp2202_get_bat_status(struct power_supply *ps,
441 union power_supply_propval *val)
442 {
443 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
444 struct regmap *regmap = bat_power->regmap;
445 unsigned int data;
446 int ret;
447
448 ret = regmap_read(regmap, AXP2202_COMM_STAT1, &data);
449 if (ret < 0) {
450 dev_dbg(&ps->dev, "error read AXP2202_COM_STAT1\n");
451 return ret;
452 }
453
454 /* chg_stat = bit[2:0] */
455 switch (data & 0x07) {
456 case AXP2202_CHARGING_TRI:
457 case AXP2202_CHARGING_NCHG:
458 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
459 break;
460 case AXP2202_CHARGING_PRE:
461 case AXP2202_CHARGING_CC:
462 case AXP2202_CHARGING_CV:
463 val->intval = POWER_SUPPLY_STATUS_CHARGING;
464 break;
465 case AXP2202_CHARGING_DONE:
466 val->intval = POWER_SUPPLY_STATUS_FULL;
467 break;
468 default:
469 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
470 break;
471 }
472
473 return 0;
474 }
475
476
axp2202_get_lowsocth(struct power_supply * ps,union power_supply_propval * val)477 static int axp2202_get_lowsocth(struct power_supply *ps,
478 union power_supply_propval *val)
479 {
480 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(ps);
481 struct regmap *regmap = bat_power->regmap;
482 unsigned int data;
483 int ret = 0;
484
485 ret = regmap_read(regmap, AXP2202_GAUGE_THLD, &data);
486 if (ret < 0)
487 return ret;
488
489 val->intval = (data >> 4) + 5;
490
491 return 0;
492 }
493
494
axp2202_set_lowsocth(struct regmap * regmap,int v)495 static int axp2202_set_lowsocth(struct regmap *regmap, int v)
496 {
497 unsigned int data;
498 int ret = 0;
499
500 data = v;
501
502 if (data > 20 || data < 5)
503 return -EINVAL;
504
505 data = (data - 5);
506 ret = regmap_update_bits(regmap, AXP2202_GAUGE_THLD, GENMASK(7, 4),
507 data);
508 if (ret < 0)
509 return ret;
510
511 return 0;
512 }
513
axp2202_set_ichg(struct regmap * regmap,int mA)514 static int axp2202_set_ichg(struct regmap *regmap, int mA)
515 {
516 unsigned int data;
517 int ret = 0;
518
519 data = mA;
520
521 if (data > 3072)
522 data = 3072;
523 if (data < 0)
524 data = 0;
525 else {
526 data = (data / 64);
527 ret = regmap_update_bits(regmap, AXP2202_ICC_CFG, GENMASK(5, 0),
528 data);
529 if (ret < 0)
530 return ret;
531 }
532
533 return 0;
534 }
535
axp2202_set_bat_max_voltage(struct regmap * regmap,int mV)536 static int axp2202_set_bat_max_voltage(struct regmap *regmap, int mV)
537 {
538 unsigned int data;
539 int ret = 0;
540
541 data = mV;
542
543 if (data > 5000) {
544 data = 5000;
545 ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
546 AXP2202_CHRG_CTRL1_TGT_5_0V);
547 } else if (data < 4100) {
548 data = 4000;
549 ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
550 AXP2202_CHRG_CTRL1_TGT_4_0V);
551 } else if (data > 4100 && data < 4200) {
552 data = 4100;
553 ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
554 AXP2202_CHRG_CTRL1_TGT_4_1V);
555 } else if (data > 4200 && data < 4350) {
556 data = 4200;
557 ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
558 AXP2202_CHRG_CTRL1_TGT_4_2V);
559 } else if (data > 4350 && data < 4400) {
560 data = 4350;
561 ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
562 AXP2202_CHRG_CTRL1_TGT_4_35V);
563 } else if (data > 4400 && data < 5000) {
564 data = 4400;
565 ret = regmap_update_bits(regmap, AXP2202_VTERM_CFG, GENMASK(2, 0),
566 AXP2202_CHRG_CTRL1_TGT_4_4V);
567 } else
568 ret = 0;
569 return 0;
570 }
571
572
axp2202_reset_mcu(struct regmap * regmap)573 static int axp2202_reset_mcu(struct regmap *regmap)
574 {
575 int ret = 0;
576
577 ret = regmap_update_bits(regmap, AXP2202_RESET_CFG, AXP2202_MODE_RSTMCU,
578 AXP2202_MODE_RSTMCU);
579 if (ret < 0)
580 return ret;
581
582 ret = regmap_update_bits(regmap, AXP2202_RESET_CFG, AXP2202_MODE_RSTMCU,
583 0);
584 if (ret < 0)
585 return ret;
586
587 return 0;
588 }
589
590 /**
591 * axp2202_get_param - get battery config from dts
592 *
593 * is not get battery config parameter from dts,
594 * then it use the default config.
595 */
axp2202_get_param(struct axp2202_bat_power * bat_power,uint8_t * para,unsigned int * len)596 static int axp2202_get_param(struct axp2202_bat_power *bat_power, uint8_t *para,
597 unsigned int *len)
598 {
599 struct device_node *n_para, *r_para;
600 const char *pparam;
601 int cnt;
602
603 n_para = of_parse_phandle(bat_power->dev->of_node, "param", 0);
604 if (!n_para)
605 goto e_n_para;
606
607 if (of_property_read_string(n_para, "select", &pparam))
608 goto e_para;
609
610 r_para = of_get_child_by_name(n_para, pparam);
611 if (!r_para)
612 goto e_para;
613
614 cnt = of_property_read_variable_u8_array(r_para, "parameter", para, 1,
615 *len);
616 if (cnt <= 0)
617 goto e_n_parameter;
618 *len = cnt;
619
620 of_node_put(r_para);
621 of_node_put(n_para);
622
623 return 0;
624
625 e_n_parameter:
626 of_node_put(r_para);
627 e_para:
628 of_node_put(n_para);
629 e_n_para:
630 return -ENODATA;
631 }
632
axp2202_model_update(struct axp2202_bat_power * bat_power)633 static int axp2202_model_update(struct axp2202_bat_power *bat_power)
634 {
635 struct regmap *regmap = bat_power->regmap;
636 int i1, ret = 0;
637 unsigned int data;
638 unsigned int len;
639 uint8_t i;
640 uint8_t *param;
641
642 /* reset_mcu */
643 ret = axp2202_reset_mcu(bat_power->regmap);
644 if (ret < 0)
645 goto UPDATE_ERR;
646
647 /* reset and open brom */
648 ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
649 AXP2202_BROMUP_EN, 0);
650 if (ret < 0)
651 goto UPDATE_ERR;
652
653 ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
654 AXP2202_BROMUP_EN, AXP2202_BROMUP_EN);
655 if (ret < 0)
656 goto UPDATE_ERR;
657
658 /* down load battery parameters */
659 len = AXP2202_MAX_PARAM;
660 param = devm_kzalloc(bat_power->dev, AXP2202_MAX_PARAM, GFP_KERNEL);
661 if (!param) {
662 pr_err("can not find memory for param\n");
663 goto UPDATE_ERR;
664 }
665 ret = axp2202_get_param(bat_power, param, &len);
666 if (ret < 0)
667 goto err_param;
668
669 for (i = 0; i < len; i++) {
670 ret = regmap_write(regmap, AXP2202_GAUGE_BROM, param[i]);
671 if (ret < 0)
672 goto err_param;
673 }
674 /* reset and open brom */
675 ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
676 AXP2202_BROMUP_EN, 0);
677 if (ret < 0)
678 goto err_param;
679
680 ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
681 AXP2202_BROMUP_EN, AXP2202_BROMUP_EN);
682 if (ret < 0)
683 goto err_param;
684
685 /* check battery parameters is ok ? */
686 for (i = 0; i < len; i++) {
687 ret = regmap_read(regmap, AXP2202_GAUGE_BROM, &data);
688 if (ret < 0)
689 goto err_param;
690
691 if (data != param[i]) {
692 pr_err("model param check %02x error!\n", i);
693 goto err_param;
694 }
695 }
696
697 devm_kfree(bat_power->dev, param);
698
699 /* close brom and set battery update flag */
700 ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG, AXP2202_BROMUP_EN,
701 0);
702 if (ret < 0)
703 goto UPDATE_ERR;
704
705 ret = regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG,
706 AXP2202_CFG_UPDATE_MARK,
707 AXP2202_CFG_UPDATE_MARK);
708 if (ret < 0)
709 goto UPDATE_ERR;
710
711 ret = regmap_read(regmap, AXP2202_GAUGE_CONFIG, &data);
712 if (ret < 0)
713 goto UPDATE_ERR;
714
715 /* reset mcu with chgcur = 0mA */
716 regmap_read(regmap, AXP2202_COMM_STAT0, &i1);
717 if (i1 & BIT(5)) {
718 pr_warn("reset gauge\n");
719 axp2202_set_ichg(regmap, 0);
720 msleep(200);
721 axp2202_reset_mcu(regmap);
722 msleep(50);
723 }
724 axp2202_set_ichg(regmap, bat_power->dts_info.pmu_runtime_chgcur);
725
726 /* reset_mcu */
727 ret = axp2202_reset_mcu(regmap);
728 if (ret < 0)
729 goto UPDATE_ERR;
730
731 /* update ok */
732 return 0;
733
734 err_param:
735 devm_kfree(bat_power->dev, param);
736
737 UPDATE_ERR:
738 regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG, AXP2202_BROMUP_EN, 0);
739 axp2202_reset_mcu(regmap);
740
741 return ret;
742 }
743
744
axp2202_model_update_check(struct regmap * regmap)745 static bool axp2202_model_update_check(struct regmap *regmap)
746 {
747 int ret = 0;
748 unsigned int data;
749
750 ret = regmap_read(regmap, AXP2202_GAUGE_CONFIG, &data);
751 if (ret < 0)
752 goto CHECK_ERR;
753
754 if ((data & AXP2202_CFG_UPDATE_MARK) == 0)
755 goto CHECK_ERR;
756
757
758 return true;
759
760 CHECK_ERR:
761 regmap_update_bits(regmap, AXP2202_GAUGE_CONFIG, AXP2202_BROMUP_EN, 0);
762 axp2202_reset_mcu(regmap);
763 return false;
764 }
765
766
767
axp2202_bat_get_property(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)768 static int axp2202_bat_get_property(struct power_supply *psy,
769 enum power_supply_property psp,
770 union power_supply_propval *val)
771 {
772 int ret = 0;
773
774 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(psy);
775
776 switch (psp) {
777 case POWER_SUPPLY_PROP_MODEL_NAME:
778 val->strval = psy->desc->name;
779 break;
780 case POWER_SUPPLY_PROP_TECHNOLOGY:
781 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
782 break;
783 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
784 ret = axp2202_bat_get_max_voltage(psy, val);
785 if (ret < 0)
786 return ret;
787 break;
788 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: // customer modify
789 ret = axp2202_get_bat_present(psy, val);
790 if (ret < 0)
791 return ret;
792
793 if (val->intval) {
794 ret = axp2202_get_soc(psy, val);
795 if (ret < 0)
796 return ret;
797
798 if (val->intval == 100)
799 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
800 else if (val->intval > 80)
801 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_HIGH;
802 else if (val->intval > bat_power->dts_info.pmu_battery_warning_level1)
803 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
804 else if (val->intval > bat_power->dts_info.pmu_battery_warning_level2)
805 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
806 else if (val->intval >= 0)
807 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
808 else
809 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
810 }
811 else
812 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
813 break;
814 case POWER_SUPPLY_PROP_STATUS:
815 ret = axp2202_get_bat_status(psy, val);
816 if (ret < 0)
817 return ret;
818 break;
819 case POWER_SUPPLY_PROP_PRESENT:
820 ret = axp2202_get_bat_present(psy, val);
821 if (ret < 0)
822 return ret;
823 break;
824 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
825 ret = axp2202_get_vbat_vol(psy, val);
826 if (ret < 0)
827 return ret;
828 break;
829 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
830 val->intval = bat_power->dts_info.pmu_battery_cap;
831 break;
832 case POWER_SUPPLY_PROP_CAPACITY:
833 ret = axp2202_get_soc(psy, val); // unit %;
834 if (ret < 0)
835 return ret;
836 break;
837 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
838 ret = axp2202_get_lowsocth(psy, val);
839 if (ret < 0)
840 return ret;
841 break;
842 case POWER_SUPPLY_PROP_TEMP:
843 ret = axp2202_get_temp(psy, val);
844 if (ret < 0)
845 return ret;
846 break;
847 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
848 ret = axp2202_get_ichg(psy, val);
849 if (ret < 0)
850 return ret;
851 break;
852 case POWER_SUPPLY_PROP_HEALTH:
853 ret = axp2202_get_bat_health(psy, val);
854 if (ret < 0)
855 return ret;
856 break;
857 case POWER_SUPPLY_PROP_TEMP_ALERT_MIN:
858 ret = bat_power->dts_info.pmu_bat_shutdown_ltf;
859 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
860 if (!bat_power->dts_info.pmu_bat_temp_enable)
861 val->intval = -200000;
862 break;
863 case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
864 ret = bat_power->dts_info.pmu_bat_shutdown_htf;
865 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
866 if (!bat_power->dts_info.pmu_bat_temp_enable)
867 val->intval = 200000;
868 break;
869 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN:
870 ret = bat_power->dts_info.pmu_bat_charge_ltf;
871 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
872 if (!bat_power->dts_info.pmu_bat_temp_enable)
873 val->intval = -200000;
874 break;
875 case POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX:
876 ret = bat_power->dts_info.pmu_bat_charge_htf;
877 val->intval = axp_vts_to_temp(ret, &bat_power->dts_info);
878 if (!bat_power->dts_info.pmu_bat_temp_enable)
879 val->intval = 200000;
880 break;
881 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
882 ret = axp2202_get_time2empty(psy, val);
883 if (ret < 0)
884 return ret;
885 break;
886 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
887 ret = axp2202_get_time2full(psy, val);
888 if (ret < 0)
889 return ret;
890 break;
891 case POWER_SUPPLY_PROP_MANUFACTURER:
892 val->strval = AXP2202_MANUFACTURER;
893 break;
894 case POWER_SUPPLY_PROP_CHARGE_COUNTER:
895 ret = axp2202_get_charger_count_current(psy, val);
896 if (ret < 0)
897 return ret;
898 break;
899 case POWER_SUPPLY_PROP_CHARGE_FULL:
900 ret = axp2202_get_charger_count(psy, val);
901 if (ret < 0)
902 return ret;
903 break;
904 default:
905 return -EINVAL;
906 }
907 return ret;
908 }
909
axp2202_bat_set_property(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)910 static int axp2202_bat_set_property(struct power_supply *psy,
911 enum power_supply_property psp,
912 const union power_supply_propval *val)
913 {
914 struct axp2202_bat_power *bat_power = power_supply_get_drvdata(psy);
915 struct regmap *regmap = bat_power->regmap;
916 int ret = 0;
917
918 switch (psp) {
919 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
920 ret = axp2202_set_lowsocth(regmap, val->intval);
921 break;
922 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
923 ret = axp2202_set_ichg(regmap, val->intval);
924 break;
925 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
926 ret = axp2202_set_bat_max_voltage(regmap, val->intval);
927 break;
928 default:
929 ret = -EINVAL;
930 }
931
932 return ret;
933 }
934
axp2202_usb_power_property_is_writeable(struct power_supply * psy,enum power_supply_property psp)935 static int axp2202_usb_power_property_is_writeable(struct power_supply *psy,
936 enum power_supply_property psp)
937 {
938 int ret = 0;
939 switch (psp) {
940 case POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN:
941 ret = 0;
942 break;
943 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
944 ret = 0;
945 break;
946 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
947 ret = 0;
948 break;
949 default:
950 ret = -EINVAL;
951 }
952 return ret;
953
954 }
955
956 static const struct power_supply_desc axp2202_bat_desc = {
957 .name = "axp2202-battery",
958 .type = POWER_SUPPLY_TYPE_BATTERY,
959 .get_property = axp2202_bat_get_property,
960 .set_property = axp2202_bat_set_property,
961 .properties = axp2202_bat_props,
962 .num_properties = ARRAY_SIZE(axp2202_bat_props),
963 .property_is_writeable = axp2202_usb_power_property_is_writeable,
964 };
965
axp2202_init_chip(struct axp2202_bat_power * bat_power)966 static int axp2202_init_chip(struct axp2202_bat_power *bat_power)
967 {
968 struct axp_config_info *axp_config = &bat_power->dts_info;
969 int ret = 0;
970 int val, vbat, soc;
971 unsigned int reg_value;
972 unsigned char temp_val[2];
973
974 if (bat_power == NULL) {
975 dev_err(bat_power->dev, "axp2202_info is invalid!\n");
976 return -ENODEV;
977 }
978
979 if (ret < 0) {
980 dev_err(bat_power->dev, "axp2202 reg update, i2c communication err!\n");
981 return ret;
982 }
983
984 /* update battery model*/
985 if (!axp2202_model_update_check(bat_power->regmap)) {
986 ret = axp2202_model_update(bat_power);
987 if (ret < 0) {
988 dev_err(bat_power->dev, "axp2202 model update fail!\n");
989 return ret;
990 }
991 }
992 dev_dbg(bat_power->dev, "axp2202 model update ok\n");
993 /*end of update battery model*/
994
995
996 /* set pre-charge current to 128mA*/
997 val = 0x02;
998 regmap_update_bits(bat_power->regmap, AXP2202_IPRECHG_CFG, 0x0f, val);
999
1000 /* set terminal charge current */
1001 if (axp_config->pmu_terminal_chgcur < 64)
1002 val = 0;
1003 else if (axp_config->pmu_terminal_chgcur > 1024)
1004 val = 0x0f;
1005 else
1006 val = axp_config->pmu_terminal_chgcur / 64 - 1;
1007 regmap_update_bits(bat_power->regmap, AXP2202_ITERM_CFG, 0x0f, val);
1008
1009 /* enable ntc */
1010 if (axp_config->pmu_bat_temp_enable) {
1011 regmap_update_bits(bat_power->regmap, AXP2202_TS_CFG, AXP2202_TS_ENABLE_MARK, 0);
1012
1013 /* set ntc curr */
1014 regmap_read(bat_power->regmap, AXP2202_TS_CFG, &val);
1015 val &= 0xFC;
1016 if (axp_config->pmu_bat_ts_current < 40)
1017 val |= 0x00;
1018 else if (axp_config->pmu_bat_ts_current < 50)
1019 val |= 0x01;
1020 else if (axp_config->pmu_bat_ts_current < 60)
1021 val |= 0x02;
1022 else
1023 val |= 0x03;
1024 regmap_write(bat_power->regmap, AXP2202_TS_CFG, val);
1025
1026 /* set ntc vol */
1027 if (axp_config->pmu_bat_charge_ltf) {
1028 if (axp_config->pmu_bat_charge_ltf < axp_config->pmu_bat_charge_htf)
1029 axp_config->pmu_bat_charge_ltf = axp_config->pmu_bat_charge_htf;
1030
1031 val = axp_config->pmu_bat_charge_ltf / 32;
1032 regmap_write(bat_power->regmap, AXP2202_VLTF_CHG, val);
1033 }
1034
1035 if (axp_config->pmu_bat_charge_htf) {
1036 if (axp_config->pmu_bat_charge_htf > 510)
1037 axp_config->pmu_bat_charge_htf = 510;
1038
1039 val = axp_config->pmu_bat_charge_htf / 2;
1040 regmap_write(bat_power->regmap, AXP2202_VHTF_CHG, val);
1041 }
1042
1043 /* set work vol */
1044 if (axp_config->pmu_bat_shutdown_ltf) {
1045 if (axp_config->pmu_bat_shutdown_ltf < axp_config->pmu_bat_charge_ltf)
1046 axp_config->pmu_bat_shutdown_ltf = axp_config->pmu_bat_charge_ltf;
1047
1048 val = axp_config->pmu_bat_shutdown_ltf / 32;
1049 regmap_write(bat_power->regmap, AXP2202_VLTF_WORK, val);
1050 }
1051
1052 if (axp_config->pmu_bat_shutdown_htf) {
1053 if (axp_config->pmu_bat_shutdown_htf > axp_config->pmu_bat_charge_htf)
1054 axp_config->pmu_bat_shutdown_htf = axp_config->pmu_bat_charge_htf;
1055
1056 val = axp_config->pmu_bat_shutdown_htf / 2;
1057 regmap_write(bat_power->regmap, AXP2202_VHTF_WORK, val);
1058 }
1059
1060 } else {
1061 regmap_update_bits(bat_power->regmap, AXP2202_TS_CFG, AXP2202_TS_ENABLE_MARK, AXP2202_TS_ENABLE_MARK);
1062 }
1063
1064 /* set jeita enable */
1065 if (axp_config->pmu_jetia_en) {
1066 regmap_update_bits(bat_power->regmap, AXP2202_JEITA_CFG, AXP2202_JEITA_ENABLE_MARK, 1);
1067
1068 /* set jeita cool vol */
1069 if (axp_config->pmu_jetia_cool) {
1070 if (axp_config->pmu_jetia_cool < axp_config->pmu_jetia_warm)
1071 axp_config->pmu_jetia_cool = axp_config->pmu_jetia_warm;
1072
1073 val = axp_config->pmu_jetia_cool / 16;
1074 regmap_write(bat_power->regmap, AXP2202_JEITA_COOL, val);
1075 }
1076
1077 /* set jeita warm vol */
1078 if (axp_config->pmu_jetia_warm) {
1079 if (axp_config->pmu_jetia_warm > 2040)
1080 axp_config->pmu_jetia_warm = 2040;
1081
1082 val = axp_config->pmu_jetia_warm/8;
1083 regmap_write(bat_power->regmap, AXP2202_JEITA_WARM, val);
1084 }
1085
1086 /* set jeita config */
1087 regmap_read(bat_power->regmap, AXP2202_JEITA_CV_CFG, &val);
1088 val &= 0x0F;
1089 if (axp_config->pmu_jwarm_ifall)
1090 val |= axp_config->pmu_jwarm_ifall << 6;
1091
1092 if (axp_config->pmu_jcool_ifall)
1093 val |= axp_config->pmu_jcool_ifall << 4;
1094
1095 regmap_write(bat_power->regmap, AXP2202_JEITA_CV_CFG, val);
1096
1097 } else {
1098 regmap_update_bits(bat_power->regmap, AXP2202_JEITA_CFG, AXP2202_JEITA_ENABLE_MARK, 0);
1099 }
1100
1101 /* set CHGLED */
1102 regmap_read(bat_power->regmap, AXP2202_CHGLED_CFG, ®_value);
1103 reg_value &= 0xf8;
1104 if (axp_config->pmu_chgled_func) {
1105 reg_value |= axp_config->pmu_chgled_type;
1106 regmap_write(bat_power->regmap, AXP2202_CHGLED_CFG, reg_value);
1107 }
1108
1109 /* set charger voltage limit */
1110 if (axp_config->pmu_init_chgvol < 4100) {
1111 regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_0V);
1112 } else if (axp_config->pmu_init_chgvol < 4200) {
1113 regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_1V);
1114 } else if (axp_config->pmu_init_chgvol < 4350) {
1115 regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_2V);
1116 } else if (axp_config->pmu_init_chgvol < 4400) {
1117 regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_35V);
1118 } else if (axp_config->pmu_init_chgvol < 5000) {
1119 regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_4_4V);
1120 } else {
1121 regmap_update_bits(bat_power->regmap, AXP2202_VTERM_CFG, 0x07, AXP2202_CHRG_CTRL1_TGT_5_0V);
1122 }
1123
1124 /* set charger charge current */
1125 axp_config->pmu_runtime_chgcur = clamp_val(axp_config->pmu_runtime_chgcur, 0, 3072);
1126 val = axp_config->pmu_runtime_chgcur / 64;
1127 regmap_update_bits(bat_power->regmap, AXP2202_ICC_CFG, GENMASK(5, 0),
1128 val);
1129
1130 /* set gauge_thld */
1131 val = clamp_val(axp_config->pmu_battery_warning_level1 - 5, 0, 15) << 4;
1132 val |= clamp_val(axp_config->pmu_battery_warning_level2, 0, 15);
1133 regmap_write(bat_power->regmap, AXP2202_GAUGE_THLD, val);
1134
1135 /* check soc & vbat*/
1136 ret = regmap_bulk_read(bat_power->regmap, AXP2202_VBAT_H, temp_val, 2);
1137 if (ret < 0)
1138 return ret;
1139 vbat = (((temp_val[0]) << 8) + temp_val[1]);
1140 ret = regmap_read(bat_power->regmap, AXP2202_GAUGE_SOC, ®_value);
1141 if (ret < 0)
1142 return ret;
1143 soc = (int)(reg_value);
1144 ret = regmap_read(bat_power->regmap, AXP2202_COMM_STAT0, ®_value);
1145 if (ret < 0)
1146 return ret;
1147 if (soc == 0) {
1148 if (reg_value & BIT(5)) {
1149 if (vbat > 3800) {
1150 axp2202_reset_mcu(bat_power->regmap);
1151 pr_warn("adapt reset gauge: soc = 0\n");
1152 }
1153 } else {
1154 if (vbat > 3700) {
1155 axp2202_reset_mcu(bat_power->regmap);
1156 pr_warn("only battery reset gauge: soc = 0\n");
1157 }
1158 }
1159 }
1160 if (vbat < 3900 && soc > 98) {
1161 axp2202_reset_mcu(bat_power->regmap);
1162 pr_warn("reset gauge: vbat < 3900, soc > 98\n");
1163 }
1164
1165 return ret;
1166 }
1167
1168
axp2202_irq_handler_bat_stat_change(int irq,void * data)1169 static irqreturn_t axp2202_irq_handler_bat_stat_change(int irq, void *data)
1170 {
1171 struct irq_desc *id = irq_to_desc(irq);
1172 struct axp2202_bat_power *bat_power = data;
1173
1174 pr_debug("%s: enter interrupt %d\n", __func__, irq);
1175
1176 power_supply_changed(bat_power->bat_supply);
1177
1178 switch (id->irq_data.hwirq) {
1179 case AXP2202_IRQ_CHGDN:
1180 pr_debug("interrupt:charger done");
1181 break;
1182 case AXP2202_IRQ_CHGST:
1183 pr_debug("interrutp:charger start");
1184 break;
1185 case AXP2202_IRQ_BINSERT:
1186 pr_debug("interrupt:battery insert");
1187 break;
1188 case AXP2202_IRQ_BREMOVE:
1189 pr_debug("interrupt:battery remove");
1190 break;
1191 default:
1192 pr_debug("interrupt:others");
1193 break;
1194 }
1195
1196 return IRQ_HANDLED;
1197 }
1198
1199 enum axp2202_bat_virq_index {
1200 AXP2202_VIRQ_BAT_IN,
1201 AXP2202_VIRQ_BAT_OUT,
1202 AXP2202_VIRQ_CHARGING,
1203 AXP2202_VIRQ_CHARGE_OVER,
1204 AXP2202_VIRQ_LOW_WARNING1,
1205 AXP2202_VIRQ_LOW_WARNING2,
1206 AXP2202_VIRQ_BAT_UNTEMP_WORK,
1207 AXP2202_VIRQ_BAT_OVTEMP_WORK,
1208 AXP2202_VIRQ_BAT_UNTEMP_CHG,
1209 AXP2202_VIRQ_BAT_OVTEMP_CHG,
1210 AXP2202_VIRQ_BAT_OV,
1211 AXP2202_VIRQ_MAX_VIRQ,
1212 };
1213
1214 static struct axp_interrupts axp_bat_irq[] = {
1215 [AXP2202_VIRQ_BAT_IN] = { "battery_insert",
1216 axp2202_irq_handler_bat_stat_change },
1217 [AXP2202_VIRQ_BAT_OUT] = { "battery_remove",
1218 axp2202_irq_handler_bat_stat_change },
1219 [AXP2202_VIRQ_CHARGING] = { "charge_start",
1220 axp2202_irq_handler_bat_stat_change },
1221 [AXP2202_VIRQ_CHARGE_OVER] = { "charge_done",
1222 axp2202_irq_handler_bat_stat_change },
1223 [AXP2202_VIRQ_LOW_WARNING1] = { "SOC_low_warning1",
1224 axp2202_irq_handler_bat_stat_change },
1225 [AXP2202_VIRQ_LOW_WARNING2] = { "SOC_low_warning2",
1226 axp2202_irq_handler_bat_stat_change },
1227 [AXP2202_VIRQ_BAT_UNTEMP_WORK] = { "bat_work_under_temp",
1228 axp2202_irq_handler_bat_stat_change },
1229 [AXP2202_VIRQ_BAT_OVTEMP_WORK] = { "bat_work_over_temp",
1230 axp2202_irq_handler_bat_stat_change },
1231 [AXP2202_VIRQ_BAT_UNTEMP_CHG] = { "bat_chg_under_temp",
1232 axp2202_irq_handler_bat_stat_change },
1233 [AXP2202_VIRQ_BAT_OVTEMP_CHG] = { "bat_chg_over_temp",
1234 axp2202_irq_handler_bat_stat_change },
1235 [AXP2202_VIRQ_BAT_OV] = { "battery_over_voltage",
1236 axp2202_irq_handler_bat_stat_change },
1237
1238 };
1239
axp2202_bat_dt_parse(struct device_node * node,struct axp_config_info * axp_config)1240 int axp2202_bat_dt_parse(struct device_node *node,
1241 struct axp_config_info *axp_config)
1242 {
1243 if (!of_device_is_available(node)) {
1244 pr_err("%s: failed\n", __func__);
1245 return -1;
1246 }
1247
1248 AXP_OF_PROP_READ(pmu_battery_cap, 4000);
1249 AXP_OF_PROP_READ(pmu_chg_ic_temp, 0);
1250 AXP_OF_PROP_READ(pmu_runtime_chgcur, 500);
1251 AXP_OF_PROP_READ(pmu_suspend_chgcur, 1200);
1252 AXP_OF_PROP_READ(pmu_shutdown_chgcur, 1200);
1253 AXP_OF_PROP_READ(pmu_prechg_chgcur, 100);
1254 AXP_OF_PROP_READ(pmu_terminal_chgcur, 50);
1255 AXP_OF_PROP_READ(pmu_init_chgvol, 4200);
1256 AXP_OF_PROP_READ(pmu_battery_warning_level1, 15);
1257 AXP_OF_PROP_READ(pmu_battery_warning_level2, 0);
1258 AXP_OF_PROP_READ(pmu_chgled_func, 1);
1259 AXP_OF_PROP_READ(pmu_chgled_type, 0);
1260 AXP_OF_PROP_READ(pmu_batdeten, 1);
1261
1262 AXP_OF_PROP_READ(pmu_bat_ts_current, 50);
1263 AXP_OF_PROP_READ(pmu_bat_charge_ltf, 1312);
1264 AXP_OF_PROP_READ(pmu_bat_charge_htf, 176);
1265 AXP_OF_PROP_READ(pmu_bat_shutdown_ltf, 1984);
1266 AXP_OF_PROP_READ(pmu_bat_shutdown_htf, 152);
1267
1268 AXP_OF_PROP_READ(pmu_jetia_en, 0);
1269 AXP_OF_PROP_READ(pmu_jetia_cool, 880);
1270 AXP_OF_PROP_READ(pmu_jetia_warm, 240);
1271 AXP_OF_PROP_READ(pmu_jcool_ifall, 1);
1272 AXP_OF_PROP_READ(pmu_jwarm_ifall, 0);
1273
1274 AXP_OF_PROP_READ(pmu_bat_temp_enable, 0);
1275 AXP_OF_PROP_READ(pmu_bat_temp_para1, 0);
1276 AXP_OF_PROP_READ(pmu_bat_temp_para2, 0);
1277 AXP_OF_PROP_READ(pmu_bat_temp_para3, 0);
1278 AXP_OF_PROP_READ(pmu_bat_temp_para4, 0);
1279 AXP_OF_PROP_READ(pmu_bat_temp_para5, 0);
1280 AXP_OF_PROP_READ(pmu_bat_temp_para6, 0);
1281 AXP_OF_PROP_READ(pmu_bat_temp_para7, 0);
1282 AXP_OF_PROP_READ(pmu_bat_temp_para8, 0);
1283 AXP_OF_PROP_READ(pmu_bat_temp_para9, 0);
1284 AXP_OF_PROP_READ(pmu_bat_temp_para10, 0);
1285 AXP_OF_PROP_READ(pmu_bat_temp_para11, 0);
1286 AXP_OF_PROP_READ(pmu_bat_temp_para12, 0);
1287 AXP_OF_PROP_READ(pmu_bat_temp_para13, 0);
1288 AXP_OF_PROP_READ(pmu_bat_temp_para14, 0);
1289 AXP_OF_PROP_READ(pmu_bat_temp_para15, 0);
1290 AXP_OF_PROP_READ(pmu_bat_temp_para16, 0);
1291
1292 axp_config->wakeup_bat_in =
1293 of_property_read_bool(node, "wakeup_bat_in");
1294 axp_config->wakeup_bat_out =
1295 of_property_read_bool(node, "wakeup_bat_out");
1296 axp_config->wakeup_bat_charging =
1297 of_property_read_bool(node, "wakeup_bat_charging");
1298 axp_config->wakeup_bat_charge_over =
1299 of_property_read_bool(node, "wakeup_bat_charge_over");
1300 axp_config->wakeup_low_warning1 =
1301 of_property_read_bool(node, "wakeup_low_warning1");
1302 axp_config->wakeup_low_warning2 =
1303 of_property_read_bool(node, "wakeup_low_warning2");
1304 axp_config->wakeup_bat_untemp_work =
1305 of_property_read_bool(node, "wakeup_bat_untemp_work");
1306 axp_config->wakeup_bat_ovtemp_work =
1307 of_property_read_bool(node, "wakeup_bat_ovtemp_work");
1308 axp_config->wakeup_untemp_chg =
1309 of_property_read_bool(node, "wakeup_bat_untemp_chg");
1310 axp_config->wakeup_ovtemp_chg =
1311 of_property_read_bool(node, "wakeup_bat_ovtemp_chg");
1312 axp_config->wakeup_bat_ov =
1313 of_property_read_bool(node, "wakeup_bat_ov");
1314
1315
1316 return 0;
1317 }
1318
axp2202_bat_parse_device_tree(struct axp2202_bat_power * bat_power)1319 static void axp2202_bat_parse_device_tree(struct axp2202_bat_power *bat_power)
1320 {
1321 int ret;
1322 struct axp_config_info *axp_config;
1323
1324 /* set input current limit */
1325 if (!bat_power->dev->of_node) {
1326 pr_info("can not find device tree\n");
1327 return;
1328 }
1329
1330 axp_config = &bat_power->dts_info;
1331 ret = axp2202_bat_dt_parse(bat_power->dev->of_node, axp_config);
1332 if (ret) {
1333 pr_info("can not parse device tree err\n");
1334 return;
1335 }
1336 }
1337
axp2202_bat_power_monitor(struct work_struct * work)1338 static void axp2202_bat_power_monitor(struct work_struct *work)
1339 {
1340 struct axp2202_bat_power *bat_power =
1341 container_of(work, typeof(*bat_power), bat_supply_mon.work);
1342 unsigned char temp_val[2];
1343 unsigned int reg_value;
1344 int ret;
1345
1346 power_supply_changed(bat_power->bat_supply);
1347
1348 /* 0xb2, 0xb3 return mcoul high 16 bit value */
1349 reg_value = 0x2e;
1350 ret = regmap_write(bat_power->regmap, AXP2202_GAUGE_FG_ADDR, reg_value);
1351
1352 regmap_read(bat_power->regmap, AXP2202_GAUGE_CONFIG, ®_value);
1353 if (reg_value & BIT(4)) {
1354 regmap_read(bat_power->regmap, AXP2202_GAUGE_FG_ADDR, ®_value);
1355 if (reg_value == 0x2e) {
1356 /* reset gauge if is overflow */
1357 regmap_bulk_read(bat_power->regmap, AXP2202_GAUGE_FG_DATA_H, temp_val, 2);
1358 reg_value = (temp_val[0] << 8) + temp_val[1];
1359 if ((reg_value != 0xffff) && (reg_value != 0x0000)) {
1360 axp2202_reset_mcu(bat_power->regmap);
1361 pr_warn("reset gauge:mcoul overflow\n");
1362 }
1363 }
1364 }
1365
1366 schedule_delayed_work(&bat_power->bat_supply_mon, msecs_to_jiffies(10 * 1000));
1367 }
1368
1369
axp2202_battery_probe(struct platform_device * pdev)1370 static int axp2202_battery_probe(struct platform_device *pdev)
1371 {
1372 int ret = 0;
1373 int i = 0, irq;
1374
1375 struct axp2202_bat_power *bat_power;
1376 struct power_supply_config psy_cfg = {};
1377 struct axp20x_dev *axp_dev = dev_get_drvdata(pdev->dev.parent);
1378
1379 if (!axp_dev->irq) {
1380 pr_err("can not register axp2202-battery without irq\n");
1381 return -EINVAL;
1382 }
1383
1384 bat_power = devm_kzalloc(&pdev->dev, sizeof(*bat_power), GFP_KERNEL);
1385 if (bat_power == NULL) {
1386 pr_err("axp2202_bat_power alloc failed\n");
1387 ret = -ENOMEM;
1388 goto err;
1389 }
1390
1391 bat_power->name = "axp2202_battery";
1392 bat_power->dev = &pdev->dev;
1393 bat_power->regmap = axp_dev->regmap;
1394
1395 /* for device tree parse */
1396 axp2202_bat_parse_device_tree(bat_power);
1397
1398 ret = axp2202_init_chip(bat_power);
1399 if (ret < 0) {
1400 dev_err(bat_power->dev, "axp2202 init chip fail!\n");
1401 ret = -ENODEV;
1402 goto err;
1403 }
1404
1405 psy_cfg.of_node = pdev->dev.of_node;
1406 psy_cfg.drv_data = bat_power;
1407
1408 bat_power->bat_supply = devm_power_supply_register(bat_power->dev,
1409 &axp2202_bat_desc, &psy_cfg);
1410
1411 if (IS_ERR(bat_power->bat_supply)) {
1412 pr_err("axp2202 failed to register bat power\n");
1413 ret = PTR_ERR(bat_power->bat_supply);
1414 return ret;
1415 }
1416
1417 for (i = 0; i < ARRAY_SIZE(axp_bat_irq); i++) {
1418 irq = platform_get_irq_byname(pdev, axp_bat_irq[i].name);
1419 if (irq < 0)
1420 continue;
1421
1422 irq = regmap_irq_get_virq(axp_dev->regmap_irqc, irq);
1423 if (irq < 0) {
1424 dev_err(&pdev->dev, "can not get irq\n");
1425 return irq;
1426 }
1427 /* we use this variable to suspend irq */
1428 axp_bat_irq[i].irq = irq;
1429 ret = devm_request_any_context_irq(&pdev->dev, irq,
1430 axp_bat_irq[i].isr, 0,
1431 axp_bat_irq[i].name, bat_power);
1432 if (ret < 0) {
1433 dev_err(&pdev->dev, "failed to request %s IRQ %d: %d\n",
1434 axp_bat_irq[i].name, irq, ret);
1435 return ret;
1436 } else {
1437 ret = 0;
1438 }
1439
1440 dev_dbg(&pdev->dev, "Requested %s IRQ %d: %d\n",
1441 axp_bat_irq[i].name, irq, ret);
1442 }
1443 platform_set_drvdata(pdev, bat_power);
1444
1445 INIT_DELAYED_WORK(&bat_power->bat_supply_mon, axp2202_bat_power_monitor);
1446 schedule_delayed_work(&bat_power->bat_supply_mon, msecs_to_jiffies(500));
1447
1448 return ret;
1449
1450 err:
1451 pr_err("%s,probe fail, ret = %d\n", __func__, ret);
1452
1453 return ret;
1454 }
1455
axp2202_battery_remove(struct platform_device * pdev)1456 static int axp2202_battery_remove(struct platform_device *pdev)
1457 {
1458 struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1459
1460 dev_dbg(&pdev->dev, "==============AXP2202 unegister==============\n");
1461 if (bat_power->bat_supply)
1462 power_supply_unregister(bat_power->bat_supply);
1463 dev_dbg(&pdev->dev, "axp2202 teardown battery dev\n");
1464
1465 return 0;
1466 }
1467
axp2202_charger_ichg_set(struct axp2202_bat_power * bat_power,int mA)1468 static void axp2202_charger_ichg_set(struct axp2202_bat_power *bat_power, int mA)
1469 {
1470
1471 mA = clamp_val(mA, 0, 3072);
1472 mA = mA / 64;
1473 /* bit 5:0 is the ctrl bit */
1474 regmap_update_bits(bat_power->regmap, AXP2202_ICC_CFG, GENMASK(5, 0), mA);
1475 }
1476
axp2202_bat_irq_set(unsigned int irq,bool enable)1477 static inline void axp2202_bat_irq_set(unsigned int irq, bool enable)
1478 {
1479 if (enable)
1480 enable_irq(irq);
1481 else
1482 disable_irq(irq);
1483 }
1484
axp2202_bat_virq_dts_set(struct axp2202_bat_power * bat_power,bool enable)1485 static void axp2202_bat_virq_dts_set(struct axp2202_bat_power *bat_power, bool enable)
1486 {
1487 struct axp_config_info *dts_info = &bat_power->dts_info;
1488
1489 if (!dts_info->wakeup_bat_in)
1490 axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_BAT_IN].irq,
1491 enable);
1492 if (!dts_info->wakeup_bat_out)
1493 axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_BAT_OUT].irq,
1494 enable);
1495 if (!dts_info->wakeup_bat_charging)
1496 axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_CHARGING].irq,
1497 enable);
1498 if (!dts_info->wakeup_bat_charge_over)
1499 axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_CHARGE_OVER].irq,
1500 enable);
1501 if (!dts_info->wakeup_low_warning1)
1502 axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_LOW_WARNING1].irq,
1503 enable);
1504 if (!dts_info->wakeup_low_warning2)
1505 axp2202_bat_irq_set(axp_bat_irq[AXP2202_VIRQ_LOW_WARNING2].irq,
1506 enable);
1507 if (!dts_info->wakeup_bat_untemp_work)
1508 axp2202_bat_irq_set(
1509 axp_bat_irq[AXP2202_VIRQ_BAT_UNTEMP_WORK].irq,
1510 enable);
1511 if (!dts_info->wakeup_bat_ovtemp_work)
1512 axp2202_bat_irq_set(
1513 axp_bat_irq[AXP2202_VIRQ_BAT_OVTEMP_WORK].irq,
1514 enable);
1515 if (!dts_info->wakeup_untemp_chg)
1516 axp2202_bat_irq_set(
1517 axp_bat_irq[AXP2202_VIRQ_BAT_UNTEMP_CHG].irq,
1518 enable);
1519 if (!dts_info->wakeup_ovtemp_chg)
1520 axp2202_bat_irq_set(
1521 axp_bat_irq[AXP2202_VIRQ_BAT_OVTEMP_CHG].irq,
1522 enable);
1523 if (!dts_info->wakeup_bat_ov)
1524 axp2202_bat_irq_set(
1525 axp_bat_irq[AXP2202_VIRQ_BAT_OV].irq,
1526 enable);
1527
1528 }
1529
axp2202_bat_shutdown(struct platform_device * pdev)1530 static void axp2202_bat_shutdown(struct platform_device *pdev)
1531 {
1532 struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1533
1534 axp2202_charger_ichg_set(bat_power, bat_power->dts_info.pmu_shutdown_chgcur);
1535
1536 }
1537
axp2202_bat_suspend(struct platform_device * pdev,pm_message_t state)1538 static int axp2202_bat_suspend(struct platform_device *pdev, pm_message_t state)
1539 {
1540 struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1541
1542 axp2202_charger_ichg_set(bat_power, bat_power->dts_info.pmu_suspend_chgcur);
1543
1544 axp2202_bat_virq_dts_set(bat_power, false);
1545 return 0;
1546 }
1547
axp2202_bat_resume(struct platform_device * pdev)1548 static int axp2202_bat_resume(struct platform_device *pdev)
1549 {
1550 struct axp2202_bat_power *bat_power = platform_get_drvdata(pdev);
1551
1552 power_supply_changed(bat_power->bat_supply);
1553
1554 axp2202_charger_ichg_set(bat_power, bat_power->dts_info.pmu_runtime_chgcur);
1555
1556 axp2202_bat_virq_dts_set(bat_power, true);
1557
1558 return 0;
1559 }
1560
1561 static const struct of_device_id axp2202_bat_power_match[] = {
1562 {
1563 .compatible = "x-powers,axp2202-bat-power-supply",
1564 .data = (void *)AXP2202_ID,
1565 }, {/* sentinel */}
1566 };
1567 MODULE_DEVICE_TABLE(of, axp2202_bat_power_match);
1568
1569 static struct platform_driver axp2202_bat_power_driver = {
1570 .driver = {
1571 .name = "axp2202-bat-power-supply",
1572 .of_match_table = axp2202_bat_power_match,
1573 },
1574 .probe = axp2202_battery_probe,
1575 .remove = axp2202_battery_remove,
1576 .shutdown = axp2202_bat_shutdown,
1577 .suspend = axp2202_bat_suspend,
1578 .resume = axp2202_bat_resume,
1579 };
1580
1581 module_platform_driver(axp2202_bat_power_driver);
1582
1583 MODULE_AUTHOR("wangxiaoliang <wangxiaoliang@x-powers.com>");
1584 MODULE_DESCRIPTION("axp2202 battery driver");
1585 MODULE_LICENSE("GPL");
1586
1587
1588