blob: 5ba7e60de942a1a53380330beb0d500e2926057c [file] [log] [blame]
eric miao9e60fdc2008-02-04 22:28:26 -08001/*
Grant Likelyc103de22011-06-04 18:38:28 -06002 * PCA953x 4/8/16 bit I/O ports
eric miao9e60fdc2008-02-04 22:28:26 -08003 *
4 * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
5 * Copyright (C) 2007 Marvell International Ltd.
6 *
7 * Derived from drivers/i2c/chips/pca9539.c
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 */
13
14#include <linux/module.h>
15#include <linux/init.h>
H Hartley Sweetend120c172009-09-22 16:46:37 -070016#include <linux/gpio.h>
Marc Zyngier89ea8bb2010-03-05 13:44:36 -080017#include <linux/interrupt.h>
18#include <linux/irq.h>
Maxime Ripard55ecd262012-11-08 18:01:51 +010019#include <linux/irqdomain.h>
eric miao9e60fdc2008-02-04 22:28:26 -080020#include <linux/i2c.h>
Guennadi Liakhovetskid1c057e32008-02-06 01:39:02 -080021#include <linux/i2c/pca953x.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090022#include <linux/slab.h>
Nate Case1965d302009-06-17 16:26:17 -070023#ifdef CONFIG_OF_GPIO
24#include <linux/of_platform.h>
Nate Case1965d302009-06-17 16:26:17 -070025#endif
eric miao9e60fdc2008-02-04 22:28:26 -080026
Haojian Zhuang33226ff2011-04-18 22:12:46 +080027#define PCA953X_INPUT 0
28#define PCA953X_OUTPUT 1
29#define PCA953X_INVERT 2
30#define PCA953X_DIRECTION 3
eric miao9e60fdc2008-02-04 22:28:26 -080031
Andreas Schallenbergae79c192012-05-09 09:46:17 +020032#define REG_ADDR_AI 0x80
33
Haojian Zhuang33226ff2011-04-18 22:12:46 +080034#define PCA957X_IN 0
35#define PCA957X_INVRT 1
36#define PCA957X_BKEN 2
37#define PCA957X_PUPD 3
38#define PCA957X_CFG 4
39#define PCA957X_OUT 5
40#define PCA957X_MSK 6
41#define PCA957X_INTS 7
42
43#define PCA_GPIO_MASK 0x00FF
44#define PCA_INT 0x0100
45#define PCA953X_TYPE 0x1000
46#define PCA957X_TYPE 0x2000
Marc Zyngier89ea8bb2010-03-05 13:44:36 -080047
Jean Delvare3760f732008-04-29 23:11:40 +020048static const struct i2c_device_id pca953x_id[] = {
Haojian Zhuang33226ff2011-04-18 22:12:46 +080049 { "pca9534", 8 | PCA953X_TYPE | PCA_INT, },
50 { "pca9535", 16 | PCA953X_TYPE | PCA_INT, },
51 { "pca9536", 4 | PCA953X_TYPE, },
52 { "pca9537", 4 | PCA953X_TYPE | PCA_INT, },
53 { "pca9538", 8 | PCA953X_TYPE | PCA_INT, },
54 { "pca9539", 16 | PCA953X_TYPE | PCA_INT, },
55 { "pca9554", 8 | PCA953X_TYPE | PCA_INT, },
56 { "pca9555", 16 | PCA953X_TYPE | PCA_INT, },
57 { "pca9556", 8 | PCA953X_TYPE, },
58 { "pca9557", 8 | PCA953X_TYPE, },
59 { "pca9574", 8 | PCA957X_TYPE | PCA_INT, },
60 { "pca9575", 16 | PCA957X_TYPE | PCA_INT, },
David Brownellab5dc372009-01-06 14:42:27 -080061
Haojian Zhuang33226ff2011-04-18 22:12:46 +080062 { "max7310", 8 | PCA953X_TYPE, },
63 { "max7312", 16 | PCA953X_TYPE | PCA_INT, },
64 { "max7313", 16 | PCA953X_TYPE | PCA_INT, },
65 { "max7315", 8 | PCA953X_TYPE | PCA_INT, },
66 { "pca6107", 8 | PCA953X_TYPE | PCA_INT, },
67 { "tca6408", 8 | PCA953X_TYPE | PCA_INT, },
68 { "tca6416", 16 | PCA953X_TYPE | PCA_INT, },
Andreas Schallenbergae79c192012-05-09 09:46:17 +020069 { "tca6424", 24 | PCA953X_TYPE | PCA_INT, },
Jean Delvare3760f732008-04-29 23:11:40 +020070 { }
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080071};
Jean Delvare3760f732008-04-29 23:11:40 +020072MODULE_DEVICE_TABLE(i2c, pca953x_id);
eric miao9e60fdc2008-02-04 22:28:26 -080073
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -080074struct pca953x_chip {
eric miao9e60fdc2008-02-04 22:28:26 -080075 unsigned gpio_start;
Andreas Schallenbergae79c192012-05-09 09:46:17 +020076 u32 reg_output;
77 u32 reg_direction;
Roland Stigge6e20fb12011-02-10 15:01:23 -080078 struct mutex i2c_lock;
eric miao9e60fdc2008-02-04 22:28:26 -080079
Marc Zyngier89ea8bb2010-03-05 13:44:36 -080080#ifdef CONFIG_GPIO_PCA953X_IRQ
81 struct mutex irq_lock;
Leed Aguilarca3ffe92012-07-10 19:05:53 +053082 u32 irq_mask;
83 u32 irq_stat;
84 u32 irq_trig_raise;
85 u32 irq_trig_fall;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -080086 int irq_base;
Maxime Ripard55ecd262012-11-08 18:01:51 +010087 struct irq_domain *domain;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -080088#endif
89
eric miao9e60fdc2008-02-04 22:28:26 -080090 struct i2c_client *client;
91 struct gpio_chip gpio_chip;
Uwe Kleine-König62154992010-05-26 14:42:17 -070092 const char *const *names;
Haojian Zhuang33226ff2011-04-18 22:12:46 +080093 int chip_type;
eric miao9e60fdc2008-02-04 22:28:26 -080094};
95
Andreas Schallenbergae79c192012-05-09 09:46:17 +020096static int pca953x_write_reg(struct pca953x_chip *chip, int reg, u32 val)
eric miao9e60fdc2008-02-04 22:28:26 -080097{
Haojian Zhuang33226ff2011-04-18 22:12:46 +080098 int ret = 0;
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080099
100 if (chip->gpio_chip.ngpio <= 8)
101 ret = i2c_smbus_write_byte_data(chip->client, reg, val);
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200102 else if (chip->gpio_chip.ngpio == 24) {
Andreas Schallenberg96b70642012-05-21 09:52:43 +0200103 cpu_to_le32s(&val);
104 ret = i2c_smbus_write_i2c_block_data(chip->client,
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200105 (reg << 2) | REG_ADDR_AI,
Andreas Schallenberg96b70642012-05-21 09:52:43 +0200106 3,
107 (u8 *) &val);
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200108 }
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800109 else {
110 switch (chip->chip_type) {
111 case PCA953X_TYPE:
112 ret = i2c_smbus_write_word_data(chip->client,
113 reg << 1, val);
114 break;
115 case PCA957X_TYPE:
116 ret = i2c_smbus_write_byte_data(chip->client, reg << 1,
117 val & 0xff);
118 if (ret < 0)
119 break;
120 ret = i2c_smbus_write_byte_data(chip->client,
121 (reg << 1) + 1,
122 (val & 0xff00) >> 8);
123 break;
124 }
125 }
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800126
127 if (ret < 0) {
128 dev_err(&chip->client->dev, "failed writing register\n");
David Brownellab5dc372009-01-06 14:42:27 -0800129 return ret;
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800130 }
131
132 return 0;
eric miao9e60fdc2008-02-04 22:28:26 -0800133}
134
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200135static int pca953x_read_reg(struct pca953x_chip *chip, int reg, u32 *val)
eric miao9e60fdc2008-02-04 22:28:26 -0800136{
137 int ret;
138
Andreas Schallenberg96b70642012-05-21 09:52:43 +0200139 if (chip->gpio_chip.ngpio <= 8) {
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800140 ret = i2c_smbus_read_byte_data(chip->client, reg);
Andreas Schallenberg96b70642012-05-21 09:52:43 +0200141 *val = ret;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200142 }
Andreas Schallenberg96b70642012-05-21 09:52:43 +0200143 else if (chip->gpio_chip.ngpio == 24) {
144 *val = 0;
145 ret = i2c_smbus_read_i2c_block_data(chip->client,
146 (reg << 2) | REG_ADDR_AI,
147 3,
148 (u8 *) val);
149 le32_to_cpus(val);
150 } else {
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800151 ret = i2c_smbus_read_word_data(chip->client, reg << 1);
Andreas Schallenberg96b70642012-05-21 09:52:43 +0200152 *val = ret;
153 }
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800154
eric miao9e60fdc2008-02-04 22:28:26 -0800155 if (ret < 0) {
156 dev_err(&chip->client->dev, "failed reading register\n");
David Brownellab5dc372009-01-06 14:42:27 -0800157 return ret;
eric miao9e60fdc2008-02-04 22:28:26 -0800158 }
159
eric miao9e60fdc2008-02-04 22:28:26 -0800160 return 0;
161}
162
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800163static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
eric miao9e60fdc2008-02-04 22:28:26 -0800164{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800165 struct pca953x_chip *chip;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200166 uint reg_val;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800167 int ret, offset = 0;
eric miao9e60fdc2008-02-04 22:28:26 -0800168
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800169 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800170
Roland Stigge6e20fb12011-02-10 15:01:23 -0800171 mutex_lock(&chip->i2c_lock);
eric miao9e60fdc2008-02-04 22:28:26 -0800172 reg_val = chip->reg_direction | (1u << off);
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800173
174 switch (chip->chip_type) {
175 case PCA953X_TYPE:
176 offset = PCA953X_DIRECTION;
177 break;
178 case PCA957X_TYPE:
179 offset = PCA957X_CFG;
180 break;
181 }
182 ret = pca953x_write_reg(chip, offset, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800183 if (ret)
Roland Stigge6e20fb12011-02-10 15:01:23 -0800184 goto exit;
eric miao9e60fdc2008-02-04 22:28:26 -0800185
186 chip->reg_direction = reg_val;
Roland Stigge6e20fb12011-02-10 15:01:23 -0800187 ret = 0;
188exit:
189 mutex_unlock(&chip->i2c_lock);
190 return ret;
eric miao9e60fdc2008-02-04 22:28:26 -0800191}
192
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800193static int pca953x_gpio_direction_output(struct gpio_chip *gc,
eric miao9e60fdc2008-02-04 22:28:26 -0800194 unsigned off, int val)
195{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800196 struct pca953x_chip *chip;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200197 uint reg_val;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800198 int ret, offset = 0;
eric miao9e60fdc2008-02-04 22:28:26 -0800199
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800200 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800201
Roland Stigge6e20fb12011-02-10 15:01:23 -0800202 mutex_lock(&chip->i2c_lock);
eric miao9e60fdc2008-02-04 22:28:26 -0800203 /* set output level */
204 if (val)
205 reg_val = chip->reg_output | (1u << off);
206 else
207 reg_val = chip->reg_output & ~(1u << off);
208
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800209 switch (chip->chip_type) {
210 case PCA953X_TYPE:
211 offset = PCA953X_OUTPUT;
212 break;
213 case PCA957X_TYPE:
214 offset = PCA957X_OUT;
215 break;
216 }
217 ret = pca953x_write_reg(chip, offset, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800218 if (ret)
Roland Stigge6e20fb12011-02-10 15:01:23 -0800219 goto exit;
eric miao9e60fdc2008-02-04 22:28:26 -0800220
221 chip->reg_output = reg_val;
222
223 /* then direction */
224 reg_val = chip->reg_direction & ~(1u << off);
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800225 switch (chip->chip_type) {
226 case PCA953X_TYPE:
227 offset = PCA953X_DIRECTION;
228 break;
229 case PCA957X_TYPE:
230 offset = PCA957X_CFG;
231 break;
232 }
233 ret = pca953x_write_reg(chip, offset, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800234 if (ret)
Roland Stigge6e20fb12011-02-10 15:01:23 -0800235 goto exit;
eric miao9e60fdc2008-02-04 22:28:26 -0800236
237 chip->reg_direction = reg_val;
Roland Stigge6e20fb12011-02-10 15:01:23 -0800238 ret = 0;
239exit:
240 mutex_unlock(&chip->i2c_lock);
241 return ret;
eric miao9e60fdc2008-02-04 22:28:26 -0800242}
243
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800244static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
eric miao9e60fdc2008-02-04 22:28:26 -0800245{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800246 struct pca953x_chip *chip;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200247 u32 reg_val;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800248 int ret, offset = 0;
eric miao9e60fdc2008-02-04 22:28:26 -0800249
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800250 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800251
Roland Stigge6e20fb12011-02-10 15:01:23 -0800252 mutex_lock(&chip->i2c_lock);
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800253 switch (chip->chip_type) {
254 case PCA953X_TYPE:
255 offset = PCA953X_INPUT;
256 break;
257 case PCA957X_TYPE:
258 offset = PCA957X_IN;
259 break;
260 }
261 ret = pca953x_read_reg(chip, offset, &reg_val);
Roland Stigge6e20fb12011-02-10 15:01:23 -0800262 mutex_unlock(&chip->i2c_lock);
eric miao9e60fdc2008-02-04 22:28:26 -0800263 if (ret < 0) {
264 /* NOTE: diagnostic already emitted; that's all we should
265 * do unless gpio_*_value_cansleep() calls become different
266 * from their nonsleeping siblings (and report faults).
267 */
268 return 0;
269 }
270
271 return (reg_val & (1u << off)) ? 1 : 0;
272}
273
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800274static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
eric miao9e60fdc2008-02-04 22:28:26 -0800275{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800276 struct pca953x_chip *chip;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200277 u32 reg_val;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800278 int ret, offset = 0;
eric miao9e60fdc2008-02-04 22:28:26 -0800279
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800280 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800281
Roland Stigge6e20fb12011-02-10 15:01:23 -0800282 mutex_lock(&chip->i2c_lock);
eric miao9e60fdc2008-02-04 22:28:26 -0800283 if (val)
284 reg_val = chip->reg_output | (1u << off);
285 else
286 reg_val = chip->reg_output & ~(1u << off);
287
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800288 switch (chip->chip_type) {
289 case PCA953X_TYPE:
290 offset = PCA953X_OUTPUT;
291 break;
292 case PCA957X_TYPE:
293 offset = PCA957X_OUT;
294 break;
295 }
296 ret = pca953x_write_reg(chip, offset, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800297 if (ret)
Roland Stigge6e20fb12011-02-10 15:01:23 -0800298 goto exit;
eric miao9e60fdc2008-02-04 22:28:26 -0800299
300 chip->reg_output = reg_val;
Roland Stigge6e20fb12011-02-10 15:01:23 -0800301exit:
302 mutex_unlock(&chip->i2c_lock);
eric miao9e60fdc2008-02-04 22:28:26 -0800303}
304
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800305static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
eric miao9e60fdc2008-02-04 22:28:26 -0800306{
307 struct gpio_chip *gc;
308
309 gc = &chip->gpio_chip;
310
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800311 gc->direction_input = pca953x_gpio_direction_input;
312 gc->direction_output = pca953x_gpio_direction_output;
313 gc->get = pca953x_gpio_get_value;
314 gc->set = pca953x_gpio_set_value;
Arnaud Patard84207802008-03-10 11:43:48 -0700315 gc->can_sleep = 1;
eric miao9e60fdc2008-02-04 22:28:26 -0800316
317 gc->base = chip->gpio_start;
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800318 gc->ngpio = gpios;
319 gc->label = chip->client->name;
David Brownelld8f388d2008-07-25 01:46:07 -0700320 gc->dev = &chip->client->dev;
Guennadi Liakhovetskid72cbed2008-04-28 02:14:45 -0700321 gc->owner = THIS_MODULE;
Daniel Silverstone77906a542009-06-17 16:26:15 -0700322 gc->names = chip->names;
eric miao9e60fdc2008-02-04 22:28:26 -0800323}
324
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800325#ifdef CONFIG_GPIO_PCA953X_IRQ
326static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off)
327{
328 struct pca953x_chip *chip;
329
330 chip = container_of(gc, struct pca953x_chip, gpio_chip);
331 return chip->irq_base + off;
332}
333
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800334static void pca953x_irq_mask(struct irq_data *d)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800335{
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800336 struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800337
Maxime Ripard55ecd262012-11-08 18:01:51 +0100338 chip->irq_mask &= ~(1 << d->hwirq);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800339}
340
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800341static void pca953x_irq_unmask(struct irq_data *d)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800342{
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800343 struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800344
Maxime Ripard55ecd262012-11-08 18:01:51 +0100345 chip->irq_mask |= 1 << d->hwirq;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800346}
347
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800348static void pca953x_irq_bus_lock(struct irq_data *d)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800349{
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800350 struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800351
352 mutex_lock(&chip->irq_lock);
353}
354
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800355static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800356{
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800357 struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
Leed Aguilarca3ffe92012-07-10 19:05:53 +0530358 u32 new_irqs;
359 u32 level;
Marc Zyngiera2cb9ae2010-04-27 13:13:07 -0700360
361 /* Look for any newly setup interrupt */
362 new_irqs = chip->irq_trig_fall | chip->irq_trig_raise;
363 new_irqs &= ~chip->reg_direction;
364
365 while (new_irqs) {
366 level = __ffs(new_irqs);
367 pca953x_gpio_direction_input(&chip->gpio_chip, level);
368 new_irqs &= ~(1 << level);
369 }
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800370
371 mutex_unlock(&chip->irq_lock);
372}
373
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800374static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800375{
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800376 struct pca953x_chip *chip = irq_data_get_irq_chip_data(d);
Maxime Ripard55ecd262012-11-08 18:01:51 +0100377 u32 mask = 1 << d->hwirq;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800378
379 if (!(type & IRQ_TYPE_EDGE_BOTH)) {
380 dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800381 d->irq, type);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800382 return -EINVAL;
383 }
384
385 if (type & IRQ_TYPE_EDGE_FALLING)
386 chip->irq_trig_fall |= mask;
387 else
388 chip->irq_trig_fall &= ~mask;
389
390 if (type & IRQ_TYPE_EDGE_RISING)
391 chip->irq_trig_raise |= mask;
392 else
393 chip->irq_trig_raise &= ~mask;
394
Marc Zyngiera2cb9ae2010-04-27 13:13:07 -0700395 return 0;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800396}
397
398static struct irq_chip pca953x_irq_chip = {
399 .name = "pca953x",
Lennert Buytenhek6f5cfc02011-01-12 17:00:15 -0800400 .irq_mask = pca953x_irq_mask,
401 .irq_unmask = pca953x_irq_unmask,
402 .irq_bus_lock = pca953x_irq_bus_lock,
403 .irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock,
404 .irq_set_type = pca953x_irq_set_type,
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800405};
406
Leed Aguilarca3ffe92012-07-10 19:05:53 +0530407static u32 pca953x_irq_pending(struct pca953x_chip *chip)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800408{
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200409 u32 cur_stat;
Leed Aguilarca3ffe92012-07-10 19:05:53 +0530410 u32 old_stat;
411 u32 pending;
412 u32 trigger;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800413 int ret, offset = 0;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800414
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800415 switch (chip->chip_type) {
416 case PCA953X_TYPE:
417 offset = PCA953X_INPUT;
418 break;
419 case PCA957X_TYPE:
420 offset = PCA957X_IN;
421 break;
422 }
423 ret = pca953x_read_reg(chip, offset, &cur_stat);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800424 if (ret)
425 return 0;
426
427 /* Remove output pins from the equation */
428 cur_stat &= chip->reg_direction;
429
430 old_stat = chip->irq_stat;
431 trigger = (cur_stat ^ old_stat) & chip->irq_mask;
432
433 if (!trigger)
434 return 0;
435
436 chip->irq_stat = cur_stat;
437
438 pending = (old_stat & chip->irq_trig_fall) |
439 (cur_stat & chip->irq_trig_raise);
440 pending &= trigger;
441
442 return pending;
443}
444
445static irqreturn_t pca953x_irq_handler(int irq, void *devid)
446{
447 struct pca953x_chip *chip = devid;
Leed Aguilarca3ffe92012-07-10 19:05:53 +0530448 u32 pending;
449 u32 level;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800450
451 pending = pca953x_irq_pending(chip);
452
453 if (!pending)
454 return IRQ_HANDLED;
455
456 do {
457 level = __ffs(pending);
Maxime Ripard55ecd262012-11-08 18:01:51 +0100458 handle_nested_irq(irq_find_mapping(chip->domain, level));
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800459
460 pending &= ~(1 << level);
461 } while (pending);
462
463 return IRQ_HANDLED;
464}
465
466static int pca953x_irq_setup(struct pca953x_chip *chip,
David Janderc6dcf592011-06-14 11:00:55 +0200467 const struct i2c_device_id *id,
468 int irq_base)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800469{
470 struct i2c_client *client = chip->client;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800471 int ret, offset = 0;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200472 u32 temporary;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800473
David Janderc6dcf592011-06-14 11:00:55 +0200474 if (irq_base != -1
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800475 && (id->driver_data & PCA_INT)) {
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800476 int lvl;
477
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800478 switch (chip->chip_type) {
479 case PCA953X_TYPE:
480 offset = PCA953X_INPUT;
481 break;
482 case PCA957X_TYPE:
483 offset = PCA957X_IN;
484 break;
485 }
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200486 ret = pca953x_read_reg(chip, offset, &temporary);
487 chip->irq_stat = temporary;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800488 if (ret)
489 goto out_failed;
490
491 /*
492 * There is no way to know which GPIO line generated the
493 * interrupt. We have to rely on the previous read for
494 * this purpose.
495 */
496 chip->irq_stat &= chip->reg_direction;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800497 mutex_init(&chip->irq_lock);
498
David Janderc6dcf592011-06-14 11:00:55 +0200499 chip->irq_base = irq_alloc_descs(-1, irq_base, chip->gpio_chip.ngpio, -1);
David Jander910c8fb2011-06-08 11:34:37 -0600500 if (chip->irq_base < 0)
501 goto out_failed;
502
Maxime Ripard55ecd262012-11-08 18:01:51 +0100503 chip->domain = irq_domain_add_legacy(client->dev.of_node,
504 chip->gpio_chip.ngpio,
505 chip->irq_base,
506 0,
507 &irq_domain_simple_ops,
508 NULL);
509 if (!chip->domain) {
510 ret = -ENODEV;
511 goto out_irqdesc_free;
512 }
513
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800514 for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) {
515 int irq = lvl + chip->irq_base;
516
David Jander910c8fb2011-06-08 11:34:37 -0600517 irq_clear_status_flags(irq, IRQ_NOREQUEST);
Thomas Gleixnerb51804b2011-03-24 21:27:36 +0000518 irq_set_chip_data(irq, chip);
David Jander6dd599f2011-06-08 11:37:45 -0600519 irq_set_chip(irq, &pca953x_irq_chip);
520 irq_set_nested_thread(irq, true);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800521#ifdef CONFIG_ARM
522 set_irq_flags(irq, IRQF_VALID);
523#else
Thomas Gleixnerb51804b2011-03-24 21:27:36 +0000524 irq_set_noprobe(irq);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800525#endif
526 }
527
528 ret = request_threaded_irq(client->irq,
529 NULL,
530 pca953x_irq_handler,
David Jander17e8b422011-06-08 11:34:41 -0600531 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800532 dev_name(&client->dev), chip);
533 if (ret) {
534 dev_err(&client->dev, "failed to request irq %d\n",
535 client->irq);
Maxime Ripard55ecd262012-11-08 18:01:51 +0100536 goto out_irqdesc_free;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800537 }
538
539 chip->gpio_chip.to_irq = pca953x_gpio_to_irq;
540 }
541
542 return 0;
543
Maxime Ripard55ecd262012-11-08 18:01:51 +0100544out_irqdesc_free:
545 irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800546out_failed:
Alek Du8a233f012010-10-26 14:22:41 -0700547 chip->irq_base = -1;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800548 return ret;
549}
550
551static void pca953x_irq_teardown(struct pca953x_chip *chip)
552{
David Janderc609c052011-06-14 11:00:54 +0200553 if (chip->irq_base != -1) {
554 irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800555 free_irq(chip->client->irq, chip);
David Janderc609c052011-06-14 11:00:54 +0200556 }
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800557}
558#else /* CONFIG_GPIO_PCA953X_IRQ */
559static int pca953x_irq_setup(struct pca953x_chip *chip,
David Janderc6dcf592011-06-14 11:00:55 +0200560 const struct i2c_device_id *id,
561 int irq_base)
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800562{
563 struct i2c_client *client = chip->client;
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800564
David Janderc6dcf592011-06-14 11:00:55 +0200565 if (irq_base != -1 && (id->driver_data & PCA_INT))
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800566 dev_warn(&client->dev, "interrupt support not compiled in\n");
567
568 return 0;
569}
570
571static void pca953x_irq_teardown(struct pca953x_chip *chip)
572{
573}
574#endif
575
Nate Case1965d302009-06-17 16:26:17 -0700576/*
577 * Handlers for alternative sources of platform_data
578 */
579#ifdef CONFIG_OF_GPIO
580/*
581 * Translate OpenFirmware node properties into platform_data
David Jandera57339b2011-06-14 11:00:56 +0200582 * WARNING: This is DEPRECATED and will be removed eventually!
Nate Case1965d302009-06-17 16:26:17 -0700583 */
Mark Brown404ba2b2011-11-21 17:57:25 +0000584static void
Chandrabhanu Mahapatra6a7b36a2012-07-10 19:05:37 +0530585pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert)
Nate Case1965d302009-06-17 16:26:17 -0700586{
Nate Case1965d302009-06-17 16:26:17 -0700587 struct device_node *node;
Dirk Eibach16482372011-02-24 10:20:43 +0100588 const __be32 *val;
589 int size;
Nate Case1965d302009-06-17 16:26:17 -0700590
Grant Likely61c7a082010-04-13 16:12:29 -0700591 node = client->dev.of_node;
Nate Case1965d302009-06-17 16:26:17 -0700592 if (node == NULL)
David Janderc6dcf592011-06-14 11:00:55 +0200593 return;
Nate Case1965d302009-06-17 16:26:17 -0700594
David Janderc6dcf592011-06-14 11:00:55 +0200595 *gpio_base = -1;
Dirk Eibach16482372011-02-24 10:20:43 +0100596 val = of_get_property(node, "linux,gpio-base", &size);
David Jandera57339b2011-06-14 11:00:56 +0200597 WARN(val, "%s: device-tree property 'linux,gpio-base' is deprecated!", __func__);
Nate Case1965d302009-06-17 16:26:17 -0700598 if (val) {
Dirk Eibach16482372011-02-24 10:20:43 +0100599 if (size != sizeof(*val))
600 dev_warn(&client->dev, "%s: wrong linux,gpio-base\n",
601 node->full_name);
Nate Case1965d302009-06-17 16:26:17 -0700602 else
David Janderc6dcf592011-06-14 11:00:55 +0200603 *gpio_base = be32_to_cpup(val);
Nate Case1965d302009-06-17 16:26:17 -0700604 }
605
606 val = of_get_property(node, "polarity", NULL);
David Jandera57339b2011-06-14 11:00:56 +0200607 WARN(val, "%s: device-tree property 'polarity' is deprecated!", __func__);
Nate Case1965d302009-06-17 16:26:17 -0700608 if (val)
David Janderc6dcf592011-06-14 11:00:55 +0200609 *invert = *val;
Nate Case1965d302009-06-17 16:26:17 -0700610}
611#else
Mark Brown404ba2b2011-11-21 17:57:25 +0000612static void
Chandrabhanu Mahapatra6a7b36a2012-07-10 19:05:37 +0530613pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, u32 *invert)
Nate Case1965d302009-06-17 16:26:17 -0700614{
Hartmut Knaack25fcf2b2011-10-11 00:22:45 +0200615 *gpio_base = -1;
Nate Case1965d302009-06-17 16:26:17 -0700616}
617#endif
618
Chandrabhanu Mahapatra6a7b36a2012-07-10 19:05:37 +0530619static int __devinit device_pca953x_init(struct pca953x_chip *chip, u32 invert)
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800620{
621 int ret;
622
623 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
624 if (ret)
625 goto out;
626
627 ret = pca953x_read_reg(chip, PCA953X_DIRECTION,
628 &chip->reg_direction);
629 if (ret)
630 goto out;
631
632 /* set platform specific polarity inversion */
633 ret = pca953x_write_reg(chip, PCA953X_INVERT, invert);
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800634out:
635 return ret;
636}
637
Chandrabhanu Mahapatra6a7b36a2012-07-10 19:05:37 +0530638static int __devinit device_pca957x_init(struct pca953x_chip *chip, u32 invert)
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800639{
640 int ret;
Andreas Schallenbergae79c192012-05-09 09:46:17 +0200641 u32 val = 0;
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800642
643 /* Let every port in proper state, that could save power */
644 pca953x_write_reg(chip, PCA957X_PUPD, 0x0);
645 pca953x_write_reg(chip, PCA957X_CFG, 0xffff);
646 pca953x_write_reg(chip, PCA957X_OUT, 0x0);
647
648 ret = pca953x_read_reg(chip, PCA957X_IN, &val);
649 if (ret)
650 goto out;
651 ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output);
652 if (ret)
653 goto out;
654 ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction);
655 if (ret)
656 goto out;
657
658 /* set platform specific polarity inversion */
659 pca953x_write_reg(chip, PCA957X_INVRT, invert);
660
661 /* To enable register 6, 7 to controll pull up and pull down */
662 pca953x_write_reg(chip, PCA957X_BKEN, 0x202);
663
664 return 0;
665out:
666 return ret;
667}
668
Jean Delvared2653e92008-04-29 23:11:39 +0200669static int __devinit pca953x_probe(struct i2c_client *client,
Jean Delvare3760f732008-04-29 23:11:40 +0200670 const struct i2c_device_id *id)
eric miao9e60fdc2008-02-04 22:28:26 -0800671{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800672 struct pca953x_platform_data *pdata;
673 struct pca953x_chip *chip;
Chandrabhanu Mahapatra6a7b36a2012-07-10 19:05:37 +0530674 int irq_base = 0;
Wolfram Sang7ea2aa22011-10-14 15:32:00 +0200675 int ret;
Chandrabhanu Mahapatra6a7b36a2012-07-10 19:05:37 +0530676 u32 invert = 0;
eric miao9e60fdc2008-02-04 22:28:26 -0800677
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800678 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
eric miao9e60fdc2008-02-04 22:28:26 -0800679 if (chip == NULL)
680 return -ENOMEM;
681
Nate Case1965d302009-06-17 16:26:17 -0700682 pdata = client->dev.platform_data;
David Janderc6dcf592011-06-14 11:00:55 +0200683 if (pdata) {
684 irq_base = pdata->irq_base;
685 chip->gpio_start = pdata->gpio_base;
686 invert = pdata->invert;
687 chip->names = pdata->names;
688 } else {
689 pca953x_get_alt_pdata(client, &chip->gpio_start, &invert);
David Jandera57339b2011-06-14 11:00:56 +0200690#ifdef CONFIG_OF_GPIO
691 /* If I2C node has no interrupts property, disable GPIO interrupts */
692 if (of_find_property(client->dev.of_node, "interrupts", NULL) == NULL)
693 irq_base = -1;
694#endif
Nate Case1965d302009-06-17 16:26:17 -0700695 }
696
eric miao9e60fdc2008-02-04 22:28:26 -0800697 chip->client = client;
698
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800699 chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
Daniel Silverstone77906a542009-06-17 16:26:15 -0700700
Roland Stigge6e20fb12011-02-10 15:01:23 -0800701 mutex_init(&chip->i2c_lock);
702
eric miao9e60fdc2008-02-04 22:28:26 -0800703 /* initialize cached registers from their original values.
704 * we can't share this chip with another i2c master.
705 */
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800706 pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800707
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800708 if (chip->chip_type == PCA953X_TYPE)
Wolfram Sang7ea2aa22011-10-14 15:32:00 +0200709 ret = device_pca953x_init(chip, invert);
Haojian Zhuang33226ff2011-04-18 22:12:46 +0800710 else
Wolfram Sang7ea2aa22011-10-14 15:32:00 +0200711 ret = device_pca957x_init(chip, invert);
712 if (ret)
eric miao9e60fdc2008-02-04 22:28:26 -0800713 goto out_failed;
714
David Janderc6dcf592011-06-14 11:00:55 +0200715 ret = pca953x_irq_setup(chip, id, irq_base);
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800716 if (ret)
717 goto out_failed;
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800718
719 ret = gpiochip_add(&chip->gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800720 if (ret)
Ben Dooks272df502011-03-31 07:18:46 +0900721 goto out_failed_irq;
eric miao9e60fdc2008-02-04 22:28:26 -0800722
David Janderc6dcf592011-06-14 11:00:55 +0200723 if (pdata && pdata->setup) {
eric miao9e60fdc2008-02-04 22:28:26 -0800724 ret = pdata->setup(client, chip->gpio_chip.base,
725 chip->gpio_chip.ngpio, pdata->context);
726 if (ret < 0)
727 dev_warn(&client->dev, "setup failed, %d\n", ret);
728 }
729
730 i2c_set_clientdata(client, chip);
731 return 0;
732
Ben Dooks272df502011-03-31 07:18:46 +0900733out_failed_irq:
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800734 pca953x_irq_teardown(chip);
Ben Dooks272df502011-03-31 07:18:46 +0900735out_failed:
eric miao9e60fdc2008-02-04 22:28:26 -0800736 kfree(chip);
737 return ret;
738}
739
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800740static int pca953x_remove(struct i2c_client *client)
eric miao9e60fdc2008-02-04 22:28:26 -0800741{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800742 struct pca953x_platform_data *pdata = client->dev.platform_data;
743 struct pca953x_chip *chip = i2c_get_clientdata(client);
eric miao9e60fdc2008-02-04 22:28:26 -0800744 int ret = 0;
745
David Janderc6dcf592011-06-14 11:00:55 +0200746 if (pdata && pdata->teardown) {
eric miao9e60fdc2008-02-04 22:28:26 -0800747 ret = pdata->teardown(client, chip->gpio_chip.base,
748 chip->gpio_chip.ngpio, pdata->context);
749 if (ret < 0) {
750 dev_err(&client->dev, "%s failed, %d\n",
751 "teardown", ret);
752 return ret;
753 }
754 }
755
756 ret = gpiochip_remove(&chip->gpio_chip);
757 if (ret) {
758 dev_err(&client->dev, "%s failed, %d\n",
759 "gpiochip_remove()", ret);
760 return ret;
761 }
762
Marc Zyngier89ea8bb2010-03-05 13:44:36 -0800763 pca953x_irq_teardown(chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800764 kfree(chip);
765 return 0;
766}
767
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800768static struct i2c_driver pca953x_driver = {
eric miao9e60fdc2008-02-04 22:28:26 -0800769 .driver = {
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800770 .name = "pca953x",
eric miao9e60fdc2008-02-04 22:28:26 -0800771 },
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800772 .probe = pca953x_probe,
773 .remove = pca953x_remove,
Jean Delvare3760f732008-04-29 23:11:40 +0200774 .id_table = pca953x_id,
eric miao9e60fdc2008-02-04 22:28:26 -0800775};
776
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800777static int __init pca953x_init(void)
eric miao9e60fdc2008-02-04 22:28:26 -0800778{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800779 return i2c_add_driver(&pca953x_driver);
eric miao9e60fdc2008-02-04 22:28:26 -0800780}
David Brownell2f8d1192008-10-15 22:03:13 -0700781/* register after i2c postcore initcall and before
782 * subsys initcalls that may rely on these GPIOs
783 */
784subsys_initcall(pca953x_init);
eric miao9e60fdc2008-02-04 22:28:26 -0800785
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800786static void __exit pca953x_exit(void)
eric miao9e60fdc2008-02-04 22:28:26 -0800787{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800788 i2c_del_driver(&pca953x_driver);
eric miao9e60fdc2008-02-04 22:28:26 -0800789}
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800790module_exit(pca953x_exit);
eric miao9e60fdc2008-02-04 22:28:26 -0800791
792MODULE_AUTHOR("eric miao <eric.miao@marvell.com>");
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800793MODULE_DESCRIPTION("GPIO expander driver for PCA953x");
eric miao9e60fdc2008-02-04 22:28:26 -0800794MODULE_LICENSE("GPL");