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.
233 lines
5.9 KiB
233 lines
5.9 KiB
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
cl.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code that contains
|
|
Cirrus Logic controller 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
|
|
CLInitialize(IN PFDO_EXTENSION FdoExtension)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initialize Cirrus Logic cardbus controllers
|
|
|
|
Arguments:
|
|
|
|
FdoExtension - Pointer to the device extension for the controller FDO
|
|
|
|
Return Value:
|
|
|
|
None
|
|
--*/
|
|
{
|
|
UCHAR byte, revisionID;
|
|
USHORT word;
|
|
|
|
|
|
byte = PcicReadSocket(FdoExtension->SocketList,
|
|
PCIC_CL_MISC_CTRL3);
|
|
|
|
if ((FdoExtension->ControllerType == PcmciaCLPD6832) &&
|
|
((byte & CL_MC3_INTMODE_MASK) == CL_MC3_INTMODE_EXTHW)) {
|
|
|
|
FdoExtension->LegacyIrqMask = 0xd8b8; //3,4,5,7,11,12,14,15
|
|
|
|
}
|
|
|
|
GetPciConfigSpace(FdoExtension, CFGSPACE_REV_ID, &revisionID, 1);
|
|
if (FdoExtension->ControllerType == PcmciaCLPD6832) {
|
|
//disable CSC IRQ routing (use PCI interrupt for CSC)
|
|
GetPciConfigSpace(FdoExtension, CFGSPACE_BRIDGE_CTRL, &word, 2);
|
|
word &= ~BCTRL_CL_CSCIRQROUTING_ENABLE;
|
|
SetPciConfigSpace(FdoExtension, CFGSPACE_BRIDGE_CTRL, &word, 2);
|
|
}
|
|
else {
|
|
//disable CSC IRQ routing (use PCI interrupt for CSC)
|
|
GetPciConfigSpace(FdoExtension, CFGSPACE_CL_CFGMISC1, &byte, 1);
|
|
byte &= ~CL_CFGMISC1_ISACSC;
|
|
SetPciConfigSpace(FdoExtension, CFGSPACE_CL_CFGMISC1, &byte, 1);
|
|
}
|
|
|
|
//enable speaker
|
|
byte = PcicReadSocket(FdoExtension->SocketList, PCIC_CL_MISC_CTRL1);
|
|
byte |= CL_MC1_SPKR_ENABLE;
|
|
PcicWriteSocket(FdoExtension->SocketList, PCIC_CL_MISC_CTRL1, byte);
|
|
|
|
byte = PcicReadSocket(FdoExtension->SocketList, PCIC_CL_DEV_IMP_C);
|
|
if (byte & (CL_IMPC_ZVP_A | CL_IMPC_ZVP_B)) {
|
|
//enable multimedia support (i.e. ZV)
|
|
byte = PcicReadSocket(FdoExtension->SocketList,PCIC_CL_MISC_CTRL3);
|
|
byte |= CL_MC3_MM_ARM;
|
|
PcicWriteSocket(FdoExtension->SocketList, PCIC_CL_MISC_CTRL3,byte);
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
CLSetPower(
|
|
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, oldMiscCtrl, newMiscCtrl;
|
|
|
|
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);
|
|
oldMiscCtrl = PcicReadSocket(SocketPtr, PCIC_CL_MISC_CTRL1);
|
|
|
|
//
|
|
// Set new vcc
|
|
//
|
|
newPower = (Enable ? PC_CARDPWR_ENABLE: 0);
|
|
//
|
|
// Since we always set 5V for R2 cards, we let MISC control be 0
|
|
// other wise it should be CL_MC1_VCC_3V if the vcc was 3.3V
|
|
//
|
|
newMiscCtrl = 0;
|
|
|
|
//
|
|
// Set vpp
|
|
//
|
|
if (Enable) {
|
|
//
|
|
// We - as always - set vpp to vcc..
|
|
//
|
|
newPower |= PC_VPP_SETTO_VCC;
|
|
}
|
|
//
|
|
// Don't nuke the non-power related bits in the register..
|
|
//
|
|
newPower |= (oldPower & PC_PWRON_BITS);
|
|
newMiscCtrl |= (oldMiscCtrl & ~CL_MC1_VCC_33V);
|
|
//
|
|
// If Vcc is turned off, reset OUTPUT_ENABLE & AUTOPWR_ENABLE
|
|
//
|
|
if (!(newPower & PC_CARDPWR_ENABLE)) {
|
|
newPower &= ~PC_PWRON_BITS;
|
|
}
|
|
//
|
|
// Only set power if nothing's changed..
|
|
//
|
|
status = STATUS_SUCCESS;
|
|
if ((newPower != oldPower) || (newMiscCtrl != oldMiscCtrl)) {
|
|
PcicWriteSocket(SocketPtr, PCIC_PWR_RST, newPower);
|
|
PcicWriteSocket(SocketPtr, PCIC_CL_MISC_CTRL1, newMiscCtrl);
|
|
//
|
|
// Allow ramp up.. (actually we don't need to this if
|
|
// Enable was FALSE). Keep it for paranoia's sake
|
|
//
|
|
*pDelayTime = PCMCIA_PCIC_STALL_POWER;
|
|
SocketPtr->PowerData = (ULONG) newPower;
|
|
status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
|
|
newPower = (UCHAR) SocketPtr->PowerData;
|
|
|
|
if ((newPower & PC_CARDPWR_ENABLE) &&
|
|
((newPower & PC_PWRON_BITS) != PC_PWRON_BITS)) {
|
|
//
|
|
// More paranoia?
|
|
//
|
|
newPower |= PC_PWRON_BITS;
|
|
PcicWriteSocket(SocketPtr, PCIC_PWR_RST, newPower);
|
|
}
|
|
status = STATUS_SUCCESS;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(FALSE);
|
|
status = STATUS_UNSUCCESSFUL;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
CLSetZV(
|
|
IN PSOCKET Socket,
|
|
IN BOOLEAN Enable
|
|
)
|
|
{
|
|
UCHAR bData;
|
|
|
|
if (Enable) {
|
|
|
|
bData = PcicReadSocket(Socket, PCIC_CL_MISC_CTRL1);
|
|
bData |= CL_MC1_MM_ENABLE;
|
|
bData &= ~CL_MC1_SPKR_ENABLE;
|
|
PcicWriteSocket(Socket, PCIC_CL_MISC_CTRL1, bData);
|
|
|
|
} else {
|
|
|
|
bData = PcicReadSocket(Socket, PCIC_CL_MISC_CTRL1);
|
|
bData &= ~CL_MC1_MM_ENABLE;
|
|
bData |= CL_MC1_SPKR_ENABLE;
|
|
PcicWriteSocket(Socket, PCIC_CL_MISC_CTRL1, bData);
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|