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 /* IIO framework gives mA but Power Supply framework gives uA */
358 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
359 ret = iio_read_channel_processed_scale(axp20x_batt->batt_chrg_i,
360 &val->intval, 1000);
361 } else {
362 ret = iio_read_channel_processed_scale(axp20x_batt->batt_dischrg_i,
363 &val1, 1000);
364 val->intval = -val1;
365 }
366 if (ret)
367 return ret;
368
369 break;
370
371 case POWER_SUPPLY_PROP_CAPACITY:
372 /* When no battery is present, return capacity is 100% */
373 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
374 ®);
375 if (ret)
376 return ret;
377
378 if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
379 val->intval = 100;
380 return 0;
381 }
382
383 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, ®);
384 if (ret)
385 return ret;
386
387 if (axp20x_batt->data->has_fg_valid && !(reg & AXP22X_FG_VALID))
388 return -EINVAL;
389
390 /*
391 * Fuel Gauge data takes 7 bits but the stored value seems to be
392 * directly the raw percentage without any scaling to 7 bits.
393 */
394 val->intval = reg & AXP209_FG_PERCENT;
395 break;
396
397 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
398 return axp20x_batt->data->get_max_voltage(axp20x_batt,
399 &val->intval);
400
401 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
402 ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®);
403 if (ret)
404 return ret;
405
406 val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
407 break;
408
409 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
410 /* IIO framework gives mV but Power Supply framework gives uV */
411 ret = iio_read_channel_processed_scale(axp20x_batt->batt_v,
412 &val->intval, 1000);
413 if (ret)
414 return ret;
415
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. Note that
523 * IIO framework gives mA but Power Supply framework
524 * gives uA.
525 */
526 ret = iio_read_channel_processed_scale(axp20x_batt->batt_chrg_i,
527 &val->intval, 1000);
528 if (ret)
529 return ret;
530
531 return 0;
532
533 case POWER_SUPPLY_PROP_CAPACITY:
534 ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
535 ®);
536 if (ret)
537 return ret;
538
539 if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg))
540 return -ENODEV;
541
542 ret = regmap_read(axp20x_batt->regmap,
543 AXP717_BATT_PERCENT_DATA, ®);
544 if (ret)
545 return ret;
546
547 /*
548 * Fuel Gauge data takes 7 bits but the stored value seems to be
549 * directly the raw percentage without any scaling to 7 bits.
550 */
551 val->intval = reg & AXP209_FG_PERCENT;
552 return 0;
553
554 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
555 return axp20x_batt->data->get_max_voltage(axp20x_batt,
556 &val->intval);
557
558 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
559 ret = regmap_read(axp20x_batt->regmap,
560 AXP717_VSYS_V_POWEROFF, ®);
561 if (ret)
562 return ret;
563
564 val->intval = AXP717_BAT_VMIN_MIN_UV + AXP717_BAT_VMIN_STEP *
565 (reg & AXP717_V_OFF_MASK);
566 return 0;
567
568 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
569 /* IIO framework gives mV but Power Supply framework gives uV */
570 ret = iio_read_channel_processed_scale(axp20x_batt->batt_v,
571 &val->intval, 1000);
572 if (ret)
573 return ret;
574
575 return 0;
576
577 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
578 ret = regmap_read(axp20x_batt->regmap,
579 AXP717_ITERM_CHG_SET, ®);
580 if (ret)
581 return ret;
582
583 val->intval = (reg & AXP717_ITERM_CHG_LIM_MASK) * AXP717_ITERM_CC_STEP;
584 return 0;
585
586 default:
587 return -EINVAL;
588 }
589 }
590
axp22x_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)591 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
592 int val)
593 {
594 switch (val) {
595 case 4100000:
596 val = AXP20X_CHRG_CTRL1_TGT_4_1V;
597 break;
598
599 case 4200000:
600 val = AXP20X_CHRG_CTRL1_TGT_4_2V;
601 break;
602
603 default:
604 /*
605 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
606 * can be set to 4.22V and 4.24V, but these voltages are too
607 * high for Lithium based batteries (AXP PMICs are supposed to
608 * be used with these kinds of battery).
609 */
610 return -EINVAL;
611 }
612
613 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
614 AXP20X_CHRG_CTRL1_TGT_VOLT, val);
615 }
616
axp20x_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)617 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
618 int val)
619 {
620 switch (val) {
621 case 4100000:
622 val = AXP20X_CHRG_CTRL1_TGT_4_1V;
623 break;
624
625 case 4150000:
626 val = AXP20X_CHRG_CTRL1_TGT_4_15V;
627 break;
628
629 case 4200000:
630 val = AXP20X_CHRG_CTRL1_TGT_4_2V;
631 break;
632
633 default:
634 /*
635 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
636 * can be set to 4.22V and 4.24V, but these voltages are too
637 * high for Lithium based batteries (AXP PMICs are supposed to
638 * be used with these kinds of battery).
639 */
640 return -EINVAL;
641 }
642
643 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
644 AXP20X_CHRG_CTRL1_TGT_VOLT, val);
645 }
646
axp717_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)647 static int axp717_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
648 int val)
649 {
650 switch (val) {
651 case 4000000:
652 val = AXP717_CHRG_CV_4_0V;
653 break;
654
655 case 4100000:
656 val = AXP717_CHRG_CV_4_1V;
657 break;
658
659 case 4200000:
660 val = AXP717_CHRG_CV_4_2V;
661 break;
662
663 default:
664 /*
665 * AXP717 can go up to 4.35, 4.4, and 5.0 volts which
666 * seem too high for lithium batteries, so do not allow.
667 */
668 return -EINVAL;
669 }
670
671 return regmap_update_bits(axp20x_batt->regmap,
672 AXP717_CV_CHG_SET,
673 AXP717_CHRG_CV_VOLT_MASK, val);
674 }
675
axp20x_set_constant_charge_current(struct axp20x_batt_ps * axp_batt,int charge_current)676 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt,
677 int charge_current)
678 {
679 if (charge_current > axp_batt->max_ccc)
680 return -EINVAL;
681
682 charge_current = (charge_current - axp_batt->data->ccc_offset) /
683 axp_batt->data->ccc_scale;
684
685 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
686 return -EINVAL;
687
688 return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1,
689 AXP20X_CHRG_CTRL1_TGT_CURR, charge_current);
690 }
691
axp717_set_constant_charge_current(struct axp20x_batt_ps * axp,int charge_current)692 static int axp717_set_constant_charge_current(struct axp20x_batt_ps *axp,
693 int charge_current)
694 {
695 int val;
696
697 if (charge_current > axp->max_ccc)
698 return -EINVAL;
699
700 if (charge_current > AXP717_BAT_CC_MAX_UA || charge_current < 0)
701 return -EINVAL;
702
703 val = (charge_current - axp->data->ccc_offset) /
704 axp->data->ccc_scale;
705
706 return regmap_update_bits(axp->regmap, AXP717_ICC_CHG_SET,
707 AXP717_ICC_CHARGER_LIM_MASK, val);
708 }
709
axp20x_set_max_constant_charge_current(struct axp20x_batt_ps * axp,int charge_current)710 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp,
711 int charge_current)
712 {
713 bool lower_max = false;
714
715 charge_current = (charge_current - axp->data->ccc_offset) /
716 axp->data->ccc_scale;
717
718 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
719 return -EINVAL;
720
721 charge_current = charge_current * axp->data->ccc_scale +
722 axp->data->ccc_offset;
723
724 if (charge_current > axp->max_ccc)
725 dev_warn(axp->dev,
726 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n");
727 else
728 lower_max = true;
729
730 axp->max_ccc = charge_current;
731
732 if (lower_max) {
733 int current_cc;
734
735 axp20x_get_constant_charge_current(axp, ¤t_cc);
736 if (current_cc > charge_current)
737 axp20x_set_constant_charge_current(axp, charge_current);
738 }
739
740 return 0;
741 }
axp20x_set_voltage_min_design(struct axp20x_batt_ps * axp_batt,int min_voltage)742 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
743 int min_voltage)
744 {
745 int val1 = (min_voltage - 2600000) / 100000;
746
747 if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
748 return -EINVAL;
749
750 return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF,
751 AXP20X_V_OFF_MASK, val1);
752 }
753
axp717_set_voltage_min_design(struct axp20x_batt_ps * axp_batt,int min_voltage)754 static int axp717_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
755 int min_voltage)
756 {
757 int val1 = (min_voltage - AXP717_BAT_VMIN_MIN_UV) / AXP717_BAT_VMIN_STEP;
758
759 if (val1 < 0 || val1 > AXP717_V_OFF_MASK)
760 return -EINVAL;
761
762 return regmap_update_bits(axp_batt->regmap,
763 AXP717_VSYS_V_POWEROFF,
764 AXP717_V_OFF_MASK, val1);
765 }
766
axp20x_battery_set_prop(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)767 static int axp20x_battery_set_prop(struct power_supply *psy,
768 enum power_supply_property psp,
769 const union power_supply_propval *val)
770 {
771 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
772
773 switch (psp) {
774 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
775 return axp20x_set_voltage_min_design(axp20x_batt, val->intval);
776
777 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
778 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
779
780 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
781 return axp20x_set_constant_charge_current(axp20x_batt,
782 val->intval);
783 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
784 return axp20x_set_max_constant_charge_current(axp20x_batt,
785 val->intval);
786 case POWER_SUPPLY_PROP_STATUS:
787 switch (val->intval) {
788 case POWER_SUPPLY_STATUS_CHARGING:
789 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
790 AXP20X_CHRG_CTRL1_ENABLE, AXP20X_CHRG_CTRL1_ENABLE);
791
792 case POWER_SUPPLY_STATUS_DISCHARGING:
793 case POWER_SUPPLY_STATUS_NOT_CHARGING:
794 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
795 AXP20X_CHRG_CTRL1_ENABLE, 0);
796 }
797 fallthrough;
798 default:
799 return -EINVAL;
800 }
801 }
802
axp717_battery_set_prop(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)803 static int axp717_battery_set_prop(struct power_supply *psy,
804 enum power_supply_property psp,
805 const union power_supply_propval *val)
806 {
807 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
808
809 switch (psp) {
810 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
811 return axp717_set_voltage_min_design(axp20x_batt, val->intval);
812
813 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
814 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
815
816 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
817 return axp717_set_constant_charge_current(axp20x_batt,
818 val->intval);
819 case POWER_SUPPLY_PROP_STATUS:
820 switch (val->intval) {
821 case POWER_SUPPLY_STATUS_CHARGING:
822 return regmap_update_bits(axp20x_batt->regmap,
823 AXP717_MODULE_EN_CONTROL_2,
824 AXP717_CHRG_ENABLE,
825 AXP717_CHRG_ENABLE);
826
827 case POWER_SUPPLY_STATUS_DISCHARGING:
828 case POWER_SUPPLY_STATUS_NOT_CHARGING:
829 return regmap_update_bits(axp20x_batt->regmap,
830 AXP717_MODULE_EN_CONTROL_2,
831 AXP717_CHRG_ENABLE, 0);
832 }
833 return -EINVAL;
834 default:
835 return -EINVAL;
836 }
837 }
838
839 static enum power_supply_property axp20x_battery_props[] = {
840 POWER_SUPPLY_PROP_PRESENT,
841 POWER_SUPPLY_PROP_ONLINE,
842 POWER_SUPPLY_PROP_STATUS,
843 POWER_SUPPLY_PROP_VOLTAGE_NOW,
844 POWER_SUPPLY_PROP_CURRENT_NOW,
845 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
846 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
847 POWER_SUPPLY_PROP_HEALTH,
848 POWER_SUPPLY_PROP_VOLTAGE_MAX,
849 POWER_SUPPLY_PROP_VOLTAGE_MIN,
850 POWER_SUPPLY_PROP_CAPACITY,
851 };
852
853 static enum power_supply_property axp717_battery_props[] = {
854 POWER_SUPPLY_PROP_PRESENT,
855 POWER_SUPPLY_PROP_ONLINE,
856 POWER_SUPPLY_PROP_STATUS,
857 POWER_SUPPLY_PROP_VOLTAGE_NOW,
858 POWER_SUPPLY_PROP_CURRENT_NOW,
859 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
860 POWER_SUPPLY_PROP_HEALTH,
861 POWER_SUPPLY_PROP_VOLTAGE_MAX,
862 POWER_SUPPLY_PROP_VOLTAGE_MIN,
863 POWER_SUPPLY_PROP_CAPACITY,
864 POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
865 };
866
axp20x_battery_prop_writeable(struct power_supply * psy,enum power_supply_property psp)867 static int axp20x_battery_prop_writeable(struct power_supply *psy,
868 enum power_supply_property psp)
869 {
870 return psp == POWER_SUPPLY_PROP_STATUS ||
871 psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
872 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
873 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT ||
874 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
875 }
876
axp717_battery_prop_writeable(struct power_supply * psy,enum power_supply_property psp)877 static int axp717_battery_prop_writeable(struct power_supply *psy,
878 enum power_supply_property psp)
879 {
880 return psp == POWER_SUPPLY_PROP_STATUS ||
881 psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
882 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
883 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
884 }
885
886 static const struct power_supply_desc axp209_batt_ps_desc = {
887 .name = "axp20x-battery",
888 .type = POWER_SUPPLY_TYPE_BATTERY,
889 .properties = axp20x_battery_props,
890 .num_properties = ARRAY_SIZE(axp20x_battery_props),
891 .property_is_writeable = axp20x_battery_prop_writeable,
892 .get_property = axp20x_battery_get_prop,
893 .set_property = axp20x_battery_set_prop,
894 };
895
896 static const struct power_supply_desc axp717_batt_ps_desc = {
897 .name = "axp20x-battery",
898 .type = POWER_SUPPLY_TYPE_BATTERY,
899 .properties = axp717_battery_props,
900 .num_properties = ARRAY_SIZE(axp717_battery_props),
901 .property_is_writeable = axp717_battery_prop_writeable,
902 .get_property = axp717_battery_get_prop,
903 .set_property = axp717_battery_set_prop,
904 };
905
axp209_bat_cfg_iio_channels(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt)906 static int axp209_bat_cfg_iio_channels(struct platform_device *pdev,
907 struct axp20x_batt_ps *axp_batt)
908 {
909 axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
910 if (IS_ERR(axp_batt->batt_v)) {
911 if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
912 return -EPROBE_DEFER;
913 return PTR_ERR(axp_batt->batt_v);
914 }
915
916 axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
917 "batt_chrg_i");
918 if (IS_ERR(axp_batt->batt_chrg_i)) {
919 if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
920 return -EPROBE_DEFER;
921 return PTR_ERR(axp_batt->batt_chrg_i);
922 }
923
924 axp_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
925 "batt_dischrg_i");
926 if (IS_ERR(axp_batt->batt_dischrg_i)) {
927 if (PTR_ERR(axp_batt->batt_dischrg_i) == -ENODEV)
928 return -EPROBE_DEFER;
929 return PTR_ERR(axp_batt->batt_dischrg_i);
930 }
931
932 return 0;
933 }
934
axp717_bat_cfg_iio_channels(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt)935 static int axp717_bat_cfg_iio_channels(struct platform_device *pdev,
936 struct axp20x_batt_ps *axp_batt)
937 {
938 axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
939 if (IS_ERR(axp_batt->batt_v)) {
940 if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
941 return -EPROBE_DEFER;
942 return PTR_ERR(axp_batt->batt_v);
943 }
944
945 axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
946 "batt_chrg_i");
947 if (IS_ERR(axp_batt->batt_chrg_i)) {
948 if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
949 return -EPROBE_DEFER;
950 return PTR_ERR(axp_batt->batt_chrg_i);
951 }
952
953 return 0;
954 }
955
axp209_set_battery_info(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt,struct power_supply_battery_info * info)956 static void axp209_set_battery_info(struct platform_device *pdev,
957 struct axp20x_batt_ps *axp_batt,
958 struct power_supply_battery_info *info)
959 {
960 int vmin = info->voltage_min_design_uv;
961 int ccc = info->constant_charge_current_max_ua;
962
963 if (vmin > 0 && axp20x_set_voltage_min_design(axp_batt, vmin))
964 dev_err(&pdev->dev,
965 "couldn't set voltage_min_design\n");
966
967 /* Set max to unverified value to be able to set CCC */
968 axp_batt->max_ccc = ccc;
969
970 if (ccc <= 0 || axp20x_set_constant_charge_current(axp_batt, ccc)) {
971 dev_err(&pdev->dev,
972 "couldn't set ccc from DT: fallback to min value\n");
973 ccc = 300000;
974 axp_batt->max_ccc = ccc;
975 axp20x_set_constant_charge_current(axp_batt, ccc);
976 }
977 }
978
axp717_set_battery_info(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt,struct power_supply_battery_info * info)979 static void axp717_set_battery_info(struct platform_device *pdev,
980 struct axp20x_batt_ps *axp_batt,
981 struct power_supply_battery_info *info)
982 {
983 int vmin = info->voltage_min_design_uv;
984 int vmax = info->voltage_max_design_uv;
985 int ccc = info->constant_charge_current_max_ua;
986 int val;
987
988 if (vmin > 0 && axp717_set_voltage_min_design(axp_batt, vmin))
989 dev_err(&pdev->dev,
990 "couldn't set voltage_min_design\n");
991
992 if (vmax > 0 && axp717_battery_set_max_voltage(axp_batt, vmax))
993 dev_err(&pdev->dev,
994 "couldn't set voltage_max_design\n");
995
996 axp717_get_constant_charge_current(axp_batt, &val);
997 axp_batt->max_ccc = ccc;
998 if (ccc <= 0 || axp717_set_constant_charge_current(axp_batt, ccc)) {
999 dev_err(&pdev->dev,
1000 "couldn't set ccc from DT: current ccc is %d\n",
1001 val);
1002 }
1003 }
1004
1005 static const struct axp_data axp209_data = {
1006 .ccc_scale = 100000,
1007 .ccc_offset = 300000,
1008 .ccc_reg = AXP20X_CHRG_CTRL1,
1009 .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1010 .bat_ps_desc = &axp209_batt_ps_desc,
1011 .get_max_voltage = axp20x_battery_get_max_voltage,
1012 .set_max_voltage = axp20x_battery_set_max_voltage,
1013 .cfg_iio_chan = axp209_bat_cfg_iio_channels,
1014 .set_bat_info = axp209_set_battery_info,
1015 };
1016
1017 static const struct axp_data axp221_data = {
1018 .ccc_scale = 150000,
1019 .ccc_offset = 300000,
1020 .ccc_reg = AXP20X_CHRG_CTRL1,
1021 .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1022 .has_fg_valid = true,
1023 .bat_ps_desc = &axp209_batt_ps_desc,
1024 .get_max_voltage = axp22x_battery_get_max_voltage,
1025 .set_max_voltage = axp22x_battery_set_max_voltage,
1026 .cfg_iio_chan = axp209_bat_cfg_iio_channels,
1027 .set_bat_info = axp209_set_battery_info,
1028 };
1029
1030 static const struct axp_data axp717_data = {
1031 .ccc_scale = 64000,
1032 .ccc_offset = 0,
1033 .ccc_reg = AXP717_ICC_CHG_SET,
1034 .ccc_mask = AXP717_ICC_CHARGER_LIM_MASK,
1035 .bat_ps_desc = &axp717_batt_ps_desc,
1036 .get_max_voltage = axp717_battery_get_max_voltage,
1037 .set_max_voltage = axp717_battery_set_max_voltage,
1038 .cfg_iio_chan = axp717_bat_cfg_iio_channels,
1039 .set_bat_info = axp717_set_battery_info,
1040 };
1041
1042 static const struct axp_data axp813_data = {
1043 .ccc_scale = 200000,
1044 .ccc_offset = 200000,
1045 .ccc_reg = AXP20X_CHRG_CTRL1,
1046 .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1047 .has_fg_valid = true,
1048 .bat_ps_desc = &axp209_batt_ps_desc,
1049 .get_max_voltage = axp813_battery_get_max_voltage,
1050 .set_max_voltage = axp20x_battery_set_max_voltage,
1051 .cfg_iio_chan = axp209_bat_cfg_iio_channels,
1052 .set_bat_info = axp209_set_battery_info,
1053 };
1054
1055 static const struct of_device_id axp20x_battery_ps_id[] = {
1056 {
1057 .compatible = "x-powers,axp209-battery-power-supply",
1058 .data = (void *)&axp209_data,
1059 }, {
1060 .compatible = "x-powers,axp221-battery-power-supply",
1061 .data = (void *)&axp221_data,
1062 }, {
1063 .compatible = "x-powers,axp717-battery-power-supply",
1064 .data = (void *)&axp717_data,
1065 }, {
1066 .compatible = "x-powers,axp813-battery-power-supply",
1067 .data = (void *)&axp813_data,
1068 }, { /* sentinel */ },
1069 };
1070 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
1071
axp20x_power_probe(struct platform_device * pdev)1072 static int axp20x_power_probe(struct platform_device *pdev)
1073 {
1074 struct axp20x_batt_ps *axp20x_batt;
1075 struct power_supply_config psy_cfg = {};
1076 struct power_supply_battery_info *info;
1077 struct device *dev = &pdev->dev;
1078 int ret;
1079
1080 if (!of_device_is_available(pdev->dev.of_node))
1081 return -ENODEV;
1082
1083 axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
1084 GFP_KERNEL);
1085 if (!axp20x_batt)
1086 return -ENOMEM;
1087
1088 axp20x_batt->dev = &pdev->dev;
1089
1090 axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1091 platform_set_drvdata(pdev, axp20x_batt);
1092
1093 psy_cfg.drv_data = axp20x_batt;
1094 psy_cfg.of_node = pdev->dev.of_node;
1095
1096 axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev);
1097
1098 ret = axp20x_batt->data->cfg_iio_chan(pdev, axp20x_batt);
1099 if (ret)
1100 return ret;
1101
1102 axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
1103 axp20x_batt->data->bat_ps_desc,
1104 &psy_cfg);
1105 if (IS_ERR(axp20x_batt->batt)) {
1106 dev_err(&pdev->dev, "failed to register power supply: %ld\n",
1107 PTR_ERR(axp20x_batt->batt));
1108 return PTR_ERR(axp20x_batt->batt);
1109 }
1110
1111 if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) {
1112 axp20x_batt->data->set_bat_info(pdev, axp20x_batt, info);
1113 power_supply_put_battery_info(axp20x_batt->batt, info);
1114 }
1115
1116 /*
1117 * Update max CCC to a valid value if battery info is present or set it
1118 * to current register value by default.
1119 */
1120 axp20x_get_constant_charge_current(axp20x_batt, &axp20x_batt->max_ccc);
1121
1122 return 0;
1123 }
1124
1125 static struct platform_driver axp20x_batt_driver = {
1126 .probe = axp20x_power_probe,
1127 .driver = {
1128 .name = "axp20x-battery-power-supply",
1129 .of_match_table = axp20x_battery_ps_id,
1130 },
1131 };
1132
1133 module_platform_driver(axp20x_batt_driver);
1134
1135 MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
1136 MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
1137 MODULE_LICENSE("GPL");
1138