203 lines
4.3 KiB
C
203 lines
4.3 KiB
C
|
|
|||
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1994 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
opti.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the code that contains
|
|||
|
OPTi controller(s) specific initialization and
|
|||
|
other dispatches
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ravisankar Pudipeddi (ravisp) 1-Nov-97
|
|||
|
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode
|
|||
|
|
|||
|
Revision History :
|
|||
|
|
|||
|
Neil Sandlin (neilsa) 3-Mar-99
|
|||
|
new setpower routine interface
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "pch.h"
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
OptiInitialize(
|
|||
|
IN PFDO_EXTENSION FdoExtension
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Initialize OPTI cardbus controllers
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
FdoExtension - Pointer to the device extension for the controller FDO
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if (FdoExtension->ControllerType == PcmciaOpti82C814) {
|
|||
|
UCHAR byte;
|
|||
|
|
|||
|
//
|
|||
|
// This fix per Opti for USB/1394 Combo hang
|
|||
|
// 5Eh[7] - enables the deadlock prevention mechanism
|
|||
|
// 5Fh[1] - reduces the retry count delay to 8 - note that 5Fh is a
|
|||
|
// WRITE-ONLY register and always reads 0. All other bits
|
|||
|
// of this register can safely be written to 0.
|
|||
|
// 5Eh[5] - enables write posting on upstream transfers
|
|||
|
// 5Eh[4] - sets the chip input buffer scaling (not related to deadlock)
|
|||
|
|
|||
|
GetPciConfigSpace(FdoExtension, 0x5e, &byte, 1);
|
|||
|
byte |= 0xB0;
|
|||
|
SetPciConfigSpace(FdoExtension, 0x5e, &byte, 1);
|
|||
|
byte = 2;
|
|||
|
SetPciConfigSpace(FdoExtension, 0x5f, &byte, 1);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
OptiSetPower(
|
|||
|
IN PSOCKET SocketPtr,
|
|||
|
IN BOOLEAN Enable,
|
|||
|
OUT PULONG pDelayTime
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Set power to the specified socket.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SocketPtr - the socket to set
|
|||
|
Enable - TRUE means to set power - FALSE is to turn it off.
|
|||
|
pDelayTime - specifies delay (msec) to occur after the current phase
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_MORE_PROCESSING_REQUIRED - increment phase, perform delay, recall
|
|||
|
other status values terminate sequence
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS status;
|
|||
|
UCHAR oldPower, newPower;
|
|||
|
|
|||
|
if (IsCardBusCardInSocket(SocketPtr)) {
|
|||
|
//
|
|||
|
// Hand over to generic power setting routine
|
|||
|
//
|
|||
|
return(CBSetPower(SocketPtr, Enable, pDelayTime));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
switch(SocketPtr->PowerPhase) {
|
|||
|
case 1:
|
|||
|
//
|
|||
|
// R2 card - special handling
|
|||
|
//
|
|||
|
oldPower = PcicReadSocket(SocketPtr, PCIC_PWR_RST);
|
|||
|
//
|
|||
|
// Set new vcc
|
|||
|
// VCC always set to 5V if power is to be enabled..
|
|||
|
//
|
|||
|
newPower = (Enable ? PC_VCC_OPTI_050V : PC_VCC_OPTI_NO_CONNECT);
|
|||
|
//
|
|||
|
// Set vpp
|
|||
|
//
|
|||
|
if (Enable) {
|
|||
|
//
|
|||
|
// We - as always - set vpp to vcc..
|
|||
|
//
|
|||
|
newPower |= PC_VPP_OPTI_SETTO_VCC;
|
|||
|
} else {
|
|||
|
newPower |= PC_VPP_OPTI_NO_CONNECT;
|
|||
|
}
|
|||
|
|
|||
|
newPower |= (oldPower & PC_OUTPUT_ENABLE);
|
|||
|
//
|
|||
|
// If Vcc is turned off, reset OUTPUT_ENABLE & AUTOPWR_ENABLE
|
|||
|
//
|
|||
|
if (!(newPower & PC_VCC_OPTI_MASK)) {
|
|||
|
newPower &= ~PC_OUTPUT_ENABLE;
|
|||
|
}
|
|||
|
|
|||
|
status = STATUS_SUCCESS;
|
|||
|
if (newPower != oldPower) {
|
|||
|
PcicWriteSocket(SocketPtr, PCIC_PWR_RST, newPower);
|
|||
|
//
|
|||
|
// Allow ramp up.. (actually we don't need to this if
|
|||
|
// Enable was FALSE). Keep it for paranoia's sake
|
|||
|
//
|
|||
|
*pDelayTime = PcicStallPower;
|
|||
|
SocketPtr->PowerData = (ULONG) newPower;
|
|||
|
status = STATUS_MORE_PROCESSING_REQUIRED;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 2:
|
|||
|
|
|||
|
newPower = (UCHAR) SocketPtr->PowerData;
|
|||
|
|
|||
|
if ((newPower & PC_VCC_OPTI_MASK) && !(newPower & PC_OUTPUT_ENABLE)){
|
|||
|
//
|
|||
|
// More paranoia?
|
|||
|
//
|
|||
|
newPower |= PC_OUTPUT_ENABLE;
|
|||
|
PcicWriteSocket(SocketPtr, PCIC_PWR_RST, newPower);
|
|||
|
}
|
|||
|
status = STATUS_SUCCESS;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
ASSERT(FALSE);
|
|||
|
status = STATUS_UNSUCCESSFUL;
|
|||
|
}
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
OptiSetZV(
|
|||
|
IN PSOCKET Socket,
|
|||
|
IN BOOLEAN Enable
|
|||
|
)
|
|||
|
{
|
|||
|
UCHAR bData;
|
|||
|
|
|||
|
if (Enable) {
|
|||
|
|
|||
|
bData = PcicReadSocket(Socket, PCIC_OPTI_GLOBAL_CTRL);
|
|||
|
bData |= OPTI_ZV_ENABLE;
|
|||
|
PcicWriteSocket(Socket, PCIC_OPTI_GLOBAL_CTRL, bData);
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
bData = PcicReadSocket(Socket, PCIC_OPTI_GLOBAL_CTRL);
|
|||
|
bData &= ~OPTI_ZV_ENABLE;
|
|||
|
PcicWriteSocket(Socket, PCIC_OPTI_GLOBAL_CTRL, bData);
|
|||
|
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|