Rev 420 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
420 | giacomo | 1 | /* |
2 | * drivers/i2c/i2c-ibm_iic.c |
||
3 | * |
||
4 | * Support for the IIC peripheral on IBM PPC 4xx |
||
5 | * |
||
6 | * Copyright (c) 2003 Zultys Technologies. |
||
7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
||
8 | * |
||
9 | * Based on original work by |
||
10 | * Ian DaSilva <idasilva@mvista.com> |
||
11 | * Armin Kuster <akuster@mvista.com> |
||
12 | * Matt Porter <mporter@mvista.com> |
||
13 | * |
||
14 | * Copyright 2000-2003 MontaVista Software Inc. |
||
15 | * |
||
16 | * Original driver version was highly leveraged from i2c-elektor.c |
||
17 | * |
||
18 | * Copyright 1995-97 Simon G. Vogl |
||
19 | * 1998-99 Hans Berglund |
||
20 | * |
||
21 | * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> |
||
22 | * and even Frodo Looijaard <frodol@dds.nl> |
||
23 | * |
||
24 | * This program is free software; you can redistribute it and/or modify it |
||
25 | * under the terms of the GNU General Public License as published by the |
||
26 | * Free Software Foundation; either version 2 of the License, or (at your |
||
27 | * option) any later version. |
||
28 | * |
||
29 | */ |
||
30 | #include <linux/module.h> |
||
31 | #include <linux/kernel.h> |
||
32 | #include <linux/ioport.h> |
||
33 | #include <linux/delay.h> |
||
34 | #include <linux/slab.h> |
||
35 | #include <linux/init.h> |
||
36 | #include <linux/interrupt.h> |
||
37 | #include <asm/irq.h> |
||
38 | #include <asm/io.h> |
||
39 | #include <linux/i2c.h> |
||
40 | #include <linux/i2c-id.h> |
||
41 | #include <asm/ocp.h> |
||
42 | #include <asm/ibm4xx.h> |
||
43 | |||
44 | #include "i2c-ibm_iic.h" |
||
45 | |||
46 | #define DRIVER_VERSION "2.0" |
||
47 | |||
48 | MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION); |
||
49 | MODULE_LICENSE("GPL"); |
||
50 | |||
51 | static int iic_scan = 0; |
||
52 | MODULE_PARM(iic_scan, "i"); |
||
53 | MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus"); |
||
54 | |||
55 | static int iic_force_poll = 0; |
||
56 | MODULE_PARM(iic_force_poll, "i"); |
||
57 | MODULE_PARM_DESC(iic_force_poll, "Force polling mode"); |
||
58 | |||
59 | static int iic_force_fast = 0; |
||
60 | MODULE_PARM(iic_force_fast, "i"); |
||
61 | MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)"); |
||
62 | |||
63 | #define DBG_LEVEL 0 |
||
64 | |||
65 | #ifdef DBG |
||
66 | #undef DBG |
||
67 | #endif |
||
68 | |||
69 | #ifdef DBG2 |
||
70 | #undef DBG2 |
||
71 | #endif |
||
72 | |||
73 | #if DBG_LEVEL > 0 |
||
74 | # define DBG(x...) printk(KERN_DEBUG "ibm-iic" ##x) |
||
75 | #else |
||
76 | # define DBG(x...) ((void)0) |
||
77 | #endif |
||
78 | #if DBG_LEVEL > 1 |
||
79 | # define DBG2(x...) DBG( ##x ) |
||
80 | #else |
||
81 | # define DBG2(x...) ((void)0) |
||
82 | #endif |
||
83 | #if DBG_LEVEL > 2 |
||
84 | static void dump_iic_regs(const char* header, struct ibm_iic_private* dev) |
||
85 | { |
||
86 | volatile struct iic_regs *iic = dev->vaddr; |
||
87 | printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header); |
||
88 | printk(KERN_DEBUG " cntl = 0x%02x, mdcntl = 0x%02x\n" |
||
89 | KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n" |
||
90 | KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n" |
||
91 | KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n", |
||
92 | in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), |
||
93 | in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), |
||
94 | in_8(&iic->xtcntlss), in_8(&iic->directcntl)); |
||
95 | } |
||
96 | # define DUMP_REGS(h,dev) dump_iic_regs((h),(dev)) |
||
97 | #else |
||
98 | # define DUMP_REGS(h,dev) ((void)0) |
||
99 | #endif |
||
100 | |||
101 | /* Enable/disable interrupt generation */ |
||
102 | static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable) |
||
103 | { |
||
104 | out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0); |
||
105 | } |
||
106 | |||
107 | /* |
||
108 | * Initialize IIC interface. |
||
109 | */ |
||
110 | static void iic_dev_init(struct ibm_iic_private* dev) |
||
111 | { |
||
112 | volatile struct iic_regs *iic = dev->vaddr; |
||
113 | |||
114 | DBG("%d: init\n", dev->idx); |
||
115 | |||
116 | /* Clear master address */ |
||
117 | out_8(&iic->lmadr, 0); |
||
118 | out_8(&iic->hmadr, 0); |
||
119 | |||
120 | /* Clear slave address */ |
||
121 | out_8(&iic->lsadr, 0); |
||
122 | out_8(&iic->hsadr, 0); |
||
123 | |||
124 | /* Clear status & extended status */ |
||
125 | out_8(&iic->sts, STS_SCMP | STS_IRQA); |
||
126 | out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA |
||
127 | | EXTSTS_ICT | EXTSTS_XFRA); |
||
128 | |||
129 | /* Set clock divider */ |
||
130 | out_8(&iic->clkdiv, dev->clckdiv); |
||
131 | |||
132 | /* Clear transfer count */ |
||
133 | out_8(&iic->xfrcnt, 0); |
||
134 | |||
135 | /* Clear extended control and status */ |
||
136 | out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC |
||
137 | | XTCNTLSS_SWS); |
||
138 | |||
139 | /* Clear control register */ |
||
140 | out_8(&iic->cntl, 0); |
||
141 | |||
142 | /* Enable interrupts if possible */ |
||
143 | iic_interrupt_mode(dev, dev->irq >= 0); |
||
144 | |||
145 | /* Set mode control */ |
||
146 | out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS |
||
147 | | (dev->fast_mode ? MDCNTL_FSM : 0)); |
||
148 | |||
149 | DUMP_REGS("iic_init", dev); |
||
150 | } |
||
151 | |||
152 | /* |
||
153 | * Reset IIC interface |
||
154 | */ |
||
155 | static void iic_dev_reset(struct ibm_iic_private* dev) |
||
156 | { |
||
157 | volatile struct iic_regs *iic = dev->vaddr; |
||
158 | int i; |
||
159 | u8 dc; |
||
160 | |||
161 | DBG("%d: soft reset\n", dev->idx); |
||
162 | DUMP_REGS("reset", dev); |
||
163 | |||
164 | /* Place chip in the reset state */ |
||
165 | out_8(&iic->xtcntlss, XTCNTLSS_SRST); |
||
166 | |||
167 | /* Check if bus is free */ |
||
168 | dc = in_8(&iic->directcntl); |
||
169 | if (!DIRCTNL_FREE(dc)){ |
||
170 | DBG("%d: trying to regain bus control\n", dev->idx); |
||
171 | |||
172 | /* Try to set bus free state */ |
||
173 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); |
||
174 | |||
175 | /* Wait until we regain bus control */ |
||
176 | for (i = 0; i < 100; ++i){ |
||
177 | dc = in_8(&iic->directcntl); |
||
178 | if (DIRCTNL_FREE(dc)) |
||
179 | break; |
||
180 | |||
181 | /* Toggle SCL line */ |
||
182 | dc ^= DIRCNTL_SCC; |
||
183 | out_8(&iic->directcntl, dc); |
||
184 | udelay(10); |
||
185 | dc ^= DIRCNTL_SCC; |
||
186 | out_8(&iic->directcntl, dc); |
||
187 | |||
188 | /* be nice */ |
||
189 | cond_resched(); |
||
190 | } |
||
191 | } |
||
192 | |||
193 | /* Remove reset */ |
||
194 | out_8(&iic->xtcntlss, 0); |
||
195 | |||
196 | /* Reinitialize interface */ |
||
197 | iic_dev_init(dev); |
||
198 | } |
||
199 | |||
200 | /* |
||
201 | * IIC interrupt handler |
||
202 | */ |
||
203 | static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs) |
||
204 | { |
||
205 | struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id; |
||
206 | volatile struct iic_regs* iic = dev->vaddr; |
||
207 | |||
208 | DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", |
||
209 | dev->idx, in_8(&iic->sts), in_8(&iic->extsts)); |
||
210 | |||
211 | /* Acknowledge IRQ and wakeup iic_wait_for_tc */ |
||
212 | out_8(&iic->sts, STS_IRQA | STS_SCMP); |
||
213 | wake_up_interruptible(&dev->wq); |
||
214 | |||
215 | return IRQ_HANDLED; |
||
216 | } |
||
217 | |||
218 | /* |
||
219 | * Get master transfer result and clear errors if any. |
||
220 | * Returns the number of actually transferred bytes or error (<0) |
||
221 | */ |
||
222 | static int iic_xfer_result(struct ibm_iic_private* dev) |
||
223 | { |
||
224 | volatile struct iic_regs *iic = dev->vaddr; |
||
225 | |||
226 | if (unlikely(in_8(&iic->sts) & STS_ERR)){ |
||
227 | DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, |
||
228 | in_8(&iic->extsts)); |
||
229 | |||
230 | /* Clear errors and possible pending IRQs */ |
||
231 | out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | |
||
232 | EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA); |
||
233 | |||
234 | /* Flush master data buffer */ |
||
235 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); |
||
236 | |||
237 | /* Is bus free? |
||
238 | * If error happened during combined xfer |
||
239 | * IIC interface is usually stuck in some strange |
||
240 | * state, the only way out - soft reset. |
||
241 | */ |
||
242 | if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ |
||
243 | DBG("%d: bus is stuck, resetting\n", dev->idx); |
||
244 | iic_dev_reset(dev); |
||
245 | } |
||
246 | return -EREMOTEIO; |
||
247 | } |
||
248 | else |
||
249 | return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK; |
||
250 | } |
||
251 | |||
252 | /* |
||
253 | * Try to abort active transfer. |
||
254 | */ |
||
255 | static void iic_abort_xfer(struct ibm_iic_private* dev) |
||
256 | { |
||
257 | volatile struct iic_regs *iic = dev->vaddr; |
||
258 | unsigned long x; |
||
259 | |||
260 | DBG("%d: iic_abort_xfer\n", dev->idx); |
||
261 | |||
262 | out_8(&iic->cntl, CNTL_HMT); |
||
263 | |||
264 | /* |
||
265 | * Wait for the abort command to complete. |
||
266 | * It's not worth to be optimized, just poll (timeout >= 1 tick) |
||
267 | */ |
||
268 | x = jiffies + 2; |
||
269 | while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ |
||
270 | if (time_after(jiffies, x)){ |
||
271 | DBG("%d: abort timeout, resetting...\n", dev->idx); |
||
272 | iic_dev_reset(dev); |
||
273 | return; |
||
274 | } |
||
275 | schedule(); |
||
276 | } |
||
277 | |||
278 | /* Just to clear errors */ |
||
279 | iic_xfer_result(dev); |
||
280 | } |
||
281 | |||
282 | /* |
||
283 | * Wait for master transfer to complete. |
||
284 | * It puts current process to sleep until we get interrupt or timeout expires. |
||
285 | * Returns the number of transferred bytes or error (<0) |
||
286 | */ |
||
287 | static int iic_wait_for_tc(struct ibm_iic_private* dev){ |
||
288 | |||
289 | volatile struct iic_regs *iic = dev->vaddr; |
||
290 | int ret = 0; |
||
291 | |||
292 | if (dev->irq >= 0){ |
||
293 | /* Interrupt mode */ |
||
294 | wait_queue_t wait; |
||
295 | init_waitqueue_entry(&wait, current); |
||
296 | |||
297 | add_wait_queue(&dev->wq, &wait); |
||
298 | set_current_state(TASK_INTERRUPTIBLE); |
||
299 | if (in_8(&iic->sts) & STS_PT) |
||
300 | schedule_timeout(dev->adap.timeout * HZ); |
||
301 | set_current_state(TASK_RUNNING); |
||
302 | remove_wait_queue(&dev->wq, &wait); |
||
303 | |||
304 | if (unlikely(signal_pending(current))){ |
||
305 | DBG("%d: wait interrupted\n", dev->idx); |
||
306 | ret = -ERESTARTSYS; |
||
307 | } else if (unlikely(in_8(&iic->sts) & STS_PT)){ |
||
308 | DBG("%d: wait timeout\n", dev->idx); |
||
309 | ret = -ETIMEDOUT; |
||
310 | } |
||
311 | } |
||
312 | else { |
||
313 | /* Polling mode */ |
||
314 | unsigned long x = jiffies + dev->adap.timeout * HZ; |
||
315 | |||
316 | while (in_8(&iic->sts) & STS_PT){ |
||
317 | if (unlikely(time_after(jiffies, x))){ |
||
318 | DBG("%d: poll timeout\n", dev->idx); |
||
319 | ret = -ETIMEDOUT; |
||
320 | break; |
||
321 | } |
||
322 | |||
323 | if (unlikely(signal_pending(current))){ |
||
324 | DBG("%d: poll interrupted\n", dev->idx); |
||
325 | ret = -ERESTARTSYS; |
||
326 | break; |
||
327 | } |
||
328 | schedule(); |
||
329 | } |
||
330 | } |
||
331 | |||
332 | if (unlikely(ret < 0)) |
||
333 | iic_abort_xfer(dev); |
||
334 | else |
||
335 | ret = iic_xfer_result(dev); |
||
336 | |||
337 | DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret); |
||
338 | |||
339 | return ret; |
||
340 | } |
||
341 | |||
342 | /* |
||
343 | * Low level master transfer routine |
||
344 | */ |
||
345 | static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, |
||
346 | int combined_xfer) |
||
347 | { |
||
348 | volatile struct iic_regs *iic = dev->vaddr; |
||
349 | char* buf = pm->buf; |
||
350 | int i, j, loops, ret = 0; |
||
351 | int len = pm->len; |
||
352 | |||
353 | u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT; |
||
354 | if (pm->flags & I2C_M_RD) |
||
355 | cntl |= CNTL_RW; |
||
356 | |||
357 | loops = (len + 3) / 4; |
||
358 | for (i = 0; i < loops; ++i, len -= 4){ |
||
359 | int count = len > 4 ? 4 : len; |
||
360 | u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT); |
||
361 | |||
362 | if (!(cntl & CNTL_RW)) |
||
363 | for (j = 0; j < count; ++j) |
||
364 | out_8((volatile u8*)&iic->mdbuf, *buf++); |
||
365 | |||
366 | if (i < loops - 1) |
||
367 | cmd |= CNTL_CHT; |
||
368 | else if (combined_xfer) |
||
369 | cmd |= CNTL_RPST; |
||
370 | |||
371 | DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd); |
||
372 | |||
373 | /* Start transfer */ |
||
374 | out_8(&iic->cntl, cmd); |
||
375 | |||
376 | /* Wait for completion */ |
||
377 | ret = iic_wait_for_tc(dev); |
||
378 | |||
379 | if (unlikely(ret < 0)) |
||
380 | break; |
||
381 | else if (unlikely(ret != count)){ |
||
382 | DBG("%d: xfer_bytes, requested %d, transfered %d\n", |
||
383 | dev->idx, count, ret); |
||
384 | |||
385 | /* If it's not a last part of xfer, abort it */ |
||
386 | if (combined_xfer || (i < loops - 1)) |
||
387 | iic_abort_xfer(dev); |
||
388 | |||
389 | ret = -EREMOTEIO; |
||
390 | break; |
||
391 | } |
||
392 | |||
393 | if (cntl & CNTL_RW) |
||
394 | for (j = 0; j < count; ++j) |
||
395 | *buf++ = in_8((volatile u8*)&iic->mdbuf); |
||
396 | } |
||
397 | |||
398 | return ret > 0 ? 0 : ret; |
||
399 | } |
||
400 | |||
401 | /* |
||
402 | * Set target slave address for master transfer |
||
403 | */ |
||
404 | static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg) |
||
405 | { |
||
406 | volatile struct iic_regs *iic = dev->vaddr; |
||
407 | u16 addr = msg->addr; |
||
408 | |||
409 | DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, |
||
410 | addr, msg->flags & I2C_M_TEN ? 10 : 7); |
||
411 | |||
412 | if (msg->flags & I2C_M_TEN){ |
||
413 | out_8(&iic->cntl, CNTL_AMD); |
||
414 | out_8(&iic->lmadr, addr); |
||
415 | out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06)); |
||
416 | } |
||
417 | else { |
||
418 | out_8(&iic->cntl, 0); |
||
419 | out_8(&iic->lmadr, addr << 1); |
||
420 | } |
||
421 | } |
||
422 | |||
423 | static inline int iic_invalid_address(const struct i2c_msg* p) |
||
424 | { |
||
425 | return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f)); |
||
426 | } |
||
427 | |||
428 | static inline int iic_address_neq(const struct i2c_msg* p1, |
||
429 | const struct i2c_msg* p2) |
||
430 | { |
||
431 | return (p1->addr != p2->addr) |
||
432 | || ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN)); |
||
433 | } |
||
434 | |||
435 | /* |
||
436 | * Generic master transfer entrypoint. |
||
437 | * Returns the number of processed messages or error (<0) |
||
438 | */ |
||
439 | static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) |
||
440 | { |
||
441 | struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap)); |
||
442 | volatile struct iic_regs *iic = dev->vaddr; |
||
443 | int i, ret = 0; |
||
444 | |||
445 | DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num); |
||
446 | |||
447 | if (!num) |
||
448 | return 0; |
||
449 | |||
450 | /* Check the sanity of the passed messages. |
||
451 | * Uhh, generic i2c layer is more suitable place for such code... |
||
452 | */ |
||
453 | if (unlikely(iic_invalid_address(&msgs[0]))){ |
||
454 | DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, |
||
455 | msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7); |
||
456 | return -EINVAL; |
||
457 | } |
||
458 | for (i = 0; i < num; ++i){ |
||
459 | if (unlikely(msgs[i].len <= 0)){ |
||
460 | DBG("%d: invalid len %d in msg[%d]\n", dev->idx, |
||
461 | msgs[i].len, i); |
||
462 | return -EINVAL; |
||
463 | } |
||
464 | if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){ |
||
465 | DBG("%d: invalid addr in msg[%d]\n", dev->idx, i); |
||
466 | return -EINVAL; |
||
467 | } |
||
468 | } |
||
469 | |||
470 | /* Check bus state */ |
||
471 | if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){ |
||
472 | DBG("%d: iic_xfer, bus is not free\n", dev->idx); |
||
473 | |||
474 | /* Usually it means something serious has happend. |
||
475 | * We *cannot* have unfinished previous transfer |
||
476 | * so it doesn't make any sense to try to stop it. |
||
477 | * Probably we were not able to recover from the |
||
478 | * previous error. |
||
479 | * The only *reasonable* thing I can think of here |
||
480 | * is soft reset. --ebs |
||
481 | */ |
||
482 | iic_dev_reset(dev); |
||
483 | |||
484 | if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ |
||
485 | DBG("%d: iic_xfer, bus is still not free\n", dev->idx); |
||
486 | return -EREMOTEIO; |
||
487 | } |
||
488 | } |
||
489 | else { |
||
490 | /* Flush master data buffer (just in case) */ |
||
491 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); |
||
492 | } |
||
493 | |||
494 | /* Load slave address */ |
||
495 | iic_address(dev, &msgs[0]); |
||
496 | |||
497 | /* Do real transfer */ |
||
498 | for (i = 0; i < num && !ret; ++i) |
||
499 | ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1); |
||
500 | |||
501 | return ret < 0 ? ret : num; |
||
502 | } |
||
503 | |||
504 | static u32 iic_func(struct i2c_adapter *adap) |
||
505 | { |
||
506 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; |
||
507 | } |
||
508 | |||
509 | static struct i2c_algorithm iic_algo = { |
||
510 | .name = "IBM IIC algorithm", |
||
511 | .id = I2C_ALGO_OCP, |
||
512 | .master_xfer = iic_xfer, |
||
513 | .smbus_xfer = NULL, |
||
514 | .slave_send = NULL, |
||
515 | .slave_recv = NULL, |
||
516 | .algo_control = NULL, |
||
517 | .functionality = iic_func |
||
518 | }; |
||
519 | |||
520 | /* |
||
521 | * Scan bus for valid 7-bit addresses (ie things that ACK on 1 byte read) |
||
522 | * We only scan range [0x08 - 0x77], all other addresses are reserved anyway |
||
523 | */ |
||
524 | static void __devinit iic_scan_bus(struct ibm_iic_private* dev) |
||
525 | { |
||
526 | int found = 0; |
||
527 | char dummy; |
||
528 | struct i2c_msg msg = { |
||
529 | .buf = &dummy, |
||
530 | .len = sizeof(dummy), |
||
531 | .flags = I2C_M_RD |
||
532 | }; |
||
533 | |||
534 | printk(KERN_INFO "ibm-iic%d: scanning bus...\n" KERN_INFO, dev->idx); |
||
535 | |||
536 | for (msg.addr = 8; msg.addr < 0x78; ++msg.addr) |
||
537 | if (iic_xfer(&dev->adap, &msg, 1) == 1){ |
||
538 | ++found; |
||
539 | printk(" 0x%02x", msg.addr); |
||
540 | } |
||
541 | |||
542 | printk("%sibm-iic%d: %d device(s) detected\n", |
||
543 | found ? "\n" KERN_INFO : "", dev->idx, found); |
||
544 | } |
||
545 | |||
546 | /* |
||
547 | * Calculates IICx_CLCKDIV value for a specific OPB clock frequency |
||
548 | */ |
||
549 | static inline u8 iic_clckdiv(unsigned int opb) |
||
550 | { |
||
551 | /* Compatibility kludge, should go away after all cards |
||
552 | * are fixed to fill correct value for opbfreq. |
||
553 | * Previous driver version used hardcoded divider value 4, |
||
554 | * it corresponds to OPB frequency from the range (40, 50] MHz |
||
555 | */ |
||
556 | if (!opb){ |
||
557 | printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq," |
||
558 | " fix your board specific setup\n"); |
||
559 | opb = 50000000; |
||
560 | } |
||
561 | |||
562 | /* Convert to MHz */ |
||
563 | opb /= 1000000; |
||
564 | |||
565 | if (opb < 20 || opb > 150){ |
||
566 | printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n", |
||
567 | opb); |
||
568 | opb = opb < 20 ? 20 : 150; |
||
569 | } |
||
570 | return (u8)((opb + 9) / 10 - 1); |
||
571 | } |
||
572 | |||
573 | /* |
||
574 | * Register single IIC interface |
||
575 | */ |
||
576 | static int __devinit iic_probe(struct ocp_device *ocp){ |
||
577 | |||
578 | struct ibm_iic_private* dev; |
||
579 | struct i2c_adapter* adap; |
||
580 | int ret; |
||
581 | bd_t* bd = (bd_t*)&__res; |
||
582 | |||
583 | if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){ |
||
584 | printk(KERN_CRIT "ibm-iic: failed to allocate device data\n"); |
||
585 | return -ENOMEM; |
||
586 | } |
||
587 | |||
588 | memset(dev, 0, sizeof(*dev)); |
||
589 | dev->idx = ocp->num; |
||
590 | ocp_set_drvdata(ocp, dev); |
||
591 | |||
592 | if (!(dev->vaddr = ioremap(ocp->paddr, sizeof(struct iic_regs)))){ |
||
593 | printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n", |
||
594 | dev->idx); |
||
595 | ret = -ENXIO; |
||
596 | goto fail2; |
||
597 | } |
||
598 | |||
599 | init_waitqueue_head(&dev->wq); |
||
600 | |||
601 | dev->irq = iic_force_poll ? -1 : ocp->irq; |
||
602 | if (dev->irq >= 0){ |
||
603 | /* Disable interrupts until we finish intialization, |
||
604 | assumes level-sensitive IRQ setup... |
||
605 | */ |
||
606 | iic_interrupt_mode(dev, 0); |
||
607 | if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){ |
||
608 | printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", |
||
609 | dev->idx, dev->irq); |
||
610 | /* Fallback to the polling mode */ |
||
611 | dev->irq = -1; |
||
612 | } |
||
613 | } |
||
614 | |||
615 | if (dev->irq < 0) |
||
616 | printk(KERN_WARNING "ibm-iic%d: using polling mode\n", |
||
617 | dev->idx); |
||
618 | |||
619 | /* Board specific settings */ |
||
620 | BUG_ON(dev->idx >= sizeof(bd->bi_iic_fast) / sizeof(bd->bi_iic_fast[0])); |
||
621 | dev->fast_mode = iic_force_fast ? 1 : bd->bi_iic_fast[dev->idx]; |
||
622 | |||
623 | /* clckdiv is the same for *all* IIC interfaces, |
||
624 | * but I'd rather make a copy than introduce another global. --ebs |
||
625 | */ |
||
626 | dev->clckdiv = iic_clckdiv(bd->bi_opb_busfreq); |
||
627 | DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv); |
||
628 | |||
629 | /* Initialize IIC interface */ |
||
630 | iic_dev_init(dev); |
||
631 | |||
632 | /* Register it with i2c layer */ |
||
633 | adap = &dev->adap; |
||
634 | strcpy(adap->dev.name, "IBM IIC"); |
||
635 | i2c_set_adapdata(adap, dev); |
||
636 | adap->id = I2C_HW_OCP | iic_algo.id; |
||
637 | adap->algo = &iic_algo; |
||
638 | adap->client_register = NULL; |
||
639 | adap->client_unregister = NULL; |
||
640 | adap->timeout = 1; |
||
641 | adap->retries = 1; |
||
642 | |||
643 | if ((ret = i2c_add_adapter(adap)) != 0){ |
||
644 | printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n", |
||
645 | dev->idx); |
||
646 | goto fail; |
||
647 | } |
||
648 | |||
649 | printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx, |
||
650 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); |
||
651 | |||
652 | /* Scan bus if requested by user */ |
||
653 | if (iic_scan) |
||
654 | iic_scan_bus(dev); |
||
655 | |||
656 | return 0; |
||
657 | |||
658 | fail: |
||
659 | if (dev->irq >= 0){ |
||
660 | iic_interrupt_mode(dev, 0); |
||
661 | free_irq(dev->irq, dev); |
||
662 | } |
||
663 | |||
664 | iounmap((void*)dev->vaddr); |
||
665 | fail2: |
||
666 | ocp_set_drvdata(ocp, 0); |
||
667 | kfree(dev); |
||
668 | return ret; |
||
669 | } |
||
670 | |||
671 | /* |
||
672 | * Cleanup initialized IIC interface |
||
673 | */ |
||
674 | static void __devexit iic_remove(struct ocp_device *ocp) |
||
675 | { |
||
676 | struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp); |
||
677 | BUG_ON(dev == NULL); |
||
678 | if (i2c_del_adapter(&dev->adap)){ |
||
679 | printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n", |
||
680 | dev->idx); |
||
681 | /* That's *very* bad, just shutdown IRQ ... */ |
||
682 | if (dev->irq >= 0){ |
||
683 | iic_interrupt_mode(dev, 0); |
||
684 | free_irq(dev->irq, dev); |
||
685 | dev->irq = -1; |
||
686 | } |
||
687 | } else { |
||
688 | if (dev->irq >= 0){ |
||
689 | iic_interrupt_mode(dev, 0); |
||
690 | free_irq(dev->irq, dev); |
||
691 | } |
||
692 | iounmap((void*)dev->vaddr); |
||
693 | kfree(dev); |
||
694 | } |
||
695 | } |
||
696 | |||
697 | static struct ocp_device_id ibm_iic_ids[] __devinitdata = |
||
698 | { |
||
699 | { .vendor = OCP_VENDOR_IBM, .device = OCP_FUNC_IIC }, |
||
700 | { .vendor = OCP_VENDOR_INVALID } |
||
701 | }; |
||
702 | |||
703 | MODULE_DEVICE_TABLE(ocp, ibm_iic_ids); |
||
704 | |||
705 | static struct ocp_driver ibm_iic_driver = |
||
706 | { |
||
707 | .name = "ocp_iic", |
||
708 | .id_table = ibm_iic_ids, |
||
709 | .probe = iic_probe, |
||
710 | .remove = __devexit_p(iic_remove), |
||
711 | #if defined(CONFIG_PM) |
||
712 | .suspend = NULL, |
||
713 | .resume = NULL, |
||
714 | #endif |
||
715 | }; |
||
716 | |||
717 | static int __init iic_init(void) |
||
718 | { |
||
719 | printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n"); |
||
720 | return ocp_module_init(&ibm_iic_driver); |
||
721 | } |
||
722 | |||
723 | static void __exit iic_exit(void) |
||
724 | { |
||
725 | ocp_unregister_driver(&ibm_iic_driver); |
||
726 | } |
||
727 | |||
728 | module_init(iic_init); |
||
729 | module_exit(iic_exit); |