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