aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric Miao <eric.miao@marvell.com>2008-07-25 04:46:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:30 -0400
commitbbcd6d543de335bf81e96477f46a60a8bf51039c (patch)
tree86d592bfa308407ce357184ff9494e7d36939c6b /drivers
parent7444a72effa632fcd8edc566f880d96fe213c73b (diff)
gpio: max732x driver
This adds a driver supporting a family of I2C port expanders from Maxim, which includes the MAX7319 and MAX7320-7327 chips. [dbrownell@users.sourceforge.net: minor fixes] Signed-off-by: Jack Ren <jack.ren@marvell.com> Signed-off-by: Eric Miao <eric.miao@marvell.com> Acked-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/Kconfig19
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/max732x.c385
3 files changed, 405 insertions, 0 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5a355f829167..dbd42d6c93a7 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -67,6 +67,25 @@ config GPIO_SYSFS
67 67
68comment "I2C GPIO expanders:" 68comment "I2C GPIO expanders:"
69 69
70config GPIO_MAX732X
71 tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
72 depends on I2C
73 help
74 Say yes here to support the MAX7319, MAX7320-7327 series of I2C
75 Port Expanders. Each IO port on these chips has a fixed role of
76 Input (designated by 'I'), Push-Pull Output ('O'), or Open-Drain
77 Input and Output (designed by 'P'). The combinations are listed
78 below:
79
80 8 bits: max7319 (8I), max7320 (8O), max7321 (8P),
81 max7322 (4I4O), max7323 (4P4O)
82
83 16 bits: max7324 (8I8O), max7325 (8P8O),
84 max7326 (4I12O), max7327 (4P12O)
85
86 Board setup code must specify the model to use, and the start
87 number for these GPIOs.
88
70config GPIO_PCA953X 89config GPIO_PCA953X
71 tristate "PCA953x, PCA955x, and MAX7310 I/O ports" 90 tristate "PCA953x, PCA955x, and MAX7310 I/O ports"
72 depends on I2C 91 depends on I2C
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 8c45948d1fe7..01b4bbde1956 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -5,6 +5,7 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
5obj-$(CONFIG_GPIOLIB) += gpiolib.o 5obj-$(CONFIG_GPIOLIB) += gpiolib.o
6 6
7obj-$(CONFIG_GPIO_MAX7301) += max7301.o 7obj-$(CONFIG_GPIO_MAX7301) += max7301.o
8obj-$(CONFIG_GPIO_MAX732X) += max732x.o
8obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o 9obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
9obj-$(CONFIG_GPIO_PCA953X) += pca953x.o 10obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
10obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o 11obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c
new file mode 100644
index 000000000000..b51c8135ca28
--- /dev/null
+++ b/drivers/gpio/max732x.c
@@ -0,0 +1,385 @@
1/*
2 * max732x.c - I2C Port Expander with 8/16 I/O
3 *
4 * Copyright (C) 2007 Marvell International Ltd.
5 * Copyright (C) 2008 Jack Ren <jack.ren@marvell.com>
6 * Copyright (C) 2008 Eric Miao <eric.miao@marvell.com>
7 *
8 * Derived from drivers/gpio/pca953x.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/string.h>
19#include <linux/gpio.h>
20
21#include <linux/i2c.h>
22#include <linux/i2c/max732x.h>
23
24
25/*
26 * Each port of MAX732x (including MAX7319) falls into one of the
27 * following three types:
28 *
29 * - Push Pull Output
30 * - Input
31 * - Open Drain I/O
32 *
33 * designated by 'O', 'I' and 'P' individually according to MAXIM's
34 * datasheets.
35 *
36 * There are two groups of I/O ports, each group usually includes
37 * up to 8 I/O ports, and is accessed by a specific I2C address:
38 *
39 * - Group A : by I2C address 0b'110xxxx
40 * - Group B : by I2C address 0b'101xxxx
41 *
42 * where 'xxxx' is decided by the connections of pin AD2/AD0. The
43 * address used also affects the initial state of output signals.
44 *
45 * Within each group of ports, there are five known combinations of
46 * I/O ports: 4I4O, 4P4O, 8I, 8P, 8O, see the definitions below for
47 * the detailed organization of these ports.
48 *
49 * GPIO numbers start from 'gpio_base + 0' to 'gpio_base + 8/16',
50 * and GPIOs from GROUP_A are numbered before those from GROUP_B
51 * (if there are two groups).
52 *
53 * NOTE: MAX7328/MAX7329 are drop-in replacements for PCF8574/a, so
54 * they are not supported by this driver.
55 */
56
57#define PORT_NONE 0x0 /* '/' No Port */
58#define PORT_OUTPUT 0x1 /* 'O' Push-Pull, Output Only */
59#define PORT_INPUT 0x2 /* 'I' Input Only */
60#define PORT_OPENDRAIN 0x3 /* 'P' Open-Drain, I/O */
61
62#define IO_4I4O 0x5AA5 /* O7 O6 I5 I4 I3 I2 O1 O0 */
63#define IO_4P4O 0x5FF5 /* O7 O6 P5 P4 P3 P2 O1 O0 */
64#define IO_8I 0xAAAA /* I7 I6 I5 I4 I3 I2 I1 I0 */
65#define IO_8P 0xFFFF /* P7 P6 P5 P4 P3 P2 P1 P0 */
66#define IO_8O 0x5555 /* O7 O6 O5 O4 O3 O2 O1 O0 */
67
68#define GROUP_A(x) ((x) & 0xffff) /* I2C Addr: 0b'110xxxx */
69#define GROUP_B(x) ((x) << 16) /* I2C Addr: 0b'101xxxx */
70
71static const struct i2c_device_id max732x_id[] = {
72 { "max7319", GROUP_A(IO_8I) },
73 { "max7320", GROUP_B(IO_8O) },
74 { "max7321", GROUP_A(IO_8P) },
75 { "max7322", GROUP_A(IO_4I4O) },
76 { "max7323", GROUP_A(IO_4P4O) },
77 { "max7324", GROUP_A(IO_8I) | GROUP_B(IO_8O) },
78 { "max7325", GROUP_A(IO_8P) | GROUP_B(IO_8O) },
79 { "max7326", GROUP_A(IO_4I4O) | GROUP_B(IO_8O) },
80 { "max7327", GROUP_A(IO_4P4O) | GROUP_B(IO_8O) },
81 { },
82};
83MODULE_DEVICE_TABLE(i2c, max732x_id);
84
85struct max732x_chip {
86 struct gpio_chip gpio_chip;
87
88 struct i2c_client *client; /* "main" client */
89 struct i2c_client *client_dummy;
90 struct i2c_client *client_group_a;
91 struct i2c_client *client_group_b;
92
93 unsigned int mask_group_a;
94 unsigned int dir_input;
95 unsigned int dir_output;
96
97 struct mutex lock;
98 uint8_t reg_out[2];
99};
100
101static int max732x_write(struct max732x_chip *chip, int group_a, uint8_t val)
102{
103 struct i2c_client *client;
104 int ret;
105
106 client = group_a ? chip->client_group_a : chip->client_group_b;
107 ret = i2c_smbus_write_byte(client, val);
108 if (ret < 0) {
109 dev_err(&client->dev, "failed writing\n");
110 return ret;
111 }
112
113 return 0;
114}
115
116static int max732x_read(struct max732x_chip *chip, int group_a, uint8_t *val)
117{
118 struct i2c_client *client;
119 int ret;
120
121 client = group_a ? chip->client_group_a : chip->client_group_b;
122 ret = i2c_smbus_read_byte(client);
123 if (ret < 0) {
124 dev_err(&client->dev, "failed reading\n");
125 return ret;
126 }
127
128 *val = (uint8_t)ret;
129 return 0;
130}
131
132static inline int is_group_a(struct max732x_chip *chip, unsigned off)
133{
134 return (1u << off) & chip->mask_group_a;
135}
136
137static int max732x_gpio_get_value(struct gpio_chip *gc, unsigned off)
138{
139 struct max732x_chip *chip;
140 uint8_t reg_val;
141 int ret;
142
143 chip = container_of(gc, struct max732x_chip, gpio_chip);
144
145 ret = max732x_read(chip, is_group_a(chip, off), &reg_val);
146 if (ret < 0)
147 return 0;
148
149 return reg_val & (1u << (off & 0x7));
150}
151
152static void max732x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
153{
154 struct max732x_chip *chip;
155 uint8_t reg_out, mask = 1u << (off & 0x7);
156 int ret;
157
158 chip = container_of(gc, struct max732x_chip, gpio_chip);
159
160 mutex_lock(&chip->lock);
161
162 reg_out = (off > 7) ? chip->reg_out[1] : chip->reg_out[0];
163 reg_out = (val) ? reg_out | mask : reg_out & ~mask;
164
165 ret = max732x_write(chip, is_group_a(chip, off), reg_out);
166 if (ret < 0)
167 goto out;
168
169 /* update the shadow register then */
170 if (off > 7)
171 chip->reg_out[1] = reg_out;
172 else
173 chip->reg_out[0] = reg_out;
174out:
175 mutex_unlock(&chip->lock);
176}
177
178static int max732x_gpio_direction_input(struct gpio_chip *gc, unsigned off)
179{
180 struct max732x_chip *chip;
181 unsigned int mask = 1u << off;
182
183 chip = container_of(gc, struct max732x_chip, gpio_chip);
184
185 if ((mask & chip->dir_input) == 0) {
186 dev_dbg(&chip->client->dev, "%s port %d is output only\n",
187 chip->client->name, off);
188 return -EACCES;
189 }
190
191 return 0;
192}
193
194static int max732x_gpio_direction_output(struct gpio_chip *gc,
195 unsigned off, int val)
196{
197 struct max732x_chip *chip;
198 unsigned int mask = 1u << off;
199
200 chip = container_of(gc, struct max732x_chip, gpio_chip);
201
202 if ((mask & chip->dir_output) == 0) {
203 dev_dbg(&chip->client->dev, "%s port %d is input only\n",
204 chip->client->name, off);
205 return -EACCES;
206 }
207
208 max732x_gpio_set_value(gc, off, val);
209 return 0;
210}
211
212static int __devinit max732x_setup_gpio(struct max732x_chip *chip,
213 const struct i2c_device_id *id,
214 unsigned gpio_start)
215{
216 struct gpio_chip *gc = &chip->gpio_chip;
217 uint32_t id_data = id->driver_data;
218 int i, port = 0;
219
220 for (i = 0; i < 16; i++, id_data >>= 2) {
221 unsigned int mask = 1 << port;
222
223 switch (id_data & 0x3) {
224 case PORT_OUTPUT:
225 chip->dir_output |= mask;
226 break;
227 case PORT_INPUT:
228 chip->dir_input |= mask;
229 break;
230 case PORT_OPENDRAIN:
231 chip->dir_output |= mask;
232 chip->dir_input |= mask;
233 break;
234 default:
235 continue;
236 }
237
238 if (i < 8)
239 chip->mask_group_a |= mask;
240 port++;
241 }
242
243 if (chip->dir_input)
244 gc->direction_input = max732x_gpio_direction_input;
245 if (chip->dir_output) {
246 gc->direction_output = max732x_gpio_direction_output;
247 gc->set = max732x_gpio_set_value;
248 }
249 gc->get = max732x_gpio_get_value;
250 gc->can_sleep = 1;
251
252 gc->base = gpio_start;
253 gc->ngpio = port;
254 gc->label = chip->client->name;
255 gc->owner = THIS_MODULE;
256
257 return port;
258}
259
260static int __devinit max732x_probe(struct i2c_client *client,
261 const struct i2c_device_id *id)
262{
263 struct max732x_platform_data *pdata;
264 struct max732x_chip *chip;
265 struct i2c_client *c;
266 uint16_t addr_a, addr_b;
267 int ret, nr_port;
268
269 pdata = client->dev.platform_data;
270 if (pdata == NULL)
271 return -ENODEV;
272
273 chip = kzalloc(sizeof(struct max732x_chip), GFP_KERNEL);
274 if (chip == NULL)
275 return -ENOMEM;
276 chip->client = client;
277
278 nr_port = max732x_setup_gpio(chip, id, pdata->gpio_base);
279
280 addr_a = (client->addr & 0x0f) | 0x60;
281 addr_b = (client->addr & 0x0f) | 0x50;
282
283 switch (client->addr & 0x70) {
284 case 0x60:
285 chip->client_group_a = client;
286 if (nr_port > 7) {
287 c = i2c_new_dummy(client->adapter, addr_b);
288 chip->client_group_b = chip->client_dummy = c;
289 }
290 break;
291 case 0x50:
292 chip->client_group_b = client;
293 if (nr_port > 7) {
294 c = i2c_new_dummy(client->adapter, addr_a);
295 chip->client_group_a = chip->client_dummy = c;
296 }
297 break;
298 default:
299 dev_err(&client->dev, "invalid I2C address specified %02x\n",
300 client->addr);
301 ret = -EINVAL;
302 goto out_failed;
303 }
304
305 mutex_init(&chip->lock);
306
307 max732x_read(chip, is_group_a(chip, 0), &chip->reg_out[0]);
308 if (nr_port > 7)
309 max732x_read(chip, is_group_a(chip, 8), &chip->reg_out[1]);
310
311 ret = gpiochip_add(&chip->gpio_chip);
312 if (ret)
313 goto out_failed;
314
315 if (pdata->setup) {
316 ret = pdata->setup(client, chip->gpio_chip.base,
317 chip->gpio_chip.ngpio, pdata->context);
318 if (ret < 0)
319 dev_warn(&client->dev, "setup failed, %d\n", ret);
320 }
321
322 i2c_set_clientdata(client, chip);
323 return 0;
324
325out_failed:
326 kfree(chip);
327 return ret;
328}
329
330static int __devexit max732x_remove(struct i2c_client *client)
331{
332 struct max732x_platform_data *pdata = client->dev.platform_data;
333 struct max732x_chip *chip = i2c_get_clientdata(client);
334 int ret;
335
336 if (pdata->teardown) {
337 ret = pdata->teardown(client, chip->gpio_chip.base,
338 chip->gpio_chip.ngpio, pdata->context);
339 if (ret < 0) {
340 dev_err(&client->dev, "%s failed, %d\n",
341 "teardown", ret);
342 return ret;
343 }
344 }
345
346 ret = gpiochip_remove(&chip->gpio_chip);
347 if (ret) {
348 dev_err(&client->dev, "%s failed, %d\n",
349 "gpiochip_remove()", ret);
350 return ret;
351 }
352
353 /* unregister any dummy i2c_client */
354 if (chip->client_dummy)
355 i2c_unregister_device(chip->client_dummy);
356
357 kfree(chip);
358 return 0;
359}
360
361static struct i2c_driver max732x_driver = {
362 .driver = {
363 .name = "max732x",
364 .owner = THIS_MODULE,
365 },
366 .probe = max732x_probe,
367 .remove = __devexit_p(max732x_remove),
368 .id_table = max732x_id,
369};
370
371static int __init max732x_init(void)
372{
373 return i2c_add_driver(&max732x_driver);
374}
375module_init(max732x_init);
376
377static void __exit max732x_exit(void)
378{
379 i2c_del_driver(&max732x_driver);
380}
381module_exit(max732x_exit);
382
383MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
384MODULE_DESCRIPTION("GPIO expander driver for MAX732X");
385MODULE_LICENSE("GPL");