You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
728 lines
20 KiB
728 lines
20 KiB
/***************************************************************************\
|
|
*
|
|
* ************************
|
|
* * MINIPORT SAMPLE CODE *
|
|
* ************************
|
|
*
|
|
* Module Name:
|
|
*
|
|
* power.c
|
|
*
|
|
* Abstract:
|
|
*
|
|
* This module contains the code that implements the power management features
|
|
*
|
|
*
|
|
* Environment:
|
|
*
|
|
* Kernel mode
|
|
*
|
|
*
|
|
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
|
|
* Copyright (c) 1995-2003 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#include "perm3.h"
|
|
|
|
#if defined(ALLOC_PRAGMA)
|
|
#pragma alloc_text(PAGE,Perm3GetPowerState)
|
|
#pragma alloc_text(PAGE,Perm3SetPowerState)
|
|
#pragma alloc_text(PAGE,Perm3GetChildDescriptor)
|
|
#pragma alloc_text(PAGE,ProgramDFP)
|
|
#pragma alloc_text(PAGE,GetDFPEdid)
|
|
#pragma alloc_text(PAGE,I2CWriteClock)
|
|
#pragma alloc_text(PAGE,I2CWriteData)
|
|
#pragma alloc_text(PAGE,I2CReadClock)
|
|
#pragma alloc_text(PAGE,I2CReadData)
|
|
#pragma alloc_text(PAGE,I2CWriteClockDFP)
|
|
#pragma alloc_text(PAGE,I2CWriteDataDFP)
|
|
#pragma alloc_text(PAGE,I2CReadClockDFP)
|
|
#pragma alloc_text(PAGE,I2CReadDataDFP)
|
|
#endif
|
|
|
|
DDC_CONTROL
|
|
DDCControlCRT = {
|
|
sizeof(DDC_CONTROL),
|
|
I2CWriteClock,
|
|
I2CWriteData,
|
|
I2CReadClock,
|
|
I2CReadData,
|
|
0
|
|
};
|
|
|
|
DDC_CONTROL
|
|
DDCControlDFP = {
|
|
sizeof(DDC_CONTROL),
|
|
I2CWriteClockDFP,
|
|
I2CWriteDataDFP,
|
|
I2CReadClockDFP,
|
|
I2CReadDataDFP,
|
|
0
|
|
};
|
|
|
|
VP_STATUS
|
|
Perm3GetPowerState(
|
|
PVOID HwDeviceExtension,
|
|
ULONG HwId,
|
|
PVIDEO_POWER_MANAGEMENT VideoPowerControl
|
|
)
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
Queries whether the device can support the requested power state.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension
|
|
Pointer to our hardware device extension structure.
|
|
|
|
HwId
|
|
Points to a 32-bit number that uniquely identifies the device that
|
|
the miniport should query.
|
|
|
|
VideoPowerControl
|
|
Points to a VIDEO_POWER_MANAGEMENT structure that specifies the
|
|
power state for which support is being queried.
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR, if the device supports the requested power state, or error code.
|
|
|
|
---*/
|
|
|
|
{
|
|
VP_STATUS status;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
|
|
VideoDebugPrint((3, "Perm3: Perm3GetPowerState: hwId(0x%x) state = %d\n",
|
|
HwId, VideoPowerControl->PowerState ));
|
|
|
|
switch(HwId) {
|
|
|
|
case PERM3_DDC_MONITOR:
|
|
case PERM3_NONDDC_MONITOR:
|
|
|
|
switch ( VideoPowerControl->PowerState ) {
|
|
|
|
case VideoPowerOn:
|
|
case VideoPowerStandBy:
|
|
case VideoPowerSuspend:
|
|
case VideoPowerOff:
|
|
case VideoPowerHibernate:
|
|
case VideoPowerShutdown:
|
|
status = NO_ERROR;
|
|
break;
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((0, "Perm3: Perm3GetPowerState: Unknown monitor PowerState = %d\n",
|
|
VideoPowerControl->PowerState ));
|
|
ASSERT(FALSE);
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
break;
|
|
|
|
case DISPLAY_ADAPTER_HW_ID:
|
|
|
|
switch ( VideoPowerControl->PowerState ) {
|
|
|
|
case VideoPowerOn:
|
|
case VideoPowerStandBy:
|
|
case VideoPowerSuspend:
|
|
case VideoPowerOff:
|
|
case VideoPowerHibernate:
|
|
case VideoPowerShutdown:
|
|
|
|
status = NO_ERROR;
|
|
break;
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((0, "Perm3: Perm3GetPowerState: Unknown adapter PowerState = %d\n",
|
|
VideoPowerControl->PowerState ));
|
|
ASSERT(FALSE);
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((0, "Perm3: Perm3GetPowerState: Unknown hwId(0x%x)", HwId));
|
|
ASSERT(FALSE);
|
|
status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return(status);
|
|
}
|
|
|
|
VP_STATUS
|
|
Perm3SetPowerState(
|
|
PVOID HwDeviceExtension,
|
|
ULONG HwId,
|
|
PVIDEO_POWER_MANAGEMENT VideoPowerControl
|
|
)
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
Sets the power state of the specified device.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension
|
|
Pointer to our hardware device extension structure.
|
|
|
|
HwId
|
|
Points to a 32-bit number that uniquely identifies the device
|
|
for which the miniport should set the power state.
|
|
|
|
VideoPowerControl
|
|
Points to a VIDEO_POWER_MANAGEMENT structure that specifies the
|
|
power state to be set.
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR
|
|
|
|
---*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG Polarity;
|
|
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
VideoDebugPrint((3, "Perm3: Perm3SetPowerState: hwId(0x%x) state = %d\n",
|
|
HwId, VideoPowerControl->PowerState));
|
|
|
|
switch(HwId) {
|
|
|
|
case PERM3_DDC_MONITOR:
|
|
case PERM3_NONDDC_MONITOR:
|
|
|
|
Polarity = VideoPortReadRegisterUlong(VIDEO_CONTROL);
|
|
Polarity &= ~VC_DPMS_MASK;
|
|
|
|
switch (VideoPowerControl->PowerState) {
|
|
|
|
case VideoPowerOn:
|
|
VideoPortWriteRegisterUlong(VIDEO_CONTROL,
|
|
Polarity | hwDeviceExtension->VideoControlMonitorON);
|
|
break;
|
|
|
|
case VideoPowerStandBy:
|
|
VideoPortWriteRegisterUlong(VIDEO_CONTROL,
|
|
Polarity | VC_DPMS_STANDBY);
|
|
break;
|
|
|
|
case VideoPowerSuspend:
|
|
VideoPortWriteRegisterUlong(VIDEO_CONTROL,
|
|
Polarity | VC_DPMS_SUSPEND);
|
|
break;
|
|
|
|
case VideoPowerShutdown:
|
|
case VideoPowerOff:
|
|
VideoPortWriteRegisterUlong(VIDEO_CONTROL,
|
|
Polarity | VC_DPMS_OFF);
|
|
break;
|
|
|
|
case VideoPowerHibernate:
|
|
|
|
//
|
|
// The monitor for the vga enabled video device must
|
|
// stay on at hibernate.
|
|
//
|
|
|
|
break;
|
|
|
|
default:
|
|
VideoDebugPrint((0, "Perm3: Perm3GetPowerState: Unknown monitor PowerState(0x%x)\n",
|
|
VideoPowerControl->PowerState));
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
//
|
|
// Track the current monitor power state
|
|
//
|
|
|
|
hwDeviceExtension->bMonitorPoweredOn =
|
|
(VideoPowerControl->PowerState == VideoPowerOn) ||
|
|
(VideoPowerControl->PowerState == VideoPowerHibernate);
|
|
|
|
break;
|
|
|
|
case DISPLAY_ADAPTER_HW_ID:
|
|
|
|
switch (VideoPowerControl->PowerState) {
|
|
|
|
case VideoPowerOn:
|
|
|
|
if ((hwDeviceExtension->PreviousPowerState == VideoPowerOff) ||
|
|
(hwDeviceExtension->PreviousPowerState == VideoPowerSuspend) ||
|
|
(hwDeviceExtension->PreviousPowerState == VideoPowerHibernate)){
|
|
|
|
//
|
|
// Turn off the monitor while we power back up so
|
|
// the user doesn't see any screen corruption
|
|
//
|
|
|
|
Polarity = VideoPortReadRegisterUlong(VIDEO_CONTROL);
|
|
Polarity &= ~VC_DPMS_MASK;
|
|
VideoPortWriteRegisterUlong(VIDEO_CONTROL, Polarity | VC_DPMS_OFF);
|
|
|
|
//
|
|
// Miniport driver can not rely on video bios to
|
|
// initialize the device registers while resuming
|
|
// from VideoPowerOff and VideoPowerSuspend.
|
|
//
|
|
// This is also true for the secondary (vga disabled)
|
|
// video device while resuming from VideoPowerHibernate
|
|
//
|
|
|
|
InitializePostRegisters(hwDeviceExtension);
|
|
}
|
|
|
|
break;
|
|
|
|
case VideoPowerStandBy:
|
|
case VideoPowerSuspend:
|
|
case VideoPowerOff:
|
|
case VideoPowerHibernate:
|
|
|
|
break;
|
|
|
|
case VideoPowerShutdown:
|
|
|
|
//
|
|
// We need to make sure no interrupts will be generated
|
|
// after the device being powered down
|
|
//
|
|
|
|
VideoPortWriteRegisterUlong(INT_ENABLE, 0);
|
|
break;
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((0, "Perm3: Perm3GetPowerState: Unknown adapter PowerState(0x%x)\n",
|
|
VideoPowerControl->PowerState));
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
hwDeviceExtension->PreviousPowerState = VideoPowerControl->PowerState;
|
|
break;
|
|
|
|
default:
|
|
|
|
VideoDebugPrint((0, "Perm3: Perm3SetPowerState: Unknown hwId(0x%x)\n",
|
|
HwId));
|
|
ASSERT(FALSE);
|
|
}
|
|
|
|
return(NO_ERROR);
|
|
}
|
|
|
|
ULONG
|
|
Perm3GetChildDescriptor(
|
|
PVOID HwDeviceExtension,
|
|
PVIDEO_CHILD_ENUM_INFO pChildInfo,
|
|
PVIDEO_CHILD_TYPE pChildType,
|
|
PUCHAR pChildDescriptor,
|
|
PULONG pUId,
|
|
PULONG Unused
|
|
)
|
|
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all child devices attached to the specified device.
|
|
|
|
This includes DDC monitors attached to the board, as well as other devices
|
|
which may be connected to a proprietary bus.
|
|
|
|
Arguments:
|
|
|
|
HwDeviceExtension
|
|
Pointer to our hardware device extension structure.
|
|
|
|
ChildEnumInfo
|
|
Pointer to VIDEO_CHILD_ENUM_INFO structure that describes the
|
|
device being enumerated.
|
|
|
|
pChildType
|
|
Points to a location in which the miniport returns the type of
|
|
child being enumerated.
|
|
|
|
pChildDescriptor
|
|
Points to a buffer in which the miniport can return data that
|
|
identifies the device.
|
|
|
|
pUId
|
|
Points to the location in which the miniport returns a unique
|
|
32-bit identifier for this device.
|
|
|
|
pUnused
|
|
Is unused and must be set to zero.
|
|
|
|
Return Value:
|
|
|
|
ERROR_MORE_DATA
|
|
There are more devices to be enumerated.
|
|
|
|
ERROR_NO_MORE_DEVICES
|
|
There are no more devices to be enumerated.
|
|
|
|
ERROR_INVALID_NAME
|
|
The miniport could not enumerate the child device identified in
|
|
ChildEnumInfo but does have more devices to be enumerated.
|
|
|
|
---*/
|
|
|
|
{
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
|
|
VideoDebugPrint((3, "Perm3: Perm3GetChildDescriptor called\n"));
|
|
|
|
switch(pChildInfo->ChildIndex) {
|
|
|
|
case 0:
|
|
|
|
//
|
|
// Case 0 is used to enumerate devices found by the ACPI firmware.
|
|
// We don't currently support ACPI devices
|
|
//
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
//
|
|
// Treat index 1 as monitor
|
|
//
|
|
|
|
*pChildType = Monitor;
|
|
|
|
//
|
|
// First we search for a DFP monitor
|
|
//
|
|
|
|
if (GetDFPEdid(hwDeviceExtension,
|
|
pChildDescriptor,
|
|
pChildInfo->ChildDescriptorSize)) {
|
|
|
|
//
|
|
// found a DFP monitor
|
|
//
|
|
|
|
*pUId = PERM3_DFP_MONITOR;
|
|
|
|
return(VIDEO_ENUM_MORE_DEVICES);
|
|
}
|
|
|
|
//
|
|
// If we didn't find a DFP, try to detect a DDC CRT monitor
|
|
//
|
|
|
|
if(VideoPortDDCMonitorHelper(HwDeviceExtension,
|
|
&DDCControlCRT,
|
|
pChildDescriptor,
|
|
pChildInfo->ChildDescriptorSize)) {
|
|
//
|
|
// found a DDC monitor
|
|
//
|
|
|
|
*pUId = PERM3_DDC_MONITOR;
|
|
|
|
} else {
|
|
|
|
//
|
|
// failed: assume non-DDC monitor
|
|
//
|
|
|
|
*pUId = PERM3_NONDDC_MONITOR;
|
|
}
|
|
|
|
return(VIDEO_ENUM_MORE_DEVICES);
|
|
|
|
}
|
|
|
|
return(ERROR_NO_MORE_DEVICES);
|
|
}
|
|
|
|
VOID
|
|
ProgramDFP(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension
|
|
)
|
|
/*+++
|
|
|
|
Routine Description:
|
|
|
|
Program the Perm3 chip to use DFP or not use DFP, depending on whether
|
|
PERM3_DFP and PERM3_DFP_MON_ATTACHED are enabled in Perm3Capabilities.
|
|
|
|
---*/
|
|
{
|
|
//
|
|
// We only try this on boards that are DFP-capable.
|
|
//
|
|
|
|
if (hwDeviceExtension->Perm3Capabilities & PERM3_DFP) {
|
|
|
|
ULONG rdMisc, vsConf, vsBCtl;
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
P3RDRAMDAC *pP3RDRegs = (P3RDRAMDAC *)hwDeviceExtension->pRamdac;
|
|
|
|
//
|
|
// Get values of registers that we are going to trash
|
|
//
|
|
|
|
P3RD_READ_INDEX_REG(P3RD_MISC_CONTROL, rdMisc);
|
|
|
|
//
|
|
// Find out the values of the registers
|
|
//
|
|
|
|
vsConf = VideoPortReadRegisterUlong(VSTREAM_CONFIG);
|
|
vsBCtl = VideoPortReadRegisterUlong(VSTREAM_B_CONTROL);
|
|
|
|
//
|
|
// Clear these bits
|
|
//
|
|
|
|
rdMisc &= ~P3RD_MISC_CONTROL_VSB_OUTPUT_ENABLED;
|
|
vsConf &= ~VSTREAM_CONFIG_UNITMODE_MASK;
|
|
vsBCtl &= ~VSTREAM_B_CONTROL_RAMDAC_ENABLE;
|
|
|
|
if (hwDeviceExtension->Perm3Capabilities & PERM3_DFP_MON_ATTACHED) {
|
|
|
|
//
|
|
// Enable flat panel output as follows:
|
|
//
|
|
|
|
rdMisc |= P3RD_MISC_CONTROL_VSB_OUTPUT_ENABLED;
|
|
vsConf |= VSTREAM_CONFIG_UNITMODE_FP;
|
|
vsBCtl |= VSTREAM_B_CONTROL_RAMDAC_ENABLE;
|
|
}
|
|
else {
|
|
|
|
//
|
|
// set up the registers for non-DFP mode.
|
|
//
|
|
|
|
rdMisc &= (~P3RD_MISC_CONTROL_VSB_OUTPUT_ENABLED);
|
|
vsConf |= VSTREAM_CONFIG_UNITMODE_CRT;
|
|
vsBCtl |= VSTREAM_B_CONTROL_RAMDAC_DISABLE;
|
|
}
|
|
|
|
VideoDebugPrint((3, "Perm3: P3RD_ProgramDFP: PXRXCaps 0x%x, misc 0x%x, conf 0x%x, ctl 0x%x\n",
|
|
hwDeviceExtension->Perm3Capabilities, rdMisc, vsConf, vsBCtl));
|
|
|
|
//
|
|
// Program the registers
|
|
//
|
|
|
|
P3RD_LOAD_INDEX_REG(P3RD_MISC_CONTROL, rdMisc);
|
|
VideoPortWriteRegisterUlong(VSTREAM_CONFIG, vsConf);
|
|
VideoPortWriteRegisterUlong(VSTREAM_B_CONTROL, vsBCtl);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
I2CWriteClock(
|
|
PVOID HwDeviceExtension,
|
|
UCHAR data
|
|
)
|
|
{
|
|
const ULONG nbitClock = 3;
|
|
const ULONG ClockMask = 1 << nbitClock;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG ul;
|
|
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul = VideoPortReadRegisterUlong(DDC_DATA);
|
|
ul &= ~ClockMask;
|
|
ul |= (data & 1) << nbitClock;
|
|
VideoPortWriteRegisterUlong(DDC_DATA, ul);
|
|
}
|
|
|
|
VOID
|
|
I2CWriteData(
|
|
PVOID HwDeviceExtension,
|
|
UCHAR data
|
|
)
|
|
{
|
|
const ULONG nbitData = 2;
|
|
const ULONG DataMask = 1 << nbitData;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG ul;
|
|
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul = VideoPortReadRegisterUlong(DDC_DATA);
|
|
ul &= ~DataMask;
|
|
ul |= ((data & 1) << nbitData);
|
|
VideoPortWriteRegisterUlong(DDC_DATA, ul);
|
|
}
|
|
|
|
BOOLEAN
|
|
I2CReadClock(
|
|
PVOID HwDeviceExtension
|
|
)
|
|
{
|
|
const ULONG nbitClock = 1;
|
|
const ULONG ClockMask = 1 << nbitClock;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG ul;
|
|
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul = VideoPortReadRegisterUlong(DDC_DATA);
|
|
ul &= ClockMask;
|
|
ul >>= nbitClock;
|
|
|
|
return((BOOLEAN)ul);
|
|
}
|
|
|
|
BOOLEAN
|
|
I2CReadData(
|
|
PVOID HwDeviceExtension
|
|
)
|
|
{
|
|
const ULONG nbitData = 0;
|
|
const ULONG DataMask = 1 << nbitData;
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
|
|
ULONG ul;
|
|
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul = VideoPortReadRegisterUlong(DDC_DATA);
|
|
ul &= DataMask;
|
|
ul >>= nbitData;
|
|
|
|
return((BOOLEAN)ul);
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
I2CReadDataDFP(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension
|
|
)
|
|
{
|
|
ULONG ul;
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul = VideoPortReadRegisterUlong(VSTREAM_SERIAL_CONTROL);
|
|
ul &= VSTREAM_SERIAL_CONTROL_DATAIN;
|
|
return (ul != 0);
|
|
}
|
|
|
|
BOOLEAN
|
|
I2CReadClockDFP(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension
|
|
)
|
|
{
|
|
ULONG ul;
|
|
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul = VideoPortReadRegisterUlong(VSTREAM_SERIAL_CONTROL);
|
|
ul &= VSTREAM_SERIAL_CONTROL_CLKIN;
|
|
return (ul != 0);
|
|
}
|
|
VOID
|
|
I2CWriteDataDFP(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension,
|
|
UCHAR data
|
|
)
|
|
{
|
|
ULONG ul = 0x0000E000;
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul |= VideoPortReadRegisterUlong(VSTREAM_SERIAL_CONTROL);
|
|
|
|
ul &= ~VSTREAM_SERIAL_CONTROL_DATAOUT;
|
|
if(data & 1)
|
|
ul |= VSTREAM_SERIAL_CONTROL_DATAOUT;
|
|
|
|
VideoPortWriteRegisterUlong (VSTREAM_SERIAL_CONTROL, ul);
|
|
}
|
|
VOID
|
|
I2CWriteClockDFP(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension,
|
|
UCHAR data
|
|
)
|
|
{
|
|
ULONG ul = 0x0000E000;
|
|
pPerm3ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase[0];
|
|
|
|
ul |= VideoPortReadRegisterUlong(VSTREAM_SERIAL_CONTROL);
|
|
|
|
ul &= ~VSTREAM_SERIAL_CONTROL_CLKOUT;
|
|
if (data & 1)
|
|
ul |= VSTREAM_SERIAL_CONTROL_CLKOUT;
|
|
|
|
VideoPortWriteRegisterUlong (VSTREAM_SERIAL_CONTROL, ul);
|
|
}
|
|
|
|
BOOLEAN
|
|
GetDFPEdid(
|
|
PHW_DEVICE_EXTENSION hwDeviceExtension,
|
|
PUCHAR EdidBuffer,
|
|
LONG EdidSize
|
|
)
|
|
{
|
|
BOOLEAN DFPPresent = FALSE;
|
|
|
|
//
|
|
// If this board is capable of driving a DFP then try using DDC to see
|
|
// if there is a monitor there.
|
|
//
|
|
|
|
if (hwDeviceExtension->Perm3Capabilities & PERM3_DFP) {
|
|
|
|
//
|
|
// Let's say that we have a monitor attached
|
|
//
|
|
|
|
hwDeviceExtension->Perm3Capabilities |= PERM3_DFP_MON_ATTACHED;
|
|
|
|
//
|
|
// Set up the DFP accordingly
|
|
//
|
|
|
|
ProgramDFP(hwDeviceExtension);
|
|
|
|
DFPPresent = VideoPortDDCMonitorHelper(hwDeviceExtension,
|
|
&DDCControlDFP,
|
|
EdidBuffer,
|
|
EdidSize);
|
|
}
|
|
|
|
//
|
|
// If the board doesn't support flat panel or one isn't attached then
|
|
// configure ourselves for non-DFP working.
|
|
//
|
|
|
|
if (!DFPPresent) {
|
|
|
|
//
|
|
// Well DDC says we don't have a DFP monitor attached, clear this bit
|
|
//
|
|
|
|
hwDeviceExtension->Perm3Capabilities &= ~PERM3_DFP_MON_ATTACHED;
|
|
|
|
//
|
|
// Set up the DFP accordingly
|
|
//
|
|
|
|
ProgramDFP(hwDeviceExtension);
|
|
}
|
|
|
|
return (DFPPresent);
|
|
}
|