aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/pca953x.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpio/pca953x.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/gpio/pca953x.c')
-rw-r--r--drivers/gpio/pca953x.c262
1 files changed, 250 insertions, 12 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 6a2fb3fbb3d9..b827c976dc62 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -14,8 +14,11 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17#include <linux/interrupt.h>
18#include <linux/irq.h>
17#include <linux/i2c.h> 19#include <linux/i2c.h>
18#include <linux/i2c/pca953x.h> 20#include <linux/i2c/pca953x.h>
21#include <linux/slab.h>
19#ifdef CONFIG_OF_GPIO 22#ifdef CONFIG_OF_GPIO
20#include <linux/of_platform.h> 23#include <linux/of_platform.h>
21#include <linux/of_gpio.h> 24#include <linux/of_gpio.h>
@@ -26,23 +29,28 @@
26#define PCA953X_INVERT 2 29#define PCA953X_INVERT 2
27#define PCA953X_DIRECTION 3 30#define PCA953X_DIRECTION 3
28 31
32#define PCA953X_GPIOS 0x00FF
33#define PCA953X_INT 0x0100
34
29static const struct i2c_device_id pca953x_id[] = { 35static const struct i2c_device_id pca953x_id[] = {
30 { "pca9534", 8, }, 36 { "pca9534", 8 | PCA953X_INT, },
31 { "pca9535", 16, }, 37 { "pca9535", 16 | PCA953X_INT, },
32 { "pca9536", 4, }, 38 { "pca9536", 4, },
33 { "pca9537", 4, }, 39 { "pca9537", 4 | PCA953X_INT, },
34 { "pca9538", 8, }, 40 { "pca9538", 8 | PCA953X_INT, },
35 { "pca9539", 16, }, 41 { "pca9539", 16 | PCA953X_INT, },
36 { "pca9554", 8, }, 42 { "pca9554", 8 | PCA953X_INT, },
37 { "pca9555", 16, }, 43 { "pca9555", 16 | PCA953X_INT, },
38 { "pca9556", 8, }, 44 { "pca9556", 8, },
39 { "pca9557", 8, }, 45 { "pca9557", 8, },
40 46
41 { "max7310", 8, }, 47 { "max7310", 8, },
42 { "max7315", 8, }, 48 { "max7312", 16 | PCA953X_INT, },
43 { "pca6107", 8, }, 49 { "max7313", 16 | PCA953X_INT, },
44 { "tca6408", 8, }, 50 { "max7315", 8 | PCA953X_INT, },
45 { "tca6416", 16, }, 51 { "pca6107", 8 | PCA953X_INT, },
52 { "tca6408", 8 | PCA953X_INT, },
53 { "tca6416", 16 | PCA953X_INT, },
46 /* NYET: { "tca6424", 24, }, */ 54 /* NYET: { "tca6424", 24, }, */
47 { } 55 { }
48}; 56};
@@ -53,6 +61,15 @@ struct pca953x_chip {
53 uint16_t reg_output; 61 uint16_t reg_output;
54 uint16_t reg_direction; 62 uint16_t reg_direction;
55 63
64#ifdef CONFIG_GPIO_PCA953X_IRQ
65 struct mutex irq_lock;
66 uint16_t irq_mask;
67 uint16_t irq_stat;
68 uint16_t irq_trig_raise;
69 uint16_t irq_trig_fall;
70 int irq_base;
71#endif
72
56 struct i2c_client *client; 73 struct i2c_client *client;
57 struct pca953x_platform_data *dyn_pdata; 74 struct pca953x_platform_data *dyn_pdata;
58 struct gpio_chip gpio_chip; 75 struct gpio_chip gpio_chip;
@@ -202,6 +219,222 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
202 gc->names = chip->names; 219 gc->names = chip->names;
203} 220}
204 221
222#ifdef CONFIG_GPIO_PCA953X_IRQ
223static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
224{
225 struct pca953x_chip *chip;
226
227 chip = container_of(gc, struct pca953x_chip, gpio_chip);
228 return chip->irq_base + off;
229}
230
231static void pca953x_irq_mask(unsigned int irq)
232{
233 struct pca953x_chip *chip = get_irq_chip_data(irq);
234
235 chip->irq_mask &= ~(1 << (irq - chip->irq_base));
236}
237
238static void pca953x_irq_unmask(unsigned int irq)
239{
240 struct pca953x_chip *chip = get_irq_chip_data(irq);
241
242 chip->irq_mask |= 1 << (irq - chip->irq_base);
243}
244
245static void pca953x_irq_bus_lock(unsigned int irq)
246{
247 struct pca953x_chip *chip = get_irq_chip_data(irq);
248
249 mutex_lock(&chip->irq_lock);
250}
251
252static void pca953x_irq_bus_sync_unlock(unsigned int irq)
253{
254 struct pca953x_chip *chip = get_irq_chip_data(irq);
255 uint16_t new_irqs;
256 uint16_t level;
257
258 /* Look for any newly setup interrupt */
259 new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
260 new_irqs &= ~chip->reg_direction;
261
262 while (new_irqs) {
263 level = __ffs(new_irqs);
264 pca953x_gpio_direction_input(&chip->gpio_chip, level);
265 new_irqs &= ~(1 << level);
266 }
267
268 mutex_unlock(&chip->irq_lock);
269}
270
271static int pca953x_irq_set_type(unsigned int irq, unsigned int type)
272{
273 struct pca953x_chip *chip = get_irq_chip_data(irq);
274 uint16_t level = irq - chip->irq_base;
275 uint16_t mask = 1 << level;
276
277 if (!(type & IRQ_TYPE_EDGE_BOTH)) {
278 dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
279 irq, type);
280 return -EINVAL;
281 }
282
283 if (type & IRQ_TYPE_EDGE_FALLING)
284 chip->irq_trig_fall |= mask;
285 else
286 chip->irq_trig_fall &= ~mask;
287
288 if (type & IRQ_TYPE_EDGE_RISING)
289 chip->irq_trig_raise |= mask;
290 else
291 chip->irq_trig_raise &= ~mask;
292
293 return 0;
294}
295
296static struct irq_chip pca953x_irq_chip = {
297 .name = "pca953x",
298 .mask = pca953x_irq_mask,
299 .unmask = pca953x_irq_unmask,
300 .bus_lock = pca953x_irq_bus_lock,
301 .bus_sync_unlock = pca953x_irq_bus_sync_unlock,
302 .set_type = pca953x_irq_set_type,
303};
304
305static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
306{
307 uint16_t cur_stat;
308 uint16_t old_stat;
309 uint16_t pending;
310 uint16_t trigger;
311 int ret;
312
313 ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
314 if (ret)
315 return 0;
316
317 /* Remove output pins from the equation */
318 cur_stat &= chip->reg_direction;
319
320 old_stat = chip->irq_stat;
321 trigger = (cur_stat ^ old_stat) & chip->irq_mask;
322
323 if (!trigger)
324 return 0;
325
326 chip->irq_stat = cur_stat;
327
328 pending = (old_stat & chip->irq_trig_fall) |
329 (cur_stat & chip->irq_trig_raise);
330 pending &= trigger;
331
332 return pending;
333}
334
335static irqreturn_t pca953x_irq_handler(int irq, void *devid)
336{
337 struct pca953x_chip *chip = devid;
338 uint16_t pending;
339 uint16_t level;
340
341 pending = pca953x_irq_pending(chip);
342
343 if (!pending)
344 return IRQ_HANDLED;
345
346 do {
347 level = __ffs(pending);
348 handle_nested_irq(level + chip->irq_base);
349
350 pending &= ~(1 << level);
351 } while (pending);
352
353 return IRQ_HANDLED;
354}
355
356static int pca953x_irq_setup(struct pca953x_chip *chip,
357 const struct i2c_device_id *id)
358{
359 struct i2c_client *client = chip->client;
360 struct pca953x_platform_data *pdata = client->dev.platform_data;
361 int ret;
362
363 if (pdata->irq_base && (id->driver_data & PCA953X_INT)) {
364 int lvl;
365
366 ret = pca953x_read_reg(chip, PCA953X_INPUT,
367 &chip->irq_stat);
368 if (ret)
369 goto out_failed;
370
371 /*
372 * There is no way to know which GPIO line generated the
373 * interrupt. We have to rely on the previous read for
374 * this purpose.
375 */
376 chip->irq_stat &= chip->reg_direction;
377 chip->irq_base = pdata->irq_base;
378 mutex_init(&chip->irq_lock);
379
380 for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
381 int irq = lvl + chip->irq_base;
382
383 set_irq_chip_data(irq, chip);
384 set_irq_chip_and_handler(irq, &pca953x_irq_chip,
385 handle_edge_irq);
386 set_irq_nested_thread(irq, 1);
387#ifdef CONFIG_ARM
388 set_irq_flags(irq, IRQF_VALID);
389#else
390 set_irq_noprobe(irq);
391#endif
392 }
393
394 ret = request_threaded_irq(client->irq,
395 NULL,
396 pca953x_irq_handler,
397 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
398 dev_name(&client->dev), chip);
399 if (ret) {
400 dev_err(&client->dev, "failed to request irq %d\n",
401 client->irq);
402 goto out_failed;
403 }
404
405 chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
406 }
407
408 return 0;
409
410out_failed:
411 chip->irq_base = 0;
412 return ret;
413}
414
415static void pca953x_irq_teardown(struct pca953x_chip *chip)
416{
417 if (chip->irq_base)
418 free_irq(chip->client->irq, chip);
419}
420#else /* CONFIG_GPIO_PCA953X_IRQ */
421static int pca953x_irq_setup(struct pca953x_chip *chip,
422 const struct i2c_device_id *id)
423{
424 struct i2c_client *client = chip->client;
425 struct pca953x_platform_data *pdata = client->dev.platform_data;
426
427 if (pdata->irq_base && (id->driver_data & PCA953X_INT))
428 dev_warn(&client->dev, "interrupt support not compiled in\n");
429
430 return 0;
431}
432
433static void pca953x_irq_teardown(struct pca953x_chip *chip)
434{
435}
436#endif
437
205/* 438/*
206 * Handlers for alternative sources of platform_data 439 * Handlers for alternative sources of platform_data
207 */ 440 */
@@ -286,7 +519,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
286 /* initialize cached registers from their original values. 519 /* initialize cached registers from their original values.
287 * we can't share this chip with another i2c master. 520 * we can't share this chip with another i2c master.
288 */ 521 */
289 pca953x_setup_gpio(chip, id->driver_data); 522 pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS);
290 523
291 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); 524 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
292 if (ret) 525 if (ret)
@@ -301,6 +534,9 @@ static int __devinit pca953x_probe(struct i2c_client *client,
301 if (ret) 534 if (ret)
302 goto out_failed; 535 goto out_failed;
303 536
537 ret = pca953x_irq_setup(chip, id);
538 if (ret)
539 goto out_failed;
304 540
305 ret = gpiochip_add(&chip->gpio_chip); 541 ret = gpiochip_add(&chip->gpio_chip);
306 if (ret) 542 if (ret)
@@ -317,6 +553,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
317 return 0; 553 return 0;
318 554
319out_failed: 555out_failed:
556 pca953x_irq_teardown(chip);
320 kfree(chip->dyn_pdata); 557 kfree(chip->dyn_pdata);
321 kfree(chip); 558 kfree(chip);
322 return ret; 559 return ret;
@@ -345,6 +582,7 @@ static int pca953x_remove(struct i2c_client *client)
345 return ret; 582 return ret;
346 } 583 }
347 584
585 pca953x_irq_teardown(chip);
348 kfree(chip->dyn_pdata); 586 kfree(chip->dyn_pdata);
349 kfree(chip); 587 kfree(chip);
350 return 0; 588 return 0;