ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

edid.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.