aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/pca953x.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index ef1fe24bcbaf..92583cd4bffd 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * pca953x.c - 16-bit I/O port with interrupt and reset 2 * pca953x.c - 4/8/16 bit I/O ports
3 * 3 *
4 * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> 4 * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
5 * Copyright (C) 2007 Marvell International Ltd. 5 * Copyright (C) 2007 Marvell International Ltd.
@@ -18,13 +18,26 @@
18 18
19#include <asm/gpio.h> 19#include <asm/gpio.h>
20 20
21#define PCA953X_INPUT 0
22#define PCA953X_OUTPUT 1
23#define PCA953X_INVERT 2
24#define PCA953X_DIRECTION 3
21 25
22#define NR_PCA953X_GPIOS 16 26/* This is temporary - in 2.6.26 i2c_driver_data should replace it. */
27struct pca953x_desc {
28 char name[I2C_NAME_SIZE];
29 unsigned long driver_data;
30};
23 31
24#define PCA953X_INPUT 0 32static const struct pca953x_desc pca953x_descs[] = {
25#define PCA953X_OUTPUT 2 33 { "pca9534", 8, },
26#define PCA953X_INVERT 4 34 { "pca9535", 16, },
27#define PCA953X_DIRECTION 6 35 { "pca9536", 4, },
36 { "pca9537", 4, },
37 { "pca9538", 8, },
38 { "pca9539", 16, },
39 /* REVISIT several pca955x parts should work here too */
40};
28 41
29struct pca953x_chip { 42struct pca953x_chip {
30 unsigned gpio_start; 43 unsigned gpio_start;
@@ -40,17 +53,30 @@ struct pca953x_chip {
40 */ 53 */
41static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) 54static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
42{ 55{
43 if (i2c_smbus_write_word_data(chip->client, reg, val) < 0) 56 int ret;
44 return -EIO; 57
58 if (chip->gpio_chip.ngpio <= 8)
59 ret = i2c_smbus_write_byte_data(chip->client, reg, val);
45 else 60 else
46 return 0; 61 ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
62
63 if (ret < 0) {
64 dev_err(&chip->client->dev, "failed writing register\n");
65 return -EIO;
66 }
67
68 return 0;
47} 69}
48 70
49static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) 71static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val)
50{ 72{
51 int ret; 73 int ret;
52 74
53 ret = i2c_smbus_read_word_data(chip->client, reg); 75 if (chip->gpio_chip.ngpio <= 8)
76 ret = i2c_smbus_read_byte_data(chip->client, reg);
77 else
78 ret = i2c_smbus_read_word_data(chip->client, reg << 1);
79
54 if (ret < 0) { 80 if (ret < 0) {
55 dev_err(&chip->client->dev, "failed reading register\n"); 81 dev_err(&chip->client->dev, "failed reading register\n");
56 return -EIO; 82 return -EIO;
@@ -148,7 +174,7 @@ static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
148 chip->reg_output = reg_val; 174 chip->reg_output = reg_val;
149} 175}
150 176
151static int pca953x_init_gpio(struct pca953x_chip *chip) 177static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
152{ 178{
153 struct gpio_chip *gc; 179 struct gpio_chip *gc;
154 180
@@ -160,22 +186,30 @@ static int pca953x_init_gpio(struct pca953x_chip *chip)
160 gc->set = pca953x_gpio_set_value; 186 gc->set = pca953x_gpio_set_value;
161 187
162 gc->base = chip->gpio_start; 188 gc->base = chip->gpio_start;
163 gc->ngpio = NR_PCA953X_GPIOS; 189 gc->ngpio = gpios;
164 gc->label = "pca953x"; 190 gc->label = chip->client->name;
165
166 return gpiochip_add(gc);
167} 191}
168 192
169static int __devinit pca953x_probe(struct i2c_client *client) 193static int __devinit pca953x_probe(struct i2c_client *client)
170{ 194{
171 struct pca953x_platform_data *pdata; 195 struct pca953x_platform_data *pdata;
172 struct pca953x_chip *chip; 196 struct pca953x_chip *chip;
173 int ret; 197 int ret, i;
198 const struct pca953x_desc *id = NULL;
174 199
175 pdata = client->dev.platform_data; 200 pdata = client->dev.platform_data;
176 if (pdata == NULL) 201 if (pdata == NULL)
177 return -ENODEV; 202 return -ENODEV;
178 203
204 /* this loop vanishes when we get i2c_device_id */
205 for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++)
206 if (!strcmp(pca953x_descs[i].name, client->name)) {
207 id = pca953x_descs + i;
208 break;
209 }
210 if (!id)
211 return -ENODEV;
212
179 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); 213 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
180 if (chip == NULL) 214 if (chip == NULL)
181 return -ENOMEM; 215 return -ENOMEM;
@@ -187,6 +221,8 @@ static int __devinit pca953x_probe(struct i2c_client *client)
187 /* initialize cached registers from their original values. 221 /* initialize cached registers from their original values.
188 * we can't share this chip with another i2c master. 222 * we can't share this chip with another i2c master.
189 */ 223 */
224 pca953x_setup_gpio(chip, id->driver_data);
225
190 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); 226 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
191 if (ret) 227 if (ret)
192 goto out_failed; 228 goto out_failed;
@@ -200,7 +236,8 @@ static int __devinit pca953x_probe(struct i2c_client *client)
200 if (ret) 236 if (ret)
201 goto out_failed; 237 goto out_failed;
202 238
203 ret = pca953x_init_gpio(chip); 239
240 ret = gpiochip_add(&chip->gpio_chip);
204 if (ret) 241 if (ret)
205 goto out_failed; 242 goto out_failed;
206 243