Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright (C) 1998 Itai Nahshon, Michael Schimek | |
3 | * | |
4 | * The original code was derived from and inspired by | |
5 | * the I2C driver from the Linux kernel. | |
6 | * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de> | |
7 | */ | |
8 | ||
9 | #ifdef HAVE_XORG_CONFIG_H | |
10 | #include <xorg-config.h> | |
11 | #endif | |
12 | ||
13 | #include <sys/time.h> | |
14 | #include <string.h> | |
15 | ||
16 | #include "misc.h" | |
17 | #include "xf86.h" | |
18 | #include "xf86_OSproc.h" | |
19 | ||
20 | #include <X11/X.h> | |
21 | #include <X11/Xos.h> | |
22 | #include <X11/Xproto.h> | |
23 | #include "scrnintstr.h" | |
24 | #include "regionstr.h" | |
25 | #include "windowstr.h" | |
26 | #include "pixmapstr.h" | |
27 | #include "validate.h" | |
28 | #include "resource.h" | |
29 | #include "gcstruct.h" | |
30 | #include "dixstruct.h" | |
31 | ||
32 | #include "xf86i2c.h" | |
33 | ||
34 | #define I2C_TIMEOUT(x) /*(x)*/ /* Report timeouts */ | |
35 | #define I2C_TRACE(x) /*(x)*/ /* Report progress */ | |
36 | ||
37 | /* This is the default I2CUDelay function if not supplied by the driver. | |
38 | * High level I2C interfaces implementing the bus protocol in hardware | |
39 | * should supply this function too. | |
40 | * | |
41 | * Delay execution at least usec microseconds. | |
42 | * All values 0 to 1e6 inclusive must be expected. | |
43 | */ | |
44 | ||
45 | static void | |
46 | I2CUDelay(I2CBusPtr b, int usec) | |
47 | { | |
48 | struct timeval begin, cur; | |
49 | long d_secs, d_usecs; | |
50 | long diff; | |
51 | ||
52 | if (usec > 0) { | |
53 | X_GETTIMEOFDAY(&begin); | |
54 | do { | |
55 | /* It would be nice to use {xf86}usleep, | |
56 | * but usleep (1) takes >10000 usec ! | |
57 | */ | |
58 | X_GETTIMEOFDAY(&cur); | |
59 | d_secs = (cur.tv_sec - begin.tv_sec); | |
60 | d_usecs = (cur.tv_usec - begin.tv_usec); | |
61 | diff = d_secs * 1000000 + d_usecs; | |
62 | } while (diff >= 0 && diff < (usec + 1)); | |
63 | } | |
64 | } | |
65 | ||
66 | /* Most drivers will register just with GetBits/PutBits functions. | |
67 | * The following functions implement a software I2C protocol | |
68 | * by using the promitive functions given by the driver. | |
69 | * ================================================================ | |
70 | * | |
71 | * It is assumed that there is just one master on the I2C bus, therefore | |
72 | * there is no explicit test for conflits. | |
73 | */ | |
74 | ||
75 | #define RISEFALLTIME 2 /* usec, actually 300 to 1000 ns according to the i2c specs */ | |
76 | ||
77 | /* Some devices will hold SCL low to slow down the bus or until | |
78 | * ready for transmission. | |
79 | * | |
80 | * This condition will be noticed when the master tries to raise | |
81 | * the SCL line. You can set the timeout to zero if the slave device | |
82 | * does not support this clock synchronization. | |
83 | */ | |
84 | ||
85 | static Bool | |
86 | I2CRaiseSCL(I2CBusPtr b, int sda, int timeout) | |
87 | { | |
88 | int i, scl; | |
89 | ||
90 | b->I2CPutBits(b, 1, sda); | |
91 | b->I2CUDelay(b, b->RiseFallTime); | |
92 | ||
93 | for (i = timeout; i > 0; i -= b->RiseFallTime) { | |
94 | b->I2CGetBits(b, &scl, &sda); | |
95 | if (scl) | |
96 | break; | |
97 | b->I2CUDelay(b, b->RiseFallTime); | |
98 | } | |
99 | ||
100 | if (i <= 0) { | |
101 | I2C_TIMEOUT(ErrorF | |
102 | ("[I2CRaiseSCL(<%s>, %d, %d) timeout]", b->BusName, sda, | |
103 | timeout)); | |
104 | return FALSE; | |
105 | } | |
106 | ||
107 | return TRUE; | |
108 | } | |
109 | ||
110 | /* Send a start signal on the I2C bus. The start signal notifies | |
111 | * devices that a new transaction is initiated by the bus master. | |
112 | * | |
113 | * The start signal is always followed by a slave address. | |
114 | * Slave addresses are 8+ bits. The first 7 bits identify the | |
115 | * device and the last bit signals if this is a read (1) or | |
116 | * write (0) operation. | |
117 | * | |
118 | * There may be more than one start signal on one transaction. | |
119 | * This happens for example on some devices that allow reading | |
120 | * of registers. First send a start bit followed by the device | |
121 | * address (with the last bit 0) and the register number. Then send | |
122 | * a new start bit with the device address (with the last bit 1) | |
123 | * and then read the value from the device. | |
124 | * | |
125 | * Note this is function does not implement a multiple master | |
126 | * arbitration procedure. | |
127 | */ | |
128 | ||
129 | static Bool | |
130 | I2CStart(I2CBusPtr b, int timeout) | |
131 | { | |
132 | if (!I2CRaiseSCL(b, 1, timeout)) | |
133 | return FALSE; | |
134 | ||
135 | b->I2CPutBits(b, 1, 0); | |
136 | b->I2CUDelay(b, b->HoldTime); | |
137 | b->I2CPutBits(b, 0, 0); | |
138 | b->I2CUDelay(b, b->HoldTime); | |
139 | ||
140 | I2C_TRACE(ErrorF("\ni2c: <")); | |
141 | ||
142 | return TRUE; | |
143 | } | |
144 | ||
145 | /* This is the default I2CStop function if not supplied by the driver. | |
146 | * | |
147 | * Signal devices on the I2C bus that a transaction on the | |
148 | * bus has finished. There may be more than one start signal | |
149 | * on a transaction but only one stop signal. | |
150 | */ | |
151 | ||
152 | static void | |
153 | I2CStop(I2CDevPtr d) | |
154 | { | |
155 | I2CBusPtr b = d->pI2CBus; | |
156 | ||
157 | b->I2CPutBits(b, 0, 0); | |
158 | b->I2CUDelay(b, b->RiseFallTime); | |
159 | ||
160 | b->I2CPutBits(b, 1, 0); | |
161 | b->I2CUDelay(b, b->HoldTime); | |
162 | b->I2CPutBits(b, 1, 1); | |
163 | b->I2CUDelay(b, b->HoldTime); | |
164 | ||
165 | I2C_TRACE(ErrorF(">\n")); | |
166 | } | |
167 | ||
168 | /* Write/Read a single bit to/from a device. | |
169 | * Return FALSE if a timeout occurs. | |
170 | */ | |
171 | ||
172 | static Bool | |
173 | I2CWriteBit(I2CBusPtr b, int sda, int timeout) | |
174 | { | |
175 | Bool r; | |
176 | ||
177 | b->I2CPutBits(b, 0, sda); | |
178 | b->I2CUDelay(b, b->RiseFallTime); | |
179 | ||
180 | r = I2CRaiseSCL(b, sda, timeout); | |
181 | b->I2CUDelay(b, b->HoldTime); | |
182 | ||
183 | b->I2CPutBits(b, 0, sda); | |
184 | b->I2CUDelay(b, b->HoldTime); | |
185 | ||
186 | return r; | |
187 | } | |
188 | ||
189 | static Bool | |
190 | I2CReadBit(I2CBusPtr b, int *psda, int timeout) | |
191 | { | |
192 | Bool r; | |
193 | int scl; | |
194 | ||
195 | r = I2CRaiseSCL(b, 1, timeout); | |
196 | b->I2CUDelay(b, b->HoldTime); | |
197 | ||
198 | b->I2CGetBits(b, &scl, psda); | |
199 | ||
200 | b->I2CPutBits(b, 0, 1); | |
201 | b->I2CUDelay(b, b->HoldTime); | |
202 | ||
203 | return r; | |
204 | } | |
205 | ||
206 | /* This is the default I2CPutByte function if not supplied by the driver. | |
207 | * | |
208 | * A single byte is sent to the device. | |
209 | * The function returns FALSE if a timeout occurs, you should send | |
210 | * a stop condition afterwards to reset the bus. | |
211 | * | |
212 | * A timeout occurs, | |
213 | * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs, | |
214 | * or slows down the bus for more than BitTimeout usecs for each bit, | |
215 | * or does not send an ACK bit (0) to acknowledge the transmission within | |
216 | * AcknTimeout usecs, but a NACK (1) bit. | |
217 | * | |
218 | * AcknTimeout must be at least b->HoldTime, the other timeouts can be | |
219 | * zero according to the comment on I2CRaiseSCL. | |
220 | */ | |
221 | ||
222 | static Bool | |
223 | I2CPutByte(I2CDevPtr d, I2CByte data) | |
224 | { | |
225 | Bool r; | |
226 | int i, scl, sda; | |
227 | I2CBusPtr b = d->pI2CBus; | |
228 | ||
229 | if (!I2CWriteBit(b, (data >> 7) & 1, d->ByteTimeout)) | |
230 | return FALSE; | |
231 | ||
232 | for (i = 6; i >= 0; i--) | |
233 | if (!I2CWriteBit(b, (data >> i) & 1, d->BitTimeout)) | |
234 | return FALSE; | |
235 | ||
236 | b->I2CPutBits(b, 0, 1); | |
237 | b->I2CUDelay(b, b->RiseFallTime); | |
238 | ||
239 | r = I2CRaiseSCL(b, 1, b->HoldTime); | |
240 | ||
241 | if (r) { | |
242 | for (i = d->AcknTimeout; i > 0; i -= b->HoldTime) { | |
243 | b->I2CUDelay(b, b->HoldTime); | |
244 | b->I2CGetBits(b, &scl, &sda); | |
245 | if (sda == 0) | |
246 | break; | |
247 | } | |
248 | ||
249 | if (i <= 0) { | |
250 | I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]", | |
251 | b->BusName, data, d->BitTimeout, | |
252 | d->ByteTimeout, d->AcknTimeout)); | |
253 | r = FALSE; | |
254 | } | |
255 | ||
256 | I2C_TRACE(ErrorF("W%02x%c ", (int) data, sda ? '-' : '+')); | |
257 | } | |
258 | ||
259 | b->I2CPutBits(b, 0, 1); | |
260 | b->I2CUDelay(b, b->HoldTime); | |
261 | ||
262 | return r; | |
263 | } | |
264 | ||
265 | /* This is the default I2CGetByte function if not supplied by the driver. | |
266 | * | |
267 | * A single byte is read from the device. | |
268 | * The function returns FALSE if a timeout occurs, you should send | |
269 | * a stop condition afterwards to reset the bus. | |
270 | * | |
271 | * A timeout occurs, | |
272 | * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs, | |
273 | * or slows down the bus for more than b->BitTimeout usecs for each bit. | |
274 | * | |
275 | * ByteTimeout must be at least b->HoldTime, the other timeouts can be | |
276 | * zero according to the comment on I2CRaiseSCL. | |
277 | * | |
278 | * For the <last> byte in a sequence the acknowledge bit NACK (1), | |
279 | * otherwise ACK (0) will be sent. | |
280 | */ | |
281 | ||
282 | static Bool | |
283 | I2CGetByte(I2CDevPtr d, I2CByte * data, Bool last) | |
284 | { | |
285 | int i, sda; | |
286 | I2CBusPtr b = d->pI2CBus; | |
287 | ||
288 | b->I2CPutBits(b, 0, 1); | |
289 | b->I2CUDelay(b, b->RiseFallTime); | |
290 | ||
291 | if (!I2CReadBit(b, &sda, d->ByteTimeout)) | |
292 | return FALSE; | |
293 | ||
294 | *data = (sda > 0) << 7; | |
295 | ||
296 | for (i = 6; i >= 0; i--) | |
297 | if (!I2CReadBit(b, &sda, d->BitTimeout)) | |
298 | return FALSE; | |
299 | else | |
300 | *data |= (sda > 0) << i; | |
301 | ||
302 | if (!I2CWriteBit(b, last ? 1 : 0, d->BitTimeout)) | |
303 | return FALSE; | |
304 | ||
305 | I2C_TRACE(ErrorF("R%02x%c ", (int) *data, last ? '+' : '-')); | |
306 | ||
307 | return TRUE; | |
308 | } | |
309 | ||
310 | /* This is the default I2CAddress function if not supplied by the driver. | |
311 | * | |
312 | * It creates the start condition, followed by the d->SlaveAddr. | |
313 | * Higher level functions must call this routine rather than | |
314 | * I2CStart/PutByte because a hardware I2C master may not be able | |
315 | * to send a slave address without a start condition. | |
316 | * | |
317 | * The same timeouts apply as with I2CPutByte and additional a | |
318 | * StartTimeout, similar to the ByteTimeout but for the start | |
319 | * condition. | |
320 | * | |
321 | * In case of a timeout, the bus is left in a clean idle condition. | |
322 | * I. e. you *must not* send a Stop. If this function succeeds, you *must*. | |
323 | * | |
324 | * The slave address format is 16 bit, with the legacy _8_bit_ slave address | |
325 | * in the least significant byte. This is, the slave address must include the | |
326 | * R/_W flag as least significant bit. | |
327 | * | |
328 | * The most significant byte of the address will be sent _after_ the LSB, | |
329 | * but only if the LSB indicates: | |
330 | * a) an 11 bit address, this is LSB = 1111 0xxx. | |
331 | * b) a 'general call address', this is LSB = 0000 000x - see the I2C specs | |
332 | * for more. | |
333 | */ | |
334 | ||
335 | static Bool | |
336 | I2CAddress(I2CDevPtr d, I2CSlaveAddr addr) | |
337 | { | |
338 | if (I2CStart(d->pI2CBus, d->StartTimeout)) { | |
339 | if (I2CPutByte(d, addr & 0xFF)) { | |
340 | if ((addr & 0xF8) != 0xF0 && (addr & 0xFE) != 0x00) | |
341 | return TRUE; | |
342 | ||
343 | if (I2CPutByte(d, (addr >> 8) & 0xFF)) | |
344 | return TRUE; | |
345 | } | |
346 | ||
347 | I2CStop(d); | |
348 | } | |
349 | ||
350 | return FALSE; | |
351 | } | |
352 | ||
353 | /* These are the hardware independent I2C helper functions. | |
354 | * ======================================================== | |
355 | */ | |
356 | ||
357 | /* Function for probing. Just send the slave address | |
358 | * and return true if the device responds. The slave address | |
359 | * must have the lsb set to reflect a read (1) or write (0) access. | |
360 | * Don't expect a read- or write-only device will respond otherwise. | |
361 | */ | |
362 | ||
363 | Bool | |
364 | xf86I2CProbeAddress(I2CBusPtr b, I2CSlaveAddr addr) | |
365 | { | |
366 | int r; | |
367 | I2CDevRec d; | |
368 | ||
369 | d.DevName = "Probing"; | |
370 | d.BitTimeout = b->BitTimeout; | |
371 | d.ByteTimeout = b->ByteTimeout; | |
372 | d.AcknTimeout = b->AcknTimeout; | |
373 | d.StartTimeout = b->StartTimeout; | |
374 | d.SlaveAddr = addr; | |
375 | d.pI2CBus = b; | |
376 | d.NextDev = NULL; | |
377 | ||
378 | r = b->I2CAddress(&d, addr); | |
379 | ||
380 | if (r) | |
381 | b->I2CStop(&d); | |
382 | ||
383 | return r; | |
384 | } | |
385 | ||
386 | /* All functions below are related to devices and take the | |
387 | * slave address and timeout values from an I2CDevRec. They | |
388 | * return FALSE in case of an error (presumably a timeout). | |
389 | */ | |
390 | ||
391 | /* General purpose read and write function. | |
392 | * | |
393 | * 1st, if nWrite > 0 | |
394 | * Send a start condition | |
395 | * Send the slave address (1 or 2 bytes) with write flag | |
396 | * Write n bytes from WriteBuffer | |
397 | * 2nd, if nRead > 0 | |
398 | * Send a start condition [again] | |
399 | * Send the slave address (1 or 2 bytes) with read flag | |
400 | * Read n bytes to ReadBuffer | |
401 | * 3rd, if a Start condition has been successfully sent, | |
402 | * Send a Stop condition. | |
403 | * | |
404 | * The functions exits immediately when an error occures, | |
405 | * not proceeding any data left. However, step 3 will | |
406 | * be executed anyway to leave the bus in clean idle state. | |
407 | */ | |
408 | ||
409 | static Bool | |
410 | I2CWriteRead(I2CDevPtr d, | |
411 | I2CByte * WriteBuffer, int nWrite, I2CByte * ReadBuffer, int nRead) | |
412 | { | |
413 | Bool r = TRUE; | |
414 | I2CBusPtr b = d->pI2CBus; | |
415 | int s = 0; | |
416 | ||
417 | if (r && nWrite > 0) { | |
418 | r = b->I2CAddress(d, d->SlaveAddr & ~1); | |
419 | if (r) { | |
420 | for (; nWrite > 0; WriteBuffer++, nWrite--) | |
421 | if (!(r = b->I2CPutByte(d, *WriteBuffer))) | |
422 | break; | |
423 | s++; | |
424 | } | |
425 | } | |
426 | ||
427 | if (r && nRead > 0) { | |
428 | r = b->I2CAddress(d, d->SlaveAddr | 1); | |
429 | if (r) { | |
430 | for (; nRead > 0; ReadBuffer++, nRead--) | |
431 | if (!(r = b->I2CGetByte(d, ReadBuffer, nRead == 1))) | |
432 | break; | |
433 | s++; | |
434 | } | |
435 | } | |
436 | ||
437 | if (s) | |
438 | b->I2CStop(d); | |
439 | ||
440 | return r; | |
441 | } | |
442 | ||
443 | /* wrapper - for compatibility and convinience */ | |
444 | ||
445 | Bool | |
446 | xf86I2CWriteRead(I2CDevPtr d, | |
447 | I2CByte * WriteBuffer, int nWrite, | |
448 | I2CByte * ReadBuffer, int nRead) | |
449 | { | |
450 | I2CBusPtr b = d->pI2CBus; | |
451 | ||
452 | return b->I2CWriteRead(d, WriteBuffer, nWrite, ReadBuffer, nRead); | |
453 | } | |
454 | ||
455 | /* Read a byte, the only readable register of a device. | |
456 | */ | |
457 | ||
458 | Bool | |
459 | xf86I2CReadStatus(I2CDevPtr d, I2CByte * pbyte) | |
460 | { | |
461 | return xf86I2CWriteRead(d, NULL, 0, pbyte, 1); | |
462 | } | |
463 | ||
464 | /* Read a byte from one of the registers determined by its sub-address. | |
465 | */ | |
466 | ||
467 | Bool | |
468 | xf86I2CReadByte(I2CDevPtr d, I2CByte subaddr, I2CByte * pbyte) | |
469 | { | |
470 | return xf86I2CWriteRead(d, &subaddr, 1, pbyte, 1); | |
471 | } | |
472 | ||
473 | /* Read bytes from subsequent registers determined by the | |
474 | * sub-address of the first register. | |
475 | */ | |
476 | ||
477 | Bool | |
478 | xf86I2CReadBytes(I2CDevPtr d, I2CByte subaddr, I2CByte * pbyte, int n) | |
479 | { | |
480 | return xf86I2CWriteRead(d, &subaddr, 1, pbyte, n); | |
481 | } | |
482 | ||
483 | /* Read a word (high byte, then low byte) from one of the registers | |
484 | * determined by its sub-address. | |
485 | */ | |
486 | ||
487 | Bool | |
488 | xf86I2CReadWord(I2CDevPtr d, I2CByte subaddr, unsigned short *pword) | |
489 | { | |
490 | I2CByte rb[2]; | |
491 | ||
492 | if (!xf86I2CWriteRead(d, &subaddr, 1, rb, 2)) | |
493 | return FALSE; | |
494 | ||
495 | *pword = (rb[0] << 8) | rb[1]; | |
496 | ||
497 | return TRUE; | |
498 | } | |
499 | ||
500 | /* Write a byte to one of the registers determined by its sub-address. | |
501 | */ | |
502 | ||
503 | Bool | |
504 | xf86I2CWriteByte(I2CDevPtr d, I2CByte subaddr, I2CByte byte) | |
505 | { | |
506 | I2CByte wb[2]; | |
507 | ||
508 | wb[0] = subaddr; | |
509 | wb[1] = byte; | |
510 | ||
511 | return xf86I2CWriteRead(d, wb, 2, NULL, 0); | |
512 | } | |
513 | ||
514 | /* Write bytes to subsequent registers determined by the | |
515 | * sub-address of the first register. | |
516 | */ | |
517 | ||
518 | Bool | |
519 | xf86I2CWriteBytes(I2CDevPtr d, I2CByte subaddr, | |
520 | I2CByte * WriteBuffer, int nWrite) | |
521 | { | |
522 | I2CBusPtr b = d->pI2CBus; | |
523 | Bool r = TRUE; | |
524 | ||
525 | if (nWrite > 0) { | |
526 | r = b->I2CAddress(d, d->SlaveAddr & ~1); | |
527 | if (r) { | |
528 | if ((r = b->I2CPutByte(d, subaddr))) | |
529 | for (; nWrite > 0; WriteBuffer++, nWrite--) | |
530 | if (!(r = b->I2CPutByte(d, *WriteBuffer))) | |
531 | break; | |
532 | ||
533 | b->I2CStop(d); | |
534 | } | |
535 | } | |
536 | ||
537 | return r; | |
538 | } | |
539 | ||
540 | /* Write a word (high byte, then low byte) to one of the registers | |
541 | * determined by its sub-address. | |
542 | */ | |
543 | ||
544 | Bool | |
545 | xf86I2CWriteWord(I2CDevPtr d, I2CByte subaddr, unsigned short word) | |
546 | { | |
547 | I2CByte wb[3]; | |
548 | ||
549 | wb[0] = subaddr; | |
550 | wb[1] = word >> 8; | |
551 | wb[2] = word & 0xFF; | |
552 | ||
553 | return xf86I2CWriteRead(d, wb, 3, NULL, 0); | |
554 | } | |
555 | ||
556 | /* Write a vector of bytes to not adjacent registers. This vector is, | |
557 | * 1st byte sub-address, 2nd byte value, 3rd byte sub-address asf. | |
558 | * This function is intended to initialize devices. Note this function | |
559 | * exits immediately when an error occurs, some registers may | |
560 | * remain uninitialized. | |
561 | */ | |
562 | ||
563 | Bool | |
564 | xf86I2CWriteVec(I2CDevPtr d, I2CByte * vec, int nValues) | |
565 | { | |
566 | I2CBusPtr b = d->pI2CBus; | |
567 | Bool r = TRUE; | |
568 | int s = 0; | |
569 | ||
570 | if (nValues > 0) { | |
571 | for (; nValues > 0; nValues--, vec += 2) { | |
572 | if (!(r = b->I2CAddress(d, d->SlaveAddr & ~1))) | |
573 | break; | |
574 | ||
575 | s++; | |
576 | ||
577 | if (!(r = b->I2CPutByte(d, vec[0]))) | |
578 | break; | |
579 | ||
580 | if (!(r = b->I2CPutByte(d, vec[1]))) | |
581 | break; | |
582 | } | |
583 | ||
584 | if (s > 0) | |
585 | b->I2CStop(d); | |
586 | } | |
587 | ||
588 | return r; | |
589 | } | |
590 | ||
591 | /* Administrative functions. | |
592 | * ========================= | |
593 | */ | |
594 | ||
595 | /* Allocates an I2CDevRec for you and initializes with propper defaults | |
596 | * you may modify before calling xf86I2CDevInit. Your I2CDevRec must | |
597 | * contain at least a SlaveAddr, and a pI2CBus pointer to the bus this | |
598 | * device shall be linked to. | |
599 | * | |
600 | * See function I2CAddress for the slave address format. Always set | |
601 | * the least significant bit, indicating a read or write access, to zero. | |
602 | */ | |
603 | ||
604 | I2CDevPtr | |
605 | xf86CreateI2CDevRec(void) | |
606 | { | |
607 | return calloc(1, sizeof(I2CDevRec)); | |
608 | } | |
609 | ||
610 | /* Unlink an I2C device. If you got the I2CDevRec from xf86CreateI2CDevRec | |
611 | * you should set <unalloc> to free it. | |
612 | */ | |
613 | ||
614 | void | |
615 | xf86DestroyI2CDevRec(I2CDevPtr d, Bool unalloc) | |
616 | { | |
617 | if (d) { | |
618 | I2CDevPtr *p; | |
619 | ||
620 | /* Remove this from the list of active I2C devices. */ | |
621 | ||
622 | for (p = &d->pI2CBus->FirstDev; *p != NULL; p = &(*p)->NextDev) | |
623 | if (*p == d) { | |
624 | *p = (*p)->NextDev; | |
625 | break; | |
626 | } | |
627 | ||
628 | xf86DrvMsg(d->pI2CBus->scrnIndex, X_INFO, | |
629 | "I2C device \"%s:%s\" removed.\n", | |
630 | d->pI2CBus->BusName, d->DevName); | |
631 | ||
632 | if (unalloc) | |
633 | free(d); | |
634 | } | |
635 | } | |
636 | ||
637 | /* I2C transmissions are related to an I2CDevRec you must link to a | |
638 | * previously registered bus (see xf86I2CBusInit) before attempting | |
639 | * to read and write data. You may call xf86I2CProbeAddress first to | |
640 | * see if the device in question is present on this bus. | |
641 | * | |
642 | * xf86I2CDevInit will not allocate an I2CBusRec for you, instead you | |
643 | * may enter a pointer to a statically allocated I2CDevRec or the (modified) | |
644 | * result of xf86CreateI2CDevRec. | |
645 | * | |
646 | * If you don't specify timeouts for the device (n <= 0), it will inherit | |
647 | * the bus-wide defaults. The function returns TRUE on success. | |
648 | */ | |
649 | ||
650 | Bool | |
651 | xf86I2CDevInit(I2CDevPtr d) | |
652 | { | |
653 | I2CBusPtr b; | |
654 | ||
655 | if (d == NULL || | |
656 | (b = d->pI2CBus) == NULL || | |
657 | (d->SlaveAddr & 1) || xf86I2CFindDev(b, d->SlaveAddr) != NULL) | |
658 | return FALSE; | |
659 | ||
660 | if (d->BitTimeout <= 0) | |
661 | d->BitTimeout = b->BitTimeout; | |
662 | if (d->ByteTimeout <= 0) | |
663 | d->ByteTimeout = b->ByteTimeout; | |
664 | if (d->AcknTimeout <= 0) | |
665 | d->AcknTimeout = b->AcknTimeout; | |
666 | if (d->StartTimeout <= 0) | |
667 | d->StartTimeout = b->StartTimeout; | |
668 | ||
669 | d->NextDev = b->FirstDev; | |
670 | b->FirstDev = d; | |
671 | ||
672 | xf86DrvMsg(b->scrnIndex, X_INFO, | |
673 | "I2C device \"%s:%s\" registered at address 0x%02X.\n", | |
674 | b->BusName, d->DevName, d->SlaveAddr); | |
675 | ||
676 | return TRUE; | |
677 | } | |
678 | ||
679 | I2CDevPtr | |
680 | xf86I2CFindDev(I2CBusPtr b, I2CSlaveAddr addr) | |
681 | { | |
682 | I2CDevPtr d; | |
683 | ||
684 | if (b) { | |
685 | for (d = b->FirstDev; d != NULL; d = d->NextDev) | |
686 | if (d->SlaveAddr == addr) | |
687 | return d; | |
688 | } | |
689 | ||
690 | return NULL; | |
691 | } | |
692 | ||
693 | static I2CBusPtr I2CBusList; | |
694 | ||
695 | /* Allocates an I2CBusRec for you and initializes with propper defaults | |
696 | * you may modify before calling xf86I2CBusInit. Your I2CBusRec must | |
697 | * contain at least a BusName, a scrnIndex (or -1), and a complete set | |
698 | * of either high or low level I2C function pointers. You may pass | |
699 | * bus-wide timeouts, otherwise inplausible values will be replaced | |
700 | * with safe defaults. | |
701 | */ | |
702 | ||
703 | I2CBusPtr | |
704 | xf86CreateI2CBusRec(void) | |
705 | { | |
706 | I2CBusPtr b; | |
707 | ||
708 | b = (I2CBusPtr) calloc(1, sizeof(I2CBusRec)); | |
709 | ||
710 | if (b != NULL) { | |
711 | b->scrnIndex = -1; | |
712 | b->pScrn = NULL; | |
713 | b->HoldTime = 5; /* 100 kHz bus */ | |
714 | b->BitTimeout = 5; | |
715 | b->ByteTimeout = 5; | |
716 | b->AcknTimeout = 5; | |
717 | b->StartTimeout = 5; | |
718 | b->RiseFallTime = RISEFALLTIME; | |
719 | } | |
720 | ||
721 | return b; | |
722 | } | |
723 | ||
724 | /* Unregister an I2C bus. If you got the I2CBusRec from xf86CreateI2CBusRec | |
725 | * you should set <unalloc> to free it. If you set <devs_too>, the function | |
726 | * xf86DestroyI2CDevRec will be called for all devices linked to the bus | |
727 | * first, passing down the <unalloc> option. | |
728 | */ | |
729 | ||
730 | void | |
731 | xf86DestroyI2CBusRec(I2CBusPtr b, Bool unalloc, Bool devs_too) | |
732 | { | |
733 | if (b) { | |
734 | I2CBusPtr *p; | |
735 | ||
736 | /* Remove this from the list of active I2C buses */ | |
737 | ||
738 | for (p = &I2CBusList; *p != NULL; p = &(*p)->NextBus) | |
739 | if (*p == b) { | |
740 | *p = (*p)->NextBus; | |
741 | break; | |
742 | } | |
743 | ||
744 | if (b->FirstDev != NULL) { | |
745 | if (devs_too) { | |
746 | I2CDevPtr d; | |
747 | ||
748 | while ((d = b->FirstDev) != NULL) { | |
749 | b->FirstDev = d->NextDev; | |
750 | xf86DestroyI2CDevRec(d, unalloc); | |
751 | } | |
752 | } | |
753 | else { | |
754 | if (unalloc) { | |
755 | xf86Msg(X_ERROR, | |
756 | "i2c bug: Attempt to remove I2C bus \"%s\", " | |
757 | "but device list is not empty.\n", b->BusName); | |
758 | return; | |
759 | } | |
760 | } | |
761 | } | |
762 | ||
763 | xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" removed.\n", | |
764 | b->BusName); | |
765 | ||
766 | if (unalloc) | |
767 | free(b); | |
768 | } | |
769 | } | |
770 | ||
771 | /* I2C masters have to register themselves using this function. | |
772 | * It will not allocate an I2CBusRec for you, instead you may enter | |
773 | * a pointer to a statically allocated I2CBusRec or the (modified) | |
774 | * result of xf86CreateI2CBusRec. Returns TRUE on success. | |
775 | * | |
776 | * At this point there won't be any traffic on the I2C bus. | |
777 | */ | |
778 | ||
779 | Bool | |
780 | xf86I2CBusInit(I2CBusPtr b) | |
781 | { | |
782 | /* I2C buses must be identified by a unique scrnIndex | |
783 | * and name. If scrnIndex is unspecified (a negative value), | |
784 | * then the name must be unique throughout the server. | |
785 | */ | |
786 | ||
787 | if (b->BusName == NULL || xf86I2CFindBus(b->scrnIndex, b->BusName) != NULL) | |
788 | return FALSE; | |
789 | ||
790 | /* If the high level functions are not | |
791 | * supplied, use the generic functions. | |
792 | * In this case we need the low-level | |
793 | * function. | |
794 | */ | |
795 | if (b->I2CWriteRead == NULL) { | |
796 | b->I2CWriteRead = I2CWriteRead; | |
797 | ||
798 | if (b->I2CPutBits == NULL || b->I2CGetBits == NULL) { | |
799 | if (b->I2CPutByte == NULL || | |
800 | b->I2CGetByte == NULL || | |
801 | b->I2CAddress == NULL || | |
802 | b->I2CStart == NULL || b->I2CStop == NULL) | |
803 | return FALSE; | |
804 | } | |
805 | else { | |
806 | b->I2CPutByte = I2CPutByte; | |
807 | b->I2CGetByte = I2CGetByte; | |
808 | b->I2CAddress = I2CAddress; | |
809 | b->I2CStop = I2CStop; | |
810 | b->I2CStart = I2CStart; | |
811 | } | |
812 | } | |
813 | ||
814 | if (b->I2CUDelay == NULL) | |
815 | b->I2CUDelay = I2CUDelay; | |
816 | ||
817 | if (b->HoldTime < 2) | |
818 | b->HoldTime = 5; | |
819 | if (b->BitTimeout <= 0) | |
820 | b->BitTimeout = b->HoldTime; | |
821 | if (b->ByteTimeout <= 0) | |
822 | b->ByteTimeout = b->HoldTime; | |
823 | if (b->AcknTimeout <= 0) | |
824 | b->AcknTimeout = b->HoldTime; | |
825 | if (b->StartTimeout <= 0) | |
826 | b->StartTimeout = b->HoldTime; | |
827 | ||
828 | /* Put new bus on list. */ | |
829 | ||
830 | b->NextBus = I2CBusList; | |
831 | I2CBusList = b; | |
832 | ||
833 | xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" initialized.\n", | |
834 | b->BusName); | |
835 | ||
836 | return TRUE; | |
837 | } | |
838 | ||
839 | I2CBusPtr | |
840 | xf86I2CFindBus(int scrnIndex, char *name) | |
841 | { | |
842 | I2CBusPtr p; | |
843 | ||
844 | if (name != NULL) | |
845 | for (p = I2CBusList; p != NULL; p = p->NextBus) | |
846 | if (scrnIndex < 0 || p->scrnIndex == scrnIndex) | |
847 | if (!strcmp(p->BusName, name)) | |
848 | return p; | |
849 | ||
850 | return NULL; | |
851 | } | |
852 | ||
853 | /* | |
854 | * Return an array of I2CBusPtr's related to a screen. The caller is | |
855 | * responsible for freeing the array. | |
856 | */ | |
857 | int | |
858 | xf86I2CGetScreenBuses(int scrnIndex, I2CBusPtr ** pppI2CBus) | |
859 | { | |
860 | I2CBusPtr pI2CBus; | |
861 | int n = 0; | |
862 | ||
863 | if (pppI2CBus) | |
864 | *pppI2CBus = NULL; | |
865 | ||
866 | for (pI2CBus = I2CBusList; pI2CBus; pI2CBus = pI2CBus->NextBus) { | |
867 | if ((pI2CBus->scrnIndex >= 0) && (pI2CBus->scrnIndex != scrnIndex)) | |
868 | continue; | |
869 | ||
870 | n++; | |
871 | ||
872 | if (!pppI2CBus) | |
873 | continue; | |
874 | ||
875 | *pppI2CBus = xnfrealloc(*pppI2CBus, n * sizeof(I2CBusPtr)); | |
876 | (*pppI2CBus)[n - 1] = pI2CBus; | |
877 | } | |
878 | ||
879 | return n; | |
880 | } |