drm/panthor: Don't add write fences to the shared BOs
[drm/drm-misc.git] / drivers / power / supply / axp20x_battery.c
blobf71cc90fea1273f2d0655af6f4cc8df9b7cbf175
1 /*
2 * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs
4 * Copyright 2016 Free Electrons NextThing Co.
5 * Quentin Schulz <quentin.schulz@free-electrons.com>
7 * This driver is based on a previous upstreaming attempt by:
8 * Bruno Prémont <bonbons@linux-vserver.org>
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.
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.
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>
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
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)
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)
50 #define AXP209_FG_PERCENT GENMASK(6, 0)
51 #define AXP22X_FG_VALID BIT(7)
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)
60 #define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5)
61 #define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5)
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
73 #define AXP813_CHRG_CTRL1_TGT_4_35V (3 << 5)
75 #define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0)
76 #define AXP717_ICC_CHARGER_LIM_MASK GENMASK(5, 0)
78 #define AXP717_ITERM_CHG_LIM_MASK GENMASK(3, 0)
79 #define AXP717_ITERM_CC_STEP 64000
81 #define AXP20X_V_OFF_MASK GENMASK(2, 0)
82 #define AXP717_V_OFF_MASK GENMASK(6, 4)
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
92 struct axp20x_batt_ps;
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);
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;
122 static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
123 int *val)
125 int ret, reg;
127 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
128 if (ret)
129 return ret;
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;
148 return 0;
151 static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
152 int *val)
154 int ret, reg;
156 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
157 if (ret)
158 return ret;
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;
177 return 0;
180 static int axp717_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
181 int *val)
183 int ret, reg;
185 ret = regmap_read(axp20x_batt->regmap, AXP717_CV_CHG_SET, &reg);
186 if (ret)
187 return ret;
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;
213 static int axp813_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
214 int *val)
216 int ret, reg;
218 ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &reg);
219 if (ret)
220 return ret;
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;
239 return 0;
242 static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp,
243 int *val)
245 int ret;
247 ret = regmap_read(axp->regmap, AXP20X_CHRG_CTRL1, val);
248 if (ret)
249 return ret;
251 *val &= AXP20X_CHRG_CTRL1_TGT_CURR;
253 *val = *val * axp->data->ccc_scale + axp->data->ccc_offset;
255 return 0;
258 static int axp717_get_constant_charge_current(struct axp20x_batt_ps *axp,
259 int *val)
261 int ret;
263 ret = regmap_read(axp->regmap, AXP717_ICC_CHG_SET, val);
264 if (ret)
265 return ret;
267 *val = FIELD_GET(AXP717_ICC_CHARGER_LIM_MASK, *val) *
268 axp->data->ccc_scale;
270 return 0;
273 static int axp20x_battery_get_prop(struct power_supply *psy,
274 enum power_supply_property psp,
275 union power_supply_propval *val)
277 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
278 int ret = 0, reg, val1;
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 &reg);
285 if (ret)
286 return ret;
288 val->intval = !!(reg & AXP20X_PWR_OP_BATT_PRESENT);
289 break;
291 case POWER_SUPPLY_PROP_STATUS:
292 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
293 &reg);
294 if (ret)
295 return ret;
297 if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
298 val->intval = POWER_SUPPLY_STATUS_CHARGING;
299 return 0;
302 ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i,
303 &val1);
304 if (ret)
305 return ret;
307 if (val1) {
308 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
309 return 0;
312 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &val1);
313 if (ret)
314 return ret;
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.
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;
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;
332 if (val1 & AXP20X_PWR_OP_BATT_ACTIVATED) {
333 val->intval = POWER_SUPPLY_HEALTH_DEAD;
334 return 0;
337 val->intval = POWER_SUPPLY_HEALTH_GOOD;
338 break;
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;
347 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
348 val->intval = axp20x_batt->max_ccc;
349 break;
351 case POWER_SUPPLY_PROP_CURRENT_NOW:
352 ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_INPUT_STATUS,
353 &reg);
354 if (ret)
355 return ret;
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;
363 if (ret)
364 return ret;
366 /* IIO framework gives mA but Power Supply framework gives uA */
367 val->intval *= 1000;
368 break;
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 &reg);
374 if (ret)
375 return ret;
377 if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
378 val->intval = 100;
379 return 0;
382 ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &reg);
383 if (ret)
384 return ret;
386 if (axp20x_batt->data->has_fg_valid && !(reg & AXP22X_FG_VALID))
387 return -EINVAL;
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.
393 val->intval = reg & AXP209_FG_PERCENT;
394 break;
396 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
397 return axp20x_batt->data->get_max_voltage(axp20x_batt,
398 &val->intval);
400 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
401 ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg);
402 if (ret)
403 return ret;
405 val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
406 break;
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;
414 /* IIO framework gives mV but Power Supply framework gives uV */
415 val->intval *= 1000;
416 break;
418 default:
419 return -EINVAL;
422 return 0;
425 static int axp717_battery_get_prop(struct power_supply *psy,
426 enum power_supply_property psp,
427 union power_supply_propval *val)
429 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
430 int ret = 0, reg;
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 &reg);
437 if (ret)
438 return ret;
440 val->intval = FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg);
441 return 0;
443 case POWER_SUPPLY_PROP_STATUS:
444 ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_STATUS_2,
445 &reg);
446 if (ret)
447 return ret;
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;
454 case AXP717_PWR_STATUS_BAT_CHRG:
455 val->intval = POWER_SUPPLY_STATUS_CHARGING;
456 return 0;
458 case AXP717_PWR_STATUS_BAT_DISCHRG:
459 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
460 return 0;
462 default:
463 val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
464 return 0;
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.
474 case POWER_SUPPLY_PROP_HEALTH:
475 ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_FAULT,
476 &reg);
477 if (ret)
478 return ret;
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;
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;
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;
505 default:
506 val->intval = POWER_SUPPLY_HEALTH_GOOD;
507 return 0;
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;
517 case POWER_SUPPLY_PROP_CURRENT_NOW:
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.
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;
531 case POWER_SUPPLY_PROP_CAPACITY:
532 ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
533 &reg);
534 if (ret)
535 return ret;
537 if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg))
538 return -ENODEV;
540 ret = regmap_read(axp20x_batt->regmap,
541 AXP717_BATT_PERCENT_DATA, &reg);
542 if (ret)
543 return ret;
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.
549 val->intval = reg & AXP209_FG_PERCENT;
550 return 0;
552 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
553 return axp20x_batt->data->get_max_voltage(axp20x_batt,
554 &val->intval);
556 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
557 ret = regmap_read(axp20x_batt->regmap,
558 AXP717_VSYS_V_POWEROFF, &reg);
559 if (ret)
560 return ret;
562 val->intval = AXP717_BAT_VMIN_MIN_UV + AXP717_BAT_VMIN_STEP *
563 (reg & AXP717_V_OFF_MASK);
564 return 0;
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;
572 /* IIO framework gives mV but Power Supply framework gives uV */
573 val->intval *= 1000;
574 return 0;
576 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
577 ret = regmap_read(axp20x_batt->regmap,
578 AXP717_ITERM_CHG_SET, &reg);
579 if (ret)
580 return ret;
582 val->intval = (reg & AXP717_ITERM_CHG_LIM_MASK) * AXP717_ITERM_CC_STEP;
583 return 0;
585 default:
586 return -EINVAL;
590 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
591 int val)
593 switch (val) {
594 case 4100000:
595 val = AXP20X_CHRG_CTRL1_TGT_4_1V;
596 break;
598 case 4200000:
599 val = AXP20X_CHRG_CTRL1_TGT_4_2V;
600 break;
602 default:
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).
609 return -EINVAL;
612 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
613 AXP20X_CHRG_CTRL1_TGT_VOLT, val);
616 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
617 int val)
619 switch (val) {
620 case 4100000:
621 val = AXP20X_CHRG_CTRL1_TGT_4_1V;
622 break;
624 case 4150000:
625 val = AXP20X_CHRG_CTRL1_TGT_4_15V;
626 break;
628 case 4200000:
629 val = AXP20X_CHRG_CTRL1_TGT_4_2V;
630 break;
632 default:
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).
639 return -EINVAL;
642 return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
643 AXP20X_CHRG_CTRL1_TGT_VOLT, val);
646 static int axp717_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
647 int val)
649 switch (val) {
650 case 4000000:
651 val = AXP717_CHRG_CV_4_0V;
652 break;
654 case 4100000:
655 val = AXP717_CHRG_CV_4_1V;
656 break;
658 case 4200000:
659 val = AXP717_CHRG_CV_4_2V;
660 break;
662 default:
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.
667 return -EINVAL;
670 return regmap_update_bits(axp20x_batt->regmap,
671 AXP717_CV_CHG_SET,
672 AXP717_CHRG_CV_VOLT_MASK, val);
675 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt,
676 int charge_current)
678 if (charge_current > axp_batt->max_ccc)
679 return -EINVAL;
681 charge_current = (charge_current - axp_batt->data->ccc_offset) /
682 axp_batt->data->ccc_scale;
684 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
685 return -EINVAL;
687 return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1,
688 AXP20X_CHRG_CTRL1_TGT_CURR, charge_current);
691 static int axp717_set_constant_charge_current(struct axp20x_batt_ps *axp,
692 int charge_current)
694 int val;
696 if (charge_current > axp->max_ccc)
697 return -EINVAL;
699 if (charge_current > AXP717_BAT_CC_MAX_UA || charge_current < 0)
700 return -EINVAL;
702 val = (charge_current - axp->data->ccc_offset) /
703 axp->data->ccc_scale;
705 return regmap_update_bits(axp->regmap, AXP717_ICC_CHG_SET,
706 AXP717_ICC_CHARGER_LIM_MASK, val);
709 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp,
710 int charge_current)
712 bool lower_max = false;
714 charge_current = (charge_current - axp->data->ccc_offset) /
715 axp->data->ccc_scale;
717 if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
718 return -EINVAL;
720 charge_current = charge_current * axp->data->ccc_scale +
721 axp->data->ccc_offset;
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;
729 axp->max_ccc = charge_current;
731 if (lower_max) {
732 int current_cc;
734 axp20x_get_constant_charge_current(axp, &current_cc);
735 if (current_cc > charge_current)
736 axp20x_set_constant_charge_current(axp, charge_current);
739 return 0;
741 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
742 int min_voltage)
744 int val1 = (min_voltage - 2600000) / 100000;
746 if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
747 return -EINVAL;
749 return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF,
750 AXP20X_V_OFF_MASK, val1);
753 static int axp717_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
754 int min_voltage)
756 int val1 = (min_voltage - AXP717_BAT_VMIN_MIN_UV) / AXP717_BAT_VMIN_STEP;
758 if (val1 < 0 || val1 > AXP717_V_OFF_MASK)
759 return -EINVAL;
761 return regmap_update_bits(axp_batt->regmap,
762 AXP717_VSYS_V_POWEROFF,
763 AXP717_V_OFF_MASK, val1);
766 static int axp20x_battery_set_prop(struct power_supply *psy,
767 enum power_supply_property psp,
768 const union power_supply_propval *val)
770 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
772 switch (psp) {
773 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
774 return axp20x_set_voltage_min_design(axp20x_batt, val->intval);
776 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
777 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
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);
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);
796 fallthrough;
797 default:
798 return -EINVAL;
802 static int axp717_battery_set_prop(struct power_supply *psy,
803 enum power_supply_property psp,
804 const union power_supply_propval *val)
806 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
808 switch (psp) {
809 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
810 return axp717_set_voltage_min_design(axp20x_batt, val->intval);
812 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
813 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
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);
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);
832 return -EINVAL;
833 default:
834 return -EINVAL;
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,
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,
866 static int axp20x_battery_prop_writeable(struct power_supply *psy,
867 enum power_supply_property psp)
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;
876 static int axp717_battery_prop_writeable(struct power_supply *psy,
877 enum power_supply_property psp)
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;
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,
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,
905 static int axp209_bat_cfg_iio_channels(struct platform_device *pdev,
906 struct axp20x_batt_ps *axp_batt)
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);
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);
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);
931 return 0;
934 static int axp717_bat_cfg_iio_channels(struct platform_device *pdev,
935 struct axp20x_batt_ps *axp_batt)
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);
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);
952 return 0;
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)
959 int vmin = info->voltage_min_design_uv;
960 int ccc = info->constant_charge_current_max_ua;
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");
966 /* Set max to unverified value to be able to set CCC */
967 axp_batt->max_ccc = ccc;
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);
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)
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;
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");
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");
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);
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,
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,
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,
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,
1054 static const struct of_device_id axp20x_battery_ps_id[] = {
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 */ },
1069 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
1071 static int axp20x_power_probe(struct platform_device *pdev)
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;
1079 if (!of_device_is_available(pdev->dev.of_node))
1080 return -ENODEV;
1082 axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
1083 GFP_KERNEL);
1084 if (!axp20x_batt)
1085 return -ENOMEM;
1087 axp20x_batt->dev = &pdev->dev;
1089 axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1090 platform_set_drvdata(pdev, axp20x_batt);
1092 psy_cfg.drv_data = axp20x_batt;
1093 psy_cfg.of_node = pdev->dev.of_node;
1095 axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev);
1097 ret = axp20x_batt->data->cfg_iio_chan(pdev, axp20x_batt);
1098 if (ret)
1099 return ret;
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);
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);
1116 * Update max CCC to a valid value if battery info is present or set it
1117 * to current register value by default.
1119 axp20x_get_constant_charge_current(axp20x_batt, &axp20x_batt->max_ccc);
1121 return 0;
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,
1132 module_platform_driver(axp20x_batt_driver);
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");