gpio: pca953x: add support for MAX7315
[deliverable/linux.git] / drivers / gpio / pca953x.c
... / ...
CommitLineData
1/*
2 * pca953x.c - 4/8/16 bit I/O ports
3 *
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>
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
22
23#include <asm/gpio.h>
24
25#define PCA953X_INPUT 0
26#define PCA953X_OUTPUT 1
27#define PCA953X_INVERT 2
28#define PCA953X_DIRECTION 3
29
30static const struct i2c_device_id pca953x_id[] = {
31 { "pca9534", 8, },
32 { "pca9535", 16, },
33 { "pca9536", 4, },
34 { "pca9537", 4, },
35 { "pca9538", 8, },
36 { "pca9539", 16, },
37 { "pca9554", 8, },
38 { "pca9555", 16, },
39 { "pca9556", 8, },
40 { "pca9557", 8, },
41
42 { "max7310", 8, },
43 { "max7315", 8, },
44 { "pca6107", 8, },
45 { "tca6408", 8, },
46 { "tca6416", 16, },
47 /* NYET: { "tca6424", 24, }, */
48 { }
49};
50MODULE_DEVICE_TABLE(i2c, pca953x_id);
51
52struct pca953x_chip {
53 unsigned gpio_start;
54 uint16_t reg_output;
55 uint16_t reg_direction;
56
57 struct i2c_client *client;
58 struct pca953x_platform_data *dyn_pdata;
59 struct gpio_chip gpio_chip;
60 char **names;
61};
62
63static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
64{
65 int ret;
66
67 if (chip->gpio_chip.ngpio <= 8)
68 ret = i2c_smbus_write_byte_data(chip->client, reg, val);
69 else
70 ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
71
72 if (ret < 0) {
73 dev_err(&chip->client->dev, "failed writing register\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val)
81{
82 int ret;
83
84 if (chip->gpio_chip.ngpio <= 8)
85 ret = i2c_smbus_read_byte_data(chip->client, reg);
86 else
87 ret = i2c_smbus_read_word_data(chip->client, reg << 1);
88
89 if (ret < 0) {
90 dev_err(&chip->client->dev, "failed reading register\n");
91 return ret;
92 }
93
94 *val = (uint16_t)ret;
95 return 0;
96}
97
98static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
99{
100 struct pca953x_chip *chip;
101 uint16_t reg_val;
102 int ret;
103
104 chip = container_of(gc, struct pca953x_chip, gpio_chip);
105
106 reg_val = chip->reg_direction | (1u << off);
107 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
108 if (ret)
109 return ret;
110
111 chip->reg_direction = reg_val;
112 return 0;
113}
114
115static int pca953x_gpio_direction_output(struct gpio_chip *gc,
116 unsigned off, int val)
117{
118 struct pca953x_chip *chip;
119 uint16_t reg_val;
120 int ret;
121
122 chip = container_of(gc, struct pca953x_chip, gpio_chip);
123
124 /* set output level */
125 if (val)
126 reg_val = chip->reg_output | (1u << off);
127 else
128 reg_val = chip->reg_output & ~(1u << off);
129
130 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
131 if (ret)
132 return ret;
133
134 chip->reg_output = reg_val;
135
136 /* then direction */
137 reg_val = chip->reg_direction & ~(1u << off);
138 ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
139 if (ret)
140 return ret;
141
142 chip->reg_direction = reg_val;
143 return 0;
144}
145
146static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off)
147{
148 struct pca953x_chip *chip;
149 uint16_t reg_val;
150 int ret;
151
152 chip = container_of(gc, struct pca953x_chip, gpio_chip);
153
154 ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
155 if (ret < 0) {
156 /* NOTE: diagnostic already emitted; that's all we should
157 * do unless gpio_*_value_cansleep() calls become different
158 * from their nonsleeping siblings (and report faults).
159 */
160 return 0;
161 }
162
163 return (reg_val & (1u << off)) ? 1 : 0;
164}
165
166static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
167{
168 struct pca953x_chip *chip;
169 uint16_t reg_val;
170 int ret;
171
172 chip = container_of(gc, struct pca953x_chip, gpio_chip);
173
174 if (val)
175 reg_val = chip->reg_output | (1u << off);
176 else
177 reg_val = chip->reg_output & ~(1u << off);
178
179 ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
180 if (ret)
181 return;
182
183 chip->reg_output = reg_val;
184}
185
186static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios)
187{
188 struct gpio_chip *gc;
189
190 gc = &chip->gpio_chip;
191
192 gc->direction_input = pca953x_gpio_direction_input;
193 gc->direction_output = pca953x_gpio_direction_output;
194 gc->get = pca953x_gpio_get_value;
195 gc->set = pca953x_gpio_set_value;
196 gc->can_sleep = 1;
197
198 gc->base = chip->gpio_start;
199 gc->ngpio = gpios;
200 gc->label = chip->client->name;
201 gc->dev = &chip->client->dev;
202 gc->owner = THIS_MODULE;
203 gc->names = chip->names;
204}
205
206/*
207 * Handlers for alternative sources of platform_data
208 */
209#ifdef CONFIG_OF_GPIO
210/*
211 * Translate OpenFirmware node properties into platform_data
212 */
213static struct pca953x_platform_data *
214pca953x_get_alt_pdata(struct i2c_client *client)
215{
216 struct pca953x_platform_data *pdata;
217 struct device_node *node;
218 const uint16_t *val;
219
220 node = dev_archdata_get_node(&client->dev.archdata);
221 if (node == NULL)
222 return NULL;
223
224 pdata = kzalloc(sizeof(struct pca953x_platform_data), GFP_KERNEL);
225 if (pdata == NULL) {
226 dev_err(&client->dev, "Unable to allocate platform_data\n");
227 return NULL;
228 }
229
230 pdata->gpio_base = -1;
231 val = of_get_property(node, "linux,gpio-base", NULL);
232 if (val) {
233 if (*val < 0)
234 dev_warn(&client->dev,
235 "invalid gpio-base in device tree\n");
236 else
237 pdata->gpio_base = *val;
238 }
239
240 val = of_get_property(node, "polarity", NULL);
241 if (val)
242 pdata->invert = *val;
243
244 return pdata;
245}
246#else
247static struct pca953x_platform_data *
248pca953x_get_alt_pdata(struct i2c_client *client)
249{
250 return NULL;
251}
252#endif
253
254static int __devinit pca953x_probe(struct i2c_client *client,
255 const struct i2c_device_id *id)
256{
257 struct pca953x_platform_data *pdata;
258 struct pca953x_chip *chip;
259 int ret;
260
261 chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
262 if (chip == NULL)
263 return -ENOMEM;
264
265 pdata = client->dev.platform_data;
266 if (pdata == NULL) {
267 pdata = pca953x_get_alt_pdata(client);
268 /*
269 * Unlike normal platform_data, this is allocated
270 * dynamically and must be freed in the driver
271 */
272 chip->dyn_pdata = pdata;
273 }
274
275 if (pdata == NULL) {
276 dev_dbg(&client->dev, "no platform data\n");
277 ret = -EINVAL;
278 goto out_failed;
279 }
280
281 chip->client = client;
282
283 chip->gpio_start = pdata->gpio_base;
284
285 chip->names = pdata->names;
286
287 /* initialize cached registers from their original values.
288 * we can't share this chip with another i2c master.
289 */
290 pca953x_setup_gpio(chip, id->driver_data);
291
292 ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
293 if (ret)
294 goto out_failed;
295
296 ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
297 if (ret)
298 goto out_failed;
299
300 /* set platform specific polarity inversion */
301 ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
302 if (ret)
303 goto out_failed;
304
305
306 ret = gpiochip_add(&chip->gpio_chip);
307 if (ret)
308 goto out_failed;
309
310 if (pdata->setup) {
311 ret = pdata->setup(client, chip->gpio_chip.base,
312 chip->gpio_chip.ngpio, pdata->context);
313 if (ret < 0)
314 dev_warn(&client->dev, "setup failed, %d\n", ret);
315 }
316
317 i2c_set_clientdata(client, chip);
318 return 0;
319
320out_failed:
321 kfree(chip->dyn_pdata);
322 kfree(chip);
323 return ret;
324}
325
326static int pca953x_remove(struct i2c_client *client)
327{
328 struct pca953x_platform_data *pdata = client->dev.platform_data;
329 struct pca953x_chip *chip = i2c_get_clientdata(client);
330 int ret = 0;
331
332 if (pdata->teardown) {
333 ret = pdata->teardown(client, chip->gpio_chip.base,
334 chip->gpio_chip.ngpio, pdata->context);
335 if (ret < 0) {
336 dev_err(&client->dev, "%s failed, %d\n",
337 "teardown", ret);
338 return ret;
339 }
340 }
341
342 ret = gpiochip_remove(&chip->gpio_chip);
343 if (ret) {
344 dev_err(&client->dev, "%s failed, %d\n",
345 "gpiochip_remove()", ret);
346 return ret;
347 }
348
349 kfree(chip->dyn_pdata);
350 kfree(chip);
351 return 0;
352}
353
354static struct i2c_driver pca953x_driver = {
355 .driver = {
356 .name = "pca953x",
357 },
358 .probe = pca953x_probe,
359 .remove = pca953x_remove,
360 .id_table = pca953x_id,
361};
362
363static int __init pca953x_init(void)
364{
365 return i2c_add_driver(&pca953x_driver);
366}
367/* register after i2c postcore initcall and before
368 * subsys initcalls that may rely on these GPIOs
369 */
370subsys_initcall(pca953x_init);
371
372static void __exit pca953x_exit(void)
373{
374 i2c_del_driver(&pca953x_driver);
375}
376module_exit(pca953x_exit);
377
378MODULE_AUTHOR("eric miao <eric.miao@marvell.com>");
379MODULE_DESCRIPTION("GPIO expander driver for PCA953x");
380MODULE_LICENSE("GPL");
This page took 0.04076 seconds and 5 git commands to generate.