aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/pca953x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpio/pca953x.c')
-rw-r--r--drivers/gpio/pca953x.c80
1 files changed, 75 insertions, 5 deletions
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index 8dc0164bd51e..cdb6574d25a6 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -15,6 +15,10 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/i2c.h> 16#include <linux/i2c.h>
17#include <linux/i2c/pca953x.h> 17#include <linux/i2c/pca953x.h>
18#ifdef CONFIG_OF_GPIO
19#include <linux/of_platform.h>
20#include <linux/of_gpio.h>
21#endif
18 22
19#include <asm/gpio.h> 23#include <asm/gpio.h>
20 24
@@ -32,6 +36,7 @@ static const struct i2c_device_id pca953x_id[] = {
32 { "pca9539", 16, }, 36 { "pca9539", 16, },
33 { "pca9554", 8, }, 37 { "pca9554", 8, },
34 { "pca9555", 16, }, 38 { "pca9555", 16, },
39 { "pca9556", 8, },
35 { "pca9557", 8, }, 40 { "pca9557", 8, },
36 41
37 { "max7310", 8, }, 42 { "max7310", 8, },
@@ -49,7 +54,9 @@ struct pca953x_chip {
49 uint16_t reg_direction; 54 uint16_t reg_direction;
50 55
51 struct i2c_client *client; 56 struct i2c_client *client;
57 struct pca953x_platform_data *dyn_pdata;
52 struct gpio_chip gpio_chip; 58 struct gpio_chip gpio_chip;
59 char **names;
53}; 60};
54 61
55static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) 62static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
@@ -192,8 +199,57 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
192 gc->label = chip->client->name; 199 gc->label = chip->client->name;
193 gc->dev = &chip->client->dev; 200 gc->dev = &chip->client->dev;
194 gc->owner = THIS_MODULE; 201 gc->owner = THIS_MODULE;
202 gc->names = chip->names;
195} 203}
196 204
205/*
206 * Handlers for alternative sources of platform_data
207 */
208#ifdef CONFIG_OF_GPIO
209/*
210 * Translate OpenFirmware node properties into platform_data
211 */
212static struct pca953x_platform_data *
213pca953x_get_alt_pdata(struct i2c_client *client)
214{
215 struct pca953x_platform_data *pdata;
216 struct device_node *node;
217 const uint16_t *val;
218
219 node = dev_archdata_get_node(&client->dev.archdata);
220 if (node == NULL)
221 return NULL;
222
223 pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL);
224 if (pdata == NULL) {
225 dev_err(&client->dev, "Unable to allocate platform_data\n");
226 return NULL;
227 }
228
229 pdata->gpio_base = -1;
230 val = of_get_property(node, "linux,gpio-base", NULL);
231 if (val) {
232 if (*val < 0)
233 dev_warn(&client->dev,
234 "invalid gpio-base in device tree\n");
235 else
236 pdata->gpio_base = *val;
237 }
238
239 val = of_get_property(node, "polarity", NULL);
240 if (val)
241 pdata->invert = *val;
242
243 return pdata;
244}
245#else
246static struct pca953x_platform_data *
247pca953x_get_alt_pdata(struct i2c_client *client)
248{
249 return NULL;
250}
251#endif
252
197static int __devinit pca953x_probe(struct i2c_client *client, 253static int __devinit pca953x_probe(struct i2c_client *client,
198 const struct i2c_device_id *id) 254 const struct i2c_device_id *id)
199{ 255{
@@ -201,20 +257,32 @@ static int __devinit pca953x_probe(struct i2c_client *client,
201 struct pca953x_chip *chip; 257 struct pca953x_chip *chip;
202 int ret; 258 int ret;
203 259
260 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
261 if (chip == NULL)
262 return -ENOMEM;
263
204 pdata = client->dev.platform_data; 264 pdata = client->dev.platform_data;
205 if (pdata == NULL) { 265 if (pdata == NULL) {
206 dev_dbg(&client->dev, "no platform data\n"); 266 pdata = pca953x_get_alt_pdata(client);
207 return -EINVAL; 267 /*
268 * Unlike normal platform_data, this is allocated
269 * dynamically and must be freed in the driver
270 */
271 chip->dyn_pdata = pdata;
208 } 272 }
209 273
210 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); 274 if (pdata == NULL) {
211 if (chip == NULL) 275 dev_dbg(&client->dev, "no platform data\n");
212 return -ENOMEM; 276 ret = -EINVAL;
277 goto out_failed;
278 }
213 279
214 chip->client = client; 280 chip->client = client;
215 281
216 chip->gpio_start = pdata->gpio_base; 282 chip->gpio_start = pdata->gpio_base;
217 283
284 chip->names = pdata->names;
285
218 /* initialize cached registers from their original values. 286 /* initialize cached registers from their original values.
219 * we can't share this chip with another i2c master. 287 * we can't share this chip with another i2c master.
220 */ 288 */
@@ -249,6 +317,7 @@ static int __devinit pca953x_probe(struct i2c_client *client,
249 return 0; 317 return 0;
250 318
251out_failed: 319out_failed:
320 kfree(chip->dyn_pdata);
252 kfree(chip); 321 kfree(chip);
253 return ret; 322 return ret;
254} 323}
@@ -276,6 +345,7 @@ static int pca953x_remove(struct i2c_client *client)
276 return ret; 345 return ret;
277 } 346 }
278 347
348 kfree(chip->dyn_pdata);
279 kfree(chip); 349 kfree(chip);
280 return 0; 350 return 0;
281} 351}