1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Power supply driver for the RICOH RN5T618 power management chip family
4  *
5  * Copyright (C) 2020 Andreas Kemnade
6  */
7 
8 #include <linux/kernel.h>
9 #include <linux/device.h>
10 #include <linux/bitops.h>
11 #include <linux/errno.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/module.h>
15 #include <linux/mfd/rn5t618.h>
16 #include <linux/platform_device.h>
17 #include <linux/power_supply.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
20 
21 #define CHG_STATE_ADP_INPUT 0x40
22 #define CHG_STATE_USB_INPUT 0x80
23 #define CHG_STATE_MASK	0x1f
24 #define CHG_STATE_CHG_OFF	0
25 #define CHG_STATE_CHG_READY_VADP	1
26 #define CHG_STATE_CHG_TRICKLE	2
27 #define CHG_STATE_CHG_RAPID	3
28 #define CHG_STATE_CHG_COMPLETE	4
29 #define CHG_STATE_SUSPEND	5
30 #define CHG_STATE_VCHG_OVER_VOL	6
31 #define CHG_STATE_BAT_ERROR	7
32 #define CHG_STATE_NO_BAT	8
33 #define CHG_STATE_BAT_OVER_VOL	9
34 #define CHG_STATE_BAT_TEMP_ERR	10
35 #define CHG_STATE_DIE_ERR	11
36 #define CHG_STATE_DIE_SHUTDOWN	12
37 #define CHG_STATE_NO_BAT2	13
38 #define CHG_STATE_CHG_READY_VUSB	14
39 
40 #define GCHGDET_TYPE_MASK 0x30
41 #define GCHGDET_TYPE_SDP 0x00
42 #define GCHGDET_TYPE_CDP 0x10
43 #define GCHGDET_TYPE_DCP 0x20
44 
45 #define FG_ENABLE 1
46 
47 /*
48  * Formula seems accurate for battery current, but for USB current around 70mA
49  * per step was seen on Kobo Clara HD but all sources show the same formula
50  * also fur USB current. To avoid accidentially unwanted high currents we stick
51  * to that formula
52  */
53 #define TO_CUR_REG(x) ((x) / 100000 - 1)
54 #define FROM_CUR_REG(x) ((((x) & 0x1f) + 1) * 100000)
55 #define CHG_MIN_CUR 100000
56 #define CHG_MAX_CUR 1800000
57 #define ADP_MAX_CUR 2500000
58 #define USB_MAX_CUR 1400000
59 
60 
61 struct rn5t618_power_info {
62 	struct rn5t618 *rn5t618;
63 	struct platform_device *pdev;
64 	struct power_supply *battery;
65 	struct power_supply *usb;
66 	struct power_supply *adp;
67 	int irq;
68 };
69 
70 static enum power_supply_usb_type rn5t618_usb_types[] = {
71 	POWER_SUPPLY_USB_TYPE_SDP,
72 	POWER_SUPPLY_USB_TYPE_DCP,
73 	POWER_SUPPLY_USB_TYPE_CDP,
74 	POWER_SUPPLY_USB_TYPE_UNKNOWN
75 };
76 
77 static enum power_supply_property rn5t618_usb_props[] = {
78 	/* input current limit is not very accurate */
79 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
80 	POWER_SUPPLY_PROP_STATUS,
81 	POWER_SUPPLY_PROP_USB_TYPE,
82 	POWER_SUPPLY_PROP_ONLINE,
83 };
84 
85 static enum power_supply_property rn5t618_adp_props[] = {
86 	/* input current limit is not very accurate */
87 	POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
88 	POWER_SUPPLY_PROP_STATUS,
89 	POWER_SUPPLY_PROP_ONLINE,
90 };
91 
92 
93 static enum power_supply_property rn5t618_battery_props[] = {
94 	POWER_SUPPLY_PROP_STATUS,
95 	POWER_SUPPLY_PROP_PRESENT,
96 	POWER_SUPPLY_PROP_VOLTAGE_NOW,
97 	POWER_SUPPLY_PROP_CURRENT_NOW,
98 	POWER_SUPPLY_PROP_CAPACITY,
99 	POWER_SUPPLY_PROP_TEMP,
100 	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
101 	POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
102 	POWER_SUPPLY_PROP_TECHNOLOGY,
103 	POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
104 	POWER_SUPPLY_PROP_CHARGE_FULL,
105 	POWER_SUPPLY_PROP_CHARGE_NOW,
106 };
107 
108 static int rn5t618_battery_read_doublereg(struct rn5t618_power_info *info,
109 					  u8 reg, u16 *result)
110 {
111 	int ret, i;
112 	u8 data[2];
113 	u16 old, new;
114 
115 	old = 0;
116 	/* Prevent races when registers are changing. */
117 	for (i = 0; i < 3; i++) {
118 		ret = regmap_bulk_read(info->rn5t618->regmap,
119 				       reg, data, sizeof(data));
120 		if (ret)
121 			return ret;
122 
123 		new = data[0] << 8;
124 		new |= data[1];
125 		if (new == old)
126 			break;
127 
128 		old = new;
129 	}
130 
131 	*result = new;
132 
133 	return 0;
134 }
135 
136 static int rn5t618_decode_status(unsigned int status)
137 {
138 	switch (status & CHG_STATE_MASK) {
139 	case CHG_STATE_CHG_OFF:
140 	case CHG_STATE_SUSPEND:
141 	case CHG_STATE_VCHG_OVER_VOL:
142 	case CHG_STATE_DIE_SHUTDOWN:
143 		return POWER_SUPPLY_STATUS_DISCHARGING;
144 
145 	case CHG_STATE_CHG_TRICKLE:
146 	case CHG_STATE_CHG_RAPID:
147 		return POWER_SUPPLY_STATUS_CHARGING;
148 
149 	case CHG_STATE_CHG_COMPLETE:
150 		return POWER_SUPPLY_STATUS_FULL;
151 
152 	default:
153 		return POWER_SUPPLY_STATUS_NOT_CHARGING;
154 	}
155 }
156 
157 static int rn5t618_battery_status(struct rn5t618_power_info *info,
158 				  union power_supply_propval *val)
159 {
160 	unsigned int v;
161 	int ret;
162 
163 	ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &v);
164 	if (ret)
165 		return ret;
166 
167 	val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
168 
169 	if (v & 0xc0) { /* USB or ADP plugged */
170 		val->intval = rn5t618_decode_status(v);
171 	} else
172 		val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
173 
174 	return ret;
175 }
176 
177 static int rn5t618_battery_present(struct rn5t618_power_info *info,
178 				   union power_supply_propval *val)
179 {
180 	unsigned int v;
181 	int ret;
182 
183 	ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &v);
184 	if (ret)
185 		return ret;
186 
187 	v &= CHG_STATE_MASK;
188 	if ((v == CHG_STATE_NO_BAT) || (v == CHG_STATE_NO_BAT2))
189 		val->intval = 0;
190 	else
191 		val->intval = 1;
192 
193 	return ret;
194 }
195 
196 static int rn5t618_battery_voltage_now(struct rn5t618_power_info *info,
197 				       union power_supply_propval *val)
198 {
199 	u16 res;
200 	int ret;
201 
202 	ret = rn5t618_battery_read_doublereg(info, RN5T618_VOLTAGE_1, &res);
203 	if (ret)
204 		return ret;
205 
206 	val->intval = res * 2 * 2500 / 4095 * 1000;
207 
208 	return 0;
209 }
210 
211 static int rn5t618_battery_current_now(struct rn5t618_power_info *info,
212 				       union power_supply_propval *val)
213 {
214 	u16 res;
215 	int ret;
216 
217 	ret = rn5t618_battery_read_doublereg(info, RN5T618_CC_AVEREG1, &res);
218 	if (ret)
219 		return ret;
220 
221 	/* current is negative when discharging */
222 	val->intval = sign_extend32(res, 13) * 1000;
223 
224 	return 0;
225 }
226 
227 static int rn5t618_battery_capacity(struct rn5t618_power_info *info,
228 				    union power_supply_propval *val)
229 {
230 	unsigned int v;
231 	int ret;
232 
233 	ret = regmap_read(info->rn5t618->regmap, RN5T618_SOC, &v);
234 	if (ret)
235 		return ret;
236 
237 	val->intval = v;
238 
239 	return 0;
240 }
241 
242 static int rn5t618_battery_temp(struct rn5t618_power_info *info,
243 				union power_supply_propval *val)
244 {
245 	u16 res;
246 	int ret;
247 
248 	ret = rn5t618_battery_read_doublereg(info, RN5T618_TEMP_1, &res);
249 	if (ret)
250 		return ret;
251 
252 	val->intval = sign_extend32(res, 11) * 10 / 16;
253 
254 	return 0;
255 }
256 
257 static int rn5t618_battery_tte(struct rn5t618_power_info *info,
258 			       union power_supply_propval *val)
259 {
260 	u16 res;
261 	int ret;
262 
263 	ret = rn5t618_battery_read_doublereg(info, RN5T618_TT_EMPTY_H, &res);
264 	if (ret)
265 		return ret;
266 
267 	if (res == 65535)
268 		return -ENODATA;
269 
270 	val->intval = res * 60;
271 
272 	return 0;
273 }
274 
275 static int rn5t618_battery_ttf(struct rn5t618_power_info *info,
276 			       union power_supply_propval *val)
277 {
278 	u16 res;
279 	int ret;
280 
281 	ret = rn5t618_battery_read_doublereg(info, RN5T618_TT_FULL_H, &res);
282 	if (ret)
283 		return ret;
284 
285 	if (res == 65535)
286 		return -ENODATA;
287 
288 	val->intval = res * 60;
289 
290 	return 0;
291 }
292 
293 static int rn5t618_battery_set_current_limit(struct rn5t618_power_info *info,
294 				const union power_supply_propval *val)
295 {
296 	if (val->intval < CHG_MIN_CUR)
297 		return -EINVAL;
298 
299 	if (val->intval >= CHG_MAX_CUR)
300 		return -EINVAL;
301 
302 	return regmap_update_bits(info->rn5t618->regmap,
303 				  RN5T618_CHGISET,
304 				  0x1F, TO_CUR_REG(val->intval));
305 }
306 
307 static int rn5t618_battery_get_current_limit(struct rn5t618_power_info *info,
308 					     union power_supply_propval *val)
309 {
310 	unsigned int regval;
311 	int ret;
312 
313 	ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGISET,
314 			  &regval);
315 	if (ret < 0)
316 		return ret;
317 
318 	val->intval = FROM_CUR_REG(regval);
319 
320 	return 0;
321 }
322 
323 static int rn5t618_battery_charge_full(struct rn5t618_power_info *info,
324 				       union power_supply_propval *val)
325 {
326 	u16 res;
327 	int ret;
328 
329 	ret = rn5t618_battery_read_doublereg(info, RN5T618_FA_CAP_H, &res);
330 	if (ret)
331 		return ret;
332 
333 	val->intval = res * 1000;
334 
335 	return 0;
336 }
337 
338 static int rn5t618_battery_charge_now(struct rn5t618_power_info *info,
339 				      union power_supply_propval *val)
340 {
341 	u16 res;
342 	int ret;
343 
344 	ret = rn5t618_battery_read_doublereg(info, RN5T618_RE_CAP_H, &res);
345 	if (ret)
346 		return ret;
347 
348 	val->intval = res * 1000;
349 
350 	return 0;
351 }
352 
353 static int rn5t618_battery_get_property(struct power_supply *psy,
354 					enum power_supply_property psp,
355 					union power_supply_propval *val)
356 {
357 	int ret = 0;
358 	struct rn5t618_power_info *info = power_supply_get_drvdata(psy);
359 
360 	switch (psp) {
361 	case POWER_SUPPLY_PROP_STATUS:
362 		ret = rn5t618_battery_status(info, val);
363 		break;
364 	case POWER_SUPPLY_PROP_PRESENT:
365 		ret = rn5t618_battery_present(info, val);
366 		break;
367 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
368 		ret = rn5t618_battery_voltage_now(info, val);
369 		break;
370 	case POWER_SUPPLY_PROP_CURRENT_NOW:
371 		ret = rn5t618_battery_current_now(info, val);
372 		break;
373 	case POWER_SUPPLY_PROP_CAPACITY:
374 		ret = rn5t618_battery_capacity(info, val);
375 		break;
376 	case POWER_SUPPLY_PROP_TEMP:
377 		ret = rn5t618_battery_temp(info, val);
378 		break;
379 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
380 		ret = rn5t618_battery_tte(info, val);
381 		break;
382 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
383 		ret = rn5t618_battery_ttf(info, val);
384 		break;
385 	case POWER_SUPPLY_PROP_TECHNOLOGY:
386 		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
387 		break;
388 	case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
389 		ret = rn5t618_battery_get_current_limit(info, val);
390 		break;
391 	case POWER_SUPPLY_PROP_CHARGE_FULL:
392 		ret = rn5t618_battery_charge_full(info, val);
393 		break;
394 	case POWER_SUPPLY_PROP_CHARGE_NOW:
395 		ret = rn5t618_battery_charge_now(info, val);
396 		break;
397 	default:
398 		return -EINVAL;
399 	}
400 
401 	return ret;
402 }
403 
404 static int rn5t618_battery_set_property(struct power_supply *psy,
405 					enum power_supply_property psp,
406 					const union power_supply_propval *val)
407 {
408 	struct rn5t618_power_info *info = power_supply_get_drvdata(psy);
409 
410 	switch (psp) {
411 	case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
412 		return rn5t618_battery_set_current_limit(info, val);
413 	default:
414 		return -EINVAL;
415 	}
416 }
417 
418 static int rn5t618_battery_property_is_writeable(struct power_supply *psy,
419 						enum power_supply_property psp)
420 {
421 	switch (psp) {
422 	case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
423 		return true;
424 	default:
425 		return false;
426 	}
427 }
428 
429 static int rn5t618_adp_get_property(struct power_supply *psy,
430 				    enum power_supply_property psp,
431 				    union power_supply_propval *val)
432 {
433 	struct rn5t618_power_info *info = power_supply_get_drvdata(psy);
434 	unsigned int chgstate;
435 	unsigned int regval;
436 	bool online;
437 	int ret;
438 
439 	ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &chgstate);
440 	if (ret)
441 		return ret;
442 
443 	online = !!(chgstate & CHG_STATE_ADP_INPUT);
444 
445 	switch (psp) {
446 	case POWER_SUPPLY_PROP_ONLINE:
447 		val->intval = online;
448 		break;
449 	case POWER_SUPPLY_PROP_STATUS:
450 		if (!online) {
451 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
452 			break;
453 		}
454 		val->intval = rn5t618_decode_status(chgstate);
455 		if (val->intval != POWER_SUPPLY_STATUS_CHARGING)
456 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
457 
458 		break;
459 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
460 		ret = regmap_read(info->rn5t618->regmap,
461 				  RN5T618_REGISET1, &regval);
462 		if (ret < 0)
463 			return ret;
464 
465 		val->intval = FROM_CUR_REG(regval);
466 		break;
467 	default:
468 		return -EINVAL;
469 	}
470 
471 	return 0;
472 }
473 
474 static int rn5t618_adp_set_property(struct power_supply *psy,
475 				    enum power_supply_property psp,
476 				    const union power_supply_propval *val)
477 {
478 	struct rn5t618_power_info *info = power_supply_get_drvdata(psy);
479 	int ret;
480 
481 	switch (psp) {
482 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
483 		if (val->intval > ADP_MAX_CUR)
484 			return -EINVAL;
485 
486 		if (val->intval < CHG_MIN_CUR)
487 			return -EINVAL;
488 
489 		ret = regmap_write(info->rn5t618->regmap, RN5T618_REGISET1,
490 				   TO_CUR_REG(val->intval));
491 		if (ret < 0)
492 			return ret;
493 
494 		break;
495 	default:
496 		return -EINVAL;
497 	}
498 
499 	return 0;
500 }
501 
502 static int rn5t618_adp_property_is_writeable(struct power_supply *psy,
503 					     enum power_supply_property psp)
504 {
505 	switch (psp) {
506 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
507 		return true;
508 	default:
509 		return false;
510 	}
511 }
512 
513 static int rc5t619_usb_get_type(struct rn5t618_power_info *info,
514 				union power_supply_propval *val)
515 {
516 	unsigned int regval;
517 	int ret;
518 
519 	ret = regmap_read(info->rn5t618->regmap, RN5T618_GCHGDET, &regval);
520 	if (ret < 0)
521 		return ret;
522 
523 	switch (regval & GCHGDET_TYPE_MASK) {
524 	case GCHGDET_TYPE_SDP:
525 		val->intval = POWER_SUPPLY_USB_TYPE_SDP;
526 		break;
527 	case GCHGDET_TYPE_CDP:
528 		val->intval = POWER_SUPPLY_USB_TYPE_CDP;
529 		break;
530 	case GCHGDET_TYPE_DCP:
531 		val->intval = POWER_SUPPLY_USB_TYPE_DCP;
532 		break;
533 	default:
534 		val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN;
535 	}
536 
537 	return 0;
538 }
539 
540 static int rn5t618_usb_get_property(struct power_supply *psy,
541 				    enum power_supply_property psp,
542 				    union power_supply_propval *val)
543 {
544 	struct rn5t618_power_info *info = power_supply_get_drvdata(psy);
545 	unsigned int chgstate;
546 	unsigned int regval;
547 	bool online;
548 	int ret;
549 
550 	ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGSTATE, &chgstate);
551 	if (ret)
552 		return ret;
553 
554 	online = !!(chgstate & CHG_STATE_USB_INPUT);
555 
556 	switch (psp) {
557 	case POWER_SUPPLY_PROP_ONLINE:
558 		val->intval = online;
559 		break;
560 	case POWER_SUPPLY_PROP_STATUS:
561 		if (!online) {
562 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
563 			break;
564 		}
565 		val->intval = rn5t618_decode_status(chgstate);
566 		if (val->intval != POWER_SUPPLY_STATUS_CHARGING)
567 			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
568 
569 		break;
570 	case POWER_SUPPLY_PROP_USB_TYPE:
571 		if (!online || (info->rn5t618->variant != RC5T619))
572 			return -ENODATA;
573 
574 		return rc5t619_usb_get_type(info, val);
575 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
576 		ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGCTL1,
577 				  &regval);
578 		if (ret < 0)
579 			return ret;
580 
581 		val->intval = 0;
582 		if (regval & 2) {
583 			ret = regmap_read(info->rn5t618->regmap,
584 					  RN5T618_REGISET2,
585 					  &regval);
586 			if (ret < 0)
587 				return ret;
588 
589 			val->intval = FROM_CUR_REG(regval);
590 		}
591 		break;
592 	default:
593 		return -EINVAL;
594 	}
595 
596 	return 0;
597 }
598 
599 static int rn5t618_usb_set_property(struct power_supply *psy,
600 				    enum power_supply_property psp,
601 				    const union power_supply_propval *val)
602 {
603 	struct rn5t618_power_info *info = power_supply_get_drvdata(psy);
604 	int ret;
605 
606 	switch (psp) {
607 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
608 		if (val->intval > USB_MAX_CUR)
609 			return -EINVAL;
610 
611 		if (val->intval < CHG_MIN_CUR)
612 			return -EINVAL;
613 
614 		ret = regmap_write(info->rn5t618->regmap, RN5T618_REGISET2,
615 				   0xE0 | TO_CUR_REG(val->intval));
616 		if (ret < 0)
617 			return ret;
618 
619 		break;
620 	default:
621 		return -EINVAL;
622 	}
623 
624 	return 0;
625 }
626 
627 static int rn5t618_usb_property_is_writeable(struct power_supply *psy,
628 					     enum power_supply_property psp)
629 {
630 	switch (psp) {
631 	case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
632 		return true;
633 	default:
634 		return false;
635 	}
636 }
637 
638 static const struct power_supply_desc rn5t618_battery_desc = {
639 	.name                   = "rn5t618-battery",
640 	.type                   = POWER_SUPPLY_TYPE_BATTERY,
641 	.properties             = rn5t618_battery_props,
642 	.num_properties         = ARRAY_SIZE(rn5t618_battery_props),
643 	.get_property           = rn5t618_battery_get_property,
644 	.set_property           = rn5t618_battery_set_property,
645 	.property_is_writeable  = rn5t618_battery_property_is_writeable,
646 };
647 
648 static const struct power_supply_desc rn5t618_adp_desc = {
649 	.name                   = "rn5t618-adp",
650 	.type                   = POWER_SUPPLY_TYPE_MAINS,
651 	.properties             = rn5t618_adp_props,
652 	.num_properties         = ARRAY_SIZE(rn5t618_adp_props),
653 	.get_property           = rn5t618_adp_get_property,
654 	.set_property           = rn5t618_adp_set_property,
655 	.property_is_writeable  = rn5t618_adp_property_is_writeable,
656 };
657 
658 static const struct power_supply_desc rn5t618_usb_desc = {
659 	.name                   = "rn5t618-usb",
660 	.type                   = POWER_SUPPLY_TYPE_USB,
661 	.usb_types		= rn5t618_usb_types,
662 	.num_usb_types		= ARRAY_SIZE(rn5t618_usb_types),
663 	.properties             = rn5t618_usb_props,
664 	.num_properties         = ARRAY_SIZE(rn5t618_usb_props),
665 	.get_property           = rn5t618_usb_get_property,
666 	.set_property           = rn5t618_usb_set_property,
667 	.property_is_writeable  = rn5t618_usb_property_is_writeable,
668 };
669 
670 static irqreturn_t rn5t618_charger_irq(int irq, void *data)
671 {
672 	struct device *dev = data;
673 	struct rn5t618_power_info *info = dev_get_drvdata(dev);
674 
675 	unsigned int ctrl, stat1, stat2, err;
676 
677 	regmap_read(info->rn5t618->regmap, RN5T618_CHGERR_IRR, &err);
678 	regmap_read(info->rn5t618->regmap, RN5T618_CHGCTRL_IRR, &ctrl);
679 	regmap_read(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR1, &stat1);
680 	regmap_read(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR2, &stat2);
681 
682 	regmap_write(info->rn5t618->regmap, RN5T618_CHGERR_IRR, 0);
683 	regmap_write(info->rn5t618->regmap, RN5T618_CHGCTRL_IRR, 0);
684 	regmap_write(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR1, 0);
685 	regmap_write(info->rn5t618->regmap, RN5T618_CHGSTAT_IRR2, 0);
686 
687 	dev_dbg(dev, "chgerr: %x chgctrl: %x chgstat: %x chgstat2: %x\n",
688 		err, ctrl, stat1, stat2);
689 
690 	power_supply_changed(info->usb);
691 	power_supply_changed(info->adp);
692 	power_supply_changed(info->battery);
693 
694 	return IRQ_HANDLED;
695 }
696 
697 static int rn5t618_power_probe(struct platform_device *pdev)
698 {
699 	int ret = 0;
700 	unsigned int v;
701 	struct power_supply_config psy_cfg = {};
702 	struct rn5t618_power_info *info;
703 
704 	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
705 	if (!info)
706 		return -ENOMEM;
707 
708 	info->pdev = pdev;
709 	info->rn5t618 = dev_get_drvdata(pdev->dev.parent);
710 	info->irq = -1;
711 
712 	platform_set_drvdata(pdev, info);
713 
714 	ret = regmap_read(info->rn5t618->regmap, RN5T618_CONTROL, &v);
715 	if (ret)
716 		return ret;
717 
718 	if (!(v & FG_ENABLE)) {
719 		/* E.g. the vendor kernels of various Kobo and Tolino Ebook
720 		 * readers disable the fuel gauge on shutdown. If a kernel
721 		 * without fuel gauge support is booted after that, the fuel
722 		 * gauge will get decalibrated.
723 		 */
724 		dev_info(&pdev->dev, "Fuel gauge not enabled, enabling now\n");
725 		dev_info(&pdev->dev, "Expect imprecise results\n");
726 		regmap_update_bits(info->rn5t618->regmap, RN5T618_CONTROL,
727 				   FG_ENABLE, FG_ENABLE);
728 	}
729 
730 	psy_cfg.drv_data = info;
731 	info->battery = devm_power_supply_register(&pdev->dev,
732 						   &rn5t618_battery_desc,
733 						   &psy_cfg);
734 	if (IS_ERR(info->battery)) {
735 		ret = PTR_ERR(info->battery);
736 		dev_err(&pdev->dev, "failed to register battery: %d\n", ret);
737 		return ret;
738 	}
739 
740 	info->adp = devm_power_supply_register(&pdev->dev,
741 					       &rn5t618_adp_desc,
742 					       &psy_cfg);
743 	if (IS_ERR(info->adp)) {
744 		ret = PTR_ERR(info->adp);
745 		dev_err(&pdev->dev, "failed to register adp: %d\n", ret);
746 		return ret;
747 	}
748 
749 	info->usb = devm_power_supply_register(&pdev->dev,
750 					       &rn5t618_usb_desc,
751 					       &psy_cfg);
752 	if (IS_ERR(info->usb)) {
753 		ret = PTR_ERR(info->usb);
754 		dev_err(&pdev->dev, "failed to register usb: %d\n", ret);
755 		return ret;
756 	}
757 
758 	if (info->rn5t618->irq_data)
759 		info->irq = regmap_irq_get_virq(info->rn5t618->irq_data,
760 						RN5T618_IRQ_CHG);
761 
762 	if (info->irq < 0)
763 		info->irq = -1;
764 	else {
765 		ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
766 						rn5t618_charger_irq,
767 						IRQF_ONESHOT,
768 						"rn5t618_power",
769 						&pdev->dev);
770 
771 		if (ret < 0) {
772 			dev_err(&pdev->dev, "request IRQ:%d fail\n",
773 				info->irq);
774 			info->irq = -1;
775 		}
776 	}
777 
778 	return 0;
779 }
780 
781 static struct platform_driver rn5t618_power_driver = {
782 	.driver = {
783 		.name   = "rn5t618-power",
784 	},
785 	.probe = rn5t618_power_probe,
786 };
787 
788 module_platform_driver(rn5t618_power_driver);
789 MODULE_ALIAS("platform:rn5t618-power");
790 MODULE_DESCRIPTION("Power supply driver for RICOH RN5T618");
791 MODULE_LICENSE("GPL");
792