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