1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/kernel.h>
37#include <linux/ioport.h>
38#include <linux/module.h>
39#include <linux/delay.h>
40#include <linux/slab.h>
41#include <linux/init.h>
42#include <asm/irq.h>
43#include <asm/io.h>
44
45#include <linux/i2c.h>
46#include <linux/i2c-algo-ite.h>
47#include <linux/i2c-adap-ite.h>
48#include "i2c-ite.h"
49
50#define DEFAULT_BASE 0x14014030
51#define ITE_IIC_IO_SIZE 0x40
52#define DEFAULT_IRQ 0
53#define DEFAULT_CLOCK 0x1b0e
54#define DEFAULT_OWN 0x55
55
56static int base = 0;
57static int irq = 0;
58static int clock = 0;
59static int own = 0;
60
61static int i2c_debug=0;
62static struct iic_ite gpi;
63static wait_queue_head_t iic_wait;
64static int iic_pending;
65
66
67#define DEB(x) if (i2c_debug>=1) x
68#define DEB2(x) if (i2c_debug>=2) x
69#define DEB3(x) if (i2c_debug>=3) x
70#define DEBE(x) x
71
72
73
74
75static void iic_ite_setiic(void *data, int ctl, short val)
76{
77 unsigned long j = jiffies + 10;
78
79 DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff));
80 DEB3({while (jiffies < j) schedule();})
81 outw(val,ctl);
82}
83
84static short iic_ite_getiic(void *data, int ctl)
85{
86 short val;
87
88 val = inw(ctl);
89 DEB3(printk("Read 0x%02x from 0x%x\n",(unsigned short)val, ctl&0xff));
90 return (val);
91}
92
93
94
95
96
97static int iic_ite_getown(void *data)
98{
99 return (gpi.iic_own);
100}
101
102
103static int iic_ite_getclock(void *data)
104{
105 return (gpi.iic_clock);
106}
107
108
109#if 0
110static void iic_ite_sleep(unsigned long timeout)
111{
112 schedule_timeout( timeout * HZ);
113}
114#endif
115
116
117
118
119
120static void iic_ite_waitforpin(void) {
121
122 int timeout = 2;
123
124
125
126
127
128
129
130 if (gpi.iic_irq > 0) {
131 cli();
132 if (iic_pending == 0) {
133 interruptible_sleep_on_timeout(&iic_wait, timeout*HZ );
134 } else
135 iic_pending = 0;
136 sti();
137 } else {
138 udelay(100);
139 }
140}
141
142
143static void iic_ite_handler(int this_irq, void *dev_id, struct pt_regs *regs)
144{
145
146 iic_pending = 1;
147
148 DEB2(printk("iic_ite_handler: in interrupt handler\n"));
149 wake_up_interruptible(&iic_wait);
150}
151
152
153
154
155
156static int iic_hw_resrc_init(void)
157{
158 if (check_region(gpi.iic_base, ITE_IIC_IO_SIZE) < 0 ) {
159 return -ENODEV;
160 } else {
161 request_region(gpi.iic_base, ITE_IIC_IO_SIZE,
162 "i2c (i2c bus adapter)");
163 }
164 if (gpi.iic_irq > 0) {
165 if (request_irq(gpi.iic_irq, iic_ite_handler, 0, "ITE IIC", 0) < 0) {
166 gpi.iic_irq = 0;
167 } else
168 DEB3(printk("Enabled IIC IRQ %d\n", gpi.iic_irq));
169 enable_irq(gpi.iic_irq);
170 }
171 return 0;
172}
173
174
175static void iic_ite_release(void)
176{
177 if (gpi.iic_irq > 0) {
178 disable_irq(gpi.iic_irq);
179 free_irq(gpi.iic_irq, 0);
180 }
181 release_region(gpi.iic_base , 2);
182}
183
184
185static int iic_ite_reg(struct i2c_client *client)
186{
187 return 0;
188}
189
190
191static int iic_ite_unreg(struct i2c_client *client)
192{
193 return 0;
194}
195
196
197static void iic_ite_inc_use(struct i2c_adapter *adap)
198{
199#ifdef MODULE
200 MOD_INC_USE_COUNT;
201#endif
202}
203
204
205static void iic_ite_dec_use(struct i2c_adapter *adap)
206{
207#ifdef MODULE
208 MOD_DEC_USE_COUNT;
209#endif
210}
211
212
213
214
215
216
217static struct i2c_algo_iic_data iic_ite_data = {
218 NULL,
219 iic_ite_setiic,
220 iic_ite_getiic,
221 iic_ite_getown,
222 iic_ite_getclock,
223 iic_ite_waitforpin,
224 80, 80, 100,
225};
226
227static struct i2c_adapter iic_ite_ops = {
228 "ITE IIC adapter",
229 I2C_HW_I_IIC,
230 NULL,
231 &iic_ite_data,
232 iic_ite_inc_use,
233 iic_ite_dec_use,
234 iic_ite_reg,
235 iic_ite_unreg,
236};
237
238
239
240
241
242static int __init iic_ite_init(void)
243{
244
245 struct iic_ite *piic = &gpi;
246
247 printk(KERN_INFO "Initialize ITE IIC adapter module\n");
248 if (base == 0)
249 piic->iic_base = DEFAULT_BASE;
250 else
251 piic->iic_base = base;
252
253 if (irq == 0)
254 piic->iic_irq = DEFAULT_IRQ;
255 else
256 piic->iic_irq = irq;
257
258 if (clock == 0)
259 piic->iic_clock = DEFAULT_CLOCK;
260 else
261 piic->iic_clock = clock;
262
263 if (own == 0)
264 piic->iic_own = DEFAULT_OWN;
265 else
266 piic->iic_own = own;
267
268 iic_ite_data.data = (void *)piic;
269 if (iic_hw_resrc_init() == 0) {
270 if (i2c_iic_add_bus(&iic_ite_ops) < 0)
271 return -ENODEV;
272 } else {
273 return -ENODEV;
274 }
275 printk(KERN_INFO " found device at %#x irq %d.\n",
276 piic->iic_base, piic->iic_irq);
277 return 0;
278}
279
280
281static void iic_ite_exit(void)
282{
283 i2c_iic_del_bus(&iic_ite_ops);
284 iic_ite_release();
285}
286
287EXPORT_NO_SYMBOLS;
288
289
290
291
292MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
293MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
294MODULE_LICENSE("GPL");
295
296MODULE_PARM(base, "i");
297MODULE_PARM(irq, "i");
298MODULE_PARM(clock, "i");
299MODULE_PARM(own, "i");
300MODULE_PARM(i2c_debug,"i");
301
302
303
304
305
306
307
308
309module_init(iic_ite_init);
310
311
312module_exit(iic_ite_exit);
313