gpio: palmas: fix compilation failures
[linux-2.6.git] / drivers / gpio / gpio-palmas.c
1 /*
2  * gpiolib support for Palmas Series PMICS
3  *
4  * Copyright 2011 Texas Instruments
5  *
6  * Author: Graeme Gregory <gg@slimlogic.co.uk>
7  *
8  * Based on gpio-wm831x.c
9  *
10  * Copyright 2009 Wolfson Microelectronics PLC.
11  *
12  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
13  *
14  *  This program is free software; you can redistribute  it and/or modify it
15  *  under  the terms of  the GNU General  Public License as published by the
16  *  Free Software Foundation;  either version 2 of the  License, or (at your
17  *  option) any later version.
18  *
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/slab.h>
23 #include <linux/module.h>
24 #include <linux/gpio.h>
25 #include <linux/mfd/core.h>
26 #include <linux/platform_device.h>
27 #include <linux/seq_file.h>
28
29 #include <linux/mfd/palmas.h>
30
31 struct palmas_gpio {
32         struct palmas *palmas;
33         struct gpio_chip gpio_chip;
34 };
35
36 #define GPIO_SLAVE      PALMAS_BASE_TO_SLAVE(PALMAS_GPIO_BASE)
37
38 int palmas_gpio_read(struct palmas *palmas, unsigned int reg,
39                                 unsigned int *dest)
40 {
41         unsigned int addr;
42         addr = PALMAS_BASE_TO_REG(PALMAS_GPIO_BASE, reg);
43
44         return regmap_read(palmas->regmap[GPIO_SLAVE], addr, dest);
45 }
46
47 int palmas_gpio_write(struct palmas *palmas, unsigned int reg,
48                                 unsigned int value)
49 {
50         unsigned int addr;
51         addr = PALMAS_BASE_TO_REG(PALMAS_GPIO_BASE, reg);
52
53         return regmap_write(palmas->regmap[GPIO_SLAVE], addr, value);
54 }
55
56 static inline struct palmas_gpio *to_palmas_gpio(struct gpio_chip *chip)
57 {
58         return container_of(chip, struct palmas_gpio, gpio_chip);
59 }
60
61 static int palmas_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
62 {
63         struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
64         struct palmas *palmas = palmas_gpio->palmas;
65         int ret;
66         unsigned int reg = 0;
67
68         if (!((1 << offset) & palmas->gpio_muxed))
69                 return -EINVAL;
70
71         ret = palmas_gpio_read(palmas, PALMAS_GPIO_DATA_DIR, &reg);
72         if (ret)
73                 return ret;
74
75         reg &= ~(1 << offset);
76
77         return palmas_gpio_write(palmas, PALMAS_GPIO_DATA_DIR, reg);
78 }
79
80 static int palmas_gpio_get(struct gpio_chip *chip, unsigned offset)
81 {
82         struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
83         struct palmas *palmas = palmas_gpio->palmas;
84         unsigned int reg = 0;
85
86         if (!((1 << offset) & palmas->gpio_muxed))
87                 return 0;
88
89         palmas_gpio_read(palmas, PALMAS_GPIO_DATA_IN, &reg);
90
91         return !!(reg & (1 << offset));
92 }
93
94 static void palmas_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
95 {
96         struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
97         struct palmas *palmas = palmas_gpio->palmas;
98         unsigned int reg;
99
100         if (!((1 << offset) & palmas->gpio_muxed))
101                 return;
102
103         palmas_gpio_read(palmas, PALMAS_GPIO_DATA_OUT, &reg);
104
105         reg &= ~(1 << offset);
106         reg |= value << offset;
107
108         palmas_gpio_write(palmas, PALMAS_GPIO_DATA_OUT, reg);
109 }
110
111 static int palmas_gpio_direction_out(struct gpio_chip *chip,
112                                      unsigned offset, int value)
113 {
114         struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
115         struct palmas *palmas = palmas_gpio->palmas;
116         int ret;
117         unsigned int reg;
118
119         if (!((1 << offset) & palmas->gpio_muxed))
120                 return -EINVAL;
121
122         ret = palmas_gpio_read(palmas, PALMAS_GPIO_DATA_DIR, &reg);
123         if (ret)
124                 return ret;
125
126         reg |= 1 << offset;
127
128         return palmas_gpio_write(palmas, PALMAS_GPIO_DATA_DIR, reg);
129 }
130
131 static int palmas_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
132 {
133         struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
134         struct palmas *palmas = palmas_gpio->palmas;
135
136         if (!regmap_irq_chip_get_base(palmas->irq_data))
137                 return -EINVAL;
138
139         return (regmap_irq_chip_get_base(palmas->irq_data))
140                                 + PALMAS_GPIO_0_IRQ + offset;
141 }
142
143 static int palmas_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
144                                     unsigned debounce)
145 {
146         struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
147         struct palmas *palmas = palmas_gpio->palmas;
148         int ret;
149         unsigned int reg;
150
151         if (!((1 << offset) & palmas->gpio_muxed))
152                 return -EINVAL;
153
154         ret = palmas_gpio_read(palmas, PALMAS_GPIO_DATA_DIR, &reg);
155         if (ret)
156                 return ret;
157
158         if (debounce)
159                 reg |= 1 << offset;
160         else
161                 reg &= ~(1 << offset);
162
163         return palmas_gpio_write(palmas, PALMAS_GPIO_DATA_DIR, reg);
164 }
165
166 static struct gpio_chip palmas_gpio_chip = {
167         .label                  = "palmas",
168         .owner                  = THIS_MODULE,
169         .direction_input        = palmas_gpio_direction_in,
170         .get                    = palmas_gpio_get,
171         .direction_output       = palmas_gpio_direction_out,
172         .set                    = palmas_gpio_set,
173         .to_irq                 = palmas_gpio_to_irq,
174         .set_debounce           = palmas_gpio_set_debounce,
175         .can_sleep              = 1,
176         .ngpio                  = 8,
177 };
178
179 static int __devinit palmas_gpio_probe(struct platform_device *pdev)
180 {
181         struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
182         struct palmas_platform_data *pdata = palmas->dev->platform_data;
183         struct palmas_gpio *gpio;
184         int ret;
185
186         gpio = kzalloc(sizeof(*gpio), GFP_KERNEL);
187         if (!gpio)
188                 return -ENOMEM;
189
190         gpio->palmas = palmas;
191         gpio->gpio_chip = palmas_gpio_chip;
192         gpio->gpio_chip.dev = &pdev->dev;
193
194         if (pdata && pdata->gpio_base)
195                 gpio->gpio_chip.base = pdata->gpio_base;
196         else
197                 gpio->gpio_chip.base = -1;
198
199         ret = gpiochip_add(&gpio->gpio_chip);
200         if (ret < 0) {
201                 dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
202                         ret);
203                 goto err;
204         }
205
206         platform_set_drvdata(pdev, gpio);
207
208         return ret;
209
210 err:
211         kfree(gpio);
212         return ret;
213 }
214
215 static int __devexit palmas_gpio_remove(struct platform_device *pdev)
216 {
217         struct palmas_gpio *gpio = platform_get_drvdata(pdev);
218         int ret;
219
220         ret = gpiochip_remove(&gpio->gpio_chip);
221         if (ret == 0)
222                 kfree(gpio);
223
224         return ret;
225 }
226
227 static struct platform_driver palmas_gpio_driver = {
228         .driver.name    = "palmas-gpio",
229         .driver.owner   = THIS_MODULE,
230         .probe          = palmas_gpio_probe,
231         .remove         = __devexit_p(palmas_gpio_remove),
232 };
233
234 static int __init palmas_gpio_init(void)
235 {
236         return platform_driver_register(&palmas_gpio_driver);
237 }
238 subsys_initcall(palmas_gpio_init);
239
240 static void __exit palmas_gpio_exit(void)
241 {
242         platform_driver_unregister(&palmas_gpio_driver);
243 }
244 module_exit(palmas_gpio_exit);
245
246 MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
247 MODULE_DESCRIPTION("GPIO interface for the Palmas series chips");
248 MODULE_LICENSE("GPL");
249 MODULE_ALIAS("platform:palmas-gpio");