f04f918cac72117799e2a292357e299cd5e19f68
[openwrt.git] / target / linux / xburst / patches-2.6.35 / 106-gpio-charger.patch
1 From 97d812a16359f6c9afd2f866176828a7e6e071dc Mon Sep 17 00:00:00 2001
2 From: Lars-Peter Clausen <lars@metafoo.de>
3 Date: Sat, 24 Apr 2010 12:29:31 +0200
4 Subject: [PATCH] Add gpio chager driver
5
6 ---
7 drivers/power/Kconfig | 7 ++
8 drivers/power/Makefile | 1 +
9 drivers/power/gpio-charger.c | 185 ++++++++++++++++++++++++++++++++++++
10 include/linux/power/gpio-charger.h | 28 ++++++
11 4 files changed, 221 insertions(+), 0 deletions(-)
12 create mode 100644 drivers/power/gpio-charger.c
13 create mode 100644 include/linux/power/gpio-charger.h
14
15 diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
16 index 1e5506b..f700b03 100644
17 --- a/drivers/power/Kconfig
18 +++ b/drivers/power/Kconfig
19 @@ -153,4 +153,11 @@ config BATTERY_JZ4740
20 This driver can be build as a module. If so, the module will be
21 called jz4740-battery.
22
23 +config CHARGER_GPIO
24 + tristate "GPIO charger"
25 + depends on GPIOLIB
26 + help
27 + Say Y to include support for chargers indicating their status through
28 + a GPIO pin.
29 +
30 endif # POWER_SUPPLY
31 diff --git a/drivers/power/Makefile b/drivers/power/Makefile
32 index cf95009..51be41a 100644
33 --- a/drivers/power/Makefile
34 +++ b/drivers/power/Makefile
35 @@ -35,3 +35,4 @@ obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
36 obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
37 obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
38 obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
39 +obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
40 diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c
41 new file mode 100644
42 index 0000000..b877f74
43 --- /dev/null
44 +++ b/drivers/power/gpio-charger.c
45 @@ -0,0 +1,185 @@
46 +/*
47 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
48 + * Driver for chargers indicating their status through a GPIO pin
49 + *
50 + * This program is free software; you can redistribute it and/or modify it
51 + * under the terms of the GNU General Public License as published by the
52 + * Free Software Foundation; either version 2 of the License, or (at your
53 + * option) any later version.
54 + *
55 + * You should have received a copy of the GNU General Public License along
56 + * with this program; if not, write to the Free Software Foundation, Inc.,
57 + * 675 Mass Ave, Cambridge, MA 02139, USA.
58 + *
59 + */
60 +
61 +#include <linux/device.h>
62 +#include <linux/gpio.h>
63 +#include <linux/init.h>
64 +#include <linux/interrupt.h>
65 +#include <linux/kernel.h>
66 +#include <linux/module.h>
67 +#include <linux/platform_device.h>
68 +#include <linux/power_supply.h>
69 +#include <linux/slab.h>
70 +#include <linux/types.h>
71 +
72 +#include <linux/power/gpio-charger.h>
73 +
74 +struct gpio_charger {
75 + const struct gpio_charger_platform_data *pdata;
76 +
77 + int irq;
78 +
79 + struct power_supply charger;
80 +};
81 +
82 +static irqreturn_t gpio_charger_irq(int irq, void *devid)
83 +{
84 + struct power_supply *charger = devid;
85 + power_supply_changed(charger);
86 +
87 + return IRQ_HANDLED;
88 +}
89 +
90 +static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy)
91 +{
92 + return container_of(psy, struct gpio_charger, charger);
93 +}
94 +
95 +static int gpio_charger_get_property(struct power_supply *psy,
96 + enum power_supply_property psp, union power_supply_propval *val)
97 +{
98 + struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy);
99 + const struct gpio_charger_platform_data *pdata = gpio_charger->pdata;
100 +
101 + switch (psp) {
102 + case POWER_SUPPLY_PROP_ONLINE:
103 + val->intval = gpio_get_value(pdata->gpio);
104 + val->intval ^= pdata->gpio_active_low;
105 + break;
106 + default:
107 + return -EINVAL;
108 + }
109 +
110 + return 0;
111 +}
112 +
113 +static enum power_supply_property gpio_charger_properties[] = {
114 + POWER_SUPPLY_PROP_ONLINE,
115 +};
116 +
117 +static int __devinit gpio_charger_probe(struct platform_device *pdev)
118 +{
119 + const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data;
120 + struct gpio_charger *gpio_charger;
121 + struct power_supply *charger;
122 + int ret;
123 +
124 + if (!pdata) {
125 + dev_err(&pdev->dev, "No platform data");
126 + return -EINVAL;
127 + }
128 +
129 + gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL);
130 +
131 + charger = &gpio_charger->charger;
132 +
133 + charger->name = pdata->name;
134 + charger->type = pdata->type;
135 + charger->properties = gpio_charger_properties;
136 + charger->num_properties = ARRAY_SIZE(gpio_charger_properties);
137 + charger->get_property = gpio_charger_get_property;
138 + charger->supplied_to = pdata->batteries;
139 + charger->num_supplicants = pdata->num_batteries;
140 +
141 + if (gpio_is_valid(pdata->gpio)) {
142 + ret = gpio_request(pdata->gpio, dev_name(&pdev->dev));
143 + if (ret) {
144 + dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret);
145 + goto err;
146 + }
147 + ret = gpio_direction_input(pdata->gpio);
148 + if (ret) {
149 + dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret);
150 + goto err_gpio_free;
151 + }
152 +
153 + gpio_charger->irq = gpio_to_irq(pdata->gpio);
154 + if (gpio_charger->irq >= 0) {
155 + ret = request_irq(gpio_charger->irq, gpio_charger_irq,
156 + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
157 + dev_name(&pdev->dev), charger);
158 + if (ret) {
159 + dev_warn(&pdev->dev, "Failed to request online gpio irq: %d\n", ret);
160 + gpio_charger->irq = -1;
161 + }
162 + }
163 + }
164 +
165 + gpio_charger->pdata = pdata;
166 +
167 + ret = power_supply_register(&pdev->dev, charger);
168 + if (ret < 0) {
169 + dev_err(&pdev->dev, "Failed to register power supply: %d\n", ret);
170 + goto err_gpio_free;
171 + }
172 +
173 + platform_set_drvdata(pdev, gpio_charger);
174 +
175 + return 0;
176 +
177 +err_gpio_free:
178 + if (gpio_is_valid(pdata->gpio)) {
179 + if (gpio_charger->irq >= 0)
180 + free_irq(gpio_charger->irq, charger);
181 + gpio_free(pdata->gpio);
182 + }
183 +err:
184 + return ret;
185 +}
186 +
187 +static int __devexit gpio_charger_remove(struct platform_device *pdev)
188 +{
189 + struct gpio_charger *gpio_charger = platform_get_drvdata(pdev);
190 + const struct gpio_charger_platform_data *pdata = gpio_charger->pdata;
191 +
192 + power_supply_unregister(&gpio_charger->charger);
193 +
194 + if (gpio_is_valid(pdata->gpio)) {
195 + if (gpio_charger->irq >= 0)
196 + free_irq(gpio_charger->irq, &gpio_charger->charger);
197 + gpio_free(pdata->gpio);
198 + }
199 +
200 + platform_set_drvdata(pdev, NULL);
201 + kfree(gpio_charger);
202 +
203 + return 0;
204 +}
205 +
206 +static struct platform_driver gpio_charger_driver = {
207 + .probe = gpio_charger_probe,
208 + .remove = __devexit_p(gpio_charger_remove),
209 + .driver = {
210 + .name = "gpio-charger",
211 + .owner = THIS_MODULE,
212 + },
213 +};
214 +
215 +static int __init gpio_charger_init(void)
216 +{
217 + return platform_driver_register(&gpio_charger_driver);
218 +}
219 +module_init(gpio_charger_init);
220 +
221 +static void __exit gpio_charger_exit(void)
222 +{
223 + platform_driver_unregister(&gpio_charger_driver);
224 +}
225 +module_exit(gpio_charger_exit);
226 +
227 +MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
228 +MODULE_DESCRIPTION("Driver for chargers indicating their status through a gpio");
229 +MODULE_LICENSE("GPL");
230 +MODULE_ALIAS("platform:gpio-charger");
231 diff --git a/include/linux/power/gpio-charger.h b/include/linux/power/gpio-charger.h
232 new file mode 100644
233 index 0000000..95cdfc3
234 --- /dev/null
235 +++ b/include/linux/power/gpio-charger.h
236 @@ -0,0 +1,28 @@
237 +/*
238 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
239 + *
240 + * This program is free software; you can redistribute it and/or modify it
241 + * under the terms of the GNU General Public License as published by the
242 + * Free Software Foundation; either version 2 of the License, or (at your
243 + * option) any later version.
244 + *
245 + * You should have received a copy of the GNU General Public License along
246 + * with this program; if not, write to the Free Software Foundation, Inc.,
247 + * 675 Mass Ave, Cambridge, MA 02139, USA.
248 + *
249 + */
250 +
251 +#ifndef __LINUX_POWER_GPIO_CHARGER_H__
252 +#define __LINUX_POWER_GPIO_CHARGER_H__
253 +
254 +struct gpio_charger_platform_data {
255 + const char *name;
256 + enum power_supply_type type;
257 + int gpio;
258 + int gpio_active_low;
259 +
260 + char **batteries;
261 + size_t num_batteries;
262 +};
263 +
264 +#endif
265 --
266 1.5.6.5
267
This page took 0.056867 seconds and 3 git commands to generate.