xref: /linux/drivers/power/supply/axp20x_battery.c (revision 448ecd5771e255629bef0fb16c9b78c4bbd7bd56)
1 /*
2  * Battery power supply driver for X-Powers AXP20X and AXP22X PMICs
3  *
4  * Copyright 2016 Free Electrons NextThing Co.
5  *	Quentin Schulz <quentin.schulz@free-electrons.com>
6  *
7  * This driver is based on a previous upstreaming attempt by:
8  *	Bruno Prémont <bonbons@linux-vserver.org>
9  *
10  * This file is subject to the terms and conditions of the GNU General
11  * Public License. See the file "COPYING" in the main directory of this
12  * archive for more details.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  */
19 
20 #include <linux/bitfield.h>
21 #include <linux/err.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/module.h>
25 #include <linux/of.h>
26 #include <linux/platform_device.h>
27 #include <linux/power_supply.h>
28 #include <linux/regmap.h>
29 #include <linux/slab.h>
30 #include <linux/time.h>
31 #include <linux/iio/iio.h>
32 #include <linux/iio/consumer.h>
33 #include <linux/mfd/axp20x.h>
34 
35 #define AXP20X_PWR_STATUS_BAT_CHARGING	BIT(2)
36 #define AXP717_PWR_STATUS_MASK		GENMASK(6, 5)
37 #define AXP717_PWR_STATUS_BAT_STANDBY	0
38 #define AXP717_PWR_STATUS_BAT_CHRG	1
39 #define AXP717_PWR_STATUS_BAT_DISCHRG	2
40 
41 #define AXP20X_PWR_OP_BATT_PRESENT	BIT(5)
42 #define AXP20X_PWR_OP_BATT_ACTIVATED	BIT(3)
43 #define AXP717_PWR_OP_BATT_PRESENT	BIT(3)
44 
45 #define AXP717_BATT_PMU_FAULT_MASK	GENMASK(2, 0)
46 #define AXP717_BATT_UVLO_2_5V		BIT(2)
47 #define AXP717_BATT_OVER_TEMP		BIT(1)
48 #define AXP717_BATT_UNDER_TEMP		BIT(0)
49 
50 #define AXP209_FG_PERCENT		GENMASK(6, 0)
51 #define AXP22X_FG_VALID			BIT(7)
52 
53 #define AXP20X_CHRG_CTRL1_ENABLE	BIT(7)
54 #define AXP20X_CHRG_CTRL1_TGT_VOLT	GENMASK(6, 5)
55 #define AXP20X_CHRG_CTRL1_TGT_4_1V	(0 << 5)
56 #define AXP20X_CHRG_CTRL1_TGT_4_15V	(1 << 5)
57 #define AXP20X_CHRG_CTRL1_TGT_4_2V	(2 << 5)
58 #define AXP20X_CHRG_CTRL1_TGT_4_36V	(3 << 5)
59 
60 #define AXP22X_CHRG_CTRL1_TGT_4_22V	(1 << 5)
61 #define AXP22X_CHRG_CTRL1_TGT_4_24V	(3 << 5)
62 
63 #define AXP717_CHRG_ENABLE		BIT(1)
64 #define AXP717_CHRG_CV_VOLT_MASK	GENMASK(2, 0)
65 #define AXP717_CHRG_CV_4_0V		0
66 #define AXP717_CHRG_CV_4_1V		1
67 #define AXP717_CHRG_CV_4_2V		2
68 #define AXP717_CHRG_CV_4_35V		3
69 #define AXP717_CHRG_CV_4_4V		4
70 /* Values 5 and 6 reserved. */
71 #define AXP717_CHRG_CV_5_0V		7
72 
73 #define AXP813_CHRG_CTRL1_TGT_4_35V	(3 << 5)
74 
75 #define AXP20X_CHRG_CTRL1_TGT_CURR	GENMASK(3, 0)
76 #define AXP717_ICC_CHARGER_LIM_MASK	GENMASK(5, 0)
77 
78 #define AXP717_ITERM_CHG_LIM_MASK	GENMASK(3, 0)
79 #define AXP717_ITERM_CC_STEP		64000
80 
81 #define AXP20X_V_OFF_MASK		GENMASK(2, 0)
82 #define AXP717_V_OFF_MASK		GENMASK(6, 4)
83 
84 #define AXP717_BAT_VMIN_MIN_UV		2600000
85 #define AXP717_BAT_VMIN_MAX_UV		3300000
86 #define AXP717_BAT_VMIN_STEP		100000
87 #define AXP717_BAT_CV_MIN_UV		4000000
88 #define AXP717_BAT_CV_MAX_UV		5000000
89 #define AXP717_BAT_CC_MIN_UA		0
90 #define AXP717_BAT_CC_MAX_UA		3008000
91 
92 struct axp20x_batt_ps;
93 
94 struct axp_data {
95 	int		ccc_scale;
96 	int		ccc_offset;
97 	unsigned int	ccc_reg;
98 	unsigned int	ccc_mask;
99 	bool		has_fg_valid;
100 	const struct	power_supply_desc *bat_ps_desc;
101 	int	(*get_max_voltage)(struct axp20x_batt_ps *batt, int *val);
102 	int	(*set_max_voltage)(struct axp20x_batt_ps *batt, int val);
103 	int	(*cfg_iio_chan)(struct platform_device *pdev,
104 				struct axp20x_batt_ps *axp_batt);
105 	void	(*set_bat_info)(struct platform_device *pdev,
106 				struct axp20x_batt_ps *axp_batt,
107 				struct power_supply_battery_info *info);
108 };
109 
110 struct axp20x_batt_ps {
111 	struct regmap *regmap;
112 	struct power_supply *batt;
113 	struct device *dev;
114 	struct iio_channel *batt_chrg_i;
115 	struct iio_channel *batt_dischrg_i;
116 	struct iio_channel *batt_v;
117 	/* Maximum constant charge current */
118 	unsigned int max_ccc;
119 	const struct axp_data	*data;
120 };
121 
axp20x_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)122 static int axp20x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
123 					  int *val)
124 {
125 	int ret, reg;
126 
127 	ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &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 
axp22x_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)151 static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
152 					  int *val)
153 {
154 	int ret, reg;
155 
156 	ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &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 
axp717_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)180 static int axp717_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
181 					  int *val)
182 {
183 	int ret, reg;
184 
185 	ret = regmap_read(axp20x_batt->regmap, AXP717_CV_CHG_SET, &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 
axp813_battery_get_max_voltage(struct axp20x_batt_ps * axp20x_batt,int * val)213 static int axp813_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
214 					  int *val)
215 {
216 	int ret, reg;
217 
218 	ret = regmap_read(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, &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 
axp20x_get_constant_charge_current(struct axp20x_batt_ps * axp,int * val)242 static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp,
243 					      int *val)
244 {
245 	int ret;
246 
247 	ret = regmap_read(axp->regmap, AXP20X_CHRG_CTRL1, val);
248 	if (ret)
249 		return ret;
250 
251 	*val &= AXP20X_CHRG_CTRL1_TGT_CURR;
252 
253 	*val = *val * axp->data->ccc_scale + axp->data->ccc_offset;
254 
255 	return 0;
256 }
257 
axp717_get_constant_charge_current(struct axp20x_batt_ps * axp,int * val)258 static int axp717_get_constant_charge_current(struct axp20x_batt_ps *axp,
259 					      int *val)
260 {
261 	int ret;
262 
263 	ret = regmap_read(axp->regmap, AXP717_ICC_CHG_SET, val);
264 	if (ret)
265 		return ret;
266 
267 	*val = FIELD_GET(AXP717_ICC_CHARGER_LIM_MASK, *val) *
268 		axp->data->ccc_scale;
269 
270 	return 0;
271 }
272 
axp20x_battery_get_prop(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)273 static int axp20x_battery_get_prop(struct power_supply *psy,
274 				   enum power_supply_property psp,
275 				   union power_supply_propval *val)
276 {
277 	struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
278 	int ret = 0, reg, val1;
279 
280 	switch (psp) {
281 	case POWER_SUPPLY_PROP_PRESENT:
282 	case POWER_SUPPLY_PROP_ONLINE:
283 		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
284 				  &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 		/* IIO framework gives mA but Power Supply framework gives uA */
358 		if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) {
359 			ret = iio_read_channel_processed_scale(axp20x_batt->batt_chrg_i,
360 							       &val->intval, 1000);
361 		} else {
362 			ret = iio_read_channel_processed_scale(axp20x_batt->batt_dischrg_i,
363 							       &val1, 1000);
364 			val->intval = -val1;
365 		}
366 		if (ret)
367 			return ret;
368 
369 		break;
370 
371 	case POWER_SUPPLY_PROP_CAPACITY:
372 		/* When no battery is present, return capacity is 100% */
373 		ret = regmap_read(axp20x_batt->regmap, AXP20X_PWR_OP_MODE,
374 				  &reg);
375 		if (ret)
376 			return ret;
377 
378 		if (!(reg & AXP20X_PWR_OP_BATT_PRESENT)) {
379 			val->intval = 100;
380 			return 0;
381 		}
382 
383 		ret = regmap_read(axp20x_batt->regmap, AXP20X_FG_RES, &reg);
384 		if (ret)
385 			return ret;
386 
387 		if (axp20x_batt->data->has_fg_valid && !(reg & AXP22X_FG_VALID))
388 			return -EINVAL;
389 
390 		/*
391 		 * Fuel Gauge data takes 7 bits but the stored value seems to be
392 		 * directly the raw percentage without any scaling to 7 bits.
393 		 */
394 		val->intval = reg & AXP209_FG_PERCENT;
395 		break;
396 
397 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
398 		return axp20x_batt->data->get_max_voltage(axp20x_batt,
399 							  &val->intval);
400 
401 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
402 		ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg);
403 		if (ret)
404 			return ret;
405 
406 		val->intval = 2600000 + 100000 * (reg & AXP20X_V_OFF_MASK);
407 		break;
408 
409 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
410 		/* IIO framework gives mV but Power Supply framework gives uV */
411 		ret = iio_read_channel_processed_scale(axp20x_batt->batt_v,
412 						 &val->intval, 1000);
413 		if (ret)
414 			return ret;
415 
416 		break;
417 
418 	default:
419 		return -EINVAL;
420 	}
421 
422 	return 0;
423 }
424 
axp717_battery_get_prop(struct power_supply * psy,enum power_supply_property psp,union power_supply_propval * val)425 static int axp717_battery_get_prop(struct power_supply *psy,
426 				   enum power_supply_property psp,
427 				   union power_supply_propval *val)
428 {
429 	struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
430 	int ret = 0, reg;
431 
432 	switch (psp) {
433 	case POWER_SUPPLY_PROP_PRESENT:
434 	case POWER_SUPPLY_PROP_ONLINE:
435 		ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
436 				  &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. Note that
523 		 * IIO framework gives mA but Power Supply framework
524 		 * gives uA.
525 		 */
526 		ret = iio_read_channel_processed_scale(axp20x_batt->batt_chrg_i,
527 						       &val->intval, 1000);
528 		if (ret)
529 			return ret;
530 
531 		return 0;
532 
533 	case POWER_SUPPLY_PROP_CAPACITY:
534 		ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
535 				  &reg);
536 		if (ret)
537 			return ret;
538 
539 		if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg))
540 			return -ENODEV;
541 
542 		ret = regmap_read(axp20x_batt->regmap,
543 				  AXP717_BATT_PERCENT_DATA, &reg);
544 		if (ret)
545 			return ret;
546 
547 		/*
548 		 * Fuel Gauge data takes 7 bits but the stored value seems to be
549 		 * directly the raw percentage without any scaling to 7 bits.
550 		 */
551 		val->intval = reg & AXP209_FG_PERCENT;
552 		return 0;
553 
554 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
555 		return axp20x_batt->data->get_max_voltage(axp20x_batt,
556 							  &val->intval);
557 
558 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
559 		ret = regmap_read(axp20x_batt->regmap,
560 				  AXP717_VSYS_V_POWEROFF, &reg);
561 		if (ret)
562 			return ret;
563 
564 		val->intval = AXP717_BAT_VMIN_MIN_UV + AXP717_BAT_VMIN_STEP *
565 			(reg & AXP717_V_OFF_MASK);
566 		return 0;
567 
568 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
569 		/* IIO framework gives mV but Power Supply framework gives uV */
570 		ret = iio_read_channel_processed_scale(axp20x_batt->batt_v,
571 						       &val->intval, 1000);
572 		if (ret)
573 			return ret;
574 
575 		return 0;
576 
577 	case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
578 		ret = regmap_read(axp20x_batt->regmap,
579 				  AXP717_ITERM_CHG_SET, &reg);
580 		if (ret)
581 			return ret;
582 
583 		val->intval = (reg & AXP717_ITERM_CHG_LIM_MASK) * AXP717_ITERM_CC_STEP;
584 		return 0;
585 
586 	default:
587 		return -EINVAL;
588 	}
589 }
590 
axp22x_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)591 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
592 					  int val)
593 {
594 	switch (val) {
595 	case 4100000:
596 		val = AXP20X_CHRG_CTRL1_TGT_4_1V;
597 		break;
598 
599 	case 4200000:
600 		val = AXP20X_CHRG_CTRL1_TGT_4_2V;
601 		break;
602 
603 	default:
604 		/*
605 		 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
606 		 * can be set to 4.22V and 4.24V, but these voltages are too
607 		 * high for Lithium based batteries (AXP PMICs are supposed to
608 		 * be used with these kinds of battery).
609 		 */
610 		return -EINVAL;
611 	}
612 
613 	return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
614 				  AXP20X_CHRG_CTRL1_TGT_VOLT, val);
615 }
616 
axp20x_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)617 static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
618 					  int val)
619 {
620 	switch (val) {
621 	case 4100000:
622 		val = AXP20X_CHRG_CTRL1_TGT_4_1V;
623 		break;
624 
625 	case 4150000:
626 		val = AXP20X_CHRG_CTRL1_TGT_4_15V;
627 		break;
628 
629 	case 4200000:
630 		val = AXP20X_CHRG_CTRL1_TGT_4_2V;
631 		break;
632 
633 	default:
634 		/*
635 		 * AXP20x max voltage can be set to 4.36V and AXP22X max voltage
636 		 * can be set to 4.22V and 4.24V, but these voltages are too
637 		 * high for Lithium based batteries (AXP PMICs are supposed to
638 		 * be used with these kinds of battery).
639 		 */
640 		return -EINVAL;
641 	}
642 
643 	return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
644 				  AXP20X_CHRG_CTRL1_TGT_VOLT, val);
645 }
646 
axp717_battery_set_max_voltage(struct axp20x_batt_ps * axp20x_batt,int val)647 static int axp717_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
648 					  int val)
649 {
650 	switch (val) {
651 	case 4000000:
652 		val = AXP717_CHRG_CV_4_0V;
653 		break;
654 
655 	case 4100000:
656 		val = AXP717_CHRG_CV_4_1V;
657 		break;
658 
659 	case 4200000:
660 		val = AXP717_CHRG_CV_4_2V;
661 		break;
662 
663 	default:
664 		/*
665 		 * AXP717 can go up to 4.35, 4.4, and 5.0 volts which
666 		 * seem too high for lithium batteries, so do not allow.
667 		 */
668 		return -EINVAL;
669 	}
670 
671 	return regmap_update_bits(axp20x_batt->regmap,
672 				  AXP717_CV_CHG_SET,
673 				  AXP717_CHRG_CV_VOLT_MASK, val);
674 }
675 
axp20x_set_constant_charge_current(struct axp20x_batt_ps * axp_batt,int charge_current)676 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt,
677 					      int charge_current)
678 {
679 	if (charge_current > axp_batt->max_ccc)
680 		return -EINVAL;
681 
682 	charge_current = (charge_current - axp_batt->data->ccc_offset) /
683 		axp_batt->data->ccc_scale;
684 
685 	if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
686 		return -EINVAL;
687 
688 	return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1,
689 				  AXP20X_CHRG_CTRL1_TGT_CURR, charge_current);
690 }
691 
axp717_set_constant_charge_current(struct axp20x_batt_ps * axp,int charge_current)692 static int axp717_set_constant_charge_current(struct axp20x_batt_ps *axp,
693 					      int charge_current)
694 {
695 	int val;
696 
697 	if (charge_current > axp->max_ccc)
698 		return -EINVAL;
699 
700 	if (charge_current > AXP717_BAT_CC_MAX_UA || charge_current < 0)
701 		return -EINVAL;
702 
703 	val = (charge_current - axp->data->ccc_offset) /
704 		axp->data->ccc_scale;
705 
706 	return regmap_update_bits(axp->regmap, AXP717_ICC_CHG_SET,
707 				  AXP717_ICC_CHARGER_LIM_MASK, val);
708 }
709 
axp20x_set_max_constant_charge_current(struct axp20x_batt_ps * axp,int charge_current)710 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp,
711 						  int charge_current)
712 {
713 	bool lower_max = false;
714 
715 	charge_current = (charge_current - axp->data->ccc_offset) /
716 		axp->data->ccc_scale;
717 
718 	if (charge_current > AXP20X_CHRG_CTRL1_TGT_CURR || charge_current < 0)
719 		return -EINVAL;
720 
721 	charge_current = charge_current * axp->data->ccc_scale +
722 		axp->data->ccc_offset;
723 
724 	if (charge_current > axp->max_ccc)
725 		dev_warn(axp->dev,
726 			 "Setting max constant charge current higher than previously defined. Note that increasing the constant charge current may damage your battery.\n");
727 	else
728 		lower_max = true;
729 
730 	axp->max_ccc = charge_current;
731 
732 	if (lower_max) {
733 		int current_cc;
734 
735 		axp20x_get_constant_charge_current(axp, &current_cc);
736 		if (current_cc > charge_current)
737 			axp20x_set_constant_charge_current(axp, charge_current);
738 	}
739 
740 	return 0;
741 }
axp20x_set_voltage_min_design(struct axp20x_batt_ps * axp_batt,int min_voltage)742 static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
743 					 int min_voltage)
744 {
745 	int val1 = (min_voltage - 2600000) / 100000;
746 
747 	if (val1 < 0 || val1 > AXP20X_V_OFF_MASK)
748 		return -EINVAL;
749 
750 	return regmap_update_bits(axp_batt->regmap, AXP20X_V_OFF,
751 				  AXP20X_V_OFF_MASK, val1);
752 }
753 
axp717_set_voltage_min_design(struct axp20x_batt_ps * axp_batt,int min_voltage)754 static int axp717_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
755 					 int min_voltage)
756 {
757 	int val1 = (min_voltage - AXP717_BAT_VMIN_MIN_UV) / AXP717_BAT_VMIN_STEP;
758 
759 	if (val1 < 0 || val1 > AXP717_V_OFF_MASK)
760 		return -EINVAL;
761 
762 	return regmap_update_bits(axp_batt->regmap,
763 				  AXP717_VSYS_V_POWEROFF,
764 				  AXP717_V_OFF_MASK, val1);
765 }
766 
axp20x_battery_set_prop(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)767 static int axp20x_battery_set_prop(struct power_supply *psy,
768 				   enum power_supply_property psp,
769 				   const union power_supply_propval *val)
770 {
771 	struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
772 
773 	switch (psp) {
774 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
775 		return axp20x_set_voltage_min_design(axp20x_batt, val->intval);
776 
777 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
778 		return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
779 
780 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
781 		return axp20x_set_constant_charge_current(axp20x_batt,
782 							  val->intval);
783 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
784 		return axp20x_set_max_constant_charge_current(axp20x_batt,
785 							      val->intval);
786 	case POWER_SUPPLY_PROP_STATUS:
787 		switch (val->intval) {
788 		case POWER_SUPPLY_STATUS_CHARGING:
789 			return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
790 				AXP20X_CHRG_CTRL1_ENABLE, AXP20X_CHRG_CTRL1_ENABLE);
791 
792 		case POWER_SUPPLY_STATUS_DISCHARGING:
793 		case POWER_SUPPLY_STATUS_NOT_CHARGING:
794 			return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1,
795 				AXP20X_CHRG_CTRL1_ENABLE, 0);
796 		}
797 		fallthrough;
798 	default:
799 		return -EINVAL;
800 	}
801 }
802 
axp717_battery_set_prop(struct power_supply * psy,enum power_supply_property psp,const union power_supply_propval * val)803 static int axp717_battery_set_prop(struct power_supply *psy,
804 				   enum power_supply_property psp,
805 				   const union power_supply_propval *val)
806 {
807 	struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
808 
809 	switch (psp) {
810 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
811 		return axp717_set_voltage_min_design(axp20x_batt, val->intval);
812 
813 	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
814 		return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
815 
816 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
817 		return axp717_set_constant_charge_current(axp20x_batt,
818 							  val->intval);
819 	case POWER_SUPPLY_PROP_STATUS:
820 		switch (val->intval) {
821 		case POWER_SUPPLY_STATUS_CHARGING:
822 			return regmap_update_bits(axp20x_batt->regmap,
823 						  AXP717_MODULE_EN_CONTROL_2,
824 						  AXP717_CHRG_ENABLE,
825 						  AXP717_CHRG_ENABLE);
826 
827 		case POWER_SUPPLY_STATUS_DISCHARGING:
828 		case POWER_SUPPLY_STATUS_NOT_CHARGING:
829 			return regmap_update_bits(axp20x_batt->regmap,
830 						  AXP717_MODULE_EN_CONTROL_2,
831 						  AXP717_CHRG_ENABLE, 0);
832 		}
833 		return -EINVAL;
834 	default:
835 		return -EINVAL;
836 	}
837 }
838 
839 static enum power_supply_property axp20x_battery_props[] = {
840 	POWER_SUPPLY_PROP_PRESENT,
841 	POWER_SUPPLY_PROP_ONLINE,
842 	POWER_SUPPLY_PROP_STATUS,
843 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
844 	POWER_SUPPLY_PROP_CURRENT_NOW,
845 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
846 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
847 	POWER_SUPPLY_PROP_HEALTH,
848 	POWER_SUPPLY_PROP_VOLTAGE_MAX,
849 	POWER_SUPPLY_PROP_VOLTAGE_MIN,
850 	POWER_SUPPLY_PROP_CAPACITY,
851 };
852 
853 static enum power_supply_property axp717_battery_props[] = {
854 	POWER_SUPPLY_PROP_PRESENT,
855 	POWER_SUPPLY_PROP_ONLINE,
856 	POWER_SUPPLY_PROP_STATUS,
857 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
858 	POWER_SUPPLY_PROP_CURRENT_NOW,
859 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
860 	POWER_SUPPLY_PROP_HEALTH,
861 	POWER_SUPPLY_PROP_VOLTAGE_MAX,
862 	POWER_SUPPLY_PROP_VOLTAGE_MIN,
863 	POWER_SUPPLY_PROP_CAPACITY,
864 	POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
865 };
866 
axp20x_battery_prop_writeable(struct power_supply * psy,enum power_supply_property psp)867 static int axp20x_battery_prop_writeable(struct power_supply *psy,
868 					 enum power_supply_property psp)
869 {
870 	return psp == POWER_SUPPLY_PROP_STATUS ||
871 	       psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
872 	       psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
873 	       psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT ||
874 	       psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
875 }
876 
axp717_battery_prop_writeable(struct power_supply * psy,enum power_supply_property psp)877 static int axp717_battery_prop_writeable(struct power_supply *psy,
878 					 enum power_supply_property psp)
879 {
880 	return psp == POWER_SUPPLY_PROP_STATUS ||
881 	       psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
882 	       psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
883 	       psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
884 }
885 
886 static const struct power_supply_desc axp209_batt_ps_desc = {
887 	.name = "axp20x-battery",
888 	.type = POWER_SUPPLY_TYPE_BATTERY,
889 	.properties = axp20x_battery_props,
890 	.num_properties = ARRAY_SIZE(axp20x_battery_props),
891 	.property_is_writeable = axp20x_battery_prop_writeable,
892 	.get_property = axp20x_battery_get_prop,
893 	.set_property = axp20x_battery_set_prop,
894 };
895 
896 static const struct power_supply_desc axp717_batt_ps_desc = {
897 	.name = "axp20x-battery",
898 	.type = POWER_SUPPLY_TYPE_BATTERY,
899 	.properties = axp717_battery_props,
900 	.num_properties = ARRAY_SIZE(axp717_battery_props),
901 	.property_is_writeable = axp717_battery_prop_writeable,
902 	.get_property = axp717_battery_get_prop,
903 	.set_property = axp717_battery_set_prop,
904 };
905 
axp209_bat_cfg_iio_channels(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt)906 static int axp209_bat_cfg_iio_channels(struct platform_device *pdev,
907 				       struct axp20x_batt_ps *axp_batt)
908 {
909 	axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
910 	if (IS_ERR(axp_batt->batt_v)) {
911 		if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
912 			return -EPROBE_DEFER;
913 		return PTR_ERR(axp_batt->batt_v);
914 	}
915 
916 	axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
917 							"batt_chrg_i");
918 	if (IS_ERR(axp_batt->batt_chrg_i)) {
919 		if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
920 			return -EPROBE_DEFER;
921 		return PTR_ERR(axp_batt->batt_chrg_i);
922 	}
923 
924 	axp_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
925 							   "batt_dischrg_i");
926 	if (IS_ERR(axp_batt->batt_dischrg_i)) {
927 		if (PTR_ERR(axp_batt->batt_dischrg_i) == -ENODEV)
928 			return -EPROBE_DEFER;
929 		return PTR_ERR(axp_batt->batt_dischrg_i);
930 	}
931 
932 	return 0;
933 }
934 
axp717_bat_cfg_iio_channels(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt)935 static int axp717_bat_cfg_iio_channels(struct platform_device *pdev,
936 				       struct axp20x_batt_ps *axp_batt)
937 {
938 	axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
939 	if (IS_ERR(axp_batt->batt_v)) {
940 		if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
941 			return -EPROBE_DEFER;
942 		return PTR_ERR(axp_batt->batt_v);
943 	}
944 
945 	axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
946 							"batt_chrg_i");
947 	if (IS_ERR(axp_batt->batt_chrg_i)) {
948 		if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
949 			return -EPROBE_DEFER;
950 		return PTR_ERR(axp_batt->batt_chrg_i);
951 	}
952 
953 	return 0;
954 }
955 
axp209_set_battery_info(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt,struct power_supply_battery_info * info)956 static void axp209_set_battery_info(struct platform_device *pdev,
957 				    struct axp20x_batt_ps *axp_batt,
958 				    struct power_supply_battery_info *info)
959 {
960 	int vmin = info->voltage_min_design_uv;
961 	int ccc = info->constant_charge_current_max_ua;
962 
963 	if (vmin > 0 && axp20x_set_voltage_min_design(axp_batt, vmin))
964 		dev_err(&pdev->dev,
965 			"couldn't set voltage_min_design\n");
966 
967 	/* Set max to unverified value to be able to set CCC */
968 	axp_batt->max_ccc = ccc;
969 
970 	if (ccc <= 0 || axp20x_set_constant_charge_current(axp_batt, ccc)) {
971 		dev_err(&pdev->dev,
972 			"couldn't set ccc from DT: fallback to min value\n");
973 		ccc = 300000;
974 		axp_batt->max_ccc = ccc;
975 		axp20x_set_constant_charge_current(axp_batt, ccc);
976 	}
977 }
978 
axp717_set_battery_info(struct platform_device * pdev,struct axp20x_batt_ps * axp_batt,struct power_supply_battery_info * info)979 static void axp717_set_battery_info(struct platform_device *pdev,
980 				    struct axp20x_batt_ps *axp_batt,
981 				    struct power_supply_battery_info *info)
982 {
983 	int vmin = info->voltage_min_design_uv;
984 	int vmax = info->voltage_max_design_uv;
985 	int ccc = info->constant_charge_current_max_ua;
986 	int val;
987 
988 	if (vmin > 0 && axp717_set_voltage_min_design(axp_batt, vmin))
989 		dev_err(&pdev->dev,
990 			"couldn't set voltage_min_design\n");
991 
992 	if (vmax > 0 && axp717_battery_set_max_voltage(axp_batt, vmax))
993 		dev_err(&pdev->dev,
994 			"couldn't set voltage_max_design\n");
995 
996 	axp717_get_constant_charge_current(axp_batt, &val);
997 	axp_batt->max_ccc = ccc;
998 	if (ccc <= 0 || axp717_set_constant_charge_current(axp_batt, ccc)) {
999 		dev_err(&pdev->dev,
1000 			"couldn't set ccc from DT: current ccc is %d\n",
1001 			val);
1002 	}
1003 }
1004 
1005 static const struct axp_data axp209_data = {
1006 	.ccc_scale = 100000,
1007 	.ccc_offset = 300000,
1008 	.ccc_reg = AXP20X_CHRG_CTRL1,
1009 	.ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1010 	.bat_ps_desc = &axp209_batt_ps_desc,
1011 	.get_max_voltage = axp20x_battery_get_max_voltage,
1012 	.set_max_voltage = axp20x_battery_set_max_voltage,
1013 	.cfg_iio_chan = axp209_bat_cfg_iio_channels,
1014 	.set_bat_info = axp209_set_battery_info,
1015 };
1016 
1017 static const struct axp_data axp221_data = {
1018 	.ccc_scale = 150000,
1019 	.ccc_offset = 300000,
1020 	.ccc_reg = AXP20X_CHRG_CTRL1,
1021 	.ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1022 	.has_fg_valid = true,
1023 	.bat_ps_desc = &axp209_batt_ps_desc,
1024 	.get_max_voltage = axp22x_battery_get_max_voltage,
1025 	.set_max_voltage = axp22x_battery_set_max_voltage,
1026 	.cfg_iio_chan = axp209_bat_cfg_iio_channels,
1027 	.set_bat_info = axp209_set_battery_info,
1028 };
1029 
1030 static const struct axp_data axp717_data = {
1031 	.ccc_scale = 64000,
1032 	.ccc_offset = 0,
1033 	.ccc_reg = AXP717_ICC_CHG_SET,
1034 	.ccc_mask = AXP717_ICC_CHARGER_LIM_MASK,
1035 	.bat_ps_desc = &axp717_batt_ps_desc,
1036 	.get_max_voltage = axp717_battery_get_max_voltage,
1037 	.set_max_voltage = axp717_battery_set_max_voltage,
1038 	.cfg_iio_chan = axp717_bat_cfg_iio_channels,
1039 	.set_bat_info = axp717_set_battery_info,
1040 };
1041 
1042 static const struct axp_data axp813_data = {
1043 	.ccc_scale = 200000,
1044 	.ccc_offset = 200000,
1045 	.ccc_reg = AXP20X_CHRG_CTRL1,
1046 	.ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
1047 	.has_fg_valid = true,
1048 	.bat_ps_desc = &axp209_batt_ps_desc,
1049 	.get_max_voltage = axp813_battery_get_max_voltage,
1050 	.set_max_voltage = axp20x_battery_set_max_voltage,
1051 	.cfg_iio_chan = axp209_bat_cfg_iio_channels,
1052 	.set_bat_info = axp209_set_battery_info,
1053 };
1054 
1055 static const struct of_device_id axp20x_battery_ps_id[] = {
1056 	{
1057 		.compatible = "x-powers,axp209-battery-power-supply",
1058 		.data = (void *)&axp209_data,
1059 	}, {
1060 		.compatible = "x-powers,axp221-battery-power-supply",
1061 		.data = (void *)&axp221_data,
1062 	}, {
1063 		.compatible = "x-powers,axp717-battery-power-supply",
1064 		.data = (void *)&axp717_data,
1065 	}, {
1066 		.compatible = "x-powers,axp813-battery-power-supply",
1067 		.data = (void *)&axp813_data,
1068 	}, { /* sentinel */ },
1069 };
1070 MODULE_DEVICE_TABLE(of, axp20x_battery_ps_id);
1071 
axp20x_power_probe(struct platform_device * pdev)1072 static int axp20x_power_probe(struct platform_device *pdev)
1073 {
1074 	struct axp20x_batt_ps *axp20x_batt;
1075 	struct power_supply_config psy_cfg = {};
1076 	struct power_supply_battery_info *info;
1077 	struct device *dev = &pdev->dev;
1078 	int ret;
1079 
1080 	if (!of_device_is_available(pdev->dev.of_node))
1081 		return -ENODEV;
1082 
1083 	axp20x_batt = devm_kzalloc(&pdev->dev, sizeof(*axp20x_batt),
1084 				   GFP_KERNEL);
1085 	if (!axp20x_batt)
1086 		return -ENOMEM;
1087 
1088 	axp20x_batt->dev = &pdev->dev;
1089 
1090 	axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1091 	platform_set_drvdata(pdev, axp20x_batt);
1092 
1093 	psy_cfg.drv_data = axp20x_batt;
1094 	psy_cfg.of_node = pdev->dev.of_node;
1095 
1096 	axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev);
1097 
1098 	ret = axp20x_batt->data->cfg_iio_chan(pdev, axp20x_batt);
1099 	if (ret)
1100 		return ret;
1101 
1102 	axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
1103 						       axp20x_batt->data->bat_ps_desc,
1104 						       &psy_cfg);
1105 	if (IS_ERR(axp20x_batt->batt)) {
1106 		dev_err(&pdev->dev, "failed to register power supply: %ld\n",
1107 			PTR_ERR(axp20x_batt->batt));
1108 		return PTR_ERR(axp20x_batt->batt);
1109 	}
1110 
1111 	if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) {
1112 		axp20x_batt->data->set_bat_info(pdev, axp20x_batt, info);
1113 		power_supply_put_battery_info(axp20x_batt->batt, info);
1114 	}
1115 
1116 	/*
1117 	 * Update max CCC to a valid value if battery info is present or set it
1118 	 * to current register value by default.
1119 	 */
1120 	axp20x_get_constant_charge_current(axp20x_batt, &axp20x_batt->max_ccc);
1121 
1122 	return 0;
1123 }
1124 
1125 static struct platform_driver axp20x_batt_driver = {
1126 	.probe    = axp20x_power_probe,
1127 	.driver   = {
1128 		.name  = "axp20x-battery-power-supply",
1129 		.of_match_table = axp20x_battery_ps_id,
1130 	},
1131 };
1132 
1133 module_platform_driver(axp20x_batt_driver);
1134 
1135 MODULE_DESCRIPTION("Battery power supply driver for AXP20X and AXP22X PMICs");
1136 MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
1137 MODULE_LICENSE("GPL");
1138