ReactOS  0.4.15-dev-5452-g3c95c95
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  * Check if DDC1/DDC2 is supported
189  */
190  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
191  BiosRegisters.Eax = VBE_DDC;
192  VBEDeviceExtension->Int10Interface.Int10CallBios(
193  VBEDeviceExtension->Int10Interface.Context,
194  &BiosRegisters);
195  if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
196  return FALSE;
197  if ((BiosRegisters.Ebx & 3) == 0)
198  return FALSE;
199 
200  /*
201  * Directly read EDID information
202  */
203  VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
204  BiosRegisters.Eax = VBE_DDC;
205  BiosRegisters.Ebx = VBE_DDC_READ_EDID;
206  BiosRegisters.Ecx = ChildIndex;
207  BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset;
208  BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
209  VBEDeviceExtension->Int10Interface.Int10CallBios(
210  VBEDeviceExtension->Int10Interface.Context,
211  &BiosRegisters);
212 
213  if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
214  return FALSE;
215 
216  /*
217  * Copy the EDID information to our buffer
218  */
219  VBEDeviceExtension->Int10Interface.Int10ReadMemory(
220  VBEDeviceExtension->Int10Interface.Context,
221  VBEDeviceExtension->TrampolineMemorySegment,
222  VBEDeviceExtension->TrampolineMemoryOffset,
223  Edid,
225 
226  return TRUE;
227 }
228 
231  IN PVOID HwDeviceExtension,
232  IN PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
233  OUT PVIDEO_CHILD_TYPE VideoChildType,
234  OUT PUCHAR pChildDescriptor,
235  OUT PULONG UId,
236  OUT PULONG pUnused)
237 {
238  if (ChildEnumInfo->Size != sizeof(VIDEO_CHILD_ENUM_INFO) ||
239  ChildEnumInfo->ChildDescriptorSize < MAX_SIZE_OF_EDID)
240  {
241  return ERROR_INVALID_FUNCTION;
242  }
243 
244  if (ChildEnumInfo->ChildIndex == 0)
245  {
246  /* We don't support enumeration of ACPI children */
247  return ERROR_NO_MORE_DEVICES;
248  }
249  else if (ChildEnumInfo->ChildIndex == 1)
250  {
251  /* Our screen */
252  *VideoChildType = Monitor;
253  *UId = 1;
254 
255  /* Try to read EDID information using 2 different methods. */
256  if (VBEReadEdid(HwDeviceExtension, 0, pChildDescriptor))
257  {
258  VideoPortDebugPrint(Info, "VBEMP: EDID information read directly\n");
259  }
260  else if (VBEReadEdidUsingSCI(HwDeviceExtension, 0, pChildDescriptor))
261  {
262  VideoPortDebugPrint(Info, "VBEMP: EDID information read using I2C\n");
263  }
264 
266  }
267  else
268  {
269  /* Unknown hardware id */
270  return ERROR_NO_MORE_DEVICES;
271  }
272 }
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:230
static BOOLEAN NTAPI VBEReadClockLine(PVOID HwDeviceExtension)
Definition: edid.c:67
#define IN
Definition: typedefs.h:39
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
IN UCHAR EdidSegment
Definition: video.h:700
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
#define ERROR_NO_MORE_DEVICES
Definition: dderror.h:18
#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)
IN I2C_CALLBACKS I2CCallbacks
Definition: video.h:699
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
#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
#define FALSE
Definition: types.h: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
#define VBE_DDC_BEGIN_SCL_SDA_CONTROL
Definition: vbemp.h:75
#define MAX_SIZE_OF_EDID
Definition: vbemp.h:187
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: inflate.c:42
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:40
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
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