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

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

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