unsigned char * GetEDID_DDC1(unsigned int *s_ptr) { unsigned char *d_block, *d_pos; unsigned int *s_pos, *s_end; int s_start; int i,j; s_start = find_start(s_ptr); if (s_start==-1) return NULL; s_end = s_ptr + NUM; s_pos = s_ptr + s_start; d_block=xalloc(EDID1_LEN); if (!d_block) return NULL; d_pos = d_block; for (i=0;i<EDID1_LEN;i++) { for (j=0;j<8;j++) { *d_pos <<= 1; if (*s_pos) { *d_pos |= 0x01; } s_pos++; if (s_pos == s_end) s_pos=s_ptr; }; s_pos++; if (s_pos == s_end) s_pos=s_ptr; d_pos++; } xfree(s_ptr); if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL; return (resort(d_block)); }
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; }
/* 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; }