Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenddc.c
Go to the documentation of this file.
00001 /* 00002 * VideoPort driver 00003 * 00004 * Copyright (C) 2002, 2003, 2004 ReactOS Team 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 * 00020 */ 00021 00022 #include "videoprt.h" 00023 00024 #define DDC_EEPROM_ADDRESS 0xA0 00025 00026 /* PRIVATE FUNCTIONS **********************************************************/ 00027 00028 #define LOW 0 00029 #define HIGH 1 00030 #define WRITE 0 00031 #define READ 1 00032 #define READ_SDA() (i2c->ReadDataLine(HwDeviceExtension)) 00033 #define READ_SCL() (i2c->ReadClockLine(HwDeviceExtension)) 00034 #define WRITE_SDA(state) (i2c->WriteDataLine(HwDeviceExtension, state)) 00035 #define WRITE_SCL(state) (i2c->WriteClockLine(HwDeviceExtension, state)) 00036 00037 static LARGE_INTEGER HalfPeriodDelay = {{0, 70}}; 00038 #define DELAY_HALF() KeDelayExecutionThread(KernelMode, FALSE, &HalfPeriodDelay) 00039 00040 00041 static BOOL 00042 I2CWrite(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Data) 00043 { 00044 UCHAR Bit; 00045 BOOL Ack; 00046 00047 /* transmit data */ 00048 for (Bit = (1 << 7); Bit != 0; Bit >>= 1) 00049 { 00050 WRITE_SCL(LOW); 00051 WRITE_SDA((Data & Bit) ? HIGH : LOW); 00052 DELAY_HALF(); 00053 WRITE_SCL(HIGH); 00054 DELAY_HALF(); 00055 } 00056 00057 /* get ack */ 00058 WRITE_SCL(LOW); 00059 WRITE_SDA(HIGH); 00060 DELAY_HALF(); 00061 WRITE_SCL(HIGH); 00062 do 00063 { 00064 DELAY_HALF(); 00065 } 00066 while (READ_SCL() != HIGH); 00067 Ack = (READ_SDA() == LOW); 00068 DELAY_HALF(); 00069 00070 INFO_(VIDEOPRT, "I2CWrite: %s\n", Ack ? "Ack" : "Nak"); 00071 return Ack; 00072 } 00073 00074 00075 static UCHAR 00076 I2CRead(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, BOOL Ack) 00077 { 00078 INT Bit = 0x80; 00079 UCHAR Data = 0; 00080 00081 /* pull down SCL and release SDA */ 00082 WRITE_SCL(LOW); 00083 WRITE_SDA(HIGH); 00084 00085 /* read byte */ 00086 for (Bit = (1 << 7); Bit != 0; Bit >>= 1) 00087 { 00088 WRITE_SCL(LOW); 00089 DELAY_HALF(); 00090 WRITE_SCL(HIGH); 00091 DELAY_HALF(); 00092 if (READ_SDA() == HIGH) 00093 Data |= Bit; 00094 } 00095 00096 /* send ack/nak */ 00097 WRITE_SCL(LOW); 00098 WRITE_SDA(Ack ? LOW : HIGH); 00099 DELAY_HALF(); 00100 WRITE_SCL(HIGH); 00101 do 00102 { 00103 DELAY_HALF(); 00104 } 00105 while (READ_SCL() != HIGH); 00106 00107 return Data; 00108 } 00109 00110 00111 static VOID 00112 I2CStop(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c) 00113 { 00114 WRITE_SCL(LOW); 00115 WRITE_SDA(LOW); 00116 DELAY_HALF(); 00117 WRITE_SCL(HIGH); 00118 DELAY_HALF(); 00119 WRITE_SDA(HIGH); 00120 } 00121 00122 00123 static BOOL 00124 I2CStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address) 00125 { 00126 /* make sure the bus is free */ 00127 if (READ_SDA() == LOW || READ_SCL() == LOW) 00128 { 00129 WARN_(VIDEOPRT, "I2CStart: Bus is not free!\n"); 00130 return FALSE; 00131 } 00132 00133 /* send address */ 00134 WRITE_SDA(LOW); 00135 DELAY_HALF(); 00136 if (!I2CWrite(HwDeviceExtension, i2c, Address)) 00137 { 00138 /* ??release the bus?? */ 00139 I2CStop(HwDeviceExtension, i2c); 00140 WARN_(VIDEOPRT, "I2CStart: Device not found (Address = 0x%x)\n", Address); 00141 return FALSE; 00142 } 00143 00144 INFO_(VIDEOPRT, "I2CStart: SUCCESS!\n"); 00145 return TRUE; 00146 } 00147 00148 00149 static BOOL 00150 I2CRepStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address) 00151 { 00152 /* setup lines for repeated start condition */ 00153 WRITE_SCL(LOW); 00154 DELAY_HALF(); 00155 WRITE_SDA(HIGH); 00156 DELAY_HALF(); 00157 WRITE_SCL(HIGH); 00158 DELAY_HALF(); 00159 00160 return I2CStart(HwDeviceExtension, i2c, Address); 00161 } 00162 00163 /* PUBLIC FUNCTIONS ***********************************************************/ 00164 00165 /* 00166 * @implemented 00167 */ 00168 00169 BOOLEAN NTAPI 00170 VideoPortDDCMonitorHelper( 00171 PVOID HwDeviceExtension, 00172 PVOID I2CFunctions, 00173 PUCHAR pEdidBuffer, 00174 ULONG EdidBufferSize 00175 ) 00176 { 00177 PDDC_CONTROL ddc = (PDDC_CONTROL)I2CFunctions; 00178 PI2C_CALLBACKS i2c = &ddc->I2CCallbacks; 00179 INT Count, i; 00180 PUCHAR pBuffer = (PUCHAR)pEdidBuffer; 00181 BOOL Ack; 00182 00183 TRACE_(VIDEOPRT, "VideoPortDDCMonitorHelper()\n"); 00184 00185 ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL); 00186 if (ddc->Size != sizeof (ddc)) 00187 { 00188 WARN_(VIDEOPRT, "ddc->Size != %d (%d)\n", sizeof (ddc), ddc->Size); 00189 return FALSE; 00190 } 00191 00192 /* select eeprom */ 00193 if (!I2CStart(HwDeviceExtension, i2c, DDC_EEPROM_ADDRESS | WRITE)) 00194 return FALSE; 00195 /* set address */ 00196 if (!I2CWrite(HwDeviceExtension, i2c, 0x00)) 00197 return FALSE; 00198 /* change into read mode */ 00199 if (!I2CRepStart(HwDeviceExtension, i2c, DDC_EEPROM_ADDRESS | READ)) 00200 return FALSE; 00201 /* read eeprom */ 00202 RtlZeroMemory(pEdidBuffer, EdidBufferSize); 00203 Count = min(128, EdidBufferSize); 00204 for (i = 0; i < Count; i++) 00205 { 00206 Ack = ((i + 1) < Count); 00207 pBuffer[i] = I2CRead(HwDeviceExtension, i2c, Ack); 00208 } 00209 I2CStop(HwDeviceExtension, i2c); 00210 00211 /* check EDID header */ 00212 if (pBuffer[0] != 0x00 || pBuffer[1] != 0xff || 00213 pBuffer[2] != 0xff || pBuffer[3] != 0xff || 00214 pBuffer[4] != 0xff || pBuffer[5] != 0xff || 00215 pBuffer[6] != 0xff || pBuffer[7] != 0x00) 00216 { 00217 WARN_(VIDEOPRT, "VideoPortDDCMonitorHelper(): Invalid EDID header!\n"); 00218 return FALSE; 00219 } 00220 00221 INFO_(VIDEOPRT, "VideoPortDDCMonitorHelper(): EDID version %d rev. %d\n", pBuffer[18], pBuffer[19]); 00222 INFO_(VIDEOPRT, "VideoPortDDCMonitorHelper() - SUCCESS!\n"); 00223 return TRUE; 00224 } 00225 Generated on Sun May 27 2012 04:38:13 for ReactOS by
1.7.6.1
|