1dfe64dd3Smacallan/* Jong 03/12/2009; added for supporting Xorg 7.0 */ 2dfe64dd3Smacallan#ifdef HAVE_CONFIG_H 3dfe64dd3Smacallan#include "config.h" 4dfe64dd3Smacallan#endif 5dfe64dd3Smacallan 6098ad5bdSmacallan#include <unistd.h> 7dfe64dd3Smacallan#include "osdef.h" 8dfe64dd3Smacallan#include "vgatypes.h" 9dfe64dd3Smacallan/* #include "vb_util.h" */ /* Jong@08032009 */ 10dfe64dd3Smacallan#include "vb_def.h" 11dfe64dd3Smacallan 12dfe64dd3Smacallan#ifdef WIN2000 13dfe64dd3Smacallan#include <dderror.h> 14dfe64dd3Smacallan#include <devioctl.h> 15dfe64dd3Smacallan#include <miniport.h> 16dfe64dd3Smacallan#include <ntddvdeo.h> 17dfe64dd3Smacallan#include <video.h> 18dfe64dd3Smacallan#include "xgiv.h" 19dfe64dd3Smacallan#include "dd_i2c.h" 20dfe64dd3Smacallan#include "tools.h" 21dfe64dd3Smacallan#endif /* WIN2000 */ 22dfe64dd3Smacallan 23dfe64dd3Smacallan#ifdef LINUX_XF86 24dfe64dd3Smacallan#include "xf86.h" 25dfe64dd3Smacallan#include "xf86PciInfo.h" 26dfe64dd3Smacallan#include "xgi.h" 27dfe64dd3Smacallan#include "xgi_regs.h" 28dfe64dd3Smacallan#include "vb_i2c.h" 29dfe64dd3Smacallan#endif 30dfe64dd3Smacallan 31dfe64dd3Smacallan#ifdef LINUX_KERNEL 32dfe64dd3Smacallan#include <linux/version.h> 33dfe64dd3Smacallan#include <asm/io.h> 34dfe64dd3Smacallan#include <linux/types.h> 35dfe64dd3Smacallan#include "vb_i2c.h" 36dfe64dd3Smacallan 37dfe64dd3Smacallan/* Jong@08052009 */ 38dfe64dd3Smacallan/* #include <linux/delay.h> */ /* udelay */ 39dfe64dd3Smacallan 40dfe64dd3Smacallan#include "XGIfb.h" 41dfe64dd3Smacallan 42dfe64dd3Smacallan#endif 43dfe64dd3Smacallan 44dfe64dd3Smacallan 45dfe64dd3Smacallan 46dfe64dd3Smacallan/*char I2CAccessBuffer(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl I2CCntl, ULONG DevAddr, ULONG Offset, PUCHAR pBuffer, ULONG ulSize); */ 47dfe64dd3Smacallanchar vGetEDIDExtensionBlocks(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2C, PUCHAR pjBuffer, ULONG ulBufferSize); 48dfe64dd3Smacallanchar vGetEnhancedEDIDBlock(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2C, ULONG ulBlockID, ULONG ulBlockTag, PUCHAR pjBuffer, ULONG ulBufferSize); 49dfe64dd3Smacallan 50dfe64dd3Smacallanchar I2COpen (PXGI_HW_DEVICE_INFO pHWDE,ULONG ulI2CEnable, ULONG ulChannelID, PI2CControl pI2CControl); 51dfe64dd3Smacallanchar I2CAccess(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 52dfe64dd3SmacallanBOOLEAN I2CNull( PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 53dfe64dd3SmacallanBOOLEAN I2CRead(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 54dfe64dd3SmacallanBOOLEAN I2CWrite(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 55dfe64dd3SmacallanBOOLEAN ResetI2C(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 56dfe64dd3SmacallanBOOLEAN I2CRead(PXGI_HW_DEVICE_INFO pHWDE,PI2CControl pI2CControl); 57dfe64dd3SmacallanBOOLEAN I2CWrite(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 58dfe64dd3SmacallanBOOLEAN ResetI2C(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl); 59dfe64dd3SmacallanBOOLEAN Ack (PXGI_HW_DEVICE_INFO pHWDE, bool fPut); 60dfe64dd3SmacallanBOOLEAN NoAck(PXGI_HW_DEVICE_INFO pHWDE); 61dfe64dd3SmacallanBOOLEAN Start( PXGI_HW_DEVICE_INFO pHWDE); 62dfe64dd3SmacallanBOOLEAN Stop(PXGI_HW_DEVICE_INFO pHWDE); 63dfe64dd3SmacallanBOOLEAN WriteUCHARI2C(PXGI_HW_DEVICE_INFO pHWDE, UCHAR cData); 64dfe64dd3SmacallanBOOLEAN ReadUCHARI2C(PXGI_HW_DEVICE_INFO pHWDE, PUCHAR pBuffer); 65dfe64dd3SmacallanUCHAR ReverseUCHAR(UCHAR data); 66dfe64dd3Smacallan 67dfe64dd3SmacallanVOID vWriteClockLineDVI(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 68dfe64dd3SmacallanVOID vWriteDataLineDVI(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 69dfe64dd3SmacallanBOOLEAN bReadClockLineDVI(PXGI_HW_DEVICE_INFO pHWDE); 70dfe64dd3SmacallanBOOLEAN bReadDataLineDVI(PXGI_HW_DEVICE_INFO pHWDE); 71dfe64dd3Smacallan 72dfe64dd3SmacallanBOOLEAN bEDIDCheckSum(PUCHAR pjEDIDBuf,ULONG ulBufSize); 73dfe64dd3Smacallan 74dfe64dd3SmacallanVOID vWriteClockLineCRT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 75dfe64dd3SmacallanVOID vWriteDataLineCRT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 76dfe64dd3SmacallanBOOLEAN bReadClockLineCRT(PXGI_HW_DEVICE_INFO pHWDE); 77dfe64dd3SmacallanBOOLEAN bReadDataLineCRT(PXGI_HW_DEVICE_INFO pHWDE); 78dfe64dd3Smacallan 79dfe64dd3Smacallan/* Jong@08102009 */ 80dfe64dd3SmacallanVOID vWriteClockLineFCNT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 81dfe64dd3SmacallanVOID vWriteDataLineFCNT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 82dfe64dd3SmacallanBOOLEAN bReadClockLineFCNT(PXGI_HW_DEVICE_INFO pHWDE); 83dfe64dd3SmacallanBOOLEAN bReadDataLineFCNT(PXGI_HW_DEVICE_INFO pHWDE); 84dfe64dd3Smacallan 85dfe64dd3Smacallan/* #define CRT_I2C */ 86dfe64dd3SmacallanVOID vWriteClockLine(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 87dfe64dd3SmacallanVOID vWriteDataLine(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data); 88dfe64dd3SmacallanBOOLEAN bReadClockLine(PXGI_HW_DEVICE_INFO pHWDE); 89dfe64dd3SmacallanBOOLEAN bReadDataLine(PXGI_HW_DEVICE_INFO pHWDE); 90dfe64dd3Smacallan 91dfe64dd3Smacallan/* Jong@08052009 */ 92dfe64dd3Smacallanextern UCHAR XGI_GetRegByte(XGIIOADDRESS port); 93dfe64dd3Smacallan 94dfe64dd3Smacallan/* Jong@08052009 */ 95dfe64dd3Smacallanvoid I2C_DelayUS(ULONG MicroSeconds) 96dfe64dd3Smacallan{ 97dfe64dd3Smacallan ErrorF(""); 98dfe64dd3Smacallan /* udelay(MicroSeconds); */ 99dfe64dd3Smacallan} 100dfe64dd3Smacallan 101dfe64dd3Smacallan 102dfe64dd3Smacallantypedef enum _I2C_ACCESS_CMD 103dfe64dd3Smacallan{ 104dfe64dd3Smacallan I2C_WRITE = 0, 105dfe64dd3Smacallan I2C_READ 106dfe64dd3Smacallan/* Jong 08/18/2008; for XFree86 */ 107dfe64dd3Smacallan /* WRITE = 0, 108dfe64dd3Smacallan READ */ 109dfe64dd3Smacallan} I2C_ACCESS_CMD; 110dfe64dd3Smacallan 111dfe64dd3Smacallan/* For XG21 */ 112dfe64dd3Smacallan 113dfe64dd3Smacallan#define ENABLE_GPIOA 0x01 114dfe64dd3Smacallan#define ENABLE_GPIOB 0x02 115dfe64dd3Smacallan#define ENABLE_GPIOC 0x04 116dfe64dd3SmacallanVOID 117dfe64dd3SmacallanEnableGPIOA( 118098ad5bdSmacallanXGIIOADDRESS pjIOPort, I2C_ACCESS_CMD CmdType) 119dfe64dd3Smacallan{ 120dfe64dd3Smacallan PDEBUGI2C(ErrorF("EnableGPIOA()-pjIOPort=0x%x...\n", pjIOPort)); 121dfe64dd3Smacallan 122dfe64dd3Smacallan UCHAR ujCR4A = XGI_GetReg(pjIOPort, IND_CR4A_GPIO_REG_III); 123dfe64dd3Smacallan 124dfe64dd3Smacallan if (CmdType == I2C_WRITE) 125dfe64dd3Smacallan { 126dfe64dd3Smacallan ujCR4A &= ~ENABLE_GPIOA; 127dfe64dd3Smacallan } 128dfe64dd3Smacallan else 129dfe64dd3Smacallan { 130dfe64dd3Smacallan ujCR4A |= ENABLE_GPIOA; 131dfe64dd3Smacallan } 132dfe64dd3Smacallan 133dfe64dd3Smacallan XGI_SetReg(pjIOPort, IND_CR4A_GPIO_REG_III, ujCR4A); 134dfe64dd3Smacallan} 135dfe64dd3Smacallan 136dfe64dd3SmacallanVOID 137dfe64dd3SmacallanEnableGPIOB( 138098ad5bdSmacallanXGIIOADDRESS pjIOPort, I2C_ACCESS_CMD CmdType) 139dfe64dd3Smacallan{ 140dfe64dd3Smacallan UCHAR ujCR4A = XGI_GetReg(pjIOPort, IND_CR4A_GPIO_REG_III); 141dfe64dd3Smacallan 142dfe64dd3Smacallan if (CmdType == I2C_WRITE) 143dfe64dd3Smacallan { 144dfe64dd3Smacallan ujCR4A &= ~ENABLE_GPIOB; 145dfe64dd3Smacallan } 146dfe64dd3Smacallan else 147dfe64dd3Smacallan { 148dfe64dd3Smacallan ujCR4A |= ENABLE_GPIOB; 149dfe64dd3Smacallan } 150dfe64dd3Smacallan 151dfe64dd3Smacallan XGI_SetReg(pjIOPort, IND_CR4A_GPIO_REG_III, ujCR4A); 152dfe64dd3Smacallan} 153dfe64dd3Smacallan 154dfe64dd3SmacallanVOID 155dfe64dd3SmacallanEnableGPIOC( 156098ad5bdSmacallanXGIIOADDRESS pjIOPort, I2C_ACCESS_CMD CmdType) 157dfe64dd3Smacallan{ 158dfe64dd3Smacallan UCHAR ujCR4A = XGI_GetReg(pjIOPort, IND_CR4A_GPIO_REG_III); 159dfe64dd3Smacallan 160dfe64dd3Smacallan if (CmdType == I2C_WRITE) 161dfe64dd3Smacallan { 162dfe64dd3Smacallan ujCR4A &= ~ENABLE_GPIOC; 163dfe64dd3Smacallan } 164dfe64dd3Smacallan else 165dfe64dd3Smacallan { 166dfe64dd3Smacallan ujCR4A |= ENABLE_GPIOC; 167dfe64dd3Smacallan } 168dfe64dd3Smacallan 169dfe64dd3Smacallan XGI_SetReg(pjIOPort, IND_CR4A_GPIO_REG_III, ujCR4A); 170dfe64dd3Smacallan} 171dfe64dd3Smacallan 172dfe64dd3Smacallan 173dfe64dd3Smacallan 174dfe64dd3Smacallan 175dfe64dd3Smacallan/** 176dfe64dd3Smacallan* Function: getGPIORWTranser() 177dfe64dd3Smacallan* 178dfe64dd3Smacallan* Description: This function is used based on Z9. Because of wrongly wired deployment by HW 179dfe64dd3Smacallan* the CR4A and CR48 for GPIO pins have reverse sequence. For example, 180dfe64dd3Smacallan* D[7:0] for read function is ordered as GPIOA to GPIOH, but D[7:0] for read 181dfe64dd3Smacallan* is as GPIOH~GPIOA 182dfe64dd3Smacallan*/ 183dfe64dd3SmacallanUCHAR 184dfe64dd3SmacallangetGPIORWTransfer( 185dfe64dd3SmacallanUCHAR ujDate) 186dfe64dd3Smacallan{ 187dfe64dd3Smacallan UCHAR ujRet = 0; 188dfe64dd3Smacallan UCHAR i = 0; 189dfe64dd3Smacallan 190dfe64dd3Smacallan for (i=0; i<8; i++) 191dfe64dd3Smacallan { 192dfe64dd3Smacallan ujRet = ujRet << 1; 193dfe64dd3Smacallan ujRet |= GETBITS(ujDate >> i, 0:0); 194dfe64dd3Smacallan } 195dfe64dd3Smacallan 196dfe64dd3Smacallan return ujRet; 197dfe64dd3Smacallan} 198dfe64dd3Smacallan 199dfe64dd3Smacallan 200dfe64dd3Smacallan 201dfe64dd3Smacallanchar I2CAccessBuffer(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl, ULONG ulDevAddr, 202dfe64dd3Smacallan ULONG ulOffset, PUCHAR pBuffer,ULONG ulSize) 203dfe64dd3Smacallan{ 204dfe64dd3Smacallan 205dfe64dd3Smacallan I2CControl I2C; 206dfe64dd3Smacallan ULONG i; 207dfe64dd3Smacallan 208dfe64dd3Smacallan if ((ulSize == 0) || (pBuffer == NULL)) { 209dfe64dd3Smacallan return -1; 210dfe64dd3Smacallan } 211dfe64dd3Smacallan if (ulDevAddr & 1) { 212dfe64dd3Smacallan return -1; 213dfe64dd3Smacallan } 214dfe64dd3Smacallan if ((ulDevAddr > 0xFF) || (ulOffset > 0xFF)) { 215dfe64dd3Smacallan return -1; 216dfe64dd3Smacallan } 217dfe64dd3Smacallan 218dfe64dd3Smacallan I2C.Command = pI2CControl->Command; 219dfe64dd3Smacallan I2C.dwCookie = pI2CControl->dwCookie; 220dfe64dd3Smacallan I2C.Data = pI2CControl->Data; 221dfe64dd3Smacallan I2C. Flags = pI2CControl->Flags; 222dfe64dd3Smacallan I2C.Status = pI2CControl->Status; 223dfe64dd3Smacallan I2C.ClockRate = pI2CControl->ClockRate; 224dfe64dd3Smacallan switch (pI2CControl->Command) { 225dfe64dd3Smacallan case I2C_COMMAND_READ: 226dfe64dd3Smacallan /* Reset I2C Bus */ 227dfe64dd3Smacallan I2C.Command = I2C_COMMAND_RESET; 228dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 229dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 230dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 231dfe64dd3Smacallan break; 232dfe64dd3Smacallan } 233dfe64dd3Smacallan 234dfe64dd3Smacallan /* Write Device Address */ 235dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 236dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_START | I2C_FLAGS_ACK; 237dfe64dd3Smacallan I2C.Data = (UCHAR)ulDevAddr; 238dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 239dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 240dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 241dfe64dd3Smacallan break; 242dfe64dd3Smacallan } 243dfe64dd3Smacallan 244dfe64dd3Smacallan /* Write Register Offset */ 245dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 246dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_ACK | I2C_FLAGS_STOP; 247dfe64dd3Smacallan I2C.Data = (UCHAR)ulOffset; 248dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 249dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 250dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 251dfe64dd3Smacallan break; 252dfe64dd3Smacallan } 253dfe64dd3Smacallan 254dfe64dd3Smacallan /* Write Device Read Address */ 255dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 256dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_START | I2C_FLAGS_ACK; 257dfe64dd3Smacallan I2C.Data = (UCHAR)ulDevAddr + 1; 258dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 259dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 260dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 261dfe64dd3Smacallan break; 262dfe64dd3Smacallan } 263dfe64dd3Smacallan 264dfe64dd3Smacallan /* Read Data */ 265dfe64dd3Smacallan for (i=0; i< ulSize; i++) { 266dfe64dd3Smacallan I2C.Command = I2C_COMMAND_READ; 267dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_ACK; 268dfe64dd3Smacallan if (i == ulSize - 1) { /* Read Last UCHAR */ 269dfe64dd3Smacallan I2C.Flags |= I2C_FLAGS_STOP; 270dfe64dd3Smacallan } 271dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 272dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 273dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 274dfe64dd3Smacallan break; 275dfe64dd3Smacallan } 276dfe64dd3Smacallan *pBuffer = I2C.Data; 277dfe64dd3Smacallan pBuffer++; 278dfe64dd3Smacallan } 279dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 280dfe64dd3Smacallan break; 281dfe64dd3Smacallan 282dfe64dd3Smacallan case I2C_COMMAND_WRITE: 283dfe64dd3Smacallan /* Reset I2C Bus */ 284dfe64dd3Smacallan I2C.Command = I2C_COMMAND_RESET; 285dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 286dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 287dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 288dfe64dd3Smacallan break; 289dfe64dd3Smacallan } 290dfe64dd3Smacallan 291dfe64dd3Smacallan /* Write Device Address */ 292dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 293dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_START | I2C_FLAGS_ACK; 294dfe64dd3Smacallan I2C.Data = (UCHAR)ulDevAddr; 295dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 296dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 297dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 298dfe64dd3Smacallan break; 299dfe64dd3Smacallan } 300dfe64dd3Smacallan 301dfe64dd3Smacallan /* Write Register Offset */ 302dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 303dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_ACK; 304dfe64dd3Smacallan I2C.Data = (UCHAR)ulOffset; 305dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 306dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 307dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 308dfe64dd3Smacallan break; 309dfe64dd3Smacallan } 310dfe64dd3Smacallan 311dfe64dd3Smacallan /* Write Data */ 312dfe64dd3Smacallan for (i=0; i< ulSize; i++) { 313dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 314dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_ACK; 315dfe64dd3Smacallan if (i == ulSize - 1) { /* Read Last UCHAR */ 316dfe64dd3Smacallan I2C.Flags |= I2C_FLAGS_STOP; 317dfe64dd3Smacallan } 318dfe64dd3Smacallan I2C.Data = *pBuffer; 319dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 320dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) { 321dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 322dfe64dd3Smacallan break; 323dfe64dd3Smacallan } 324dfe64dd3Smacallan pBuffer++; 325dfe64dd3Smacallan } 326dfe64dd3Smacallan pI2CControl->Status = I2C.Status; 327dfe64dd3Smacallan break; 328dfe64dd3Smacallan } 329dfe64dd3Smacallan 330dfe64dd3Smacallan if (pI2CControl->Status == I2C_STATUS_NOERROR) 331dfe64dd3Smacallan { 332dfe64dd3Smacallan return 0; 333dfe64dd3Smacallan } 334dfe64dd3Smacallan else 335dfe64dd3Smacallan { 336dfe64dd3Smacallan return -1; 337dfe64dd3Smacallan } 338dfe64dd3Smacallan} 339dfe64dd3Smacallan 340dfe64dd3Smacallan 341dfe64dd3Smacallan/************************************************************************* 342dfe64dd3Smacallan// char vGetEDIDExtensionBlocks 343dfe64dd3Smacallan// 344dfe64dd3Smacallan// Routine Description: 345dfe64dd3Smacallan// Reads the extension part behind a 128KB block of EDID which is in 1.3 346dfe64dd3Smacallan// format. The extension part can be distributed into 128KB-blocks. 347dfe64dd3Smacallan// 348dfe64dd3Smacallan// Arguments: 349dfe64dd3Smacallan// pHWDE - Hardware extension object pointer 350dfe64dd3Smacallan// pI2C - I2C pointer 351dfe64dd3Smacallan// pjBuffer - EDID Buffer 352dfe64dd3Smacallan// ulBufferSize - Buffer size 353dfe64dd3Smacallan// 354dfe64dd3Smacallan// 355dfe64dd3Smacallan// Return Value: 356dfe64dd3Smacallan// Status of returning EDID. 357dfe64dd3Smacallan// NO_ERROR - success 358dfe64dd3Smacallan// ERROR_INVALID_PARAMETER - failed 359dfe64dd3Smacallan// 360dfe64dd3Smacallan****************************************************************************/ 361dfe64dd3Smacallanchar vGetEDIDExtensionBlocks( 362dfe64dd3Smacallan PXGI_HW_DEVICE_INFO pHWDE, 363dfe64dd3Smacallan PI2CControl pI2C, 364dfe64dd3Smacallan PUCHAR pjBuffer, 365dfe64dd3Smacallan ULONG ulBufferSize) 366dfe64dd3Smacallan{ 367dfe64dd3Smacallan char status; 368dfe64dd3Smacallan ULONG ulBlockTag; 369dfe64dd3Smacallan ULONG i; 370dfe64dd3Smacallan PUCHAR pBlockMap; 371dfe64dd3Smacallan 372dfe64dd3Smacallan 373dfe64dd3Smacallan if ((ulBufferSize < 128) || (pjBuffer == NULL)) 374dfe64dd3Smacallan { 375dfe64dd3Smacallan return -1; 376dfe64dd3Smacallan } 377dfe64dd3Smacallan 378dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_READ; 379dfe64dd3Smacallan status = I2CAccessBuffer(pHWDE, pI2C, 0xA0, 128, pjBuffer, 128); 380dfe64dd3Smacallan if ((status != 0) || (pI2C->Status != I2C_STATUS_NOERROR)) 381dfe64dd3Smacallan { 382dfe64dd3Smacallan return status; 383dfe64dd3Smacallan } 384dfe64dd3Smacallan 385dfe64dd3Smacallan if (bEDIDCheckSum(pjBuffer, 128) != 0) { 386dfe64dd3Smacallan return -1; 387dfe64dd3Smacallan } 388dfe64dd3Smacallan 389dfe64dd3Smacallan if (*pjBuffer == 0xF0) 390dfe64dd3Smacallan { /* A Block Map, we should read other extension blocks*/ 391dfe64dd3Smacallan pBlockMap = pjBuffer; 392dfe64dd3Smacallan for (i=1; i<=126; i++) 393dfe64dd3Smacallan { 394dfe64dd3Smacallan ulBlockTag = *(pBlockMap + i); 395dfe64dd3Smacallan if (ulBlockTag) 396dfe64dd3Smacallan { 397dfe64dd3Smacallan pjBuffer += 128; 398dfe64dd3Smacallan ulBufferSize -= 128; 399dfe64dd3Smacallan status = vGetEnhancedEDIDBlock(pHWDE, pI2C, i+1, ulBlockTag, pjBuffer, ulBufferSize); 400dfe64dd3Smacallan if ((status != 0) || (pI2C->Status != I2C_STATUS_NOERROR)) 401dfe64dd3Smacallan { 402dfe64dd3Smacallan return -1; 403dfe64dd3Smacallan } 404dfe64dd3Smacallan } 405dfe64dd3Smacallan else 406dfe64dd3Smacallan { 407dfe64dd3Smacallan if (i > 1) 408dfe64dd3Smacallan { 409dfe64dd3Smacallan return 0; /* All Extension blocks must be sequential, no holes allowed. (VESA E-EDID)*/ 410dfe64dd3Smacallan } 411dfe64dd3Smacallan else 412dfe64dd3Smacallan { 413dfe64dd3Smacallan return -1; 414dfe64dd3Smacallan } 415dfe64dd3Smacallan } 416dfe64dd3Smacallan } 417dfe64dd3Smacallan /* We should read block # 128 */ 418dfe64dd3Smacallan pjBuffer += 128; 419dfe64dd3Smacallan ulBufferSize -= 128; 420dfe64dd3Smacallan ulBlockTag = 0xF0; 421dfe64dd3Smacallan status = vGetEnhancedEDIDBlock(pHWDE, pI2C, 128, ulBlockTag, pjBuffer, ulBufferSize); 422dfe64dd3Smacallan if ((status != 0) || (pI2C->Status != I2C_STATUS_NOERROR)) 423dfe64dd3Smacallan { 424dfe64dd3Smacallan return 0; /* Monitor may has only 128 blocks (0~127) */ 425dfe64dd3Smacallan } 426dfe64dd3Smacallan 427dfe64dd3Smacallan pBlockMap = pjBuffer; 428dfe64dd3Smacallan for (i=1; i<=126; i++) 429dfe64dd3Smacallan { /* Read Block # 128 ~ 254 */ 430dfe64dd3Smacallan ulBlockTag = *(pBlockMap + i); 431dfe64dd3Smacallan if (ulBlockTag) 432dfe64dd3Smacallan { 433dfe64dd3Smacallan pjBuffer += 128; 434dfe64dd3Smacallan ulBufferSize -= 128; 435dfe64dd3Smacallan status = vGetEnhancedEDIDBlock(pHWDE, pI2C, i+128, ulBlockTag, pjBuffer, ulBufferSize); 436dfe64dd3Smacallan if ((status != 0) || (pI2C->Status != I2C_STATUS_NOERROR)) 437dfe64dd3Smacallan { 438dfe64dd3Smacallan return -1; 439dfe64dd3Smacallan } 440dfe64dd3Smacallan } 441dfe64dd3Smacallan else 442dfe64dd3Smacallan { 443dfe64dd3Smacallan if (i > 1) 444dfe64dd3Smacallan { 445dfe64dd3Smacallan return 0; /* All Extension blocks must be sequential, no holes allowed. (VESA E-EDID) */ 446dfe64dd3Smacallan } 447dfe64dd3Smacallan else 448dfe64dd3Smacallan { 449dfe64dd3Smacallan return -1; 450dfe64dd3Smacallan } 451dfe64dd3Smacallan } 452dfe64dd3Smacallan } 453dfe64dd3Smacallan } 454dfe64dd3Smacallan 455dfe64dd3Smacallan return 0; 456dfe64dd3Smacallan} 457dfe64dd3Smacallan 458dfe64dd3Smacallan/************************************************************************* 459dfe64dd3Smacallan// char vGetEnhancedEDIDBlock 460dfe64dd3Smacallan// 461dfe64dd3Smacallan// Routine Description: 462dfe64dd3Smacallan// Get the EDID which is in Enhanced-EDID format via I2C. The parse-in block 463dfe64dd3Smacallan// tag(ulBlockTag) and the first UCHAR of the retrieved buffer should be identical. 464dfe64dd3Smacallan// Returns error when they are not, otherwise return NO_ERROR. 465dfe64dd3Smacallan// 466dfe64dd3Smacallan// Arguments: 467dfe64dd3Smacallan// pHWDE - Hardware extension object pointer 468dfe64dd3Smacallan// pI2C - I2C pointer 469dfe64dd3Smacallan// ulBlockID - Block ID 470dfe64dd3Smacallan// ulBlockTag - Block Tag 471dfe64dd3Smacallan// pjBuffer - EDID Buffer 472dfe64dd3Smacallan// ulBufferSize - Buffer size 473dfe64dd3Smacallan// 474dfe64dd3Smacallan// 475dfe64dd3Smacallan// Return Value: 476dfe64dd3Smacallan// Status of returning EDID. 477dfe64dd3Smacallan// NO_ERROR - success 478dfe64dd3Smacallan// ERROR_INVALID_PARAMETER - failed 479dfe64dd3Smacallan// 480dfe64dd3Smacallan****************************************************************************/ 481dfe64dd3Smacallanchar vGetEnhancedEDIDBlock( 482dfe64dd3Smacallan PXGI_HW_DEVICE_INFO pHWDE, 483dfe64dd3Smacallan PI2CControl pI2C, 484dfe64dd3Smacallan ULONG ulBlockID, 485dfe64dd3Smacallan ULONG ulBlockTag, 486dfe64dd3Smacallan PUCHAR pjBuffer, 487dfe64dd3Smacallan ULONG ulBufferSize) 488dfe64dd3Smacallan{ 489dfe64dd3Smacallan ULONG ulOffset, SegmentID; 490dfe64dd3Smacallan char status; 491dfe64dd3Smacallan 492dfe64dd3Smacallan if ((ulBufferSize < 128) || (pjBuffer == NULL)) 493dfe64dd3Smacallan { 494dfe64dd3Smacallan return -1; 495dfe64dd3Smacallan } 496dfe64dd3Smacallan 497dfe64dd3Smacallan SegmentID = ulBlockID / 2; 498dfe64dd3Smacallan ulOffset = (ulBlockID % 2) * 128; 499dfe64dd3Smacallan 500dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_WRITE; 501dfe64dd3Smacallan status = I2CAccessBuffer(pHWDE, pI2C, 0x60, 0, (PUCHAR)&SegmentID, 1); 502dfe64dd3Smacallan if ((status == NO_ERROR) && (pI2C->Status == I2C_STATUS_NOERROR)) 503dfe64dd3Smacallan { 504dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_READ; 505dfe64dd3Smacallan status = I2CAccessBuffer(pHWDE, pI2C, 0xA0, ulOffset, pjBuffer, 128); 506dfe64dd3Smacallan if ((status == 0) && (pI2C->Status == I2C_STATUS_NOERROR)) 507dfe64dd3Smacallan { 508dfe64dd3Smacallan if (*pjBuffer != (UCHAR)ulBlockTag) 509dfe64dd3Smacallan { 510dfe64dd3Smacallan return -1; 511dfe64dd3Smacallan } 512dfe64dd3Smacallan 513dfe64dd3Smacallan if (bEDIDCheckSum(pjBuffer, 128) != 0) 514dfe64dd3Smacallan { 515dfe64dd3Smacallan return -1; 516dfe64dd3Smacallan } 517dfe64dd3Smacallan } 518dfe64dd3Smacallan else 519dfe64dd3Smacallan { 520dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 521dfe64dd3Smacallan } 522dfe64dd3Smacallan } 523dfe64dd3Smacallan else 524dfe64dd3Smacallan { 525dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 526dfe64dd3Smacallan } 527dfe64dd3Smacallan 528dfe64dd3Smacallan 529dfe64dd3Smacallan return NO_ERROR; 530dfe64dd3Smacallan} 531dfe64dd3Smacallanchar I2COpen (PXGI_HW_DEVICE_INFO pHWDE, ULONG ulI2CEnable, ULONG ulChannelID, PI2CControl pI2CControl) 532dfe64dd3Smacallan{ 533dfe64dd3Smacallan/* 534dfe64dd3Smacallan// printk("\nI2COpen(%d) : Channel ID = %d\n", ulI2CEnable, ulChannelID); 535dfe64dd3Smacallan // we need to determine the Context area for each command we receive 536dfe64dd3Smacallan // i.e. which hardware I2C bus is the command for. 537dfe64dd3Smacallan // this is unimplemented here! 538dfe64dd3Smacallan*/ 539dfe64dd3Smacallan if (ulChannelID >= MAX_I2C_CHANNEL) 540dfe64dd3Smacallan { 541dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 542dfe64dd3Smacallan } 543dfe64dd3Smacallan if (ulI2CEnable) /* Open I2C Port */ 544dfe64dd3Smacallan { 545dfe64dd3Smacallan/* // verify clock rate. If you cannot implement the given rate, 546dfe64dd3Smacallan // enable a lower clock rate closest to the request clock rate. 547dfe64dd3Smacallan // 548dfe64dd3Smacallan // put a better check here if your device can only do discrete 549dfe64dd3Smacallan // clock rate values. 550dfe64dd3Smacallan*/ 551dfe64dd3Smacallan if (pI2CControl->ClockRate > I2C_MAX_CLOCK_RATE) 552dfe64dd3Smacallan { 553dfe64dd3Smacallan pI2CControl->ClockRate = I2C_MAX_CLOCK_RATE; 554dfe64dd3Smacallan } 555dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 556dfe64dd3Smacallan } 557dfe64dd3Smacallan else /* Close I2C Port*/ 558dfe64dd3Smacallan { 559dfe64dd3Smacallan /* Set Acquired state to FALSE */ 560dfe64dd3Smacallan 561dfe64dd3Smacallan pI2CControl->dwCookie = 0; 562dfe64dd3Smacallan /* Set status */ 563dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 564dfe64dd3Smacallan } 565dfe64dd3Smacallan 566dfe64dd3Smacallan 567dfe64dd3Smacallan 568dfe64dd3Smacallan return 0; 569dfe64dd3Smacallan} 570dfe64dd3Smacallan/* end of I2COpen */ 571dfe64dd3Smacallanchar I2CAccess(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl) 572dfe64dd3Smacallan{ 573dfe64dd3Smacallan ULONG ulChannel = pI2CControl->dwCookie % MAX_I2C_CHANNEL; 574dfe64dd3Smacallan 575dfe64dd3Smacallan 576dfe64dd3Smacallan if (pI2CControl->ClockRate > I2C_MAX_CLOCK_RATE) 577dfe64dd3Smacallan { 578dfe64dd3Smacallan pI2CControl->ClockRate = I2C_MAX_CLOCK_RATE; 579dfe64dd3Smacallan } 580dfe64dd3Smacallan if (pI2CControl->ClockRate == 0) { 581dfe64dd3Smacallan pI2CControl->ClockRate = 20000; 582dfe64dd3Smacallan } 583dfe64dd3Smacallan 584dfe64dd3Smacallan pHWDE->I2CDelay = (1000000 / pI2CControl->ClockRate) * 10 * 2; /* in 100ns */ 585dfe64dd3Smacallan /* pHWDE->I2CDelay = (1000000 / pI2CControl->ClockRate) * 10; */ /* in 100ns */ 586dfe64dd3Smacallan /* pHWDE->I2CDelay = 100; */ 587dfe64dd3Smacallan /* PDEBUG(ErrorF("I2CAccess()-I2CDelay = %d...\n", pHWDE->I2CDelay)); */ 588dfe64dd3Smacallan 589dfe64dd3Smacallan /* pHWDE->I2CDelay = 100; */ /* Jong@08032009 */ 590dfe64dd3Smacallan 591dfe64dd3Smacallan switch (pI2CControl->Command) 592dfe64dd3Smacallan { 593dfe64dd3Smacallan /* Issue a STOP or START without a READ or WRITE Command */ 594dfe64dd3Smacallan case I2C_COMMAND_NULL: 595dfe64dd3Smacallan if (I2CNull(pHWDE, pI2CControl) == FALSE) break; 596dfe64dd3Smacallan/* if (pI2CControl->Flags & I2C_FLAGS_STOP) { 597dfe64dd3Smacallan pI2CContext->dwI2CPortAcquired = FALSE; 598dfe64dd3Smacallan } 599dfe64dd3Smacallan*/ break; 600dfe64dd3Smacallan 601dfe64dd3Smacallan /* READ or WRITE Command */ 602dfe64dd3Smacallan case I2C_COMMAND_READ: 603dfe64dd3Smacallan if (I2CRead(pHWDE, pI2CControl) == FALSE) break; 604dfe64dd3Smacallan/* if (pI2CControl->Flags & I2C_FLAGS_STOP) { 605dfe64dd3Smacallan pI2CContext->dwI2CPortAcquired = FALSE; 606dfe64dd3Smacallan } 607dfe64dd3Smacallan*/ break; 608dfe64dd3Smacallan 609dfe64dd3Smacallan case I2C_COMMAND_WRITE: 610dfe64dd3Smacallan if (I2CWrite(pHWDE, pI2CControl) == FALSE) break; 611dfe64dd3Smacallan/* if (pI2CControl->Flags & I2C_FLAGS_STOP) { 612dfe64dd3Smacallan pI2CContext->dwI2CPortAcquired = FALSE; 613dfe64dd3Smacallan } 614dfe64dd3Smacallan*/ break; 615dfe64dd3Smacallan 616dfe64dd3Smacallan case I2C_COMMAND_STATUS: 617dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 618dfe64dd3Smacallan break; 619dfe64dd3Smacallan 620dfe64dd3Smacallan case I2C_COMMAND_RESET: 621dfe64dd3Smacallan /* Reset I2C bus */ 622dfe64dd3Smacallan if (ResetI2C(pHWDE, pI2CControl) == FALSE) break; 623dfe64dd3Smacallan break; 624dfe64dd3Smacallan 625dfe64dd3Smacallan default: 626dfe64dd3Smacallan /* Invalid Command */ 627dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 628dfe64dd3Smacallan } 629dfe64dd3Smacallan 630dfe64dd3Smacallan 631dfe64dd3Smacallan/* printk("\nI2CAccess(): I2C Cmd = 0x%X I2C Flags = 0x%X I2C Status = 0x%X I2C Data = 0x%X", pI2CControl->Command, pI2CControl->Flags, pI2CControl->Status, pI2CControl->Data); */ 632dfe64dd3Smacallan 633dfe64dd3Smacallan return NO_ERROR; 634dfe64dd3Smacallan} 635dfe64dd3Smacallan 636dfe64dd3Smacallan 637dfe64dd3Smacallan/*^^* 638dfe64dd3Smacallan * Function: I2CNull 639dfe64dd3Smacallan * 640dfe64dd3Smacallan * Purpose: To complete an I2C instruction. 641dfe64dd3Smacallan * 642dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated 643dfe64dd3Smacallan * with card being accessed 644dfe64dd3Smacallan * I2CCntl : PI2CControl, pointer to I2C control structure 645dfe64dd3Smacallan * 646dfe64dd3Smacallan * Outputs: void. 647dfe64dd3Smacallan *^^*/ 648dfe64dd3SmacallanBOOLEAN I2CNull( PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl) 649dfe64dd3Smacallan{ 650dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_ERROR; 651dfe64dd3Smacallan 652dfe64dd3Smacallan/*///// Issue STOP - START, if I2C_FLAGS_DATACHAINING ////////*/ 653dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_DATACHAINING) 654dfe64dd3Smacallan { 655dfe64dd3Smacallan if (Stop(pHWDE) == FALSE) return FALSE; 656dfe64dd3Smacallan if (Start(pHWDE) == FALSE) return FALSE; 657dfe64dd3Smacallan } 658dfe64dd3Smacallan 659dfe64dd3Smacallan/*///// Issue START ////////*/ 660dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_START) 661dfe64dd3Smacallan { 662dfe64dd3Smacallan if (Start(pHWDE) == FALSE) return FALSE; 663dfe64dd3Smacallan } 664dfe64dd3Smacallan 665dfe64dd3Smacallan/*////// Issue STOP /////////*/ 666dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_STOP) 667dfe64dd3Smacallan { 668dfe64dd3Smacallan if (Stop(pHWDE) == FALSE) return FALSE; 669dfe64dd3Smacallan } 670dfe64dd3Smacallan 671dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 672dfe64dd3Smacallan return TRUE; 673dfe64dd3Smacallan}/* end of I2CNull()*/ 674dfe64dd3Smacallan 675dfe64dd3Smacallan/*^^* 676dfe64dd3Smacallan * Function: I2CRead 677dfe64dd3Smacallan * 678dfe64dd3Smacallan * Purpose: To complete an I2C instruction. 679dfe64dd3Smacallan * 680dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated 681dfe64dd3Smacallan * with card being accessed 682dfe64dd3Smacallan * I2CCntl : PI2CControl, pointer to I2C control structure 683dfe64dd3Smacallan * 684dfe64dd3Smacallan * Outputs: void. 685dfe64dd3Smacallan *^^*/ 686dfe64dd3SmacallanBOOLEAN I2CRead(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl) 687dfe64dd3Smacallan{ 688dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_ERROR; 689dfe64dd3Smacallan 690dfe64dd3Smacallan/*///// Issue STOP - START, if I2C_FLAGS_DATACHAINING ////////*/ 691dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_DATACHAINING) 692dfe64dd3Smacallan { 693dfe64dd3Smacallan if (Stop(pHWDE) == FALSE) return FALSE; 694dfe64dd3Smacallan if (Start(pHWDE) == FALSE) return FALSE; 695dfe64dd3Smacallan } 696dfe64dd3Smacallan 697dfe64dd3Smacallan/*///// Issue START ////////*/ 698dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_START) 699dfe64dd3Smacallan { 700dfe64dd3Smacallan if (Start(pHWDE) == FALSE) return FALSE; 701dfe64dd3Smacallan } 702dfe64dd3Smacallan 703dfe64dd3Smacallan/*///// Read Command ///////*/ 704dfe64dd3Smacallan if (ReadUCHARI2C(pHWDE, &pI2CControl->Data) == FALSE) 705dfe64dd3Smacallan return FALSE; 706dfe64dd3Smacallan 707dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_STOP) { 708dfe64dd3Smacallan if (NoAck(pHWDE) == FALSE) return FALSE; 709dfe64dd3Smacallan } 710dfe64dd3Smacallan else { /* Should we issue ACK*/ 711dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_ACK) { 712dfe64dd3Smacallan if (Ack(pHWDE, SEND_ACK) == FALSE) return FALSE; 713dfe64dd3Smacallan } 714dfe64dd3Smacallan } 715dfe64dd3Smacallan 716dfe64dd3Smacallan/*////// Issue STOP /////////*/ 717dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_STOP) 718dfe64dd3Smacallan { 719dfe64dd3Smacallan if (Stop(pHWDE) == FALSE) return FALSE; 720dfe64dd3Smacallan } 721dfe64dd3Smacallan 722dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 723dfe64dd3Smacallan return TRUE; 724dfe64dd3Smacallan} /* end of I2CRead() */ 725dfe64dd3Smacallan 726dfe64dd3Smacallan/*^^* 727dfe64dd3Smacallan * Function: I2CWrite 728dfe64dd3Smacallan * 729dfe64dd3Smacallan * Purpose: To complete an I2C instruction. 730dfe64dd3Smacallan * 731dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated 732dfe64dd3Smacallan * with card being accessed 733dfe64dd3Smacallan * I2CCntl : PI2CControl, pointer to I2C control structure 734dfe64dd3Smacallan * 735dfe64dd3Smacallan * Outputs: void. 736dfe64dd3Smacallan *^^*/ 737dfe64dd3SmacallanBOOLEAN I2CWrite(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl) 738dfe64dd3Smacallan{ 739dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_ERROR; 740dfe64dd3Smacallan 741dfe64dd3Smacallan/*///// Issue STOP - START, if I2C_FLAGS_DATACHAINING ////////*/ 742dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_DATACHAINING) 743dfe64dd3Smacallan { 744dfe64dd3Smacallan if (Stop(pHWDE) == FALSE) 745dfe64dd3Smacallan { 746dfe64dd3Smacallan 747dfe64dd3Smacallan return FALSE; 748dfe64dd3Smacallan } 749dfe64dd3Smacallan if (Start(pHWDE) == FALSE) 750dfe64dd3Smacallan { 751dfe64dd3Smacallan 752dfe64dd3Smacallan 753dfe64dd3Smacallan return FALSE; 754dfe64dd3Smacallan } 755dfe64dd3Smacallan } 756dfe64dd3Smacallan 757dfe64dd3Smacallan/*///// Issue START ////////*/ 758dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_START) 759dfe64dd3Smacallan { 760dfe64dd3Smacallan if (Start(pHWDE) == FALSE) 761dfe64dd3Smacallan { 762dfe64dd3Smacallan return FALSE; 763dfe64dd3Smacallan } 764dfe64dd3Smacallan } 765dfe64dd3Smacallan 766dfe64dd3Smacallan/*///// Write Command ///////*/ 767dfe64dd3Smacallan if (WriteUCHARI2C(pHWDE, pI2CControl->Data) == FALSE) 768dfe64dd3Smacallan { 769dfe64dd3Smacallan 770dfe64dd3Smacallan return FALSE; 771dfe64dd3Smacallan } 772dfe64dd3Smacallan 773dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_ACK) { 774dfe64dd3Smacallan if (Ack(pHWDE, RECV_ACK) == FALSE) 775dfe64dd3Smacallan { 776dfe64dd3Smacallan return FALSE; 777dfe64dd3Smacallan } 778dfe64dd3Smacallan } 779dfe64dd3Smacallan 780dfe64dd3Smacallan/*////// Issue STOP /////////*/ 781dfe64dd3Smacallan if (pI2CControl->Flags & I2C_FLAGS_STOP) 782dfe64dd3Smacallan { 783dfe64dd3Smacallan if (Stop(pHWDE) == FALSE) 784dfe64dd3Smacallan { 785dfe64dd3Smacallan return FALSE; 786dfe64dd3Smacallan } 787dfe64dd3Smacallan } 788dfe64dd3Smacallan 789dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 790dfe64dd3Smacallan return TRUE; 791dfe64dd3Smacallan} /* end of I2CWrite() */ 792dfe64dd3Smacallan 793dfe64dd3Smacallan/*^^* 794dfe64dd3Smacallan * Function: ResetI2C 795dfe64dd3Smacallan * 796dfe64dd3Smacallan * Purpose: To reset I2CBus 797dfe64dd3Smacallan * 798dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated with 799dfe64dd3Smacallan * lpI2C_ContextData being accessed 800dfe64dd3Smacallan * 801dfe64dd3Smacallan * Outputs: UCHAR, the data that was read. 802dfe64dd3Smacallan *^^*/ 803dfe64dd3SmacallanBOOLEAN ResetI2C(PXGI_HW_DEVICE_INFO pHWDE, PI2CControl pI2CControl) 804dfe64dd3Smacallan{ 805dfe64dd3Smacallan 806dfe64dd3Smacallan if (Stop(pHWDE) == TRUE) { 807dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_NOERROR; 808dfe64dd3Smacallan return TRUE; 809dfe64dd3Smacallan } 810dfe64dd3Smacallan else { 811dfe64dd3Smacallan pI2CControl->Status = I2C_STATUS_ERROR; 812dfe64dd3Smacallan return FALSE; 813dfe64dd3Smacallan } 814dfe64dd3Smacallan} /* ResetI2C() */ 815dfe64dd3Smacallan 816dfe64dd3Smacallan 817dfe64dd3Smacallan 818dfe64dd3Smacallan 819dfe64dd3Smacallan/*^^* 820dfe64dd3Smacallan * Function: Ack 821dfe64dd3Smacallan * 822dfe64dd3Smacallan * Purpose: To ask the I2C bus for an acknowledge. 823dfe64dd3Smacallan * 824dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated with 825dfe64dd3Smacallan * lpI2C_ContextData being accessed 826dfe64dd3Smacallan * 827dfe64dd3Smacallan * Outputs: char, ack status. 828dfe64dd3Smacallan *^^*/ 829dfe64dd3SmacallanBOOLEAN Ack (PXGI_HW_DEVICE_INFO pHWDE, bool fPut) 830dfe64dd3Smacallan{ 831dfe64dd3Smacallan BOOLEAN status = FALSE; 832dfe64dd3Smacallan ULONG i, delay, delay2; 833dfe64dd3Smacallan ULONG ack; 834dfe64dd3Smacallan 835dfe64dd3Smacallan delay = pHWDE->I2CDelay / 10 / 2; 836dfe64dd3Smacallan if (fPut == SEND_ACK) /* Send Ack into I2C bus */ 837dfe64dd3Smacallan { 838dfe64dd3Smacallan vWriteDataLine(pHWDE, LODAT); 839dfe64dd3Smacallan I2C_DelayUS(delay); 840dfe64dd3Smacallan 841dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 842dfe64dd3Smacallan I2C_DelayUS(delay); 843dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 844dfe64dd3Smacallan i = 0; 845dfe64dd3Smacallan delay2 = delay * 2; 846dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 847dfe64dd3Smacallan do { 848dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 849dfe64dd3Smacallan I2C_DelayUS(delay2); 850dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 851dfe64dd3Smacallan i++; 852dfe64dd3Smacallan delay2 *= 2; 853dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 854dfe64dd3Smacallan } while (1); 855dfe64dd3Smacallan } 856dfe64dd3Smacallan 857dfe64dd3Smacallan 858dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 859dfe64dd3Smacallan vWriteClockLine(pHWDE, LOCLK); 860dfe64dd3Smacallan I2C_DelayUS(delay); 861dfe64dd3Smacallan 862dfe64dd3Smacallan return TRUE; 863dfe64dd3Smacallan } 864dfe64dd3Smacallan else 865dfe64dd3Smacallan { 866dfe64dd3Smacallan /* Receive Ack from I2C bus */ 867dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 868dfe64dd3Smacallan I2C_DelayUS(delay); 869dfe64dd3Smacallan ack = bReadDataLine(pHWDE); 870dfe64dd3Smacallan 871dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 872dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 873dfe64dd3Smacallan I2C_DelayUS(delay); 874dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 875dfe64dd3Smacallan i = 0; 876dfe64dd3Smacallan delay2 = delay * 2; 877dfe64dd3Smacallan do { 878dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 879dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 880dfe64dd3Smacallan I2C_DelayUS(delay2); 881dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 882dfe64dd3Smacallan i++; 883dfe64dd3Smacallan delay2 *= 2; 884dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 885dfe64dd3Smacallan } while (1); 886dfe64dd3Smacallan } 887dfe64dd3Smacallan 888dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 889dfe64dd3Smacallan status = bReadDataLine(pHWDE); 890dfe64dd3Smacallan 891dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 892dfe64dd3Smacallan vWriteClockLine(pHWDE, LOCLK); 893dfe64dd3Smacallan I2C_DelayUS(delay); 894dfe64dd3Smacallan 895dfe64dd3Smacallan if (status != LODAT) { 896dfe64dd3Smacallan if (ack == LODAT) { 897dfe64dd3Smacallan status = LODAT; 898dfe64dd3Smacallan } 899dfe64dd3Smacallan 900dfe64dd3Smacallan else { 901dfe64dd3Smacallan 902dfe64dd3Smacallan } 903dfe64dd3Smacallan 904dfe64dd3Smacallan } 905dfe64dd3Smacallan return (BOOLEAN)(status == LODAT); 906dfe64dd3Smacallan } 907dfe64dd3Smacallan}/* end of Ack() */ 908dfe64dd3Smacallan 909dfe64dd3Smacallan 910dfe64dd3SmacallanBOOLEAN NoAck(PXGI_HW_DEVICE_INFO pHWDE) 911dfe64dd3Smacallan{ 912dfe64dd3Smacallan ULONG i, delay, delay2; 913dfe64dd3Smacallan 914dfe64dd3Smacallan delay = pHWDE->I2CDelay / 10 / 2; 915dfe64dd3Smacallan 916dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 917dfe64dd3Smacallan I2C_DelayUS(delay); 918dfe64dd3Smacallan 919dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 920dfe64dd3Smacallan I2C_DelayUS(delay); 921dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 922dfe64dd3Smacallan delay2 = delay * 2; 923dfe64dd3Smacallan i = 0; 924dfe64dd3Smacallan do { 925dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 926dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 927dfe64dd3Smacallan I2C_DelayUS(delay2); 928dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 929dfe64dd3Smacallan i++; 930dfe64dd3Smacallan delay2 *= 2; 931dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 932dfe64dd3Smacallan } while (1); 933dfe64dd3Smacallan } 934dfe64dd3Smacallan 935dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 936dfe64dd3Smacallan vWriteClockLine(pHWDE, LOCLK); 937dfe64dd3Smacallan I2C_DelayUS(delay); 938dfe64dd3Smacallan 939dfe64dd3Smacallan return TRUE; 940dfe64dd3Smacallan} 941dfe64dd3Smacallan 942dfe64dd3Smacallan 943dfe64dd3Smacallan/*^^* 944dfe64dd3Smacallan * Function: Start 945dfe64dd3Smacallan * 946dfe64dd3Smacallan * Purpose: To start a transfer on the I2C bus. 947dfe64dd3Smacallan * 948dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated with 949dfe64dd3Smacallan * lpI2C_ContextData being accessed 950dfe64dd3Smacallan * 951dfe64dd3Smacallan * Outputs: void. 952dfe64dd3Smacallan *^^*/ 953dfe64dd3SmacallanBOOLEAN Start( PXGI_HW_DEVICE_INFO pHWDE) 954dfe64dd3Smacallan{ 955dfe64dd3Smacallan ULONG i, delay, delay2; 956dfe64dd3Smacallan 957dfe64dd3Smacallan delay = pHWDE->I2CDelay / 10 / 2; 958dfe64dd3Smacallan 959dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 960dfe64dd3Smacallan I2C_DelayUS(delay); 961dfe64dd3Smacallan if (bReadDataLine(pHWDE) != HIDAT) { 962dfe64dd3Smacallan delay2 = delay * 2; 963dfe64dd3Smacallan i = 0; 964dfe64dd3Smacallan do { 965dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 966dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 967dfe64dd3Smacallan I2C_DelayUS(delay2); 968dfe64dd3Smacallan if (bReadDataLine(pHWDE) == HIDAT) break; 969dfe64dd3Smacallan i++; 970dfe64dd3Smacallan delay2 *= 2; 971dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 972dfe64dd3Smacallan } while (1); 973dfe64dd3Smacallan } 974dfe64dd3Smacallan 975dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 976dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 977dfe64dd3Smacallan I2C_DelayUS(delay); 978dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 979dfe64dd3Smacallan delay2 = delay * 2; 980dfe64dd3Smacallan i = 0; 981dfe64dd3Smacallan do { 982dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 983dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 984dfe64dd3Smacallan I2C_DelayUS(delay2); 985dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 986dfe64dd3Smacallan i++; 987dfe64dd3Smacallan delay2 *= 2; 988dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 989dfe64dd3Smacallan } while (1); 990dfe64dd3Smacallan } 991dfe64dd3Smacallan 992dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 993dfe64dd3Smacallan vWriteDataLine(pHWDE, LODAT); 994dfe64dd3Smacallan I2C_DelayUS(delay); 995dfe64dd3Smacallan 996dfe64dd3Smacallan vWriteClockLine(pHWDE, LOCLK); 997dfe64dd3Smacallan I2C_DelayUS(delay); 998dfe64dd3Smacallan 999dfe64dd3Smacallan return TRUE; 1000dfe64dd3Smacallan}/* end of Start */ 1001dfe64dd3Smacallan 1002dfe64dd3Smacallan/*^^* 1003dfe64dd3Smacallan * Function: Stop 1004dfe64dd3Smacallan * 1005dfe64dd3Smacallan * Purpose: To stop a transfer on the I2C bus. 1006dfe64dd3Smacallan * 1007dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated with 1008dfe64dd3Smacallan * lpI2C_ContextData being accessed 1009dfe64dd3Smacallan * 1010dfe64dd3Smacallan * Outputs: void. 1011dfe64dd3Smacallan *^^*/ 1012dfe64dd3SmacallanBOOLEAN Stop(PXGI_HW_DEVICE_INFO pHWDE) 1013dfe64dd3Smacallan{ 1014dfe64dd3Smacallan ULONG i, delay, delay2; 1015dfe64dd3Smacallan 1016dfe64dd3Smacallan delay = pHWDE->I2CDelay / 10 / 2; 1017dfe64dd3Smacallan PDEBUGI2C(ErrorF("Stop()-begin-pHWDE->I2CDelay=%d, delay=%d...\n", pHWDE->I2CDelay, delay)); 1018dfe64dd3Smacallan 1019dfe64dd3Smacallan vWriteDataLine(pHWDE, LODAT); 1020dfe64dd3Smacallan I2C_DelayUS(delay); 1021dfe64dd3Smacallan 1022dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 1023dfe64dd3Smacallan I2C_DelayUS(delay); 1024dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 1025dfe64dd3Smacallan i = 0; 1026dfe64dd3Smacallan delay2 = delay * 2; 1027dfe64dd3Smacallan do { 1028dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 1029dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 1030dfe64dd3Smacallan I2C_DelayUS(delay2); 1031dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 1032dfe64dd3Smacallan i++; 1033dfe64dd3Smacallan delay2 *= 2; 1034dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 1035dfe64dd3Smacallan } while (1); 1036dfe64dd3Smacallan } 1037dfe64dd3Smacallan 1038dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 1039dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 1040dfe64dd3Smacallan I2C_DelayUS(delay); 1041dfe64dd3Smacallan 1042dfe64dd3Smacallan return (BOOLEAN)(bReadDataLine(pHWDE) == HIDAT); 1043dfe64dd3Smacallan}/* end of Stop*/ 1044dfe64dd3Smacallan 1045dfe64dd3Smacallan/*^^* 1046dfe64dd3Smacallan * Function: WriteUCHARI2C 1047dfe64dd3Smacallan * 1048dfe64dd3Smacallan * Purpose: To write a UCHAR of data to the I2C bus. 1049dfe64dd3Smacallan * 1050dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated with 1051dfe64dd3Smacallan * lpI2C_ContextData being accessed 1052dfe64dd3Smacallan * cData: UCHAR, the data to write 1053dfe64dd3Smacallan * 1054dfe64dd3Smacallan * Outputs: void. 1055dfe64dd3Smacallan *^^*/ 1056dfe64dd3SmacallanBOOLEAN WriteUCHARI2C(PXGI_HW_DEVICE_INFO pHWDE, UCHAR cData) 1057dfe64dd3Smacallan{ 1058dfe64dd3Smacallan ULONG i, j, delay, delay2; 1059dfe64dd3Smacallan 1060dfe64dd3Smacallan cData = ReverseUCHAR(cData); 1061dfe64dd3Smacallan 1062dfe64dd3Smacallan delay = pHWDE->I2CDelay / 10 / 2; 1063dfe64dd3Smacallan 1064dfe64dd3Smacallan for (j=0; j<8; j++, cData>>=1) 1065dfe64dd3Smacallan { 1066dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 1067dfe64dd3Smacallan vWriteDataLine(pHWDE, cData); 1068dfe64dd3Smacallan I2C_DelayUS(delay); 1069dfe64dd3Smacallan 1070dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 1071dfe64dd3Smacallan I2C_DelayUS(delay); 1072dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 1073dfe64dd3Smacallan i = 0; 1074dfe64dd3Smacallan delay2 = delay * 2; 1075dfe64dd3Smacallan do { 1076dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 1077dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 1078dfe64dd3Smacallan I2C_DelayUS(delay2); 1079dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 1080dfe64dd3Smacallan i++; 1081dfe64dd3Smacallan delay2 *= 2; 1082dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 1083dfe64dd3Smacallan } while (1); 1084dfe64dd3Smacallan } 1085dfe64dd3Smacallan 1086dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 1087dfe64dd3Smacallan vWriteClockLine(pHWDE, LOCLK); 1088dfe64dd3Smacallan I2C_DelayUS(delay); 1089dfe64dd3Smacallan } 1090dfe64dd3Smacallan return TRUE; 1091dfe64dd3Smacallan}/* end of WriteUCHARI2C */ 1092dfe64dd3Smacallan 1093dfe64dd3Smacallan/*^^* 1094dfe64dd3Smacallan * Function: ReadUCHARI2C 1095dfe64dd3Smacallan * 1096dfe64dd3Smacallan * Purpose: To read a UCHAR of data from the I2C bus. 1097dfe64dd3Smacallan * 1098dfe64dd3Smacallan * Inputs: lpI2C_ContextData : PI2C_CONTEXT, pointer to data struct associated with 1099dfe64dd3Smacallan * lpI2C_ContextData being accessed 1100dfe64dd3Smacallan * 1101dfe64dd3Smacallan * Outputs: UCHAR, the data that was read. 1102dfe64dd3Smacallan *^^*/ 1103dfe64dd3SmacallanBOOLEAN ReadUCHARI2C(PXGI_HW_DEVICE_INFO pHWDE, PUCHAR pBuffer) 1104dfe64dd3Smacallan{ 1105dfe64dd3Smacallan ULONG ulReadData, data, i, j, delay, delay2; 1106dfe64dd3Smacallan 1107dfe64dd3Smacallan delay = pHWDE->I2CDelay / 10 / 2; 1108dfe64dd3Smacallan 1109dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 1110dfe64dd3Smacallan I2C_DelayUS(delay); 1111dfe64dd3Smacallan 1112dfe64dd3Smacallan ulReadData = 0; 1113dfe64dd3Smacallan for (j = 0; j < 8; j++) 1114dfe64dd3Smacallan { 1115dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 1116dfe64dd3Smacallan I2C_DelayUS(delay); 1117dfe64dd3Smacallan if (bReadClockLine(pHWDE) != HICLK) { 1118dfe64dd3Smacallan i = 0; 1119dfe64dd3Smacallan delay2 = delay * 2; 1120dfe64dd3Smacallan do { 1121dfe64dd3Smacallan I2C_DelayUS(delay2); /* Jong@08052008 */ 1122dfe64dd3Smacallan vWriteClockLine(pHWDE, HICLK); 1123dfe64dd3Smacallan I2C_DelayUS(delay2); 1124dfe64dd3Smacallan if (bReadClockLine(pHWDE) == HICLK) break; 1125dfe64dd3Smacallan i++; 1126dfe64dd3Smacallan delay2 *= 2; 1127dfe64dd3Smacallan if (i >= I2C_RETRY_COUNT) return FALSE; 1128dfe64dd3Smacallan } while (1); 1129dfe64dd3Smacallan } 1130dfe64dd3Smacallan 1131dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 1132dfe64dd3Smacallan data = bReadDataLine(pHWDE); 1133dfe64dd3Smacallan ulReadData = (ulReadData << 1) | (data & 1); 1134dfe64dd3Smacallan 1135dfe64dd3Smacallan I2C_DelayUS(delay); /* Jong@08052008 */ 1136dfe64dd3Smacallan vWriteClockLine(pHWDE, LOCLK); 1137dfe64dd3Smacallan I2C_DelayUS(delay); 1138dfe64dd3Smacallan 1139dfe64dd3Smacallan vWriteDataLine(pHWDE, HIDAT); 1140dfe64dd3Smacallan I2C_DelayUS(delay); 1141dfe64dd3Smacallan } 1142dfe64dd3Smacallan 1143dfe64dd3Smacallan *pBuffer = (UCHAR) ulReadData; 1144dfe64dd3Smacallan return TRUE; 1145dfe64dd3Smacallan} 1146dfe64dd3Smacallan 1147dfe64dd3Smacallan 1148dfe64dd3SmacallanUCHAR ReverseUCHAR(UCHAR data) 1149dfe64dd3Smacallan{ 1150dfe64dd3Smacallan UCHAR rdata = 0; 1151dfe64dd3Smacallan int i; 1152dfe64dd3Smacallan 1153dfe64dd3Smacallan for (i=0; i<8; i++) 1154dfe64dd3Smacallan { 1155dfe64dd3Smacallan rdata <<= 1; 1156dfe64dd3Smacallan rdata |= (data & 1); 1157dfe64dd3Smacallan data >>= 1; 1158dfe64dd3Smacallan } 1159dfe64dd3Smacallan 1160dfe64dd3Smacallan return(rdata); 1161dfe64dd3Smacallan} 1162dfe64dd3Smacallan 1163dfe64dd3Smacallan/************************************************************************************ 1164dfe64dd3Smacallan For DVI I2C Interface 1165dfe64dd3Smacallan***************************************************************************************/ 1166dfe64dd3Smacallan 1167dfe64dd3Smacallan/************************************************************************* 1168dfe64dd3Smacallan// VOID vWriteClockLineDVI() 1169dfe64dd3Smacallan// IOReg xx14, index 0F is defined as follows: 1170dfe64dd3Smacallan// 1171dfe64dd3Smacallan// ... 1 0 1172dfe64dd3Smacallan// --------|------|-------| 1173dfe64dd3Smacallan// ...| Data | Clock | 1174dfe64dd3Smacallan// ------------------------ 1175dfe64dd3Smacallan*************************************************************************/ 1176dfe64dd3SmacallanVOID vWriteClockLineDVI(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1177dfe64dd3Smacallan{ 1178098ad5bdSmacallan UCHAR temp; 1179098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase; 1180dfe64dd3Smacallan 1181dfe64dd3Smacallan PDEBUGI2C(ErrorF("vWriteClockLineDVI()...begin\n")); 1182dfe64dd3Smacallan 1183dfe64dd3Smacallan if ((pHWDE->jChipType < XG21)&&(pHWDE->jChipType != XG27)) 1184dfe64dd3Smacallan { 1185dfe64dd3Smacallan ErrorF("vWriteClockLineDVI()...0\n"); 1186dfe64dd3Smacallan } 1187dfe64dd3Smacallan else 1188dfe64dd3Smacallan { 1189dfe64dd3Smacallan PDEBUGI2C(ErrorF("vWriteClockLineDVI()...1\n")); 1190dfe64dd3Smacallan pjI2cIOBase = pHWDE->pjIOAddress + CRTC_ADDRESS_PORT_COLOR; 1191dfe64dd3Smacallan 1192dfe64dd3Smacallan /* Enable GPIOA Write */ 1193dfe64dd3Smacallan 1194dfe64dd3Smacallan EnableGPIOA(pjI2cIOBase, I2C_WRITE); 1195dfe64dd3Smacallan 1196dfe64dd3Smacallan PDEBUGI2C(ErrorF("*1 - pHWDE->ucI2cDVI = %d\n", pHWDE->ucI2cDVI)); 1197dfe64dd3Smacallan pHWDE->ucI2cDVI = (pHWDE->ucI2cDVI & MASK(1:1)) | SETBITS(data, 0:0); 1198dfe64dd3Smacallan PDEBUGI2C(ErrorF("*2 - pHWDE->ucI2cDVI = %d\n", pHWDE->ucI2cDVI)); 1199dfe64dd3Smacallan 1200dfe64dd3Smacallan temp = XGI_GetReg(pjI2cIOBase, IND_CR48_GPIO_REG_I); 1201dfe64dd3Smacallan PDEBUGI2C(ErrorF("IND_CR48_GPIO_REG_I = %d\n", temp)); 1202dfe64dd3Smacallan 1203dfe64dd3Smacallan { 1204dfe64dd3Smacallan UCHAR temp2 = getGPIORWTransfer(temp); 1205dfe64dd3Smacallan PDEBUGI2C(ErrorF("temp2 = %d\n", temp2)); 1206dfe64dd3Smacallan temp = temp2; 1207dfe64dd3Smacallan } 1208dfe64dd3Smacallan 1209dfe64dd3Smacallan temp = (temp & (~MASK(1:0))) | pHWDE->ucI2cDVI; 1210dfe64dd3Smacallan PDEBUGI2C(ErrorF("temp= %d\n", temp)); 1211dfe64dd3Smacallan XGI_SetReg(pjI2cIOBase,IND_CR48_GPIO_REG_I, temp); 1212dfe64dd3Smacallan } 1213dfe64dd3Smacallan 1214dfe64dd3Smacallan PDEBUGI2C(ErrorF("vWriteClockLineDVI()...end\n")); 1215dfe64dd3Smacallan} 1216dfe64dd3Smacallan 1217dfe64dd3Smacallan/************************************************************************* 1218dfe64dd3Smacallan// VOID vWriteDataLineDVI() 1219dfe64dd3Smacallan// IOReg xx14, index 0F is defined as follows: 1220dfe64dd3Smacallan// 1221dfe64dd3Smacallan// ... 1 0 1222dfe64dd3Smacallan// --------|------|-------| 1223dfe64dd3Smacallan// ...| Data | Clock | 1224dfe64dd3Smacallan// ------------------------ 1225dfe64dd3Smacallan*************************************************************************/ 1226dfe64dd3SmacallanVOID vWriteDataLineDVI(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1227dfe64dd3Smacallan{ 1228098ad5bdSmacallan UCHAR temp; 1229098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase; 1230dfe64dd3Smacallan 1231dfe64dd3Smacallan PDEBUGI2C(ErrorF("vWriteDataLineDVI()...begin\n")); 1232dfe64dd3Smacallan 1233dfe64dd3Smacallan if ((pHWDE->jChipType < XG21)&&(pHWDE->jChipType != XG27)) 1234dfe64dd3Smacallan { 1235dfe64dd3Smacallan ErrorF("vWriteDataLineDVI()...0\n"); 1236dfe64dd3Smacallan } 1237dfe64dd3Smacallan else 1238dfe64dd3Smacallan { 1239dfe64dd3Smacallan PDEBUGI2C(ErrorF("vWriteDataLineDVI()...1\n")); 1240dfe64dd3Smacallan pjI2cIOBase = pHWDE->pjIOAddress + CRTC_ADDRESS_PORT_COLOR; 1241dfe64dd3Smacallan 1242dfe64dd3Smacallan 1243dfe64dd3Smacallan /* Enable GPIOB Write */ 1244dfe64dd3Smacallan 1245dfe64dd3Smacallan EnableGPIOB(pjI2cIOBase, I2C_WRITE); 1246dfe64dd3Smacallan 1247dfe64dd3Smacallan PDEBUGI2C(ErrorF("*1 - pHWDE->ucI2cDVI = %d\n", pHWDE->ucI2cDVI)); 1248dfe64dd3Smacallan pHWDE->ucI2cDVI = (pHWDE->ucI2cDVI & MASK(0:0)) | SETBITS(data, 1:1); 1249dfe64dd3Smacallan PDEBUGI2C(ErrorF("*2 - pHWDE->ucI2cDVI = %d\n", pHWDE->ucI2cDVI)); 1250dfe64dd3Smacallan 1251dfe64dd3Smacallan temp = XGI_GetReg(pjI2cIOBase, IND_CR48_GPIO_REG_I); 1252dfe64dd3Smacallan PDEBUGI2C(ErrorF("IND_CR48_GPIO_REG_I = %d\n", temp)); 1253dfe64dd3Smacallan 1254dfe64dd3Smacallan { 1255dfe64dd3Smacallan UCHAR temp2 = getGPIORWTransfer(temp); 1256dfe64dd3Smacallan PDEBUGI2C(ErrorF("temp2 = %d\n", temp2)); 1257dfe64dd3Smacallan 1258dfe64dd3Smacallan temp = temp2; 1259dfe64dd3Smacallan } 1260dfe64dd3Smacallan 1261dfe64dd3Smacallan temp = (temp & (~MASK(1:0))) | pHWDE->ucI2cDVI; 1262dfe64dd3Smacallan PDEBUGI2C(ErrorF("temp = %d\n", temp)); 1263dfe64dd3Smacallan 1264dfe64dd3Smacallan XGI_SetReg(pjI2cIOBase,IND_CR48_GPIO_REG_I, temp); 1265dfe64dd3Smacallan } 1266dfe64dd3Smacallan 1267dfe64dd3Smacallan PDEBUGI2C(ErrorF("vWriteDataLineDVI()...end\n")); 1268dfe64dd3Smacallan} 1269dfe64dd3Smacallan 1270dfe64dd3Smacallan/************************************************************************* 1271dfe64dd3Smacallan// BOOLEAN bReadClockLineDVI() 1272dfe64dd3Smacallan// IOReg xx14, index 0F is defined as follows: 1273dfe64dd3Smacallan// 1274dfe64dd3Smacallan// ... 1 0 1275dfe64dd3Smacallan// --------|------|-------| 1276dfe64dd3Smacallan// ...| Data | Clock | 1277dfe64dd3Smacallan// ------------------------ 1278dfe64dd3Smacallan*************************************************************************/ 1279dfe64dd3SmacallanBOOLEAN bReadClockLineDVI(PXGI_HW_DEVICE_INFO pHWDE) 1280dfe64dd3Smacallan{ 1281098ad5bdSmacallan UCHAR cPortData; 1282098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase; 1283dfe64dd3Smacallan 1284dfe64dd3Smacallan PDEBUGI2C(ErrorF("bReadClockLineDVI()...begin\n")); 1285dfe64dd3Smacallan 1286dfe64dd3Smacallan if ((pHWDE->jChipType != XG21)&&(pHWDE->jChipType != XG27)) 1287dfe64dd3Smacallan { 1288dfe64dd3Smacallan ErrorF("bReadClockLineDVI()...0\n"); 1289dfe64dd3Smacallan } 1290dfe64dd3Smacallan else 1291dfe64dd3Smacallan { 1292dfe64dd3Smacallan PDEBUGI2C(ErrorF("bReadClockLineDVI()...1\n")); 1293dfe64dd3Smacallan pjI2cIOBase = pHWDE->pjIOAddress + CRTC_ADDRESS_PORT_COLOR; 1294dfe64dd3Smacallan 1295dfe64dd3Smacallan /* Enable GPIOA READ */ 1296dfe64dd3Smacallan 1297dfe64dd3Smacallan EnableGPIOA(pjI2cIOBase, I2C_READ); 1298dfe64dd3Smacallan 1299dfe64dd3Smacallan cPortData = XGI_GetReg(pjI2cIOBase, IND_CR48_GPIO_REG_I); 1300dfe64dd3Smacallan PDEBUGI2C(ErrorF("*1 - cPortData = %d...\n", cPortData)); 1301dfe64dd3Smacallan 1302dfe64dd3Smacallan cPortData = GETBITS(cPortData, 7:7); 1303dfe64dd3Smacallan PDEBUGI2C(ErrorF("*2 - cPortData = %d...\n", cPortData)); 1304dfe64dd3Smacallan } 1305dfe64dd3Smacallan 1306dfe64dd3Smacallan PDEBUGI2C(ErrorF("bReadClockLineDVI()...return(cPortData=%d)\n", cPortData)); 1307dfe64dd3Smacallan return cPortData; 1308dfe64dd3Smacallan} 1309dfe64dd3Smacallan 1310dfe64dd3Smacallan/************************************************************************* 1311dfe64dd3Smacallan// BOOLEAN bReadDataLineDVI() 1312dfe64dd3Smacallan// IOReg xx14, index 0F is defined as follows: 1313dfe64dd3Smacallan// 1314dfe64dd3Smacallan// ... 1 0 1315dfe64dd3Smacallan// --------|------|-------| 1316dfe64dd3Smacallan// ...| Data | Clock | 1317dfe64dd3Smacallan// ------------------------ 1318dfe64dd3Smacallan*************************************************************************/ 1319dfe64dd3SmacallanBOOLEAN bReadDataLineDVI(PXGI_HW_DEVICE_INFO pHWDE) 1320dfe64dd3Smacallan{ 1321dfe64dd3Smacallan UCHAR cPortData; 1322098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase; 1323dfe64dd3Smacallan 1324dfe64dd3Smacallan PDEBUGI2C(ErrorF("bReadDataLineDVI()...begin\n")); 1325dfe64dd3Smacallan 1326dfe64dd3Smacallan if ((pHWDE->jChipType != XG21)&&(pHWDE->jChipType != XG27)) 1327dfe64dd3Smacallan { 1328dfe64dd3Smacallan ErrorF("bReadDataLineDVI()...0\n"); 1329dfe64dd3Smacallan } 1330dfe64dd3Smacallan else 1331dfe64dd3Smacallan { 1332dfe64dd3Smacallan PDEBUGI2C(ErrorF("bReadDataLineDVI()...1\n")); 1333dfe64dd3Smacallan pjI2cIOBase = pHWDE->pjIOAddress + CRTC_ADDRESS_PORT_COLOR; 1334dfe64dd3Smacallan 1335dfe64dd3Smacallan 1336dfe64dd3Smacallan /* Enable GPIOB Write */ 1337dfe64dd3Smacallan 1338dfe64dd3Smacallan EnableGPIOB(pjI2cIOBase, I2C_READ); 1339dfe64dd3Smacallan 1340dfe64dd3Smacallan cPortData = XGI_GetReg(pjI2cIOBase, IND_CR48_GPIO_REG_I); 1341dfe64dd3Smacallan PDEBUGI2C(ErrorF("*1 - cPortData = %d...\n", cPortData)); 1342dfe64dd3Smacallan cPortData = GETBITS(cPortData, 6:6); 1343dfe64dd3Smacallan PDEBUGI2C(ErrorF("*2 - cPortData = %d...\n", cPortData)); 1344dfe64dd3Smacallan } 1345dfe64dd3Smacallan 1346dfe64dd3Smacallan 1347dfe64dd3Smacallan PDEBUGI2C(ErrorF("bReadDataLineDVI()...return(cPortData=%d)\n", cPortData)); 1348dfe64dd3Smacallan return cPortData; 1349dfe64dd3Smacallan} 1350dfe64dd3Smacallan 1351dfe64dd3Smacallan//*************************************************************************// 1352dfe64dd3Smacallan// VOID vWaitForCRT1VsyncActive() 1353dfe64dd3Smacallan// IoReg 3DA 1354dfe64dd3Smacallan// ... 3 ... 1355dfe64dd3Smacallan// --------|--------------|-------| 1356dfe64dd3Smacallan// ...| Vertical Sync| | 1357dfe64dd3Smacallan// -------------------------------- 1358dfe64dd3Smacallan//*************************************************************************// 1359dfe64dd3SmacallanVOID vWaitForCRT1HsyncActive(PXGI_HW_DEVICE_INFO pHWDE) 1360dfe64dd3Smacallan{ 1361098ad5bdSmacallan XGIIOADDRESS pjPort = pHWDE->pjIOAddress + INPUT_STATUS_1_COLOR; 1362dfe64dd3Smacallan ULONG i; 1363dfe64dd3Smacallan 1364dfe64dd3Smacallan for (i = 0; i < 0x00FFFF; i++) 1365dfe64dd3Smacallan { 1366dfe64dd3Smacallan if ( (XGI_GetRegByte(pjPort) & 0x01) == 0) 1367dfe64dd3Smacallan { 1368dfe64dd3Smacallan // Inactive 1369dfe64dd3Smacallan break; 1370dfe64dd3Smacallan } //if 1371dfe64dd3Smacallan } //for-loop 1372dfe64dd3Smacallan 1373dfe64dd3Smacallan for (i = 0; i < 0x00FFFF; i++) 1374dfe64dd3Smacallan { 1375dfe64dd3Smacallan if ( (XGI_GetRegByte(pjPort) & 0x01) != 0) 1376dfe64dd3Smacallan { 1377dfe64dd3Smacallan // active 1378dfe64dd3Smacallan break; 1379dfe64dd3Smacallan } //if 1380dfe64dd3Smacallan } //for-loop 1381dfe64dd3Smacallan 1382dfe64dd3Smacallan} //vWaitForCRT1HsyncActive() 1383dfe64dd3Smacallan 1384dfe64dd3Smacallan//////////////////////////////////////////////////////////////////////////////////// 1385dfe64dd3Smacallan// 1386dfe64dd3Smacallan// For CRT I2C Interface 1387dfe64dd3Smacallan// 1388dfe64dd3Smacallan//////////////////////////////////////////////////////////////////////////////////// 1389dfe64dd3Smacallan 1390dfe64dd3Smacallan//*************************************************************************// 1391dfe64dd3Smacallan// VOID vWriteClockLineCRT() 1392dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1393dfe64dd3Smacallan// 1394dfe64dd3Smacallan// ... 1 0 1395dfe64dd3Smacallan// --------|------|-------| 1396dfe64dd3Smacallan// ...| Data | Clock | 1397dfe64dd3Smacallan// ------------------------ 1398dfe64dd3Smacallan//*************************************************************************// 1399dfe64dd3SmacallanVOID vWriteClockLineCRT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1400dfe64dd3Smacallan{ 1401dfe64dd3Smacallan UCHAR temp, ujSR1F; 1402098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1403dfe64dd3Smacallan 1404dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Write CRT clock = %x\n", data & 1)); 1405dfe64dd3Smacallan 1406dfe64dd3Smacallan ujSR1F = XGI_GetReg(pjI2cIOBase, IND_SR1F_POWER_MANAGEMENT); 1407dfe64dd3Smacallan 1408dfe64dd3Smacallan pHWDE->ucI2cCRT = (pHWDE->ucI2cCRT & MASK(1:1)) | SETBITS(data, 0:0); 1409dfe64dd3Smacallan 1410dfe64dd3Smacallan temp = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1411dfe64dd3Smacallan temp = (temp & (~MASK(1:0))) | pHWDE->ucI2cCRT; 1412dfe64dd3Smacallan 1413dfe64dd3Smacallan //wait for CRT1 retrace only when CRT1 is enabled! 1414dfe64dd3Smacallan /* if (pHWDE->bMonitorPoweredOn) */ /* jong@08042009; ignore here */ 1415dfe64dd3Smacallan { 1416dfe64dd3Smacallan if(!(data & 1) && ((ujSR1F & 0xC0)==0) ) 1417dfe64dd3Smacallan { 1418dfe64dd3Smacallan vWaitForCRT1HsyncActive(pHWDE); 1419dfe64dd3Smacallan } 1420dfe64dd3Smacallan } 1421dfe64dd3Smacallan 1422dfe64dd3Smacallan XGI_SetReg(pjI2cIOBase, IND_SR11_DDC_REG, temp); 1423dfe64dd3Smacallan} 1424dfe64dd3Smacallan 1425dfe64dd3Smacallan//*************************************************************************// 1426dfe64dd3Smacallan// VOID vWriteDataLineCRT() 1427dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1428dfe64dd3Smacallan// 1429dfe64dd3Smacallan// ... 1 0 1430dfe64dd3Smacallan// --------|------|-------| 1431dfe64dd3Smacallan// ...| Data | Clock | 1432dfe64dd3Smacallan// ------------------------ 1433dfe64dd3Smacallan//*************************************************************************// 1434dfe64dd3SmacallanVOID vWriteDataLineCRT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1435dfe64dd3Smacallan{ 1436dfe64dd3Smacallan UCHAR temp, ujSR1F; 1437098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1438dfe64dd3Smacallan 1439dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Write CRT data = %x\n", data & 1)); 1440dfe64dd3Smacallan 1441dfe64dd3Smacallan ujSR1F = XGI_GetReg(pHWDE->pjIOAddress + SEQ_ADDRESS_PORT, IND_SR1F_POWER_MANAGEMENT); 1442dfe64dd3Smacallan 1443dfe64dd3Smacallan pHWDE->ucI2cCRT = (pHWDE->ucI2cCRT & MASK(0:0)) | SETBITS(data, 1:1); 1444dfe64dd3Smacallan temp = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1445dfe64dd3Smacallan temp = (temp & (~MASK(1:0))) | pHWDE->ucI2cCRT; 1446dfe64dd3Smacallan 1447dfe64dd3Smacallan //wait for CRT1 retrace only when CRT1 is enabled! 1448dfe64dd3Smacallan /* if (pHWDE->bMonitorPoweredOn) */ /* Jong@08042009; ignore checking */ 1449dfe64dd3Smacallan { 1450dfe64dd3Smacallan if(!(data & 1) && ((ujSR1F & 0xC0)==0) ) 1451dfe64dd3Smacallan { 1452dfe64dd3Smacallan vWaitForCRT1HsyncActive(pHWDE); 1453dfe64dd3Smacallan } 1454dfe64dd3Smacallan } 1455dfe64dd3Smacallan 1456dfe64dd3Smacallan XGI_SetReg(pjI2cIOBase, IND_SR11_DDC_REG, temp); 1457dfe64dd3Smacallan} 1458dfe64dd3Smacallan 1459dfe64dd3Smacallan//*************************************************************************// 1460dfe64dd3Smacallan// BOOLEAN bReadClockLineCRT() 1461dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1462dfe64dd3Smacallan// 1463dfe64dd3Smacallan// ... 1 0 1464dfe64dd3Smacallan// --------|------|-------| 1465dfe64dd3Smacallan// ...| Data | Clock | 1466dfe64dd3Smacallan// ------------------------ 1467dfe64dd3Smacallan//*************************************************************************// 1468dfe64dd3SmacallanBOOLEAN bReadClockLineCRT(PXGI_HW_DEVICE_INFO pHWDE) 1469dfe64dd3Smacallan{ 1470dfe64dd3Smacallan UCHAR cPortData; 1471098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1472dfe64dd3Smacallan 1473dfe64dd3Smacallan cPortData = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1474dfe64dd3Smacallan cPortData = GETBITS(cPortData, 0:0); 1475dfe64dd3Smacallan 1476dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Read Channel CRT clock = %x\n", cPortData)); 1477dfe64dd3Smacallan 1478dfe64dd3Smacallan return cPortData; 1479dfe64dd3Smacallan} 1480dfe64dd3Smacallan 1481dfe64dd3Smacallan//*************************************************************************// 1482dfe64dd3Smacallan// BOOLEAN bReadDataLineCRT() 1483dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1484dfe64dd3Smacallan// 1485dfe64dd3Smacallan// ... 1 0 1486dfe64dd3Smacallan// --------|------|-------| 1487dfe64dd3Smacallan// ...| Data | Clock | 1488dfe64dd3Smacallan// ------------------------ 1489dfe64dd3Smacallan//*************************************************************************// 1490dfe64dd3SmacallanBOOLEAN bReadDataLineCRT(PXGI_HW_DEVICE_INFO pHWDE) 1491dfe64dd3Smacallan{ 1492dfe64dd3Smacallan UCHAR cPortData; 1493098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1494dfe64dd3Smacallan 1495dfe64dd3Smacallan cPortData = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1496dfe64dd3Smacallan cPortData = GETBITS(cPortData, 1:1); 1497dfe64dd3Smacallan 1498dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Read Channel CRT data = %x\n", cPortData)); 1499dfe64dd3Smacallan 1500dfe64dd3Smacallan return cPortData; 1501dfe64dd3Smacallan} 1502dfe64dd3Smacallan 1503dfe64dd3Smacallan//////////////////////////////////////////////////////////////////////////////////// 1504dfe64dd3Smacallan// 1505dfe64dd3Smacallan// For Feature Connector I2C Interface 1506dfe64dd3Smacallan// 1507dfe64dd3Smacallan//////////////////////////////////////////////////////////////////////////////////// 1508dfe64dd3Smacallan 1509dfe64dd3Smacallan//*************************************************************************// 1510dfe64dd3Smacallan// VOID vWriteClockLineFCNT() 1511dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1512dfe64dd3Smacallan// 1513dfe64dd3Smacallan// ... 3 2 ... 1514dfe64dd3Smacallan// --------|------|-------|-------| 1515dfe64dd3Smacallan// ...| Data | Clock | | 1516dfe64dd3Smacallan// -------------------------------- 1517dfe64dd3Smacallan//*************************************************************************// 1518dfe64dd3SmacallanVOID vWriteClockLineFCNT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1519dfe64dd3Smacallan{ 1520dfe64dd3Smacallan UCHAR temp; 1521098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1522dfe64dd3Smacallan 1523dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Write FCNT clock = %x\n", data & 1)); 1524dfe64dd3Smacallan 1525dfe64dd3Smacallan pHWDE->ucI2cFCNT = (pHWDE->ucI2cFCNT & MASK(3:3)) | SETBITS(data, 2:2); 1526dfe64dd3Smacallan 1527dfe64dd3Smacallan temp = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1528dfe64dd3Smacallan temp = (temp & (~MASK(3:2))) | pHWDE->ucI2cFCNT; 1529dfe64dd3Smacallan 1530dfe64dd3Smacallan XGI_SetReg(pjI2cIOBase, IND_SR11_DDC_REG, temp); 1531dfe64dd3Smacallan} 1532dfe64dd3Smacallan 1533dfe64dd3Smacallan//*************************************************************************// 1534dfe64dd3Smacallan// VOID vWriteDataLineFCNT() 1535dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1536dfe64dd3Smacallan// 1537dfe64dd3Smacallan// ... 3 2 ... 1538dfe64dd3Smacallan// --------|------|-------|-------| 1539dfe64dd3Smacallan// ...| Data | Clock | | 1540dfe64dd3Smacallan// -------------------------------- 1541dfe64dd3Smacallan//*************************************************************************// 1542dfe64dd3SmacallanVOID vWriteDataLineFCNT(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1543dfe64dd3Smacallan{ 1544dfe64dd3Smacallan UCHAR temp, temp2, temp3; 1545098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1546dfe64dd3Smacallan 1547dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Write FCNT data = %x\n", data & 1)); 1548dfe64dd3Smacallan 1549dfe64dd3Smacallan pHWDE->ucI2cFCNT = (pHWDE->ucI2cFCNT & MASK(2:2)) | SETBITS(data, 3:3); 1550dfe64dd3Smacallan 1551dfe64dd3Smacallan temp = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1552dfe64dd3Smacallan temp = (temp & (~MASK(3:2))) | pHWDE->ucI2cFCNT; 1553dfe64dd3Smacallan 1554dfe64dd3Smacallan XGI_SetReg(pjI2cIOBase, IND_SR11_DDC_REG, temp); 1555dfe64dd3Smacallan} 1556dfe64dd3Smacallan 1557dfe64dd3Smacallan//*************************************************************************// 1558dfe64dd3Smacallan// BOOLEAN bReadClockLineFCNT() 1559dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1560dfe64dd3Smacallan// 1561dfe64dd3Smacallan// ... 3 2 ... 1562dfe64dd3Smacallan// --------|------|-------|-------| 1563dfe64dd3Smacallan// ...| Data | Clock | | 1564dfe64dd3Smacallan// -------------------------------- 1565dfe64dd3Smacallan//*************************************************************************// 1566dfe64dd3SmacallanBOOLEAN bReadClockLineFCNT(PXGI_HW_DEVICE_INFO pHWDE) 1567dfe64dd3Smacallan{ 1568dfe64dd3Smacallan UCHAR cPortData; 1569098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1570dfe64dd3Smacallan 1571dfe64dd3Smacallan cPortData = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1572dfe64dd3Smacallan cPortData = GETBITS(cPortData, 2:2); 1573dfe64dd3Smacallan 1574dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Read Channel FCNT clock = %x\n", cPortData)); 1575dfe64dd3Smacallan 1576dfe64dd3Smacallan return cPortData; 1577dfe64dd3Smacallan} 1578dfe64dd3Smacallan 1579dfe64dd3Smacallan//*************************************************************************// 1580dfe64dd3Smacallan// BOOLEAN bReadDataLineFCNT() 1581dfe64dd3Smacallan// IOReg SR11 is defined as follows: 1582dfe64dd3Smacallan// 1583dfe64dd3Smacallan// ... 3 2 ... 1584dfe64dd3Smacallan// --------|------|-------|-------| 1585dfe64dd3Smacallan// ...| Data | Clock | | 1586dfe64dd3Smacallan// -------------------------------- 1587dfe64dd3Smacallan//*************************************************************************// 1588dfe64dd3SmacallanBOOLEAN bReadDataLineFCNT(PXGI_HW_DEVICE_INFO pHWDE) 1589dfe64dd3Smacallan{ 1590dfe64dd3Smacallan UCHAR cPortData; 1591098ad5bdSmacallan XGIIOADDRESS pjI2cIOBase = pHWDE->pjIOAddress + SEQ_ADDRESS_PORT; 1592dfe64dd3Smacallan 1593dfe64dd3Smacallan cPortData = XGI_GetReg(pjI2cIOBase, IND_SR11_DDC_REG); 1594dfe64dd3Smacallan cPortData = GETBITS(cPortData, 3:3); 1595dfe64dd3Smacallan 1596dfe64dd3Smacallan PDEBUGI2C(ErrorF("I2C:Read Channel FCNT data = %x\n", cPortData)); 1597dfe64dd3Smacallan 1598dfe64dd3Smacallan return cPortData; 1599dfe64dd3Smacallan} 1600dfe64dd3Smacallan 1601dfe64dd3Smacallan/*=======================================================*/ 1602dfe64dd3SmacallanVOID vWriteClockLine(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1603dfe64dd3Smacallan{ 1604dfe64dd3Smacallan if(pHWDE->crtno == 0) 1605dfe64dd3Smacallan vWriteClockLineCRT(pHWDE, data); 1606dfe64dd3Smacallan else if(pHWDE->crtno == 1) 1607dfe64dd3Smacallan vWriteClockLineDVI(pHWDE, data); 1608dfe64dd3Smacallan else if(pHWDE->crtno == 2) 1609dfe64dd3Smacallan vWriteClockLineFCNT(pHWDE, data); 1610dfe64dd3Smacallan else 1611dfe64dd3Smacallan ErrorF("Error(XGI) : Unkonwn output device! \n"); 1612dfe64dd3Smacallan} 1613dfe64dd3Smacallan 1614dfe64dd3SmacallanVOID vWriteDataLine(PXGI_HW_DEVICE_INFO pHWDE, UCHAR data) 1615dfe64dd3Smacallan{ 1616dfe64dd3Smacallan if(pHWDE->crtno == 0) 1617dfe64dd3Smacallan vWriteDataLineCRT(pHWDE, data); 1618dfe64dd3Smacallan else if(pHWDE->crtno == 1) 1619dfe64dd3Smacallan vWriteDataLineDVI(pHWDE, data); 1620dfe64dd3Smacallan else if(pHWDE->crtno == 2) 1621dfe64dd3Smacallan vWriteDataLineFCNT(pHWDE, data); 1622dfe64dd3Smacallan else 1623dfe64dd3Smacallan ErrorF("Error(XGI) : Unkonwn output device! \n"); 1624dfe64dd3Smacallan} 1625dfe64dd3Smacallan 1626dfe64dd3SmacallanBOOLEAN bReadClockLine(PXGI_HW_DEVICE_INFO pHWDE) 1627dfe64dd3Smacallan{ 1628dfe64dd3Smacallan if(pHWDE->crtno == 0) 1629dfe64dd3Smacallan return(bReadClockLineCRT(pHWDE)); 1630dfe64dd3Smacallan else if(pHWDE->crtno == 1) 1631dfe64dd3Smacallan return(bReadClockLineDVI(pHWDE)); 1632dfe64dd3Smacallan else if(pHWDE->crtno == 2) 1633dfe64dd3Smacallan return(bReadClockLineFCNT(pHWDE)); 1634ecb1bcb9Sapb else { 1635dfe64dd3Smacallan ErrorF("Error(XGI) : Unkonwn output device! \n"); 1636ecb1bcb9Sapb return FALSE; 1637ecb1bcb9Sapb } 1638dfe64dd3Smacallan} 1639dfe64dd3Smacallan 1640dfe64dd3SmacallanBOOLEAN bReadDataLine(PXGI_HW_DEVICE_INFO pHWDE) 1641dfe64dd3Smacallan{ 1642dfe64dd3Smacallan if(pHWDE->crtno == 0) 1643dfe64dd3Smacallan return(bReadDataLineCRT(pHWDE)); 1644dfe64dd3Smacallan else if(pHWDE->crtno == 1) 1645dfe64dd3Smacallan return(bReadDataLineDVI(pHWDE)); 1646dfe64dd3Smacallan else if(pHWDE->crtno == 2) 1647dfe64dd3Smacallan return(bReadDataLineFCNT(pHWDE)); 1648ecb1bcb9Sapb else { 1649dfe64dd3Smacallan ErrorF("Error(XGI) : Unkonwn output device! \n"); 1650ecb1bcb9Sapb return FALSE; 1651ecb1bcb9Sapb } 1652dfe64dd3Smacallan} 1653dfe64dd3Smacallan 1654dfe64dd3SmacallanBOOLEAN bEDIDCheckSum(PUCHAR pjEDIDBuf,ULONG ulBufSize) 1655dfe64dd3Smacallan{ 1656dfe64dd3Smacallan ULONG i; 1657dfe64dd3Smacallan UCHAR ujSum = 0; 1658dfe64dd3Smacallan PUCHAR pujPtr; 1659dfe64dd3Smacallan 1660dfe64dd3Smacallan pujPtr = pjEDIDBuf; 1661dfe64dd3Smacallan 1662dfe64dd3Smacallan for (i = 0; i < ulBufSize; i++) 1663dfe64dd3Smacallan { 1664dfe64dd3Smacallan /* printk("pujPtr=%x, ",*pujPtr); */ 1665dfe64dd3Smacallan ujSum += *(pujPtr++); 1666dfe64dd3Smacallan } /*for-loop */ 1667dfe64dd3Smacallan 1668dfe64dd3Smacallan return(ujSum); 1669dfe64dd3Smacallan 1670dfe64dd3Smacallan} 1671dfe64dd3Smacallan 1672dfe64dd3Smacallan/* Jong 08/03/2009; Get EDID functions; ported from MS Windows */ 1673dfe64dd3Smacallan//*************************************************************************\\ 1674dfe64dd3Smacallan// VP_STATUS vGetEDID_1 1675dfe64dd3Smacallan// 1676dfe64dd3Smacallan// Routine Description: 1677dfe64dd3Smacallan// Get the EDID which is in version 1.x format via I2C. 1678dfe64dd3Smacallan// 1679dfe64dd3Smacallan// Arguments: 1680dfe64dd3Smacallan// pHWDE - Hardware extension object pointer 1681dfe64dd3Smacallan// pI2C - I2C pointer 1682dfe64dd3Smacallan// pjBuffer - EDID Buffer 1683dfe64dd3Smacallan// ulBufferSize - Buffer size 1684dfe64dd3Smacallan// 1685dfe64dd3Smacallan// 1686dfe64dd3Smacallan// Return Value: 1687dfe64dd3Smacallan// Status of returning EDID. 1688dfe64dd3Smacallan// NO_ERROR - success 1689dfe64dd3Smacallan// ERROR_INVALID_PARAMETER - failed 1690dfe64dd3Smacallan// 1691dfe64dd3Smacallan//**************************************************************************** 1692dfe64dd3SmacallanVP_STATUS vGetEDID_1( 1693dfe64dd3Smacallan PXGI_HW_DEVICE_INFO pHWDE, 1694dfe64dd3Smacallan PI2CControl pI2C, 1695dfe64dd3Smacallan PUCHAR pjBuffer, 1696dfe64dd3Smacallan ULONG ulBufferSize) 1697dfe64dd3Smacallan{ 1698dfe64dd3Smacallan VP_STATUS status; 1699dfe64dd3Smacallan 1700dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_1()\n")); 1701dfe64dd3Smacallan 1702dfe64dd3Smacallan if ((ulBufferSize < 128) || (pjBuffer == NULL)) { 1703dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1704dfe64dd3Smacallan } 1705dfe64dd3Smacallan 1706dfe64dd3Smacallan // Set Segment Block ID as 0 if Monitor support Enhanced-EDID 1707dfe64dd3Smacallan /* 1708dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_WRITE_SEGMENT; // to replace I2C_COMMAND_WRITE 1709dfe64dd3Smacallan pI2C->Data = 0; 1710dfe64dd3Smacallan I2CAccessBuffer(pHWDE, pI2C, 0x60, 0, &(pI2C->Data), 0); 1711dfe64dd3Smacallan */ 1712dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_WRITE; 1713dfe64dd3Smacallan pI2C->Data = 0; 1714dfe64dd3Smacallan I2CAccessBuffer(pHWDE, pI2C, 0x60, 0, &(pI2C->Data), 0); 1715dfe64dd3Smacallan 1716dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_READ; 1717dfe64dd3Smacallan status = I2CAccessBuffer(pHWDE, pI2C, 0xA0, 0, pjBuffer, 128); 1718dfe64dd3Smacallan if ((status == NO_ERROR) && (pI2C->Status == I2C_STATUS_NOERROR)) 1719dfe64dd3Smacallan { 1720dfe64dd3Smacallan // Check Block 0 EDID Header and its checksum 1721dfe64dd3Smacallan if ((*((PULONG)(pjBuffer )) != 0xFFFFFF00) || 1722dfe64dd3Smacallan (*((PULONG)(pjBuffer+4)) != 0x00FFFFFF)) 1723dfe64dd3Smacallan { 1724dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_1(): EDID Header Incorrect!!\n")); 1725dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1726dfe64dd3Smacallan } 1727dfe64dd3Smacallan 1728dfe64dd3Smacallan if (bEDIDCheckSum(pjBuffer, 128) != 0) 1729dfe64dd3Smacallan { 1730dfe64dd3Smacallan if ((*((PULONG)(pjBuffer+0x60)) ==0x4d636e79)&& (*((PULONG)(pjBuffer+0x64)) ==0x65747361)) 1731dfe64dd3Smacallan { 1732dfe64dd3Smacallan return NO_ERROR; //To Fix SyncMaster Checksum error issue 1733dfe64dd3Smacallan } 1734dfe64dd3Smacallan 1735dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_1(): EDID Checksum Error!!\n")); 1736dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1737dfe64dd3Smacallan } 1738dfe64dd3Smacallan 1739dfe64dd3Smacallan } 1740dfe64dd3Smacallan else 1741dfe64dd3Smacallan { 1742dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_1 : call I2CAccessBuffer(0xA0) fail !!!\n")); 1743dfe64dd3Smacallan return status; 1744dfe64dd3Smacallan } 1745dfe64dd3Smacallan 1746dfe64dd3Smacallan return NO_ERROR; 1747dfe64dd3Smacallan} 1748dfe64dd3Smacallan 1749dfe64dd3Smacallan//*************************************************************************\\ 1750dfe64dd3Smacallan// VP_STATUS vGetEDID_2 1751dfe64dd3Smacallan// 1752dfe64dd3Smacallan// Routine Description: 1753dfe64dd3Smacallan// Get the EDID which is in version 2.0 format via I2C. 1754dfe64dd3Smacallan// 1755dfe64dd3Smacallan// Arguments: 1756dfe64dd3Smacallan// pHWDE - Hardware extension object pointer 1757dfe64dd3Smacallan// pI2C - I2C pointer 1758dfe64dd3Smacallan// pjBuffer - EDID Buffer 1759dfe64dd3Smacallan// ulBufferSize - Buffer size 1760dfe64dd3Smacallan// 1761dfe64dd3Smacallan// 1762dfe64dd3Smacallan// Return Value: 1763dfe64dd3Smacallan// Status of returning EDID. 1764dfe64dd3Smacallan// NO_ERROR - success 1765dfe64dd3Smacallan// ERROR_INVALID_PARAMETER - failed 1766dfe64dd3Smacallan// 1767dfe64dd3Smacallan//**************************************************************************** 1768dfe64dd3SmacallanVP_STATUS vGetEDID_2( 1769dfe64dd3Smacallan PXGI_HW_DEVICE_INFO pHWDE, 1770dfe64dd3Smacallan PI2CControl pI2C, 1771dfe64dd3Smacallan PUCHAR pjBuffer, 1772dfe64dd3Smacallan ULONG ulBufferSize) 1773dfe64dd3Smacallan{ 1774dfe64dd3Smacallan VP_STATUS status; 1775dfe64dd3Smacallan 1776dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_2()\n")); 1777dfe64dd3Smacallan 1778dfe64dd3Smacallan if ((ulBufferSize < 256) || (pjBuffer == NULL)) { 1779dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1780dfe64dd3Smacallan } 1781dfe64dd3Smacallan 1782dfe64dd3Smacallan pI2C->Command = I2C_COMMAND_READ; 1783dfe64dd3Smacallan status = I2CAccessBuffer(pHWDE, pI2C, 0xA2, 0, pjBuffer, 256); 1784dfe64dd3Smacallan if ((status != NO_ERROR) || (pI2C->Status != I2C_STATUS_NOERROR)) { 1785dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_2 : call I2CAccessBuffer(0xA2) fail !!!\n")); 1786dfe64dd3Smacallan usleep(5); 1787dfe64dd3Smacallan status = I2CAccessBuffer(pHWDE, pI2C, 0xA6, 0, pjBuffer, 256); 1788dfe64dd3Smacallan if ((status != NO_ERROR) || (pI2C->Status != I2C_STATUS_NOERROR)) { 1789dfe64dd3Smacallan PDEBUGI2C(ErrorF("vGetEDID_2 : call I2CAccessBuffer(0xA6) fail !!!\n")); 1790dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1791dfe64dd3Smacallan } 1792dfe64dd3Smacallan } 1793dfe64dd3Smacallan 1794dfe64dd3Smacallan if (*pjBuffer != 0x20) 1795dfe64dd3Smacallan { 1796dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1797dfe64dd3Smacallan } 1798dfe64dd3Smacallan 1799dfe64dd3Smacallan if (bEDIDCheckSum(pjBuffer, 256) != 0) 1800dfe64dd3Smacallan { 1801dfe64dd3Smacallan return ERROR_INVALID_PARAMETER; 1802dfe64dd3Smacallan } 1803dfe64dd3Smacallan 1804dfe64dd3Smacallan return NO_ERROR; 1805dfe64dd3Smacallan} 1806dfe64dd3Smacallan 1807dfe64dd3Smacallan//*************************************************************************\\ 1808dfe64dd3Smacallan// BOOLEAN bGetEDID 1809dfe64dd3Smacallan// 1810dfe64dd3Smacallan// Routine Description: 1811dfe64dd3Smacallan// For driver to get the monitor EDID through I2C. This function works similar 1812dfe64dd3Smacallan// with VideoPortDDCMonitorHelper() does. 1813dfe64dd3Smacallan// 1814dfe64dd3Smacallan// 1815dfe64dd3Smacallan// Arguments: 1816dfe64dd3Smacallan// pHWDE - Hardware extension object pointer 1817dfe64dd3Smacallan// ulChannelID - Channel ID 1818dfe64dd3Smacallan// pjEDIDBuffer - EDID Buffer 1819dfe64dd3Smacallan// ulBufferSize - Buffer size 1820dfe64dd3Smacallan// 1821dfe64dd3Smacallan// 1822dfe64dd3Smacallan// Return Value: 1823dfe64dd3Smacallan// Status of returning EDID. 1824dfe64dd3Smacallan// TRUE - success 1825dfe64dd3Smacallan// FALSE - failed 1826dfe64dd3Smacallan// 1827dfe64dd3Smacallan//**************************************************************************** 1828dfe64dd3SmacallanBOOLEAN bGetEDID( 1829dfe64dd3Smacallan PXGI_HW_DEVICE_INFO pHWDE, 1830dfe64dd3Smacallan ULONG ulChannelID, 1831dfe64dd3Smacallan PUCHAR pjEDIDBuffer, 1832dfe64dd3Smacallan ULONG ulBufferSize) 1833dfe64dd3Smacallan{ 1834dfe64dd3Smacallan I2CControl I2C; 1835dfe64dd3Smacallan VP_STATUS status; 1836dfe64dd3Smacallan 1837dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID() is called.\n")); 1838dfe64dd3Smacallan 1839dfe64dd3Smacallan if ((ulBufferSize != 0) && (pjEDIDBuffer != NULL)) 1840dfe64dd3Smacallan { 1841dfe64dd3Smacallan memset(pjEDIDBuffer, 0, ulBufferSize); 1842dfe64dd3Smacallan } 1843dfe64dd3Smacallan else 1844dfe64dd3Smacallan { 1845dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID()-(ulBufferSize == 0) || (pjEDIDBuffer == NULL)\n")); 1846dfe64dd3Smacallan return FALSE; 1847dfe64dd3Smacallan } 1848dfe64dd3Smacallan 1849dfe64dd3Smacallan if (I2COpen(pHWDE, I2C_OPEN, ulChannelID, &I2C) != NO_ERROR) 1850dfe64dd3Smacallan { 1851dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID()-I2COpen()-fail!\n")); 1852dfe64dd3Smacallan return FALSE; 1853dfe64dd3Smacallan } 1854dfe64dd3Smacallan 1855dfe64dd3Smacallan // Force Monitor using DDC2 protocal... 1856dfe64dd3Smacallan I2C.ClockRate = I2C_MAX_CLOCK_RATE; 1857dfe64dd3Smacallan I2C.Command = I2C_COMMAND_WRITE; 1858dfe64dd3Smacallan I2C.Flags = I2C_FLAGS_STOP; 1859dfe64dd3Smacallan I2C.Data = 0xFF; 1860dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 1861dfe64dd3Smacallan 1862dfe64dd3Smacallan // Reset I2C bus 1863dfe64dd3Smacallan I2C.Command = I2C_COMMAND_RESET; 1864dfe64dd3Smacallan I2CAccess(pHWDE, &I2C); 1865dfe64dd3Smacallan if (I2C.Status != I2C_STATUS_NOERROR) 1866dfe64dd3Smacallan { 1867dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID() fail: Reset I2C bus fail.\n")); 1868dfe64dd3Smacallan return FALSE; 1869dfe64dd3Smacallan } 1870dfe64dd3Smacallan 1871dfe64dd3Smacallan status = vGetEDID_2(pHWDE, &I2C, pjEDIDBuffer, ulBufferSize); 1872dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID()-vGetEDID_2-status=%d\n", status == NO_ERROR ? 1:0)); 1873dfe64dd3Smacallan 1874dfe64dd3Smacallan if (status != NO_ERROR) 1875dfe64dd3Smacallan { 1876dfe64dd3Smacallan usleep(5); 1877dfe64dd3Smacallan status = vGetEDID_1(pHWDE, &I2C, pjEDIDBuffer, ulBufferSize); 1878dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID()-vGetEDID_1-status=%d\n", status == NO_ERROR ? 1:0)); 1879dfe64dd3Smacallan 1880dfe64dd3Smacallan if (status == NO_ERROR) 1881dfe64dd3Smacallan { 1882dfe64dd3Smacallan if (*(pjEDIDBuffer+0x7E) != 0) 1883dfe64dd3Smacallan { 1884dfe64dd3Smacallan vGetEDIDExtensionBlocks(pHWDE, &I2C, pjEDIDBuffer+128, ulBufferSize-128); 1885dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID()-vGetEDIDExtensionBlocks()\n")); 1886dfe64dd3Smacallan } 1887dfe64dd3Smacallan } 1888dfe64dd3Smacallan else 1889dfe64dd3Smacallan { 1890dfe64dd3Smacallan ErrorF( "bGetEDID() fail !!\n"); 1891dfe64dd3Smacallan } 1892dfe64dd3Smacallan } 1893dfe64dd3Smacallan 1894dfe64dd3Smacallan I2COpen(pHWDE, I2C_CLOSE, ulChannelID, &I2C); 1895dfe64dd3Smacallan 1896dfe64dd3Smacallan PDEBUGI2C(ErrorF("bGetEDID()-return(%d)\n", status == NO_ERROR ? 1:0)); 1897dfe64dd3Smacallan return (status == NO_ERROR); 1898ecb1bcb9Sapb} 1899