diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/i2c/busses/i2c-ibm_iic.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/i2c/busses/i2c-ibm_iic.c')
-rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 819 |
1 files changed, 819 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c new file mode 100644 index 00000000000..bb885215c08 --- /dev/null +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -0,0 +1,819 @@ | |||
1 | /* | ||
2 | * drivers/i2c/i2c-ibm_iic.c | ||
3 | * | ||
4 | * Support for the IIC peripheral on IBM PPC 4xx | ||
5 | * | ||
6 | * Copyright (c) 2003, 2004 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 | |||
31 | #include <linux/config.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/ioport.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/slab.h> | ||
37 | #include <linux/init.h> | ||
38 | #include <linux/interrupt.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/io.h> | ||
41 | #include <linux/i2c.h> | ||
42 | #include <linux/i2c-id.h> | ||
43 | #include <asm/ocp.h> | ||
44 | #include <asm/ibm4xx.h> | ||
45 | |||
46 | #include "i2c-ibm_iic.h" | ||
47 | |||
48 | #define DRIVER_VERSION "2.1" | ||
49 | |||
50 | MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION); | ||
51 | MODULE_LICENSE("GPL"); | ||
52 | |||
53 | static int iic_force_poll; | ||
54 | module_param(iic_force_poll, bool, 0); | ||
55 | MODULE_PARM_DESC(iic_force_poll, "Force polling mode"); | ||
56 | |||
57 | static int iic_force_fast; | ||
58 | module_param(iic_force_fast, bool, 0); | ||
59 | MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)"); | ||
60 | |||
61 | #define DBG_LEVEL 0 | ||
62 | |||
63 | #ifdef DBG | ||
64 | #undef DBG | ||
65 | #endif | ||
66 | |||
67 | #ifdef DBG2 | ||
68 | #undef DBG2 | ||
69 | #endif | ||
70 | |||
71 | #if DBG_LEVEL > 0 | ||
72 | # define DBG(f,x...) printk(KERN_DEBUG "ibm-iic" f, ##x) | ||
73 | #else | ||
74 | # define DBG(f,x...) ((void)0) | ||
75 | #endif | ||
76 | #if DBG_LEVEL > 1 | ||
77 | # define DBG2(f,x...) DBG(f, ##x) | ||
78 | #else | ||
79 | # define DBG2(f,x...) ((void)0) | ||
80 | #endif | ||
81 | #if DBG_LEVEL > 2 | ||
82 | static void dump_iic_regs(const char* header, struct ibm_iic_private* dev) | ||
83 | { | ||
84 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
85 | printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header); | ||
86 | printk(KERN_DEBUG " cntl = 0x%02x, mdcntl = 0x%02x\n" | ||
87 | KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n" | ||
88 | KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n" | ||
89 | KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n", | ||
90 | in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), | ||
91 | in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), | ||
92 | in_8(&iic->xtcntlss), in_8(&iic->directcntl)); | ||
93 | } | ||
94 | # define DUMP_REGS(h,dev) dump_iic_regs((h),(dev)) | ||
95 | #else | ||
96 | # define DUMP_REGS(h,dev) ((void)0) | ||
97 | #endif | ||
98 | |||
99 | /* Bus timings (in ns) for bit-banging */ | ||
100 | static struct i2c_timings { | ||
101 | unsigned int hd_sta; | ||
102 | unsigned int su_sto; | ||
103 | unsigned int low; | ||
104 | unsigned int high; | ||
105 | unsigned int buf; | ||
106 | } timings [] = { | ||
107 | /* Standard mode (100 KHz) */ | ||
108 | { | ||
109 | .hd_sta = 4000, | ||
110 | .su_sto = 4000, | ||
111 | .low = 4700, | ||
112 | .high = 4000, | ||
113 | .buf = 4700, | ||
114 | }, | ||
115 | /* Fast mode (400 KHz) */ | ||
116 | { | ||
117 | .hd_sta = 600, | ||
118 | .su_sto = 600, | ||
119 | .low = 1300, | ||
120 | .high = 600, | ||
121 | .buf = 1300, | ||
122 | }}; | ||
123 | |||
124 | /* Enable/disable interrupt generation */ | ||
125 | static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable) | ||
126 | { | ||
127 | out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0); | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Initialize IIC interface. | ||
132 | */ | ||
133 | static void iic_dev_init(struct ibm_iic_private* dev) | ||
134 | { | ||
135 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
136 | |||
137 | DBG("%d: init\n", dev->idx); | ||
138 | |||
139 | /* Clear master address */ | ||
140 | out_8(&iic->lmadr, 0); | ||
141 | out_8(&iic->hmadr, 0); | ||
142 | |||
143 | /* Clear slave address */ | ||
144 | out_8(&iic->lsadr, 0); | ||
145 | out_8(&iic->hsadr, 0); | ||
146 | |||
147 | /* Clear status & extended status */ | ||
148 | out_8(&iic->sts, STS_SCMP | STS_IRQA); | ||
149 | out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA | ||
150 | | EXTSTS_ICT | EXTSTS_XFRA); | ||
151 | |||
152 | /* Set clock divider */ | ||
153 | out_8(&iic->clkdiv, dev->clckdiv); | ||
154 | |||
155 | /* Clear transfer count */ | ||
156 | out_8(&iic->xfrcnt, 0); | ||
157 | |||
158 | /* Clear extended control and status */ | ||
159 | out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC | ||
160 | | XTCNTLSS_SWS); | ||
161 | |||
162 | /* Clear control register */ | ||
163 | out_8(&iic->cntl, 0); | ||
164 | |||
165 | /* Enable interrupts if possible */ | ||
166 | iic_interrupt_mode(dev, dev->irq >= 0); | ||
167 | |||
168 | /* Set mode control */ | ||
169 | out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS | ||
170 | | (dev->fast_mode ? MDCNTL_FSM : 0)); | ||
171 | |||
172 | DUMP_REGS("iic_init", dev); | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * Reset IIC interface | ||
177 | */ | ||
178 | static void iic_dev_reset(struct ibm_iic_private* dev) | ||
179 | { | ||
180 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
181 | int i; | ||
182 | u8 dc; | ||
183 | |||
184 | DBG("%d: soft reset\n", dev->idx); | ||
185 | DUMP_REGS("reset", dev); | ||
186 | |||
187 | /* Place chip in the reset state */ | ||
188 | out_8(&iic->xtcntlss, XTCNTLSS_SRST); | ||
189 | |||
190 | /* Check if bus is free */ | ||
191 | dc = in_8(&iic->directcntl); | ||
192 | if (!DIRCTNL_FREE(dc)){ | ||
193 | DBG("%d: trying to regain bus control\n", dev->idx); | ||
194 | |||
195 | /* Try to set bus free state */ | ||
196 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); | ||
197 | |||
198 | /* Wait until we regain bus control */ | ||
199 | for (i = 0; i < 100; ++i){ | ||
200 | dc = in_8(&iic->directcntl); | ||
201 | if (DIRCTNL_FREE(dc)) | ||
202 | break; | ||
203 | |||
204 | /* Toggle SCL line */ | ||
205 | dc ^= DIRCNTL_SCC; | ||
206 | out_8(&iic->directcntl, dc); | ||
207 | udelay(10); | ||
208 | dc ^= DIRCNTL_SCC; | ||
209 | out_8(&iic->directcntl, dc); | ||
210 | |||
211 | /* be nice */ | ||
212 | cond_resched(); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | /* Remove reset */ | ||
217 | out_8(&iic->xtcntlss, 0); | ||
218 | |||
219 | /* Reinitialize interface */ | ||
220 | iic_dev_init(dev); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Do 0-length transaction using bit-banging through IIC_DIRECTCNTL register. | ||
225 | */ | ||
226 | |||
227 | /* Wait for SCL and/or SDA to be high */ | ||
228 | static int iic_dc_wait(volatile struct iic_regs __iomem *iic, u8 mask) | ||
229 | { | ||
230 | unsigned long x = jiffies + HZ / 28 + 2; | ||
231 | while ((in_8(&iic->directcntl) & mask) != mask){ | ||
232 | if (unlikely(time_after(jiffies, x))) | ||
233 | return -1; | ||
234 | cond_resched(); | ||
235 | } | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int iic_smbus_quick(struct ibm_iic_private* dev, const struct i2c_msg* p) | ||
240 | { | ||
241 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
242 | const struct i2c_timings* t = &timings[dev->fast_mode ? 1 : 0]; | ||
243 | u8 mask, v, sda; | ||
244 | int i, res; | ||
245 | |||
246 | /* Only 7-bit addresses are supported */ | ||
247 | if (unlikely(p->flags & I2C_M_TEN)){ | ||
248 | DBG("%d: smbus_quick - 10 bit addresses are not supported\n", | ||
249 | dev->idx); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | DBG("%d: smbus_quick(0x%02x)\n", dev->idx, p->addr); | ||
254 | |||
255 | /* Reset IIC interface */ | ||
256 | out_8(&iic->xtcntlss, XTCNTLSS_SRST); | ||
257 | |||
258 | /* Wait for bus to become free */ | ||
259 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); | ||
260 | if (unlikely(iic_dc_wait(iic, DIRCNTL_MSDA | DIRCNTL_MSC))) | ||
261 | goto err; | ||
262 | ndelay(t->buf); | ||
263 | |||
264 | /* START */ | ||
265 | out_8(&iic->directcntl, DIRCNTL_SCC); | ||
266 | sda = 0; | ||
267 | ndelay(t->hd_sta); | ||
268 | |||
269 | /* Send address */ | ||
270 | v = (u8)((p->addr << 1) | ((p->flags & I2C_M_RD) ? 1 : 0)); | ||
271 | for (i = 0, mask = 0x80; i < 8; ++i, mask >>= 1){ | ||
272 | out_8(&iic->directcntl, sda); | ||
273 | ndelay(t->low / 2); | ||
274 | sda = (v & mask) ? DIRCNTL_SDAC : 0; | ||
275 | out_8(&iic->directcntl, sda); | ||
276 | ndelay(t->low / 2); | ||
277 | |||
278 | out_8(&iic->directcntl, DIRCNTL_SCC | sda); | ||
279 | if (unlikely(iic_dc_wait(iic, DIRCNTL_MSC))) | ||
280 | goto err; | ||
281 | ndelay(t->high); | ||
282 | } | ||
283 | |||
284 | /* ACK */ | ||
285 | out_8(&iic->directcntl, sda); | ||
286 | ndelay(t->low / 2); | ||
287 | out_8(&iic->directcntl, DIRCNTL_SDAC); | ||
288 | ndelay(t->low / 2); | ||
289 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); | ||
290 | if (unlikely(iic_dc_wait(iic, DIRCNTL_MSC))) | ||
291 | goto err; | ||
292 | res = (in_8(&iic->directcntl) & DIRCNTL_MSDA) ? -EREMOTEIO : 1; | ||
293 | ndelay(t->high); | ||
294 | |||
295 | /* STOP */ | ||
296 | out_8(&iic->directcntl, 0); | ||
297 | ndelay(t->low); | ||
298 | out_8(&iic->directcntl, DIRCNTL_SCC); | ||
299 | if (unlikely(iic_dc_wait(iic, DIRCNTL_MSC))) | ||
300 | goto err; | ||
301 | ndelay(t->su_sto); | ||
302 | out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); | ||
303 | |||
304 | ndelay(t->buf); | ||
305 | |||
306 | DBG("%d: smbus_quick -> %s\n", dev->idx, res ? "NACK" : "ACK"); | ||
307 | out: | ||
308 | /* Remove reset */ | ||
309 | out_8(&iic->xtcntlss, 0); | ||
310 | |||
311 | /* Reinitialize interface */ | ||
312 | iic_dev_init(dev); | ||
313 | |||
314 | return res; | ||
315 | err: | ||
316 | DBG("%d: smbus_quick - bus is stuck\n", dev->idx); | ||
317 | res = -EREMOTEIO; | ||
318 | goto out; | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * IIC interrupt handler | ||
323 | */ | ||
324 | static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
325 | { | ||
326 | struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id; | ||
327 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
328 | |||
329 | DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", | ||
330 | dev->idx, in_8(&iic->sts), in_8(&iic->extsts)); | ||
331 | |||
332 | /* Acknowledge IRQ and wakeup iic_wait_for_tc */ | ||
333 | out_8(&iic->sts, STS_IRQA | STS_SCMP); | ||
334 | wake_up_interruptible(&dev->wq); | ||
335 | |||
336 | return IRQ_HANDLED; | ||
337 | } | ||
338 | |||
339 | /* | ||
340 | * Get master transfer result and clear errors if any. | ||
341 | * Returns the number of actually transferred bytes or error (<0) | ||
342 | */ | ||
343 | static int iic_xfer_result(struct ibm_iic_private* dev) | ||
344 | { | ||
345 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
346 | |||
347 | if (unlikely(in_8(&iic->sts) & STS_ERR)){ | ||
348 | DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, | ||
349 | in_8(&iic->extsts)); | ||
350 | |||
351 | /* Clear errors and possible pending IRQs */ | ||
352 | out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | | ||
353 | EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA); | ||
354 | |||
355 | /* Flush master data buffer */ | ||
356 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); | ||
357 | |||
358 | /* Is bus free? | ||
359 | * If error happened during combined xfer | ||
360 | * IIC interface is usually stuck in some strange | ||
361 | * state, the only way out - soft reset. | ||
362 | */ | ||
363 | if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ | ||
364 | DBG("%d: bus is stuck, resetting\n", dev->idx); | ||
365 | iic_dev_reset(dev); | ||
366 | } | ||
367 | return -EREMOTEIO; | ||
368 | } | ||
369 | else | ||
370 | return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK; | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Try to abort active transfer. | ||
375 | */ | ||
376 | static void iic_abort_xfer(struct ibm_iic_private* dev) | ||
377 | { | ||
378 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
379 | unsigned long x; | ||
380 | |||
381 | DBG("%d: iic_abort_xfer\n", dev->idx); | ||
382 | |||
383 | out_8(&iic->cntl, CNTL_HMT); | ||
384 | |||
385 | /* | ||
386 | * Wait for the abort command to complete. | ||
387 | * It's not worth to be optimized, just poll (timeout >= 1 tick) | ||
388 | */ | ||
389 | x = jiffies + 2; | ||
390 | while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ | ||
391 | if (time_after(jiffies, x)){ | ||
392 | DBG("%d: abort timeout, resetting...\n", dev->idx); | ||
393 | iic_dev_reset(dev); | ||
394 | return; | ||
395 | } | ||
396 | schedule(); | ||
397 | } | ||
398 | |||
399 | /* Just to clear errors */ | ||
400 | iic_xfer_result(dev); | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Wait for master transfer to complete. | ||
405 | * It puts current process to sleep until we get interrupt or timeout expires. | ||
406 | * Returns the number of transferred bytes or error (<0) | ||
407 | */ | ||
408 | static int iic_wait_for_tc(struct ibm_iic_private* dev){ | ||
409 | |||
410 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
411 | int ret = 0; | ||
412 | |||
413 | if (dev->irq >= 0){ | ||
414 | /* Interrupt mode */ | ||
415 | ret = wait_event_interruptible_timeout(dev->wq, | ||
416 | !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ); | ||
417 | |||
418 | if (unlikely(ret < 0)) | ||
419 | DBG("%d: wait interrupted\n", dev->idx); | ||
420 | else if (unlikely(in_8(&iic->sts) & STS_PT)){ | ||
421 | DBG("%d: wait timeout\n", dev->idx); | ||
422 | ret = -ETIMEDOUT; | ||
423 | } | ||
424 | } | ||
425 | else { | ||
426 | /* Polling mode */ | ||
427 | unsigned long x = jiffies + dev->adap.timeout * HZ; | ||
428 | |||
429 | while (in_8(&iic->sts) & STS_PT){ | ||
430 | if (unlikely(time_after(jiffies, x))){ | ||
431 | DBG("%d: poll timeout\n", dev->idx); | ||
432 | ret = -ETIMEDOUT; | ||
433 | break; | ||
434 | } | ||
435 | |||
436 | if (unlikely(signal_pending(current))){ | ||
437 | DBG("%d: poll interrupted\n", dev->idx); | ||
438 | ret = -ERESTARTSYS; | ||
439 | break; | ||
440 | } | ||
441 | schedule(); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (unlikely(ret < 0)) | ||
446 | iic_abort_xfer(dev); | ||
447 | else | ||
448 | ret = iic_xfer_result(dev); | ||
449 | |||
450 | DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret); | ||
451 | |||
452 | return ret; | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * Low level master transfer routine | ||
457 | */ | ||
458 | static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, | ||
459 | int combined_xfer) | ||
460 | { | ||
461 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
462 | char* buf = pm->buf; | ||
463 | int i, j, loops, ret = 0; | ||
464 | int len = pm->len; | ||
465 | |||
466 | u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT; | ||
467 | if (pm->flags & I2C_M_RD) | ||
468 | cntl |= CNTL_RW; | ||
469 | |||
470 | loops = (len + 3) / 4; | ||
471 | for (i = 0; i < loops; ++i, len -= 4){ | ||
472 | int count = len > 4 ? 4 : len; | ||
473 | u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT); | ||
474 | |||
475 | if (!(cntl & CNTL_RW)) | ||
476 | for (j = 0; j < count; ++j) | ||
477 | out_8((void __iomem *)&iic->mdbuf, *buf++); | ||
478 | |||
479 | if (i < loops - 1) | ||
480 | cmd |= CNTL_CHT; | ||
481 | else if (combined_xfer) | ||
482 | cmd |= CNTL_RPST; | ||
483 | |||
484 | DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd); | ||
485 | |||
486 | /* Start transfer */ | ||
487 | out_8(&iic->cntl, cmd); | ||
488 | |||
489 | /* Wait for completion */ | ||
490 | ret = iic_wait_for_tc(dev); | ||
491 | |||
492 | if (unlikely(ret < 0)) | ||
493 | break; | ||
494 | else if (unlikely(ret != count)){ | ||
495 | DBG("%d: xfer_bytes, requested %d, transfered %d\n", | ||
496 | dev->idx, count, ret); | ||
497 | |||
498 | /* If it's not a last part of xfer, abort it */ | ||
499 | if (combined_xfer || (i < loops - 1)) | ||
500 | iic_abort_xfer(dev); | ||
501 | |||
502 | ret = -EREMOTEIO; | ||
503 | break; | ||
504 | } | ||
505 | |||
506 | if (cntl & CNTL_RW) | ||
507 | for (j = 0; j < count; ++j) | ||
508 | *buf++ = in_8((void __iomem *)&iic->mdbuf); | ||
509 | } | ||
510 | |||
511 | return ret > 0 ? 0 : ret; | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Set target slave address for master transfer | ||
516 | */ | ||
517 | static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg) | ||
518 | { | ||
519 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
520 | u16 addr = msg->addr; | ||
521 | |||
522 | DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, | ||
523 | addr, msg->flags & I2C_M_TEN ? 10 : 7); | ||
524 | |||
525 | if (msg->flags & I2C_M_TEN){ | ||
526 | out_8(&iic->cntl, CNTL_AMD); | ||
527 | out_8(&iic->lmadr, addr); | ||
528 | out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06)); | ||
529 | } | ||
530 | else { | ||
531 | out_8(&iic->cntl, 0); | ||
532 | out_8(&iic->lmadr, addr << 1); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | static inline int iic_invalid_address(const struct i2c_msg* p) | ||
537 | { | ||
538 | return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f)); | ||
539 | } | ||
540 | |||
541 | static inline int iic_address_neq(const struct i2c_msg* p1, | ||
542 | const struct i2c_msg* p2) | ||
543 | { | ||
544 | return (p1->addr != p2->addr) | ||
545 | || ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN)); | ||
546 | } | ||
547 | |||
548 | /* | ||
549 | * Generic master transfer entrypoint. | ||
550 | * Returns the number of processed messages or error (<0) | ||
551 | */ | ||
552 | static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | ||
553 | { | ||
554 | struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap)); | ||
555 | volatile struct iic_regs __iomem *iic = dev->vaddr; | ||
556 | int i, ret = 0; | ||
557 | |||
558 | DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num); | ||
559 | |||
560 | if (!num) | ||
561 | return 0; | ||
562 | |||
563 | /* Check the sanity of the passed messages. | ||
564 | * Uhh, generic i2c layer is more suitable place for such code... | ||
565 | */ | ||
566 | if (unlikely(iic_invalid_address(&msgs[0]))){ | ||
567 | DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, | ||
568 | msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7); | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | for (i = 0; i < num; ++i){ | ||
572 | if (unlikely(msgs[i].len <= 0)){ | ||
573 | if (num == 1 && !msgs[0].len){ | ||
574 | /* Special case for I2C_SMBUS_QUICK emulation. | ||
575 | * IBM IIC doesn't support 0-length transactions | ||
576 | * so we have to emulate them using bit-banging. | ||
577 | */ | ||
578 | return iic_smbus_quick(dev, &msgs[0]); | ||
579 | } | ||
580 | DBG("%d: invalid len %d in msg[%d]\n", dev->idx, | ||
581 | msgs[i].len, i); | ||
582 | return -EINVAL; | ||
583 | } | ||
584 | if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){ | ||
585 | DBG("%d: invalid addr in msg[%d]\n", dev->idx, i); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | } | ||
589 | |||
590 | /* Check bus state */ | ||
591 | if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){ | ||
592 | DBG("%d: iic_xfer, bus is not free\n", dev->idx); | ||
593 | |||
594 | /* Usually it means something serious has happend. | ||
595 | * We *cannot* have unfinished previous transfer | ||
596 | * so it doesn't make any sense to try to stop it. | ||
597 | * Probably we were not able to recover from the | ||
598 | * previous error. | ||
599 | * The only *reasonable* thing I can think of here | ||
600 | * is soft reset. --ebs | ||
601 | */ | ||
602 | iic_dev_reset(dev); | ||
603 | |||
604 | if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){ | ||
605 | DBG("%d: iic_xfer, bus is still not free\n", dev->idx); | ||
606 | return -EREMOTEIO; | ||
607 | } | ||
608 | } | ||
609 | else { | ||
610 | /* Flush master data buffer (just in case) */ | ||
611 | out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB); | ||
612 | } | ||
613 | |||
614 | /* Load slave address */ | ||
615 | iic_address(dev, &msgs[0]); | ||
616 | |||
617 | /* Do real transfer */ | ||
618 | for (i = 0; i < num && !ret; ++i) | ||
619 | ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1); | ||
620 | |||
621 | return ret < 0 ? ret : num; | ||
622 | } | ||
623 | |||
624 | static u32 iic_func(struct i2c_adapter *adap) | ||
625 | { | ||
626 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; | ||
627 | } | ||
628 | |||
629 | static struct i2c_algorithm iic_algo = { | ||
630 | .name = "IBM IIC algorithm", | ||
631 | .id = I2C_ALGO_OCP, | ||
632 | .master_xfer = iic_xfer, | ||
633 | .functionality = iic_func | ||
634 | }; | ||
635 | |||
636 | /* | ||
637 | * Calculates IICx_CLCKDIV value for a specific OPB clock frequency | ||
638 | */ | ||
639 | static inline u8 iic_clckdiv(unsigned int opb) | ||
640 | { | ||
641 | /* Compatibility kludge, should go away after all cards | ||
642 | * are fixed to fill correct value for opbfreq. | ||
643 | * Previous driver version used hardcoded divider value 4, | ||
644 | * it corresponds to OPB frequency from the range (40, 50] MHz | ||
645 | */ | ||
646 | if (!opb){ | ||
647 | printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq," | ||
648 | " fix your board specific setup\n"); | ||
649 | opb = 50000000; | ||
650 | } | ||
651 | |||
652 | /* Convert to MHz */ | ||
653 | opb /= 1000000; | ||
654 | |||
655 | if (opb < 20 || opb > 150){ | ||
656 | printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n", | ||
657 | opb); | ||
658 | opb = opb < 20 ? 20 : 150; | ||
659 | } | ||
660 | return (u8)((opb + 9) / 10 - 1); | ||
661 | } | ||
662 | |||
663 | /* | ||
664 | * Register single IIC interface | ||
665 | */ | ||
666 | static int __devinit iic_probe(struct ocp_device *ocp){ | ||
667 | |||
668 | struct ibm_iic_private* dev; | ||
669 | struct i2c_adapter* adap; | ||
670 | struct ocp_func_iic_data* iic_data = ocp->def->additions; | ||
671 | int ret; | ||
672 | |||
673 | if (!iic_data) | ||
674 | printk(KERN_WARNING"ibm-iic%d: missing additional data!\n", | ||
675 | ocp->def->index); | ||
676 | |||
677 | if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){ | ||
678 | printk(KERN_CRIT "ibm-iic%d: failed to allocate device data\n", | ||
679 | ocp->def->index); | ||
680 | return -ENOMEM; | ||
681 | } | ||
682 | |||
683 | memset(dev, 0, sizeof(*dev)); | ||
684 | dev->idx = ocp->def->index; | ||
685 | ocp_set_drvdata(ocp, dev); | ||
686 | |||
687 | if (!(dev->vaddr = ioremap(ocp->def->paddr, sizeof(struct iic_regs)))){ | ||
688 | printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n", | ||
689 | dev->idx); | ||
690 | ret = -ENXIO; | ||
691 | goto fail2; | ||
692 | } | ||
693 | |||
694 | init_waitqueue_head(&dev->wq); | ||
695 | |||
696 | dev->irq = iic_force_poll ? -1 : ocp->def->irq; | ||
697 | if (dev->irq >= 0){ | ||
698 | /* Disable interrupts until we finish intialization, | ||
699 | assumes level-sensitive IRQ setup... | ||
700 | */ | ||
701 | iic_interrupt_mode(dev, 0); | ||
702 | if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){ | ||
703 | printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", | ||
704 | dev->idx, dev->irq); | ||
705 | /* Fallback to the polling mode */ | ||
706 | dev->irq = -1; | ||
707 | } | ||
708 | } | ||
709 | |||
710 | if (dev->irq < 0) | ||
711 | printk(KERN_WARNING "ibm-iic%d: using polling mode\n", | ||
712 | dev->idx); | ||
713 | |||
714 | /* Board specific settings */ | ||
715 | dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0); | ||
716 | |||
717 | /* clckdiv is the same for *all* IIC interfaces, | ||
718 | * but I'd rather make a copy than introduce another global. --ebs | ||
719 | */ | ||
720 | dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq); | ||
721 | DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv); | ||
722 | |||
723 | /* Initialize IIC interface */ | ||
724 | iic_dev_init(dev); | ||
725 | |||
726 | /* Register it with i2c layer */ | ||
727 | adap = &dev->adap; | ||
728 | strcpy(adap->name, "IBM IIC"); | ||
729 | i2c_set_adapdata(adap, dev); | ||
730 | adap->id = I2C_HW_OCP | iic_algo.id; | ||
731 | adap->algo = &iic_algo; | ||
732 | adap->client_register = NULL; | ||
733 | adap->client_unregister = NULL; | ||
734 | adap->timeout = 1; | ||
735 | adap->retries = 1; | ||
736 | |||
737 | if ((ret = i2c_add_adapter(adap)) != 0){ | ||
738 | printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n", | ||
739 | dev->idx); | ||
740 | goto fail; | ||
741 | } | ||
742 | |||
743 | printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx, | ||
744 | dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)"); | ||
745 | |||
746 | return 0; | ||
747 | |||
748 | fail: | ||
749 | if (dev->irq >= 0){ | ||
750 | iic_interrupt_mode(dev, 0); | ||
751 | free_irq(dev->irq, dev); | ||
752 | } | ||
753 | |||
754 | iounmap(dev->vaddr); | ||
755 | fail2: | ||
756 | ocp_set_drvdata(ocp, NULL); | ||
757 | kfree(dev); | ||
758 | return ret; | ||
759 | } | ||
760 | |||
761 | /* | ||
762 | * Cleanup initialized IIC interface | ||
763 | */ | ||
764 | static void __devexit iic_remove(struct ocp_device *ocp) | ||
765 | { | ||
766 | struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp); | ||
767 | BUG_ON(dev == NULL); | ||
768 | if (i2c_del_adapter(&dev->adap)){ | ||
769 | printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n", | ||
770 | dev->idx); | ||
771 | /* That's *very* bad, just shutdown IRQ ... */ | ||
772 | if (dev->irq >= 0){ | ||
773 | iic_interrupt_mode(dev, 0); | ||
774 | free_irq(dev->irq, dev); | ||
775 | dev->irq = -1; | ||
776 | } | ||
777 | } else { | ||
778 | if (dev->irq >= 0){ | ||
779 | iic_interrupt_mode(dev, 0); | ||
780 | free_irq(dev->irq, dev); | ||
781 | } | ||
782 | iounmap(dev->vaddr); | ||
783 | kfree(dev); | ||
784 | } | ||
785 | } | ||
786 | |||
787 | static struct ocp_device_id ibm_iic_ids[] __devinitdata = | ||
788 | { | ||
789 | { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC }, | ||
790 | { .vendor = OCP_VENDOR_INVALID } | ||
791 | }; | ||
792 | |||
793 | MODULE_DEVICE_TABLE(ocp, ibm_iic_ids); | ||
794 | |||
795 | static struct ocp_driver ibm_iic_driver = | ||
796 | { | ||
797 | .name = "iic", | ||
798 | .id_table = ibm_iic_ids, | ||
799 | .probe = iic_probe, | ||
800 | .remove = __devexit_p(iic_remove), | ||
801 | #if defined(CONFIG_PM) | ||
802 | .suspend = NULL, | ||
803 | .resume = NULL, | ||
804 | #endif | ||
805 | }; | ||
806 | |||
807 | static int __init iic_init(void) | ||
808 | { | ||
809 | printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n"); | ||
810 | return ocp_register_driver(&ibm_iic_driver); | ||
811 | } | ||
812 | |||
813 | static void __exit iic_exit(void) | ||
814 | { | ||
815 | ocp_unregister_driver(&ibm_iic_driver); | ||
816 | } | ||
817 | |||
818 | module_init(iic_init); | ||
819 | module_exit(iic_exit); | ||