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