kernel: refresh 3.12 patches on -rc7 release
[openwrt.git] / target / linux / ixp4xx / patches-3.10 / 020-gateworks_i2c_pld.patch
1 --- a/drivers/gpio/Kconfig
2 +++ b/drivers/gpio/Kconfig
3 @@ -625,6 +625,14 @@ config GPIO_RDC321X
4           Support for the RDC R321x SoC GPIOs over southbridge
5           PCI configuration space.
6  
7 +config GPIO_GW_I2C_PLD
8 +       tristate "Gateworks I2C PLD GPIO Expander"
9 +       depends on I2C
10 +       help
11 +               Say yes here to provide access to the Gateworks I2C PLD GPIO
12 +               Expander. This is used at least on the GW2358-4.
13 +
14 +
15  comment "SPI GPIO expanders:"
16  
17  config GPIO_MAX7301
18 --- a/drivers/gpio/Makefile
19 +++ b/drivers/gpio/Makefile
20 @@ -87,3 +87,4 @@ obj-$(CONFIG_GPIO_WM831X)     += gpio-wm831x
21  obj-$(CONFIG_GPIO_WM8350)      += gpio-wm8350.o
22  obj-$(CONFIG_GPIO_WM8994)      += gpio-wm8994.o
23  obj-$(CONFIG_GPIO_XILINX)      += gpio-xilinx.o
24 +obj-$(CONFIG_GPIO_GW_I2C_PLD)  += gw_i2c_pld.o
25 --- /dev/null
26 +++ b/drivers/gpio/gw_i2c_pld.c
27 @@ -0,0 +1,373 @@
28 +/*
29 + * Gateworks I2C PLD GPIO expander
30 + *
31 + * Copyright (C) 2009 Gateworks Corporation
32 + *
33 + * This program is free software; you can redistribute it and/or modify
34 + * it under the terms of the GNU General Public License as published by
35 + * the Free Software Foundation; either version 2 of the License, or
36 + * (at your option) any later version.
37 + *
38 + * This program is distributed in the hope that it will be useful,
39 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
40 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
41 + * GNU General Public License for more details.
42 + *
43 + * You should have received a copy of the GNU General Public License
44 + * along with this program; if not, write to the Free Software
45 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
46 + */
47 +
48 +#include <linux/kernel.h>
49 +#include <linux/slab.h>
50 +#include <linux/hardirq.h>
51 +#include <linux/i2c.h>
52 +#include <linux/i2c/gw_i2c_pld.h>
53 +#include <linux/module.h>
54 +#include <linux/export.h>
55 +#include <asm/gpio.h>
56 +
57 +static const struct i2c_device_id gw_i2c_pld_id[] = {
58 +       { "gw_i2c_pld", 8 },
59 +       { }
60 +};
61 +MODULE_DEVICE_TABLE(i2c, gw_i2c_pld_id);
62 +
63 +/*
64 + * The Gateworks I2C PLD chip only expose one read and one
65 + * write register.  Writing a "one" bit (to match the reset state) lets
66 + * that pin be used as an input. It is an open-drain model.
67 + */
68 +
69 +struct gw_i2c_pld {
70 +       struct gpio_chip        chip;
71 +       struct i2c_client       *client;
72 +       unsigned                out;            /* software latch */
73 +};
74 +
75 +/*-------------------------------------------------------------------------*/
76 +
77 +/*
78 + * The Gateworks I2C PLD chip does not properly send the acknowledge bit
79 + * thus we cannot use standard i2c_smbus functions. We have recreated
80 + * our own here, but we still use the rt_mutex_lock to lock the i2c_bus
81 + * as the device still exists on the I2C bus.
82 +*/
83 +
84 +#define PLD_SCL_GPIO 6
85 +#define PLD_SDA_GPIO 7
86 +
87 +#define SCL_LO()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_LOW)
88 +#define SCL_HI()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_HIGH)
89 +#define SCL_EN()  gpio_line_config(PLD_SCL_GPIO, IXP4XX_GPIO_OUT)
90 +#define SDA_LO()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_LOW)
91 +#define SDA_HI()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_HIGH)
92 +#define SDA_EN()  gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_OUT)
93 +#define SDA_DIS() gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_IN)
94 +#define SDA_IN(x) gpio_line_get(PLD_SDA_GPIO, &x);
95 +
96 +static int i2c_pld_write_byte(int address, int byte)
97 +{
98 +       int i;
99 +
100 +       address = (address << 1) & ~0x1;
101 +
102 +       SDA_HI();
103 +       SDA_EN();
104 +       SCL_EN();
105 +       SCL_HI();
106 +       SDA_LO();
107 +       SCL_LO();
108 +
109 +       for (i = 7; i >= 0; i--)
110 +       {
111 +               if (address & (1 << i))
112 +                       SDA_HI();
113 +               else
114 +                       SDA_LO();
115 +
116 +               SCL_HI();
117 +               SCL_LO();
118 +       }
119 +
120 +       SDA_DIS();
121 +       SCL_HI();
122 +       SDA_IN(i);
123 +       SCL_LO();
124 +       SDA_EN();
125 +
126 +       for (i = 7; i >= 0; i--)
127 +       {
128 +               if (byte & (1 << i))
129 +      SDA_HI();
130 +               else
131 +                       SDA_LO();
132 +               SCL_HI();
133 +               SCL_LO();
134 +       }
135 +
136 +       SDA_DIS();
137 +       SCL_HI();
138 +       SDA_IN(i);
139 +       SCL_LO();
140 +
141 +       SDA_HI();
142 +       SDA_EN();
143 +
144 +       SDA_LO();
145 +       SCL_HI();
146 +       SDA_HI();
147 +       SCL_LO();
148 +       SCL_HI();
149 +
150 +       return 0;
151 +}
152 +
153 +static unsigned int i2c_pld_read_byte(int address)
154 +{
155 +       int i = 0, byte = 0;
156 +       int bit;
157 +
158 +       address = (address << 1) | 0x1;
159 +
160 +       SDA_HI();
161 +       SDA_EN();
162 +       SCL_EN();
163 +       SCL_HI();
164 +       SDA_LO();
165 +       SCL_LO();
166 +
167 +       for (i = 7; i >= 0; i--)
168 +       {
169 +               if (address & (1 << i))
170 +                       SDA_HI();
171 +               else
172 +                       SDA_LO();
173 +
174 +               SCL_HI();
175 +               SCL_LO();
176 +       }
177 +
178 +       SDA_DIS();
179 +       SCL_HI();
180 +       SDA_IN(i);
181 +       SCL_LO();
182 +       SDA_EN();
183 +
184 +       SDA_DIS();
185 +       for (i = 7; i >= 0; i--)
186 +       {
187 +               SCL_HI();
188 +               SDA_IN(bit);
189 +               byte |= bit << i;
190 +               SCL_LO();
191 +       }
192 +
193 +       SDA_LO();
194 +       SCL_HI();
195 +       SDA_HI();
196 +       SCL_LO();
197 +       SCL_HI();
198 +
199 +       return byte;
200 +}
201 +
202 +
203 +static int gw_i2c_pld_input8(struct gpio_chip *chip, unsigned offset)
204 +{
205 +       int ret;
206 +       struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
207 +       struct i2c_adapter *adap = gpio->client->adapter;
208 +
209 +       if (in_atomic() || irqs_disabled()) {
210 +               ret = rt_mutex_trylock(&adap->bus_lock);
211 +               if (!ret)
212 +                       /* I2C activity is ongoing. */
213 +                       return -EAGAIN;
214 +       } else {
215 +               rt_mutex_lock(&adap->bus_lock);
216 +       }
217 +
218 +       gpio->out |= (1 << offset);
219 +
220 +       ret = i2c_pld_write_byte(gpio->client->addr, gpio->out);
221 +
222 +       rt_mutex_unlock(&adap->bus_lock);
223 +
224 +       return ret;
225 +}
226 +
227 +static int gw_i2c_pld_get8(struct gpio_chip *chip, unsigned offset)
228 +{
229 +       int ret;
230 +       s32     value;
231 +       struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
232 +       struct i2c_adapter *adap = gpio->client->adapter;
233 +
234 +       if (in_atomic() || irqs_disabled()) {
235 +               ret = rt_mutex_trylock(&adap->bus_lock);
236 +               if (!ret)
237 +                       /* I2C activity is ongoing. */
238 +                       return -EAGAIN;
239 +       } else {
240 +               rt_mutex_lock(&adap->bus_lock);
241 +       }
242 +
243 +       value = i2c_pld_read_byte(gpio->client->addr);
244 +
245 +       rt_mutex_unlock(&adap->bus_lock);
246 +
247 +       return (value < 0) ? 0 : (value & (1 << offset));
248 +}
249 +
250 +static int gw_i2c_pld_output8(struct gpio_chip *chip, unsigned offset, int value)
251 +{
252 +       int ret;
253 +
254 +       struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
255 +       struct i2c_adapter *adap = gpio->client->adapter;
256 +
257 +       unsigned bit = 1 << offset;
258 +
259 +       if (in_atomic() || irqs_disabled()) {
260 +               ret = rt_mutex_trylock(&adap->bus_lock);
261 +               if (!ret)
262 +                       /* I2C activity is ongoing. */
263 +                       return -EAGAIN;
264 +       } else {
265 +               rt_mutex_lock(&adap->bus_lock);
266 +       }
267 +
268 +
269 +       if (value)
270 +               gpio->out |= bit;
271 +       else
272 +               gpio->out &= ~bit;
273 +
274 +       ret = i2c_pld_write_byte(gpio->client->addr, gpio->out);
275 +
276 +       rt_mutex_unlock(&adap->bus_lock);
277 +
278 +       return ret;
279 +}
280 +
281 +static void gw_i2c_pld_set8(struct gpio_chip *chip, unsigned offset, int value)
282 +{
283 +       gw_i2c_pld_output8(chip, offset, value);
284 +}
285 +
286 +/*-------------------------------------------------------------------------*/
287 +
288 +static int gw_i2c_pld_probe(struct i2c_client *client,
289 +                        const struct i2c_device_id *id)
290 +{
291 +       struct gw_i2c_pld_platform_data *pdata;
292 +       struct gw_i2c_pld *gpio;
293 +       int status;
294 +
295 +       pdata = client->dev.platform_data;
296 +       if (!pdata)
297 +               return -ENODEV;
298 +
299 +       /* Allocate, initialize, and register this gpio_chip. */
300 +       gpio = kzalloc(sizeof *gpio, GFP_KERNEL);
301 +       if (!gpio)
302 +               return -ENOMEM;
303 +
304 +       gpio->chip.base = pdata->gpio_base;
305 +       gpio->chip.can_sleep = 1;
306 +       gpio->chip.dev = &client->dev;
307 +       gpio->chip.owner = THIS_MODULE;
308 +
309 +       gpio->chip.ngpio = pdata->nr_gpio;
310 +       gpio->chip.direction_input = gw_i2c_pld_input8;
311 +       gpio->chip.get = gw_i2c_pld_get8;
312 +       gpio->chip.direction_output = gw_i2c_pld_output8;
313 +       gpio->chip.set = gw_i2c_pld_set8;
314 +
315 +       gpio->chip.label = client->name;
316 +
317 +       gpio->client = client;
318 +       i2c_set_clientdata(client, gpio);
319 +
320 +       gpio->out = 0xFF;
321 +
322 +       status = gpiochip_add(&gpio->chip);
323 +       if (status < 0)
324 +               goto fail;
325 +
326 +       dev_info(&client->dev, "gpios %d..%d on a %s%s\n",
327 +                       gpio->chip.base,
328 +                       gpio->chip.base + gpio->chip.ngpio - 1,
329 +                       client->name,
330 +                       client->irq ? " (irq ignored)" : "");
331 +
332 +       /* Let platform code set up the GPIOs and their users.
333 +        * Now is the first time anyone could use them.
334 +        */
335 +       if (pdata->setup) {
336 +               status = pdata->setup(client,
337 +                               gpio->chip.base, gpio->chip.ngpio,
338 +                               pdata->context);
339 +               if (status < 0)
340 +                       dev_warn(&client->dev, "setup --> %d\n", status);
341 +       }
342 +
343 +       return 0;
344 +
345 +fail:
346 +       dev_dbg(&client->dev, "probe error %d for '%s'\n",
347 +                       status, client->name);
348 +       kfree(gpio);
349 +       return status;
350 +}
351 +
352 +static int gw_i2c_pld_remove(struct i2c_client *client)
353 +{
354 +       struct gw_i2c_pld_platform_data *pdata = client->dev.platform_data;
355 +       struct gw_i2c_pld *gpio = i2c_get_clientdata(client);
356 +       int                             status = 0;
357 +
358 +       if (pdata->teardown) {
359 +               status = pdata->teardown(client,
360 +                               gpio->chip.base, gpio->chip.ngpio,
361 +                               pdata->context);
362 +               if (status < 0) {
363 +                       dev_err(&client->dev, "%s --> %d\n",
364 +                                       "teardown", status);
365 +                       return status;
366 +               }
367 +       }
368 +
369 +       status = gpiochip_remove(&gpio->chip);
370 +       if (status == 0)
371 +               kfree(gpio);
372 +       else
373 +               dev_err(&client->dev, "%s --> %d\n", "remove", status);
374 +       return status;
375 +}
376 +
377 +static struct i2c_driver gw_i2c_pld_driver = {
378 +       .driver = {
379 +               .name   = "gw_i2c_pld",
380 +               .owner  = THIS_MODULE,
381 +       },
382 +       .probe  = gw_i2c_pld_probe,
383 +       .remove = gw_i2c_pld_remove,
384 +       .id_table = gw_i2c_pld_id,
385 +};
386 +
387 +static int __init gw_i2c_pld_init(void)
388 +{
389 +       return i2c_add_driver(&gw_i2c_pld_driver);
390 +}
391 +module_init(gw_i2c_pld_init);
392 +
393 +static void __exit gw_i2c_pld_exit(void)
394 +{
395 +       i2c_del_driver(&gw_i2c_pld_driver);
396 +}
397 +module_exit(gw_i2c_pld_exit);
398 +
399 +MODULE_LICENSE("GPL");
400 +MODULE_AUTHOR("Chris Lang");
401 --- /dev/null
402 +++ b/include/linux/i2c/gw_i2c_pld.h
403 @@ -0,0 +1,20 @@
404 +#ifndef __LINUX_GW_I2C_PLD_H
405 +#define __LINUX_GW_I2C_PLD_H
406 +
407 +/**
408 + * The Gateworks I2C PLD Implements an additional 8 bits of GPIO through the PLD
409 + */
410 +
411 +struct gw_i2c_pld_platform_data {
412 +       unsigned gpio_base;
413 +       unsigned nr_gpio;
414 +       int             (*setup)(struct i2c_client *client,
415 +                                       int gpio, unsigned ngpio,
416 +                                       void *context);
417 +       int             (*teardown)(struct i2c_client *client,
418 +                                       int gpio, unsigned ngpio,
419 +                                       void *context);
420 +       void            *context;
421 +};
422 +
423 +#endif /* __LINUX_GW_I2C_PLD_H */