xref: /linux/drivers/power/supply/bq257xx_charger.c (revision 4f38da1f027ea2c9f01bb71daa7a299c191b6940)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * BQ257XX Battery Charger Driver
4  * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com>
5  */
6 
7 #include <linux/bitfield.h>
8 #include <linux/i2c.h>
9 #include <linux/interrupt.h>
10 #include <linux/mfd/bq257xx.h>
11 #include <linux/platform_device.h>
12 #include <linux/power_supply.h>
13 #include <linux/property.h>
14 #include <linux/regmap.h>
15 
16 /* Forward declaration of driver data. */
17 struct bq257xx_chg;
18 
19 /**
20  * struct bq257xx_chip_info - chip specific routines
21  * @bq257xx_hw_init: init function for hw
22  * @bq257xx_hw_shutdown: shutdown function for hw
23  * @bq257xx_get_state: get and update state of hardware
24  * @bq257xx_set_ichg: set maximum charge current (in uA)
25  * @bq257xx_set_vbatreg: set maximum charge voltage (in uV)
26  * @bq257xx_set_iindpm: set maximum input current (in uA)
27  */
28 struct bq257xx_chip_info {
29 	int (*bq257xx_hw_init)(struct bq257xx_chg *pdata);
30 	void (*bq257xx_hw_shutdown)(struct bq257xx_chg *pdata);
31 	int (*bq257xx_get_state)(struct bq257xx_chg *pdata);
32 	int (*bq257xx_set_ichg)(struct bq257xx_chg *pdata, int ichg);
33 	int (*bq257xx_set_vbatreg)(struct bq257xx_chg *pdata, int vbatreg);
34 	int (*bq257xx_set_iindpm)(struct bq257xx_chg *pdata, int iindpm);
35 };
36 
37 /**
38  * struct bq257xx_chg - driver data for charger
39  * @chip: hw specific functions
40  * @bq: parent MFD device
41  * @charger: power supply device
42  * @online: charger input is present
43  * @fast_charge: charger is in fast charge mode
44  * @pre_charge: charger is in pre-charge mode
45  * @ov_fault: charger reports over voltage fault
46  * @batoc_fault: charger reports battery over current fault
47  * @oc_fault: charger reports over current fault
48  * @usb_type: USB type reported from parent power supply
49  * @supplied: Status of parent power supply
50  * @iindpm_max: maximum input current limit (uA)
51  * @vbat_max: maximum charge voltage (uV)
52  * @ichg_max: maximum charge current (uA)
53  * @vsys_min: minimum system voltage (uV)
54  */
55 struct bq257xx_chg {
56 	const struct bq257xx_chip_info *chip;
57 	struct bq257xx_device *bq;
58 	struct power_supply *charger;
59 	bool online;
60 	bool fast_charge;
61 	bool pre_charge;
62 	bool ov_fault;
63 	bool batoc_fault;
64 	bool oc_fault;
65 	int usb_type;
66 	int supplied;
67 	u32 iindpm_max;
68 	u32 vbat_max;
69 	u32 ichg_max;
70 	u32 vsys_min;
71 };
72 
73 /**
74  * bq25703_get_state() - Get the current state of the device
75  * @pdata: driver platform data
76  *
77  * Get the current state of the charger. Check if the charger is
78  * powered, what kind of charge state (if any) the device is in,
79  * and if there are any active faults.
80  *
81  * Return: Returns 0 on success, or error on failure to read device.
82  */
83 static int bq25703_get_state(struct bq257xx_chg *pdata)
84 {
85 	unsigned int reg;
86 	int ret;
87 
88 	ret = regmap_read(pdata->bq->regmap, BQ25703_CHARGER_STATUS, &reg);
89 	if (ret)
90 		return ret;
91 
92 	pdata->online = reg & BQ25703_STS_AC_STAT;
93 	pdata->fast_charge = reg & BQ25703_STS_IN_FCHRG;
94 	pdata->pre_charge = reg & BQ25703_STS_IN_PCHRG;
95 	pdata->ov_fault = reg & BQ25703_STS_FAULT_ACOV;
96 	pdata->batoc_fault = reg & BQ25703_STS_FAULT_BATOC;
97 	pdata->oc_fault = reg & BQ25703_STS_FAULT_ACOC;
98 
99 	return 0;
100 }
101 
102 /**
103  * bq25703_get_min_vsys() - Get the minimum system voltage
104  * @pdata: driver platform data
105  * @intval: value for minimum voltage
106  *
107  * Return: Returns 0 on success or error on failure to read.
108  */
109 static int bq25703_get_min_vsys(struct bq257xx_chg *pdata, int *intval)
110 {
111 	unsigned int reg;
112 	int ret;
113 
114 	ret = regmap_read(pdata->bq->regmap, BQ25703_MIN_VSYS,
115 			  &reg);
116 	if (ret)
117 		return ret;
118 
119 	reg = FIELD_GET(BQ25703_MINVSYS_MASK, reg);
120 	*intval = (reg * BQ25703_MINVSYS_STEP_UV) + BQ25703_MINVSYS_MIN_UV;
121 
122 	return ret;
123 }
124 
125 /**
126  * bq25703_set_min_vsys() - Set the minimum system voltage
127  * @pdata: driver platform data
128  * @vsys: voltage value to set in uV.
129  *
130  * This function takes a requested minimum system voltage value, clamps
131  * it between the minimum supported value by the charger and a user
132  * defined minimum system value, and then writes the value to the
133  * appropriate register.
134  *
135  * Return: Returns 0 on success or error if an error occurs.
136  */
137 static int bq25703_set_min_vsys(struct bq257xx_chg *pdata, int vsys)
138 {
139 	unsigned int reg;
140 	int vsys_min = pdata->vsys_min;
141 
142 	vsys = clamp(vsys, BQ25703_MINVSYS_MIN_UV, vsys_min);
143 	reg = ((vsys - BQ25703_MINVSYS_MIN_UV) / BQ25703_MINVSYS_STEP_UV);
144 	reg = FIELD_PREP(BQ25703_MINVSYS_MASK, reg);
145 
146 	return regmap_write(pdata->bq->regmap, BQ25703_MIN_VSYS,
147 			    reg);
148 }
149 
150 /**
151  * bq25703_get_cur() - Get the reported current from the battery
152  * @pdata: driver platform data
153  * @intval: value of reported battery current
154  *
155  * Read the reported current from the battery. Since value is always
156  * positive set sign to negative if discharging.
157  *
158  * Return: Returns 0 on success or error if unable to read value.
159  */
160 static int bq25703_get_cur(struct bq257xx_chg *pdata, int *intval)
161 {
162 	unsigned int reg;
163 	int ret;
164 
165 	ret = regmap_read(pdata->bq->regmap, BQ25703_ADCIBAT_CHG, &reg);
166 	if (ret < 0)
167 		return ret;
168 
169 	if (pdata->online)
170 		*intval = FIELD_GET(BQ25703_ADCIBAT_CHG_MASK, reg) *
171 			  BQ25703_ADCIBAT_CHG_STEP_UA;
172 	else
173 		*intval = -(FIELD_GET(BQ25703_ADCIBAT_DISCHG_MASK, reg) *
174 			    BQ25703_ADCIBAT_DIS_STEP_UA);
175 
176 	return ret;
177 }
178 
179 /**
180  * bq25703_get_ichg_cur() - Get the maximum reported charge current
181  * @pdata: driver platform data
182  * @intval: value of maximum reported charge current
183  *
184  * Get the maximum reported charge current from the battery.
185  *
186  * Return: Returns 0 on success or error if unable to read value.
187  */
188 static int bq25703_get_ichg_cur(struct bq257xx_chg *pdata, int *intval)
189 {
190 	unsigned int reg;
191 	int ret;
192 
193 	ret = regmap_read(pdata->bq->regmap, BQ25703_CHARGE_CURRENT, &reg);
194 	if (ret)
195 		return ret;
196 
197 	*intval = FIELD_GET(BQ25703_ICHG_MASK, reg) * BQ25703_ICHG_STEP_UA;
198 
199 	return ret;
200 }
201 
202 /**
203  * bq25703_set_ichg_cur() - Set the maximum charge current
204  * @pdata: driver platform data
205  * @ichg: current value to set in uA.
206  *
207  * This function takes a requested maximum charge current value, clamps
208  * it between the minimum supported value by the charger and a user
209  * defined maximum charging value, and then writes the value to the
210  * appropriate register.
211  *
212  * Return: Returns 0 on success or error if an error occurs.
213  */
214 static int bq25703_set_ichg_cur(struct bq257xx_chg *pdata, int ichg)
215 {
216 	unsigned int reg;
217 	int ichg_max = pdata->ichg_max;
218 
219 	ichg = clamp(ichg, BQ25703_ICHG_MIN_UA, ichg_max);
220 	reg = FIELD_PREP(BQ25703_ICHG_MASK, (ichg / BQ25703_ICHG_STEP_UA));
221 
222 	return regmap_write(pdata->bq->regmap, BQ25703_CHARGE_CURRENT,
223 			    reg);
224 }
225 
226 /**
227  * bq25703_get_chrg_volt() - Get the maximum set charge voltage
228  * @pdata: driver platform data
229  * @intval: maximum charge voltage value
230  *
231  * Return: Returns 0 on success or error if unable to read value.
232  */
233 static int bq25703_get_chrg_volt(struct bq257xx_chg *pdata, int *intval)
234 {
235 	unsigned int reg;
236 	int ret;
237 
238 	ret = regmap_read(pdata->bq->regmap, BQ25703_MAX_CHARGE_VOLT,
239 			  &reg);
240 	if (ret)
241 		return ret;
242 
243 	*intval = FIELD_GET(BQ25703_MAX_CHARGE_VOLT_MASK, reg) *
244 		  BQ25703_VBATREG_STEP_UV;
245 
246 	return ret;
247 }
248 
249 /**
250  * bq25703_set_chrg_volt() - Set the maximum charge voltage
251  * @pdata: driver platform data
252  * @vbat: voltage value to set in uV.
253  *
254  * This function takes a requested maximum charge voltage value, clamps
255  * it between the minimum supported value by the charger and a user
256  * defined maximum charging value, and then writes the value to the
257  * appropriate register.
258  *
259  * Return: Returns 0 on success or error if an error occurs.
260  */
261 static int bq25703_set_chrg_volt(struct bq257xx_chg *pdata, int vbat)
262 {
263 	unsigned int reg;
264 	int vbat_max = pdata->vbat_max;
265 
266 	vbat = clamp(vbat, BQ25703_VBATREG_MIN_UV, vbat_max);
267 
268 	reg = FIELD_PREP(BQ25703_MAX_CHARGE_VOLT_MASK,
269 			 (vbat / BQ25703_VBATREG_STEP_UV));
270 
271 	return regmap_write(pdata->bq->regmap, BQ25703_MAX_CHARGE_VOLT,
272 			    reg);
273 }
274 
275 /**
276  * bq25703_get_iindpm() - Get the maximum set input current
277  * @pdata: driver platform data
278  * @intval: maximum input current value
279  *
280  * Read the actual input current limit from the device into intval.
281  * This can differ from the value programmed due to some autonomous
282  * functions that may be enabled (but are not currently). This is why
283  * there is a different register used.
284  *
285  * Return: Returns 0 on success or error if unable to read register
286  * value.
287  */
288 static int bq25703_get_iindpm(struct bq257xx_chg *pdata, int *intval)
289 {
290 	unsigned int reg;
291 	int ret;
292 
293 	ret = regmap_read(pdata->bq->regmap, BQ25703_IIN_DPM, &reg);
294 	if (ret)
295 		return ret;
296 
297 	reg = FIELD_GET(BQ25703_IINDPM_MASK, reg);
298 	*intval = (reg * BQ25703_IINDPM_STEP_UA) + BQ25703_IINDPM_OFFSET_UA;
299 
300 	return ret;
301 }
302 
303 /**
304  * bq25703_set_iindpm() - Set the maximum input current
305  * @pdata: driver platform data
306  * @iindpm: current value in uA.
307  *
308  * This function takes a requested maximum input current value, clamps
309  * it between the minimum supported value by the charger and a user
310  * defined maximum input value, and then writes the value to the
311  * appropriate register.
312  *
313  * Return: Returns 0 on success or error if an error occurs.
314  */
315 static int bq25703_set_iindpm(struct bq257xx_chg *pdata, int iindpm)
316 {
317 	unsigned int reg;
318 	int iindpm_max = pdata->iindpm_max;
319 
320 	iindpm = clamp(iindpm, BQ25703_IINDPM_MIN_UA, iindpm_max);
321 
322 	reg = ((iindpm - BQ25703_IINDPM_OFFSET_UA) / BQ25703_IINDPM_STEP_UA);
323 
324 	return regmap_write(pdata->bq->regmap, BQ25703_IIN_HOST,
325 			    FIELD_PREP(BQ25703_IINDPM_MASK, reg));
326 }
327 
328 /**
329  * bq25703_get_vbat() - Get the reported voltage from the battery
330  * @pdata: driver platform data
331  * @intval: value of reported battery voltage
332  *
333  * Read value of battery voltage into intval.
334  *
335  * Return: Returns 0 on success or error if unable to read value.
336  */
337 static int bq25703_get_vbat(struct bq257xx_chg *pdata, int *intval)
338 {
339 	unsigned int reg;
340 	int ret;
341 
342 	ret = regmap_read(pdata->bq->regmap, BQ25703_ADCVSYSVBAT, &reg);
343 	if (ret)
344 		return ret;
345 
346 	reg = FIELD_GET(BQ25703_ADCVBAT_MASK, reg);
347 	*intval = (reg * BQ25703_ADCVSYSVBAT_STEP) + BQ25703_ADCVSYSVBAT_OFFSET_UV;
348 
349 	return ret;
350 }
351 
352 /**
353  * bq25703_hw_init() - Set all the required registers to init the charger
354  * @pdata: driver platform data
355  *
356  * Initialize the BQ25703 by first disabling the watchdog timer (which
357  * shuts off the charger in the absence of periodic writes). Then, set
358  * the charge current, charge voltage, minimum system voltage, and
359  * input current limit. Disable low power mode to allow ADCs and
360  * interrupts. Enable the ADC, start the ADC, set the ADC scale to
361  * full, and enable each individual ADC channel.
362  *
363  * Return: Returns 0 on success or error code on error.
364  */
365 static int bq25703_hw_init(struct bq257xx_chg *pdata)
366 {
367 	struct regmap *regmap = pdata->bq->regmap;
368 	int ret = 0;
369 
370 	regmap_update_bits(regmap, BQ25703_CHARGE_OPTION_0,
371 			   BQ25703_WDTMR_ADJ_MASK,
372 			   FIELD_PREP(BQ25703_WDTMR_ADJ_MASK,
373 			   BQ25703_WDTMR_DISABLE));
374 
375 	ret = pdata->chip->bq257xx_set_ichg(pdata, pdata->ichg_max);
376 	if (ret)
377 		return ret;
378 
379 	ret = pdata->chip->bq257xx_set_vbatreg(pdata, pdata->vbat_max);
380 	if (ret)
381 		return ret;
382 
383 	ret = bq25703_set_min_vsys(pdata, pdata->vsys_min);
384 	if (ret)
385 		return ret;
386 
387 	ret = pdata->chip->bq257xx_set_iindpm(pdata, pdata->iindpm_max);
388 	if (ret)
389 		return ret;
390 
391 	/* Disable low power mode by writing 0 to the register. */
392 	regmap_update_bits(regmap, BQ25703_CHARGE_OPTION_0,
393 			   BQ25703_EN_LWPWR, 0);
394 
395 	/* Enable the ADC. */
396 	regmap_update_bits(regmap, BQ25703_ADC_OPTION,
397 			   BQ25703_ADC_CONV_EN, BQ25703_ADC_CONV_EN);
398 
399 	/* Start the ADC. */
400 	regmap_update_bits(regmap, BQ25703_ADC_OPTION,
401 			   BQ25703_ADC_START, BQ25703_ADC_START);
402 
403 	/* Set the scale of the ADC. */
404 	regmap_update_bits(regmap, BQ25703_ADC_OPTION,
405 			   BQ25703_ADC_FULL_SCALE, BQ25703_ADC_FULL_SCALE);
406 
407 	/* Enable each of the ADC channels available. */
408 	regmap_update_bits(regmap, BQ25703_ADC_OPTION,
409 			   BQ25703_ADC_CH_MASK,
410 			   (BQ25703_ADC_CMPIN_EN | BQ25703_ADC_VBUS_EN |
411 			   BQ25703_ADC_PSYS_EN | BQ25703_ADC_IIN_EN |
412 			   BQ25703_ADC_IDCHG_EN | BQ25703_ADC_ICHG_EN |
413 			   BQ25703_ADC_VSYS_EN | BQ25703_ADC_VBAT_EN));
414 
415 	return ret;
416 }
417 
418 /**
419  * bq25703_hw_shutdown() - Set registers for shutdown
420  * @pdata: driver platform data
421  *
422  * Enable low power mode for the device while in shutdown.
423  */
424 static void bq25703_hw_shutdown(struct bq257xx_chg *pdata)
425 {
426 	regmap_update_bits(pdata->bq->regmap, BQ25703_CHARGE_OPTION_0,
427 			   BQ25703_EN_LWPWR, BQ25703_EN_LWPWR);
428 }
429 
430 static int bq257xx_set_charger_property(struct power_supply *psy,
431 		enum power_supply_property prop,
432 		const union power_supply_propval *val)
433 {
434 	struct bq257xx_chg *pdata = power_supply_get_drvdata(psy);
435 
436 	switch (prop) {
437 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
438 		return pdata->chip->bq257xx_set_iindpm(pdata, val->intval);
439 
440 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
441 		return pdata->chip->bq257xx_set_vbatreg(pdata, val->intval);
442 
443 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
444 		return pdata->chip->bq257xx_set_ichg(pdata, val->intval);
445 
446 	default:
447 		break;
448 	}
449 
450 	return -EINVAL;
451 }
452 
453 static int bq257xx_get_charger_property(struct power_supply *psy,
454 				enum power_supply_property psp,
455 				union power_supply_propval *val)
456 {
457 	struct bq257xx_chg *pdata = power_supply_get_drvdata(psy);
458 	int ret = 0;
459 
460 	ret = pdata->chip->bq257xx_get_state(pdata);
461 	if (ret)
462 		return ret;
463 
464 	switch (psp) {
465 	case POWER_SUPPLY_PROP_STATUS:
466 		if (!pdata->online)
467 			val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
468 		else if (pdata->fast_charge || pdata->pre_charge)
469 			val->intval = POWER_SUPPLY_STATUS_CHARGING;
470 		else
471 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
472 		break;
473 
474 	case POWER_SUPPLY_PROP_HEALTH:
475 		if (pdata->ov_fault || pdata->batoc_fault)
476 			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
477 		else if (pdata->oc_fault)
478 			val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT;
479 		else
480 			val->intval = POWER_SUPPLY_HEALTH_GOOD;
481 		break;
482 
483 	case POWER_SUPPLY_PROP_MANUFACTURER:
484 		val->strval = "Texas Instruments";
485 		break;
486 
487 	case POWER_SUPPLY_PROP_ONLINE:
488 		val->intval = pdata->online;
489 		break;
490 
491 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
492 		return bq25703_get_iindpm(pdata, &val->intval);
493 
494 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
495 		return bq25703_get_chrg_volt(pdata, &val->intval);
496 
497 	case POWER_SUPPLY_PROP_CURRENT_NOW:
498 		return bq25703_get_cur(pdata, &val->intval);
499 
500 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
501 		return bq25703_get_vbat(pdata, &val->intval);
502 
503 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
504 		return bq25703_get_ichg_cur(pdata, &val->intval);
505 
506 	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
507 		return bq25703_get_min_vsys(pdata, &val->intval);
508 
509 	case POWER_SUPPLY_PROP_USB_TYPE:
510 		val->intval = pdata->usb_type;
511 		break;
512 
513 	default:
514 		return -EINVAL;
515 	}
516 
517 	return ret;
518 }
519 
520 static enum power_supply_property bq257xx_power_supply_props[] = {
521 	POWER_SUPPLY_PROP_MANUFACTURER,
522 	POWER_SUPPLY_PROP_STATUS,
523 	POWER_SUPPLY_PROP_ONLINE,
524 	POWER_SUPPLY_PROP_HEALTH,
525 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
526 	POWER_SUPPLY_PROP_CURRENT_NOW,
527 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
528 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
529 	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
530 	POWER_SUPPLY_PROP_VOLTAGE_MIN,
531 	POWER_SUPPLY_PROP_USB_TYPE,
532 };
533 
534 static int bq257xx_property_is_writeable(struct power_supply *psy,
535 					 enum power_supply_property prop)
536 {
537 	switch (prop) {
538 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
539 	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
540 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
541 		return true;
542 	default:
543 		return false;
544 	}
545 }
546 
547 /**
548  * bq257xx_external_power_changed() - Handler for external power change
549  * @psy: Power supply data
550  *
551  * When the external power into the charger is changed, check the USB
552  * type so that it can be reported. Additionally, update the max input
553  * current and max charging current to the value reported if it is a
554  * USB PD charger, otherwise use the default value. Note that each time
555  * a charger is removed the max charge current register is erased, so
556  * it must be set again each time the input changes or the device will
557  * not charge.
558  */
559 static void bq257xx_external_power_changed(struct power_supply *psy)
560 {
561 	struct bq257xx_chg *pdata = power_supply_get_drvdata(psy);
562 	union power_supply_propval val;
563 	int ret;
564 	int imax = pdata->iindpm_max;
565 
566 	pdata->chip->bq257xx_get_state(pdata);
567 
568 	pdata->supplied = power_supply_am_i_supplied(pdata->charger);
569 	if (pdata->supplied < 0)
570 		return;
571 
572 	if (pdata->supplied == 0)
573 		goto out;
574 
575 	ret = power_supply_get_property_from_supplier(psy,
576 						      POWER_SUPPLY_PROP_USB_TYPE,
577 						      &val);
578 	if (ret)
579 		return;
580 
581 	pdata->usb_type = val.intval;
582 
583 	if ((pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD) ||
584 	    (pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD_DRP) ||
585 	    (pdata->usb_type == POWER_SUPPLY_USB_TYPE_PD_PPS)) {
586 		ret = power_supply_get_property_from_supplier(psy,
587 							      POWER_SUPPLY_PROP_CURRENT_MAX,
588 							      &val);
589 		if (ret)
590 			return;
591 
592 		if (val.intval)
593 			imax = val.intval;
594 	}
595 
596 	if (pdata->supplied) {
597 		pdata->chip->bq257xx_set_ichg(pdata, pdata->ichg_max);
598 		pdata->chip->bq257xx_set_iindpm(pdata, imax);
599 		pdata->chip->bq257xx_set_vbatreg(pdata, pdata->vbat_max);
600 	}
601 
602 out:
603 	power_supply_changed(psy);
604 }
605 
606 static irqreturn_t bq257xx_irq_handler_thread(int irq, void *private)
607 {
608 	struct bq257xx_chg *pdata = private;
609 
610 	bq257xx_external_power_changed(pdata->charger);
611 	return IRQ_HANDLED;
612 }
613 
614 static const struct power_supply_desc bq257xx_power_supply_desc = {
615 	.name = "bq257xx-charger",
616 	.type = POWER_SUPPLY_TYPE_USB,
617 	.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) |
618 		     BIT(POWER_SUPPLY_USB_TYPE_PD) |
619 		     BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) |
620 		     BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) |
621 		     BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
622 	.properties = bq257xx_power_supply_props,
623 	.num_properties = ARRAY_SIZE(bq257xx_power_supply_props),
624 	.get_property = bq257xx_get_charger_property,
625 	.set_property = bq257xx_set_charger_property,
626 	.property_is_writeable = bq257xx_property_is_writeable,
627 	.external_power_changed = bq257xx_external_power_changed,
628 };
629 
630 static const struct bq257xx_chip_info bq25703_chip_info = {
631 		.bq257xx_hw_init = &bq25703_hw_init,
632 		.bq257xx_hw_shutdown = &bq25703_hw_shutdown,
633 		.bq257xx_get_state = &bq25703_get_state,
634 		.bq257xx_set_ichg = &bq25703_set_ichg_cur,
635 		.bq257xx_set_vbatreg = &bq25703_set_chrg_volt,
636 		.bq257xx_set_iindpm = &bq25703_set_iindpm,
637 };
638 
639 /**
640  * bq257xx_parse_dt() - Parse the device tree for required properties
641  * @pdata: driver platform data
642  * @psy_cfg: power supply config data
643  * @dev: device struct
644  *
645  * Read the device tree to identify the minimum system voltage, the
646  * maximum charge current, the maximum charge voltage, and the maximum
647  * input current.
648  *
649  * Return: Returns 0 on success or error code on error.
650  */
651 static int bq257xx_parse_dt(struct bq257xx_chg *pdata,
652 		struct power_supply_config *psy_cfg, struct device *dev)
653 {
654 	struct power_supply_battery_info *bat_info;
655 	int ret;
656 
657 	ret = power_supply_get_battery_info(pdata->charger,
658 					    &bat_info);
659 	if (ret)
660 		return dev_err_probe(dev, ret,
661 				     "Unable to get battery info\n");
662 
663 	if ((bat_info->voltage_min_design_uv <= 0) ||
664 	    (bat_info->constant_charge_voltage_max_uv <= 0) ||
665 	    (bat_info->constant_charge_current_max_ua <= 0))
666 		return dev_err_probe(dev, -EINVAL,
667 				     "Required bat info missing or invalid\n");
668 
669 	pdata->vsys_min = bat_info->voltage_min_design_uv;
670 	pdata->vbat_max = bat_info->constant_charge_voltage_max_uv;
671 	pdata->ichg_max = bat_info->constant_charge_current_max_ua;
672 
673 	power_supply_put_battery_info(pdata->charger, bat_info);
674 
675 	ret = device_property_read_u32(dev,
676 				       "input-current-limit-microamp",
677 				       &pdata->iindpm_max);
678 	if (ret)
679 		pdata->iindpm_max = BQ25703_IINDPM_DEFAULT_UA;
680 
681 	return 0;
682 }
683 
684 static int bq257xx_charger_probe(struct platform_device *pdev)
685 {
686 	struct device *dev = &pdev->dev;
687 	struct bq257xx_device *bq = dev_get_drvdata(pdev->dev.parent);
688 	struct bq257xx_chg *pdata;
689 	struct power_supply_config psy_cfg = { };
690 	int ret;
691 
692 	device_set_of_node_from_dev(dev, pdev->dev.parent);
693 
694 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
695 	if (!pdata)
696 		return -ENOMEM;
697 
698 	pdata->bq = bq;
699 	pdata->chip = &bq25703_chip_info;
700 
701 	platform_set_drvdata(pdev, pdata);
702 
703 	psy_cfg.drv_data = pdata;
704 	psy_cfg.fwnode = dev_fwnode(dev);
705 
706 	pdata->charger = devm_power_supply_register(dev,
707 						    &bq257xx_power_supply_desc,
708 						    &psy_cfg);
709 	if (IS_ERR(pdata->charger))
710 		return dev_err_probe(dev, PTR_ERR(pdata->charger),
711 				     "Power supply register charger failed\n");
712 
713 	ret = bq257xx_parse_dt(pdata, &psy_cfg, dev);
714 	if (ret)
715 		return ret;
716 
717 	ret = pdata->chip->bq257xx_hw_init(pdata);
718 	if (ret)
719 		return dev_err_probe(dev, ret, "Cannot initialize the charger\n");
720 
721 	platform_set_drvdata(pdev, pdata);
722 
723 	if (bq->client->irq) {
724 		ret = devm_request_threaded_irq(dev, bq->client->irq, NULL,
725 						bq257xx_irq_handler_thread,
726 						IRQF_TRIGGER_RISING |
727 						IRQF_TRIGGER_FALLING |
728 						IRQF_ONESHOT,
729 						dev_name(&bq->client->dev), pdata);
730 		if (ret < 0)
731 			dev_err_probe(dev, ret, "Charger get irq failed\n");
732 	}
733 
734 	return ret;
735 }
736 
737 static void bq257xx_charger_shutdown(struct platform_device *pdev)
738 {
739 	struct bq257xx_chg *pdata = platform_get_drvdata(pdev);
740 
741 	pdata->chip->bq257xx_hw_shutdown(pdata);
742 }
743 
744 static struct platform_driver bq257xx_chg_driver = {
745 	.driver = {
746 		.name = "bq257xx-charger",
747 	},
748 	.probe = bq257xx_charger_probe,
749 	.shutdown = bq257xx_charger_shutdown,
750 };
751 module_platform_driver(bq257xx_chg_driver);
752 
753 MODULE_DESCRIPTION("bq257xx charger driver");
754 MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
755 MODULE_LICENSE("GPL");
756