aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2010-10-27 18:33:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-27 21:03:07 -0400
commit459773ae8dbbd480886d186181c6bc2e8556025f (patch)
tree38d738b858105a46a473bcae0958e2ded77a2e21 /drivers/gpio
parentead6db084392349ad33323b1bb2916058dd7e82b (diff)
gpio: adp5588-gpio: support interrupt controller
Implement irq_chip functionality on ADP5588/5587 GPIO expanders. Only level sensitive interrupts are supported. Interrupts provided by this irq_chip must be requested using request_threaded_irq(). Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/Kconfig7
-rw-r--r--drivers/gpio/adp5588-gpio.c277
2 files changed, 263 insertions, 21 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bc7b0fca6415..3f3181dac8d7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -272,6 +272,13 @@ config GPIO_ADP5588
272 To compile this driver as a module, choose M here: the module will be 272 To compile this driver as a module, choose M here: the module will be
273 called adp5588-gpio. 273 called adp5588-gpio.
274 274
275config GPIO_ADP5588_IRQ
276 bool "Interrupt controller support for ADP5588"
277 depends on GPIO_ADP5588=y
278 help
279 Say yes here to enable the adp5588 to be used as an interrupt
280 controller. It requires the driver to be built in the kernel.
281
275comment "PCI GPIO expanders:" 282comment "PCI GPIO expanders:"
276 283
277config GPIO_CS5535 284config GPIO_CS5535
diff --git a/drivers/gpio/adp5588-gpio.c b/drivers/gpio/adp5588-gpio.c
index 2e8e9e24f887..0871f78af593 100644
--- a/drivers/gpio/adp5588-gpio.c
+++ b/drivers/gpio/adp5588-gpio.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * GPIO Chip driver for Analog Devices 2 * GPIO Chip driver for Analog Devices
3 * ADP5588 I/O Expander and QWERTY Keypad Controller 3 * ADP5588/ADP5587 I/O Expander and QWERTY Keypad Controller
4 * 4 *
5 * Copyright 2009 Analog Devices Inc. 5 * Copyright 2009-2010 Analog Devices Inc.
6 * 6 *
7 * Licensed under the GPL-2 or later. 7 * Licensed under the GPL-2 or later.
8 */ 8 */
@@ -13,21 +13,34 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
16 18
17#include <linux/i2c/adp5588.h> 19#include <linux/i2c/adp5588.h>
18 20
19#define DRV_NAME "adp5588-gpio" 21#define DRV_NAME "adp5588-gpio"
20#define MAXGPIO 18 22
21#define ADP_BANK(offs) ((offs) >> 3) 23/*
22#define ADP_BIT(offs) (1u << ((offs) & 0x7)) 24 * Early pre 4.0 Silicon required to delay readout by at least 25ms,
25 * since the Event Counter Register updated 25ms after the interrupt
26 * asserted.
27 */
28#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4)
23 29
24struct adp5588_gpio { 30struct adp5588_gpio {
25 struct i2c_client *client; 31 struct i2c_client *client;
26 struct gpio_chip gpio_chip; 32 struct gpio_chip gpio_chip;
27 struct mutex lock; /* protect cached dir, dat_out */ 33 struct mutex lock; /* protect cached dir, dat_out */
34 /* protect serialized access to the interrupt controller bus */
35 struct mutex irq_lock;
28 unsigned gpio_start; 36 unsigned gpio_start;
37 unsigned irq_base;
29 uint8_t dat_out[3]; 38 uint8_t dat_out[3];
30 uint8_t dir[3]; 39 uint8_t dir[3];
40 uint8_t int_lvl[3];
41 uint8_t int_en[3];
42 uint8_t irq_mask[3];
43 uint8_t irq_stat[3];
31}; 44};
32 45
33static int adp5588_gpio_read(struct i2c_client *client, u8 reg) 46static int adp5588_gpio_read(struct i2c_client *client, u8 reg)
@@ -55,8 +68,8 @@ static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
55 struct adp5588_gpio *dev = 68 struct adp5588_gpio *dev =
56 container_of(chip, struct adp5588_gpio, gpio_chip); 69 container_of(chip, struct adp5588_gpio, gpio_chip);
57 70
58 return !!(adp5588_gpio_read(dev->client, GPIO_DAT_STAT1 + ADP_BANK(off)) 71 return !!(adp5588_gpio_read(dev->client,
59 & ADP_BIT(off)); 72 GPIO_DAT_STAT1 + ADP5588_BANK(off)) & ADP5588_BIT(off));
60} 73}
61 74
62static void adp5588_gpio_set_value(struct gpio_chip *chip, 75static void adp5588_gpio_set_value(struct gpio_chip *chip,
@@ -66,8 +79,8 @@ static void adp5588_gpio_set_value(struct gpio_chip *chip,
66 struct adp5588_gpio *dev = 79 struct adp5588_gpio *dev =
67 container_of(chip, struct adp5588_gpio, gpio_chip); 80 container_of(chip, struct adp5588_gpio, gpio_chip);
68 81
69 bank = ADP_BANK(off); 82 bank = ADP5588_BANK(off);
70 bit = ADP_BIT(off); 83 bit = ADP5588_BIT(off);
71 84
72 mutex_lock(&dev->lock); 85 mutex_lock(&dev->lock);
73 if (val) 86 if (val)
@@ -87,10 +100,10 @@ static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
87 struct adp5588_gpio *dev = 100 struct adp5588_gpio *dev =
88 container_of(chip, struct adp5588_gpio, gpio_chip); 101 container_of(chip, struct adp5588_gpio, gpio_chip);
89 102
90 bank = ADP_BANK(off); 103 bank = ADP5588_BANK(off);
91 104
92 mutex_lock(&dev->lock); 105 mutex_lock(&dev->lock);
93 dev->dir[bank] &= ~ADP_BIT(off); 106 dev->dir[bank] &= ~ADP5588_BIT(off);
94 ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]); 107 ret = adp5588_gpio_write(dev->client, GPIO_DIR1 + bank, dev->dir[bank]);
95 mutex_unlock(&dev->lock); 108 mutex_unlock(&dev->lock);
96 109
@@ -105,8 +118,8 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
105 struct adp5588_gpio *dev = 118 struct adp5588_gpio *dev =
106 container_of(chip, struct adp5588_gpio, gpio_chip); 119 container_of(chip, struct adp5588_gpio, gpio_chip);
107 120
108 bank = ADP_BANK(off); 121 bank = ADP5588_BANK(off);
109 bit = ADP_BIT(off); 122 bit = ADP5588_BIT(off);
110 123
111 mutex_lock(&dev->lock); 124 mutex_lock(&dev->lock);
112 dev->dir[bank] |= bit; 125 dev->dir[bank] |= bit;
@@ -125,6 +138,213 @@ static int adp5588_gpio_direction_output(struct gpio_chip *chip,
125 return ret; 138 return ret;
126} 139}
127 140
141#ifdef CONFIG_GPIO_ADP5588_IRQ
142static int adp5588_gpio_to_irq(struct gpio_chip *chip, unsigned off)
143{
144 struct adp5588_gpio *dev =
145 container_of(chip, struct adp5588_gpio, gpio_chip);
146 return dev->irq_base + off;
147}
148
149static void adp5588_irq_bus_lock(unsigned int irq)
150{
151 struct adp5588_gpio *dev = get_irq_chip_data(irq);
152 mutex_lock(&dev->irq_lock);
153}
154
155 /*
156 * genirq core code can issue chip->mask/unmask from atomic context.
157 * This doesn't work for slow busses where an access needs to sleep.
158 * bus_sync_unlock() is therefore called outside the atomic context,
159 * syncs the current irq mask state with the slow external controller
160 * and unlocks the bus.
161 */
162
163static void adp5588_irq_bus_sync_unlock(unsigned int irq)
164{
165 struct adp5588_gpio *dev = get_irq_chip_data(irq);
166 int i;
167
168 for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++)
169 if (dev->int_en[i] ^ dev->irq_mask[i]) {
170 dev->int_en[i] = dev->irq_mask[i];
171 adp5588_gpio_write(dev->client, GPIO_INT_EN1 + i,
172 dev->int_en[i]);
173 }
174
175 mutex_unlock(&dev->irq_lock);
176}
177
178static void adp5588_irq_mask(unsigned int irq)
179{
180 struct adp5588_gpio *dev = get_irq_chip_data(irq);
181 unsigned gpio = irq - dev->irq_base;
182
183 dev->irq_mask[ADP5588_BANK(gpio)] &= ~ADP5588_BIT(gpio);
184}
185
186static void adp5588_irq_unmask(unsigned int irq)
187{
188 struct adp5588_gpio *dev = get_irq_chip_data(irq);
189 unsigned gpio = irq - dev->irq_base;
190
191 dev->irq_mask[ADP5588_BANK(gpio)] |= ADP5588_BIT(gpio);
192}
193
194static int adp5588_irq_set_type(unsigned int irq, unsigned int type)
195{
196 struct adp5588_gpio *dev = get_irq_chip_data(irq);
197 uint16_t gpio = irq - dev->irq_base;
198 unsigned bank, bit;
199
200 if ((type & IRQ_TYPE_EDGE_BOTH)) {
201 dev_err(&dev->client->dev, "irq %d: unsupported type %d\n",
202 irq, type);
203 return -EINVAL;
204 }
205
206 bank = ADP5588_BANK(gpio);
207 bit = ADP5588_BIT(gpio);
208
209 if (type & IRQ_TYPE_LEVEL_HIGH)
210 dev->int_lvl[bank] |= bit;
211 else if (type & IRQ_TYPE_LEVEL_LOW)
212 dev->int_lvl[bank] &= ~bit;
213 else
214 return -EINVAL;
215
216 adp5588_gpio_direction_input(&dev->gpio_chip, gpio);
217 adp5588_gpio_write(dev->client, GPIO_INT_LVL1 + bank,
218 dev->int_lvl[bank]);
219
220 return 0;
221}
222
223static struct irq_chip adp5588_irq_chip = {
224 .name = "adp5588",
225 .mask = adp5588_irq_mask,
226 .unmask = adp5588_irq_unmask,
227 .bus_lock = adp5588_irq_bus_lock,
228 .bus_sync_unlock = adp5588_irq_bus_sync_unlock,
229 .set_type = adp5588_irq_set_type,
230};
231
232static int adp5588_gpio_read_intstat(struct i2c_client *client, u8 *buf)
233{
234 int ret = i2c_smbus_read_i2c_block_data(client, GPIO_INT_STAT1, 3, buf);
235
236 if (ret < 0)
237 dev_err(&client->dev, "Read INT_STAT Error\n");
238
239 return ret;
240}
241
242static irqreturn_t adp5588_irq_handler(int irq, void *devid)
243{
244 struct adp5588_gpio *dev = devid;
245 unsigned status, bank, bit, pending;
246 int ret;
247 status = adp5588_gpio_read(dev->client, INT_STAT);
248
249 if (status & ADP5588_GPI_INT) {
250 ret = adp5588_gpio_read_intstat(dev->client, dev->irq_stat);
251 if (ret < 0)
252 memset(dev->irq_stat, 0, ARRAY_SIZE(dev->irq_stat));
253
254 for (bank = 0; bank <= ADP5588_BANK(ADP5588_MAXGPIO);
255 bank++, bit = 0) {
256 pending = dev->irq_stat[bank] & dev->irq_mask[bank];
257
258 while (pending) {
259 if (pending & (1 << bit)) {
260 handle_nested_irq(dev->irq_base +
261 (bank << 3) + bit);
262 pending &= ~(1 << bit);
263
264 }
265 bit++;
266 }
267 }
268 }
269
270 adp5588_gpio_write(dev->client, INT_STAT, status); /* Status is W1C */
271
272 return IRQ_HANDLED;
273}
274
275static int adp5588_irq_setup(struct adp5588_gpio *dev)
276{
277 struct i2c_client *client = dev->client;
278 struct adp5588_gpio_platform_data *pdata = client->dev.platform_data;
279 unsigned gpio;
280 int ret;
281
282 adp5588_gpio_write(client, CFG, ADP5588_AUTO_INC);
283 adp5588_gpio_write(client, INT_STAT, -1); /* status is W1C */
284 adp5588_gpio_read_intstat(client, dev->irq_stat); /* read to clear */
285
286 dev->irq_base = pdata->irq_base;
287 mutex_init(&dev->irq_lock);
288
289 for (gpio = 0; gpio < dev->gpio_chip.ngpio; gpio++) {
290 int irq = gpio + dev->irq_base;
291 set_irq_chip_data(irq, dev);
292 set_irq_chip_and_handler(irq, &adp5588_irq_chip,
293 handle_level_irq);
294 set_irq_nested_thread(irq, 1);
295#ifdef CONFIG_ARM
296 /*
297 * ARM needs us to explicitly flag the IRQ as VALID,
298 * once we do so, it will also set the noprobe.
299 */
300 set_irq_flags(irq, IRQF_VALID);
301#else
302 set_irq_noprobe(irq);
303#endif
304 }
305
306 ret = request_threaded_irq(client->irq,
307 NULL,
308 adp5588_irq_handler,
309 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
310 dev_name(&client->dev), dev);
311 if (ret) {
312 dev_err(&client->dev, "failed to request irq %d\n",
313 client->irq);
314 goto out;
315 }
316
317 dev->gpio_chip.to_irq = adp5588_gpio_to_irq;
318 adp5588_gpio_write(client, CFG,
319 ADP5588_AUTO_INC | ADP5588_INT_CFG | ADP5588_GPI_INT);
320
321 return 0;
322
323out:
324 dev->irq_base = 0;
325 return ret;
326}
327
328static void adp5588_irq_teardown(struct adp5588_gpio *dev)
329{
330 if (dev->irq_base)
331 free_irq(dev->client->irq, dev);
332}
333
334#else
335static int adp5588_irq_setup(struct adp5588_gpio *dev)
336{
337 struct i2c_client *client = dev->client;
338 dev_warn(&client->dev, "interrupt support not compiled in\n");
339
340 return 0;
341}
342
343static void adp5588_irq_teardown(struct adp5588_gpio *dev)
344{
345}
346#endif /* CONFIG_GPIO_ADP5588_IRQ */
347
128static int __devinit adp5588_gpio_probe(struct i2c_client *client, 348static int __devinit adp5588_gpio_probe(struct i2c_client *client,
129 const struct i2c_device_id *id) 349 const struct i2c_device_id *id)
130{ 350{
@@ -160,37 +380,46 @@ static int __devinit adp5588_gpio_probe(struct i2c_client *client,
160 gc->can_sleep = 1; 380 gc->can_sleep = 1;
161 381
162 gc->base = pdata->gpio_start; 382 gc->base = pdata->gpio_start;
163 gc->ngpio = MAXGPIO; 383 gc->ngpio = ADP5588_MAXGPIO;
164 gc->label = client->name; 384 gc->label = client->name;
165 gc->owner = THIS_MODULE; 385 gc->owner = THIS_MODULE;
166 386
167 mutex_init(&dev->lock); 387 mutex_init(&dev->lock);
168 388
169
170 ret = adp5588_gpio_read(dev->client, DEV_ID); 389 ret = adp5588_gpio_read(dev->client, DEV_ID);
171 if (ret < 0) 390 if (ret < 0)
172 goto err; 391 goto err;
173 392
174 revid = ret & ADP5588_DEVICE_ID_MASK; 393 revid = ret & ADP5588_DEVICE_ID_MASK;
175 394
176 for (i = 0, ret = 0; i <= ADP_BANK(MAXGPIO); i++) { 395 for (i = 0, ret = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
177 dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i); 396 dev->dat_out[i] = adp5588_gpio_read(client, GPIO_DAT_OUT1 + i);
178 dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i); 397 dev->dir[i] = adp5588_gpio_read(client, GPIO_DIR1 + i);
179 ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0); 398 ret |= adp5588_gpio_write(client, KP_GPIO1 + i, 0);
180 ret |= adp5588_gpio_write(client, GPIO_PULL1 + i, 399 ret |= adp5588_gpio_write(client, GPIO_PULL1 + i,
181 (pdata->pullup_dis_mask >> (8 * i)) & 0xFF); 400 (pdata->pullup_dis_mask >> (8 * i)) & 0xFF);
182 401 ret |= adp5588_gpio_write(client, GPIO_INT_EN1 + i, 0);
183 if (ret) 402 if (ret)
184 goto err; 403 goto err;
185 } 404 }
186 405
406 if (pdata->irq_base) {
407 if (WA_DELAYED_READOUT_REVID(revid)) {
408 dev_warn(&client->dev, "GPIO int not supported\n");
409 } else {
410 ret = adp5588_irq_setup(dev);
411 if (ret)
412 goto err;
413 }
414 }
415
187 ret = gpiochip_add(&dev->gpio_chip); 416 ret = gpiochip_add(&dev->gpio_chip);
188 if (ret) 417 if (ret)
189 goto err; 418 goto err_irq;
190 419
191 dev_info(&client->dev, "gpios %d..%d on a %s Rev. %d\n", 420 dev_info(&client->dev, "gpios %d..%d (IRQ Base %d) on a %s Rev. %d\n",
192 gc->base, gc->base + gc->ngpio - 1, 421 gc->base, gc->base + gc->ngpio - 1,
193 client->name, revid); 422 pdata->irq_base, client->name, revid);
194 423
195 if (pdata->setup) { 424 if (pdata->setup) {
196 ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context); 425 ret = pdata->setup(client, gc->base, gc->ngpio, pdata->context);
@@ -199,8 +428,11 @@ static int __devinit adp5588_gpio_probe(struct i2c_client *client,
199 } 428 }
200 429
201 i2c_set_clientdata(client, dev); 430 i2c_set_clientdata(client, dev);
431
202 return 0; 432 return 0;
203 433
434err_irq:
435 adp5588_irq_teardown(dev);
204err: 436err:
205 kfree(dev); 437 kfree(dev);
206 return ret; 438 return ret;
@@ -222,6 +454,9 @@ static int __devexit adp5588_gpio_remove(struct i2c_client *client)
222 } 454 }
223 } 455 }
224 456
457 if (dev->irq_base)
458 free_irq(dev->client->irq, dev);
459
225 ret = gpiochip_remove(&dev->gpio_chip); 460 ret = gpiochip_remove(&dev->gpio_chip);
226 if (ret) { 461 if (ret) {
227 dev_err(&client->dev, "gpiochip_remove failed %d\n", ret); 462 dev_err(&client->dev, "gpiochip_remove failed %d\n", ret);