windows-nt/Source/XPSP1/NT/base/busdrv/pccard/pcmcibus/opti.c
2020-09-26 16:20:57 +08:00

203 lines
4.3 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}