Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenedid.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS VBE EDID management 00003 * 00004 * Copyright (C) 2006 Hervé Poussineau 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program 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 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 * 00020 */ 00021 00022 /* INCLUDES *******************************************************************/ 00023 00024 #include "vbemp.h" 00025 00026 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/ 00027 00028 static VOID NTAPI 00029 VBEWriteClockLine( 00030 PVOID HwDeviceExtension, 00031 UCHAR data) 00032 { 00033 INT10_BIOS_ARGUMENTS BiosRegisters; 00034 PVBE_DEVICE_EXTENSION VBEDeviceExtension = 00035 (PVBE_DEVICE_EXTENSION)HwDeviceExtension; 00036 00037 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00038 BiosRegisters.Eax = VBE_DDC; 00039 BiosRegisters.Ebx = VBE_DDC_WRITE_SCL_CLOCK_LINE; 00040 BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex; 00041 BiosRegisters.Edx = data; 00042 VBEDeviceExtension->Int10Interface.Int10CallBios( 00043 VBEDeviceExtension->Int10Interface.Context, 00044 &BiosRegisters); 00045 } 00046 00047 static VOID NTAPI 00048 VBEWriteDataLine( 00049 PVOID HwDeviceExtension, 00050 UCHAR data) 00051 { 00052 INT10_BIOS_ARGUMENTS BiosRegisters; 00053 PVBE_DEVICE_EXTENSION VBEDeviceExtension = 00054 (PVBE_DEVICE_EXTENSION)HwDeviceExtension; 00055 00056 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00057 BiosRegisters.Eax = VBE_DDC; 00058 BiosRegisters.Ebx = VBE_DDC_WRITE_SDA_DATA_LINE; 00059 BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex; 00060 BiosRegisters.Edx = data; 00061 VBEDeviceExtension->Int10Interface.Int10CallBios( 00062 VBEDeviceExtension->Int10Interface.Context, 00063 &BiosRegisters); 00064 } 00065 00066 static BOOLEAN NTAPI 00067 VBEReadClockLine( 00068 PVOID HwDeviceExtension) 00069 { 00070 INT10_BIOS_ARGUMENTS BiosRegisters; 00071 PVBE_DEVICE_EXTENSION VBEDeviceExtension = 00072 (PVBE_DEVICE_EXTENSION)HwDeviceExtension; 00073 00074 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00075 BiosRegisters.Eax = VBE_DDC; 00076 BiosRegisters.Ebx = VBE_DDC_READ_SCL_CLOCK_LINE; 00077 BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex; 00078 VBEDeviceExtension->Int10Interface.Int10CallBios( 00079 VBEDeviceExtension->Int10Interface.Context, 00080 &BiosRegisters); 00081 00082 return BiosRegisters.Edx; 00083 } 00084 00085 static BOOLEAN NTAPI 00086 VBEReadDataLine( 00087 PVOID HwDeviceExtension) 00088 { 00089 INT10_BIOS_ARGUMENTS BiosRegisters; 00090 PVBE_DEVICE_EXTENSION VBEDeviceExtension = 00091 (PVBE_DEVICE_EXTENSION)HwDeviceExtension; 00092 00093 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00094 BiosRegisters.Eax = VBE_DDC; 00095 BiosRegisters.Ebx = VBE_DDC_READ_SDA_DATA_LINE; 00096 BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex; 00097 VBEDeviceExtension->Int10Interface.Int10CallBios( 00098 VBEDeviceExtension->Int10Interface.Context, 00099 &BiosRegisters); 00100 00101 return BiosRegisters.Edx; 00102 } 00103 00104 static BOOLEAN 00105 VBEReadEdidUsingSCI( 00106 IN PVOID HwDeviceExtension, 00107 IN ULONG ChildIndex, 00108 OUT PVOID Edid) 00109 { 00110 INT10_BIOS_ARGUMENTS BiosRegisters; 00111 PVBE_DEVICE_EXTENSION VBEDeviceExtension = 00112 (PVBE_DEVICE_EXTENSION)HwDeviceExtension; 00113 DDC_CONTROL DDCControl; 00114 BOOLEAN ret; 00115 00116 VideoPortDebugPrint(Trace, "VBEMP: VBEReadEdidUsingSCI() called\n"); 00117 00118 /* 00119 * Check if graphic card support I²C interface 00120 */ 00121 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00122 BiosRegisters.Eax = VBE_DDC; 00123 BiosRegisters.Ebx = VBE_DDC_REPORT_CAPABILITIES; 00124 BiosRegisters.Ecx = ChildIndex; 00125 VBEDeviceExtension->Int10Interface.Int10CallBios( 00126 VBEDeviceExtension->Int10Interface.Context, 00127 &BiosRegisters); 00128 if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS) 00129 return FALSE; 00130 VideoPortDebugPrint(Info, "VBEMP: VBE/SCI version %x\n", BiosRegisters.Ecx); 00131 if ((BiosRegisters.Ebx & 0xF) != 0xF) 00132 return FALSE; 00133 00134 /* 00135 * Enable I²C interface 00136 */ 00137 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00138 BiosRegisters.Eax = VBE_DDC; 00139 BiosRegisters.Ebx = VBE_DDC_BEGIN_SCL_SDA_CONTROL; 00140 BiosRegisters.Ecx = ChildIndex; 00141 VBEDeviceExtension->Int10Interface.Int10CallBios( 00142 VBEDeviceExtension->Int10Interface.Context, 00143 &BiosRegisters); 00144 if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS) 00145 return FALSE; 00146 00147 /* 00148 * Read EDID information 00149 */ 00150 VBEDeviceExtension->CurrentChildIndex = ChildIndex; 00151 DDCControl.Size = sizeof(DDC_CONTROL); 00152 DDCControl.I2CCallbacks.WriteClockLine = VBEWriteClockLine; 00153 DDCControl.I2CCallbacks.WriteDataLine = VBEWriteDataLine; 00154 DDCControl.I2CCallbacks.ReadClockLine = VBEReadClockLine; 00155 DDCControl.I2CCallbacks.ReadDataLine = VBEReadDataLine; 00156 DDCControl.EdidSegment = 0; 00157 ret = VideoPortDDCMonitorHelper( 00158 HwDeviceExtension, 00159 &DDCControl, 00160 (PUCHAR)&Edid, 00161 MAX_SIZE_OF_EDID); 00162 00163 /* 00164 * Disable I²C interface 00165 */ 00166 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00167 BiosRegisters.Eax = VBE_DDC; 00168 BiosRegisters.Ebx = VBE_DDC_END_SCL_SDA_CONTROL; 00169 VBEDeviceExtension->Int10Interface.Int10CallBios( 00170 VBEDeviceExtension->Int10Interface.Context, 00171 &BiosRegisters); 00172 /* Ignore the possible error, as we did our best to prevent problems */ 00173 00174 return ret; 00175 } 00176 00177 static BOOLEAN 00178 VBEReadEdid( 00179 IN PVBE_DEVICE_EXTENSION VBEDeviceExtension, 00180 IN ULONG ChildIndex, 00181 OUT PVOID Edid) 00182 { 00183 INT10_BIOS_ARGUMENTS BiosRegisters; 00184 00185 VideoPortDebugPrint(Trace, "VBEMP: VBEReadEdid() called\n"); 00186 00187 /* 00188 * Directly read EDID information 00189 */ 00190 VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters)); 00191 BiosRegisters.Eax = VBE_DDC; 00192 BiosRegisters.Ebx = VBE_DDC_READ_EDID; 00193 BiosRegisters.Ecx = ChildIndex; 00194 BiosRegisters.Edx = 1; 00195 BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset; 00196 BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment; 00197 VBEDeviceExtension->Int10Interface.Int10CallBios( 00198 VBEDeviceExtension->Int10Interface.Context, 00199 &BiosRegisters); 00200 00201 if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS) 00202 return FALSE; 00203 00204 /* 00205 * Copy the EDID information to our buffer 00206 */ 00207 VBEDeviceExtension->Int10Interface.Int10ReadMemory( 00208 VBEDeviceExtension->Int10Interface.Context, 00209 VBEDeviceExtension->TrampolineMemorySegment, 00210 VBEDeviceExtension->TrampolineMemoryOffset, 00211 Edid, 00212 MAX_SIZE_OF_EDID); 00213 00214 return TRUE; 00215 } 00216 00217 VP_STATUS NTAPI 00218 VBEGetVideoChildDescriptor( 00219 IN PVOID HwDeviceExtension, 00220 IN PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, 00221 OUT PVIDEO_CHILD_TYPE VideoChildType, 00222 OUT PUCHAR pChildDescriptor, 00223 OUT PULONG UId, 00224 OUT PULONG pUnused) 00225 { 00226 PVBE_DEVICE_EXTENSION VBEDeviceExtension = 00227 (PVBE_DEVICE_EXTENSION)HwDeviceExtension; 00228 ULONG ChildIndex; 00229 00230 /* 00231 * We are called very early in device initialization, even before 00232 * VBEInitialize is called. So, our Int10 interface is not set. 00233 * Ignore this call, we will trigger another one later. 00234 */ 00235 if (VBEDeviceExtension->Int10Interface.Size == 0) 00236 return VIDEO_ENUM_NO_MORE_DEVICES; 00237 00238 if (ChildEnumInfo->Size != sizeof(VIDEO_CHILD_ENUM_INFO)) 00239 { 00240 VideoPortDebugPrint(Error, "VBEMP: Wrong VIDEO_CHILD_ENUM_INFO structure size\n"); 00241 return VIDEO_ENUM_NO_MORE_DEVICES; 00242 } 00243 else if (ChildEnumInfo->ChildDescriptorSize < MAX_SIZE_OF_EDID) 00244 { 00245 VideoPortDebugPrint(Warn, "VBEMP: Too small buffer for EDID\n"); 00246 return VIDEO_ENUM_NO_MORE_DEVICES; 00247 } 00248 else if (ChildEnumInfo->ChildIndex == DISPLAY_ADAPTER_HW_ID) 00249 { 00250 *VideoChildType = VideoChip; 00251 *UId = 0; 00252 return VIDEO_ENUM_MORE_DEVICES; /* FIXME: not sure... */ 00253 } 00254 00255 /* 00256 * Get Child ID 00257 */ 00258 if (ChildEnumInfo->ChildIndex != 0) 00259 ChildIndex = ChildEnumInfo->ChildIndex; 00260 else 00261 ChildIndex = ChildEnumInfo->ACPIHwId; 00262 VideoPortDebugPrint(Info, "VBEMP: ChildEnumInfo->ChildIndex %lu, ChildEnumInfo->ACPIHwId %lu => %lu\n", 00263 ChildEnumInfo->ChildIndex, ChildEnumInfo->ACPIHwId, ChildIndex); 00264 00265 /* 00266 * Try to read EDID information using 2 different methods. 00267 */ 00268 if (VBEReadEdid(HwDeviceExtension, ChildIndex, pChildDescriptor)) 00269 { 00270 VideoPortDebugPrint(Info, "VBEMP: EDID information read directly\n"); 00271 } 00272 else if (VBEReadEdidUsingSCI(HwDeviceExtension, ChildIndex, pChildDescriptor)) 00273 { 00274 VideoPortDebugPrint(Info, "VBEMP: EDID information read using I²C\n"); 00275 } 00276 else if (ChildEnumInfo->ChildIndex == 1) 00277 { 00278 /* We must have 1 monitor, so just report it with no EDID information */ 00279 VideoPortDebugPrint(Info, "VBEMP: Reporting monitor with no EDID information\n"); 00280 } 00281 else 00282 { 00283 VideoPortDebugPrint(Warn, "VBEMP: Unable to read EDID information\n"); 00284 return VIDEO_ENUM_NO_MORE_DEVICES; 00285 } 00286 00287 /* 00288 * Fill return data 00289 */ 00290 *VideoChildType = Monitor; 00291 if (ChildIndex == 0) 00292 { 00293 /* 00294 * This is the actual display adapter 00295 */ 00296 *UId = DISPLAY_ADAPTER_HW_ID; 00297 } 00298 else 00299 *UId = ChildIndex; 00300 *pUnused = 0; 00301 return VIDEO_ENUM_MORE_DEVICES; 00302 } Generated on Sun May 27 2012 04:38:11 for ReactOS by
1.7.6.1
|