/* block is the EDID block number. a segment is two blocks. */ static Bool DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer) { unsigned char W_Buffer[1]; int i, segment; I2CDevPtr seg; void (*stop) (I2CDevPtr); for (i = 0; i < RETRIES; i++) { /* Stop bits reset the segment pointer to 0, so be careful here. */ segment = block >> 1; if (segment) { Bool b; if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060))) return FALSE; W_Buffer[0] = segment; stop = dev->pI2CBus->I2CStop; dev->pI2CBus->I2CStop = EEDIDStop; b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0); dev->pI2CBus->I2CStop = stop; if (!b) { dev->pI2CBus->I2CStop(dev); continue; } } W_Buffer[0] = (block & 0x01) * EDID1_LEN; if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) { if (!DDC_checksum(R_Buffer, EDID1_LEN)) return TRUE; } } return FALSE; }
static unsigned char * DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) { I2CDevPtr dev; unsigned char W_Buffer[2]; int w_bytes; unsigned char *R_Buffer; int i; xf86LoaderReqSymLists(i2cSymbols, NULL); dev = xf86CreateI2CDevRec(); dev->DevName = "ddc2"; dev->SlaveAddr = 0xA0; dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ dev->StartTimeout = 550; dev->BitTimeout = 40; dev->ByteTimeout = 40; dev->AcknTimeout = 40; dev->pI2CBus = pBus; if (! xf86I2CDevInit(dev)) { xf86DrvMsg(X_PROBED,scrnIndex,"No DDC2 device\n"); return NULL; } if (start < 0x100) { w_bytes = 1; W_Buffer[0] = start; } else { w_bytes = 2; W_Buffer[0] = start & 0xFF; W_Buffer[1] = (start & 0xFF00) >> 8; } R_Buffer = xcalloc(1,sizeof(unsigned char) * (len)); for (i=0; i<RETRIES; i++) { if (xf86I2CWriteRead(dev, W_Buffer,w_bytes, R_Buffer,len)) { if (!DDC_checksum(R_Buffer,len)) { xf86DestroyI2CDevRec(dev,TRUE); return R_Buffer; } #ifdef DEBUG else ErrorF("Checksum error in EDID block\n"); #endif } #ifdef DEBUG else ErrorF("Error reading EDID block\n"); #endif } xf86DestroyI2CDevRec(dev,TRUE); xfree(R_Buffer); return NULL; }
static unsigned char * DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) { static char name[5] = "ddc2"; I2CDevPtr dev; unsigned char W_Buffer[2]; int w_bytes; unsigned char *R_Buffer; int i; if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) { dev = xf86CreateI2CDevRec(); dev->DevName = name; dev->SlaveAddr = 0xA0; dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ dev->StartTimeout = 550; dev->BitTimeout = 40; dev->ByteTimeout = 40; dev->AcknTimeout = 40; dev->pI2CBus = pBus; if (!xf86I2CDevInit(dev)) { LOG("No DDC2 device\n"); return NULL; } } if (start < 0x100) { w_bytes = 1; W_Buffer[0] = start; } else { w_bytes = 2; W_Buffer[0] = start & 0xFF; W_Buffer[1] = (start & 0xFF00) >> 8; } R_Buffer = (unsigned char *)IOMalloc(sizeof(unsigned char) * len); if (!R_Buffer) return NULL; bzero(R_Buffer, sizeof(unsigned char) * len); for (i=0; i<RETRIES; i++) { if (xf86I2CWriteRead(dev, W_Buffer,w_bytes, R_Buffer,len)) { if (!DDC_checksum(R_Buffer,len)) return R_Buffer; else LOGV("Checksum error in EDID block\n"); } else LOGV("Error reading EDID block\n"); } xf86DestroyI2CDevRec(dev,TRUE); IOFree(R_Buffer, sizeof(unsigned char) * len); return NULL; }