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>
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
;
98 unsigned int ccc_mask
;
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
;
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
,
127 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_CHRG_CTRL1
, ®
);
131 switch (reg
& AXP20X_CHRG_CTRL1_TGT_VOLT
) {
132 case AXP20X_CHRG_CTRL1_TGT_4_1V
:
135 case AXP20X_CHRG_CTRL1_TGT_4_15V
:
138 case AXP20X_CHRG_CTRL1_TGT_4_2V
:
141 case AXP20X_CHRG_CTRL1_TGT_4_36V
:
151 static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
156 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_CHRG_CTRL1
, ®
);
160 switch (reg
& AXP20X_CHRG_CTRL1_TGT_VOLT
) {
161 case AXP20X_CHRG_CTRL1_TGT_4_1V
:
164 case AXP20X_CHRG_CTRL1_TGT_4_2V
:
167 case AXP22X_CHRG_CTRL1_TGT_4_22V
:
170 case AXP22X_CHRG_CTRL1_TGT_4_24V
:
180 static int axp717_battery_get_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
185 ret
= regmap_read(axp20x_batt
->regmap
, AXP717_CV_CHG_SET
, ®
);
189 switch (reg
& AXP717_CHRG_CV_VOLT_MASK
) {
190 case AXP717_CHRG_CV_4_0V
:
193 case AXP717_CHRG_CV_4_1V
:
196 case AXP717_CHRG_CV_4_2V
:
199 case AXP717_CHRG_CV_4_35V
:
202 case AXP717_CHRG_CV_4_4V
:
205 case AXP717_CHRG_CV_5_0V
:
213 static int axp813_battery_get_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
218 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_CHRG_CTRL1
, ®
);
222 switch (reg
& AXP20X_CHRG_CTRL1_TGT_VOLT
) {
223 case AXP20X_CHRG_CTRL1_TGT_4_1V
:
226 case AXP20X_CHRG_CTRL1_TGT_4_15V
:
229 case AXP20X_CHRG_CTRL1_TGT_4_2V
:
232 case AXP813_CHRG_CTRL1_TGT_4_35V
:
242 static int axp20x_get_constant_charge_current(struct axp20x_batt_ps
*axp
,
247 ret
= regmap_read(axp
->regmap
, AXP20X_CHRG_CTRL1
, val
);
251 *val
&= AXP20X_CHRG_CTRL1_TGT_CURR
;
253 *val
= *val
* axp
->data
->ccc_scale
+ axp
->data
->ccc_offset
;
258 static int axp717_get_constant_charge_current(struct axp20x_batt_ps
*axp
,
263 ret
= regmap_read(axp
->regmap
, AXP717_ICC_CHG_SET
, val
);
267 *val
= FIELD_GET(AXP717_ICC_CHARGER_LIM_MASK
, *val
) *
268 axp
->data
->ccc_scale
;
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
;
281 case POWER_SUPPLY_PROP_PRESENT
:
282 case POWER_SUPPLY_PROP_ONLINE
:
283 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_PWR_OP_MODE
,
288 val
->intval
= !!(reg
& AXP20X_PWR_OP_BATT_PRESENT
);
291 case POWER_SUPPLY_PROP_STATUS
:
292 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_PWR_INPUT_STATUS
,
297 if (reg
& AXP20X_PWR_STATUS_BAT_CHARGING
) {
298 val
->intval
= POWER_SUPPLY_STATUS_CHARGING
;
302 ret
= iio_read_channel_processed(axp20x_batt
->batt_dischrg_i
,
308 val
->intval
= POWER_SUPPLY_STATUS_DISCHARGING
;
312 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_FG_RES
, &val1
);
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
;
323 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
326 case POWER_SUPPLY_PROP_HEALTH
:
327 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_PWR_OP_MODE
,
332 if (val1
& AXP20X_PWR_OP_BATT_ACTIVATED
) {
333 val
->intval
= POWER_SUPPLY_HEALTH_DEAD
;
337 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
340 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
341 ret
= axp20x_get_constant_charge_current(axp20x_batt
,
347 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
348 val
->intval
= axp20x_batt
->max_ccc
;
351 case POWER_SUPPLY_PROP_CURRENT_NOW
:
352 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_PWR_INPUT_STATUS
,
357 if (reg
& AXP20X_PWR_STATUS_BAT_CHARGING
) {
358 ret
= iio_read_channel_processed(axp20x_batt
->batt_chrg_i
, &val
->intval
);
360 ret
= iio_read_channel_processed(axp20x_batt
->batt_dischrg_i
, &val1
);
366 /* IIO framework gives mA but Power Supply framework gives uA */
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
,
377 if (!(reg
& AXP20X_PWR_OP_BATT_PRESENT
)) {
382 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_FG_RES
, ®
);
386 if (axp20x_batt
->data
->has_fg_valid
&& !(reg
& AXP22X_FG_VALID
))
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
;
396 case POWER_SUPPLY_PROP_VOLTAGE_MAX
:
397 return axp20x_batt
->data
->get_max_voltage(axp20x_batt
,
400 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
401 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_V_OFF
, ®
);
405 val
->intval
= 2600000 + 100000 * (reg
& AXP20X_V_OFF_MASK
);
408 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
409 ret
= iio_read_channel_processed(axp20x_batt
->batt_v
,
414 /* IIO framework gives mV but Power Supply framework gives uV */
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
);
433 case POWER_SUPPLY_PROP_PRESENT
:
434 case POWER_SUPPLY_PROP_ONLINE
:
435 ret
= regmap_read(axp20x_batt
->regmap
, AXP717_ON_INDICATE
,
440 val
->intval
= FIELD_GET(AXP717_PWR_OP_BATT_PRESENT
, reg
);
443 case POWER_SUPPLY_PROP_STATUS
:
444 ret
= regmap_read(axp20x_batt
->regmap
, AXP717_PMU_STATUS_2
,
449 switch (FIELD_GET(AXP717_PWR_STATUS_MASK
, reg
)) {
450 case AXP717_PWR_STATUS_BAT_STANDBY
:
451 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
454 case AXP717_PWR_STATUS_BAT_CHRG
:
455 val
->intval
= POWER_SUPPLY_STATUS_CHARGING
;
458 case AXP717_PWR_STATUS_BAT_DISCHRG
:
459 val
->intval
= POWER_SUPPLY_STATUS_DISCHARGING
;
463 val
->intval
= POWER_SUPPLY_STATUS_UNKNOWN
;
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
,
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
,
485 AXP717_BATT_UVLO_2_5V
,
486 AXP717_BATT_UVLO_2_5V
);
489 case AXP717_BATT_OVER_TEMP
:
490 val
->intval
= POWER_SUPPLY_HEALTH_HOT
;
491 regmap_update_bits(axp20x_batt
->regmap
,
493 AXP717_BATT_OVER_TEMP
,
494 AXP717_BATT_OVER_TEMP
);
497 case AXP717_BATT_UNDER_TEMP
:
498 val
->intval
= POWER_SUPPLY_HEALTH_COLD
;
499 regmap_update_bits(axp20x_batt
->regmap
,
501 AXP717_BATT_UNDER_TEMP
,
502 AXP717_BATT_UNDER_TEMP
);
506 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
510 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
511 ret
= axp717_get_constant_charge_current(axp20x_batt
,
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
);
527 /* IIO framework gives mA but Power Supply framework gives uA */
531 case POWER_SUPPLY_PROP_CAPACITY
:
532 ret
= regmap_read(axp20x_batt
->regmap
, AXP717_ON_INDICATE
,
537 if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT
, reg
))
540 ret
= regmap_read(axp20x_batt
->regmap
,
541 AXP717_BATT_PERCENT_DATA
, ®
);
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
;
552 case POWER_SUPPLY_PROP_VOLTAGE_MAX
:
553 return axp20x_batt
->data
->get_max_voltage(axp20x_batt
,
556 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
557 ret
= regmap_read(axp20x_batt
->regmap
,
558 AXP717_VSYS_V_POWEROFF
, ®
);
562 val
->intval
= AXP717_BAT_VMIN_MIN_UV
+ AXP717_BAT_VMIN_STEP
*
563 (reg
& AXP717_V_OFF_MASK
);
566 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
567 ret
= iio_read_channel_processed(axp20x_batt
->batt_v
,
572 /* IIO framework gives mV but Power Supply framework gives uV */
576 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
577 ret
= regmap_read(axp20x_batt
->regmap
,
578 AXP717_ITERM_CHG_SET
, ®
);
582 val
->intval
= (reg
& AXP717_ITERM_CHG_LIM_MASK
) * AXP717_ITERM_CC_STEP
;
590 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
595 val
= AXP20X_CHRG_CTRL1_TGT_4_1V
;
599 val
= AXP20X_CHRG_CTRL1_TGT_4_2V
;
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).
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
,
621 val
= AXP20X_CHRG_CTRL1_TGT_4_1V
;
625 val
= AXP20X_CHRG_CTRL1_TGT_4_15V
;
629 val
= AXP20X_CHRG_CTRL1_TGT_4_2V
;
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).
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
,
651 val
= AXP717_CHRG_CV_4_0V
;
655 val
= AXP717_CHRG_CV_4_1V
;
659 val
= AXP717_CHRG_CV_4_2V
;
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.
670 return regmap_update_bits(axp20x_batt
->regmap
,
672 AXP717_CHRG_CV_VOLT_MASK
, val
);
675 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps
*axp_batt
,
678 if (charge_current
> axp_batt
->max_ccc
)
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)
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
,
696 if (charge_current
> axp
->max_ccc
)
699 if (charge_current
> AXP717_BAT_CC_MAX_UA
|| charge_current
< 0)
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
,
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)
720 charge_current
= charge_current
* axp
->data
->ccc_scale
+
721 axp
->data
->ccc_offset
;
723 if (charge_current
> axp
->max_ccc
)
725 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n");
729 axp
->max_ccc
= charge_current
;
734 axp20x_get_constant_charge_current(axp
, ¤t_cc
);
735 if (current_cc
> charge_current
)
736 axp20x_set_constant_charge_current(axp
, charge_current
);
741 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps
*axp_batt
,
744 int val1
= (min_voltage
- 2600000) / 100000;
746 if (val1
< 0 || val1
> AXP20X_V_OFF_MASK
)
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
,
756 int val1
= (min_voltage
- AXP717_BAT_VMIN_MIN_UV
) / AXP717_BAT_VMIN_STEP
;
758 if (val1
< 0 || val1
> AXP717_V_OFF_MASK
)
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
);
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
,
782 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
783 return axp20x_set_max_constant_charge_current(axp20x_batt
,
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);
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
);
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
,
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
,
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);
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
,
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
,
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
);
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
,
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
);
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
))
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
)) {
971 "couldn't set ccc from DT: fallback to min value\n");
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
;
987 if (vmin
> 0 && axp717_set_voltage_min_design(axp_batt
, vmin
))
989 "couldn't set voltage_min_design\n");
991 if (vmax
> 0 && axp717_battery_set_max_voltage(axp_batt
, vmax
))
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
)) {
999 "couldn't set ccc from DT: current ccc is %d\n",
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
= {
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
,
1059 .compatible
= "x-powers,axp221-battery-power-supply",
1060 .data
= (void *)&axp221_data
,
1062 .compatible
= "x-powers,axp717-battery-power-supply",
1063 .data
= (void *)&axp717_data
,
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
;
1079 if (!of_device_is_available(pdev
->dev
.of_node
))
1082 axp20x_batt
= devm_kzalloc(&pdev
->dev
, sizeof(*axp20x_batt
),
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
);
1101 axp20x_batt
->batt
= devm_power_supply_register(&pdev
->dev
,
1102 axp20x_batt
->data
->bat_ps_desc
,
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
);
1124 static struct platform_driver axp20x_batt_driver
= {
1125 .probe
= axp20x_power_probe
,
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");