2 * Copyright (C) 2017, Topic Embedded Products
3 * Driver for LTC3651 charger IC.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
11 #include <linux/device.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/power_supply.h>
19 #include <linux/slab.h>
22 struct ltc3651_charger
{
23 struct power_supply
*charger
;
24 struct power_supply_desc charger_desc
;
25 struct gpio_desc
*acpr_gpio
;
26 struct gpio_desc
*fault_gpio
;
27 struct gpio_desc
*chrg_gpio
;
30 static irqreturn_t
ltc3651_charger_irq(int irq
, void *devid
)
32 struct power_supply
*charger
= devid
;
34 power_supply_changed(charger
);
39 static inline struct ltc3651_charger
*psy_to_ltc3651_charger(
40 struct power_supply
*psy
)
42 return power_supply_get_drvdata(psy
);
45 static int ltc3651_charger_get_property(struct power_supply
*psy
,
46 enum power_supply_property psp
, union power_supply_propval
*val
)
48 struct ltc3651_charger
*ltc3651_charger
= psy_to_ltc3651_charger(psy
);
51 case POWER_SUPPLY_PROP_STATUS
:
52 if (!ltc3651_charger
->chrg_gpio
) {
53 val
->intval
= POWER_SUPPLY_STATUS_UNKNOWN
;
56 if (gpiod_get_value(ltc3651_charger
->chrg_gpio
))
57 val
->intval
= POWER_SUPPLY_STATUS_CHARGING
;
59 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
61 case POWER_SUPPLY_PROP_ONLINE
:
62 val
->intval
= gpiod_get_value(ltc3651_charger
->acpr_gpio
);
64 case POWER_SUPPLY_PROP_HEALTH
:
65 if (!ltc3651_charger
->fault_gpio
) {
66 val
->intval
= POWER_SUPPLY_HEALTH_UNKNOWN
;
69 if (!gpiod_get_value(ltc3651_charger
->fault_gpio
)) {
70 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
74 * If the fault pin is active, the chrg pin explains the type
77 if (!ltc3651_charger
->chrg_gpio
) {
78 val
->intval
= POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
;
81 val
->intval
= gpiod_get_value(ltc3651_charger
->chrg_gpio
) ?
82 POWER_SUPPLY_HEALTH_OVERHEAT
:
83 POWER_SUPPLY_HEALTH_DEAD
;
92 static enum power_supply_property ltc3651_charger_properties
[] = {
93 POWER_SUPPLY_PROP_STATUS
,
94 POWER_SUPPLY_PROP_ONLINE
,
95 POWER_SUPPLY_PROP_HEALTH
,
98 static int ltc3651_charger_probe(struct platform_device
*pdev
)
100 struct power_supply_config psy_cfg
= {};
101 struct ltc3651_charger
*ltc3651_charger
;
102 struct power_supply_desc
*charger_desc
;
105 ltc3651_charger
= devm_kzalloc(&pdev
->dev
, sizeof(*ltc3651_charger
),
107 if (!ltc3651_charger
)
110 ltc3651_charger
->acpr_gpio
= devm_gpiod_get(&pdev
->dev
,
111 "lltc,acpr", GPIOD_IN
);
112 if (IS_ERR(ltc3651_charger
->acpr_gpio
)) {
113 ret
= PTR_ERR(ltc3651_charger
->acpr_gpio
);
114 dev_err(&pdev
->dev
, "Failed to acquire acpr GPIO: %d\n", ret
);
117 ltc3651_charger
->fault_gpio
= devm_gpiod_get_optional(&pdev
->dev
,
118 "lltc,fault", GPIOD_IN
);
119 if (IS_ERR(ltc3651_charger
->fault_gpio
)) {
120 ret
= PTR_ERR(ltc3651_charger
->fault_gpio
);
121 dev_err(&pdev
->dev
, "Failed to acquire fault GPIO: %d\n", ret
);
124 ltc3651_charger
->chrg_gpio
= devm_gpiod_get_optional(&pdev
->dev
,
125 "lltc,chrg", GPIOD_IN
);
126 if (IS_ERR(ltc3651_charger
->chrg_gpio
)) {
127 ret
= PTR_ERR(ltc3651_charger
->chrg_gpio
);
128 dev_err(&pdev
->dev
, "Failed to acquire chrg GPIO: %d\n", ret
);
132 charger_desc
= <c3651_charger
->charger_desc
;
133 charger_desc
->name
= pdev
->dev
.of_node
->name
;
134 charger_desc
->type
= POWER_SUPPLY_TYPE_MAINS
;
135 charger_desc
->properties
= ltc3651_charger_properties
;
136 charger_desc
->num_properties
= ARRAY_SIZE(ltc3651_charger_properties
);
137 charger_desc
->get_property
= ltc3651_charger_get_property
;
138 psy_cfg
.of_node
= pdev
->dev
.of_node
;
139 psy_cfg
.drv_data
= ltc3651_charger
;
141 ltc3651_charger
->charger
= devm_power_supply_register(&pdev
->dev
,
142 charger_desc
, &psy_cfg
);
143 if (IS_ERR(ltc3651_charger
->charger
)) {
144 ret
= PTR_ERR(ltc3651_charger
->charger
);
145 dev_err(&pdev
->dev
, "Failed to register power supply: %d\n",
151 * Acquire IRQs for the GPIO pins if possible. If the system does not
152 * support IRQs on these pins, userspace will have to poll the sysfs
155 if (ltc3651_charger
->acpr_gpio
) {
156 ret
= gpiod_to_irq(ltc3651_charger
->acpr_gpio
);
158 ret
= devm_request_any_context_irq(&pdev
->dev
, ret
,
160 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
161 dev_name(&pdev
->dev
), ltc3651_charger
->charger
);
163 dev_warn(&pdev
->dev
, "Failed to request acpr irq\n");
165 if (ltc3651_charger
->fault_gpio
) {
166 ret
= gpiod_to_irq(ltc3651_charger
->fault_gpio
);
168 ret
= devm_request_any_context_irq(&pdev
->dev
, ret
,
170 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
171 dev_name(&pdev
->dev
), ltc3651_charger
->charger
);
173 dev_warn(&pdev
->dev
, "Failed to request fault irq\n");
175 if (ltc3651_charger
->chrg_gpio
) {
176 ret
= gpiod_to_irq(ltc3651_charger
->chrg_gpio
);
178 ret
= devm_request_any_context_irq(&pdev
->dev
, ret
,
180 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
181 dev_name(&pdev
->dev
), ltc3651_charger
->charger
);
183 dev_warn(&pdev
->dev
, "Failed to request chrg irq\n");
186 platform_set_drvdata(pdev
, ltc3651_charger
);
191 static const struct of_device_id ltc3651_charger_match
[] = {
192 { .compatible
= "lltc,ltc3651-charger" },
195 MODULE_DEVICE_TABLE(of
, ltc3651_charger_match
);
197 static struct platform_driver ltc3651_charger_driver
= {
198 .probe
= ltc3651_charger_probe
,
200 .name
= "ltc3651-charger",
201 .of_match_table
= ltc3651_charger_match
,
205 module_platform_driver(ltc3651_charger_driver
);
207 MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
208 MODULE_DESCRIPTION("Driver for LTC3651 charger");
209 MODULE_LICENSE("GPL");
210 MODULE_ALIAS("platform:ltc3651-charger");