ReactOS  0.4.14-dev-583-g2a1ba2c
edid.c
Go to the documentation of this file.
1 /*
2  * ReactOS VBE EDID management
3  *
4  * Copyright (C) 2006 Herv Poussineau
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21 
22 /* INCLUDES *******************************************************************/
23 
24 #include "vbemp.h"
25 
26 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
27 
28 static VOID NTAPI
30  PVOID HwDeviceExtension,
31  UCHAR data)
32 {
33  INT10_BIOS_ARGUMENTS BiosRegisters;
34  PVBE_DEVICE_EXTENSION VBEDeviceExtension =
35  (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
36 
37  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
38  BiosRegisters.Eax = VBE_DDC;
39  BiosRegisters.Ebx = VBE_DDC_WRITE_SCL_CLOCK_LINE;
40  BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex;
41  BiosRegisters.Edx = data;
42  VBEDeviceExtension->Int10Interface.Int10CallBios(
43  VBEDeviceExtension->Int10Interface.Context,
44  &BiosRegisters);
45 }
46 
47 static VOID NTAPI
49  PVOID HwDeviceExtension,
50  UCHAR data)
51 {
52  INT10_BIOS_ARGUMENTS BiosRegisters;
53  PVBE_DEVICE_EXTENSION VBEDeviceExtension =
54  (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
55 
56  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
57  BiosRegisters.Eax = VBE_DDC;
58  BiosRegisters.Ebx = VBE_DDC_WRITE_SDA_DATA_LINE;
59  BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex;
60  BiosRegisters.Edx = data;
61  VBEDeviceExtension->Int10Interface.Int10CallBios(
62  VBEDeviceExtension->Int10Interface.Context,
63  &BiosRegisters);
64 }
65 
66 static BOOLEAN NTAPI
68  PVOID HwDeviceExtension)
69 {
70  INT10_BIOS_ARGUMENTS BiosRegisters;
71  PVBE_DEVICE_EXTENSION VBEDeviceExtension =
72  (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
73 
74  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
75  BiosRegisters.Eax = VBE_DDC;
76  BiosRegisters.Ebx = VBE_DDC_READ_SCL_CLOCK_LINE;
77  BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex;
78  VBEDeviceExtension->Int10Interface.Int10CallBios(
79  VBEDeviceExtension->Int10Interface.Context,
80  &BiosRegisters);
81 
82  return BiosRegisters.Edx;
83 }
84 
85 static BOOLEAN NTAPI
87  PVOID HwDeviceExtension)
88 {
89  INT10_BIOS_ARGUMENTS BiosRegisters;
90  PVBE_DEVICE_EXTENSION VBEDeviceExtension =
91  (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
92 
93  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
94  BiosRegisters.Eax = VBE_DDC;
95  BiosRegisters.Ebx = VBE_DDC_READ_SDA_DATA_LINE;
96  BiosRegisters.Ecx = VBEDeviceExtension->CurrentChildIndex;
97  VBEDeviceExtension->Int10Interface.Int10CallBios(
98  VBEDeviceExtension->Int10Interface.Context,
99  &BiosRegisters);
100 
101  return BiosRegisters.Edx;
102 }
103 
104 static BOOLEAN
106  IN PVOID HwDeviceExtension,
107  IN ULONG ChildIndex,
108  OUT PVOID Edid)
109 {
110  INT10_BIOS_ARGUMENTS BiosRegisters;
111  PVBE_DEVICE_EXTENSION VBEDeviceExtension =
112  (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
113  DDC_CONTROL DDCControl;
114  BOOLEAN ret;
115 
116  VideoPortDebugPrint(Trace, "VBEMP: VBEReadEdidUsingSCI() called\n");
117 
118  /*
119  * Check if graphic card support IC interface
120  */
121  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
122  BiosRegisters.Eax = VBE_DDC;
123  BiosRegisters.Ebx = VBE_DDC_REPORT_CAPABILITIES;
124  BiosRegisters.Ecx = ChildIndex;
125  VBEDeviceExtension->Int10Interface.Int10CallBios(
126  VBEDeviceExtension->Int10Interface.Context,
127  &BiosRegisters);
128  if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
129  return FALSE;
130  VideoPortDebugPrint(Info, "VBEMP: VBE/SCI version %x\n", BiosRegisters.Ecx);
131  if ((BiosRegisters.Ebx & 0xF) != 0xF)
132  return FALSE;
133 
134  /*
135  * Enable IC interface
136  */
137  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
138  BiosRegisters.Eax = VBE_DDC;
139  BiosRegisters.Ebx = VBE_DDC_BEGIN_SCL_SDA_CONTROL;
140  BiosRegisters.Ecx = ChildIndex;
141  VBEDeviceExtension->Int10Interface.Int10CallBios(
142  VBEDeviceExtension->Int10Interface.Context,
143  &BiosRegisters);
144  if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
145  return FALSE;
146 
147  /*
148  * Read EDID information
149  */
150  VBEDeviceExtension->CurrentChildIndex = ChildIndex;
151  DDCControl.Size = sizeof(DDC_CONTROL);
156  DDCControl.EdidSegment = 0;
158  HwDeviceExtension,
159  &DDCControl,
160  (PUCHAR)&Edid,
162 
163  /*
164  * Disable IC interface
165  */
166  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
167  BiosRegisters.Eax = VBE_DDC;
168  BiosRegisters.Ebx = VBE_DDC_END_SCL_SDA_CONTROL;
169  VBEDeviceExtension->Int10Interface.Int10CallBios(
170  VBEDeviceExtension->Int10Interface.Context,
171  &BiosRegisters);
172  /* Ignore the possible error, as we did our best to prevent problems */
173 
174  return ret;
175 }
176 
177 static BOOLEAN
179  IN PVBE_DEVICE_EXTENSION VBEDeviceExtension,
180  IN ULONG ChildIndex,
181  OUT PVOID Edid)
182 {
183  INT10_BIOS_ARGUMENTS BiosRegisters;
184 
185  VideoPortDebugPrint(Trace, "VBEMP: VBEReadEdid() called\n");
186 
187  /*
188  * Directly read EDID information
189  */
190  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
191  BiosRegisters.Eax = VBE_DDC;
192  BiosRegisters.Ebx = VBE_DDC_READ_EDID;
193  BiosRegisters.Ecx = ChildIndex;
194  BiosRegisters.Edx = 1;
195  BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset;
196  BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
197  VBEDeviceExtension->Int10Interface.Int10CallBios(
198  VBEDeviceExtension->Int10Interface.Context,
199  &BiosRegisters);
200 
201  if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
202  return FALSE;
203 
204  /*
205  * Copy the EDID information to our buffer
206  */
207  VBEDeviceExtension->Int10Interface.Int10ReadMemory(
208  VBEDeviceExtension->Int10Interface.Context,
209  VBEDeviceExtension->TrampolineMemorySegment,
210  VBEDeviceExtension->TrampolineMemoryOffset,
211  Edid,
213 
214  return TRUE;
215 }
216 
219  IN PVOID HwDeviceExtension,
220  IN PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
221  OUT PVIDEO_CHILD_TYPE VideoChildType,
222  OUT PUCHAR pChildDescriptor,
223  OUT PULONG UId,
224  OUT PULONG pUnused)
225 {
226  PVBE_DEVICE_EXTENSION VBEDeviceExtension =
227  (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
228  ULONG ChildIndex;
229 
230  /*
231  * We are called very early in device initialization, even before
232  * VBEInitialize is called. So, our Int10 interface is not set.
233  * Ignore this call, we will trigger another one later.
234  */
235  if (VBEDeviceExtension->Int10Interface.Size == 0)
237 
238  if (ChildEnumInfo->Size != sizeof(VIDEO_CHILD_ENUM_INFO))
239  {
240  VideoPortDebugPrint(Error, "VBEMP: Wrong VIDEO_CHILD_ENUM_INFO structure size\n");
242  }
243  else if (ChildEnumInfo->ChildDescriptorSize < MAX_SIZE_OF_EDID)
244  {
245  VideoPortDebugPrint(Warn, "VBEMP: Too small buffer for EDID\n");
247  }
248  else if (ChildEnumInfo->ChildIndex == DISPLAY_ADAPTER_HW_ID)
249  {
250  *VideoChildType = VideoChip;
251  *UId = 0;
252  return VIDEO_ENUM_MORE_DEVICES; /* FIXME: not sure... */
253  }
254 
255  /*
256  * Get Child ID
257  */
258  if (ChildEnumInfo->ChildIndex != 0)
259  ChildIndex = ChildEnumInfo->ChildIndex;
260  else
261  ChildIndex = ChildEnumInfo->ACPIHwId;
262  VideoPortDebugPrint(Info, "VBEMP: ChildEnumInfo->ChildIndex %lu, ChildEnumInfo->ACPIHwId %lu => %lu\n",
263  ChildEnumInfo->ChildIndex, ChildEnumInfo->ACPIHwId, ChildIndex);
264 
265  /*
266  * Try to read EDID information using 2 different methods.
267  */
268  if (VBEReadEdid(HwDeviceExtension, ChildIndex, pChildDescriptor))
269  {
270  VideoPortDebugPrint(Info, "VBEMP: EDID information read directly\n");
271  }
272  else if (VBEReadEdidUsingSCI(HwDeviceExtension, ChildIndex, pChildDescriptor))
273  {
274  VideoPortDebugPrint(Info, "VBEMP: EDID information read using IC\n");
275  }
276  else if (ChildEnumInfo->ChildIndex == 1)
277  {
278  /* We must have 1 monitor, so just report it with no EDID information */
279  VideoPortDebugPrint(Info, "VBEMP: Reporting monitor with no EDID information\n");
280  }
281  else
282  {
283  VideoPortDebugPrint(Warn, "VBEMP: Unable to read EDID information\n");
285  }
286 
287  /*
288  * Fill return data
289  */
290  *VideoChildType = Monitor;
291  if (ChildIndex == 0)
292  {
293  /*
294  * This is the actual display adapter
295  */
296  *UId = DISPLAY_ADAPTER_HW_ID;
297  }
298  else
299  *UId = ChildIndex;
300  *pUnused = 0;
302 }
VP_STATUS NTAPI VBEGetVideoChildDescriptor(IN PVOID HwDeviceExtension, IN PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, OUT PVIDEO_CHILD_TYPE VideoChildType, OUT PUCHAR pChildDescriptor, OUT PULONG UId, OUT PULONG pUnused)
Definition: edid.c:218
#define DISPLAY_ADAPTER_HW_ID
Definition: video.h:115
static BOOLEAN NTAPI VBEReadClockLine(PVOID HwDeviceExtension)
Definition: edid.c:67
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
IN UCHAR EdidSegment
Definition: video.h:700
unsigned char * PUCHAR
Definition: retypes.h:3
#define VBE_DDC_READ_SDA_DATA_LINE
Definition: vbemp.h:80
#define VBE_GETRETURNCODE(x)
Definition: vbemp.h:100
static BOOLEAN VBEReadEdid(IN PVBE_DEVICE_EXTENSION VBEDeviceExtension, IN ULONG ChildIndex, OUT PVOID Edid)
Definition: edid.c:178
#define VBE_DDC_WRITE_SDA_DATA_LINE
Definition: vbemp.h:78
VPAPI VOID NTAPI VideoPortZeroMemory(IN PVOID Destination, IN ULONG Length)
struct TraceInfo Info
IN I2C_CALLBACKS I2CCallbacks
Definition: video.h:699
#define VBE_DDC_WRITE_SCL_CLOCK_LINE
Definition: vbemp.h:77
#define VBE_SUCCESS
Definition: vbemp.h:95
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static BOOLEAN VBEReadEdidUsingSCI(IN PVOID HwDeviceExtension, IN ULONG ChildIndex, OUT PVOID Edid)
Definition: edid.c:105
unsigned char BOOLEAN
IN PVIDEO_READ_CLOCK_LINE ReadClockLine
Definition: video.h:372
IN PVIDEO_READ_DATA_LINE ReadDataLine
Definition: video.h:373
#define VBE_DDC_READ_SCL_CLOCK_LINE
Definition: vbemp.h:79
static BOOLEAN NTAPI VBEReadDataLine(PVOID HwDeviceExtension)
Definition: edid.c:86
#define VIDEO_ENUM_MORE_DEVICES
Definition: video.h:139
#define VBE_DDC
Definition: vbemp.h:67
IN PVIDEO_WRITE_CLOCK_LINE WriteClockLine
Definition: video.h:370
#define VBE_DDC_END_SCL_SDA_CONTROL
Definition: vbemp.h:76
Definition: video.h:581
#define VBE_DDC_BEGIN_SCL_SDA_CONTROL
Definition: vbemp.h:75
#define MAX_SIZE_OF_EDID
Definition: vbemp.h:187
BOOL Error
Definition: chkdsk.c:66
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct _DDC_CONTROL DDC_CONTROL
IN PVIDEO_WRITE_DATA_LINE WriteDataLine
Definition: video.h:371
unsigned char UCHAR
Definition: xmlstorage.h:181
int ret
#define Trace(x)
Definition: zutil.h:197
VIDEO_PORT_INT10_INTERFACE Int10Interface
Definition: vbemp.h:194
ULONG CurrentChildIndex
Definition: vbemp.h:210
Definition: video.h:270
unsigned int * PULONG
Definition: retypes.h:1
struct VBE_DEVICE_EXTENSION * PVBE_DEVICE_EXTENSION
static VOID NTAPI VBEWriteClockLine(PVOID HwDeviceExtension, UCHAR data)
Definition: edid.c:29
IN ULONG Size
Definition: video.h:698
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
OUT PINT10_CALL_BIOS Int10CallBios
Definition: video.h:782
LONG VP_STATUS
Definition: video.h:153
enum _VIDEO_CHILD_TYPE * PVIDEO_CHILD_TYPE
#define VBE_DDC_READ_EDID
Definition: vbemp.h:73
VPAPI VOID __cdecl VideoPortDebugPrint(IN VIDEO_DEBUG_LEVEL DebugPrintLevel, IN PSTR DebugMessage, IN ...)
static VOID NTAPI VBEWriteDataLine(PVOID HwDeviceExtension, UCHAR data)
Definition: edid.c:48
#define VIDEO_ENUM_NO_MORE_DEVICES
Definition: video.h:140
VPAPI BOOLEAN NTAPI VideoPortDDCMonitorHelper(IN PVOID HwDeviceExtension, IN PVOID DDCControl, IN OUT PUCHAR EdidBuffer, IN ULONG EdidBufferSize)
#define VBE_DDC_REPORT_CAPABILITIES
Definition: vbemp.h:74