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