3e85c92a7d599f475c0ee522a7ff12ba27e94864
[linux-2.6.git] / drivers / gpio / pca9539.c
1 /*
2  *  pca9539.c - 16-bit I/O port with interrupt and reset
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/pca9539.h>
18
19 #include <asm/gpio.h>
20
21
22 #define NR_PCA9539_GPIOS        16
23
24 #define PCA9539_INPUT           0
25 #define PCA9539_OUTPUT          2
26 #define PCA9539_INVERT          4
27 #define PCA9539_DIRECTION       6
28
29 struct pca9539_chip {
30         unsigned gpio_start;
31         uint16_t reg_output;
32         uint16_t reg_direction;
33
34         struct i2c_client *client;
35         struct gpio_chip gpio_chip;
36 };
37
38 /* NOTE:  we can't currently rely on fault codes to come from SMBus
39  * calls, so we map all errors to EIO here and return zero otherwise.
40  */
41 static int pca9539_write_reg(struct pca9539_chip *chip, int reg, uint16_t val)
42 {
43         if (i2c_smbus_write_word_data(chip->client, reg, val) < 0)
44                 return -EIO;
45         else
46                 return 0;
47 }
48
49 static int pca9539_read_reg(struct pca9539_chip *chip, int reg, uint16_t *val)
50 {
51         int ret;
52
53         ret = i2c_smbus_read_word_data(chip->client, reg);
54         if (ret < 0) {
55                 dev_err(&chip->client->dev, "failed reading register\n");
56                 return -EIO;
57         }
58
59         *val = (uint16_t)ret;
60         return 0;
61 }
62
63 static int pca9539_gpio_direction_input(struct gpio_chip *gc, unsigned off)
64 {
65         struct pca9539_chip *chip;
66         uint16_t reg_val;
67         int ret;
68
69         chip = container_of(gc, struct pca9539_chip, gpio_chip);
70
71         reg_val = chip->reg_direction | (1u << off);
72         ret = pca9539_write_reg(chip, PCA9539_DIRECTION, reg_val);
73         if (ret)
74                 return ret;
75
76         chip->reg_direction = reg_val;
77         return 0;
78 }
79
80 static int pca9539_gpio_direction_output(struct gpio_chip *gc,
81                 unsigned off, int val)
82 {
83         struct pca9539_chip *chip;
84         uint16_t reg_val;
85         int ret;
86
87         chip = container_of(gc, struct pca9539_chip, gpio_chip);
88
89         /* set output level */
90         if (val)
91                 reg_val = chip->reg_output | (1u << off);
92         else
93                 reg_val = chip->reg_output & ~(1u << off);
94
95         ret = pca9539_write_reg(chip, PCA9539_OUTPUT, reg_val);
96         if (ret)
97                 return ret;
98
99         chip->reg_output = reg_val;
100
101         /* then direction */
102         reg_val = chip->reg_direction & ~(1u << off);
103         ret = pca9539_write_reg(chip, PCA9539_DIRECTION, reg_val);
104         if (ret)
105                 return ret;
106
107         chip->reg_direction = reg_val;
108         return 0;
109 }
110
111 static int pca9539_gpio_get_value(struct gpio_chip *gc, unsigned off)
112 {
113         struct pca9539_chip *chip;
114         uint16_t reg_val;
115         int ret;
116
117         chip = container_of(gc, struct pca9539_chip, gpio_chip);
118
119         ret = pca9539_read_reg(chip, PCA9539_INPUT, &reg_val);
120         if (ret < 0) {
121                 /* NOTE:  diagnostic already emitted; that's all we should
122                  * do unless gpio_*_value_cansleep() calls become different
123                  * from their nonsleeping siblings (and report faults).
124                  */
125                 return 0;
126         }
127
128         return (reg_val & (1u << off)) ? 1 : 0;
129 }
130
131 static void pca9539_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
132 {
133         struct pca9539_chip *chip;
134         uint16_t reg_val;
135         int ret;
136
137         chip = container_of(gc, struct pca9539_chip, gpio_chip);
138
139         if (val)
140                 reg_val = chip->reg_output | (1u << off);
141         else
142                 reg_val = chip->reg_output & ~(1u << off);
143
144         ret = pca9539_write_reg(chip, PCA9539_OUTPUT, reg_val);
145         if (ret)
146                 return;
147
148         chip->reg_output = reg_val;
149 }
150
151 static int pca9539_init_gpio(struct pca9539_chip *chip)
152 {
153         struct gpio_chip *gc;
154
155         gc = &chip->gpio_chip;
156
157         gc->direction_input  = pca9539_gpio_direction_input;
158         gc->direction_output = pca9539_gpio_direction_output;
159         gc->get = pca9539_gpio_get_value;
160         gc->set = pca9539_gpio_set_value;
161
162         gc->base = chip->gpio_start;
163         gc->ngpio = NR_PCA9539_GPIOS;
164         gc->label = "pca9539";
165
166         return gpiochip_add(gc);
167 }
168
169 static int __devinit pca9539_probe(struct i2c_client *client)
170 {
171         struct pca9539_platform_data *pdata;
172         struct pca9539_chip *chip;
173         int ret;
174
175         pdata = client->dev.platform_data;
176         if (pdata == NULL)
177                 return -ENODEV;
178
179         chip = kzalloc(sizeof(struct pca9539_chip), GFP_KERNEL);
180         if (chip == NULL)
181                 return -ENOMEM;
182
183         chip->client = client;
184
185         chip->gpio_start = pdata->gpio_base;
186
187         /* initialize cached registers from their original values.
188          * we can't share this chip with another i2c master.
189          */
190         ret = pca9539_read_reg(chip, PCA9539_OUTPUT, &chip->reg_output);
191         if (ret)
192                 goto out_failed;
193
194         ret = pca9539_read_reg(chip, PCA9539_DIRECTION, &chip->reg_direction);
195         if (ret)
196                 goto out_failed;
197
198         /* set platform specific polarity inversion */
199         ret = pca9539_write_reg(chip, PCA9539_INVERT, pdata->invert);
200         if (ret)
201                 goto out_failed;
202
203         ret = pca9539_init_gpio(chip);
204         if (ret)
205                 goto out_failed;
206
207         if (pdata->setup) {
208                 ret = pdata->setup(client, chip->gpio_chip.base,
209                                 chip->gpio_chip.ngpio, pdata->context);
210                 if (ret < 0)
211                         dev_warn(&client->dev, "setup failed, %d\n", ret);
212         }
213
214         i2c_set_clientdata(client, chip);
215         return 0;
216
217 out_failed:
218         kfree(chip);
219         return ret;
220 }
221
222 static int pca9539_remove(struct i2c_client *client)
223 {
224         struct pca9539_platform_data *pdata = client->dev.platform_data;
225         struct pca9539_chip *chip = i2c_get_clientdata(client);
226         int ret = 0;
227
228         if (pdata->teardown) {
229                 ret = pdata->teardown(client, chip->gpio_chip.base,
230                                 chip->gpio_chip.ngpio, pdata->context);
231                 if (ret < 0) {
232                         dev_err(&client->dev, "%s failed, %d\n",
233                                         "teardown", ret);
234                         return ret;
235                 }
236         }
237
238         ret = gpiochip_remove(&chip->gpio_chip);
239         if (ret) {
240                 dev_err(&client->dev, "%s failed, %d\n",
241                                 "gpiochip_remove()", ret);
242                 return ret;
243         }
244
245         kfree(chip);
246         return 0;
247 }
248
249 static struct i2c_driver pca9539_driver = {
250         .driver = {
251                 .name   = "pca9539",
252         },
253         .probe          = pca9539_probe,
254         .remove         = pca9539_remove,
255 };
256
257 static int __init pca9539_init(void)
258 {
259         return i2c_add_driver(&pca9539_driver);
260 }
261 module_init(pca9539_init);
262
263 static void __exit pca9539_exit(void)
264 {
265         i2c_del_driver(&pca9539_driver);
266 }
267 module_exit(pca9539_exit);
268
269 MODULE_AUTHOR("eric miao <eric.miao@marvell.com>");
270 MODULE_DESCRIPTION("GPIO expander driver for PCA9539");
271 MODULE_LICENSE("GPL");