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