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 /* 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
,
362 ret
= iio_read_channel_processed_scale(axp20x_batt
->batt_dischrg_i
,
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
,
378 if (!(reg
& AXP20X_PWR_OP_BATT_PRESENT
)) {
383 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_FG_RES
, ®
);
387 if (axp20x_batt
->data
->has_fg_valid
&& !(reg
& AXP22X_FG_VALID
))
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.
394 val
->intval
= reg
& AXP209_FG_PERCENT
;
397 case POWER_SUPPLY_PROP_VOLTAGE_MAX
:
398 return axp20x_batt
->data
->get_max_voltage(axp20x_batt
,
401 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
402 ret
= regmap_read(axp20x_batt
->regmap
, AXP20X_V_OFF
, ®
);
406 val
->intval
= 2600000 + 100000 * (reg
& AXP20X_V_OFF_MASK
);
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
,
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. Note that
523 * IIO framework gives mA but Power Supply framework
526 ret
= iio_read_channel_processed_scale(axp20x_batt
->batt_chrg_i
,
533 case POWER_SUPPLY_PROP_CAPACITY
:
534 ret
= regmap_read(axp20x_batt
->regmap
, AXP717_ON_INDICATE
,
539 if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT
, reg
))
542 ret
= regmap_read(axp20x_batt
->regmap
,
543 AXP717_BATT_PERCENT_DATA
, ®
);
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.
551 val
->intval
= reg
& AXP209_FG_PERCENT
;
554 case POWER_SUPPLY_PROP_VOLTAGE_MAX
:
555 return axp20x_batt
->data
->get_max_voltage(axp20x_batt
,
558 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
559 ret
= regmap_read(axp20x_batt
->regmap
,
560 AXP717_VSYS_V_POWEROFF
, ®
);
564 val
->intval
= AXP717_BAT_VMIN_MIN_UV
+ AXP717_BAT_VMIN_STEP
*
565 (reg
& AXP717_V_OFF_MASK
);
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
,
577 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT
:
578 ret
= regmap_read(axp20x_batt
->regmap
,
579 AXP717_ITERM_CHG_SET
, ®
);
583 val
->intval
= (reg
& AXP717_ITERM_CHG_LIM_MASK
) * AXP717_ITERM_CC_STEP
;
591 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
596 val
= AXP20X_CHRG_CTRL1_TGT_4_1V
;
600 val
= AXP20X_CHRG_CTRL1_TGT_4_2V
;
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).
613 return regmap_update_bits(axp20x_batt
->regmap
, AXP20X_CHRG_CTRL1
,
614 AXP20X_CHRG_CTRL1_TGT_VOLT
, val
);
617 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
622 val
= AXP20X_CHRG_CTRL1_TGT_4_1V
;
626 val
= AXP20X_CHRG_CTRL1_TGT_4_15V
;
630 val
= AXP20X_CHRG_CTRL1_TGT_4_2V
;
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).
643 return regmap_update_bits(axp20x_batt
->regmap
, AXP20X_CHRG_CTRL1
,
644 AXP20X_CHRG_CTRL1_TGT_VOLT
, val
);
647 static int axp717_battery_set_max_voltage(struct axp20x_batt_ps
*axp20x_batt
,
652 val
= AXP717_CHRG_CV_4_0V
;
656 val
= AXP717_CHRG_CV_4_1V
;
660 val
= AXP717_CHRG_CV_4_2V
;
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.
671 return regmap_update_bits(axp20x_batt
->regmap
,
673 AXP717_CHRG_CV_VOLT_MASK
, val
);
676 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps
*axp_batt
,
679 if (charge_current
> axp_batt
->max_ccc
)
682 charge_current
= (charge_current
- axp_batt
->data
->ccc_offset
) /
683 axp_batt
->data
->ccc_scale
;
685 if (charge_current
> AXP20X_CHRG_CTRL1_TGT_CURR
|| charge_current
< 0)
688 return regmap_update_bits(axp_batt
->regmap
, AXP20X_CHRG_CTRL1
,
689 AXP20X_CHRG_CTRL1_TGT_CURR
, charge_current
);
692 static int axp717_set_constant_charge_current(struct axp20x_batt_ps
*axp
,
697 if (charge_current
> axp
->max_ccc
)
700 if (charge_current
> AXP717_BAT_CC_MAX_UA
|| charge_current
< 0)
703 val
= (charge_current
- axp
->data
->ccc_offset
) /
704 axp
->data
->ccc_scale
;
706 return regmap_update_bits(axp
->regmap
, AXP717_ICC_CHG_SET
,
707 AXP717_ICC_CHARGER_LIM_MASK
, val
);
710 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps
*axp
,
713 bool lower_max
= false;
715 charge_current
= (charge_current
- axp
->data
->ccc_offset
) /
716 axp
->data
->ccc_scale
;
718 if (charge_current
> AXP20X_CHRG_CTRL1_TGT_CURR
|| charge_current
< 0)
721 charge_current
= charge_current
* axp
->data
->ccc_scale
+
722 axp
->data
->ccc_offset
;
724 if (charge_current
> axp
->max_ccc
)
726 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n");
730 axp
->max_ccc
= charge_current
;
735 axp20x_get_constant_charge_current(axp
, ¤t_cc
);
736 if (current_cc
> charge_current
)
737 axp20x_set_constant_charge_current(axp
, charge_current
);
742 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps
*axp_batt
,
745 int val1
= (min_voltage
- 2600000) / 100000;
747 if (val1
< 0 || val1
> AXP20X_V_OFF_MASK
)
750 return regmap_update_bits(axp_batt
->regmap
, AXP20X_V_OFF
,
751 AXP20X_V_OFF_MASK
, val1
);
754 static int axp717_set_voltage_min_design(struct axp20x_batt_ps
*axp_batt
,
757 int val1
= (min_voltage
- AXP717_BAT_VMIN_MIN_UV
) / AXP717_BAT_VMIN_STEP
;
759 if (val1
< 0 || val1
> AXP717_V_OFF_MASK
)
762 return regmap_update_bits(axp_batt
->regmap
,
763 AXP717_VSYS_V_POWEROFF
,
764 AXP717_V_OFF_MASK
, val1
);
767 static int axp20x_battery_set_prop(struct power_supply
*psy
,
768 enum power_supply_property psp
,
769 const union power_supply_propval
*val
)
771 struct axp20x_batt_ps
*axp20x_batt
= power_supply_get_drvdata(psy
);
774 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
775 return axp20x_set_voltage_min_design(axp20x_batt
, val
->intval
);
777 case POWER_SUPPLY_PROP_VOLTAGE_MAX
:
778 return axp20x_batt
->data
->set_max_voltage(axp20x_batt
, val
->intval
);
780 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT
:
781 return axp20x_set_constant_charge_current(axp20x_batt
,
783 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
784 return axp20x_set_max_constant_charge_current(axp20x_batt
,
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
);
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);
803 static int axp717_battery_set_prop(struct power_supply
*psy
,
804 enum power_supply_property psp
,
805 const union power_supply_propval
*val
)
807 struct axp20x_batt_ps
*axp20x_batt
= power_supply_get_drvdata(psy
);
810 case POWER_SUPPLY_PROP_VOLTAGE_MIN
:
811 return axp717_set_voltage_min_design(axp20x_batt
, val
->intval
);
813 case POWER_SUPPLY_PROP_VOLTAGE_MAX
:
814 return axp20x_batt
->data
->set_max_voltage(axp20x_batt
, val
->intval
);
816 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX
:
817 return axp717_set_constant_charge_current(axp20x_batt
,
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
,
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);
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
,
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
,
867 static int axp20x_battery_prop_writeable(struct power_supply
*psy
,
868 enum power_supply_property psp
)
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
;
877 static int axp717_battery_prop_writeable(struct power_supply
*psy
,
878 enum power_supply_property psp
)
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
;
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
,
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
,
906 static int axp209_bat_cfg_iio_channels(struct platform_device
*pdev
,
907 struct axp20x_batt_ps
*axp_batt
)
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
);
916 axp_batt
->batt_chrg_i
= devm_iio_channel_get(&pdev
->dev
,
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
);
924 axp_batt
->batt_dischrg_i
= devm_iio_channel_get(&pdev
->dev
,
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
);
935 static int axp717_bat_cfg_iio_channels(struct platform_device
*pdev
,
936 struct axp20x_batt_ps
*axp_batt
)
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
);
945 axp_batt
->batt_chrg_i
= devm_iio_channel_get(&pdev
->dev
,
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
);
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
)
960 int vmin
= info
->voltage_min_design_uv
;
961 int ccc
= info
->constant_charge_current_max_ua
;
963 if (vmin
> 0 && axp20x_set_voltage_min_design(axp_batt
, vmin
))
965 "couldn't set voltage_min_design\n");
967 /* Set max to unverified value to be able to set CCC */
968 axp_batt
->max_ccc
= ccc
;
970 if (ccc
<= 0 || axp20x_set_constant_charge_current(axp_batt
, ccc
)) {
972 "couldn't set ccc from DT: fallback to min value\n");
974 axp_batt
->max_ccc
= ccc
;
975 axp20x_set_constant_charge_current(axp_batt
, ccc
);
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
)
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
;
988 if (vmin
> 0 && axp717_set_voltage_min_design(axp_batt
, vmin
))
990 "couldn't set voltage_min_design\n");
992 if (vmax
> 0 && axp717_battery_set_max_voltage(axp_batt
, vmax
))
994 "couldn't set voltage_max_design\n");
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
)) {
1000 "couldn't set ccc from DT: current ccc is %d\n",
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
,
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
,
1030 static const struct axp_data axp717_data
= {
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
,
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
,
1055 static const struct of_device_id axp20x_battery_ps_id
[] = {
1057 .compatible
= "x-powers,axp209-battery-power-supply",
1058 .data
= (void *)&axp209_data
,
1060 .compatible
= "x-powers,axp221-battery-power-supply",
1061 .data
= (void *)&axp221_data
,
1063 .compatible
= "x-powers,axp717-battery-power-supply",
1064 .data
= (void *)&axp717_data
,
1066 .compatible
= "x-powers,axp813-battery-power-supply",
1067 .data
= (void *)&axp813_data
,
1068 }, { /* sentinel */ },
1070 MODULE_DEVICE_TABLE(of
, axp20x_battery_ps_id
);
1072 static int axp20x_power_probe(struct platform_device
*pdev
)
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
;
1080 if (!of_device_is_available(pdev
->dev
.of_node
))
1083 axp20x_batt
= devm_kzalloc(&pdev
->dev
, sizeof(*axp20x_batt
),
1088 axp20x_batt
->dev
= &pdev
->dev
;
1090 axp20x_batt
->regmap
= dev_get_regmap(pdev
->dev
.parent
, NULL
);
1091 platform_set_drvdata(pdev
, axp20x_batt
);
1093 psy_cfg
.drv_data
= axp20x_batt
;
1094 psy_cfg
.of_node
= pdev
->dev
.of_node
;
1096 axp20x_batt
->data
= (struct axp_data
*)of_device_get_match_data(dev
);
1098 ret
= axp20x_batt
->data
->cfg_iio_chan(pdev
, axp20x_batt
);
1102 axp20x_batt
->batt
= devm_power_supply_register(&pdev
->dev
,
1103 axp20x_batt
->data
->bat_ps_desc
,
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
);
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
);
1117 * Update max CCC to a valid value if battery info is present or set it
1118 * to current register value by default.
1120 axp20x_get_constant_charge_current(axp20x_batt
, &axp20x_batt
->max_ccc
);
1125 static struct platform_driver axp20x_batt_driver
= {
1126 .probe
= axp20x_power_probe
,
1128 .name
= "axp20x-battery-power-supply",
1129 .of_match_table
= axp20x_battery_ps_id
,
1133 module_platform_driver(axp20x_batt_driver
);
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");