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