ReactOS 0.4.15-dev-8096-ga0eec98
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
40static LARGE_INTEGER HalfPeriodDelay = {{0, 70}};
41#define DELAY_HALF() KeDelayExecutionThread(KernelMode, FALSE, &HalfPeriodDelay)
42
43
44static BOOL
45I2CWrite(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 {
54 WRITE_SDA((Data & Bit) ? HIGH : LOW);
55 DELAY_HALF();
57 DELAY_HALF();
58 }
59
60 /* get ack */
63 DELAY_HALF();
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
78static UCHAR
79I2CRead(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, BOOL Ack)
80{
81 INT Bit = 0x80;
82 UCHAR Data = 0;
83
84 /* pull down SCL and release SDA */
87
88 /* read byte */
89 for (Bit = (1 << 7); Bit != 0; Bit >>= 1)
90 {
92 DELAY_HALF();
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();
104 do
105 {
106 DELAY_HALF();
107 }
108 while (READ_SCL() != HIGH);
109
110 return Data;
111}
112
113
114static VOID
115I2CStop(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c)
116{
117 WRITE_SCL(LOW);
118 WRITE_SDA(LOW);
119 DELAY_HALF();
121 DELAY_HALF();
123}
124
125
126static BOOL
127I2CStart(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
152static BOOL
154{
155 /* setup lines for repeated start condition */
156 WRITE_SCL(LOW);
157 DELAY_HALF();
159 DELAY_HALF();
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}
unsigned char BOOLEAN
#define WRITE_SDA(state)
Definition: ddc.c:37
static BOOL I2CRepStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
Definition: ddc.c:153
static UCHAR I2CRead(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, BOOL Ack)
Definition: ddc.c:79
static BOOL I2CWrite(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Data)
Definition: ddc.c:45
#define DDC_EEPROM_ADDRESS
Definition: ddc.c:27
#define HIGH
Definition: ddc.c:32
static BOOL I2CStart(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c, UCHAR Address)
Definition: ddc.c:127
#define DELAY_HALF()
Definition: ddc.c:41
#define WRITE
Definition: ddc.c:33
static LARGE_INTEGER HalfPeriodDelay
Definition: ddc.c:40
#define WRITE_SCL(state)
Definition: ddc.c:38
#define LOW
Definition: ddc.c:31
BOOLEAN NTAPI VideoPortDDCMonitorHelper(PVOID HwDeviceExtension, PVOID I2CFunctions, PUCHAR pEdidBuffer, ULONG EdidBufferSize)
Definition: ddc.c:173
#define READ
Definition: ddc.c:34
static VOID I2CStop(PVOID HwDeviceExtension, PI2C_CALLBACKS i2c)
Definition: ddc.c:115
#define READ_SCL()
Definition: ddc.c:36
#define READ_SDA()
Definition: ddc.c:35
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE_(x)
Definition: compat.h:76
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
unsigned int BOOL
Definition: ntddk_ex.h:94
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
#define min(a, b)
Definition: monoChain.cc:55
int Count
Definition: noreturn.cpp:7
static WCHAR Address[46]
Definition: ping.c:68
PVOID pBuffer
struct _DDC_CONTROL * PDDC_CONTROL
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
IN ULONG Size
Definition: video.h:706
IN I2C_CALLBACKS I2CCallbacks
Definition: video.h:707
#define NTAPI
Definition: typedefs.h:36
int32_t INT
Definition: typedefs.h:58
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
unsigned char UCHAR
Definition: xmlstorage.h:181