Make the i2c driver work, as a module
[openwrt/openwrt.git] / target / linux / au1000-2.6 / patches / 010-au100_gpio_i2c.patch
1 diff -urN linux-2.6.19/drivers/i2c/busses/Kconfig linux-2.6.19.new/drivers/i2c/busses/Kconfig
2 --- linux-2.6.19/drivers/i2c/busses/Kconfig 2006-11-29 22:57:37.000000000 +0100
3 +++ linux-2.6.19.new/drivers/i2c/busses/Kconfig 2006-12-28 17:04:34.000000000 +0100
4 @@ -84,6 +84,17 @@
5 This driver can also be built as a module. If so, the module
6 will be called i2c-au1550.
7
8 +config I2C_AU1X00GPIO
9 + tristate "Au1x00 i2c using GPIO pins"
10 + depends on I2C
11 + select I2C_ALGOBIT
12 + help
13 + If you say yest to this option, support will be included for the
14 + Au1x00 GPIO interface.
15 +
16 + This driver can also be built as a module. If so, the module
17 + will be called i2c-au1x00gpio.
18 +
19 config I2C_ELEKTOR
20 tristate "Elektor ISA card"
21 depends on I2C && ISA && BROKEN_ON_SMP
22 diff -urN linux-2.6.19/drivers/i2c/busses/Makefile linux-2.6.19.new/drivers/i2c/busses/Makefile
23 --- linux-2.6.19/drivers/i2c/busses/Makefile 2006-11-29 22:57:37.000000000 +0100
24 +++ linux-2.6.19.new/drivers/i2c/busses/Makefile 2006-12-28 03:07:37.000000000 +0100
25 @@ -9,6 +9,7 @@
26 obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o
27 obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
28 obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
29 +obj-$(CONFIG_I2C_AU1X00GPIO) += i2c-au1x00gpio.o
30 obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
31 obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o
32 obj-$(CONFIG_I2C_I801) += i2c-i801.o
33 diff -urN linux-2.6.19/drivers/i2c/busses/i2c-au1x00gpio.c linux-2.6.19.new/drivers/i2c/busses/i2c-au1x00gpio.c
34 --- linux-2.6.19/drivers/i2c/busses/i2c-au1x00gpio.c 1970-01-01 01:00:00.000000000 +0100
35 +++ linux-2.6.19.new/drivers/i2c/busses/i2c-au1x00gpio.c 2006-12-28 17:02:10.000000000 +0100
36 @@ -0,0 +1,406 @@
37 +/* ------------------------------------------------------------------------- */
38 +/* i2c-au1x00gpio.c i2c-hw access for Au1x00 GPIO pins. */
39 +/* ------------------------------------------------------------------------- */
40 +/* Copyright (C) 1995-2000 Michael Stickel
41 +
42 + This program is free software; you can redistribute it and/or modify
43 + it under the terms of the GNU General Public License as published by
44 + the Free Software Foundation; either version 2 of the License, or
45 + (at your option) any later version.
46 +
47 + This program is distributed in the hope that it will be useful,
48 + but WITHOUT ANY WARRANTY; without even the implied warranty of
49 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50 + GNU General Public License for more details.
51 +
52 + You should have received a copy of the GNU General Public License
53 + along with this program; if not, write to the Free Software
54 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
55 +/* ------------------------------------------------------------------------- */
56 +
57 +/* With some changes from Ky�stialkki <kmalkki@cc.hut.fi> and even
58 + Frodo Looijaard <frodol@dds.nl>
59 + Simon G. Vogl
60 +*/
61 +
62 +/* $Id: i2c-au1x00gpio.c,v 1.1.1.2 2004/01/22 15:35:47 br1 Exp $ */
63 +
64 +#include <linux/module.h>
65 +#include <linux/types.h>
66 +#include <linux/kernel.h>
67 +#include <linux/init.h>
68 +#include <linux/stddef.h>
69 +#include <linux/ioport.h>
70 +#include <asm/uaccess.h>
71 +#include <asm/io.h>
72 +#include <asm-mips/mach-au1x00/au1000.h>
73 +#include <asm-mips/mach-au1x00/au1000_gpio.h>
74 +
75 +#include <linux/slab.h>
76 +#include <linux/mm.h>
77 +
78 +#include <linux/i2c.h>
79 +#include <linux/i2c-algo-bit.h>
80 +
81 +struct i2c_au1x00gpio
82 +{
83 + struct i2c_au1x00gpio *next;
84 +
85 + short scl_gpio;
86 + short sda_gpio;
87 +
88 + unsigned long scl_mask;
89 + unsigned long sda_mask;
90 +
91 + struct i2c_adapter adapter;
92 + struct i2c_algo_bit_data bit_au1x00gpio_data;
93 +};
94 +
95 +static struct i2c_au1x00gpio *adapter_list;
96 +
97 +
98 +
99 +/* ----- global defines ----------------------------------------------- */
100 +#define DEB(x) /* should be reasonable open, close &c. */
101 +#define DEB2(x) /* low level debugging - very slow */
102 +#define DEBE(x) x /* error messages */
103 +
104 +/* ----- printer port defines ------------------------------------------*/
105 +
106 +/* ----- local functions ---------------------------------------------- */
107 +
108 +
109 +//-- Primary GPIO
110 +static void bit_au1x00gpio_setscl(void *data, int state)
111 +{
112 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
113 + if (state)
114 + au_writel(adapter->scl_mask, SYS_TRIOUTCLR); // Disable Driver: Switch off Transistor => 1
115 + else
116 + au_writel(adapter->scl_mask, SYS_OUTPUTCLR); // Clear Output and switch on Transistor => 0
117 +}
118 +
119 +
120 +static void bit_au1x00gpio_setsda(void *data, int state)
121 +{
122 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
123 + if (state)
124 + au_writel(adapter->sda_mask, SYS_TRIOUTCLR);
125 + else
126 + au_writel(adapter->sda_mask, SYS_OUTPUTCLR);
127 +}
128 +
129 +
130 +static int bit_au1x00gpio_getscl(void *data)
131 +{
132 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
133 + return (au_readl(SYS_PINSTATERD) & adapter->scl_mask) ? 1 : 0;
134 +}
135 +
136 +
137 +static int bit_au1x00gpio_getsda(void *data)
138 +{
139 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
140 + return (au_readl(SYS_PINSTATERD) & adapter->sda_mask) ? 1 : 0;
141 +}
142 +
143 +
144 +
145 +
146 +/*--
147 + *-- Functions for accessing GPIO-2
148 + *--
149 + */
150 +static void bit_au1x00gpio2_setscl(void *data, int state)
151 +{
152 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
153 + if (state)
154 + {
155 + au_writel(au_readl(GPIO2_DIR) & ~adapter->scl_mask, GPIO2_DIR);
156 + }
157 + else
158 + {
159 + au_writel(au_readl(GPIO2_OUTPUT) & ~adapter->scl_mask, GPIO2_OUTPUT);
160 + au_writel(au_readl(GPIO2_DIR) | adapter->scl_mask, GPIO2_DIR);
161 + }
162 +}
163 +
164 +static void bit_au1x00gpio2_setsda(void *data, int state)
165 +{
166 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
167 + if (state)
168 + {
169 + au_writel(au_readl(GPIO2_DIR) & ~adapter->sda_mask, GPIO2_DIR);
170 + }
171 + else
172 + {
173 + au_writel(au_readl(GPIO2_OUTPUT) & ~adapter->sda_mask, GPIO2_OUTPUT);
174 + au_writel(au_readl(GPIO2_DIR) | adapter->sda_mask, GPIO2_DIR);
175 + }
176 +}
177 +
178 +static int bit_au1x00gpio2_getscl(void *data)
179 +{
180 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
181 + return (au_readl(GPIO2_PINSTATE) & adapter->scl_mask) ? 1 : 0;
182 +}
183 +
184 +static int bit_au1x00gpio2_getsda(void *data)
185 +{
186 + struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data;
187 + return (au_readl(GPIO2_PINSTATE) & adapter->sda_mask) ? 1 : 0;
188 +}
189 +
190 +
191 +
192 +static int check_i2c_au1x00gpio_adapter(struct i2c_au1x00gpio *adapter)
193 +{
194 + int state = 0;
195 +
196 + adapter->bit_au1x00gpio_data.setsda (adapter, 1);
197 + adapter->bit_au1x00gpio_data.setscl (adapter, 1);
198 +
199 + if (adapter->bit_au1x00gpio_data.getsda(adapter)==0)
200 + {
201 + printk ("i2c-au1x00gpio: sda line should read 1 but reads 0\n");
202 + state = -1;
203 + }
204 + if (adapter->bit_au1x00gpio_data.getscl(adapter)==0)
205 + {
206 + printk ("i2c-au1x00gpio: scl line should read 1 but reads 0\n");
207 + state = -1;
208 + }
209 +
210 +
211 + adapter->bit_au1x00gpio_data.setsda (adapter, 0);
212 + adapter->bit_au1x00gpio_data.setscl (adapter, 0);
213 +
214 + if (adapter->bit_au1x00gpio_data.getsda(adapter)==1)
215 + {
216 + printk ("i2c-au1x00gpio: sda line should read 0 but reads 1\n");
217 + state = -1;
218 + }
219 + if (adapter->bit_au1x00gpio_data.getscl(adapter)==1)
220 + {
221 + printk ("i2c-au1x00gpio: scl line should read 0 but reads 1\n");
222 + state = -1;
223 + }
224 +
225 + if (state==0)
226 + printk ("i2c-au1x00gpio: adapter with scl=GPIO%d,sda=GPIO%d is working\n",
227 + adapter->scl_gpio, adapter->sda_gpio
228 + );
229 + return state;
230 +}
231 +
232 +
233 +
234 +#if 0
235 +static int bit_au1x00gpio_reg(struct i2c_client *client)
236 +{
237 + return 0;
238 +}
239 +
240 +static int bit_au1x00gpio_unreg(struct i2c_client *client)
241 +{
242 + return 0;
243 +}
244 +
245 +static void bit_au1x00gpio_inc_use(struct i2c_adapter *adap)
246 +{
247 + MOD_INC_USE_COUNT;
248 +}
249 +
250 +static void bit_au1x00gpio_dec_use(struct i2c_adapter *adap)
251 +{
252 + MOD_DEC_USE_COUNT;
253 +}
254 +#endif
255 +
256 +
257 +
258 +static struct i2c_algo_bit_data bit_au1x00gpio_data = {
259 + .data = NULL,
260 + .setsda = bit_au1x00gpio_setsda,
261 + .setscl = bit_au1x00gpio_setscl,
262 + .getsda = bit_au1x00gpio_getsda,
263 + .getscl = bit_au1x00gpio_getscl,
264 + .udelay = 80,
265 + .timeout = HZ,
266 +};
267 +
268 +
269 +static struct i2c_adapter bit_au1x00gpio_ops = {
270 + .owner = THIS_MODULE,
271 + .name = "Au1x00 GPIO I2C adapter",
272 + .id = I2C_HW_B_AU1x00GPIO,
273 +};
274 +
275 +
276 +
277 +/*
278 + * scl_gpio:
279 + * 0..31 for primary GPIO's
280 + * 200..215 for secondary GPIO's
281 + *
282 + * sda_gpio:
283 + * 0..31 for primary GPIO's
284 + * 200..215 for secondary GPIO's
285 + *
286 + * You can even mix primary and secondary GPIO's.
287 + * E.g.: i2c_au1x00gpio_create(4,206);
288 + */
289 +
290 +static int i2c_au1x00gpio_create (int scl_gpio, int sda_gpio)
291 +{
292 + if ((scl_gpio < 32 || (scl_gpio >= 200 && scl_gpio <= 215)) &&
293 + (scl_gpio < 32 || (scl_gpio >= 200 && scl_gpio <= 215)))
294 + {
295 + struct i2c_au1x00gpio *adapter = kmalloc(sizeof(struct i2c_au1x00gpio),
296 + GFP_KERNEL);
297 + if (!adapter) {
298 + printk(KERN_ERR "i2c-au1x00-gpio: Unable to malloc.\n");
299 + return -1;
300 + }
301 +
302 + printk(KERN_DEBUG "i2c-au1x00-gpio.o: attaching to SCL=GPIO%d, SDA=GPIO%d\n",
303 + scl_gpio, sda_gpio);
304 +
305 + memset (adapter, 0, sizeof(struct i2c_au1x00gpio));
306 +
307 + adapter->adapter = bit_au1x00gpio_ops;
308 +
309 + adapter->adapter.algo_data = &adapter->bit_au1x00gpio_data;
310 + adapter->bit_au1x00gpio_data = bit_au1x00gpio_data;
311 + adapter->bit_au1x00gpio_data.data = adapter;
312 +
313 + adapter->bit_au1x00gpio_data.data = adapter;
314 +
315 + adapter->scl_gpio = scl_gpio;
316 + adapter->sda_gpio = sda_gpio;
317 +
318 + if (sda_gpio < 32)
319 + {
320 + adapter->bit_au1x00gpio_data.setsda = bit_au1x00gpio_setsda;
321 + adapter->bit_au1x00gpio_data.getsda = bit_au1x00gpio_getsda;
322 + adapter->sda_mask = 1<<sda_gpio;
323 + }
324 + else if (sda_gpio >= 200 && sda_gpio <= 215)
325 + {
326 + adapter->bit_au1x00gpio_data.setsda = bit_au1x00gpio2_setsda;
327 + adapter->bit_au1x00gpio_data.getsda = bit_au1x00gpio2_getsda;
328 + adapter->sda_mask = 1<<(sda_gpio-200);
329 + }
330 +
331 +
332 + if (scl_gpio < 32)
333 + {
334 + adapter->bit_au1x00gpio_data.setscl = bit_au1x00gpio_setscl;
335 + adapter->bit_au1x00gpio_data.getscl = bit_au1x00gpio_getscl;
336 + adapter->scl_mask = 1<<scl_gpio;
337 + }
338 + else if (scl_gpio >= 200 && scl_gpio <= 215)
339 + {
340 + adapter->bit_au1x00gpio_data.setscl = bit_au1x00gpio2_setscl;
341 + adapter->bit_au1x00gpio_data.getscl = bit_au1x00gpio2_getscl;
342 + adapter->scl_mask = 1<<(scl_gpio-200);
343 + }
344 +
345 + au_writel(0L, SYS_PININPUTEN);
346 + if (check_i2c_au1x00gpio_adapter(adapter)==0)
347 + {
348 + adapter->bit_au1x00gpio_data.setsda (adapter, 1);
349 + adapter->bit_au1x00gpio_data.setscl (adapter, 1);
350 +
351 + if (i2c_bit_add_bus(&adapter->adapter) < 0)
352 + {
353 + printk(KERN_ERR "i2c-au1x00-gpio: Unable to register with I2C.\n");
354 + kfree(adapter);
355 + return -1; /* No good */
356 + }
357 +
358 + adapter->next = adapter_list;
359 + adapter_list = adapter;
360 + return 0;
361 + }
362 + }
363 + else
364 + printk(KERN_ERR "i2c-au1x00-gpio: Invalid argument scl_gpio=%d, sda_gpio=%d.\n", scl_gpio, sda_gpio);
365 + return -1;
366 +}
367 +
368 +
369 +
370 +static void i2c_au1x00gpio_delete (int scl_gpio, int sda_gpio)
371 +{
372 + struct i2c_au1x00gpio *adapter, *prev = NULL;
373 +
374 + for (adapter = adapter_list; adapter; adapter = adapter->next)
375 + {
376 + if (adapter->scl_gpio == scl_gpio &&
377 + adapter->sda_gpio == sda_gpio)
378 + {
379 + i2c_bit_del_bus(&adapter->adapter);
380 + if (prev)
381 + prev->next = adapter->next;
382 + else
383 + adapter_list = adapter->next;
384 + kfree(adapter);
385 + return;
386 + }
387 + prev = adapter;
388 + }
389 +}
390 +
391 +
392 +
393 +
394 +
395 +#ifndef CONFIG_I2C_AU1X00GPIO_SCL
396 +#define CONFIG_I2C_AU1X00GPIO_SCL (210)
397 +#endif
398 +
399 +#ifndef CONFIG_I2C_AU1X00GPIO_SDA
400 +#define CONFIG_I2C_AU1X00GPIO_SDA (9)
401 +#endif
402 +
403 +static int au1x00gpiopin_scl = CONFIG_I2C_AU1X00GPIO_SCL;
404 +static int au1x00gpiopin_sda = CONFIG_I2C_AU1X00GPIO_SDA;
405 +
406 +
407 +
408 +static int __init i2c_bit_au1x00gpio_init(void)
409 +{
410 + printk(KERN_INFO "i2c-au1x00gpio.o: i2c Au1x00 GPIO adapter module version\n");
411 +
412 + if (i2c_au1x00gpio_create (au1x00gpiopin_scl, au1x00gpiopin_sda) == 0)
413 + {
414 + printk(KERN_INFO "i2c-au1x00gpio.o: registered I2C-Bus for GPIO%d,GPIO%d\n",
415 + au1x00gpiopin_scl, au1x00gpiopin_sda
416 + );
417 + return 0;
418 + }
419 + printk(KERN_INFO "i2c-au1x00gpio.o: failed to register I2C-Bus for GPIO%d,GPIO%d\n",
420 + au1x00gpiopin_scl, au1x00gpiopin_sda
421 + );
422 + return -1;
423 +}
424 +
425 +
426 +static void __exit i2c_bit_au1x00gpio_exit(void)
427 +{
428 + i2c_au1x00gpio_delete (au1x00gpiopin_scl, au1x00gpiopin_sda);
429 +}
430 +
431 +module_param(au1x00gpiopin_scl, int, 0644);
432 +MODULE_PARM_DESC(au1x00gpiopin_scl, "GPIO pin number used for SCL pin.");
433 +
434 +module_param(au1x00gpiopin_sda, int, 0644);
435 +MODULE_PARM_DESC(au1x00gpiopin_sda, "GPIO pin number used for SDA pin.");
436 +
437 +MODULE_AUTHOR("Michael Stickel <michael@cubic.org>");
438 +MODULE_DESCRIPTION("I2C-Bus adapter routines for Au1x00 GPIO adapter.");
439 +MODULE_LICENSE("GPL");
440 +
441 +module_init(i2c_bit_au1x00gpio_init);
442 +module_exit(i2c_bit_au1x00gpio_exit);
443 diff -urN linux-2.6.19/include/linux/i2c-id.h linux-2.6.19.new/include/linux/i2c-id.h
444 --- linux-2.6.19/include/linux/i2c-id.h 2006-11-29 22:57:37.000000000 +0100
445 +++ linux-2.6.19.new/include/linux/i2c-id.h 2006-12-28 03:12:15.000000000 +0100
446 @@ -231,6 +231,9 @@
447 /* --- Au1550 PSC adapters adapters */
448 #define I2C_HW_AU1550_PSC 0x1b0000
449
450 +/* --- Au1x00 i2c GPIO adapter */
451 +#define I2C_HW_B_AU1x00GPIO 0x1b
452 +
453 /* --- SMBus only adapters */
454 #define I2C_HW_SMBUS_PIIX4 0x040000
455 #define I2C_HW_SMBUS_ALI15X3 0x040001