1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for Analog Devices (Linear Technology) LT3651 charger IC.
4 * Copyright (C) 2017, Topic Embedded Products
7 #include <linux/device.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/init.h>
10 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/power_supply.h>
15 #include <linux/slab.h>
18 struct lt3651_charger
{
19 struct power_supply
*charger
;
20 struct power_supply_desc charger_desc
;
21 struct gpio_desc
*acpr_gpio
;
22 struct gpio_desc
*fault_gpio
;
23 struct gpio_desc
*chrg_gpio
;
26 static irqreturn_t
lt3651_charger_irq(int irq
, void *devid
)
28 struct power_supply
*charger
= devid
;
30 power_supply_changed(charger
);
35 static inline struct lt3651_charger
*psy_to_lt3651_charger(
36 struct power_supply
*psy
)
38 return power_supply_get_drvdata(psy
);
41 static int lt3651_charger_get_property(struct power_supply
*psy
,
42 enum power_supply_property psp
, union power_supply_propval
*val
)
44 struct lt3651_charger
*lt3651_charger
= psy_to_lt3651_charger(psy
);
47 case POWER_SUPPLY_PROP_STATUS
:
48 if (!lt3651_charger
->chrg_gpio
) {
49 val
->intval
= POWER_SUPPLY_STATUS_UNKNOWN
;
52 if (gpiod_get_value(lt3651_charger
->chrg_gpio
))
53 val
->intval
= POWER_SUPPLY_STATUS_CHARGING
;
55 val
->intval
= POWER_SUPPLY_STATUS_NOT_CHARGING
;
57 case POWER_SUPPLY_PROP_ONLINE
:
58 val
->intval
= gpiod_get_value(lt3651_charger
->acpr_gpio
);
60 case POWER_SUPPLY_PROP_HEALTH
:
61 if (!lt3651_charger
->fault_gpio
) {
62 val
->intval
= POWER_SUPPLY_HEALTH_UNKNOWN
;
65 if (!gpiod_get_value(lt3651_charger
->fault_gpio
)) {
66 val
->intval
= POWER_SUPPLY_HEALTH_GOOD
;
70 * If the fault pin is active, the chrg pin explains the type
73 if (!lt3651_charger
->chrg_gpio
) {
74 val
->intval
= POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
;
77 val
->intval
= gpiod_get_value(lt3651_charger
->chrg_gpio
) ?
78 POWER_SUPPLY_HEALTH_OVERHEAT
:
79 POWER_SUPPLY_HEALTH_DEAD
;
88 static enum power_supply_property lt3651_charger_properties
[] = {
89 POWER_SUPPLY_PROP_STATUS
,
90 POWER_SUPPLY_PROP_ONLINE
,
91 POWER_SUPPLY_PROP_HEALTH
,
94 static int lt3651_charger_probe(struct platform_device
*pdev
)
96 struct power_supply_config psy_cfg
= {};
97 struct lt3651_charger
*lt3651_charger
;
98 struct power_supply_desc
*charger_desc
;
101 lt3651_charger
= devm_kzalloc(&pdev
->dev
, sizeof(*lt3651_charger
),
106 lt3651_charger
->acpr_gpio
= devm_gpiod_get(&pdev
->dev
,
107 "lltc,acpr", GPIOD_IN
);
108 if (IS_ERR(lt3651_charger
->acpr_gpio
)) {
109 ret
= PTR_ERR(lt3651_charger
->acpr_gpio
);
110 dev_err(&pdev
->dev
, "Failed to acquire acpr GPIO: %d\n", ret
);
113 lt3651_charger
->fault_gpio
= devm_gpiod_get_optional(&pdev
->dev
,
114 "lltc,fault", GPIOD_IN
);
115 if (IS_ERR(lt3651_charger
->fault_gpio
)) {
116 ret
= PTR_ERR(lt3651_charger
->fault_gpio
);
117 dev_err(&pdev
->dev
, "Failed to acquire fault GPIO: %d\n", ret
);
120 lt3651_charger
->chrg_gpio
= devm_gpiod_get_optional(&pdev
->dev
,
121 "lltc,chrg", GPIOD_IN
);
122 if (IS_ERR(lt3651_charger
->chrg_gpio
)) {
123 ret
= PTR_ERR(lt3651_charger
->chrg_gpio
);
124 dev_err(&pdev
->dev
, "Failed to acquire chrg GPIO: %d\n", ret
);
128 charger_desc
= <3651_charger
->charger_desc
;
129 charger_desc
->name
= pdev
->dev
.of_node
->name
;
130 charger_desc
->type
= POWER_SUPPLY_TYPE_MAINS
;
131 charger_desc
->properties
= lt3651_charger_properties
;
132 charger_desc
->num_properties
= ARRAY_SIZE(lt3651_charger_properties
);
133 charger_desc
->get_property
= lt3651_charger_get_property
;
134 psy_cfg
.of_node
= pdev
->dev
.of_node
;
135 psy_cfg
.drv_data
= lt3651_charger
;
137 lt3651_charger
->charger
= devm_power_supply_register(&pdev
->dev
,
138 charger_desc
, &psy_cfg
);
139 if (IS_ERR(lt3651_charger
->charger
)) {
140 ret
= PTR_ERR(lt3651_charger
->charger
);
141 dev_err(&pdev
->dev
, "Failed to register power supply: %d\n",
147 * Acquire IRQs for the GPIO pins if possible. If the system does not
148 * support IRQs on these pins, userspace will have to poll the sysfs
151 if (lt3651_charger
->acpr_gpio
) {
152 ret
= gpiod_to_irq(lt3651_charger
->acpr_gpio
);
154 ret
= devm_request_any_context_irq(&pdev
->dev
, ret
,
156 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
157 dev_name(&pdev
->dev
), lt3651_charger
->charger
);
159 dev_warn(&pdev
->dev
, "Failed to request acpr irq\n");
161 if (lt3651_charger
->fault_gpio
) {
162 ret
= gpiod_to_irq(lt3651_charger
->fault_gpio
);
164 ret
= devm_request_any_context_irq(&pdev
->dev
, ret
,
166 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
167 dev_name(&pdev
->dev
), lt3651_charger
->charger
);
169 dev_warn(&pdev
->dev
, "Failed to request fault irq\n");
171 if (lt3651_charger
->chrg_gpio
) {
172 ret
= gpiod_to_irq(lt3651_charger
->chrg_gpio
);
174 ret
= devm_request_any_context_irq(&pdev
->dev
, ret
,
176 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
,
177 dev_name(&pdev
->dev
), lt3651_charger
->charger
);
179 dev_warn(&pdev
->dev
, "Failed to request chrg irq\n");
182 platform_set_drvdata(pdev
, lt3651_charger
);
187 static const struct of_device_id lt3651_charger_match
[] = {
188 { .compatible
= "lltc,ltc3651-charger" }, /* DEPRECATED */
189 { .compatible
= "lltc,lt3651-charger" },
192 MODULE_DEVICE_TABLE(of
, lt3651_charger_match
);
194 static struct platform_driver lt3651_charger_driver
= {
195 .probe
= lt3651_charger_probe
,
197 .name
= "lt3651-charger",
198 .of_match_table
= lt3651_charger_match
,
202 module_platform_driver(lt3651_charger_driver
);
204 MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
205 MODULE_DESCRIPTION("Driver for LT3651 charger");
206 MODULE_LICENSE("GPL");
207 MODULE_ALIAS("platform:lt3651-charger");