Add 2.6.34 patches
[openwrt/openwrt.git] / target / linux / xburst / patches-2.6.34 / 106-gpio-charger.patch
1 From fc2a5da7117de38ddb538fb7c9907ec1aeb386ba 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 | 184 ++++++++++++++++++++++++++++++++++++
10 include/linux/power/gpio-charger.h | 28 ++++++
11 4 files changed, 220 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 2f4e51f..81d13b8 100644
17 --- a/drivers/power/Kconfig
18 +++ b/drivers/power/Kconfig
19 @@ -142,4 +142,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 3b6b971..8deb992 100644
33 --- a/drivers/power/Makefile
34 +++ b/drivers/power/Makefile
35 @@ -33,3 +33,4 @@ obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
36 obj-$(CONFIG_BATTERY_MAX17040) += max17040_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..7a84994
43 --- /dev/null
44 +++ b/drivers/power/gpio-charger.c
45 @@ -0,0 +1,184 @@
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 + ret = power_supply_register(&pdev->dev, charger);
166 + if (ret < 0) {
167 + dev_err(&pdev->dev, "Failed to register power supply: %d\n", ret);
168 + goto err_gpio_free;
169 + }
170 +
171 + gpio_charger->pdata = pdata;
172 + platform_set_drvdata(pdev, gpio_charger);
173 +
174 + return 0;
175 +
176 +err_gpio_free:
177 + if (gpio_is_valid(pdata->gpio)) {
178 + if (gpio_charger->irq >= 0)
179 + free_irq(gpio_charger->irq, charger);
180 + gpio_free(pdata->gpio);
181 + }
182 +err:
183 + return ret;
184 +}
185 +
186 +static int __devexit gpio_charger_remove(struct platform_device *pdev)
187 +{
188 + struct gpio_charger *gpio_charger = platform_get_drvdata(pdev);
189 + const struct gpio_charger_platform_data *pdata = gpio_charger->pdata;
190 +
191 + power_supply_unregister(&gpio_charger->charger);
192 +
193 + if (gpio_is_valid(pdata->gpio)) {
194 + if (gpio_charger->irq >= 0)
195 + free_irq(gpio_charger->irq, &gpio_charger->charger);
196 + gpio_free(pdata->gpio);
197 + }
198 +
199 + platform_set_drvdata(pdev, NULL);
200 + kfree(gpio_charger);
201 +
202 + return 0;
203 +}
204 +
205 +static struct platform_driver gpio_charger_driver = {
206 + .probe = gpio_charger_probe,
207 + .remove = __devexit_p(gpio_charger_remove),
208 + .driver = {
209 + .name = "gpio-charger",
210 + .owner = THIS_MODULE,
211 + },
212 +};
213 +
214 +static int __init gpio_charger_init(void)
215 +{
216 + return platform_driver_register(&gpio_charger_driver);
217 +}
218 +module_init(gpio_charger_init);
219 +
220 +static void __exit gpio_charger_exit(void)
221 +{
222 + platform_driver_unregister(&gpio_charger_driver);
223 +}
224 +module_exit(gpio_charger_exit);
225 +
226 +MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
227 +MODULE_DESCRIPTION("Driver for chargers indicating their status through a gpio");
228 +MODULE_LICENSE("GPL");
229 +MODULE_ALIAS("platform:gpio-charger");
230 diff --git a/include/linux/power/gpio-charger.h b/include/linux/power/gpio-charger.h
231 new file mode 100644
232 index 0000000..95cdfc3
233 --- /dev/null
234 +++ b/include/linux/power/gpio-charger.h
235 @@ -0,0 +1,28 @@
236 +/*
237 + * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
238 + *
239 + * This program is free software; you can redistribute it and/or modify it
240 + * under the terms of the GNU General Public License as published by the
241 + * Free Software Foundation; either version 2 of the License, or (at your
242 + * option) any later version.
243 + *
244 + * You should have received a copy of the GNU General Public License along
245 + * with this program; if not, write to the Free Software Foundation, Inc.,
246 + * 675 Mass Ave, Cambridge, MA 02139, USA.
247 + *
248 + */
249 +
250 +#ifndef __LINUX_POWER_GPIO_CHARGER_H__
251 +#define __LINUX_POWER_GPIO_CHARGER_H__
252 +
253 +struct gpio_charger_platform_data {
254 + const char *name;
255 + enum power_supply_type type;
256 + int gpio;
257 + int gpio_active_low;
258 +
259 + char **batteries;
260 + size_t num_batteries;
261 +};
262 +
263 +#endif
264 --
265 1.5.6.5
266