ReactOS  0.4.15-dev-1377-ga59cecd
ddc.c
Go to the documentation of this file.
1 /*
2  * VideoPort driver
3  *
4  * Copyright (C) 2002, 2003, 2004 ReactOS Team
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  */
21 
22 #include "videoprt.h"
23 
24 #define NDEBUG
25 #include <debug.h>
26 
27 #define DDC_EEPROM_ADDRESS 0xA0
28 
29 /* PRIVATE FUNCTIONS **********************************************************/
30 
31 #define LOW 0
32 #define HIGH 1
33 #define WRITE 0
34 #define READ 1
35 #define READ_SDA() (i2c->ReadDataLine(HwDeviceExtension))
36 #define READ_SCL() (i2c->ReadClockLine(HwDeviceExtension))
37 #define WRITE_SDA(state) (i2c->WriteDataLine(HwDeviceExtension, state))
38 #define WRITE_SCL(state) (i2c->WriteClockLine(HwDeviceExtension, state))
39 
40 static LARGE_INTEGER HalfPeriodDelay = {{0, 70}};
41 #define DELAY_HALF() KeDelayExecutionThread(KernelMode, FALSE, &HalfPeriodDelay)
42 
43 
44 static BOOL
45 I2CWrite(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Data)
46 {
47  UCHAR Bit;
48  BOOL Ack;
49 
50  /* transmit data */
51  for (Bit = (1 << 7); Bit != 0; Bit >>= 1)
52  {
53  WRITE_SCL(LOW);
54  WRITE_SDA((Data & Bit) ? HIGH : LOW);
55  DELAY_HALF();
56  WRITE_SCL(HIGH);
57  DELAY_HALF();
58  }
59 
60  /* get ack */
61  WRITE_SCL(LOW);
62  WRITE_SDA(HIGH);
63  DELAY_HALF();
64  WRITE_SCL(HIGH);
65  do
66  {
67  DELAY_HALF();
68  }
69  while (READ_SCL() != HIGH);
70  Ack = (READ_SDA() == LOW);
71  DELAY_HALF();
72 
73  INFO_(VIDEOPRT, "I2CWrite: %s\n", Ack ? "Ack" : "Nak");
74  return Ack;
75 }
76 
77 
78 static UCHAR
79 I2CRead(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, BOOL Ack)
80 {
81  INT Bit = 0x80;
82  UCHAR Data = 0;
83 
84  /* pull down SCL and release SDA */
85  WRITE_SCL(LOW);
86  WRITE_SDA(HIGH);
87 
88  /* read byte */
89  for (Bit = (1 << 7); Bit != 0; Bit >>= 1)
90  {
91  WRITE_SCL(LOW);
92  DELAY_HALF();
93  WRITE_SCL(HIGH);
94  DELAY_HALF();
95  if (READ_SDA() == HIGH)
96  Data |= Bit;
97  }
98 
99  /* send ack/nak */
100  WRITE_SCL(LOW);
101  WRITE_SDA(Ack ? LOW : HIGH);
102  DELAY_HALF();
103  WRITE_SCL(HIGH);
104  do
105  {
106  DELAY_HALF();
107  }
108  while (READ_SCL() != HIGH);
109 
110  return Data;
111 }
112 
113 
114 static VOID
115 I2CStop(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c)
116 {
117  WRITE_SCL(LOW);
118  WRITE_SDA(LOW);
119  DELAY_HALF();
120  WRITE_SCL(HIGH);
121  DELAY_HALF();
122  WRITE_SDA(HIGH);
123 }
124 
125 
126 static BOOL
127 I2CStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
128 {
129  /* make sure the bus is free */
130  if (READ_SDA() == LOW || READ_SCL() == LOW)
131  {
132  WARN_(VIDEOPRT, "I2CStart: Bus is not free!\n");
133  return FALSE;
134  }
135 
136  /* send address */
137  WRITE_SDA(LOW);
138  DELAY_HALF();
139  if (!I2CWrite(HwDeviceExtension, i2c, Address))
140  {
141  /* ??release the bus?? */
142  I2CStop(HwDeviceExtension, i2c);
143  WARN_(VIDEOPRT, "I2CStart: Device not found (Address = 0x%x)\n", Address);
144  return FALSE;
145  }
146 
147  INFO_(VIDEOPRT, "I2CStart: SUCCESS!\n");
148  return TRUE;
149 }
150 
151 
152 static BOOL
153 I2CRepStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
154 {
155  /* setup lines for repeated start condition */
156  WRITE_SCL(LOW);
157  DELAY_HALF();
158  WRITE_SDA(HIGH);
159  DELAY_HALF();
160  WRITE_SCL(HIGH);
161  DELAY_HALF();
162 
163  return I2CStart(HwDeviceExtension, i2c, Address);
164 }
165 
166 /* PUBLIC FUNCTIONS ***********************************************************/
167 
168 /*
169  * @implemented
170  */
171 
174  PVOID HwDeviceExtension,
175  PVOID I2CFunctions,
176  PUCHAR pEdidBuffer,
177  ULONG EdidBufferSize
178  )
179 {
180  PDDC_CONTROL ddc = (PDDC_CONTROL)I2CFunctions;
181  PI2C_CALLBACKS i2c = &ddc->I2CCallbacks;
182  INT Count, i;
183  PUCHAR pBuffer = (PUCHAR)pEdidBuffer;
184  BOOL Ack;
185 
186  TRACE_(VIDEOPRT, "VideoPortDDCMonitorHelper()\n");
187 
189  if (ddc->Size != sizeof (ddc))
190  {
191  WARN_(VIDEOPRT, "ddc->Size != %d (%d)\n", sizeof (ddc), ddc->Size);
192  return FALSE;
193  }
194 
195  /* select eeprom */
196  if (!I2CStart(HwDeviceExtension, i2c, DDC_EEPROM_ADDRESS | WRITE))
197  return FALSE;
198  /* set address */
199  if (!I2CWrite(HwDeviceExtension, i2c, 0x00))
200  return FALSE;
201  /* change into read mode */
202  if (!I2CRepStart(HwDeviceExtension, i2c, DDC_EEPROM_ADDRESS | READ))
203  return FALSE;
204  /* read eeprom */
205  RtlZeroMemory(pEdidBuffer, EdidBufferSize);
206  Count = min(128, EdidBufferSize);
207  for (i = 0; i < Count; i++)
208  {
209  Ack = ((i + 1) < Count);
210  pBuffer[i] = I2CRead(HwDeviceExtension, i2c, Ack);
211  }
212  I2CStop(HwDeviceExtension, i2c);
213 
214  /* check EDID header */
215  if (pBuffer[0] != 0x00 || pBuffer[1] != 0xff ||
216  pBuffer[2] != 0xff || pBuffer[3] != 0xff ||
217  pBuffer[4] != 0xff || pBuffer[5] != 0xff ||
218  pBuffer[6] != 0xff || pBuffer[7] != 0x00)
219  {
220  WARN_(VIDEOPRT, "VideoPortDDCMonitorHelper(): Invalid EDID header!\n");
221  return FALSE;
222  }
223 
224  INFO_(VIDEOPRT, "VideoPortDDCMonitorHelper(): EDID version %d rev. %d\n", pBuffer[18], pBuffer[19]);
225  INFO_(VIDEOPRT, "VideoPortDDCMonitorHelper() - SUCCESS!\n");
226  return TRUE;
227 }
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define INFO_(ch,...)
Definition: debug.h:159
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
#define READ
Definition: ddc.c:34
#define LOW
Definition: ddc.c:31
int32_t INT
Definition: typedefs.h:58
IN I2C_CALLBACKS I2CCallbacks
Definition: video.h:699
#define WRITE_SCL(state)
Definition: ddc.c:38
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned char BOOLEAN
struct _DDC_CONTROL * PDDC_CONTROL
PVOID pBuffer
static WCHAR Address[46]
Definition: ping.c:68
#define READ_SDA()
Definition: ddc.c:35
#define TRACE_(x)
Definition: compat.h:76
int Count
Definition: noreturn.cpp:7
#define HIGH
Definition: ddc.c:32
static BOOL I2CRepStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
Definition: ddc.c:153
#define WRITE
Definition: ddc.c:33
static VOID I2CStop(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c)
Definition: ddc.c:115
static BOOL I2CWrite(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Data)
Definition: ddc.c:45
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DELAY_HALF()
Definition: ddc.c:41
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DDC_EEPROM_ADDRESS
Definition: ddc.c:27
static UCHAR I2CRead(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, BOOL Ack)
Definition: ddc.c:79
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOLEAN NTAPI VideoPortDDCMonitorHelper(PVOID HwDeviceExtension, PVOID I2CFunctions, PUCHAR pEdidBuffer, ULONG EdidBufferSize)
Definition: ddc.c:173
#define READ_SCL()
Definition: ddc.c:36
#define min(a, b)
Definition: monoChain.cc:55
IN ULONG Size
Definition: video.h:698
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static BOOL I2CStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
Definition: ddc.c:127
#define WRITE_SDA(state)
Definition: ddc.c:37
#define WARN_(ch,...)
Definition: debug.h:157
static LARGE_INTEGER HalfPeriodDelay
Definition: ddc.c:40