Root/target/linux/ixp4xx/patches-3.0/020-gateworks_i2c_pld.patch

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

Archive Download this file



interactive