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