]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* ------------------------------------------------------------------------- */ |
2 | /* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */ | |
3 | /* ------------------------------------------------------------------------- */ | |
4 | /* Copyright (C) 1995-1997 Simon G. Vogl | |
5 | 1998-2000 Hans Berglund | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
20 | /* ------------------------------------------------------------------------- */ | |
21 | ||
96de0e25 | 22 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and |
1da177e4 LT |
23 | Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey |
24 | <mbailey@littlefeet-inc.com> */ | |
25 | ||
26 | /* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple | |
27 | messages, proper stop/repstart signaling during receive, | |
28 | added detect code */ | |
29 | ||
30 | #include <linux/kernel.h> | |
31 | #include <linux/module.h> | |
32 | #include <linux/delay.h> | |
33 | #include <linux/slab.h> | |
34 | #include <linux/init.h> | |
35 | #include <linux/errno.h> | |
36 | #include <linux/i2c.h> | |
37 | #include <linux/i2c-algo-pcf.h> | |
38 | #include "i2c-algo-pcf.h" | |
39 | ||
40 | ||
41 | #define DEB2(x) if (i2c_debug>=2) x | |
42 | #define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/ | |
43 | #define DEBPROTO(x) if (i2c_debug>=9) x; | |
44 | /* debug the protocol by showing transferred bits */ | |
45 | #define DEF_TIMEOUT 16 | |
46 | ||
47 | /* module parameters: | |
48 | */ | |
49 | static int i2c_debug; | |
50 | ||
51 | /* --- setting states on the bus with the right timing: --------------- */ | |
52 | ||
53 | #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val) | |
54 | #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl) | |
55 | #define get_own(adap) adap->getown(adap->data) | |
56 | #define get_clock(adap) adap->getclock(adap->data) | |
57 | #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val) | |
58 | #define i2c_inb(adap) adap->getpcf(adap->data, 0) | |
59 | ||
60 | /* --- other auxiliary functions -------------------------------------- */ | |
61 | ||
62 | static void i2c_start(struct i2c_algo_pcf_data *adap) | |
63 | { | |
64 | DEBPROTO(printk("S ")); | |
65 | set_pcf(adap, 1, I2C_PCF_START); | |
66 | } | |
67 | ||
68 | static void i2c_repstart(struct i2c_algo_pcf_data *adap) | |
69 | { | |
70 | DEBPROTO(printk(" Sr ")); | |
71 | set_pcf(adap, 1, I2C_PCF_REPSTART); | |
72 | } | |
73 | ||
74 | ||
75 | static void i2c_stop(struct i2c_algo_pcf_data *adap) | |
76 | { | |
77 | DEBPROTO(printk("P\n")); | |
78 | set_pcf(adap, 1, I2C_PCF_STOP); | |
79 | } | |
80 | ||
0573d11b EB |
81 | static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) |
82 | { | |
83 | DEB2(printk(KERN_INFO | |
84 | "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", | |
85 | *status)); | |
86 | ||
87 | /* Cleanup from LAB -- reset and enable ESO. | |
88 | * This resets the PCF8584; since we've lost the bus, no | |
89 | * further attempts should be made by callers to clean up | |
90 | * (no i2c_stop() etc.) | |
91 | */ | |
92 | set_pcf(adap, 1, I2C_PCF_PIN); | |
93 | set_pcf(adap, 1, I2C_PCF_ESO); | |
94 | ||
95 | /* We pause for a time period sufficient for any running | |
96 | * I2C transaction to complete -- the arbitration logic won't | |
97 | * work properly until the next START is seen. | |
98 | * It is assumed the bus driver or client has set a proper value. | |
99 | * | |
100 | * REVISIT: should probably use msleep instead of mdelay if we | |
101 | * know we can sleep. | |
102 | */ | |
103 | if (adap->lab_mdelay) | |
104 | mdelay(adap->lab_mdelay); | |
105 | ||
106 | DEB2(printk(KERN_INFO | |
107 | "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", | |
108 | get_pcf(adap, 1))); | |
109 | } | |
110 | ||
1da177e4 LT |
111 | static int wait_for_bb(struct i2c_algo_pcf_data *adap) { |
112 | ||
113 | int timeout = DEF_TIMEOUT; | |
114 | int status; | |
115 | ||
116 | status = get_pcf(adap, 1); | |
117 | #ifndef STUB_I2C | |
118 | while (timeout-- && !(status & I2C_PCF_BB)) { | |
119 | udelay(100); /* wait for 100 us */ | |
120 | status = get_pcf(adap, 1); | |
121 | } | |
122 | #endif | |
123 | if (timeout <= 0) { | |
124 | printk(KERN_ERR "Timeout waiting for Bus Busy\n"); | |
125 | } | |
126 | ||
127 | return (timeout<=0); | |
128 | } | |
129 | ||
130 | ||
131 | static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) { | |
132 | ||
133 | int timeout = DEF_TIMEOUT; | |
134 | ||
135 | *status = get_pcf(adap, 1); | |
136 | #ifndef STUB_I2C | |
137 | while (timeout-- && (*status & I2C_PCF_PIN)) { | |
08e5338d | 138 | adap->waitforpin(adap->data); |
1da177e4 LT |
139 | *status = get_pcf(adap, 1); |
140 | } | |
141 | if (*status & I2C_PCF_LAB) { | |
0573d11b | 142 | handle_lab(adap, status); |
1da177e4 LT |
143 | return(-EINTR); |
144 | } | |
145 | #endif | |
146 | if (timeout <= 0) | |
147 | return(-1); | |
148 | else | |
149 | return(0); | |
150 | } | |
151 | ||
152 | /* | |
153 | * This should perform the 'PCF8584 initialization sequence' as described | |
154 | * in the Philips IC12 data book (1995, Aug 29). | |
155 | * There should be a 30 clock cycle wait after reset, I assume this | |
156 | * has been fulfilled. | |
157 | * There should be a delay at the end equal to the longest I2C message | |
158 | * to synchronize the BB-bit (in multimaster systems). How long is | |
159 | * this? I assume 1 second is always long enough. | |
160 | * | |
161 | * vdovikin: added detect code for PCF8584 | |
162 | */ | |
163 | static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |
164 | { | |
165 | unsigned char temp; | |
166 | ||
167 | DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); | |
168 | ||
169 | /* S1=0x80: S0 selected, serial interface off */ | |
170 | set_pcf(adap, 1, I2C_PCF_PIN); | |
171 | /* check to see S1 now used as R/W ctrl - | |
172 | PCF8584 does that when ESO is zero */ | |
173 | if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { | |
174 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); | |
175 | return -ENXIO; /* definetly not PCF8584 */ | |
176 | } | |
177 | ||
178 | /* load own address in S0, effective address is (own << 1) */ | |
179 | i2c_outb(adap, get_own(adap)); | |
180 | /* check it's really written */ | |
181 | if ((temp = i2c_inb(adap)) != get_own(adap)) { | |
182 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); | |
183 | return -ENXIO; | |
184 | } | |
185 | ||
186 | /* S1=0xA0, next byte in S2 */ | |
187 | set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); | |
188 | /* check to see S2 now selected */ | |
189 | if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { | |
190 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); | |
191 | return -ENXIO; | |
192 | } | |
193 | ||
194 | /* load clock register S2 */ | |
195 | i2c_outb(adap, get_clock(adap)); | |
196 | /* check it's really written, the only 5 lowest bits does matter */ | |
197 | if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { | |
198 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); | |
199 | return -ENXIO; | |
200 | } | |
201 | ||
202 | /* Enable serial interface, idle, S0 selected */ | |
203 | set_pcf(adap, 1, I2C_PCF_IDLE); | |
204 | ||
205 | /* check to see PCF is really idled and we can access status register */ | |
206 | if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { | |
207 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); | |
208 | return -ENXIO; | |
209 | } | |
210 | ||
211 | printk(KERN_DEBUG "i2c-algo-pcf.o: deteted and initialized PCF8584.\n"); | |
212 | ||
213 | return 0; | |
214 | } | |
215 | ||
216 | ||
217 | /* ----- Utility functions | |
218 | */ | |
219 | ||
1da177e4 LT |
220 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, |
221 | int count, int last) | |
222 | { | |
223 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; | |
224 | int wrcount, status, timeout; | |
225 | ||
226 | for (wrcount=0; wrcount<count; ++wrcount) { | |
227 | DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", | |
228 | buf[wrcount]&0xff)); | |
229 | i2c_outb(adap, buf[wrcount]); | |
230 | timeout = wait_for_pin(adap, &status); | |
231 | if (timeout) { | |
232 | if (timeout == -EINTR) { | |
233 | /* arbitration lost */ | |
234 | return -EINTR; | |
235 | } | |
236 | i2c_stop(adap); | |
237 | dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); | |
238 | return -EREMOTEIO; /* got a better one ?? */ | |
239 | } | |
240 | #ifndef STUB_I2C | |
241 | if (status & I2C_PCF_LRB) { | |
242 | i2c_stop(adap); | |
243 | dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); | |
244 | return -EREMOTEIO; /* got a better one ?? */ | |
245 | } | |
246 | #endif | |
247 | } | |
248 | if (last) { | |
249 | i2c_stop(adap); | |
250 | } | |
251 | else { | |
252 | i2c_repstart(adap); | |
253 | } | |
254 | ||
255 | return (wrcount); | |
256 | } | |
257 | ||
258 | ||
259 | static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, | |
260 | int count, int last) | |
261 | { | |
262 | int i, status; | |
263 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; | |
264 | int wfp; | |
265 | ||
266 | /* increment number of bytes to read by one -- read dummy byte */ | |
267 | for (i = 0; i <= count; i++) { | |
268 | ||
269 | if ((wfp = wait_for_pin(adap, &status))) { | |
270 | if (wfp == -EINTR) { | |
271 | /* arbitration lost */ | |
272 | return -EINTR; | |
273 | } | |
274 | i2c_stop(adap); | |
275 | dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); | |
276 | return (-1); | |
277 | } | |
278 | ||
279 | #ifndef STUB_I2C | |
280 | if ((status & I2C_PCF_LRB) && (i != count)) { | |
281 | i2c_stop(adap); | |
282 | dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); | |
283 | return (-1); | |
284 | } | |
285 | #endif | |
286 | ||
287 | if (i == count - 1) { | |
288 | set_pcf(adap, 1, I2C_PCF_ESO); | |
289 | } else | |
290 | if (i == count) { | |
291 | if (last) { | |
292 | i2c_stop(adap); | |
293 | } else { | |
294 | i2c_repstart(adap); | |
295 | } | |
296 | }; | |
297 | ||
298 | if (i) { | |
299 | buf[i - 1] = i2c_inb(adap); | |
300 | } else { | |
301 | i2c_inb(adap); /* dummy read */ | |
302 | } | |
303 | } | |
304 | ||
305 | return (i - 1); | |
306 | } | |
307 | ||
308 | ||
6408a833 JD |
309 | static int pcf_doAddress(struct i2c_algo_pcf_data *adap, |
310 | struct i2c_msg *msg) | |
1da177e4 LT |
311 | { |
312 | unsigned short flags = msg->flags; | |
313 | unsigned char addr; | |
6408a833 JD |
314 | |
315 | addr = msg->addr << 1; | |
316 | if (flags & I2C_M_RD) | |
317 | addr |= 1; | |
318 | if (flags & I2C_M_REV_DIR_ADDR) | |
319 | addr ^= 1; | |
320 | i2c_outb(adap, addr); | |
321 | ||
1da177e4 LT |
322 | return 0; |
323 | } | |
324 | ||
325 | static int pcf_xfer(struct i2c_adapter *i2c_adap, | |
326 | struct i2c_msg *msgs, | |
327 | int num) | |
328 | { | |
329 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; | |
330 | struct i2c_msg *pmsg; | |
331 | int i; | |
332 | int ret=0, timeout, status; | |
333 | ||
334 | ||
335 | /* Check for bus busy */ | |
336 | timeout = wait_for_bb(adap); | |
337 | if (timeout) { | |
338 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " | |
339 | "Timeout waiting for BB in pcf_xfer\n");) | |
340 | return -EIO; | |
341 | } | |
342 | ||
343 | for (i = 0;ret >= 0 && i < num; i++) { | |
344 | pmsg = &msgs[i]; | |
345 | ||
346 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", | |
347 | pmsg->flags & I2C_M_RD ? "read" : "write", | |
348 | pmsg->len, pmsg->addr, i + 1, num);) | |
349 | ||
6408a833 | 350 | ret = pcf_doAddress(adap, pmsg); |
1da177e4 LT |
351 | |
352 | /* Send START */ | |
353 | if (i == 0) { | |
354 | i2c_start(adap); | |
355 | } | |
356 | ||
357 | /* Wait for PIN (pending interrupt NOT) */ | |
358 | timeout = wait_for_pin(adap, &status); | |
359 | if (timeout) { | |
360 | if (timeout == -EINTR) { | |
361 | /* arbitration lost */ | |
362 | return (-EINTR); | |
363 | } | |
364 | i2c_stop(adap); | |
365 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting " | |
366 | "for PIN(1) in pcf_xfer\n");) | |
367 | return (-EREMOTEIO); | |
368 | } | |
369 | ||
370 | #ifndef STUB_I2C | |
371 | /* Check LRB (last rcvd bit - slave ack) */ | |
372 | if (status & I2C_PCF_LRB) { | |
373 | i2c_stop(adap); | |
374 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");) | |
375 | return (-EREMOTEIO); | |
376 | } | |
377 | #endif | |
378 | ||
379 | DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", | |
380 | i, msgs[i].addr, msgs[i].flags, msgs[i].len);) | |
381 | ||
382 | /* Read */ | |
383 | if (pmsg->flags & I2C_M_RD) { | |
384 | /* read bytes into buffer*/ | |
385 | ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, | |
386 | (i + 1 == num)); | |
387 | ||
388 | if (ret != pmsg->len) { | |
389 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " | |
390 | "only read %d bytes.\n",ret)); | |
391 | } else { | |
392 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); | |
393 | } | |
394 | } else { /* Write */ | |
395 | ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, | |
396 | (i + 1 == num)); | |
397 | ||
398 | if (ret != pmsg->len) { | |
399 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " | |
400 | "only wrote %d bytes.\n",ret)); | |
401 | } else { | |
402 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret)); | |
403 | } | |
404 | } | |
405 | } | |
406 | ||
407 | return (i); | |
408 | } | |
409 | ||
410 | static u32 pcf_func(struct i2c_adapter *adap) | |
411 | { | |
412 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | |
6408a833 | 413 | I2C_FUNC_PROTOCOL_MANGLING; |
1da177e4 LT |
414 | } |
415 | ||
416 | /* -----exported algorithm data: ------------------------------------- */ | |
417 | ||
9e11a9fb | 418 | static const struct i2c_algorithm pcf_algo = { |
1da177e4 LT |
419 | .master_xfer = pcf_xfer, |
420 | .functionality = pcf_func, | |
421 | }; | |
422 | ||
423 | /* | |
424 | * registering functions to load algorithms at runtime | |
425 | */ | |
426 | int i2c_pcf_add_bus(struct i2c_adapter *adap) | |
427 | { | |
428 | struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; | |
429 | int rval; | |
430 | ||
431 | DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); | |
432 | ||
433 | /* register new adapter to i2c module... */ | |
1da177e4 | 434 | adap->algo = &pcf_algo; |
6408a833 | 435 | adap->timeout = 100; |
1da177e4 | 436 | |
b39ad0cf MH |
437 | if ((rval = pcf_init_8584(pcf_adap))) |
438 | return rval; | |
439 | ||
440 | rval = i2c_add_adapter(adap); | |
441 | ||
1da177e4 LT |
442 | return rval; |
443 | } | |
1da177e4 | 444 | EXPORT_SYMBOL(i2c_pcf_add_bus); |
1da177e4 LT |
445 | |
446 | MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>"); | |
447 | MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm"); | |
448 | MODULE_LICENSE("GPL"); | |
449 | ||
450 | module_param(i2c_debug, int, S_IRUGO | S_IWUSR); | |
451 | MODULE_PARM_DESC(i2c_debug, | |
452 | "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); |