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