aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@marvell.com>2011-04-18 10:12:46 -0400
committerGrant Likely <grant.likely@secretlab.ca>2011-05-26 15:58:30 -0400
commit33226ffd0726508da1eeb660170a63100f4456ac (patch)
treefc89cbb6ba9e62b9cb8d66a7115ea1bc5369223d /drivers/gpio
parent073cc4e95ad5dd2d86f5328b9ea5c9355907c6a2 (diff)
gpio/pca953x: Add support for pca9574 and pca9575 devices
PCA957x is i2c gpio expander, and similar to PCA953x. Although register configurations are different between PCA957x and PCA953x. They can share a lot of components, such as IRQ handling, GPIO IN/OUT. So updating PCA953x driver to support PCA957x chips. Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/pca953x.c249
1 files changed, 191 insertions, 58 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 78a843947d8..0451d7ac94a 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
35static const struct i2c_device_id pca953x_id[] = { 46static 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};
@@ -75,16 +88,32 @@ struct pca953x_chip {
75 struct pca953x_platform_data *dyn_pdata; 88 struct pca953x_platform_data *dyn_pdata;
76 struct gpio_chip gpio_chip; 89 struct gpio_chip gpio_chip;
77 const char *const *names; 90 const char *const *names;
91 int chip_type;
78}; 92};
79 93
80static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) 94static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
81{ 95{
82 int ret; 96 int ret = 0;
83 97
84 if (chip->gpio_chip.ngpio <= 8) 98 if (chip->gpio_chip.ngpio <= 8)
85 ret = i2c_smbus_write_byte_data(chip->client, reg, val); 99 ret = i2c_smbus_write_byte_data(chip->client, reg, val);
86 else 100 else {
87 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 }
88 117
89 if (ret < 0) { 118 if (ret < 0) {
90 dev_err(&chip->client->dev, "failed writing register\n"); 119 dev_err(&chip->client->dev, "failed writing register\n");
@@ -116,13 +145,22 @@ static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
116{ 145{
117 struct pca953x_chip *chip; 146 struct pca953x_chip *chip;
118 uint16_t reg_val; 147 uint16_t reg_val;
119 int ret; 148 int ret, offset = 0;
120 149
121 chip = container_of(gc, struct pca953x_chip, gpio_chip); 150 chip = container_of(gc, struct pca953x_chip, gpio_chip);
122 151
123 mutex_lock(&chip->i2c_lock); 152 mutex_lock(&chip->i2c_lock);
124 reg_val = chip->reg_direction | (1u << off); 153 reg_val = chip->reg_direction | (1u << off);
125 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);
126 if (ret) 164 if (ret)
127 goto exit; 165 goto exit;
128 166
@@ -138,7 +176,7 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
138{ 176{
139 struct pca953x_chip *chip; 177 struct pca953x_chip *chip;
140 uint16_t reg_val; 178 uint16_t reg_val;
141 int ret; 179 int ret, offset = 0;
142 180
143 chip = container_of(gc, struct pca953x_chip, gpio_chip); 181 chip = container_of(gc, struct pca953x_chip, gpio_chip);
144 182
@@ -149,7 +187,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
149 else 187 else
150 reg_val = chip->reg_output & ~(1u << off); 188 reg_val = chip->reg_output & ~(1u << off);
151 189
152 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);
153 if (ret) 199 if (ret)
154 goto exit; 200 goto exit;
155 201
@@ -157,7 +203,15 @@ static int pca953x_gpio_direction_output(struct gpio_chip *gc,
157 203
158 /* then direction */ 204 /* then direction */
159 reg_val = chip->reg_direction & ~(1u << off); 205 reg_val = chip->reg_direction & ~(1u << off);
160 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);
161 if (ret) 215 if (ret)
162 goto exit; 216 goto exit;
163 217
@@ -172,12 +226,20 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
172{ 226{
173 struct pca953x_chip *chip; 227 struct pca953x_chip *chip;
174 uint16_t reg_val; 228 uint16_t reg_val;
175 int ret; 229 int ret, offset = 0;
176 230
177 chip = container_of(gc, struct pca953x_chip, gpio_chip); 231 chip = container_of(gc, struct pca953x_chip, gpio_chip);
178 232
179 mutex_lock(&chip->i2c_lock); 233 mutex_lock(&chip->i2c_lock);
180 ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val); 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, &reg_val);
181 mutex_unlock(&chip->i2c_lock); 243 mutex_unlock(&chip->i2c_lock);
182 if (ret < 0) { 244 if (ret < 0) {
183 /* NOTE: diagnostic already emitted; that's all we should 245 /* NOTE: diagnostic already emitted; that's all we should
@@ -194,7 +256,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
194{ 256{
195 struct pca953x_chip *chip; 257 struct pca953x_chip *chip;
196 uint16_t reg_val; 258 uint16_t reg_val;
197 int ret; 259 int ret, offset = 0;
198 260
199 chip = container_of(gc, struct pca953x_chip, gpio_chip); 261 chip = container_of(gc, struct pca953x_chip, gpio_chip);
200 262
@@ -204,7 +266,15 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
204 else 266 else
205 reg_val = chip->reg_output & ~(1u << off); 267 reg_val = chip->reg_output & ~(1u << off);
206 268
207 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);
208 if (ret) 278 if (ret)
209 goto exit; 279 goto exit;
210 280
@@ -322,9 +392,17 @@ static uint16_t pca953x_irq_pending(struct pca953x_chip *chip)
322 uint16_t old_stat; 392 uint16_t old_stat;
323 uint16_t pending; 393 uint16_t pending;
324 uint16_t trigger; 394 uint16_t trigger;
325 int ret; 395 int ret, offset = 0;
326 396
327 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);
328 if (ret) 406 if (ret)
329 return 0; 407 return 0;
330 408
@@ -372,14 +450,21 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
372{ 450{
373 struct i2c_client *client = chip->client; 451 struct i2c_client *client = chip->client;
374 struct pca953x_platform_data *pdata = client->dev.platform_data; 452 struct pca953x_platform_data *pdata = client->dev.platform_data;
375 int ret; 453 int ret, offset = 0;
376 454
377 if (pdata->irq_base != -1 455 if (pdata->irq_base != -1
378 && (id->driver_data & PCA953X_INT)) { 456 && (id->driver_data & PCA_INT)) {
379 int lvl; 457 int lvl;
380 458
381 ret = pca953x_read_reg(chip, PCA953X_INPUT, 459 switch (chip->chip_type) {
382 &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);
383 if (ret) 468 if (ret)
384 goto out_failed; 469 goto out_failed;
385 470
@@ -439,7 +524,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
439 struct i2c_client *client = chip->client; 524 struct i2c_client *client = chip->client;
440 struct pca953x_platform_data *pdata = client->dev.platform_data; 525 struct pca953x_platform_data *pdata = client->dev.platform_data;
441 526
442 if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT)) 527 if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
443 dev_warn(&client->dev, "interrupt support not compiled in\n"); 528 dev_warn(&client->dev, "interrupt support not compiled in\n");
444 529
445 return 0; 530 return 0;
@@ -499,12 +584,65 @@ pca953x_get_alt_pdata(struct i2c_client *client)
499} 584}
500#endif 585#endif
501 586
587static 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;
605out:
606 return ret;
607}
608
609static 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;
636out:
637 return ret;
638}
639
502static int __devinit pca953x_probe(struct i2c_client *client, 640static int __devinit pca953x_probe(struct i2c_client *client,
503 const struct i2c_device_id *id) 641 const struct i2c_device_id *id)
504{ 642{
505 struct pca953x_platform_data *pdata; 643 struct pca953x_platform_data *pdata;
506 struct pca953x_chip *chip; 644 struct pca953x_chip *chip;
507 int ret; 645 int ret = 0;
508 646
509 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); 647 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
510 if (chip == NULL) 648 if (chip == NULL)
@@ -531,25 +669,20 @@ static int __devinit pca953x_probe(struct i2c_client *client,
531 chip->gpio_start = pdata->gpio_base; 669 chip->gpio_start = pdata->gpio_base;
532 670
533 chip->names = pdata->names; 671 chip->names = pdata->names;
672 chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
534 673
535 mutex_init(&chip->i2c_lock); 674 mutex_init(&chip->i2c_lock);
536 675
537 /* initialize cached registers from their original values. 676 /* initialize cached registers from their original values.
538 * we can't share this chip with another i2c master. 677 * we can't share this chip with another i2c master.
539 */ 678 */
540 pca953x_setup_gpio(chip, id->driver_data & PCA953X_GPIOS); 679 pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
541 680
542 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); 681 if (chip->chip_type == PCA953X_TYPE)
543 if (ret) 682 device_pca953x_init(chip, pdata->invert);
544 goto out_failed; 683 else if (chip->chip_type == PCA957X_TYPE)
545 684 device_pca957x_init(chip, pdata->invert);
546 ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); 685 else
547 if (ret)
548 goto out_failed;
549
550 /* set platform specific polarity inversion */
551 ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
552 if (ret)
553 goto out_failed; 686 goto out_failed;
554 687
555 ret = pca953x_irq_setup(chip, id); 688 ret = pca953x_irq_setup(chip, id);