1 // SPDX-License-Identifier: GPL-2.0+
3 * Power supply driver for the RICOH RN5T618 power management chip family
5 * Copyright (C) 2020 Andreas Kemnade
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>
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
41 #define GCHGDET_TYPE_MASK 0x30
42 #define GCHGDET_TYPE_SDP 0x00
43 #define GCHGDET_TYPE_CDP 0x10
44 #define GCHGDET_TYPE_DCP 0x20
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
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
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
;
73 static enum power_supply_property rn5t618_usb_props
[] = {
74 /* input current limit is not very accurate */
75 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
,
76 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
77 POWER_SUPPLY_PROP_STATUS
,
78 POWER_SUPPLY_PROP_USB_TYPE
,
79 POWER_SUPPLY_PROP_ONLINE
,
82 static enum power_supply_property rn5t618_adp_props
[] = {
83 /* input current limit is not very accurate */
84 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
,
85 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
86 POWER_SUPPLY_PROP_STATUS
,
87 POWER_SUPPLY_PROP_ONLINE
,
91 static enum power_supply_property rn5t618_battery_props
[] = {
92 POWER_SUPPLY_PROP_STATUS
,
93 POWER_SUPPLY_PROP_PRESENT
,
94 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
95 POWER_SUPPLY_PROP_CURRENT_NOW
,
96 POWER_SUPPLY_PROP_CAPACITY
,
97 POWER_SUPPLY_PROP_TEMP
,
98 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW
,
99 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
,
100 POWER_SUPPLY_PROP_TECHNOLOGY
,
101 POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
,
102 POWER_SUPPLY_PROP_CHARGE_FULL
,
103 POWER_SUPPLY_PROP_CHARGE_NOW
,
106 static int rn5t618_battery_read_doublereg(struct rn5t618_power_info
*info
,
114 /* Prevent races when registers are changing. */
115 for (i
= 0; i
< 3; i
++) {
116 ret
= regmap_bulk_read(info
->rn5t618
->regmap
,
117 reg
, data
, sizeof(data
));
134 static int rn5t618_decode_status(unsigned int status
)
136 switch (status
& CHG_STATE_MASK
) {
137 case CHG_STATE_CHG_OFF
:
138 case CHG_STATE_SUSPEND
:
139 case CHG_STATE_VCHG_OVER_VOL
:
140 case CHG_STATE_DIE_SHUTDOWN
:
141 return POWER_SUPPLY_STATUS_DISCHARGING
;
143 case CHG_STATE_CHG_TRICKLE
:
144 case CHG_STATE_CHG_RAPID
:
145 return POWER_SUPPLY_STATUS_CHARGING
;
147 case CHG_STATE_CHG_COMPLETE
:
148 return POWER_SUPPLY_STATUS_FULL
;
151 return POWER_SUPPLY_STATUS_NOT_CHARGING
;
155 static int rn5t618_battery_status(struct rn5t618_power_info
*info
,
156 union power_supply_propval
*val
)
161 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGSTATE
, &v
);
165 val
->intval
= POWER_SUPPLY_STATUS_UNKNOWN
;
167 if (v
& 0xc0) { /* USB or ADP plugged */
168 val
->intval
= rn5t618_decode_status(v
);
170 val
->intval
= POWER_SUPPLY_STATUS_DISCHARGING
;
175 static int rn5t618_battery_present(struct rn5t618_power_info
*info
,
176 union power_supply_propval
*val
)
181 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGSTATE
, &v
);
186 if ((v
== CHG_STATE_NO_BAT
) || (v
== CHG_STATE_NO_BAT2
))
194 static int rn5t618_battery_voltage_now(struct rn5t618_power_info
*info
,
195 union power_supply_propval
*val
)
200 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_VOLTAGE_1
, &res
);
204 val
->intval
= res
* 2 * 2500 / 4095 * 1000;
209 static int rn5t618_battery_current_now(struct rn5t618_power_info
*info
,
210 union power_supply_propval
*val
)
215 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_CC_AVEREG1
, &res
);
219 /* current is negative when discharging */
220 val
->intval
= sign_extend32(res
, 13) * 1000;
225 static int rn5t618_battery_capacity(struct rn5t618_power_info
*info
,
226 union power_supply_propval
*val
)
231 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_SOC
, &v
);
240 static int rn5t618_battery_temp(struct rn5t618_power_info
*info
,
241 union power_supply_propval
*val
)
246 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_TEMP_1
, &res
);
250 val
->intval
= sign_extend32(res
, 11) * 10 / 16;
255 static int rn5t618_battery_tte(struct rn5t618_power_info
*info
,
256 union power_supply_propval
*val
)
261 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_TT_EMPTY_H
, &res
);
268 val
->intval
= res
* 60;
273 static int rn5t618_battery_ttf(struct rn5t618_power_info
*info
,
274 union power_supply_propval
*val
)
279 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_TT_FULL_H
, &res
);
286 val
->intval
= res
* 60;
291 static int rn5t618_battery_set_current_limit(struct rn5t618_power_info
*info
,
292 const union power_supply_propval
*val
)
294 if (val
->intval
< CHG_MIN_CUR
)
297 if (val
->intval
>= CHG_MAX_CUR
)
300 return regmap_update_bits(info
->rn5t618
->regmap
,
302 0x1F, TO_CUR_REG(val
->intval
));
305 static int rn5t618_battery_get_current_limit(struct rn5t618_power_info
*info
,
306 union power_supply_propval
*val
)
311 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGISET
,
316 val
->intval
= FROM_CUR_REG(regval
);
321 static int rn5t618_battery_charge_full(struct rn5t618_power_info
*info
,
322 union power_supply_propval
*val
)
327 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_FA_CAP_H
, &res
);
331 val
->intval
= res
* 1000;
336 static int rn5t618_battery_charge_now(struct rn5t618_power_info
*info
,
337 union power_supply_propval
*val
)
342 ret
= rn5t618_battery_read_doublereg(info
, RN5T618_RE_CAP_H
, &res
);
346 val
->intval
= res
* 1000;
351 static int rn5t618_battery_get_property(struct power_supply
*psy
,
352 enum power_supply_property psp
,
353 union power_supply_propval
*val
)
356 struct rn5t618_power_info
*info
= power_supply_get_drvdata(psy
);
359 case POWER_SUPPLY_PROP_STATUS
:
360 ret
= rn5t618_battery_status(info
, val
);
362 case POWER_SUPPLY_PROP_PRESENT
:
363 ret
= rn5t618_battery_present(info
, val
);
365 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
366 ret
= rn5t618_battery_voltage_now(info
, val
);
368 case POWER_SUPPLY_PROP_CURRENT_NOW
:
369 ret
= rn5t618_battery_current_now(info
, val
);
371 case POWER_SUPPLY_PROP_CAPACITY
:
372 ret
= rn5t618_battery_capacity(info
, val
);
374 case POWER_SUPPLY_PROP_TEMP
:
375 ret
= rn5t618_battery_temp(info
, val
);
377 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW
:
378 ret
= rn5t618_battery_tte(info
, val
);
380 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
:
381 ret
= rn5t618_battery_ttf(info
, val
);
383 case POWER_SUPPLY_PROP_TECHNOLOGY
:
384 val
->intval
= POWER_SUPPLY_TECHNOLOGY_LION
;
386 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
:
387 ret
= rn5t618_battery_get_current_limit(info
, val
);
389 case POWER_SUPPLY_PROP_CHARGE_FULL
:
390 ret
= rn5t618_battery_charge_full(info
, val
);
392 case POWER_SUPPLY_PROP_CHARGE_NOW
:
393 ret
= rn5t618_battery_charge_now(info
, val
);
402 static int rn5t618_battery_set_property(struct power_supply
*psy
,
403 enum power_supply_property psp
,
404 const union power_supply_propval
*val
)
406 struct rn5t618_power_info
*info
= power_supply_get_drvdata(psy
);
409 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
:
410 return rn5t618_battery_set_current_limit(info
, val
);
416 static int rn5t618_battery_property_is_writeable(struct power_supply
*psy
,
417 enum power_supply_property psp
)
420 case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT
:
427 static int rn5t618_adp_get_property(struct power_supply
*psy
,
428 enum power_supply_property psp
,
429 union power_supply_propval
*val
)
431 struct rn5t618_power_info
*info
= power_supply_get_drvdata(psy
);
432 unsigned int chgstate
;
437 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGSTATE
, &chgstate
);
441 online
= !!(chgstate
& CHG_STATE_ADP_INPUT
);
444 case POWER_SUPPLY_PROP_ONLINE
:
445 val
->intval
= online
;
447 case POWER_SUPPLY_PROP_STATUS
:
449 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
452 val
->intval
= rn5t618_decode_status(chgstate
);
453 if (val
->intval
!= POWER_SUPPLY_STATUS_CHARGING
)
454 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
457 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
458 ret
= regmap_read(info
->rn5t618
->regmap
,
459 RN5T618_REGISET1
, ®val
);
463 val
->intval
= FROM_CUR_REG(regval
);
465 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
466 if (!info
->channel_vadp
)
469 ret
= iio_read_channel_processed_scale(info
->channel_vadp
, &val
->intval
, 1000);
481 static int rn5t618_adp_set_property(struct power_supply
*psy
,
482 enum power_supply_property psp
,
483 const union power_supply_propval
*val
)
485 struct rn5t618_power_info
*info
= power_supply_get_drvdata(psy
);
489 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
490 if (val
->intval
> ADP_MAX_CUR
)
493 if (val
->intval
< CHG_MIN_CUR
)
496 ret
= regmap_write(info
->rn5t618
->regmap
, RN5T618_REGISET1
,
497 TO_CUR_REG(val
->intval
));
509 static int rn5t618_adp_property_is_writeable(struct power_supply
*psy
,
510 enum power_supply_property psp
)
513 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
520 static int rc5t619_usb_get_type(struct rn5t618_power_info
*info
,
521 union power_supply_propval
*val
)
526 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_GCHGDET
, ®val
);
530 switch (regval
& GCHGDET_TYPE_MASK
) {
531 case GCHGDET_TYPE_SDP
:
532 val
->intval
= POWER_SUPPLY_USB_TYPE_SDP
;
534 case GCHGDET_TYPE_CDP
:
535 val
->intval
= POWER_SUPPLY_USB_TYPE_CDP
;
537 case GCHGDET_TYPE_DCP
:
538 val
->intval
= POWER_SUPPLY_USB_TYPE_DCP
;
541 val
->intval
= POWER_SUPPLY_USB_TYPE_UNKNOWN
;
547 static int rn5t618_usb_get_property(struct power_supply
*psy
,
548 enum power_supply_property psp
,
549 union power_supply_propval
*val
)
551 struct rn5t618_power_info
*info
= power_supply_get_drvdata(psy
);
552 unsigned int chgstate
;
557 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGSTATE
, &chgstate
);
561 online
= !!(chgstate
& CHG_STATE_USB_INPUT
);
564 case POWER_SUPPLY_PROP_ONLINE
:
565 val
->intval
= online
;
567 case POWER_SUPPLY_PROP_STATUS
:
569 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
572 val
->intval
= rn5t618_decode_status(chgstate
);
573 if (val
->intval
!= POWER_SUPPLY_STATUS_CHARGING
)
574 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
577 case POWER_SUPPLY_PROP_USB_TYPE
:
578 if (!online
|| (info
->rn5t618
->variant
!= RC5T619
))
581 return rc5t619_usb_get_type(info
, val
);
582 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
583 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGCTL1
,
590 ret
= regmap_read(info
->rn5t618
->regmap
,
596 val
->intval
= FROM_CUR_REG(regval
);
599 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
600 if (!info
->channel_vusb
)
603 ret
= iio_read_channel_processed_scale(info
->channel_vusb
, &val
->intval
, 1000);
615 static int rn5t618_usb_set_property(struct power_supply
*psy
,
616 enum power_supply_property psp
,
617 const union power_supply_propval
*val
)
619 struct rn5t618_power_info
*info
= power_supply_get_drvdata(psy
);
623 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
624 if (val
->intval
> USB_MAX_CUR
)
627 if (val
->intval
< CHG_MIN_CUR
)
630 ret
= regmap_write(info
->rn5t618
->regmap
, RN5T618_REGISET2
,
631 0xE0 | TO_CUR_REG(val
->intval
));
643 static int rn5t618_usb_property_is_writeable(struct power_supply
*psy
,
644 enum power_supply_property psp
)
647 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT
:
654 static const struct power_supply_desc rn5t618_battery_desc
= {
655 .name
= "rn5t618-battery",
656 .type
= POWER_SUPPLY_TYPE_BATTERY
,
657 .properties
= rn5t618_battery_props
,
658 .num_properties
= ARRAY_SIZE(rn5t618_battery_props
),
659 .get_property
= rn5t618_battery_get_property
,
660 .set_property
= rn5t618_battery_set_property
,
661 .property_is_writeable
= rn5t618_battery_property_is_writeable
,
664 static const struct power_supply_desc rn5t618_adp_desc
= {
665 .name
= "rn5t618-adp",
666 .type
= POWER_SUPPLY_TYPE_MAINS
,
667 .properties
= rn5t618_adp_props
,
668 .num_properties
= ARRAY_SIZE(rn5t618_adp_props
),
669 .get_property
= rn5t618_adp_get_property
,
670 .set_property
= rn5t618_adp_set_property
,
671 .property_is_writeable
= rn5t618_adp_property_is_writeable
,
674 static const struct power_supply_desc rn5t618_usb_desc
= {
675 .name
= "rn5t618-usb",
676 .type
= POWER_SUPPLY_TYPE_USB
,
677 .usb_types
= BIT(POWER_SUPPLY_USB_TYPE_SDP
) |
678 BIT(POWER_SUPPLY_USB_TYPE_CDP
) |
679 BIT(POWER_SUPPLY_USB_TYPE_DCP
) |
680 BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN
),
681 .properties
= rn5t618_usb_props
,
682 .num_properties
= ARRAY_SIZE(rn5t618_usb_props
),
683 .get_property
= rn5t618_usb_get_property
,
684 .set_property
= rn5t618_usb_set_property
,
685 .property_is_writeable
= rn5t618_usb_property_is_writeable
,
688 static irqreturn_t
rn5t618_charger_irq(int irq
, void *data
)
690 struct device
*dev
= data
;
691 struct rn5t618_power_info
*info
= dev_get_drvdata(dev
);
693 unsigned int ctrl
, stat1
, stat2
, err
;
695 regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGERR_IRR
, &err
);
696 regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGCTRL_IRR
, &ctrl
);
697 regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGSTAT_IRR1
, &stat1
);
698 regmap_read(info
->rn5t618
->regmap
, RN5T618_CHGSTAT_IRR2
, &stat2
);
700 regmap_write(info
->rn5t618
->regmap
, RN5T618_CHGERR_IRR
, 0);
701 regmap_write(info
->rn5t618
->regmap
, RN5T618_CHGCTRL_IRR
, 0);
702 regmap_write(info
->rn5t618
->regmap
, RN5T618_CHGSTAT_IRR1
, 0);
703 regmap_write(info
->rn5t618
->regmap
, RN5T618_CHGSTAT_IRR2
, 0);
705 dev_dbg(dev
, "chgerr: %x chgctrl: %x chgstat: %x chgstat2: %x\n",
706 err
, ctrl
, stat1
, stat2
);
708 power_supply_changed(info
->usb
);
709 power_supply_changed(info
->adp
);
710 power_supply_changed(info
->battery
);
715 static int rn5t618_power_probe(struct platform_device
*pdev
)
719 struct power_supply_config psy_cfg
= {};
720 struct rn5t618_power_info
*info
;
722 info
= devm_kzalloc(&pdev
->dev
, sizeof(*info
), GFP_KERNEL
);
727 info
->rn5t618
= dev_get_drvdata(pdev
->dev
.parent
);
730 platform_set_drvdata(pdev
, info
);
732 info
->channel_vusb
= devm_iio_channel_get(&pdev
->dev
, "vusb");
733 if (IS_ERR(info
->channel_vusb
)) {
734 if (PTR_ERR(info
->channel_vusb
) == -ENODEV
)
735 return -EPROBE_DEFER
;
736 return PTR_ERR(info
->channel_vusb
);
739 info
->channel_vadp
= devm_iio_channel_get(&pdev
->dev
, "vadp");
740 if (IS_ERR(info
->channel_vadp
)) {
741 if (PTR_ERR(info
->channel_vadp
) == -ENODEV
)
742 return -EPROBE_DEFER
;
743 return PTR_ERR(info
->channel_vadp
);
746 ret
= regmap_read(info
->rn5t618
->regmap
, RN5T618_CONTROL
, &v
);
750 if (!(v
& FG_ENABLE
)) {
751 /* E.g. the vendor kernels of various Kobo and Tolino Ebook
752 * readers disable the fuel gauge on shutdown. If a kernel
753 * without fuel gauge support is booted after that, the fuel
754 * gauge will get decalibrated.
756 dev_info(&pdev
->dev
, "Fuel gauge not enabled, enabling now\n");
757 dev_info(&pdev
->dev
, "Expect imprecise results\n");
758 regmap_update_bits(info
->rn5t618
->regmap
, RN5T618_CONTROL
,
759 FG_ENABLE
, FG_ENABLE
);
762 psy_cfg
.drv_data
= info
;
763 info
->battery
= devm_power_supply_register(&pdev
->dev
,
764 &rn5t618_battery_desc
,
766 if (IS_ERR(info
->battery
)) {
767 ret
= PTR_ERR(info
->battery
);
768 dev_err(&pdev
->dev
, "failed to register battery: %d\n", ret
);
772 info
->adp
= devm_power_supply_register(&pdev
->dev
,
775 if (IS_ERR(info
->adp
)) {
776 ret
= PTR_ERR(info
->adp
);
777 dev_err(&pdev
->dev
, "failed to register adp: %d\n", ret
);
781 info
->usb
= devm_power_supply_register(&pdev
->dev
,
784 if (IS_ERR(info
->usb
)) {
785 ret
= PTR_ERR(info
->usb
);
786 dev_err(&pdev
->dev
, "failed to register usb: %d\n", ret
);
790 if (info
->rn5t618
->irq_data
)
791 info
->irq
= regmap_irq_get_virq(info
->rn5t618
->irq_data
,
797 ret
= devm_request_threaded_irq(&pdev
->dev
, info
->irq
, NULL
,
804 dev_err(&pdev
->dev
, "request IRQ:%d fail\n",
813 static struct platform_driver rn5t618_power_driver
= {
815 .name
= "rn5t618-power",
817 .probe
= rn5t618_power_probe
,
820 module_platform_driver(rn5t618_power_driver
);
821 MODULE_ALIAS("platform:rn5t618-power");
822 MODULE_DESCRIPTION("Power supply driver for RICOH RN5T618");
823 MODULE_LICENSE("GPL");