cns3xxx: backport pci fix for cns3xxx_write_config
[openwrt.git] / target / linux / ixp4xx / patches-4.1 / 020-gateworks_i2c_pld.patch
1 --- a/drivers/gpio/Kconfig
2 +++ b/drivers/gpio/Kconfig
3 @@ -647,6 +647,14 @@ config GPIO_SX150X
4           8 bits:  sx1508q
5           16 bits: sx1509q
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  endmenu
16  
17  menu "MFD GPIO expanders"
18 --- a/drivers/gpio/Makefile
19 +++ b/drivers/gpio/Makefile
20 @@ -112,3 +112,4 @@ obj-$(CONFIG_GPIO_XILINX)   += gpio-xilinx
21  obj-$(CONFIG_GPIO_XTENSA)      += gpio-xtensa.o
22  obj-$(CONFIG_GPIO_ZEVIO)       += gpio-zevio.o
23  obj-$(CONFIG_GPIO_ZYNQ)                += gpio-zynq.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,371 @@
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 +#include <mach/hardware.h>
57 +
58 +static const struct i2c_device_id gw_i2c_pld_id[] = {
59 +       { "gw_i2c_pld", 8 },
60 +       { }
61 +};
62 +MODULE_DEVICE_TABLE(i2c, gw_i2c_pld_id);
63 +
64 +/*
65 + * The Gateworks I2C PLD chip only expose one read and one
66 + * write register.  Writing a "one" bit (to match the reset state) lets
67 + * that pin be used as an input. It is an open-drain model.
68 + */
69 +
70 +struct gw_i2c_pld {
71 +       struct gpio_chip        chip;
72 +       struct i2c_client       *client;
73 +       unsigned                out;            /* software latch */
74 +};
75 +
76 +/*-------------------------------------------------------------------------*/
77 +
78 +/*
79 + * The Gateworks I2C PLD chip does not properly send the acknowledge bit
80 + * thus we cannot use standard i2c_smbus functions. We have recreated
81 + * our own here, but we still use the rt_mutex_lock to lock the i2c_bus
82 + * as the device still exists on the I2C bus.
83 +*/
84 +
85 +#define PLD_SCL_GPIO 6
86 +#define PLD_SDA_GPIO 7
87 +
88 +#define SCL_LO()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_LOW)
89 +#define SCL_HI()  gpio_line_set(PLD_SCL_GPIO, IXP4XX_GPIO_HIGH)
90 +#define SCL_EN()  gpio_line_config(PLD_SCL_GPIO, IXP4XX_GPIO_OUT)
91 +#define SDA_LO()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_LOW)
92 +#define SDA_HI()  gpio_line_set(PLD_SDA_GPIO, IXP4XX_GPIO_HIGH)
93 +#define SDA_EN()  gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_OUT)
94 +#define SDA_DIS() gpio_line_config(PLD_SDA_GPIO, IXP4XX_GPIO_IN)
95 +#define SDA_IN(x) gpio_line_get(PLD_SDA_GPIO, &x);
96 +
97 +static int i2c_pld_write_byte(int address, int byte)
98 +{
99 +       int i;
100 +
101 +       address = (address << 1) & ~0x1;
102 +
103 +       SDA_HI();
104 +       SDA_EN();
105 +       SCL_EN();
106 +       SCL_HI();
107 +       SDA_LO();
108 +       SCL_LO();
109 +
110 +       for (i = 7; i >= 0; i--)
111 +       {
112 +               if (address & (1 << i))
113 +                       SDA_HI();
114 +               else
115 +                       SDA_LO();
116 +
117 +               SCL_HI();
118 +               SCL_LO();
119 +       }
120 +
121 +       SDA_DIS();
122 +       SCL_HI();
123 +       SDA_IN(i);
124 +       SCL_LO();
125 +       SDA_EN();
126 +
127 +       for (i = 7; i >= 0; i--)
128 +       {
129 +               if (byte & (1 << i))
130 +      SDA_HI();
131 +               else
132 +                       SDA_LO();
133 +               SCL_HI();
134 +               SCL_LO();
135 +       }
136 +
137 +       SDA_DIS();
138 +       SCL_HI();
139 +       SDA_IN(i);
140 +       SCL_LO();
141 +
142 +       SDA_HI();
143 +       SDA_EN();
144 +
145 +       SDA_LO();
146 +       SCL_HI();
147 +       SDA_HI();
148 +       SCL_LO();
149 +       SCL_HI();
150 +
151 +       return 0;
152 +}
153 +
154 +static unsigned int i2c_pld_read_byte(int address)
155 +{
156 +       int i = 0, byte = 0;
157 +       int bit;
158 +
159 +       address = (address << 1) | 0x1;
160 +
161 +       SDA_HI();
162 +       SDA_EN();
163 +       SCL_EN();
164 +       SCL_HI();
165 +       SDA_LO();
166 +       SCL_LO();
167 +
168 +       for (i = 7; i >= 0; i--)
169 +       {
170 +               if (address & (1 << i))
171 +                       SDA_HI();
172 +               else
173 +                       SDA_LO();
174 +
175 +               SCL_HI();
176 +               SCL_LO();
177 +       }
178 +
179 +       SDA_DIS();
180 +       SCL_HI();
181 +       SDA_IN(i);
182 +       SCL_LO();
183 +       SDA_EN();
184 +
185 +       SDA_DIS();
186 +       for (i = 7; i >= 0; i--)
187 +       {
188 +               SCL_HI();
189 +               SDA_IN(bit);
190 +               byte |= bit << i;
191 +               SCL_LO();
192 +       }
193 +
194 +       SDA_LO();
195 +       SCL_HI();
196 +       SDA_HI();
197 +       SCL_LO();
198 +       SCL_HI();
199 +
200 +       return byte;
201 +}
202 +
203 +
204 +static int gw_i2c_pld_input8(struct gpio_chip *chip, unsigned offset)
205 +{
206 +       int ret;
207 +       struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
208 +       struct i2c_adapter *adap = gpio->client->adapter;
209 +
210 +       if (in_atomic() || irqs_disabled()) {
211 +               ret = rt_mutex_trylock(&adap->bus_lock);
212 +               if (!ret)
213 +                       /* I2C activity is ongoing. */
214 +                       return -EAGAIN;
215 +       } else {
216 +               rt_mutex_lock(&adap->bus_lock);
217 +       }
218 +
219 +       gpio->out |= (1 << offset);
220 +
221 +       ret = i2c_pld_write_byte(gpio->client->addr, gpio->out);
222 +
223 +       rt_mutex_unlock(&adap->bus_lock);
224 +
225 +       return ret;
226 +}
227 +
228 +static int gw_i2c_pld_get8(struct gpio_chip *chip, unsigned offset)
229 +{
230 +       int ret;
231 +       s32     value;
232 +       struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
233 +       struct i2c_adapter *adap = gpio->client->adapter;
234 +
235 +       if (in_atomic() || irqs_disabled()) {
236 +               ret = rt_mutex_trylock(&adap->bus_lock);
237 +               if (!ret)
238 +                       /* I2C activity is ongoing. */
239 +                       return -EAGAIN;
240 +       } else {
241 +               rt_mutex_lock(&adap->bus_lock);
242 +       }
243 +
244 +       value = i2c_pld_read_byte(gpio->client->addr);
245 +
246 +       rt_mutex_unlock(&adap->bus_lock);
247 +
248 +       return (value < 0) ? 0 : (value & (1 << offset));
249 +}
250 +
251 +static int gw_i2c_pld_output8(struct gpio_chip *chip, unsigned offset, int value)
252 +{
253 +       int ret;
254 +
255 +       struct gw_i2c_pld *gpio = container_of(chip, struct gw_i2c_pld, chip);
256 +       struct i2c_adapter *adap = gpio->client->adapter;
257 +
258 +       unsigned bit = 1 << offset;
259 +
260 +       if (in_atomic() || irqs_disabled()) {
261 +               ret = rt_mutex_trylock(&adap->bus_lock);
262 +               if (!ret)
263 +                       /* I2C activity is ongoing. */
264 +                       return -EAGAIN;
265 +       } else {
266 +               rt_mutex_lock(&adap->bus_lock);
267 +       }
268 +
269 +
270 +       if (value)
271 +               gpio->out |= bit;
272 +       else
273 +               gpio->out &= ~bit;
274 +
275 +       ret = i2c_pld_write_byte(gpio->client->addr, gpio->out);
276 +
277 +       rt_mutex_unlock(&adap->bus_lock);
278 +
279 +       return ret;
280 +}
281 +
282 +static void gw_i2c_pld_set8(struct gpio_chip *chip, unsigned offset, int value)
283 +{
284 +       gw_i2c_pld_output8(chip, offset, value);
285 +}
286 +
287 +/*-------------------------------------------------------------------------*/
288 +
289 +static int gw_i2c_pld_probe(struct i2c_client *client,
290 +                        const struct i2c_device_id *id)
291 +{
292 +       struct gw_i2c_pld_platform_data *pdata;
293 +       struct gw_i2c_pld *gpio;
294 +       int status;
295 +
296 +       pdata = client->dev.platform_data;
297 +       if (!pdata)
298 +               return -ENODEV;
299 +
300 +       /* Allocate, initialize, and register this gpio_chip. */
301 +       gpio = kzalloc(sizeof *gpio, GFP_KERNEL);
302 +       if (!gpio)
303 +               return -ENOMEM;
304 +
305 +       gpio->chip.base = pdata->gpio_base;
306 +       gpio->chip.can_sleep = 1;
307 +       gpio->chip.dev = &client->dev;
308 +       gpio->chip.owner = THIS_MODULE;
309 +
310 +       gpio->chip.ngpio = pdata->nr_gpio;
311 +       gpio->chip.direction_input = gw_i2c_pld_input8;
312 +       gpio->chip.get = gw_i2c_pld_get8;
313 +       gpio->chip.direction_output = gw_i2c_pld_output8;
314 +       gpio->chip.set = gw_i2c_pld_set8;
315 +
316 +       gpio->chip.label = client->name;
317 +
318 +       gpio->client = client;
319 +       i2c_set_clientdata(client, gpio);
320 +
321 +       gpio->out = 0xFF;
322 +
323 +       status = gpiochip_add(&gpio->chip);
324 +       if (status < 0)
325 +               goto fail;
326 +
327 +       dev_info(&client->dev, "gpios %d..%d on a %s%s\n",
328 +                       gpio->chip.base,
329 +                       gpio->chip.base + gpio->chip.ngpio - 1,
330 +                       client->name,
331 +                       client->irq ? " (irq ignored)" : "");
332 +
333 +       /* Let platform code set up the GPIOs and their users.
334 +        * Now is the first time anyone could use them.
335 +        */
336 +       if (pdata->setup) {
337 +               status = pdata->setup(client,
338 +                               gpio->chip.base, gpio->chip.ngpio,
339 +                               pdata->context);
340 +               if (status < 0)
341 +                       dev_warn(&client->dev, "setup --> %d\n", status);
342 +       }
343 +
344 +       return 0;
345 +
346 +fail:
347 +       dev_dbg(&client->dev, "probe error %d for '%s'\n",
348 +                       status, client->name);
349 +       kfree(gpio);
350 +       return status;
351 +}
352 +
353 +static int gw_i2c_pld_remove(struct i2c_client *client)
354 +{
355 +       struct gw_i2c_pld_platform_data *pdata = client->dev.platform_data;
356 +       struct gw_i2c_pld *gpio = i2c_get_clientdata(client);
357 +       int                             status = 0;
358 +
359 +       if (pdata->teardown) {
360 +               status = pdata->teardown(client,
361 +                               gpio->chip.base, gpio->chip.ngpio,
362 +                               pdata->context);
363 +               if (status < 0) {
364 +                       dev_err(&client->dev, "%s --> %d\n",
365 +                                       "teardown", status);
366 +                       return status;
367 +               }
368 +       }
369 +
370 +       gpiochip_remove(&gpio->chip);
371 +       kfree(gpio);
372 +       return 0;
373 +}
374 +
375 +static struct i2c_driver gw_i2c_pld_driver = {
376 +       .driver = {
377 +               .name   = "gw_i2c_pld",
378 +               .owner  = THIS_MODULE,
379 +       },
380 +       .probe  = gw_i2c_pld_probe,
381 +       .remove = gw_i2c_pld_remove,
382 +       .id_table = gw_i2c_pld_id,
383 +};
384 +
385 +static int __init gw_i2c_pld_init(void)
386 +{
387 +       return i2c_add_driver(&gw_i2c_pld_driver);
388 +}
389 +module_init(gw_i2c_pld_init);
390 +
391 +static void __exit gw_i2c_pld_exit(void)
392 +{
393 +       i2c_del_driver(&gw_i2c_pld_driver);
394 +}
395 +module_exit(gw_i2c_pld_exit);
396 +
397 +MODULE_LICENSE("GPL");
398 +MODULE_AUTHOR("Chris Lang");
399 --- /dev/null
400 +++ b/include/linux/i2c/gw_i2c_pld.h
401 @@ -0,0 +1,20 @@
402 +#ifndef __LINUX_GW_I2C_PLD_H
403 +#define __LINUX_GW_I2C_PLD_H
404 +
405 +/**
406 + * The Gateworks I2C PLD Implements an additional 8 bits of GPIO through the PLD
407 + */
408 +
409 +struct gw_i2c_pld_platform_data {
410 +       unsigned gpio_base;
411 +       unsigned nr_gpio;
412 +       int             (*setup)(struct i2c_client *client,
413 +                                       int gpio, unsigned ngpio,
414 +                                       void *context);
415 +       int             (*teardown)(struct i2c_client *client,
416 +                                       int gpio, unsigned ngpio,
417 +                                       void *context);
418 +       void            *context;
419 +};
420 +
421 +#endif /* __LINUX_GW_I2C_PLD_H */