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