blob: e9d6d5bdd300e86d5a4f86a71c50e80c1184a3a3 [file] [log] [blame]
eric miao9e60fdc2008-02-04 22:28:26 -08001/*
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -08002 * pca953x.c - 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>
16#include <linux/i2c.h>
Guennadi Liakhovetskid1c057e32008-02-06 01:39:02 -080017#include <linux/i2c/pca953x.h>
Nate Case1965d302009-06-17 16:26:17 -070018#ifdef CONFIG_OF_GPIO
19#include <linux/of_platform.h>
20#include <linux/of_gpio.h>
21#endif
eric miao9e60fdc2008-02-04 22:28:26 -080022
23#include <asm/gpio.h>
24
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080025#define PCA953X_INPUT 0
26#define PCA953X_OUTPUT 1
27#define PCA953X_INVERT 2
28#define PCA953X_DIRECTION 3
eric miao9e60fdc2008-02-04 22:28:26 -080029
Jean Delvare3760f732008-04-29 23:11:40 +020030static const struct i2c_device_id pca953x_id[] = {
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080031 { "pca9534", 8, },
32 { "pca9535", 16, },
33 { "pca9536", 4, },
34 { "pca9537", 4, },
35 { "pca9538", 8, },
36 { "pca9539", 16, },
David Brownell69292b32008-05-23 13:04:42 -070037 { "pca9554", 8, },
Will Newtonf39e5782008-05-01 04:35:10 -070038 { "pca9555", 16, },
39 { "pca9557", 8, },
David Brownellab5dc3722009-01-06 14:42:27 -080040
David Brownell7059d4b2008-07-04 09:59:37 -070041 { "max7310", 8, },
David Brownellab5dc3722009-01-06 14:42:27 -080042 { "pca6107", 8, },
43 { "tca6408", 8, },
44 { "tca6416", 16, },
45 /* NYET: { "tca6424", 24, }, */
Jean Delvare3760f732008-04-29 23:11:40 +020046 { }
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080047};
Jean Delvare3760f732008-04-29 23:11:40 +020048MODULE_DEVICE_TABLE(i2c, pca953x_id);
eric miao9e60fdc2008-02-04 22:28:26 -080049
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -080050struct pca953x_chip {
eric miao9e60fdc2008-02-04 22:28:26 -080051 unsigned gpio_start;
52 uint16_t reg_output;
53 uint16_t reg_direction;
54
55 struct i2c_client *client;
Nate Case1965d302009-06-17 16:26:17 -070056 struct pca953x_platform_data *dyn_pdata;
eric miao9e60fdc2008-02-04 22:28:26 -080057 struct gpio_chip gpio_chip;
Daniel Silverstone77906a542009-06-17 16:26:15 -070058 char **names;
eric miao9e60fdc2008-02-04 22:28:26 -080059};
60
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -080061static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
eric miao9e60fdc2008-02-04 22:28:26 -080062{
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080063 int ret;
64
65 if (chip->gpio_chip.ngpio <= 8)
66 ret = i2c_smbus_write_byte_data(chip->client, reg, val);
eric miao9e60fdc2008-02-04 22:28:26 -080067 else
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080068 ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
69
70 if (ret < 0) {
71 dev_err(&chip->client->dev, "failed writing register\n");
David Brownellab5dc3722009-01-06 14:42:27 -080072 return ret;
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080073 }
74
75 return 0;
eric miao9e60fdc2008-02-04 22:28:26 -080076}
77
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -080078static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val)
eric miao9e60fdc2008-02-04 22:28:26 -080079{
80 int ret;
81
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -080082 if (chip->gpio_chip.ngpio <= 8)
83 ret = i2c_smbus_read_byte_data(chip->client, reg);
84 else
85 ret = i2c_smbus_read_word_data(chip->client, reg << 1);
86
eric miao9e60fdc2008-02-04 22:28:26 -080087 if (ret < 0) {
88 dev_err(&chip->client->dev, "failed reading register\n");
David Brownellab5dc3722009-01-06 14:42:27 -080089 return ret;
eric miao9e60fdc2008-02-04 22:28:26 -080090 }
91
92 *val = (uint16_t)ret;
93 return 0;
94}
95
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -080096static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
eric miao9e60fdc2008-02-04 22:28:26 -080097{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -080098 struct pca953x_chip *chip;
eric miao9e60fdc2008-02-04 22:28:26 -080099 uint16_t reg_val;
100 int ret;
101
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800102 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800103
104 reg_val = chip->reg_direction | (1u << off);
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800105 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800106 if (ret)
107 return ret;
108
109 chip->reg_direction = reg_val;
110 return 0;
111}
112
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800113static int pca953x_gpio_direction_output(struct gpio_chip *gc,
eric miao9e60fdc2008-02-04 22:28:26 -0800114 unsigned off, int val)
115{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800116 struct pca953x_chip *chip;
eric miao9e60fdc2008-02-04 22:28:26 -0800117 uint16_t reg_val;
118 int ret;
119
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800120 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800121
122 /* set output level */
123 if (val)
124 reg_val = chip->reg_output | (1u << off);
125 else
126 reg_val = chip->reg_output & ~(1u << off);
127
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800128 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800129 if (ret)
130 return ret;
131
132 chip->reg_output = reg_val;
133
134 /* then direction */
135 reg_val = chip->reg_direction & ~(1u << off);
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800136 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800137 if (ret)
138 return ret;
139
140 chip->reg_direction = reg_val;
141 return 0;
142}
143
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800144static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
eric miao9e60fdc2008-02-04 22:28:26 -0800145{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800146 struct pca953x_chip *chip;
eric miao9e60fdc2008-02-04 22:28:26 -0800147 uint16_t reg_val;
148 int ret;
149
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800150 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800151
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800152 ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800153 if (ret < 0) {
154 /* NOTE: diagnostic already emitted; that's all we should
155 * do unless gpio_*_value_cansleep() calls become different
156 * from their nonsleeping siblings (and report faults).
157 */
158 return 0;
159 }
160
161 return (reg_val & (1u << off)) ? 1 : 0;
162}
163
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800164static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
eric miao9e60fdc2008-02-04 22:28:26 -0800165{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800166 struct pca953x_chip *chip;
eric miao9e60fdc2008-02-04 22:28:26 -0800167 uint16_t reg_val;
168 int ret;
169
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800170 chip = container_of(gc, struct pca953x_chip, gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800171
172 if (val)
173 reg_val = chip->reg_output | (1u << off);
174 else
175 reg_val = chip->reg_output & ~(1u << off);
176
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800177 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
eric miao9e60fdc2008-02-04 22:28:26 -0800178 if (ret)
179 return;
180
181 chip->reg_output = reg_val;
182}
183
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800184static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
eric miao9e60fdc2008-02-04 22:28:26 -0800185{
186 struct gpio_chip *gc;
187
188 gc = &chip->gpio_chip;
189
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800190 gc->direction_input = pca953x_gpio_direction_input;
191 gc->direction_output = pca953x_gpio_direction_output;
192 gc->get = pca953x_gpio_get_value;
193 gc->set = pca953x_gpio_set_value;
Arnaud Patard84207802008-03-10 11:43:48 -0700194 gc->can_sleep = 1;
eric miao9e60fdc2008-02-04 22:28:26 -0800195
196 gc->base = chip->gpio_start;
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800197 gc->ngpio = gpios;
198 gc->label = chip->client->name;
David Brownelld8f388d82008-07-25 01:46:07 -0700199 gc->dev = &chip->client->dev;
Guennadi Liakhovetskid72cbed2008-04-28 02:14:45 -0700200 gc->owner = THIS_MODULE;
Daniel Silverstone77906a542009-06-17 16:26:15 -0700201 gc->names = chip->names;
eric miao9e60fdc2008-02-04 22:28:26 -0800202}
203
Nate Case1965d302009-06-17 16:26:17 -0700204/*
205 * Handlers for alternative sources of platform_data
206 */
207#ifdef CONFIG_OF_GPIO
208/*
209 * Translate OpenFirmware node properties into platform_data
210 */
211static struct pca953x_platform_data *
212pca953x_get_alt_pdata(struct i2c_client *client)
213{
214 struct pca953x_platform_data *pdata;
215 struct device_node *node;
216 const uint16_t *val;
217
218 node = dev_archdata_get_node(&client->dev.archdata);
219 if (node == NULL)
220 return NULL;
221
222 pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL);
223 if (pdata == NULL) {
224 dev_err(&client->dev, "Unable to allocate platform_data\n");
225 return NULL;
226 }
227
228 pdata->gpio_base = -1;
229 val = of_get_property(node, "linux,gpio-base", NULL);
230 if (val) {
231 if (*val < 0)
232 dev_warn(&client->dev,
233 "invalid gpio-base in device tree\n");
234 else
235 pdata->gpio_base = *val;
236 }
237
238 val = of_get_property(node, "polarity", NULL);
239 if (val)
240 pdata->invert = *val;
241
242 return pdata;
243}
244#else
245static struct pca953x_platform_data *
246pca953x_get_alt_pdata(struct i2c_client *client)
247{
248 return NULL;
249}
250#endif
251
Jean Delvared2653e92008-04-29 23:11:39 +0200252static int __devinit pca953x_probe(struct i2c_client *client,
Jean Delvare3760f732008-04-29 23:11:40 +0200253 const struct i2c_device_id *id)
eric miao9e60fdc2008-02-04 22:28:26 -0800254{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800255 struct pca953x_platform_data *pdata;
256 struct pca953x_chip *chip;
Will Newtonf39e5782008-05-01 04:35:10 -0700257 int ret;
eric miao9e60fdc2008-02-04 22:28:26 -0800258
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800259 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
eric miao9e60fdc2008-02-04 22:28:26 -0800260 if (chip == NULL)
261 return -ENOMEM;
262
Nate Case1965d302009-06-17 16:26:17 -0700263 pdata = client->dev.platform_data;
264 if (pdata == NULL) {
265 pdata = pca953x_get_alt_pdata(client);
266 /*
267 * Unlike normal platform_data, this is allocated
268 * dynamically and must be freed in the driver
269 */
270 chip->dyn_pdata = pdata;
271 }
272
273 if (pdata == NULL) {
274 dev_dbg(&client->dev, "no platform data\n");
275 ret = -EINVAL;
276 goto out_failed;
277 }
278
eric miao9e60fdc2008-02-04 22:28:26 -0800279 chip->client = client;
280
281 chip->gpio_start = pdata->gpio_base;
282
Daniel Silverstone77906a542009-06-17 16:26:15 -0700283 chip->names = pdata->names;
284
eric miao9e60fdc2008-02-04 22:28:26 -0800285 /* initialize cached registers from their original values.
286 * we can't share this chip with another i2c master.
287 */
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800288 pca953x_setup_gpio(chip, id->driver_data);
289
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800290 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
eric miao9e60fdc2008-02-04 22:28:26 -0800291 if (ret)
292 goto out_failed;
293
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800294 ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
eric miao9e60fdc2008-02-04 22:28:26 -0800295 if (ret)
296 goto out_failed;
297
298 /* set platform specific polarity inversion */
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800299 ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
eric miao9e60fdc2008-02-04 22:28:26 -0800300 if (ret)
301 goto out_failed;
302
Guennadi Liakhovetskif5e8ff42008-02-06 01:39:04 -0800303
304 ret = gpiochip_add(&chip->gpio_chip);
eric miao9e60fdc2008-02-04 22:28:26 -0800305 if (ret)
306 goto out_failed;
307
308 if (pdata->setup) {
309 ret = pdata->setup(client, chip->gpio_chip.base,
310 chip->gpio_chip.ngpio, pdata->context);
311 if (ret < 0)
312 dev_warn(&client->dev, "setup failed, %d\n", ret);
313 }
314
315 i2c_set_clientdata(client, chip);
316 return 0;
317
318out_failed:
Nate Case1965d302009-06-17 16:26:17 -0700319 kfree(chip->dyn_pdata);
eric miao9e60fdc2008-02-04 22:28:26 -0800320 kfree(chip);
321 return ret;
322}
323
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800324static int pca953x_remove(struct i2c_client *client)
eric miao9e60fdc2008-02-04 22:28:26 -0800325{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800326 struct pca953x_platform_data *pdata = client->dev.platform_data;
327 struct pca953x_chip *chip = i2c_get_clientdata(client);
eric miao9e60fdc2008-02-04 22:28:26 -0800328 int ret = 0;
329
330 if (pdata->teardown) {
331 ret = pdata->teardown(client, chip->gpio_chip.base,
332 chip->gpio_chip.ngpio, pdata->context);
333 if (ret < 0) {
334 dev_err(&client->dev, "%s failed, %d\n",
335 "teardown", ret);
336 return ret;
337 }
338 }
339
340 ret = gpiochip_remove(&chip->gpio_chip);
341 if (ret) {
342 dev_err(&client->dev, "%s failed, %d\n",
343 "gpiochip_remove()", ret);
344 return ret;
345 }
346
Nate Case1965d302009-06-17 16:26:17 -0700347 kfree(chip->dyn_pdata);
eric miao9e60fdc2008-02-04 22:28:26 -0800348 kfree(chip);
349 return 0;
350}
351
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800352static struct i2c_driver pca953x_driver = {
eric miao9e60fdc2008-02-04 22:28:26 -0800353 .driver = {
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800354 .name = "pca953x",
eric miao9e60fdc2008-02-04 22:28:26 -0800355 },
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800356 .probe = pca953x_probe,
357 .remove = pca953x_remove,
Jean Delvare3760f732008-04-29 23:11:40 +0200358 .id_table = pca953x_id,
eric miao9e60fdc2008-02-04 22:28:26 -0800359};
360
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800361static int __init pca953x_init(void)
eric miao9e60fdc2008-02-04 22:28:26 -0800362{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800363 return i2c_add_driver(&pca953x_driver);
eric miao9e60fdc2008-02-04 22:28:26 -0800364}
David Brownell2f8d1192008-10-15 22:03:13 -0700365/* register after i2c postcore initcall and before
366 * subsys initcalls that may rely on these GPIOs
367 */
368subsys_initcall(pca953x_init);
eric miao9e60fdc2008-02-04 22:28:26 -0800369
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800370static void __exit pca953x_exit(void)
eric miao9e60fdc2008-02-04 22:28:26 -0800371{
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800372 i2c_del_driver(&pca953x_driver);
eric miao9e60fdc2008-02-04 22:28:26 -0800373}
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800374module_exit(pca953x_exit);
eric miao9e60fdc2008-02-04 22:28:26 -0800375
376MODULE_AUTHOR("eric miao <eric.miao@marvell.com>");
Guennadi Liakhovetskif3dc3632008-02-06 01:39:03 -0800377MODULE_DESCRIPTION("GPIO expander driver for PCA953x");
eric miao9e60fdc2008-02-04 22:28:26 -0800378MODULE_LICENSE("GPL");