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