1706f2543Smrg/*
2706f2543Smrg * Copyright (C) 1998 Itai Nahshon, Michael Schimek
3706f2543Smrg *
4706f2543Smrg * The original code was derived from and inspired by
5706f2543Smrg * the I2C driver from the Linux kernel.
6706f2543Smrg *      (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
7706f2543Smrg */
8706f2543Smrg
9706f2543Smrg
10706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
11706f2543Smrg#include <xorg-config.h>
12706f2543Smrg#endif
13706f2543Smrg
14706f2543Smrg#include <sys/time.h>
15706f2543Smrg#include <string.h>
16706f2543Smrg
17706f2543Smrg#include "misc.h"
18706f2543Smrg#include "xf86.h"
19706f2543Smrg#include "xf86_OSproc.h"
20706f2543Smrg
21706f2543Smrg#include <X11/X.h>
22706f2543Smrg#include <X11/Xos.h>
23706f2543Smrg#include <X11/Xproto.h>
24706f2543Smrg#include "scrnintstr.h"
25706f2543Smrg#include "regionstr.h"
26706f2543Smrg#include "windowstr.h"
27706f2543Smrg#include "pixmapstr.h"
28706f2543Smrg#include "validate.h"
29706f2543Smrg#include "resource.h"
30706f2543Smrg#include "gcstruct.h"
31706f2543Smrg#include "dixstruct.h"
32706f2543Smrg
33706f2543Smrg#include "xf86i2c.h"
34706f2543Smrg
35706f2543Smrg#define I2C_TIMEOUT(x)	/*(x)*/  /* Report timeouts */
36706f2543Smrg#define I2C_TRACE(x)    /*(x)*/  /* Report progress */
37706f2543Smrg
38706f2543Smrg/* This is the default I2CUDelay function if not supplied by the driver.
39706f2543Smrg * High level I2C interfaces implementing the bus protocol in hardware
40706f2543Smrg * should supply this function too.
41706f2543Smrg *
42706f2543Smrg * Delay execution at least usec microseconds.
43706f2543Smrg * All values 0 to 1e6 inclusive must be expected.
44706f2543Smrg */
45706f2543Smrg
46706f2543Smrgstatic void
47706f2543SmrgI2CUDelay(I2CBusPtr b, int usec)
48706f2543Smrg{
49706f2543Smrg  struct timeval begin, cur;
50706f2543Smrg  long d_secs, d_usecs;
51706f2543Smrg  long diff;
52706f2543Smrg
53706f2543Smrg  if (usec > 0) {
54706f2543Smrg    X_GETTIMEOFDAY(&begin);
55706f2543Smrg    do {
56706f2543Smrg      /* It would be nice to use {xf86}usleep,
57706f2543Smrg       * but usleep (1) takes >10000 usec !
58706f2543Smrg       */
59706f2543Smrg      X_GETTIMEOFDAY(&cur);
60706f2543Smrg      d_secs  = (cur.tv_sec - begin.tv_sec);
61706f2543Smrg      d_usecs = (cur.tv_usec - begin.tv_usec);
62706f2543Smrg      diff = d_secs*1000000 + d_usecs;
63706f2543Smrg    } while (diff>=0 && diff< (usec + 1));
64706f2543Smrg  }
65706f2543Smrg}
66706f2543Smrg
67706f2543Smrg/* Most drivers will register just with GetBits/PutBits functions.
68706f2543Smrg * The following functions implement a software I2C protocol
69706f2543Smrg * by using the promitive functions given by the driver.
70706f2543Smrg * ================================================================
71706f2543Smrg *
72706f2543Smrg * It is assumed that there is just one master on the I2C bus, therefore
73706f2543Smrg * there is no explicit test for conflits.
74706f2543Smrg */
75706f2543Smrg
76706f2543Smrg#define RISEFALLTIME 2 /* usec, actually 300 to 1000 ns according to the i2c specs */
77706f2543Smrg
78706f2543Smrg/* Some devices will hold SCL low to slow down the bus or until
79706f2543Smrg * ready for transmission.
80706f2543Smrg *
81706f2543Smrg * This condition will be noticed when the master tries to raise
82706f2543Smrg * the SCL line. You can set the timeout to zero if the slave device
83706f2543Smrg * does not support this clock synchronization.
84706f2543Smrg */
85706f2543Smrg
86706f2543Smrgstatic Bool
87706f2543SmrgI2CRaiseSCL(I2CBusPtr b, int sda, int timeout)
88706f2543Smrg{
89706f2543Smrg    int i, scl;
90706f2543Smrg
91706f2543Smrg    b->I2CPutBits(b, 1, sda);
92706f2543Smrg    b->I2CUDelay(b, b->RiseFallTime);
93706f2543Smrg
94706f2543Smrg    for (i = timeout; i > 0; i -= b->RiseFallTime) {
95706f2543Smrg	b->I2CGetBits(b, &scl, &sda);
96706f2543Smrg	if (scl) break;
97706f2543Smrg	b->I2CUDelay(b, b->RiseFallTime);
98706f2543Smrg    }
99706f2543Smrg
100706f2543Smrg    if (i <= 0) {
101706f2543Smrg	I2C_TIMEOUT(ErrorF("[I2CRaiseSCL(<%s>, %d, %d) timeout]", b->BusName, sda, timeout));
102706f2543Smrg	return FALSE;
103706f2543Smrg    }
104706f2543Smrg
105706f2543Smrg    return TRUE;
106706f2543Smrg}
107706f2543Smrg
108706f2543Smrg/* Send a start signal on the I2C bus. The start signal notifies
109706f2543Smrg * devices that a new transaction is initiated by the bus master.
110706f2543Smrg *
111706f2543Smrg * The start signal is always followed by a slave address.
112706f2543Smrg * Slave addresses are 8+ bits. The first 7 bits identify the
113706f2543Smrg * device and the last bit signals if this is a read (1) or
114706f2543Smrg * write (0) operation.
115706f2543Smrg *
116706f2543Smrg * There may be more than one start signal on one transaction.
117706f2543Smrg * This happens for example on some devices that allow reading
118706f2543Smrg * of registers. First send a start bit followed by the device
119706f2543Smrg * address (with the last bit 0) and the register number. Then send
120706f2543Smrg * a new start bit with the device address (with the last bit 1)
121706f2543Smrg * and then read the value from the device.
122706f2543Smrg *
123706f2543Smrg * Note this is function does not implement a multiple master
124706f2543Smrg * arbitration procedure.
125706f2543Smrg */
126706f2543Smrg
127706f2543Smrgstatic Bool
128706f2543SmrgI2CStart(I2CBusPtr b, int timeout)
129706f2543Smrg{
130706f2543Smrg    if (!I2CRaiseSCL(b, 1, timeout))
131706f2543Smrg	return FALSE;
132706f2543Smrg
133706f2543Smrg    b->I2CPutBits(b, 1, 0);
134706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
135706f2543Smrg    b->I2CPutBits(b, 0, 0);
136706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
137706f2543Smrg
138706f2543Smrg    I2C_TRACE(ErrorF("\ni2c: <"));
139706f2543Smrg
140706f2543Smrg    return TRUE;
141706f2543Smrg}
142706f2543Smrg
143706f2543Smrg/* This is the default I2CStop function if not supplied by the driver.
144706f2543Smrg *
145706f2543Smrg * Signal devices on the I2C bus that a transaction on the
146706f2543Smrg * bus has finished. There may be more than one start signal
147706f2543Smrg * on a transaction but only one stop signal.
148706f2543Smrg */
149706f2543Smrg
150706f2543Smrgstatic void
151706f2543SmrgI2CStop(I2CDevPtr d)
152706f2543Smrg{
153706f2543Smrg    I2CBusPtr b = d->pI2CBus;
154706f2543Smrg
155706f2543Smrg    b->I2CPutBits(b, 0, 0);
156706f2543Smrg    b->I2CUDelay(b, b->RiseFallTime);
157706f2543Smrg
158706f2543Smrg    b->I2CPutBits(b, 1, 0);
159706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
160706f2543Smrg    b->I2CPutBits(b, 1, 1);
161706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
162706f2543Smrg
163706f2543Smrg    I2C_TRACE(ErrorF(">\n"));
164706f2543Smrg}
165706f2543Smrg
166706f2543Smrg/* Write/Read a single bit to/from a device.
167706f2543Smrg * Return FALSE if a timeout occurs.
168706f2543Smrg */
169706f2543Smrg
170706f2543Smrgstatic Bool
171706f2543SmrgI2CWriteBit(I2CBusPtr b, int sda, int timeout)
172706f2543Smrg{
173706f2543Smrg    Bool r;
174706f2543Smrg
175706f2543Smrg    b->I2CPutBits(b, 0, sda);
176706f2543Smrg    b->I2CUDelay(b, b->RiseFallTime);
177706f2543Smrg
178706f2543Smrg    r = I2CRaiseSCL(b, sda, timeout);
179706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
180706f2543Smrg
181706f2543Smrg    b->I2CPutBits(b, 0, sda);
182706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
183706f2543Smrg
184706f2543Smrg    return r;
185706f2543Smrg}
186706f2543Smrg
187706f2543Smrgstatic Bool
188706f2543SmrgI2CReadBit(I2CBusPtr b, int *psda, int timeout)
189706f2543Smrg{
190706f2543Smrg    Bool r;
191706f2543Smrg    int scl;
192706f2543Smrg
193706f2543Smrg    r = I2CRaiseSCL(b, 1, timeout);
194706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
195706f2543Smrg
196706f2543Smrg    b->I2CGetBits(b, &scl, psda);
197706f2543Smrg
198706f2543Smrg    b->I2CPutBits(b, 0, 1);
199706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
200706f2543Smrg
201706f2543Smrg    return r;
202706f2543Smrg}
203706f2543Smrg
204706f2543Smrg/* This is the default I2CPutByte function if not supplied by the driver.
205706f2543Smrg *
206706f2543Smrg * A single byte is sent to the device.
207706f2543Smrg * The function returns FALSE if a timeout occurs, you should send
208706f2543Smrg * a stop condition afterwards to reset the bus.
209706f2543Smrg *
210706f2543Smrg * A timeout occurs,
211706f2543Smrg * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
212706f2543Smrg * or slows down the bus for more than BitTimeout usecs for each bit,
213706f2543Smrg * or does not send an ACK bit (0) to acknowledge the transmission within
214706f2543Smrg * AcknTimeout usecs, but a NACK (1) bit.
215706f2543Smrg *
216706f2543Smrg * AcknTimeout must be at least b->HoldTime, the other timeouts can be
217706f2543Smrg * zero according to the comment on I2CRaiseSCL.
218706f2543Smrg */
219706f2543Smrg
220706f2543Smrgstatic Bool
221706f2543SmrgI2CPutByte(I2CDevPtr d, I2CByte data)
222706f2543Smrg{
223706f2543Smrg    Bool r;
224706f2543Smrg    int i, scl, sda;
225706f2543Smrg    I2CBusPtr b = d->pI2CBus;
226706f2543Smrg
227706f2543Smrg    if (!I2CWriteBit(b, (data >> 7) & 1, d->ByteTimeout))
228706f2543Smrg	return FALSE;
229706f2543Smrg
230706f2543Smrg    for (i = 6; i >= 0; i--)
231706f2543Smrg	if (!I2CWriteBit(b, (data >> i) & 1, d->BitTimeout))
232706f2543Smrg	    return FALSE;
233706f2543Smrg
234706f2543Smrg    b->I2CPutBits(b, 0, 1);
235706f2543Smrg    b->I2CUDelay(b, b->RiseFallTime);
236706f2543Smrg
237706f2543Smrg    r = I2CRaiseSCL(b, 1, b->HoldTime);
238706f2543Smrg
239706f2543Smrg    if (r) {
240706f2543Smrg    	for (i = d->AcknTimeout; i > 0; i -= b->HoldTime) {
241706f2543Smrg	    b->I2CUDelay(b, b->HoldTime);
242706f2543Smrg	    b->I2CGetBits(b, &scl, &sda);
243706f2543Smrg	    if (sda == 0) break;
244706f2543Smrg	}
245706f2543Smrg
246706f2543Smrg	if (i <= 0) {
247706f2543Smrg	    I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]",
248706f2543Smrg				       b->BusName, data, d->BitTimeout,
249706f2543Smrg				       d->ByteTimeout, d->AcknTimeout));
250706f2543Smrg	    r = FALSE;
251706f2543Smrg	}
252706f2543Smrg
253706f2543Smrg	I2C_TRACE(ErrorF("W%02x%c ", (int) data, sda ? '-' : '+'));
254706f2543Smrg    }
255706f2543Smrg
256706f2543Smrg    b->I2CPutBits(b, 0, 1);
257706f2543Smrg    b->I2CUDelay(b, b->HoldTime);
258706f2543Smrg
259706f2543Smrg    return r;
260706f2543Smrg}
261706f2543Smrg
262706f2543Smrg/* This is the default I2CGetByte function if not supplied by the driver.
263706f2543Smrg *
264706f2543Smrg * A single byte is read from the device.
265706f2543Smrg * The function returns FALSE if a timeout occurs, you should send
266706f2543Smrg * a stop condition afterwards to reset the bus.
267706f2543Smrg *
268706f2543Smrg * A timeout occurs,
269706f2543Smrg * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
270706f2543Smrg * or slows down the bus for more than b->BitTimeout usecs for each bit.
271706f2543Smrg *
272706f2543Smrg * ByteTimeout must be at least b->HoldTime, the other timeouts can be
273706f2543Smrg * zero according to the comment on I2CRaiseSCL.
274706f2543Smrg *
275706f2543Smrg * For the <last> byte in a sequence the acknowledge bit NACK (1),
276706f2543Smrg * otherwise ACK (0) will be sent.
277706f2543Smrg */
278706f2543Smrg
279706f2543Smrgstatic Bool
280706f2543SmrgI2CGetByte(I2CDevPtr d, I2CByte *data, Bool last)
281706f2543Smrg{
282706f2543Smrg    int i, sda;
283706f2543Smrg    I2CBusPtr b = d->pI2CBus;
284706f2543Smrg
285706f2543Smrg    b->I2CPutBits(b, 0, 1);
286706f2543Smrg    b->I2CUDelay(b, b->RiseFallTime);
287706f2543Smrg
288706f2543Smrg    if (!I2CReadBit(b, &sda, d->ByteTimeout))
289706f2543Smrg	return FALSE;
290706f2543Smrg
291706f2543Smrg    *data = (sda > 0) << 7;
292706f2543Smrg
293706f2543Smrg    for (i = 6; i >= 0; i--)
294706f2543Smrg	if (!I2CReadBit(b, &sda, d->BitTimeout))
295706f2543Smrg	    return FALSE;
296706f2543Smrg	else
297706f2543Smrg	    *data |= (sda > 0) << i;
298706f2543Smrg
299706f2543Smrg    if (!I2CWriteBit(b, last ? 1 : 0, d->BitTimeout))
300706f2543Smrg	return FALSE;
301706f2543Smrg
302706f2543Smrg    I2C_TRACE(ErrorF("R%02x%c ", (int) *data, last ? '+' : '-'));
303706f2543Smrg
304706f2543Smrg    return TRUE;
305706f2543Smrg}
306706f2543Smrg
307706f2543Smrg/* This is the default I2CAddress function if not supplied by the driver.
308706f2543Smrg *
309706f2543Smrg * It creates the start condition, followed by the d->SlaveAddr.
310706f2543Smrg * Higher level functions must call this routine rather than
311706f2543Smrg * I2CStart/PutByte because a hardware I2C master may not be able
312706f2543Smrg * to send a slave address without a start condition.
313706f2543Smrg *
314706f2543Smrg * The same timeouts apply as with I2CPutByte and additional a
315706f2543Smrg * StartTimeout, similar to the ByteTimeout but for the start
316706f2543Smrg * condition.
317706f2543Smrg *
318706f2543Smrg * In case of a timeout, the bus is left in a clean idle condition.
319706f2543Smrg * I. e. you *must not* send a Stop. If this function succeeds, you *must*.
320706f2543Smrg *
321706f2543Smrg * The slave address format is 16 bit, with the legacy _8_bit_ slave address
322706f2543Smrg * in the least significant byte. This is, the slave address must include the
323706f2543Smrg * R/_W flag as least significant bit.
324706f2543Smrg *
325706f2543Smrg * The most significant byte of the address will be sent _after_ the LSB,
326706f2543Smrg * but only if the LSB indicates:
327706f2543Smrg * a) an 11 bit address, this is LSB = 1111 0xxx.
328706f2543Smrg * b) a 'general call address', this is LSB = 0000 000x - see the I2C specs
329706f2543Smrg *    for more.
330706f2543Smrg */
331706f2543Smrg
332706f2543Smrgstatic Bool
333706f2543SmrgI2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
334706f2543Smrg{
335706f2543Smrg    if (I2CStart(d->pI2CBus, d->StartTimeout)) {
336706f2543Smrg	if (I2CPutByte(d, addr & 0xFF)) {
337706f2543Smrg	    if ((addr & 0xF8) != 0xF0 &&
338706f2543Smrg		(addr & 0xFE) != 0x00)
339706f2543Smrg		return TRUE;
340706f2543Smrg
341706f2543Smrg	    if (I2CPutByte(d, (addr >> 8) & 0xFF))
342706f2543Smrg		return TRUE;
343706f2543Smrg	}
344706f2543Smrg
345706f2543Smrg	I2CStop(d);
346706f2543Smrg    }
347706f2543Smrg
348706f2543Smrg    return FALSE;
349706f2543Smrg}
350706f2543Smrg
351706f2543Smrg/* These are the hardware independent I2C helper functions.
352706f2543Smrg * ========================================================
353706f2543Smrg */
354706f2543Smrg
355706f2543Smrg/* Function for probing. Just send the slave address
356706f2543Smrg * and return true if the device responds. The slave address
357706f2543Smrg * must have the lsb set to reflect a read (1) or write (0) access.
358706f2543Smrg * Don't expect a read- or write-only device will respond otherwise.
359706f2543Smrg */
360706f2543Smrg
361706f2543SmrgBool
362706f2543Smrgxf86I2CProbeAddress(I2CBusPtr b, I2CSlaveAddr addr)
363706f2543Smrg{
364706f2543Smrg    int r;
365706f2543Smrg    I2CDevRec d;
366706f2543Smrg
367706f2543Smrg    d.DevName = "Probing";
368706f2543Smrg    d.BitTimeout = b->BitTimeout;
369706f2543Smrg    d.ByteTimeout = b->ByteTimeout;
370706f2543Smrg    d.AcknTimeout = b->AcknTimeout;
371706f2543Smrg    d.StartTimeout = b->StartTimeout;
372706f2543Smrg    d.SlaveAddr = addr;
373706f2543Smrg    d.pI2CBus = b;
374706f2543Smrg    d.NextDev = NULL;
375706f2543Smrg
376706f2543Smrg    r = b->I2CAddress(&d, addr);
377706f2543Smrg
378706f2543Smrg    if (r) b->I2CStop(&d);
379706f2543Smrg
380706f2543Smrg    return r;
381706f2543Smrg}
382706f2543Smrg
383706f2543Smrg/* All functions below are related to devices and take the
384706f2543Smrg * slave address and timeout values from an I2CDevRec. They
385706f2543Smrg * return FALSE in case of an error (presumably a timeout).
386706f2543Smrg */
387706f2543Smrg
388706f2543Smrg/* General purpose read and write function.
389706f2543Smrg *
390706f2543Smrg * 1st, if nWrite > 0
391706f2543Smrg *   Send a start condition
392706f2543Smrg *   Send the slave address (1 or 2 bytes) with write flag
393706f2543Smrg *   Write n bytes from WriteBuffer
394706f2543Smrg * 2nd, if nRead > 0
395706f2543Smrg *   Send a start condition [again]
396706f2543Smrg *   Send the slave address (1 or 2 bytes) with read flag
397706f2543Smrg *   Read n bytes to ReadBuffer
398706f2543Smrg * 3rd, if a Start condition has been successfully sent,
399706f2543Smrg *   Send a Stop condition.
400706f2543Smrg *
401706f2543Smrg * The functions exits immediately when an error occures,
402706f2543Smrg * not proceeding any data left. However, step 3 will
403706f2543Smrg * be executed anyway to leave the bus in clean idle state.
404706f2543Smrg */
405706f2543Smrg
406706f2543Smrgstatic Bool
407706f2543SmrgI2CWriteRead(I2CDevPtr d,
408706f2543Smrg		 I2CByte *WriteBuffer, int nWrite,
409706f2543Smrg		 I2CByte *ReadBuffer,  int nRead)
410706f2543Smrg{
411706f2543Smrg    Bool r = TRUE;
412706f2543Smrg    I2CBusPtr b = d->pI2CBus;
413706f2543Smrg    int s = 0;
414706f2543Smrg
415706f2543Smrg    if (r && nWrite > 0) {
416706f2543Smrg	r = b->I2CAddress(d, d->SlaveAddr & ~1);
417706f2543Smrg	if (r) {
418706f2543Smrg	    for (; nWrite > 0; WriteBuffer++, nWrite--)
419706f2543Smrg		if (!(r = b->I2CPutByte(d, *WriteBuffer)))
420706f2543Smrg		    break;
421706f2543Smrg	    s++;
422706f2543Smrg	}
423706f2543Smrg    }
424706f2543Smrg
425706f2543Smrg    if (r && nRead > 0) {
426706f2543Smrg	r = b->I2CAddress(d, d->SlaveAddr | 1);
427706f2543Smrg	if (r) {
428706f2543Smrg	    for (; nRead > 0; ReadBuffer++, nRead--)
429706f2543Smrg		if (!(r = b->I2CGetByte(d, ReadBuffer, nRead == 1)))
430706f2543Smrg		    break;
431706f2543Smrg	    s++;
432706f2543Smrg	}
433706f2543Smrg    }
434706f2543Smrg
435706f2543Smrg    if (s) b->I2CStop(d);
436706f2543Smrg
437706f2543Smrg    return r;
438706f2543Smrg}
439706f2543Smrg
440706f2543Smrg/* wrapper - for compatibility and convinience */
441706f2543Smrg
442706f2543SmrgBool
443706f2543Smrgxf86I2CWriteRead(I2CDevPtr d,
444706f2543Smrg		 I2CByte *WriteBuffer, int nWrite,
445706f2543Smrg		 I2CByte *ReadBuffer,  int nRead)
446706f2543Smrg{
447706f2543Smrg    I2CBusPtr b = d->pI2CBus;
448706f2543Smrg    return b->I2CWriteRead(d,WriteBuffer,nWrite,ReadBuffer,nRead);
449706f2543Smrg}
450706f2543Smrg
451706f2543Smrg/* Read a byte, the only readable register of a device.
452706f2543Smrg */
453706f2543Smrg
454706f2543SmrgBool
455706f2543Smrgxf86I2CReadStatus(I2CDevPtr d, I2CByte *pbyte)
456706f2543Smrg{
457706f2543Smrg    return xf86I2CWriteRead(d, NULL, 0, pbyte, 1);
458706f2543Smrg}
459706f2543Smrg
460706f2543Smrg/* Read a byte from one of the registers determined by its sub-address.
461706f2543Smrg */
462706f2543Smrg
463706f2543SmrgBool
464706f2543Smrgxf86I2CReadByte(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte)
465706f2543Smrg{
466706f2543Smrg    return xf86I2CWriteRead(d, &subaddr, 1, pbyte, 1);
467706f2543Smrg}
468706f2543Smrg
469706f2543Smrg/* Read bytes from subsequent registers determined by the
470706f2543Smrg * sub-address of the first register.
471706f2543Smrg */
472706f2543Smrg
473706f2543SmrgBool
474706f2543Smrgxf86I2CReadBytes(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte, int n)
475706f2543Smrg{
476706f2543Smrg    return xf86I2CWriteRead(d, &subaddr, 1, pbyte, n);
477706f2543Smrg}
478706f2543Smrg
479706f2543Smrg/* Read a word (high byte, then low byte) from one of the registers
480706f2543Smrg * determined by its sub-address.
481706f2543Smrg */
482706f2543Smrg
483706f2543SmrgBool
484706f2543Smrgxf86I2CReadWord(I2CDevPtr d, I2CByte subaddr, unsigned short *pword)
485706f2543Smrg{
486706f2543Smrg    I2CByte rb[2];
487706f2543Smrg
488706f2543Smrg    if (!xf86I2CWriteRead(d, &subaddr, 1, rb, 2)) return FALSE;
489706f2543Smrg
490706f2543Smrg    *pword = (rb[0] << 8) | rb[1];
491706f2543Smrg
492706f2543Smrg    return TRUE;
493706f2543Smrg}
494706f2543Smrg
495706f2543Smrg/* Write a byte to one of the registers determined by its sub-address.
496706f2543Smrg */
497706f2543Smrg
498706f2543SmrgBool
499706f2543Smrgxf86I2CWriteByte(I2CDevPtr d, I2CByte subaddr, I2CByte byte)
500706f2543Smrg{
501706f2543Smrg    I2CByte wb[2];
502706f2543Smrg
503706f2543Smrg    wb[0] = subaddr;
504706f2543Smrg    wb[1] = byte;
505706f2543Smrg
506706f2543Smrg    return xf86I2CWriteRead(d, wb, 2, NULL, 0);
507706f2543Smrg}
508706f2543Smrg
509706f2543Smrg/* Write bytes to subsequent registers determined by the
510706f2543Smrg * sub-address of the first register.
511706f2543Smrg */
512706f2543Smrg
513706f2543SmrgBool
514706f2543Smrgxf86I2CWriteBytes(I2CDevPtr d, I2CByte subaddr,
515706f2543Smrg		  I2CByte *WriteBuffer, int nWrite)
516706f2543Smrg{
517706f2543Smrg    I2CBusPtr b = d->pI2CBus;
518706f2543Smrg    Bool r = TRUE;
519706f2543Smrg
520706f2543Smrg    if (nWrite > 0) {
521706f2543Smrg	r = b->I2CAddress(d, d->SlaveAddr & ~1);
522706f2543Smrg	if (r){
523706f2543Smrg	    if ((r = b->I2CPutByte(d, subaddr)))
524706f2543Smrg		for (; nWrite > 0; WriteBuffer++, nWrite--)
525706f2543Smrg		    if (!(r = b->I2CPutByte(d, *WriteBuffer)))
526706f2543Smrg			break;
527706f2543Smrg
528706f2543Smrg	    b->I2CStop(d);
529706f2543Smrg	}
530706f2543Smrg    }
531706f2543Smrg
532706f2543Smrg    return r;
533706f2543Smrg}
534706f2543Smrg
535706f2543Smrg/* Write a word (high byte, then low byte) to one of the registers
536706f2543Smrg * determined by its sub-address.
537706f2543Smrg */
538706f2543Smrg
539706f2543SmrgBool
540706f2543Smrgxf86I2CWriteWord(I2CDevPtr d, I2CByte subaddr, unsigned short word)
541706f2543Smrg{
542706f2543Smrg    I2CByte wb[3];
543706f2543Smrg
544706f2543Smrg    wb[0] = subaddr;
545706f2543Smrg    wb[1] = word >> 8;
546706f2543Smrg    wb[2] = word & 0xFF;
547706f2543Smrg
548706f2543Smrg    return xf86I2CWriteRead(d, wb, 3, NULL, 0);
549706f2543Smrg}
550706f2543Smrg
551706f2543Smrg/* Write a vector of bytes to not adjacent registers. This vector is,
552706f2543Smrg * 1st byte sub-address, 2nd byte value, 3rd byte sub-address asf.
553706f2543Smrg * This function is intended to initialize devices. Note this function
554706f2543Smrg * exits immediately when an error occurs, some registers may
555706f2543Smrg * remain uninitialized.
556706f2543Smrg */
557706f2543Smrg
558706f2543SmrgBool
559706f2543Smrgxf86I2CWriteVec(I2CDevPtr d, I2CByte *vec, int nValues)
560706f2543Smrg{
561706f2543Smrg    I2CBusPtr b = d->pI2CBus;
562706f2543Smrg    Bool r = TRUE;
563706f2543Smrg    int s = 0;
564706f2543Smrg
565706f2543Smrg    if (nValues > 0) {
566706f2543Smrg	for (; nValues > 0; nValues--, vec += 2) {
567706f2543Smrg	    if (!(r = b->I2CAddress(d, d->SlaveAddr & ~1)))
568706f2543Smrg	    	break;
569706f2543Smrg
570706f2543Smrg	    s++;
571706f2543Smrg
572706f2543Smrg	    if (!(r = b->I2CPutByte(d, vec[0])))
573706f2543Smrg		break;
574706f2543Smrg
575706f2543Smrg	    if (!(r = b->I2CPutByte(d, vec[1])))
576706f2543Smrg		break;
577706f2543Smrg	}
578706f2543Smrg
579706f2543Smrg	if (s > 0) b->I2CStop(d);
580706f2543Smrg    }
581706f2543Smrg
582706f2543Smrg    return r;
583706f2543Smrg}
584706f2543Smrg
585706f2543Smrg/* Administrative functions.
586706f2543Smrg * =========================
587706f2543Smrg */
588706f2543Smrg
589706f2543Smrg/* Allocates an I2CDevRec for you and initializes with propper defaults
590706f2543Smrg * you may modify before calling xf86I2CDevInit. Your I2CDevRec must
591706f2543Smrg * contain at least a SlaveAddr, and a pI2CBus pointer to the bus this
592706f2543Smrg * device shall be linked to.
593706f2543Smrg *
594706f2543Smrg * See function I2CAddress for the slave address format. Always set
595706f2543Smrg * the least significant bit, indicating a read or write access, to zero.
596706f2543Smrg */
597706f2543Smrg
598706f2543SmrgI2CDevPtr
599706f2543Smrgxf86CreateI2CDevRec(void)
600706f2543Smrg{
601706f2543Smrg    return calloc(1, sizeof(I2CDevRec));
602706f2543Smrg}
603706f2543Smrg
604706f2543Smrg/* Unlink an I2C device. If you got the I2CDevRec from xf86CreateI2CDevRec
605706f2543Smrg * you should set <unalloc> to free it.
606706f2543Smrg */
607706f2543Smrg
608706f2543Smrgvoid
609706f2543Smrgxf86DestroyI2CDevRec(I2CDevPtr d, Bool unalloc)
610706f2543Smrg{
611706f2543Smrg    if (d) {
612706f2543Smrg	I2CDevPtr *p;
613706f2543Smrg
614706f2543Smrg	/* Remove this from the list of active I2C devices. */
615706f2543Smrg
616706f2543Smrg	for (p = &d->pI2CBus->FirstDev; *p != NULL; p = &(*p)->NextDev)
617706f2543Smrg	    if (*p == d) {
618706f2543Smrg		*p = (*p)->NextDev;
619706f2543Smrg		break;
620706f2543Smrg	    }
621706f2543Smrg
622706f2543Smrg	xf86DrvMsg(d->pI2CBus->scrnIndex, X_INFO,
623706f2543Smrg		   "I2C device \"%s:%s\" removed.\n",
624706f2543Smrg		   d->pI2CBus->BusName, d->DevName);
625706f2543Smrg
626706f2543Smrg	if (unalloc) free(d);
627706f2543Smrg    }
628706f2543Smrg}
629706f2543Smrg
630706f2543Smrg/* I2C transmissions are related to an I2CDevRec you must link to a
631706f2543Smrg * previously registered bus (see xf86I2CBusInit) before attempting
632706f2543Smrg * to read and write data. You may call xf86I2CProbeAddress first to
633706f2543Smrg * see if the device in question is present on this bus.
634706f2543Smrg *
635706f2543Smrg * xf86I2CDevInit will not allocate an I2CBusRec for you, instead you
636706f2543Smrg * may enter a pointer to a statically allocated I2CDevRec or the (modified)
637706f2543Smrg * result of xf86CreateI2CDevRec.
638706f2543Smrg *
639706f2543Smrg * If you don't specify timeouts for the device (n <= 0), it will inherit
640706f2543Smrg * the bus-wide defaults. The function returns TRUE on success.
641706f2543Smrg */
642706f2543Smrg
643706f2543SmrgBool
644706f2543Smrgxf86I2CDevInit(I2CDevPtr d)
645706f2543Smrg{
646706f2543Smrg    I2CBusPtr b;
647706f2543Smrg
648706f2543Smrg    if (d == NULL ||
649706f2543Smrg	(b = d->pI2CBus) == NULL ||
650706f2543Smrg        (d->SlaveAddr & 1) ||
651706f2543Smrg        xf86I2CFindDev(b, d->SlaveAddr) != NULL)
652706f2543Smrg	return FALSE;
653706f2543Smrg
654706f2543Smrg    if (d->BitTimeout <= 0) d->BitTimeout = b->BitTimeout;
655706f2543Smrg    if (d->ByteTimeout <= 0) d->ByteTimeout = b->ByteTimeout;
656706f2543Smrg    if (d->AcknTimeout <= 0) d->AcknTimeout = b->AcknTimeout;
657706f2543Smrg    if (d->StartTimeout <= 0) d->StartTimeout = b->StartTimeout;
658706f2543Smrg
659706f2543Smrg    d->NextDev = b->FirstDev;
660706f2543Smrg    b->FirstDev = d;
661706f2543Smrg
662706f2543Smrg    xf86DrvMsg(b->scrnIndex, X_INFO,
663706f2543Smrg	       "I2C device \"%s:%s\" registered at address 0x%02X.\n",
664706f2543Smrg	       b->BusName, d->DevName, d->SlaveAddr);
665706f2543Smrg
666706f2543Smrg    return TRUE;
667706f2543Smrg}
668706f2543Smrg
669706f2543SmrgI2CDevPtr
670706f2543Smrgxf86I2CFindDev(I2CBusPtr b, I2CSlaveAddr addr)
671706f2543Smrg{
672706f2543Smrg    I2CDevPtr d;
673706f2543Smrg
674706f2543Smrg    if (b) {
675706f2543Smrg         for (d = b->FirstDev; d != NULL; d = d->NextDev)
676706f2543Smrg	    if (d->SlaveAddr == addr)
677706f2543Smrg		return d;
678706f2543Smrg    }
679706f2543Smrg
680706f2543Smrg    return NULL;
681706f2543Smrg}
682706f2543Smrg
683706f2543Smrgstatic I2CBusPtr I2CBusList;
684706f2543Smrg
685706f2543Smrg/* Allocates an I2CBusRec for you and initializes with propper defaults
686706f2543Smrg * you may modify before calling xf86I2CBusInit. Your I2CBusRec must
687706f2543Smrg * contain at least a BusName, a scrnIndex (or -1), and a complete set
688706f2543Smrg * of either high or low level I2C function pointers. You may pass
689706f2543Smrg * bus-wide timeouts, otherwise inplausible values will be replaced
690706f2543Smrg * with safe defaults.
691706f2543Smrg */
692706f2543Smrg
693706f2543SmrgI2CBusPtr
694706f2543Smrgxf86CreateI2CBusRec(void)
695706f2543Smrg{
696706f2543Smrg    I2CBusPtr b;
697706f2543Smrg
698706f2543Smrg    b = (I2CBusPtr) calloc(1, sizeof(I2CBusRec));
699706f2543Smrg
700706f2543Smrg    if (b != NULL) {
701706f2543Smrg	b->scrnIndex = -1;
702706f2543Smrg	b->HoldTime = 5; /* 100 kHz bus */
703706f2543Smrg	b->BitTimeout = 5;
704706f2543Smrg	b->ByteTimeout = 5;
705706f2543Smrg	b->AcknTimeout = 5;
706706f2543Smrg	b->StartTimeout = 5;
707706f2543Smrg	b->RiseFallTime = RISEFALLTIME;
708706f2543Smrg    }
709706f2543Smrg
710706f2543Smrg    return b;
711706f2543Smrg}
712706f2543Smrg
713706f2543Smrg/* Unregister an I2C bus. If you got the I2CBusRec from xf86CreateI2CBusRec
714706f2543Smrg * you should set <unalloc> to free it. If you set <devs_too>, the function
715706f2543Smrg * xf86DestroyI2CDevRec will be called for all devices linked to the bus
716706f2543Smrg * first, passing down the <unalloc> option.
717706f2543Smrg */
718706f2543Smrg
719706f2543Smrgvoid
720706f2543Smrgxf86DestroyI2CBusRec(I2CBusPtr b, Bool unalloc, Bool devs_too)
721706f2543Smrg{
722706f2543Smrg    if (b) {
723706f2543Smrg	I2CBusPtr *p;
724706f2543Smrg
725706f2543Smrg	/* Remove this from the list of active I2C buses */
726706f2543Smrg
727706f2543Smrg	for (p = &I2CBusList; *p != NULL; p = &(*p)->NextBus)
728706f2543Smrg	    if (*p == b) {
729706f2543Smrg		*p = (*p)->NextBus;
730706f2543Smrg		break;
731706f2543Smrg	    }
732706f2543Smrg
733706f2543Smrg	if (b->FirstDev != NULL) {
734706f2543Smrg	    if (devs_too) {
735706f2543Smrg		I2CDevPtr d;
736706f2543Smrg
737706f2543Smrg		while ((d = b->FirstDev) != NULL) {
738706f2543Smrg		    b->FirstDev = d->NextDev;
739706f2543Smrg		    xf86DestroyI2CDevRec(d, unalloc);
740706f2543Smrg		}
741706f2543Smrg	    } else {
742706f2543Smrg		if (unalloc) {
743706f2543Smrg		    xf86Msg(X_ERROR, "i2c bug: Attempt to remove I2C bus \"%s\", "
744706f2543Smrg			    "but device list is not empty.\n",
745706f2543Smrg			    b->BusName);
746706f2543Smrg		    return;
747706f2543Smrg		}
748706f2543Smrg	    }
749706f2543Smrg	}
750706f2543Smrg
751706f2543Smrg	xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" removed.\n",
752706f2543Smrg		   b->BusName);
753706f2543Smrg
754706f2543Smrg	if (unalloc) free(b);
755706f2543Smrg    }
756706f2543Smrg}
757706f2543Smrg
758706f2543Smrg/* I2C masters have to register themselves using this function.
759706f2543Smrg * It will not allocate an I2CBusRec for you, instead you may enter
760706f2543Smrg * a pointer to a statically allocated I2CBusRec or the (modified)
761706f2543Smrg * result of xf86CreateI2CBusRec. Returns TRUE on success.
762706f2543Smrg *
763706f2543Smrg * At this point there won't be any traffic on the I2C bus.
764706f2543Smrg */
765706f2543Smrg
766706f2543SmrgBool
767706f2543Smrgxf86I2CBusInit(I2CBusPtr b)
768706f2543Smrg{
769706f2543Smrg    /* I2C buses must be identified by a unique scrnIndex
770706f2543Smrg     * and name. If scrnIndex is unspecified (a negative value),
771706f2543Smrg     * then the name must be unique throughout the server.
772706f2543Smrg     */
773706f2543Smrg
774706f2543Smrg    if (b->BusName == NULL ||
775706f2543Smrg	xf86I2CFindBus(b->scrnIndex, b->BusName) != NULL)
776706f2543Smrg	return FALSE;
777706f2543Smrg
778706f2543Smrg    /* If the high level functions are not
779706f2543Smrg     * supplied, use the generic functions.
780706f2543Smrg     * In this case we need the low-level
781706f2543Smrg     * function.
782706f2543Smrg     */
783706f2543Smrg    if (b->I2CWriteRead == NULL)
784706f2543Smrg    {
785706f2543Smrg        b->I2CWriteRead=I2CWriteRead;
786706f2543Smrg
787706f2543Smrg        if (b->I2CPutBits == NULL ||
788706f2543Smrg	    b->I2CGetBits == NULL)
789706f2543Smrg        {
790706f2543Smrg	    if (b->I2CPutByte == NULL ||
791706f2543Smrg	        b->I2CGetByte == NULL ||
792706f2543Smrg	        b->I2CAddress == NULL ||
793706f2543Smrg	        b->I2CStart   == NULL ||
794706f2543Smrg	        b->I2CStop    == NULL)
795706f2543Smrg	        return FALSE;
796706f2543Smrg        } else {
797706f2543Smrg	    b->I2CPutByte = I2CPutByte;
798706f2543Smrg	    b->I2CGetByte = I2CGetByte;
799706f2543Smrg	    b->I2CAddress = I2CAddress;
800706f2543Smrg	    b->I2CStop    = I2CStop;
801706f2543Smrg	    b->I2CStart   = I2CStart;
802706f2543Smrg        }
803706f2543Smrg     }
804706f2543Smrg
805706f2543Smrg    if (b->I2CUDelay == NULL)
806706f2543Smrg	b->I2CUDelay = I2CUDelay;
807706f2543Smrg
808706f2543Smrg    if (b->HoldTime < 2) b->HoldTime = 5;
809706f2543Smrg    if (b->BitTimeout <= 0) b->BitTimeout = b->HoldTime;
810706f2543Smrg    if (b->ByteTimeout <= 0) b->ByteTimeout = b->HoldTime;
811706f2543Smrg    if (b->AcknTimeout <= 0) b->AcknTimeout = b->HoldTime;
812706f2543Smrg    if (b->StartTimeout <= 0) b->StartTimeout = b->HoldTime;
813706f2543Smrg
814706f2543Smrg    /* Put new bus on list. */
815706f2543Smrg
816706f2543Smrg    b->NextBus = I2CBusList;
817706f2543Smrg    I2CBusList = b;
818706f2543Smrg
819706f2543Smrg    xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" initialized.\n",
820706f2543Smrg	       b->BusName);
821706f2543Smrg
822706f2543Smrg    return TRUE;
823706f2543Smrg}
824706f2543Smrg
825706f2543SmrgI2CBusPtr
826706f2543Smrgxf86I2CFindBus(int scrnIndex, char *name)
827706f2543Smrg{
828706f2543Smrg    I2CBusPtr p;
829706f2543Smrg
830706f2543Smrg    if (name != NULL)
831706f2543Smrg	for (p = I2CBusList; p != NULL; p = p->NextBus)
832706f2543Smrg	    if (scrnIndex < 0 || p->scrnIndex == scrnIndex)
833706f2543Smrg		if (!strcmp(p->BusName, name))
834706f2543Smrg		    return p;
835706f2543Smrg
836706f2543Smrg    return NULL;
837706f2543Smrg}
838706f2543Smrg
839706f2543Smrg/*
840706f2543Smrg * Return an array of I2CBusPtr's related to a screen.  The caller is
841706f2543Smrg * responsible for freeing the array.
842706f2543Smrg */
843706f2543Smrgint
844706f2543Smrgxf86I2CGetScreenBuses(int scrnIndex, I2CBusPtr **pppI2CBus)
845706f2543Smrg{
846706f2543Smrg    I2CBusPtr pI2CBus;
847706f2543Smrg    int n = 0;
848706f2543Smrg
849706f2543Smrg    if (pppI2CBus)
850706f2543Smrg	*pppI2CBus = NULL;
851706f2543Smrg
852706f2543Smrg    for (pI2CBus = I2CBusList;  pI2CBus;  pI2CBus = pI2CBus->NextBus) {
853706f2543Smrg	if ((pI2CBus->scrnIndex >= 0) && (pI2CBus->scrnIndex != scrnIndex))
854706f2543Smrg	    continue;
855706f2543Smrg
856706f2543Smrg	n++;
857706f2543Smrg
858706f2543Smrg	if (!pppI2CBus)
859706f2543Smrg	    continue;
860706f2543Smrg
861706f2543Smrg        *pppI2CBus = xnfrealloc(*pppI2CBus, n * sizeof(I2CBusPtr));
862706f2543Smrg	(*pppI2CBus)[n - 1] = pI2CBus;
863706f2543Smrg    }
864706f2543Smrg
865706f2543Smrg    return n;
866706f2543Smrg}
867