[ep93xx] add support for the Simplemachines Sim.One board
[openwrt.git] / target / linux / ep93xx / patches-2.6.30 / 003-ep93xx-i2c.patch
1 Index: linux-2.6.30.9/drivers/i2c/busses/Kconfig
2 ===================================================================
3 --- linux-2.6.30.9.orig/drivers/i2c/busses/Kconfig      2009-11-24 21:00:21.000000000 +0100
4 +++ linux-2.6.30.9/drivers/i2c/busses/Kconfig   2009-11-24 21:00:23.000000000 +0100
5 @@ -326,6 +326,10 @@
6           devices such as DaVinci NIC.
7           For details please see http://www.ti.com/davinci
8  
9 +config I2C_EP93XX
10 +       tristate "EP93XX I2C"
11 +       depends on I2C && ARCH_EP93XX
12 +
13  config I2C_GPIO
14         tristate "GPIO-based bitbanging I2C"
15         depends on GENERIC_GPIO
16 Index: linux-2.6.30.9/drivers/i2c/busses/Makefile
17 ===================================================================
18 --- linux-2.6.30.9.orig/drivers/i2c/busses/Makefile     2009-11-24 21:00:21.000000000 +0100
19 +++ linux-2.6.30.9/drivers/i2c/busses/Makefile  2009-11-24 21:00:23.000000000 +0100
20 @@ -30,6 +30,7 @@
21  obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
22  obj-$(CONFIG_I2C_CPM)          += i2c-cpm.o
23  obj-$(CONFIG_I2C_DAVINCI)      += i2c-davinci.o
24 +obj-$(CONFIG_I2C_EP93XX)       += i2c-ep93xx.o
25  obj-$(CONFIG_I2C_GPIO)         += i2c-gpio.o
26  obj-$(CONFIG_I2C_HIGHLANDER)   += i2c-highlander.o
27  obj-$(CONFIG_I2C_IBM_IIC)      += i2c-ibm_iic.o
28 Index: linux-2.6.30.9/drivers/i2c/busses/i2c-ep93xx.c
29 ===================================================================
30 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
31 +++ linux-2.6.30.9/drivers/i2c/busses/i2c-ep93xx.c      2009-11-24 21:00:38.000000000 +0100
32 @@ -0,0 +1,193 @@
33 +/* ------------------------------------------------------------------------ *
34 + * i2c-ep933xx.c I2C bus glue for Cirrus EP93xx                             *
35 + * ------------------------------------------------------------------------ *
36 +
37 +   Copyright (C) 2004 Michael Burian
38 +
39 +   Based on i2c-parport-light.c
40 +   Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org>
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 +
58 +//#include <linux/config.h>
59 +#include <linux/kernel.h>
60 +#include <linux/module.h>
61 +#include <linux/init.h>
62 +#include <linux/ioport.h>
63 +#include <linux/delay.h>
64 +#include <linux/i2c.h>
65 +#include <linux/i2c-algo-bit.h>
66 +#include <asm/io.h>
67 +#include <mach/hardware.h>
68 +
69 +//1/(2*clockfrequency)
70 +#define EE_DELAY_USEC       50
71 +#define GPIOG_EECLK 1
72 +#define GPIOG_EEDAT 2
73 +
74 +/* ----- I2C algorithm call-back functions and structures ----------------- */
75 +
76 +// TODO: optimize
77 +static void ep93xx_setscl(void *data, int state)
78 +{
79 +       unsigned int uiPGDR, uiPGDDR;
80 +
81 +       uiPGDR = inl(GPIO_PGDR);
82 +       uiPGDDR = inl(GPIO_PGDDR);
83 +
84 +       /* Configure the clock line as output. */
85 +       uiPGDDR |= GPIOG_EECLK;
86 +       outl(uiPGDDR, GPIO_PGDDR);
87 +
88 +       /* Set clock line to state */
89 +       if(state)
90 +               uiPGDR |= GPIOG_EECLK;
91 +       else
92 +               uiPGDR &= ~GPIOG_EECLK;
93 +
94 +       outl(uiPGDR, GPIO_PGDR);
95 +}
96 +
97 +static void ep93xx_setsda(void *data, int state)
98 +{
99 +       unsigned int uiPGDR, uiPGDDR;
100 +
101 +       uiPGDR = inl(GPIO_PGDR);
102 +       uiPGDDR = inl(GPIO_PGDDR);
103 +
104 +       /* Configure the data line as output. */
105 +       uiPGDDR |= GPIOG_EEDAT;
106 +       outl(uiPGDDR, GPIO_PGDDR);
107 +
108 +       /* Set data line to state */
109 +       if(state)
110 +               uiPGDR |= GPIOG_EEDAT;
111 +       else
112 +               uiPGDR &= ~GPIOG_EEDAT;
113 +
114 +       outl(uiPGDR, GPIO_PGDR);
115 +}
116 +
117 +static int ep93xx_getscl(void *data)
118 +{
119 +       unsigned int uiPGDR, uiPGDDR;
120 +
121 +       uiPGDR = inl(GPIO_PGDR);
122 +       uiPGDDR = inl(GPIO_PGDDR);
123 +
124 +       /* Configure the clock line as input */
125 +       uiPGDDR &= ~GPIOG_EECLK;
126 +       outl(uiPGDDR, GPIO_PGDDR);
127 +
128 +       /* Return state of the clock line */
129 +       return (inl(GPIO_PGDR) & GPIOG_EECLK) ? 1 : 0;
130 +}
131 +
132 +static int ep93xx_getsda(void *data)
133 +{
134 +       unsigned int uiPGDR, uiPGDDR;
135 +       uiPGDR = inl(GPIO_PGDR);
136 +       uiPGDDR = inl(GPIO_PGDDR);
137 +
138 +       /* Configure the data line as input */
139 +       uiPGDDR &= ~GPIOG_EEDAT;
140 +       outl(uiPGDDR, GPIO_PGDDR);
141 +
142 +       /* Return state of the data line */
143 +       return (inl(GPIO_PGDR) & GPIOG_EEDAT) ? 1 : 0;
144 +}
145 +
146 +/* ------------------------------------------------------------------------
147 + * Encapsulate the above functions in the correct operations structure.
148 + * This is only done when more than one hardware adapter is supported.
149 + */
150 +
151 +/* last line (us, ms, timeout)
152 + * us dominates the bit rate: 10us  means: 100Kbit/sec(25 means 40kbps)
153 + *                            10ms  not known
154 + *                            100ms timeout
155 + */
156 +static struct i2c_algo_bit_data ep93xx_data = {
157 +       .setsda         = ep93xx_setsda,
158 +       .setscl         = ep93xx_setscl,
159 +       .getsda         = ep93xx_getsda,
160 +       .getscl         = ep93xx_getscl,
161 +       .udelay         = 10,
162 +       //.mdelay               = 10,
163 +       .timeout        = HZ,
164 +};
165 +
166 +/* ----- I2c structure ---------------------------------------------------- */
167 +static struct i2c_adapter ep93xx_adapter = {
168 +       .owner          = THIS_MODULE,
169 +       .class          = I2C_CLASS_HWMON,
170 +       .algo_data      = &ep93xx_data,
171 +       .name           = "EP93XX I2C bit-bang interface",
172 +};
173 +
174 +/* ----- Module loading, unloading and information ------------------------ */
175 +
176 +static int __init i2c_ep93xx_init(void)
177 +{
178 +       unsigned long uiPGDR, uiPGDDR;
179 +
180 +       /* Read the current value of the GPIO data and data direction registers. */
181 +       uiPGDR = inl(GPIO_PGDR);
182 +       uiPGDDR = inl(GPIO_PGDDR);
183 +
184 +       /* If the GPIO pins have not been configured since reset, the data
185 +        * and clock lines will be set as inputs and with data value of 0.
186 +        * External pullup resisters are pulling them high.
187 +        * Set them both high before configuring them as outputs. */
188 +       uiPGDR |= (GPIOG_EEDAT | GPIOG_EECLK);
189 +       outl(uiPGDR, GPIO_PGDR);
190 +
191 +       /* Delay to meet the EE Interface timing specification. */
192 +       udelay(EE_DELAY_USEC);
193 +
194 +
195 +       /* Configure the EE data and clock lines as outputs. */
196 +       uiPGDDR |= (GPIOG_EEDAT | GPIOG_EECLK);
197 +       outl(uiPGDDR, GPIO_PGDDR);
198 +
199 +       /* Delay to meet the EE Interface timing specification. */
200 +       udelay(EE_DELAY_USEC);
201 +
202 +       /* Reset hardware to a sane state (SCL and SDA high) */
203 +       ep93xx_setsda(NULL, 1);
204 +       ep93xx_setscl(NULL, 1);
205 +
206 +       if (i2c_bit_add_bus(&ep93xx_adapter) > 0) {
207 +               printk(KERN_ERR "i2c-ep93xx: Unable to register with I2C\n");
208 +               return -ENODEV;
209 +       }
210 +
211 +       return 0;
212 +}
213 +
214 +static void __exit i2c_ep93xx_exit(void)
215 +{
216 +       //i2c_bit_del_bus(&ep93xx_adapter);
217 +       i2c_del_adapter(&ep93xx_adapter);
218 +}
219 +
220 +MODULE_AUTHOR("Michael Burian");
221 +MODULE_DESCRIPTION("I2C bus glue for Cirrus EP93xx processors");
222 +MODULE_LICENSE("GPL");
223 +
224 +module_init(i2c_ep93xx_init);
225 +module_exit(i2c_ep93xx_exit);