1 /*
2 * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs
3 *
4 * Copyright 2016 Free Electrons NextThing Co.
5 * Quentin Schulz <quentin.schulz@free-electrons.com>
6 *
7 * This driver is based on a previous upstreaming attempt by:
8 * Bruno Prémont <bonbons@linux-vserver.org>
9 *
10 * This file is subject to the terms and conditions of the GNU General
11 * Public License. See the file "COPYING" in the main directory of this
12 * archive for more details.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20 #include <linux/bitfield.h>
21 #include <linux/err.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/module.h>
25 #include <linux/of.h>
26 #include <linux/platform_device.h>
27 #include <linux/power_supply.h>
28 #include <linux/regmap.h>
29 #include <linux/slab.h>
30 #include <linux/time.h>
31 #include <linux/iio/iio.h>
32 #include <linux/iio/consumer.h>
33 #include <linux/mfd/axp20x.h>
34
35 #define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2)
36 #define AXP717_PWR_STATUS_MASK GENMASK(6, 5)
37 #define AXP717_PWR_STATUS_BAT_STANDBY 0
38 #define AXP717_PWR_STATUS_BAT_CHRG 1
39 #define AXP717_PWR_STATUS_BAT_DISCHRG 2
40
41 #define AXP20X_PWR_OP_BATT_PRESENT BIT(5)
42 #define AXP20X_PWR_OP_BATT_ACTIVATED BIT(3)
43 #define AXP717_PWR_OP_BATT_PRESENT BIT(3)
44
45 #define AXP717_BATT_PMU_FAULT_MASK GENMASK(2, 0)
46 #define AXP717_BATT_UVLO_2_5V BIT(2)
47 #define AXP717_BATT_OVER_TEMP BIT(1)
48 #define AXP717_BATT_UNDER_TEMP BIT(0)
49
50 #define AXP209_FG_PERCENT GENMASK(6, 0)
51 #define AXP22X_FG_VALID BIT(7)
52
53 #define AXP20X_CHRG_CTRL1_ENABLE BIT(7)
54 #define AXP20X_CHRG_CTRL1_TGT_VOLT GENMASK(6, 5)
55 #define AXP20X_CHRG_CTRL1_TGT_4_1V (0 << 5)
56 #define AXP20X_CHRG_CTRL1_TGT_4_15V (1 << 5)
57 #define AXP20X_CHRG_CTRL1_TGT_4_2V (2 << 5)
58 #define AXP20X_CHRG_CTRL1_TGT_4_36V (3 << 5)
59
60 #define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5)
61 #define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5)
62
63 #define AXP717_CHRG_ENABLE BIT(1)
64 #define AXP717_CHRG_CV_VOLT_MASK GENMASK(2, 0)
65 #define AXP717_CHRG_CV_4_0V 0
66 #define AXP717_CHRG_CV_4_1V 1
67 #define AXP717_CHRG_CV_4_2V 2
68 #define AXP717_CHRG_CV_4_35V 3
69 #define AXP717_CHRG_CV_4_4V 4
70 /* Values 5 and 6 reserved. */
71 #define AXP717_CHRG_CV_5_0V 7
72
73 #define AXP813_CHRG_CTRL1_TGT_4_35V (3 << 5)
74
75 #define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0)
76 #define AXP717_ICC_CHARGER_LIM_MASK GENMASK(5, 0)
77
78 #define AXP717_ITERM_CHG_LIM_MASK GENMASK(3, 0)
79 #define AXP717_ITERM_CC_STEP 64000
80
81 #define AXP20X_V_OFF_MASK GENMASK(2, 0)
82 #define AXP717_V_OFF_MASK GENMASK(6, 4)
83
84 #define AXP717_BAT_VMIN_MIN_UV 2600000
85 #define AXP717_BAT_VMIN_MAX_UV 3300000
86 #define AXP717_BAT_VMIN_STEP 100000
87 #define AXP717_BAT_CV_MIN_UV 4000000
88 #define AXP717_BAT_CV_MAX_UV 5000000
89 #define AXP717_BAT_CC_MIN_UA 0
90 #define AXP717_BAT_CC_MAX_UA 3008000
91
92 struct axp20x_batt_ps;
93
94 struct axp_data {
95 int ccc_scale;
96 int ccc_offset;
97 unsigned int ccc_reg;
98 unsigned int ccc_mask;
99 bool has_fg_valid;
100 const struct power_supply_desc *bat_ps_desc;
101 int (*get_max_voltage)(struct axp20x_batt_ps *batt, int *val);
102 int (*set_max_voltage)(struct axp20x_batt_ps *batt, int val);
103 int (*cfg_iio_chan)(struct platform_device *pdev,
104 struct axp20x_batt_ps *axp_batt);
105 void (*set_bat_info)(struct platform_device *pdev,
106 struct axp20x_batt_ps *axp_batt,
107 struct power_supply_battery_info *info);
108 };
109
110 struct axp20x_batt_ps {
111 struct regmap *regmap;
112 struct power_supply *batt;
113 struct device *dev;
114 struct iio_channel *batt_chrg_i;
115 struct iio_channel *batt_dischrg_i;
116 struct iio_channel *batt_v;
117 /* Maximum constant charge current */
118 unsigned int max_ccc;
119 const struct axp_data *data;
120 };
121
axp20x_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)122 static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
123 int *val)
124 {
125 int ret, reg;
126
127 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®);
128 if (ret)
129 return ret;
130
131 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
132 case AXP20X_CHRG_CTRL1_TGT_4_1V:
133 *val = 4100000;
134 break;
135 case AXP20X_CHRG_CTRL1_TGT_4_15V:
136 *val = 4150000;
137 break;
138 case AXP20X_CHRG_CTRL1_TGT_4_2V:
139 *val = 4200000;
140 break;
141 case AXP20X_CHRG_CTRL1_TGT_4_36V:
142 *val = 4360000;
143 break;
144 default:
145 return -EINVAL;
146 }
147
148 return 0;
149 }
150
axp22x_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)151 static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
152 int *val)
153 {
154 int ret, reg;
155
156 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®);
157 if (ret)
158 return ret;
159
160 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
161 case AXP20X_CHRG_CTRL1_TGT_4_1V:
162 *val = 4100000;
163 break;
164 case AXP20X_CHRG_CTRL1_TGT_4_2V:
165 *val = 4200000;
166 break;
167 case AXP22X_CHRG_CTRL1_TGT_4_22V:
168 *val = 4220000;
169 break;
170 case AXP22X_CHRG_CTRL1_TGT_4_24V:
171 *val = 4240000;
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 return 0;
178 }
179
axp717_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)180 static int axp717_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
181 int *val)
182 {
183 int ret, reg;
184
185 ret = regmap_read(axp20x_batt->regmap, AXP717_CV_CHG_SET, ®);
186 if (ret)
187 return ret;
188
189 switch (reg & AXP717_CHRG_CV_VOLT_MASK) {
190 case AXP717_CHRG_CV_4_0V:
191 *val = 4000000;
192 return 0;
193 case AXP717_CHRG_CV_4_1V:
194 *val = 4100000;
195 return 0;
196 case AXP717_CHRG_CV_4_2V:
197 *val = 4200000;
198 return 0;
199 case AXP717_CHRG_CV_4_35V:
200 *val = 4350000;
201 return 0;
202 case AXP717_CHRG_CV_4_4V:
203 *val = 4400000;
204 return 0;
205 case AXP717_CHRG_CV_5_0V:
206 *val = 5000000;
207 return 0;
208 default:
209 return -EINVAL;
210 }
211 }
212
axp813_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)213 static int axp813_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
214 int *val)
215 {
216 int ret, reg;
217
218 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, ®);
219 if (ret)
220 return ret;
221
222 switch (reg & AXP20X_CHRG_CTRL1_TGT_VOLT) {
223 case AXP20X_CHRG_CTRL1_TGT_4_1V:
224 *val = 4100000;
225 break;
226 case AXP20X_CHRG_CTRL1_TGT_4_15V:
227 *val = 4150000;
228 break;
229 case AXP20X_CHRG_CTRL1_TGT_4_2V:
230 *val = 4200000;
231 break;
232 case AXP813_CHRG_CTRL1_TGT_4_35V:
233 *val = 4350000;
234 break;
235 default:
236 return -EINVAL;
237 }
238
239 return 0;
240 }
241
axp20x_get_constant_charge_current(struct axp20x_batt_ps * axp,int * val)242 static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp,
243 int *val)
244 {
245 int ret;
246
247 ret = regmap_read(axp->regmap, AXP20X_CHRG_CTRL1, val);
248 if (ret)
249 return ret;
250
251 *val &= AXP20X_CHRG_CTRL1_TGT_CURR;
252
253 *val = *val * axp->data->ccc_scale + axp->data->ccc_offset;
254
255 return 0;
256 }
257
axp717_get_constant_charge_current(struct axp20x_batt_ps * axp,int * val)258 static int axp717_get_constant_charge_current(struct axp20x_batt_ps *axp,
259 int *val)
260 {
261 int ret;
262
263 ret = regmap_read(axp->regmap, AXP717_ICC_CHG_SET, val);
264 if (ret)
265 return ret;
266
267 *val = FIELD_GET(AXP717_ICC_CHARGER_LIM_MASK, *val) *
268 axp->data->ccc_scale;
269
270 return 0;
271 }
272
axp20x_battery_get_prop(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)273 static int axp20x_battery_get_prop(struct power_supply *psy,
274 enum power_supply_property psp,
275 union power_supply_propval *val)
276 {
277 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
278 int ret = 0, reg, val1;
279
280 switch (psp) {
281 case POWER_SUPPLY_PROP_PRESENT:
282 case POWER_SUPPLY_PROP_ONLINE:
283 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
284 ®);
285 if (ret)
286 return ret;
287
288 val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT);
289 break;
290
291 case POWER_SUPPLY_PROP_STATUS:
292 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
293 ®);
294 if (ret)
295 return ret;
296
297 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
298 val->intval = POWER_SUPPLY_STATUS_CHARGING;
299 return 0;
300 }
301
302 ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i,
303 &val1);
304 if (ret)
305 return ret;
306
307 if (val1) {
308 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
309 return 0;
310 }
311
312 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1);
313 if (ret)
314 return ret;
315
316 /*
317 * Fuel Gauge data takes 7 bits but the stored value seems to be
318 * directly the raw percentage without any scaling to 7 bits.
319 */
320 if ((val1 & AXP209_FG_PERCENT) == 100)
321 val->intval = POWER_SUPPLY_STATUS_FULL;
322 else
323 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
324 break;
325
326 case POWER_SUPPLY_PROP_HEALTH:
327 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
328 &val1);
329 if (ret)
330 return ret;
331
332 if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) {
333 val->intval = POWER_SUPPLY_HEALTH_DEAD;
334 return 0;
335 }
336
337 val->intval = POWER_SUPPLY_HEALTH_GOOD;
338 break;
339
340 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
341 ret = axp20x_get_constant_charge_current(axp20x_batt,
342 &val->intval);
343 if (ret)
344 return ret;
345 break;
346
347 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
348 val->intval = axp20x_batt->max_ccc;
349 break;
350
351 case POWER_SUPPLY_PROP_CURRENT_NOW:
352 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
353 ®);
354 if (ret)
355 return ret;
356
357 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
358 ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval);
359 } else {
360 ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, &val1);
361 val->intval = -val1;
362 }
363 if (ret)
364 return ret;
365
366 /* IIO framework gives mA but Power Supply framework gives uA */
367 val->intval *= 1000;
368 break;
369
370 case POWER_SUPPLY_PROP_CAPACITY:
371 /* When no battery is present, return capacity is 100% */
372 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
373 ®);
374 if (ret)
375 return ret;
376
377 if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
378 val->intval = 100;
379 return 0;
380 }
381
382 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, ®);
383 if (ret)
384 return ret;
385
386 if (axp20x_batt->data->has_fg_valid && !(reg & AXP22X_FG_VALID))
387 return -EINVAL;
388
389 /*
390 * Fuel Gauge data takes 7 bits but the stored value seems to be
391 * directly the raw percentage without any scaling to 7 bits.
392 */
393 val->intval = reg & AXP209_FG_PERCENT;
394 break;
395
396 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
397 return axp20x_batt->data->get_max_voltage(axp20x_batt,
398 &val->intval);
399
400 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
401 ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®);
402 if (ret)
403 return ret;
404
405 val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
406 break;
407
408 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
409 ret = iio_read_channel_processed(axp20x_batt->batt_v,
410 &val->intval);
411 if (ret)
412 return ret;
413
414 /* IIO framework gives mV but Power Supply framework gives uV */
415 val->intval *= 1000;
416 break;
417
418 default:
419 return -EINVAL;
420 }
421
422 return 0;
423 }
424
axp717_battery_get_prop(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)425 static int axp717_battery_get_prop(struct power_supply *psy,
426 enum power_supply_property psp,
427 union power_supply_propval *val)
428 {
429 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
430 int ret = 0, reg;
431
432 switch (psp) {
433 case POWER_SUPPLY_PROP_PRESENT:
434 case POWER_SUPPLY_PROP_ONLINE:
435 ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
436 ®);
437 if (ret)
438 return ret;
439
440 val->intval = FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg);
441 return 0;
442
443 case POWER_SUPPLY_PROP_STATUS:
444 ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_STATUS_2,
445 ®);
446 if (ret)
447 return ret;
448
449 switch (FIELD_GET(AXP717_PWR_STATUS_MASK, reg)) {
450 case AXP717_PWR_STATUS_BAT_STANDBY:
451 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
452 return 0;
453
454 case AXP717_PWR_STATUS_BAT_CHRG:
455 val->intval = POWER_SUPPLY_STATUS_CHARGING;
456 return 0;
457
458 case AXP717_PWR_STATUS_BAT_DISCHRG:
459 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
460 return 0;
461
462 default:
463 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
464 return 0;
465 }
466
467 /*
468 * If a fault is detected it must also be cleared; if the
469 * condition persists it should reappear (This is an
470 * assumption, it's actually not documented). A restart was
471 * not sufficient to clear the bit in testing despite the
472 * register listed as POR.
473 */
474 case POWER_SUPPLY_PROP_HEALTH:
475 ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_FAULT,
476 ®);
477 if (ret)
478 return ret;
479
480 switch (reg & AXP717_BATT_PMU_FAULT_MASK) {
481 case AXP717_BATT_UVLO_2_5V:
482 val->intval = POWER_SUPPLY_HEALTH_DEAD;
483 regmap_update_bits(axp20x_batt->regmap,
484 AXP717_PMU_FAULT,
485 AXP717_BATT_UVLO_2_5V,
486 AXP717_BATT_UVLO_2_5V);
487 return 0;
488
489 case AXP717_BATT_OVER_TEMP:
490 val->intval = POWER_SUPPLY_HEALTH_HOT;
491 regmap_update_bits(axp20x_batt->regmap,
492 AXP717_PMU_FAULT,
493 AXP717_BATT_OVER_TEMP,
494 AXP717_BATT_OVER_TEMP);
495 return 0;
496
497 case AXP717_BATT_UNDER_TEMP:
498 val->intval = POWER_SUPPLY_HEALTH_COLD;
499 regmap_update_bits(axp20x_batt->regmap,
500 AXP717_PMU_FAULT,
501 AXP717_BATT_UNDER_TEMP,
502 AXP717_BATT_UNDER_TEMP);
503 return 0;
504
505 default:
506 val->intval = POWER_SUPPLY_HEALTH_GOOD;
507 return 0;
508 }
509
510 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
511 ret = axp717_get_constant_charge_current(axp20x_batt,
512 &val->intval);
513 if (ret)
514 return ret;
515 return 0;
516
517 case POWER_SUPPLY_PROP_CURRENT_NOW:
518 /*
519 * The offset of this value is currently unknown and is
520 * not documented in the datasheet. Based on
521 * observation it's assumed to be somewhere around
522 * 450ma. I will leave the value raw for now.
523 */
524 ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval);
525 if (ret)
526 return ret;
527 /* IIO framework gives mA but Power Supply framework gives uA */
528 val->intval *= 1000;
529 return 0;
530
531 case POWER_SUPPLY_PROP_CAPACITY:
532 ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
533 ®);
534 if (ret)
535 return ret;
536
537 if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg))
538 return -ENODEV;
539
540 ret = regmap_read(axp20x_batt->regmap,
541 AXP717_BATT_PERCENT_DATA, ®);
542 if (ret)
543 return ret;
544
545 /*
546 * Fuel Gauge data takes 7 bits but the stored value seems to be
547 * directly the raw percentage without any scaling to 7 bits.
548 */
549 val->intval = reg & AXP209_FG_PERCENT;
550 return 0;
551
552 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
553 return axp20x_batt->data->get_max_voltage(axp20x_batt,
554 &val->intval);
555
556 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
557 ret = regmap_read(axp20x_batt->regmap,
558 AXP717_VSYS_V_POWEROFF, ®);
559 if (ret)
560 return ret;
561
562 val->intval = AXP717_BAT_VMIN_MIN_UV + AXP717_BAT_VMIN_STEP *
563 (reg & AXP717_V_OFF_MASK);
564 return 0;
565
566 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
567 ret = iio_read_channel_processed(axp20x_batt->batt_v,
568 &val->intval);
569 if (ret)
570 return ret;
571
572 /* IIO framework gives mV but Power Supply framework gives uV */
573 val->intval *= 1000;
574 return 0;
575
576 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
577 ret = regmap_read(axp20x_batt->regmap,
578 AXP717_ITERM_CHG_SET, ®);
579 if (ret)
580 return ret;
581
582 val->intval = (reg & AXP717_ITERM_CHG_LIM_MASK) * AXP717_ITERM_CC_STEP;
583 return 0;
584
585 default:
586 return -EINVAL;
587 }
588 }
589
axp22x_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)590 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
591 int val)
592 {
593 switch (val) {
594 case 4100000:
595 val = AXP20X_CHRG_CTRL1_TGT_4_1V;
596 break;
597
598 case 4200000:
599 val = AXP20X_CHRG_CTRL1_TGT_4_2V;
600 break;
601
602 default:
603 /*
604 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
605 * can be set to 4.22V and 4.24V, but these voltages are too
606 * high for Lithium based batteries (AXP PMICs are supposed to
607 * be used with these kinds of battery).
608 */
609 return -EINVAL;
610 }
611
612 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
613 AXP20X_CHRG_CTRL1_TGT_VOLT, val);
614 }
615
axp20x_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)616 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
617 int val)
618 {
619 switch (val) {
620 case 4100000:
621 val = AXP20X_CHRG_CTRL1_TGT_4_1V;
622 break;
623
624 case 4150000:
625 val = AXP20X_CHRG_CTRL1_TGT_4_15V;
626 break;
627
628 case 4200000:
629 val = AXP20X_CHRG_CTRL1_TGT_4_2V;
630 break;
631
632 default:
633 /*
634 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
635 * can be set to 4.22V and 4.24V, but these voltages are too
636 * high for Lithium based batteries (AXP PMICs are supposed to
637 * be used with these kinds of battery).
638 */
639 return -EINVAL;
640 }
641
642 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
643 AXP20X_CHRG_CTRL1_TGT_VOLT, val);
644 }
645
axp717_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)646 static int axp717_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
647 int val)
648 {
649 switch (val) {
650 case 4000000:
651 val = AXP717_CHRG_CV_4_0V;
652 break;
653
654 case 4100000:
655 val = AXP717_CHRG_CV_4_1V;
656 break;
657
658 case 4200000:
659 val = AXP717_CHRG_CV_4_2V;
660 break;
661
662 default:
663 /*
664 * AXP717 can go up to 4.35, 4.4, and 5.0 volts which
665 * seem too high for lithium batteries, so do not allow.
666 */
667 return -EINVAL;
668 }
669
670 return regmap_update_bits(axp20x_batt->regmap,
671 AXP717_CV_CHG_SET,
672 AXP717_CHRG_CV_VOLT_MASK, val);
673 }
674
axp20x_set_constant_charge_current(struct axp20x_batt_ps * axp_batt,int charge_current)675 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt,
676 int charge_current)
677 {
678 if (charge_current > axp_batt->max_ccc)
679 return -EINVAL;
680
681 charge_current = (charge_current - axp_batt->data->ccc_offset) /
682 axp_batt->data->ccc_scale;
683
684 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
685 return -EINVAL;
686
687 return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1,
688 AXP20X_CHRG_CTRL1_TGT_CURR, charge_current);
689 }
690
axp717_set_constant_charge_current(struct axp20x_batt_ps * axp,int charge_current)691 static int axp717_set_constant_charge_current(struct axp20x_batt_ps *axp,
692 int charge_current)
693 {
694 int val;
695
696 if (charge_current > axp->max_ccc)
697 return -EINVAL;
698
699 if (charge_current > AXP717_BAT_CC_MAX_UA || charge_current < 0)
700 return -EINVAL;
701
702 val = (charge_current - axp->data->ccc_offset) /
703 axp->data->ccc_scale;
704
705 return regmap_update_bits(axp->regmap, AXP717_ICC_CHG_SET,
706 AXP717_ICC_CHARGER_LIM_MASK, val);
707 }
708
axp20x_set_max_constant_charge_current(struct axp20x_batt_ps * axp,int charge_current)709 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp,
710 int charge_current)
711 {
712 bool lower_max = false;
713
714 charge_current = (charge_current - axp->data->ccc_offset) /
715 axp->data->ccc_scale;
716
717 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
718 return -EINVAL;
719
720 charge_current = charge_current * axp->data->ccc_scale +
721 axp->data->ccc_offset;
722
723 if (charge_current > axp->max_ccc)
724 dev_warn(axp->dev,
725 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n");
726 else
727 lower_max = true;
728
729 axp->max_ccc = charge_current;
730
731 if (lower_max) {
732 int current_cc;
733
734 axp20x_get_constant_charge_current(axp, ¤t_cc);
735 if (current_cc > charge_current)
736 axp20x_set_constant_charge_current(axp, charge_current);
737 }
738
739 return 0;
740 }
axp20x_set_voltage_min_design(struct axp20x_batt_ps * axp_batt,int min_voltage)741 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
742 int min_voltage)
743 {
744 int val1 = (min_voltage - 2600000) / 100000;
745
746 if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
747 return -EINVAL;
748
749 return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF,
750 AXP20X_V_OFF_MASK, val1);
751 }
752
axp717_set_voltage_min_design(struct axp20x_batt_ps * axp_batt,int min_voltage)753 static int axp717_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
754 int min_voltage)
755 {
756 int val1 = (min_voltage - AXP717_BAT_VMIN_MIN_UV) / AXP717_BAT_VMIN_STEP;
757
758 if (val1 < 0 || val1 > AXP717_V_OFF_MASK)
759 return -EINVAL;
760
761 return regmap_update_bits(axp_batt->regmap,
762 AXP717_VSYS_V_POWEROFF,
763 AXP717_V_OFF_MASK, val1);
764 }
765
axp20x_battery_set_prop(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)766 static int axp20x_battery_set_prop(struct power_supply *psy,
767 enum power_supply_property psp,
768 const union power_supply_propval *val)
769 {
770 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
771
772 switch (psp) {
773 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
774 return axp20x_set_voltage_min_design(axp20x_batt, val->intval);
775
776 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
777 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
778
779 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
780 return axp20x_set_constant_charge_current(axp20x_batt,
781 val->intval);
782 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
783 return axp20x_set_max_constant_charge_current(axp20x_batt,
784 val->intval);
785 case POWER_SUPPLY_PROP_STATUS:
786 switch (val->intval) {
787 case POWER_SUPPLY_STATUS_CHARGING:
788 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
789 AXP20X_CHRG_CTRL1_ENABLE, AXP20X_CHRG_CTRL1_ENABLE);
790
791 case POWER_SUPPLY_STATUS_DISCHARGING:
792 case POWER_SUPPLY_STATUS_NOT_CHARGING:
793 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
794 AXP20X_CHRG_CTRL1_ENABLE, 0);
795 }
796 fallthrough;
797 default:
798 return -EINVAL;
799 }
800 }
801
axp717_battery_set_prop(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)802 static int axp717_battery_set_prop(struct power_supply *psy,
803 enum power_supply_property psp,
804 const union power_supply_propval *val)
805 {
806 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
807
808 switch (psp) {
809 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
810 return axp717_set_voltage_min_design(axp20x_batt, val->intval);
811
812 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
813 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
814
815 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
816 return axp717_set_constant_charge_current(axp20x_batt,
817 val->intval);
818 case POWER_SUPPLY_PROP_STATUS:
819 switch (val->intval) {
820 case POWER_SUPPLY_STATUS_CHARGING:
821 return regmap_update_bits(axp20x_batt->regmap,
822 AXP717_MODULE_EN_CONTROL_2,
823 AXP717_CHRG_ENABLE,
824 AXP717_CHRG_ENABLE);
825
826 case POWER_SUPPLY_STATUS_DISCHARGING:
827 case POWER_SUPPLY_STATUS_NOT_CHARGING:
828 return regmap_update_bits(axp20x_batt->regmap,
829 AXP717_MODULE_EN_CONTROL_2,
830 AXP717_CHRG_ENABLE, 0);
831 }
832 return -EINVAL;
833 default:
834 return -EINVAL;
835 }
836 }
837
838 static enum power_supply_property axp20x_battery_props[] = {
839 POWER_SUPPLY_PROP_PRESENT,
840 POWER_SUPPLY_PROP_ONLINE,
841 POWER_SUPPLY_PROP_STATUS,
842 POWER_SUPPLY_PROP_VOLTAGE_NOW,
843 POWER_SUPPLY_PROP_CURRENT_NOW,
844 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
845 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
846 POWER_SUPPLY_PROP_HEALTH,
847 POWER_SUPPLY_PROP_VOLTAGE_MAX,
848 POWER_SUPPLY_PROP_VOLTAGE_MIN,
849 POWER_SUPPLY_PROP_CAPACITY,
850 };
851
852 static enum power_supply_property axp717_battery_props[] = {
853 POWER_SUPPLY_PROP_PRESENT,
854 POWER_SUPPLY_PROP_ONLINE,
855 POWER_SUPPLY_PROP_STATUS,
856 POWER_SUPPLY_PROP_VOLTAGE_NOW,
857 POWER_SUPPLY_PROP_CURRENT_NOW,
858 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
859 POWER_SUPPLY_PROP_HEALTH,
860 POWER_SUPPLY_PROP_VOLTAGE_MAX,
861 POWER_SUPPLY_PROP_VOLTAGE_MIN,
862 POWER_SUPPLY_PROP_CAPACITY,
863 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
864 };
865
axp20x_battery_prop_writeable(struct power_supply * psy,enum power_supply_property psp)866 static int axp20x_battery_prop_writeable(struct power_supply *psy,
867 enum power_supply_property psp)
868 {
869 return psp == POWER_SUPPLY_PROP_STATUS ||
870 psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
871 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
872 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT ||
873 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
874 }
875
axp717_battery_prop_writeable(struct power_supply * psy,enum power_supply_property psp)876 static int axp717_battery_prop_writeable(struct power_supply *psy,
877 enum power_supply_property psp)
878 {
879 return psp == POWER_SUPPLY_PROP_STATUS ||
880 psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
881 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
882 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
883 }
884
885 static const struct power_supply_desc axp209_batt_ps_desc = {
886 .name = "axp20x-battery",
887 .type = POWER_SUPPLY_TYPE_BATTERY,
888 .properties = axp20x_battery_props,
889 .num_properties = ARRAY_SIZE(axp20x_battery_props),
890 .property_is_writeable = axp20x_battery_prop_writeable,
891 .get_property = axp20x_battery_get_prop,
892 .set_property = axp20x_battery_set_prop,
893 };
894
895 static const struct power_supply_desc axp717_batt_ps_desc = {
896 .name = "axp20x-battery",
897 .type = POWER_SUPPLY_TYPE_BATTERY,
898 .properties = axp717_battery_props,
899 .num_properties = ARRAY_SIZE(axp717_battery_props),
900 .property_is_writeable = axp717_battery_prop_writeable,
901 .get_property = axp717_battery_get_prop,
902 .set_property = axp717_battery_set_prop,
903 };
904
axp209_bat_cfg_iio_channels(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt)905 static int axp209_bat_cfg_iio_channels(struct platform_device *pdev,
906 struct axp20x_batt_ps *axp_batt)
907 {
908 axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
909 if (IS_ERR(axp_batt->batt_v)) {
910 if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
911 return -EPROBE_DEFER;
912 return PTR_ERR(axp_batt->batt_v);
913 }
914
915 axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
916 "batt_chrg_i");
917 if (IS_ERR(axp_batt->batt_chrg_i)) {
918 if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
919 return -EPROBE_DEFER;
920 return PTR_ERR(axp_batt->batt_chrg_i);
921 }
922
923 axp_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
924 "batt_dischrg_i");
925 if (IS_ERR(axp_batt->batt_dischrg_i)) {
926 if (PTR_ERR(axp_batt->batt_dischrg_i) == -ENODEV)
927 return -EPROBE_DEFER;
928 return PTR_ERR(axp_batt->batt_dischrg_i);
929 }
930
931 return 0;
932 }
933
axp717_bat_cfg_iio_channels(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt)934 static int axp717_bat_cfg_iio_channels(struct platform_device *pdev,
935 struct axp20x_batt_ps *axp_batt)
936 {
937 axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
938 if (IS_ERR(axp_batt->batt_v)) {
939 if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
940 return -EPROBE_DEFER;
941 return PTR_ERR(axp_batt->batt_v);
942 }
943
944 axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
945 "batt_chrg_i");
946 if (IS_ERR(axp_batt->batt_chrg_i)) {
947 if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
948 return -EPROBE_DEFER;
949 return PTR_ERR(axp_batt->batt_chrg_i);
950 }
951
952 return 0;
953 }
954
axp209_set_battery_info(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt,struct power_supply_battery_info * info)955 static void axp209_set_battery_info(struct platform_device *pdev,
956 struct axp20x_batt_ps *axp_batt,
957 struct power_supply_battery_info *info)
958 {
959 int vmin = info->voltage_min_design_uv;
960 int ccc = info->constant_charge_current_max_ua;
961
962 if (vmin > 0 && axp20x_set_voltage_min_design(axp_batt, vmin))
963 dev_err(&pdev->dev,
964 "couldn't set voltage_min_design\n");
965
966 /* Set max to unverified value to be able to set CCC */
967 axp_batt->max_ccc = ccc;
968
969 if (ccc <= 0 || axp20x_set_constant_charge_current(axp_batt, ccc)) {
970 dev_err(&pdev->dev,
971 "couldn't set ccc from DT: fallback to min value\n");
972 ccc = 300000;
973 axp_batt->max_ccc = ccc;
974 axp20x_set_constant_charge_current(axp_batt, ccc);
975 }
976 }
977
axp717_set_battery_info(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt,struct power_supply_battery_info * info)978 static void axp717_set_battery_info(struct platform_device *pdev,
979 struct axp20x_batt_ps *axp_batt,
980 struct power_supply_battery_info *info)
981 {
982 int vmin = info->voltage_min_design_uv;
983 int vmax = info->voltage_max_design_uv;
984 int ccc = info->constant_charge_current_max_ua;
985 int val;
986
987 if (vmin > 0 && axp717_set_voltage_min_design(axp_batt, vmin))
988 dev_err(&pdev->dev,
989 "couldn't set voltage_min_design\n");
990
991 if (vmax > 0 && axp717_battery_set_max_voltage(axp_batt, vmax))
992 dev_err(&pdev->dev,
993 "couldn't set voltage_max_design\n");
994
995 axp717_get_constant_charge_current(axp_batt, &val);
996 axp_batt->max_ccc = ccc;
997 if (ccc <= 0 || axp717_set_constant_charge_current(axp_batt, ccc)) {
998 dev_err(&pdev->dev,
999 "couldn't set ccc from DT: current ccc is %d\n",
1000 val);
1001 }
1002 }
1003
1004 static const struct axp_data axp209_data = {
1005 .ccc_scale = 100000,
1006 .ccc_offset = 300000,
1007 .ccc_reg = AXP20X_CHRG_CTRL1,
1008 .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1009 .bat_ps_desc = &axp209_batt_ps_desc,
1010 .get_max_voltage = axp20x_battery_get_max_voltage,
1011 .set_max_voltage = axp20x_battery_set_max_voltage,
1012 .cfg_iio_chan = axp209_bat_cfg_iio_channels,
1013 .set_bat_info = axp209_set_battery_info,
1014 };
1015
1016 static const struct axp_data axp221_data = {
1017 .ccc_scale = 150000,
1018 .ccc_offset = 300000,
1019 .ccc_reg = AXP20X_CHRG_CTRL1,
1020 .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1021 .has_fg_valid = true,
1022 .bat_ps_desc = &axp209_batt_ps_desc,
1023 .get_max_voltage = axp22x_battery_get_max_voltage,
1024 .set_max_voltage = axp22x_battery_set_max_voltage,
1025 .cfg_iio_chan = axp209_bat_cfg_iio_channels,
1026 .set_bat_info = axp209_set_battery_info,
1027 };
1028
1029 static const struct axp_data axp717_data = {
1030 .ccc_scale = 64000,
1031 .ccc_offset = 0,
1032 .ccc_reg = AXP717_ICC_CHG_SET,
1033 .ccc_mask = AXP717_ICC_CHARGER_LIM_MASK,
1034 .bat_ps_desc = &axp717_batt_ps_desc,
1035 .get_max_voltage = axp717_battery_get_max_voltage,
1036 .set_max_voltage = axp717_battery_set_max_voltage,
1037 .cfg_iio_chan = axp717_bat_cfg_iio_channels,
1038 .set_bat_info = axp717_set_battery_info,
1039 };
1040
1041 static const struct axp_data axp813_data = {
1042 .ccc_scale = 200000,
1043 .ccc_offset = 200000,
1044 .ccc_reg = AXP20X_CHRG_CTRL1,
1045 .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1046 .has_fg_valid = true,
1047 .bat_ps_desc = &axp209_batt_ps_desc,
1048 .get_max_voltage = axp813_battery_get_max_voltage,
1049 .set_max_voltage = axp20x_battery_set_max_voltage,
1050 .cfg_iio_chan = axp209_bat_cfg_iio_channels,
1051 .set_bat_info = axp209_set_battery_info,
1052 };
1053
1054 static const struct of_device_id axp20x_battery_ps_id[] = {
1055 {
1056 .compatible = "x-powers,axp209-battery-power-supply",
1057 .data = (void *)&axp209_data,
1058 }, {
1059 .compatible = "x-powers,axp221-battery-power-supply",
1060 .data = (void *)&axp221_data,
1061 }, {
1062 .compatible = "x-powers,axp717-battery-power-supply",
1063 .data = (void *)&axp717_data,
1064 }, {
1065 .compatible = "x-powers,axp813-battery-power-supply",
1066 .data = (void *)&axp813_data,
1067 }, { /* sentinel */ },
1068 };
1069 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
1070
axp20x_power_probe(struct platform_device * pdev)1071 static int axp20x_power_probe(struct platform_device *pdev)
1072 {
1073 struct axp20x_batt_ps *axp20x_batt;
1074 struct power_supply_config psy_cfg = {};
1075 struct power_supply_battery_info *info;
1076 struct device *dev = &pdev->dev;
1077 int ret;
1078
1079 if (!of_device_is_available(pdev->dev.of_node))
1080 return -ENODEV;
1081
1082 axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
1083 GFP_KERNEL);
1084 if (!axp20x_batt)
1085 return -ENOMEM;
1086
1087 axp20x_batt->dev = &pdev->dev;
1088
1089 axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1090 platform_set_drvdata(pdev, axp20x_batt);
1091
1092 psy_cfg.drv_data = axp20x_batt;
1093 psy_cfg.of_node = pdev->dev.of_node;
1094
1095 axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev);
1096
1097 ret = axp20x_batt->data->cfg_iio_chan(pdev, axp20x_batt);
1098 if (ret)
1099 return ret;
1100
1101 axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
1102 axp20x_batt->data->bat_ps_desc,
1103 &psy_cfg);
1104 if (IS_ERR(axp20x_batt->batt)) {
1105 dev_err(&pdev->dev, "failed to register power supply: %ld\n",
1106 PTR_ERR(axp20x_batt->batt));
1107 return PTR_ERR(axp20x_batt->batt);
1108 }
1109
1110 if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) {
1111 axp20x_batt->data->set_bat_info(pdev, axp20x_batt, info);
1112 power_supply_put_battery_info(axp20x_batt->batt, info);
1113 }
1114
1115 /*
1116 * Update max CCC to a valid value if battery info is present or set it
1117 * to current register value by default.
1118 */
1119 axp20x_get_constant_charge_current(axp20x_batt, &axp20x_batt->max_ccc);
1120
1121 return 0;
1122 }
1123
1124 static struct platform_driver axp20x_batt_driver = {
1125 .probe = axp20x_power_probe,
1126 .driver = {
1127 .name = "axp20x-battery-power-supply",
1128 .of_match_table = axp20x_battery_ps_id,
1129 },
1130 };
1131
1132 module_platform_driver(axp20x_batt_driver);
1133
1134 MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
1135 MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
1136 MODULE_LICENSE("GPL");
1137