xref: /linux/drivers/power/supply/bd71828-power.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* ROHM BD71815, BD71828 and BD71878 Charger driver */
3 
4 #include <linux/interrupt.h>
5 #include <linux/kernel.h>
6 #include <linux/mfd/rohm-bd71815.h>
7 #include <linux/mfd/rohm-bd71828.h>
8 #include <linux/mfd/rohm-bd72720.h>
9 #include <linux/module.h>
10 #include <linux/mod_devicetable.h>
11 #include <linux/platform_device.h>
12 #include <linux/property.h>
13 #include <linux/power_supply.h>
14 #include <linux/slab.h>
15 
16 /* common defines */
17 #define BD7182x_MASK_VBAT_U			0x1f
18 #define BD7182x_MASK_VDCIN_U			0x0f
19 #define BD7182x_MASK_IBAT_U			0x3f
20 #define BD7182x_MASK_CURDIR_DISCHG		0x80
21 #define BD7182x_MASK_CHG_STATE			0x7f
22 #define BD7182x_MASK_BAT_TEMP			0x07
23 #define BD7182x_MASK_DCIN_DET			BIT(0)
24 #define BD7182x_MASK_CONF_PON			BIT(0)
25 #define BD71815_MASK_CONF_XSTB			BIT(1)
26 #define BD7182x_MASK_BAT_STAT			0x3f
27 #define BD7182x_MASK_DCIN_STAT			0x07
28 
29 #define BD7182x_MASK_WDT_AUTO			0x40
30 #define BD7182x_MASK_VBAT_ALM_LIMIT_U		0x01
31 #define BD7182x_MASK_CHG_EN			0x01
32 
33 #define BD7182x_DCIN_COLLAPSE_DEFAULT		0x36
34 
35 #define MAX_CURRENT_DEFAULT			890000		/* uA */
36 #define AC_NAME					"bd71828_ac"
37 #define BAT_NAME				"bd71828_bat"
38 
39 #define BAT_OPEN	0x7
40 
41 /*
42  * VBAT Low voltage detection Threshold
43  * 0x00D4*16mV = 212*0.016 = 3.392v
44  */
45 #define VBAT_LOW_TH			0x00D4
46 
47 struct pwr_regs {
48 	unsigned int vbat_avg;
49 	unsigned int ibat;
50 	unsigned int ibat_avg;
51 	unsigned int btemp_vth;
52 	unsigned int chg_state;
53 	unsigned int bat_temp;
54 	unsigned int dcin_stat;
55 	unsigned int dcin_online_mask;
56 	unsigned int dcin_collapse_limit;
57 	unsigned int chg_set1;
58 	unsigned int chg_en;
59 	unsigned int vbat_alm_limit_u;
60 	unsigned int conf;
61 	unsigned int vdcin;
62 	unsigned int vdcin_himask;
63 };
64 
65 static const struct pwr_regs pwr_regs_bd71828 = {
66 	.vbat_avg = BD71828_REG_VBAT_U,
67 	.ibat = BD71828_REG_IBAT_U,
68 	.ibat_avg = BD71828_REG_IBAT_AVG_U,
69 	.btemp_vth = BD71828_REG_VM_BTMP_U,
70 	.chg_state = BD71828_REG_CHG_STATE,
71 	.bat_temp = BD71828_REG_BAT_TEMP,
72 	.dcin_stat = BD71828_REG_DCIN_STAT,
73 	.dcin_online_mask = BD7182x_MASK_DCIN_DET,
74 	.dcin_collapse_limit = BD71828_REG_DCIN_CLPS,
75 	.chg_set1 = BD71828_REG_CHG_SET1,
76 	.chg_en   = BD71828_REG_CHG_EN,
77 	.vbat_alm_limit_u = BD71828_REG_ALM_VBAT_LIMIT_U,
78 	.conf = BD71828_REG_CONF,
79 	.vdcin = BD71828_REG_VDCIN_U,
80 	.vdcin_himask = BD7182x_MASK_VDCIN_U,
81 };
82 
83 static const struct pwr_regs pwr_regs_bd71815 = {
84 	.vbat_avg = BD71815_REG_VM_SA_VBAT_U,
85 	/* BD71815 does not have separate current and current avg */
86 	.ibat = BD71815_REG_CC_CURCD_U,
87 	.ibat_avg = BD71815_REG_CC_CURCD_U,
88 
89 	.btemp_vth = BD71815_REG_VM_BTMP,
90 	.chg_state = BD71815_REG_CHG_STATE,
91 	.bat_temp = BD71815_REG_BAT_TEMP,
92 	.dcin_stat = BD71815_REG_DCIN_STAT,
93 	.dcin_online_mask = BD7182x_MASK_DCIN_DET,
94 	.dcin_collapse_limit = BD71815_REG_DCIN_CLPS,
95 	.chg_set1 = BD71815_REG_CHG_SET1,
96 	.chg_en   = BD71815_REG_CHG_SET1,
97 	.vbat_alm_limit_u = BD71815_REG_ALM_VBAT_TH_U,
98 	.conf = BD71815_REG_CONF,
99 
100 	.vdcin = BD71815_REG_VM_DCIN_U,
101 	.vdcin_himask = BD7182x_MASK_VDCIN_U,
102 };
103 
104 static struct pwr_regs pwr_regs_bd72720 = {
105 	.vbat_avg = BD72720_REG_VM_SA_VBAT_U,
106 	.ibat = BD72720_REG_CC_CURCD_U,
107 	.ibat_avg = BD72720_REG_CC_SA_CURCD_U,
108 	.btemp_vth = BD72720_REG_VM_BTMP_U,
109 	/*
110 	 * Note, state 0x40 IMP_CHK. not documented
111 	 * on other variants but was still handled in
112 	 * existing code. No memory traces as to why.
113 	 */
114 	.chg_state = BD72720_REG_CHG_STATE,
115 	.bat_temp = BD72720_REG_CHG_BAT_TEMP_STAT,
116 	.dcin_stat = BD72720_REG_INT_VBUS_SRC,
117 	.dcin_online_mask = BD72720_MASK_DCIN_DET,
118 	.dcin_collapse_limit = -1, /* Automatic. Setting not supported */
119 	.chg_set1 = BD72720_REG_CHG_SET_1,
120 	.chg_en = BD72720_REG_CHG_EN,
121 	/* 15mV note in data-sheet */
122 	.vbat_alm_limit_u = BD72720_REG_ALM_VBAT_TH_U,
123 	.conf = BD72720_REG_CONF, /* o XSTB, only PON. Seprate slave addr */
124 	.vdcin = BD72720_REG_VM_VBUS_U, /* 10 bits not 11 as with other ICs */
125 	.vdcin_himask = BD72720_MASK_VDCIN_U,
126 };
127 
128 struct bd71828_power {
129 	struct regmap *regmap;
130 	enum rohm_chip_type chip_type;
131 	struct device *dev;
132 	struct power_supply *ac;
133 	struct power_supply *bat;
134 
135 	const struct pwr_regs *regs;
136 	/* Reg val to uA */
137 	int curr_factor;
138 	int rsens;
139 	int (*get_temp)(struct bd71828_power *pwr, int *temp);
140 	int (*bat_inserted)(struct bd71828_power *pwr);
141 };
142 
143 static int bd7182x_write16(struct bd71828_power *pwr, int reg, u16 val)
144 {
145 	__be16 tmp;
146 
147 	tmp = cpu_to_be16(val);
148 
149 	return regmap_bulk_write(pwr->regmap, reg, &tmp, sizeof(tmp));
150 }
151 
152 static int bd7182x_read16_himask(struct bd71828_power *pwr, int reg, int himask,
153 				 u16 *val)
154 {
155 	struct regmap *regmap = pwr->regmap;
156 	int ret;
157 	__be16 rvals;
158 	u8 *tmp = (u8 *)&rvals;
159 
160 	ret = regmap_bulk_read(regmap, reg, &rvals, sizeof(*val));
161 	if (!ret) {
162 		*tmp &= himask;
163 		*val = be16_to_cpu(rvals);
164 	}
165 
166 	return ret;
167 }
168 
169 static int bd71828_get_vbat(struct bd71828_power *pwr, int *vcell)
170 {
171 	u16 tmp_vcell;
172 	int ret;
173 
174 	ret = bd7182x_read16_himask(pwr, pwr->regs->vbat_avg,
175 				    BD7182x_MASK_VBAT_U, &tmp_vcell);
176 	if (ret)
177 		dev_err(pwr->dev, "Failed to read battery average voltage\n");
178 	else
179 		*vcell = ((int)tmp_vcell) * 1000;
180 
181 	return ret;
182 }
183 
184 static int bd71828_get_current_ds_adc(struct bd71828_power *pwr, int *curr, int *curr_avg)
185 {
186 	__be16 tmp_curr;
187 	char *tmp = (char *)&tmp_curr;
188 	int dir = 1;
189 	int regs[] = { pwr->regs->ibat, pwr->regs->ibat_avg };
190 	int *vals[] = { curr, curr_avg };
191 	int ret, i;
192 
193 	for (dir = 1, i = 0; i < ARRAY_SIZE(regs); i++) {
194 		ret = regmap_bulk_read(pwr->regmap, regs[i], &tmp_curr,
195 				       sizeof(tmp_curr));
196 		if (ret)
197 			break;
198 
199 		if (*tmp & BD7182x_MASK_CURDIR_DISCHG)
200 			dir = -1;
201 
202 		*tmp &= BD7182x_MASK_IBAT_U;
203 
204 		*vals[i] = dir * ((int)be16_to_cpu(tmp_curr)) * pwr->curr_factor;
205 	}
206 
207 	return ret;
208 }
209 
210 /* Unit is tenths of degree C */
211 static int bd71815_get_temp(struct bd71828_power *pwr, int *temp)
212 {
213 	struct regmap *regmap = pwr->regmap;
214 	int ret;
215 	int t;
216 
217 	ret = regmap_read(regmap, pwr->regs->btemp_vth, &t);
218 	if (ret)
219 		return ret;
220 
221 	t = 200 - t;
222 
223 	if (t > 200) {
224 		dev_err(pwr->dev, "Failed to read battery temperature\n");
225 		return -ENODATA;
226 	}
227 
228 	return 0;
229 }
230 
231 /* Unit is tenths of degree C */
232 static int bd71828_get_temp(struct bd71828_power *pwr, int *temp)
233 {
234 	u16 t;
235 	int ret;
236 	int tmp = 200 * 10000;
237 
238 	ret = bd7182x_read16_himask(pwr, pwr->regs->btemp_vth,
239 				    BD71828_MASK_VM_BTMP_U, &t);
240 	if (ret)
241 		return ret;
242 
243 	if (t > 3200) {
244 		dev_err(pwr->dev,
245 			"Failed to read battery temperature\n");
246 		return -ENODATA;
247 	}
248 
249 	tmp -= 625ULL * (unsigned int)t;
250 	*temp = tmp / 1000;
251 
252 	return ret;
253 }
254 
255 static int bd71828_charge_status(struct bd71828_power *pwr,
256 				 int *s, int *h)
257 {
258 	unsigned int state;
259 	int status, health;
260 	int ret = 1;
261 
262 	ret = regmap_read(pwr->regmap, pwr->regs->chg_state, &state);
263 	if (ret) {
264 		dev_err(pwr->dev, "charger status reading failed (%d)\n", ret);
265 		return ret;
266 	}
267 
268 	state &= BD7182x_MASK_CHG_STATE;
269 
270 	dev_dbg(pwr->dev, "CHG_STATE %d\n", state);
271 
272 	switch (state) {
273 	case 0x00:
274 		status = POWER_SUPPLY_STATUS_DISCHARGING;
275 		health = POWER_SUPPLY_HEALTH_GOOD;
276 		break;
277 	case 0x01:
278 	case 0x02:
279 	case 0x03:
280 	case 0x0E:
281 		status = POWER_SUPPLY_STATUS_CHARGING;
282 		health = POWER_SUPPLY_HEALTH_GOOD;
283 		break;
284 	case 0x0F:
285 		status = POWER_SUPPLY_STATUS_FULL;
286 		health = POWER_SUPPLY_HEALTH_GOOD;
287 		break;
288 	case 0x10:
289 	case 0x11:
290 	case 0x12:
291 	case 0x13:
292 	case 0x14:
293 	case 0x20:
294 	case 0x21:
295 	case 0x22:
296 	case 0x23:
297 	case 0x24:
298 		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
299 		health = POWER_SUPPLY_HEALTH_OVERHEAT;
300 		break;
301 	case 0x30:
302 	case 0x31:
303 	case 0x32:
304 	case 0x40:
305 		status = POWER_SUPPLY_STATUS_DISCHARGING;
306 		health = POWER_SUPPLY_HEALTH_GOOD;
307 		break;
308 	case 0x7f:
309 	default:
310 		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
311 		health = POWER_SUPPLY_HEALTH_DEAD;
312 		break;
313 	}
314 
315 	if (s)
316 		*s = status;
317 	if (h)
318 		*h = health;
319 
320 	return ret;
321 }
322 
323 static int get_chg_online(struct bd71828_power *pwr, int *chg_online)
324 {
325 	int r, ret;
326 
327 	ret = regmap_read(pwr->regmap, pwr->regs->dcin_stat, &r);
328 	if (ret) {
329 		dev_err(pwr->dev, "Failed to read DCIN status\n");
330 		return ret;
331 	}
332 	*chg_online = ((r & pwr->regs->dcin_online_mask) != 0);
333 
334 	return 0;
335 }
336 
337 static int get_bat_online(struct bd71828_power *pwr, int *bat_online)
338 {
339 	int r, ret;
340 
341 	ret = regmap_read(pwr->regmap, pwr->regs->bat_temp, &r);
342 	if (ret) {
343 		dev_err(pwr->dev, "Failed to read battery temperature\n");
344 		return ret;
345 	}
346 	*bat_online = ((r & BD7182x_MASK_BAT_TEMP) != BAT_OPEN);
347 
348 	return 0;
349 }
350 
351 static int bd71828_bat_inserted(struct bd71828_power *pwr)
352 {
353 	int ret, val;
354 
355 	ret = regmap_read(pwr->regmap, pwr->regs->conf, &val);
356 	if (ret) {
357 		dev_err(pwr->dev, "Failed to read CONF register\n");
358 		return 0;
359 	}
360 	ret = val & BD7182x_MASK_CONF_PON;
361 
362 	if (ret)
363 		if (regmap_update_bits(pwr->regmap, pwr->regs->conf, BD7182x_MASK_CONF_PON, 0))
364 			dev_err(pwr->dev, "Failed to write CONF register\n");
365 
366 	return ret;
367 }
368 
369 static int bd71815_bat_inserted(struct bd71828_power *pwr)
370 {
371 	int ret, val;
372 
373 	ret = regmap_read(pwr->regmap, pwr->regs->conf, &val);
374 	if (ret) {
375 		dev_err(pwr->dev, "Failed to read CONF register\n");
376 		return ret;
377 	}
378 
379 	ret = !(val & BD71815_MASK_CONF_XSTB);
380 	if (ret)
381 		regmap_write(pwr->regmap, pwr->regs->conf,  val |
382 			     BD71815_MASK_CONF_XSTB);
383 
384 	return ret;
385 }
386 
387 static int bd71828_init_hardware(struct bd71828_power *pwr)
388 {
389 	int ret;
390 
391 	/* TODO: Collapse limit should come from device-tree ? */
392 	if (pwr->regs->dcin_collapse_limit != (unsigned int)-1) {
393 		ret = regmap_write(pwr->regmap, pwr->regs->dcin_collapse_limit,
394 				   BD7182x_DCIN_COLLAPSE_DEFAULT);
395 		if (ret) {
396 			dev_err(pwr->dev, "Failed to write DCIN collapse limit\n");
397 			return ret;
398 		}
399 	}
400 
401 	ret = pwr->bat_inserted(pwr);
402 	if (ret < 0)
403 		return ret;
404 
405 	if (ret) {
406 		/* WDT_FST auto set */
407 		ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_set1,
408 					 BD7182x_MASK_WDT_AUTO,
409 					 BD7182x_MASK_WDT_AUTO);
410 		if (ret)
411 			return ret;
412 
413 		ret = bd7182x_write16(pwr, pwr->regs->vbat_alm_limit_u,
414 				      VBAT_LOW_TH);
415 		if (ret)
416 			return ret;
417 
418 		/*
419 		 * On BD71815 "we mask the power-state" from relax detection.
420 		 * I am unsure what the impact of the power-state would be if
421 		 * we didn't - but this is what the vendor driver did - and
422 		 * that driver has been used in few projects so I just assume
423 		 * this is needed.
424 		 */
425 		if (pwr->chip_type == ROHM_CHIP_TYPE_BD71815) {
426 			ret = regmap_set_bits(pwr->regmap,
427 					      BD71815_REG_REX_CTRL_1,
428 					      REX_PMU_STATE_MASK);
429 			if (ret)
430 				return ret;
431 		}
432 	}
433 
434 	return 0;
435 }
436 
437 static int bd71828_charger_get_property(struct power_supply *psy,
438 					enum power_supply_property psp,
439 					union power_supply_propval *val)
440 {
441 	struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
442 	u32 vot;
443 	u16 tmp;
444 	int online;
445 	int ret;
446 
447 	switch (psp) {
448 	case POWER_SUPPLY_PROP_ONLINE:
449 		ret = get_chg_online(pwr, &online);
450 		if (!ret)
451 			val->intval = online;
452 		break;
453 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
454 		ret = bd7182x_read16_himask(pwr, pwr->regs->vdcin,
455 					    pwr->regs->vdcin_himask, &tmp);
456 		if (ret)
457 			return ret;
458 
459 		vot = tmp;
460 		/* 5 milli volt steps */
461 		val->intval = 5000 * vot;
462 		break;
463 	default:
464 		return -EINVAL;
465 	}
466 
467 	return 0;
468 }
469 
470 static int bd71828_battery_get_property(struct power_supply *psy,
471 					enum power_supply_property psp,
472 					union power_supply_propval *val)
473 {
474 	struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
475 	int ret = 0;
476 	int status, health, tmp, curr, curr_avg, chg_en;
477 
478 	if (psp == POWER_SUPPLY_PROP_STATUS ||
479 	    psp == POWER_SUPPLY_PROP_HEALTH ||
480 	    psp == POWER_SUPPLY_PROP_CHARGE_TYPE)
481 		ret = bd71828_charge_status(pwr, &status, &health);
482 	else if (psp == POWER_SUPPLY_PROP_CURRENT_AVG ||
483 		 psp == POWER_SUPPLY_PROP_CURRENT_NOW)
484 		ret = bd71828_get_current_ds_adc(pwr, &curr, &curr_avg);
485 	if (ret)
486 		return ret;
487 
488 	switch (psp) {
489 	case POWER_SUPPLY_PROP_STATUS:
490 		val->intval = status;
491 		break;
492 	case POWER_SUPPLY_PROP_HEALTH:
493 		val->intval = health;
494 		break;
495 	case POWER_SUPPLY_PROP_PRESENT:
496 		ret = get_bat_online(pwr, &tmp);
497 		if (!ret)
498 			val->intval = tmp;
499 		break;
500 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
501 		ret = bd71828_get_vbat(pwr, &tmp);
502 		val->intval = tmp;
503 		break;
504 	case POWER_SUPPLY_PROP_TECHNOLOGY:
505 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
506 		break;
507 	case POWER_SUPPLY_PROP_CURRENT_AVG:
508 		val->intval = curr_avg;
509 		break;
510 	case POWER_SUPPLY_PROP_CURRENT_NOW:
511 		val->intval = curr;
512 		break;
513 	case POWER_SUPPLY_PROP_CURRENT_MAX:
514 		val->intval = MAX_CURRENT_DEFAULT;
515 		break;
516 	case POWER_SUPPLY_PROP_TEMP:
517 		ret = pwr->get_temp(pwr, &val->intval);
518 		break;
519 	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
520 		ret = regmap_read(pwr->regmap, pwr->regs->chg_en, &chg_en);
521 		if (ret)
522 			return ret;
523 
524 		val->intval = (chg_en & BD7182x_MASK_CHG_EN) ?
525 			POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO :
526 			POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE;
527 		break;
528 	default:
529 		ret = -EINVAL;
530 		break;
531 	}
532 
533 	return ret;
534 }
535 
536 static int bd71828_battery_set_property(struct power_supply *psy,
537 					enum power_supply_property psp,
538 					const union power_supply_propval *val)
539 {
540 	struct bd71828_power *pwr = dev_get_drvdata(psy->dev.parent);
541 	int ret = 0;
542 
543 	switch (psp) {
544 	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
545 		if (val->intval == POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO)
546 			ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en,
547 						 BD7182x_MASK_CHG_EN,
548 						 BD7182x_MASK_CHG_EN);
549 		else
550 			ret = regmap_update_bits(pwr->regmap, pwr->regs->chg_en,
551 						 BD7182x_MASK_CHG_EN,
552 						 0);
553 		break;
554 	default:
555 		return -EINVAL;
556 	}
557 
558 	return ret;
559 }
560 
561 static int bd71828_battery_property_is_writeable(struct power_supply *psy,
562 						 enum power_supply_property psp)
563 {
564 	switch (psp) {
565 	case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
566 		return true;
567 	default:
568 		return false;
569 	}
570 }
571 
572 /** @brief ac properties */
573 static const enum power_supply_property bd71828_charger_props[] = {
574 	POWER_SUPPLY_PROP_ONLINE,
575 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
576 };
577 
578 static const enum power_supply_property bd71828_battery_props[] = {
579 	POWER_SUPPLY_PROP_STATUS,
580 	POWER_SUPPLY_PROP_HEALTH,
581 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
582 	POWER_SUPPLY_PROP_HEALTH,
583 	POWER_SUPPLY_PROP_PRESENT,
584 	POWER_SUPPLY_PROP_TECHNOLOGY,
585 	POWER_SUPPLY_PROP_TEMP,
586 	POWER_SUPPLY_PROP_CURRENT_AVG,
587 	POWER_SUPPLY_PROP_CURRENT_NOW,
588 	POWER_SUPPLY_PROP_CURRENT_MAX,
589 	POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR,
590 };
591 
592 /** @brief powers supplied by bd71828_ac */
593 static char *bd71828_ac_supplied_to[] = {
594 	BAT_NAME,
595 };
596 
597 static const struct power_supply_desc bd71828_ac_desc = {
598 	.name		= AC_NAME,
599 	.type		= POWER_SUPPLY_TYPE_MAINS,
600 	.properties	= bd71828_charger_props,
601 	.num_properties	= ARRAY_SIZE(bd71828_charger_props),
602 	.get_property	= bd71828_charger_get_property,
603 };
604 
605 static const struct power_supply_desc bd71828_bat_desc = {
606 	.name		= BAT_NAME,
607 	.type		= POWER_SUPPLY_TYPE_BATTERY,
608 	.charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) |
609 			     BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE),
610 	.properties	= bd71828_battery_props,
611 	.num_properties = ARRAY_SIZE(bd71828_battery_props),
612 	.get_property	= bd71828_battery_get_property,
613 	.set_property	= bd71828_battery_set_property,
614 	.property_is_writeable   = bd71828_battery_property_is_writeable,
615 };
616 
617 #define RSENS_CURR 10000000LLU
618 
619 #define BD_ISR_NAME(name) \
620 bd7181x_##name##_isr
621 
622 #define BD_ISR_BAT(name, print, run_gauge)				\
623 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data)		\
624 {									\
625 	struct bd71828_power *pwr = (struct bd71828_power *)data;	\
626 									\
627 	dev_dbg(pwr->dev, "%s\n", print);				\
628 	power_supply_changed(pwr->bat);				\
629 									\
630 	return IRQ_HANDLED;						\
631 }
632 
633 #define BD_ISR_AC(name, print, run_gauge)				\
634 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data)		\
635 {									\
636 	struct bd71828_power *pwr = (struct bd71828_power *)data;	\
637 									\
638 	power_supply_changed(pwr->ac);					\
639 	dev_dbg(pwr->dev, "%s\n", print);				\
640 	power_supply_changed(pwr->bat);				\
641 									\
642 	return IRQ_HANDLED;						\
643 }
644 
645 #define BD_ISR_DUMMY(name, print)					\
646 static irqreturn_t BD_ISR_NAME(name)(int irq, void *data)		\
647 {									\
648 	struct bd71828_power *pwr = (struct bd71828_power *)data;	\
649 									\
650 	dev_dbg(pwr->dev, "%s\n", print);				\
651 									\
652 	return IRQ_HANDLED;						\
653 }
654 
655 BD_ISR_BAT(chg_state_changed, "CHG state changed", true)
656 /* DCIN voltage changes */
657 BD_ISR_AC(dcin_removed, "DCIN removed", true)
658 BD_ISR_AC(clps_out, "DCIN voltage back to normal", true)
659 BD_ISR_AC(clps_in, "DCIN voltage collapsed", false)
660 BD_ISR_AC(dcin_ovp_res, "DCIN voltage normal", true)
661 BD_ISR_AC(dcin_ovp_det, "DCIN OVER VOLTAGE", true)
662 
663 BD_ISR_DUMMY(dcin_mon_det, "DCIN voltage below threshold")
664 BD_ISR_DUMMY(dcin_mon_res, "DCIN voltage above threshold")
665 
666 BD_ISR_DUMMY(vbus_curr_limit, "VBUS current limited")
667 BD_ISR_DUMMY(vsys_ov_res, "VSYS over-voltage cleared")
668 BD_ISR_DUMMY(vsys_ov_det, "VSYS over-voltage")
669 BD_ISR_DUMMY(vsys_uv_res, "VSYS under-voltage cleared")
670 BD_ISR_DUMMY(vsys_uv_det, "VSYS under-voltage")
671 BD_ISR_DUMMY(vsys_low_res, "'VSYS low' cleared")
672 BD_ISR_DUMMY(vsys_low_det, "VSYS low")
673 BD_ISR_DUMMY(vsys_mon_res, "VSYS mon - resumed")
674 BD_ISR_DUMMY(vsys_mon_det, "VSYS mon - detected")
675 BD_ISR_BAT(chg_wdg_temp, "charger temperature watchdog triggered", true)
676 BD_ISR_BAT(chg_wdg, "charging watchdog triggered", true)
677 BD_ISR_BAT(bat_removed, "Battery removed", true)
678 BD_ISR_BAT(bat_det, "Battery detected", true)
679 /* TODO: Verify the meaning of these interrupts */
680 BD_ISR_BAT(rechg_det, "Recharging", true)
681 BD_ISR_BAT(rechg_res, "Recharge ending", true)
682 BD_ISR_DUMMY(temp_transit, "Temperature transition")
683 BD_ISR_BAT(therm_rmv, "bd71815-therm-rmv", false)
684 BD_ISR_BAT(therm_det, "bd71815-therm-det", true)
685 BD_ISR_BAT(bat_dead, "bd71815-bat-dead", false)
686 BD_ISR_BAT(bat_short_res, "bd71815-bat-short-res", true)
687 BD_ISR_BAT(bat_short, "bd71815-bat-short-det", false)
688 BD_ISR_BAT(bat_low_res, "bd71815-bat-low-res", true)
689 BD_ISR_BAT(bat_low, "bd71815-bat-low-det", true)
690 BD_ISR_BAT(bat_ov_res, "bd71815-bat-over-res", true)
691 /* What should we do here? */
692 BD_ISR_BAT(bat_ov, "bd71815-bat-over-det", false)
693 BD_ISR_BAT(bat_mon_res, "bd71815-bat-mon-res", true)
694 BD_ISR_BAT(bat_mon, "bd71815-bat-mon-det", true)
695 BD_ISR_BAT(bat_cc_mon, "bd71815-bat-cc-mon2", false)
696 BD_ISR_BAT(bat_oc1_res, "bd71815-bat-oc1-res", true)
697 BD_ISR_BAT(bat_oc1, "bd71815-bat-oc1-det", false)
698 BD_ISR_BAT(bat_oc2_res, "bd71815-bat-oc2-res", true)
699 BD_ISR_BAT(bat_oc2, "bd71815-bat-oc2-det", false)
700 BD_ISR_BAT(bat_oc3_res, "bd71815-bat-oc3-res", true)
701 BD_ISR_BAT(bat_oc3, "bd71815-bat-oc3-det", false)
702 BD_ISR_BAT(temp_bat_low_res, "bd71815-temp-bat-low-res", true)
703 BD_ISR_BAT(temp_bat_low, "bd71815-temp-bat-low-det", true)
704 BD_ISR_BAT(temp_bat_hi_res, "bd71815-temp-bat-hi-res", true)
705 BD_ISR_BAT(temp_bat_hi, "bd71815-temp-bat-hi-det", true)
706 
707 static irqreturn_t bd7182x_dcin_removed(int irq, void *data)
708 {
709 	struct bd71828_power *pwr = (struct bd71828_power *)data;
710 
711 	power_supply_changed(pwr->ac);
712 	dev_dbg(pwr->dev, "DCIN removed\n");
713 
714 	return IRQ_HANDLED;
715 }
716 
717 static irqreturn_t bd718x7_chg_done(int irq, void *data)
718 {
719 	struct bd71828_power *pwr = (struct bd71828_power *)data;
720 
721 	power_supply_changed(pwr->bat);
722 
723 	return IRQ_HANDLED;
724 }
725 
726 static irqreturn_t bd7182x_dcin_detected(int irq, void *data)
727 {
728 	struct bd71828_power *pwr = (struct bd71828_power *)data;
729 
730 	dev_dbg(pwr->dev, "DCIN inserted\n");
731 	power_supply_changed(pwr->ac);
732 
733 	return IRQ_HANDLED;
734 }
735 
736 static irqreturn_t bd71828_vbat_low_res(int irq, void *data)
737 {
738 	struct bd71828_power *pwr = (struct bd71828_power *)data;
739 
740 	dev_dbg(pwr->dev, "VBAT LOW Resumed\n");
741 
742 	return IRQ_HANDLED;
743 }
744 
745 static irqreturn_t bd71828_vbat_low_det(int irq, void *data)
746 {
747 	struct bd71828_power *pwr = (struct bd71828_power *)data;
748 
749 	dev_dbg(pwr->dev, "VBAT LOW Detected\n");
750 
751 	return IRQ_HANDLED;
752 }
753 
754 static irqreturn_t bd71828_temp_bat_hi_det(int irq, void *data)
755 {
756 	struct bd71828_power *pwr = (struct bd71828_power *)data;
757 
758 	dev_warn(pwr->dev, "Overtemp Detected\n");
759 	power_supply_changed(pwr->bat);
760 
761 	return IRQ_HANDLED;
762 }
763 
764 static irqreturn_t bd71828_temp_bat_hi_res(int irq, void *data)
765 {
766 	struct bd71828_power *pwr = (struct bd71828_power *)data;
767 
768 	dev_dbg(pwr->dev, "Overtemp Resumed\n");
769 	power_supply_changed(pwr->bat);
770 
771 	return IRQ_HANDLED;
772 }
773 
774 static irqreturn_t bd71828_temp_bat_low_det(int irq, void *data)
775 {
776 	struct bd71828_power *pwr = (struct bd71828_power *)data;
777 
778 	dev_dbg(pwr->dev, "Lowtemp Detected\n");
779 	power_supply_changed(pwr->bat);
780 
781 	return IRQ_HANDLED;
782 }
783 
784 static irqreturn_t bd71828_temp_bat_low_res(int irq, void *data)
785 {
786 	struct bd71828_power *pwr = (struct bd71828_power *)data;
787 
788 	dev_dbg(pwr->dev, "Lowtemp Resumed\n");
789 	power_supply_changed(pwr->bat);
790 
791 	return IRQ_HANDLED;
792 }
793 
794 static irqreturn_t bd71828_temp_vf_det(int irq, void *data)
795 {
796 	struct bd71828_power *pwr = (struct bd71828_power *)data;
797 
798 	dev_dbg(pwr->dev, "VF Detected\n");
799 	power_supply_changed(pwr->bat);
800 
801 	return IRQ_HANDLED;
802 }
803 
804 static irqreturn_t bd71828_temp_vf_res(int irq, void *data)
805 {
806 	struct bd71828_power *pwr = (struct bd71828_power *)data;
807 
808 	dev_dbg(pwr->dev, "VF Resumed\n");
809 	power_supply_changed(pwr->bat);
810 
811 	return IRQ_HANDLED;
812 }
813 
814 static irqreturn_t bd71828_temp_vf125_det(int irq, void *data)
815 {
816 	struct bd71828_power *pwr = (struct bd71828_power *)data;
817 
818 	dev_dbg(pwr->dev, "VF125 Detected\n");
819 	power_supply_changed(pwr->bat);
820 
821 	return IRQ_HANDLED;
822 }
823 
824 static irqreturn_t bd71828_temp_vf125_res(int irq, void *data)
825 {
826 	struct bd71828_power *pwr = (struct bd71828_power *)data;
827 
828 	dev_dbg(pwr->dev, "VF125 Resumed\n");
829 	power_supply_changed(pwr->bat);
830 
831 	return IRQ_HANDLED;
832 }
833 
834 struct bd7182x_irq_res {
835 	const char *name;
836 	irq_handler_t handler;
837 };
838 
839 #define BDIRQ(na, hn) { .name = (na), .handler = (hn) }
840 
841 static int bd7182x_get_irqs(struct platform_device *pdev,
842 			    struct bd71828_power *pwr)
843 {
844 	int i, irq, ret;
845 	static const struct bd7182x_irq_res bd71815_irqs[] = {
846 		BDIRQ("bd71815-dcin-rmv", BD_ISR_NAME(dcin_removed)),
847 		BDIRQ("bd71815-dcin-clps-out", BD_ISR_NAME(clps_out)),
848 		BDIRQ("bd71815-dcin-clps-in", BD_ISR_NAME(clps_in)),
849 		BDIRQ("bd71815-dcin-ovp-res", BD_ISR_NAME(dcin_ovp_res)),
850 		BDIRQ("bd71815-dcin-ovp-det", BD_ISR_NAME(dcin_ovp_det)),
851 		BDIRQ("bd71815-dcin-mon-res", BD_ISR_NAME(dcin_mon_res)),
852 		BDIRQ("bd71815-dcin-mon-det", BD_ISR_NAME(dcin_mon_det)),
853 
854 		BDIRQ("bd71815-vsys-uv-res", BD_ISR_NAME(vsys_uv_res)),
855 		BDIRQ("bd71815-vsys-uv-det", BD_ISR_NAME(vsys_uv_det)),
856 		BDIRQ("bd71815-vsys-low-res", BD_ISR_NAME(vsys_low_res)),
857 		BDIRQ("bd71815-vsys-low-det",  BD_ISR_NAME(vsys_low_det)),
858 		BDIRQ("bd71815-vsys-mon-res",  BD_ISR_NAME(vsys_mon_res)),
859 		BDIRQ("bd71815-vsys-mon-det",  BD_ISR_NAME(vsys_mon_det)),
860 		BDIRQ("bd71815-chg-wdg-temp", BD_ISR_NAME(chg_wdg_temp)),
861 		BDIRQ("bd71815-chg-wdg",  BD_ISR_NAME(chg_wdg)),
862 		BDIRQ("bd71815-rechg-det", BD_ISR_NAME(rechg_det)),
863 		BDIRQ("bd71815-rechg-res", BD_ISR_NAME(rechg_res)),
864 		BDIRQ("bd71815-ranged-temp-transit", BD_ISR_NAME(temp_transit)),
865 		BDIRQ("bd71815-chg-state-change", BD_ISR_NAME(chg_state_changed)),
866 		BDIRQ("bd71815-bat-temp-normal", bd71828_temp_bat_hi_res),
867 		BDIRQ("bd71815-bat-temp-erange", bd71828_temp_bat_hi_det),
868 		BDIRQ("bd71815-bat-rmv", BD_ISR_NAME(bat_removed)),
869 		BDIRQ("bd71815-bat-det", BD_ISR_NAME(bat_det)),
870 
871 		/* Add ISRs for these */
872 		BDIRQ("bd71815-therm-rmv", BD_ISR_NAME(therm_rmv)),
873 		BDIRQ("bd71815-therm-det", BD_ISR_NAME(therm_det)),
874 		BDIRQ("bd71815-bat-dead", BD_ISR_NAME(bat_dead)),
875 		BDIRQ("bd71815-bat-short-res", BD_ISR_NAME(bat_short_res)),
876 		BDIRQ("bd71815-bat-short-det", BD_ISR_NAME(bat_short)),
877 		BDIRQ("bd71815-bat-low-res", BD_ISR_NAME(bat_low_res)),
878 		BDIRQ("bd71815-bat-low-det", BD_ISR_NAME(bat_low)),
879 		BDIRQ("bd71815-bat-over-res", BD_ISR_NAME(bat_ov_res)),
880 		BDIRQ("bd71815-bat-over-det", BD_ISR_NAME(bat_ov)),
881 		BDIRQ("bd71815-bat-mon-res", BD_ISR_NAME(bat_mon_res)),
882 		BDIRQ("bd71815-bat-mon-det", BD_ISR_NAME(bat_mon)),
883 		/* cc-mon 1 & 3 ? */
884 		BDIRQ("bd71815-bat-cc-mon2", BD_ISR_NAME(bat_cc_mon)),
885 		BDIRQ("bd71815-bat-oc1-res", BD_ISR_NAME(bat_oc1_res)),
886 		BDIRQ("bd71815-bat-oc1-det", BD_ISR_NAME(bat_oc1)),
887 		BDIRQ("bd71815-bat-oc2-res", BD_ISR_NAME(bat_oc2_res)),
888 		BDIRQ("bd71815-bat-oc2-det", BD_ISR_NAME(bat_oc2)),
889 		BDIRQ("bd71815-bat-oc3-res", BD_ISR_NAME(bat_oc3_res)),
890 		BDIRQ("bd71815-bat-oc3-det", BD_ISR_NAME(bat_oc3)),
891 		BDIRQ("bd71815-temp-bat-low-res", BD_ISR_NAME(temp_bat_low_res)),
892 		BDIRQ("bd71815-temp-bat-low-det", BD_ISR_NAME(temp_bat_low)),
893 		BDIRQ("bd71815-temp-bat-hi-res", BD_ISR_NAME(temp_bat_hi_res)),
894 		BDIRQ("bd71815-temp-bat-hi-det", BD_ISR_NAME(temp_bat_hi)),
895 		/*
896 		 * TODO: add rest of the IRQs and re-check the handling.
897 		 * Check the bd71815-bat-cc-mon1, bd71815-bat-cc-mon3,
898 		 * bd71815-bat-low-res, bd71815-bat-low-det,
899 		 * bd71815-bat-hi-res, bd71815-bat-hi-det.
900 		 */
901 	};
902 	static const struct bd7182x_irq_res bd71828_irqs[] = {
903 		BDIRQ("bd71828-chg-done", bd718x7_chg_done),
904 		BDIRQ("bd71828-pwr-dcin-in", bd7182x_dcin_detected),
905 		BDIRQ("bd71828-pwr-dcin-out", bd7182x_dcin_removed),
906 		BDIRQ("bd71828-vbat-normal", bd71828_vbat_low_res),
907 		BDIRQ("bd71828-vbat-low", bd71828_vbat_low_det),
908 		BDIRQ("bd71828-btemp-hi", bd71828_temp_bat_hi_det),
909 		BDIRQ("bd71828-btemp-cool", bd71828_temp_bat_hi_res),
910 		BDIRQ("bd71828-btemp-lo", bd71828_temp_bat_low_det),
911 		BDIRQ("bd71828-btemp-warm", bd71828_temp_bat_low_res),
912 		BDIRQ("bd71828-temp-hi", bd71828_temp_vf_det),
913 		BDIRQ("bd71828-temp-norm", bd71828_temp_vf_res),
914 		BDIRQ("bd71828-temp-125-over", bd71828_temp_vf125_det),
915 		BDIRQ("bd71828-temp-125-under", bd71828_temp_vf125_res),
916 	};
917 	static const struct bd7182x_irq_res bd72720_irqs[] = {
918 		BDIRQ("bd72720_int_vbus_rmv", BD_ISR_NAME(dcin_removed)),
919 		BDIRQ("bd72720_int_vbus_det", bd7182x_dcin_detected),
920 		BDIRQ("bd72720_int_vbus_mon_res", BD_ISR_NAME(dcin_mon_res)),
921 		BDIRQ("bd72720_int_vbus_mon_det", BD_ISR_NAME(dcin_mon_det)),
922 		BDIRQ("bd72720_int_vsys_mon_res", BD_ISR_NAME(vsys_mon_res)),
923 		BDIRQ("bd72720_int_vsys_mon_det", BD_ISR_NAME(vsys_mon_det)),
924 		BDIRQ("bd72720_int_vsys_uv_res", BD_ISR_NAME(vsys_uv_res)),
925 		BDIRQ("bd72720_int_vsys_uv_det", BD_ISR_NAME(vsys_uv_det)),
926 		BDIRQ("bd72720_int_vsys_lo_res", BD_ISR_NAME(vsys_low_res)),
927 		BDIRQ("bd72720_int_vsys_lo_det", BD_ISR_NAME(vsys_low_det)),
928 		BDIRQ("bd72720_int_vsys_ov_res", BD_ISR_NAME(vsys_ov_res)),
929 		BDIRQ("bd72720_int_vsys_ov_det", BD_ISR_NAME(vsys_ov_det)),
930 		BDIRQ("bd72720_int_bat_ilim", BD_ISR_NAME(vbus_curr_limit)),
931 		BDIRQ("bd72720_int_chg_done", bd718x7_chg_done),
932 		BDIRQ("bd72720_int_extemp_tout", BD_ISR_NAME(chg_wdg_temp)),
933 		BDIRQ("bd72720_int_chg_wdt_exp", BD_ISR_NAME(chg_wdg)),
934 		BDIRQ("bd72720_int_bat_mnt_out", BD_ISR_NAME(rechg_res)),
935 		BDIRQ("bd72720_int_bat_mnt_in", BD_ISR_NAME(rechg_det)),
936 		BDIRQ("bd72720_int_chg_trns", BD_ISR_NAME(chg_state_changed)),
937 
938 		BDIRQ("bd72720_int_vbat_mon_res", BD_ISR_NAME(bat_mon_res)),
939 		BDIRQ("bd72720_int_vbat_mon_det", BD_ISR_NAME(bat_mon)),
940 		BDIRQ("bd72720_int_vbat_sht_res", BD_ISR_NAME(bat_short_res)),
941 		BDIRQ("bd72720_int_vbat_sht_det", BD_ISR_NAME(bat_short)),
942 		BDIRQ("bd72720_int_vbat_lo_res", BD_ISR_NAME(bat_low_res)),
943 		BDIRQ("bd72720_int_vbat_lo_det", BD_ISR_NAME(bat_low)),
944 		BDIRQ("bd72720_int_vbat_ov_res", BD_ISR_NAME(bat_ov_res)),
945 		BDIRQ("bd72720_int_vbat_ov_det", BD_ISR_NAME(bat_ov)),
946 		BDIRQ("bd72720_int_bat_rmv", BD_ISR_NAME(bat_removed)),
947 		BDIRQ("bd72720_int_bat_det", BD_ISR_NAME(bat_det)),
948 		BDIRQ("bd72720_int_dbat_det", BD_ISR_NAME(bat_dead)),
949 		BDIRQ("bd72720_int_bat_temp_trns", BD_ISR_NAME(temp_transit)),
950 		BDIRQ("bd72720_int_lobtmp_res", BD_ISR_NAME(temp_bat_low_res)),
951 		BDIRQ("bd72720_int_lobtmp_det", BD_ISR_NAME(temp_bat_low)),
952 		BDIRQ("bd72720_int_ovbtmp_res", BD_ISR_NAME(temp_bat_hi_res)),
953 		BDIRQ("bd72720_int_ovbtmp_det", BD_ISR_NAME(temp_bat_hi)),
954 		BDIRQ("bd72720_int_ocur1_res", BD_ISR_NAME(bat_oc1_res)),
955 		BDIRQ("bd72720_int_ocur1_det", BD_ISR_NAME(bat_oc1)),
956 		BDIRQ("bd72720_int_ocur2_res", BD_ISR_NAME(bat_oc2_res)),
957 		BDIRQ("bd72720_int_ocur2_det", BD_ISR_NAME(bat_oc2)),
958 		BDIRQ("bd72720_int_ocur3_res", BD_ISR_NAME(bat_oc3_res)),
959 		BDIRQ("bd72720_int_ocur3_det", BD_ISR_NAME(bat_oc3)),
960 		BDIRQ("bd72720_int_cc_mon2_det", BD_ISR_NAME(bat_cc_mon)),
961 	};
962 	int num_irqs;
963 	const struct bd7182x_irq_res *irqs;
964 
965 	switch (pwr->chip_type) {
966 	case ROHM_CHIP_TYPE_BD71828:
967 		irqs = &bd71828_irqs[0];
968 		num_irqs = ARRAY_SIZE(bd71828_irqs);
969 		break;
970 	case ROHM_CHIP_TYPE_BD71815:
971 		irqs = &bd71815_irqs[0];
972 		num_irqs = ARRAY_SIZE(bd71815_irqs);
973 		break;
974 	case ROHM_CHIP_TYPE_BD72720:
975 		irqs = &bd72720_irqs[0];
976 		num_irqs = ARRAY_SIZE(bd72720_irqs);
977 		break;
978 	default:
979 		return -EINVAL;
980 	}
981 
982 	for (i = 0; i < num_irqs; i++) {
983 		irq = platform_get_irq_byname(pdev, irqs[i].name);
984 
985 		ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
986 						irqs[i].handler, 0,
987 						irqs[i].name, pwr);
988 		if (ret)
989 			break;
990 	}
991 
992 	return ret;
993 }
994 
995 #define RSENS_DEFAULT_30MOHM 30000 /* 30 mOhm in uOhms*/
996 
997 static int bd7182x_get_rsens(struct bd71828_power *pwr)
998 {
999 	u64 tmp = RSENS_CURR;
1000 	int rsens_ohm = RSENS_DEFAULT_30MOHM;
1001 	struct fwnode_handle *node = NULL;
1002 
1003 	if (pwr->dev->parent)
1004 		node = dev_fwnode(pwr->dev->parent);
1005 
1006 	if (node) {
1007 		int ret;
1008 		u32 rs;
1009 
1010 		ret = fwnode_property_read_u32(node,
1011 					       "rohm,charger-sense-resistor-micro-ohms",
1012 					       &rs);
1013 		if (ret) {
1014 			if (ret == -EINVAL) {
1015 				rs = RSENS_DEFAULT_30MOHM;
1016 			} else {
1017 				dev_err(pwr->dev, "Bad RSENS dt property\n");
1018 				return ret;
1019 			}
1020 		}
1021 		if (!rs) {
1022 			dev_err(pwr->dev, "Bad RSENS value\n");
1023 			return -EINVAL;
1024 		}
1025 
1026 		rsens_ohm = (int)rs;
1027 	}
1028 
1029 	/* Reg val to uA */
1030 	do_div(tmp, rsens_ohm);
1031 
1032 	pwr->curr_factor = tmp;
1033 	pwr->rsens = rsens_ohm;
1034 	dev_dbg(pwr->dev, "Setting rsens to %u micro ohm\n", pwr->rsens);
1035 	dev_dbg(pwr->dev, "Setting curr-factor to %u\n", pwr->curr_factor);
1036 
1037 	return 0;
1038 }
1039 
1040 static int bd71828_power_probe(struct platform_device *pdev)
1041 {
1042 	struct bd71828_power *pwr;
1043 	struct power_supply_config ac_cfg = {};
1044 	struct power_supply_config bat_cfg = {};
1045 	int ret;
1046 
1047 	pwr = devm_kzalloc(&pdev->dev, sizeof(*pwr), GFP_KERNEL);
1048 	if (!pwr)
1049 		return -ENOMEM;
1050 
1051 	/*
1052 	 * The BD72720 MFD device registers two regmaps. Power-supply driver
1053 	 * uses the "wrap-map", which provides access to both of the I2C slave
1054 	 * addresses used by the BD72720
1055 	 */
1056 	pwr->chip_type = platform_get_device_id(pdev)->driver_data;
1057 	if (pwr->chip_type != ROHM_CHIP_TYPE_BD72720)
1058 		pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL);
1059 	else
1060 		pwr->regmap = dev_get_regmap(pdev->dev.parent, "wrap-map");
1061 	if (!pwr->regmap)
1062 		return dev_err_probe(&pdev->dev, -EINVAL, "No parent regmap\n");
1063 
1064 	pwr->dev = &pdev->dev;
1065 
1066 	switch (pwr->chip_type) {
1067 	case ROHM_CHIP_TYPE_BD71828:
1068 		pwr->bat_inserted = bd71828_bat_inserted;
1069 		pwr->get_temp = bd71828_get_temp;
1070 		pwr->regs = &pwr_regs_bd71828;
1071 		break;
1072 	case ROHM_CHIP_TYPE_BD71815:
1073 		pwr->bat_inserted = bd71815_bat_inserted;
1074 		pwr->get_temp = bd71815_get_temp;
1075 		pwr->regs = &pwr_regs_bd71815;
1076 		break;
1077 	case ROHM_CHIP_TYPE_BD72720:
1078 		pwr->bat_inserted = bd71828_bat_inserted;
1079 		pwr->regs = &pwr_regs_bd72720;
1080 		pwr->get_temp = bd71828_get_temp;
1081 		dev_dbg(pwr->dev, "Found ROHM BD72720\n");
1082 		break;
1083 	default:
1084 		return dev_err_probe(pwr->dev, -EINVAL, "Unknown PMIC\n");
1085 	}
1086 
1087 	ret = bd7182x_get_rsens(pwr);
1088 	if (ret)
1089 		return dev_err_probe(&pdev->dev, ret, "sense resistor missing\n");
1090 
1091 	dev_set_drvdata(&pdev->dev, pwr);
1092 	bd71828_init_hardware(pwr);
1093 
1094 	bat_cfg.drv_data	= pwr;
1095 	bat_cfg.fwnode		= dev_fwnode(&pdev->dev);
1096 
1097 	ac_cfg.supplied_to	= bd71828_ac_supplied_to;
1098 	ac_cfg.num_supplicants	= ARRAY_SIZE(bd71828_ac_supplied_to);
1099 	ac_cfg.drv_data		= pwr;
1100 
1101 	pwr->ac = devm_power_supply_register(&pdev->dev, &bd71828_ac_desc,
1102 					     &ac_cfg);
1103 	if (IS_ERR(pwr->ac))
1104 		return dev_err_probe(&pdev->dev, PTR_ERR(pwr->ac),
1105 				     "failed to register ac\n");
1106 
1107 	pwr->bat = devm_power_supply_register(&pdev->dev, &bd71828_bat_desc,
1108 					      &bat_cfg);
1109 	if (IS_ERR(pwr->bat))
1110 		return dev_err_probe(&pdev->dev, PTR_ERR(pwr->bat),
1111 				     "failed to register bat\n");
1112 
1113 	ret = bd7182x_get_irqs(pdev, pwr);
1114 	if (ret)
1115 		return dev_err_probe(&pdev->dev, ret, "failed to request IRQs");
1116 
1117 	/* Configure wakeup capable */
1118 	device_set_wakeup_capable(pwr->dev, 1);
1119 	device_set_wakeup_enable(pwr->dev, 1);
1120 
1121 	return 0;
1122 }
1123 
1124 static const struct platform_device_id bd71828_charger_id[] = {
1125 	{ "bd71815-power", ROHM_CHIP_TYPE_BD71815 },
1126 	{ "bd71828-power", ROHM_CHIP_TYPE_BD71828 },
1127 	{ "bd72720-power", ROHM_CHIP_TYPE_BD72720 },
1128 	{ },
1129 };
1130 MODULE_DEVICE_TABLE(platform, bd71828_charger_id);
1131 
1132 static struct platform_driver bd71828_power_driver = {
1133 	.driver = {
1134 		.name = "bd718xx-power",
1135 	},
1136 	.probe = bd71828_power_probe,
1137 	.id_table = bd71828_charger_id,
1138 };
1139 
1140 module_platform_driver(bd71828_power_driver);
1141 
1142 MODULE_AUTHOR("Cong Pham <cpham2403@gmail.com>");
1143 MODULE_DESCRIPTION("ROHM BD718(15/28/78) PMIC Battery Charger driver");
1144 MODULE_LICENSE("GPL");
1145