diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/gpio/pca953x.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/gpio/pca953x.c')
-rw-r--r-- | drivers/gpio/pca953x.c | 350 |
1 files changed, 251 insertions, 99 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index a2b12aa1f2b9..0451d7ac94ac 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -24,33 +24,46 @@ | |||
24 | #include <linux/of_gpio.h> | 24 | #include <linux/of_gpio.h> |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #define PCA953X_INPUT 0 | 27 | #define PCA953X_INPUT 0 |
28 | #define PCA953X_OUTPUT 1 | 28 | #define PCA953X_OUTPUT 1 |
29 | #define PCA953X_INVERT 2 | 29 | #define PCA953X_INVERT 2 |
30 | #define PCA953X_DIRECTION 3 | 30 | #define PCA953X_DIRECTION 3 |
31 | 31 | ||
32 | #define PCA953X_GPIOS 0x00FF | 32 | #define PCA957X_IN 0 |
33 | #define PCA953X_INT 0x0100 | 33 | #define PCA957X_INVRT 1 |
34 | #define PCA957X_BKEN 2 | ||
35 | #define PCA957X_PUPD 3 | ||
36 | #define PCA957X_CFG 4 | ||
37 | #define PCA957X_OUT 5 | ||
38 | #define PCA957X_MSK 6 | ||
39 | #define PCA957X_INTS 7 | ||
40 | |||
41 | #define PCA_GPIO_MASK 0x00FF | ||
42 | #define PCA_INT 0x0100 | ||
43 | #define PCA953X_TYPE 0x1000 | ||
44 | #define PCA957X_TYPE 0x2000 | ||
34 | 45 | ||
35 | static const struct i2c_device_id pca953x_id[] = { | 46 | static const struct i2c_device_id pca953x_id[] = { |
36 | { "pca9534", 8 | PCA953X_INT, }, | 47 | { "pca9534", 8 | PCA953X_TYPE | PCA_INT, }, |
37 | { "pca9535", 16 | PCA953X_INT, }, | 48 | { "pca9535", 16 | PCA953X_TYPE | PCA_INT, }, |
38 | { "pca9536", 4, }, | 49 | { "pca9536", 4 | PCA953X_TYPE, }, |
39 | { "pca9537", 4 | PCA953X_INT, }, | 50 | { "pca9537", 4 | PCA953X_TYPE | PCA_INT, }, |
40 | { "pca9538", 8 | PCA953X_INT, }, | 51 | { "pca9538", 8 | PCA953X_TYPE | PCA_INT, }, |
41 | { "pca9539", 16 | PCA953X_INT, }, | 52 | { "pca9539", 16 | PCA953X_TYPE | PCA_INT, }, |
42 | { "pca9554", 8 | PCA953X_INT, }, | 53 | { "pca9554", 8 | PCA953X_TYPE | PCA_INT, }, |
43 | { "pca9555", 16 | PCA953X_INT, }, | 54 | { "pca9555", 16 | PCA953X_TYPE | PCA_INT, }, |
44 | { "pca9556", 8, }, | 55 | { "pca9556", 8 | PCA953X_TYPE, }, |
45 | { "pca9557", 8, }, | 56 | { "pca9557", 8 | PCA953X_TYPE, }, |
46 | 57 | { "pca9574", 8 | PCA957X_TYPE | PCA_INT, }, | |
47 | { "max7310", 8, }, | 58 | { "pca9575", 16 | PCA957X_TYPE | PCA_INT, }, |
48 | { "max7312", 16 | PCA953X_INT, }, | 59 | |
49 | { "max7313", 16 | PCA953X_INT, }, | 60 | { "max7310", 8 | PCA953X_TYPE, }, |
50 | { "max7315", 8 | PCA953X_INT, }, | 61 | { "max7312", 16 | PCA953X_TYPE | PCA_INT, }, |
51 | { "pca6107", 8 | PCA953X_INT, }, | 62 | { "max7313", 16 | PCA953X_TYPE | PCA_INT, }, |
52 | { "tca6408", 8 | PCA953X_INT, }, | 63 | { "max7315", 8 | PCA953X_TYPE | PCA_INT, }, |
53 | { "tca6416", 16 | PCA953X_INT, }, | 64 | { "pca6107", 8 | PCA953X_TYPE | PCA_INT, }, |
65 | { "tca6408", 8 | PCA953X_TYPE | PCA_INT, }, | ||
66 | { "tca6416", 16 | PCA953X_TYPE | PCA_INT, }, | ||
54 | /* NYET: { "tca6424", 24, }, */ | 67 | /* NYET: { "tca6424", 24, }, */ |
55 | { } | 68 | { } |
56 | }; | 69 | }; |
@@ -60,6 +73,7 @@ struct pca953x_chip { | |||
60 | unsigned gpio_start; | 73 | unsigned gpio_start; |
61 | uint16_t reg_output; | 74 | uint16_t reg_output; |
62 | uint16_t reg_direction; | 75 | uint16_t reg_direction; |
76 | struct mutex i2c_lock; | ||
63 | 77 | ||
64 | #ifdef CONFIG_GPIO_PCA953X_IRQ | 78 | #ifdef CONFIG_GPIO_PCA953X_IRQ |
65 | struct mutex irq_lock; | 79 | struct mutex irq_lock; |
@@ -74,16 +88,32 @@ struct pca953x_chip { | |||
74 | struct pca953x_platform_data *dyn_pdata; | 88 | struct pca953x_platform_data *dyn_pdata; |
75 | struct gpio_chip gpio_chip; | 89 | struct gpio_chip gpio_chip; |
76 | const char *const *names; | 90 | const char *const *names; |
91 | int chip_type; | ||
77 | }; | 92 | }; |
78 | 93 | ||
79 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | 94 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) |
80 | { | 95 | { |
81 | int ret; | 96 | int ret = 0; |
82 | 97 | ||
83 | if (chip->gpio_chip.ngpio <= 8) | 98 | if (chip->gpio_chip.ngpio <= 8) |
84 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); | 99 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); |
85 | else | 100 | else { |
86 | ret = i2c_smbus_write_word_data(chip->client, reg << 1, val); | 101 | switch (chip->chip_type) { |
102 | case PCA953X_TYPE: | ||
103 | ret = i2c_smbus_write_word_data(chip->client, | ||
104 | reg << 1, val); | ||
105 | break; | ||
106 | case PCA957X_TYPE: | ||
107 | ret = i2c_smbus_write_byte_data(chip->client, reg << 1, | ||
108 | val & 0xff); | ||
109 | if (ret < 0) | ||
110 | break; | ||
111 | ret = i2c_smbus_write_byte_data(chip->client, | ||
112 | (reg << 1) + 1, | ||
113 | (val & 0xff00) >> 8); | ||
114 | break; | ||
115 | } | ||
116 | } | ||
87 | 117 | ||
88 | if (ret < 0) { | 118 | if (ret < 0) { |
89 | dev_err(&chip->client->dev, "failed writing register\n"); | 119 | dev_err(&chip->client->dev, "failed writing register\n"); |
@@ -115,17 +145,30 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) | |||
115 | { | 145 | { |
116 | struct pca953x_chip *chip; | 146 | struct pca953x_chip *chip; |
117 | uint16_t reg_val; | 147 | uint16_t reg_val; |
118 | int ret; | 148 | int ret, offset = 0; |
119 | 149 | ||
120 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 150 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
121 | 151 | ||
152 | mutex_lock(&chip->i2c_lock); | ||
122 | reg_val = chip->reg_direction | (1u << off); | 153 | reg_val = chip->reg_direction | (1u << off); |
123 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | 154 | |
155 | switch (chip->chip_type) { | ||
156 | case PCA953X_TYPE: | ||
157 | offset = PCA953X_DIRECTION; | ||
158 | break; | ||
159 | case PCA957X_TYPE: | ||
160 | offset = PCA957X_CFG; | ||
161 | break; | ||
162 | } | ||
163 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
124 | if (ret) | 164 | if (ret) |
125 | return ret; | 165 | goto exit; |
126 | 166 | ||
127 | chip->reg_direction = reg_val; | 167 | chip->reg_direction = reg_val; |
128 | return 0; | 168 | ret = 0; |
169 | exit: | ||
170 | mutex_unlock(&chip->i2c_lock); | ||
171 | return ret; | ||
129 | } | 172 | } |
130 | 173 | ||
131 | static int pca953x_gpio_direction_output(struct gpio_chip *gc, | 174 | static int pca953x_gpio_direction_output(struct gpio_chip *gc, |
@@ -133,41 +176,71 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc, | |||
133 | { | 176 | { |
134 | struct pca953x_chip *chip; | 177 | struct pca953x_chip *chip; |
135 | uint16_t reg_val; | 178 | uint16_t reg_val; |
136 | int ret; | 179 | int ret, offset = 0; |
137 | 180 | ||
138 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 181 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
139 | 182 | ||
183 | mutex_lock(&chip->i2c_lock); | ||
140 | /* set output level */ | 184 | /* set output level */ |
141 | if (val) | 185 | if (val) |
142 | reg_val = chip->reg_output | (1u << off); | 186 | reg_val = chip->reg_output | (1u << off); |
143 | else | 187 | else |
144 | reg_val = chip->reg_output & ~(1u << off); | 188 | reg_val = chip->reg_output & ~(1u << off); |
145 | 189 | ||
146 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | 190 | switch (chip->chip_type) { |
191 | case PCA953X_TYPE: | ||
192 | offset = PCA953X_OUTPUT; | ||
193 | break; | ||
194 | case PCA957X_TYPE: | ||
195 | offset = PCA957X_OUT; | ||
196 | break; | ||
197 | } | ||
198 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
147 | if (ret) | 199 | if (ret) |
148 | return ret; | 200 | goto exit; |
149 | 201 | ||
150 | chip->reg_output = reg_val; | 202 | chip->reg_output = reg_val; |
151 | 203 | ||
152 | /* then direction */ | 204 | /* then direction */ |
153 | reg_val = chip->reg_direction & ~(1u << off); | 205 | reg_val = chip->reg_direction & ~(1u << off); |
154 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | 206 | switch (chip->chip_type) { |
207 | case PCA953X_TYPE: | ||
208 | offset = PCA953X_DIRECTION; | ||
209 | break; | ||
210 | case PCA957X_TYPE: | ||
211 | offset = PCA957X_CFG; | ||
212 | break; | ||
213 | } | ||
214 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
155 | if (ret) | 215 | if (ret) |
156 | return ret; | 216 | goto exit; |
157 | 217 | ||
158 | chip->reg_direction = reg_val; | 218 | chip->reg_direction = reg_val; |
159 | return 0; | 219 | ret = 0; |
220 | exit: | ||
221 | mutex_unlock(&chip->i2c_lock); | ||
222 | return ret; | ||
160 | } | 223 | } |
161 | 224 | ||
162 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | 225 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) |
163 | { | 226 | { |
164 | struct pca953x_chip *chip; | 227 | struct pca953x_chip *chip; |
165 | uint16_t reg_val; | 228 | uint16_t reg_val; |
166 | int ret; | 229 | int ret, offset = 0; |
167 | 230 | ||
168 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 231 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
169 | 232 | ||
170 | ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); | 233 | mutex_lock(&chip->i2c_lock); |
234 | switch (chip->chip_type) { | ||
235 | case PCA953X_TYPE: | ||
236 | offset = PCA953X_INPUT; | ||
237 | break; | ||
238 | case PCA957X_TYPE: | ||
239 | offset = PCA957X_IN; | ||
240 | break; | ||
241 | } | ||
242 | ret = pca953x_read_reg(chip, offset, ®_val); | ||
243 | mutex_unlock(&chip->i2c_lock); | ||
171 | if (ret < 0) { | 244 | if (ret < 0) { |
172 | /* NOTE: diagnostic already emitted; that's all we should | 245 | /* NOTE: diagnostic already emitted; that's all we should |
173 | * do unless gpio_*_value_cansleep() calls become different | 246 | * do unless gpio_*_value_cansleep() calls become different |
@@ -183,20 +256,31 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | |||
183 | { | 256 | { |
184 | struct pca953x_chip *chip; | 257 | struct pca953x_chip *chip; |
185 | uint16_t reg_val; | 258 | uint16_t reg_val; |
186 | int ret; | 259 | int ret, offset = 0; |
187 | 260 | ||
188 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | 261 | chip = container_of(gc, struct pca953x_chip, gpio_chip); |
189 | 262 | ||
263 | mutex_lock(&chip->i2c_lock); | ||
190 | if (val) | 264 | if (val) |
191 | reg_val = chip->reg_output | (1u << off); | 265 | reg_val = chip->reg_output | (1u << off); |
192 | else | 266 | else |
193 | reg_val = chip->reg_output & ~(1u << off); | 267 | reg_val = chip->reg_output & ~(1u << off); |
194 | 268 | ||
195 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | 269 | switch (chip->chip_type) { |
270 | case PCA953X_TYPE: | ||
271 | offset = PCA953X_OUTPUT; | ||
272 | break; | ||
273 | case PCA957X_TYPE: | ||
274 | offset = PCA957X_OUT; | ||
275 | break; | ||
276 | } | ||
277 | ret = pca953x_write_reg(chip, offset, reg_val); | ||
196 | if (ret) | 278 | if (ret) |
197 | return; | 279 | goto exit; |
198 | 280 | ||
199 | chip->reg_output = reg_val; | 281 | chip->reg_output = reg_val; |
282 | exit: | ||
283 | mutex_unlock(&chip->i2c_lock); | ||
200 | } | 284 | } |
201 | 285 | ||
202 | static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) | 286 | static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) |
@@ -228,30 +312,30 @@ static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off) | |||
228 | return chip->irq_base + off; | 312 | return chip->irq_base + off; |
229 | } | 313 | } |
230 | 314 | ||
231 | static void pca953x_irq_mask(unsigned int irq) | 315 | static void pca953x_irq_mask(struct irq_data *d) |
232 | { | 316 | { |
233 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 317 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
234 | 318 | ||
235 | chip->irq_mask &= ~(1 << (irq - chip->irq_base)); | 319 | chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); |
236 | } | 320 | } |
237 | 321 | ||
238 | static void pca953x_irq_unmask(unsigned int irq) | 322 | static void pca953x_irq_unmask(struct irq_data *d) |
239 | { | 323 | { |
240 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 324 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
241 | 325 | ||
242 | chip->irq_mask |= 1 << (irq - chip->irq_base); | 326 | chip->irq_mask |= 1 << (d->irq - chip->irq_base); |
243 | } | 327 | } |
244 | 328 | ||
245 | static void pca953x_irq_bus_lock(unsigned int irq) | 329 | static void pca953x_irq_bus_lock(struct irq_data *d) |
246 | { | 330 | { |
247 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 331 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
248 | 332 | ||
249 | mutex_lock(&chip->irq_lock); | 333 | mutex_lock(&chip->irq_lock); |
250 | } | 334 | } |
251 | 335 | ||
252 | static void pca953x_irq_bus_sync_unlock(unsigned int irq) | 336 | static void pca953x_irq_bus_sync_unlock(struct irq_data *d) |
253 | { | 337 | { |
254 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 338 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
255 | uint16_t new_irqs; | 339 | uint16_t new_irqs; |
256 | uint16_t level; | 340 | uint16_t level; |
257 | 341 | ||
@@ -268,15 +352,15 @@ static void pca953x_irq_bus_sync_unlock(unsigned int irq) | |||
268 | mutex_unlock(&chip->irq_lock); | 352 | mutex_unlock(&chip->irq_lock); |
269 | } | 353 | } |
270 | 354 | ||
271 | static int pca953x_irq_set_type(unsigned int irq, unsigned int type) | 355 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
272 | { | 356 | { |
273 | struct pca953x_chip *chip = get_irq_chip_data(irq); | 357 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
274 | uint16_t level = irq - chip->irq_base; | 358 | uint16_t level = d->irq - chip->irq_base; |
275 | uint16_t mask = 1 << level; | 359 | uint16_t mask = 1 << level; |
276 | 360 | ||
277 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 361 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
278 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 362 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
279 | irq, type); | 363 | d->irq, type); |
280 | return -EINVAL; | 364 | return -EINVAL; |
281 | } | 365 | } |
282 | 366 | ||
@@ -295,11 +379,11 @@ static int pca953x_irq_set_type(unsigned int irq, unsigned int type) | |||
295 | 379 | ||
296 | static struct irq_chip pca953x_irq_chip = { | 380 | static struct irq_chip pca953x_irq_chip = { |
297 | .name = "pca953x", | 381 | .name = "pca953x", |
298 | .mask = pca953x_irq_mask, | 382 | .irq_mask = pca953x_irq_mask, |
299 | .unmask = pca953x_irq_unmask, | 383 | .irq_unmask = pca953x_irq_unmask, |
300 | .bus_lock = pca953x_irq_bus_lock, | 384 | .irq_bus_lock = pca953x_irq_bus_lock, |
301 | .bus_sync_unlock = pca953x_irq_bus_sync_unlock, | 385 | .irq_bus_sync_unlock = pca953x_irq_bus_sync_unlock, |
302 | .set_type = pca953x_irq_set_type, | 386 | .irq_set_type = pca953x_irq_set_type, |
303 | }; | 387 | }; |
304 | 388 | ||
305 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | 389 | static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) |
@@ -308,9 +392,17 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip) | |||
308 | uint16_t old_stat; | 392 | uint16_t old_stat; |
309 | uint16_t pending; | 393 | uint16_t pending; |
310 | uint16_t trigger; | 394 | uint16_t trigger; |
311 | int ret; | 395 | int ret, offset = 0; |
312 | 396 | ||
313 | ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat); | 397 | switch (chip->chip_type) { |
398 | case PCA953X_TYPE: | ||
399 | offset = PCA953X_INPUT; | ||
400 | break; | ||
401 | case PCA957X_TYPE: | ||
402 | offset = PCA957X_IN; | ||
403 | break; | ||
404 | } | ||
405 | ret = pca953x_read_reg(chip, offset, &cur_stat); | ||
314 | if (ret) | 406 | if (ret) |
315 | return 0; | 407 | return 0; |
316 | 408 | ||
@@ -345,7 +437,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
345 | 437 | ||
346 | do { | 438 | do { |
347 | level = __ffs(pending); | 439 | level = __ffs(pending); |
348 | handle_nested_irq(level + chip->irq_base); | 440 | generic_handle_irq(level + chip->irq_base); |
349 | 441 | ||
350 | pending &= ~(1 << level); | 442 | pending &= ~(1 << level); |
351 | } while (pending); | 443 | } while (pending); |
@@ -358,13 +450,21 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
358 | { | 450 | { |
359 | struct i2c_client *client = chip->client; | 451 | struct i2c_client *client = chip->client; |
360 | struct pca953x_platform_data *pdata = client->dev.platform_data; | 452 | struct pca953x_platform_data *pdata = client->dev.platform_data; |
361 | int ret; | 453 | int ret, offset = 0; |
362 | 454 | ||
363 | if (pdata->irq_base && (id->driver_data & PCA953X_INT)) { | 455 | if (pdata->irq_base != -1 |
456 | && (id->driver_data & PCA_INT)) { | ||
364 | int lvl; | 457 | int lvl; |
365 | 458 | ||
366 | ret = pca953x_read_reg(chip, PCA953X_INPUT, | 459 | switch (chip->chip_type) { |
367 | &chip->irq_stat); | 460 | case PCA953X_TYPE: |
461 | offset = PCA953X_INPUT; | ||
462 | break; | ||
463 | case PCA957X_TYPE: | ||
464 | offset = PCA957X_IN; | ||
465 | break; | ||
466 | } | ||
467 | ret = pca953x_read_reg(chip, offset, &chip->irq_stat); | ||
368 | if (ret) | 468 | if (ret) |
369 | goto out_failed; | 469 | goto out_failed; |
370 | 470 | ||
@@ -380,20 +480,20 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
380 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { | 480 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { |
381 | int irq = lvl + chip->irq_base; | 481 | int irq = lvl + chip->irq_base; |
382 | 482 | ||
383 | set_irq_chip_data(irq, chip); | 483 | irq_set_chip_data(irq, chip); |
384 | set_irq_chip_and_handler(irq, &pca953x_irq_chip, | 484 | irq_set_chip_and_handler(irq, &pca953x_irq_chip, |
385 | handle_edge_irq); | 485 | handle_simple_irq); |
386 | set_irq_nested_thread(irq, 1); | ||
387 | #ifdef CONFIG_ARM | 486 | #ifdef CONFIG_ARM |
388 | set_irq_flags(irq, IRQF_VALID); | 487 | set_irq_flags(irq, IRQF_VALID); |
389 | #else | 488 | #else |
390 | set_irq_noprobe(irq); | 489 | irq_set_noprobe(irq); |
391 | #endif | 490 | #endif |
392 | } | 491 | } |
393 | 492 | ||
394 | ret = request_threaded_irq(client->irq, | 493 | ret = request_threaded_irq(client->irq, |
395 | NULL, | 494 | NULL, |
396 | pca953x_irq_handler, | 495 | pca953x_irq_handler, |
496 | IRQF_TRIGGER_RISING | | ||
397 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 497 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
398 | dev_name(&client->dev), chip); | 498 | dev_name(&client->dev), chip); |
399 | if (ret) { | 499 | if (ret) { |
@@ -408,13 +508,13 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
408 | return 0; | 508 | return 0; |
409 | 509 | ||
410 | out_failed: | 510 | out_failed: |
411 | chip->irq_base = 0; | 511 | chip->irq_base = -1; |
412 | return ret; | 512 | return ret; |
413 | } | 513 | } |
414 | 514 | ||
415 | static void pca953x_irq_teardown(struct pca953x_chip *chip) | 515 | static void pca953x_irq_teardown(struct pca953x_chip *chip) |
416 | { | 516 | { |
417 | if (chip->irq_base) | 517 | if (chip->irq_base != -1) |
418 | free_irq(chip->client->irq, chip); | 518 | free_irq(chip->client->irq, chip); |
419 | } | 519 | } |
420 | #else /* CONFIG_GPIO_PCA953X_IRQ */ | 520 | #else /* CONFIG_GPIO_PCA953X_IRQ */ |
@@ -424,7 +524,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
424 | struct i2c_client *client = chip->client; | 524 | struct i2c_client *client = chip->client; |
425 | struct pca953x_platform_data *pdata = client->dev.platform_data; | 525 | struct pca953x_platform_data *pdata = client->dev.platform_data; |
426 | 526 | ||
427 | if (pdata->irq_base && (id->driver_data & PCA953X_INT)) | 527 | if (pdata->irq_base != -1 && (id->driver_data & PCA_INT)) |
428 | dev_warn(&client->dev, "interrupt support not compiled in\n"); | 528 | dev_warn(&client->dev, "interrupt support not compiled in\n"); |
429 | 529 | ||
430 | return 0; | 530 | return 0; |
@@ -447,7 +547,8 @@ pca953x_get_alt_pdata(struct i2c_client *client) | |||
447 | { | 547 | { |
448 | struct pca953x_platform_data *pdata; | 548 | struct pca953x_platform_data *pdata; |
449 | struct device_node *node; | 549 | struct device_node *node; |
450 | const uint16_t *val; | 550 | const __be32 *val; |
551 | int size; | ||
451 | 552 | ||
452 | node = client->dev.of_node; | 553 | node = client->dev.of_node; |
453 | if (node == NULL) | 554 | if (node == NULL) |
@@ -460,13 +561,13 @@ pca953x_get_alt_pdata(struct i2c_client *client) | |||
460 | } | 561 | } |
461 | 562 | ||
462 | pdata->gpio_base = -1; | 563 | pdata->gpio_base = -1; |
463 | val = of_get_property(node, "linux,gpio-base", NULL); | 564 | val = of_get_property(node, "linux,gpio-base", &size); |
464 | if (val) { | 565 | if (val) { |
465 | if (*val < 0) | 566 | if (size != sizeof(*val)) |
466 | dev_warn(&client->dev, | 567 | dev_warn(&client->dev, "%s: wrong linux,gpio-base\n", |
467 | "invalid gpio-base in device tree\n"); | 568 | node->full_name); |
468 | else | 569 | else |
469 | pdata->gpio_base = *val; | 570 | pdata->gpio_base = be32_to_cpup(val); |
470 | } | 571 | } |
471 | 572 | ||
472 | val = of_get_property(node, "polarity", NULL); | 573 | val = of_get_property(node, "polarity", NULL); |
@@ -483,12 +584,65 @@ pca953x_get_alt_pdata(struct i2c_client *client) | |||
483 | } | 584 | } |
484 | #endif | 585 | #endif |
485 | 586 | ||
587 | static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) | ||
588 | { | ||
589 | int ret; | ||
590 | |||
591 | ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); | ||
592 | if (ret) | ||
593 | goto out; | ||
594 | |||
595 | ret = pca953x_read_reg(chip, PCA953X_DIRECTION, | ||
596 | &chip->reg_direction); | ||
597 | if (ret) | ||
598 | goto out; | ||
599 | |||
600 | /* set platform specific polarity inversion */ | ||
601 | ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); | ||
602 | if (ret) | ||
603 | goto out; | ||
604 | return 0; | ||
605 | out: | ||
606 | return ret; | ||
607 | } | ||
608 | |||
609 | static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert) | ||
610 | { | ||
611 | int ret; | ||
612 | uint16_t val = 0; | ||
613 | |||
614 | /* Let every port in proper state, that could save power */ | ||
615 | pca953x_write_reg(chip, PCA957X_PUPD, 0x0); | ||
616 | pca953x_write_reg(chip, PCA957X_CFG, 0xffff); | ||
617 | pca953x_write_reg(chip, PCA957X_OUT, 0x0); | ||
618 | |||
619 | ret = pca953x_read_reg(chip, PCA957X_IN, &val); | ||
620 | if (ret) | ||
621 | goto out; | ||
622 | ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output); | ||
623 | if (ret) | ||
624 | goto out; | ||
625 | ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction); | ||
626 | if (ret) | ||
627 | goto out; | ||
628 | |||
629 | /* set platform specific polarity inversion */ | ||
630 | pca953x_write_reg(chip, PCA957X_INVRT, invert); | ||
631 | |||
632 | /* To enable register 6, 7 to controll pull up and pull down */ | ||
633 | pca953x_write_reg(chip, PCA957X_BKEN, 0x202); | ||
634 | |||
635 | return 0; | ||
636 | out: | ||
637 | return ret; | ||
638 | } | ||
639 | |||
486 | static int __devinit pca953x_probe(struct i2c_client *client, | 640 | static int __devinit pca953x_probe(struct i2c_client *client, |
487 | const struct i2c_device_id *id) | 641 | const struct i2c_device_id *id) |
488 | { | 642 | { |
489 | struct pca953x_platform_data *pdata; | 643 | struct pca953x_platform_data *pdata; |
490 | struct pca953x_chip *chip; | 644 | struct pca953x_chip *chip; |
491 | int ret; | 645 | int ret = 0; |
492 | 646 | ||
493 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | 647 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); |
494 | if (chip == NULL) | 648 | if (chip == NULL) |
@@ -515,23 +669,20 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
515 | chip->gpio_start = pdata->gpio_base; | 669 | chip->gpio_start = pdata->gpio_base; |
516 | 670 | ||
517 | chip->names = pdata->names; | 671 | chip->names = pdata->names; |
672 | chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE); | ||
673 | |||
674 | mutex_init(&chip->i2c_lock); | ||
518 | 675 | ||
519 | /* initialize cached registers from their original values. | 676 | /* initialize cached registers from their original values. |
520 | * we can't share this chip with another i2c master. | 677 | * we can't share this chip with another i2c master. |
521 | */ | 678 | */ |
522 | pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS); | 679 | pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); |
523 | |||
524 | ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); | ||
525 | if (ret) | ||
526 | goto out_failed; | ||
527 | 680 | ||
528 | ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); | 681 | if (chip->chip_type == PCA953X_TYPE) |
529 | if (ret) | 682 | device_pca953x_init(chip, pdata->invert); |
530 | goto out_failed; | 683 | else if (chip->chip_type == PCA957X_TYPE) |
531 | 684 | device_pca957x_init(chip, pdata->invert); | |
532 | /* set platform specific polarity inversion */ | 685 | else |
533 | ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); | ||
534 | if (ret) | ||
535 | goto out_failed; | 686 | goto out_failed; |
536 | 687 | ||
537 | ret = pca953x_irq_setup(chip, id); | 688 | ret = pca953x_irq_setup(chip, id); |
@@ -540,7 +691,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
540 | 691 | ||
541 | ret = gpiochip_add(&chip->gpio_chip); | 692 | ret = gpiochip_add(&chip->gpio_chip); |
542 | if (ret) | 693 | if (ret) |
543 | goto out_failed; | 694 | goto out_failed_irq; |
544 | 695 | ||
545 | if (pdata->setup) { | 696 | if (pdata->setup) { |
546 | ret = pdata->setup(client, chip->gpio_chip.base, | 697 | ret = pdata->setup(client, chip->gpio_chip.base, |
@@ -552,8 +703,9 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
552 | i2c_set_clientdata(client, chip); | 703 | i2c_set_clientdata(client, chip); |
553 | return 0; | 704 | return 0; |
554 | 705 | ||
555 | out_failed: | 706 | out_failed_irq: |
556 | pca953x_irq_teardown(chip); | 707 | pca953x_irq_teardown(chip); |
708 | out_failed: | ||
557 | kfree(chip->dyn_pdata); | 709 | kfree(chip->dyn_pdata); |
558 | kfree(chip); | 710 | kfree(chip); |
559 | return ret; | 711 | return ret; |