📄 hd465socket.c
字号:
WRITE_REGISTER_USHORT(PcmciaRegisters[uSocket].pCSCIER,
((READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pCSCIER) & ~CC_PCMCIA_CSCIER_IREQ_MASK)|
EnableCSCIERInts));
WRITE_REGISTER_USHORT(PcmciaRegisters[uSocket].pCSCIER,
(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pCSCIER) &
~DisableCSCIERInts));
// Check the power settings of the new socket state to see if they're different than the current settings.
if ((pState->fVcc != v_SockState[uSocket].fVcc) ||
(pState->uVpp1 != v_SockState[uSocket].uVpp1) ||
(pState->uVpp2 != v_SockState[uSocket].uVpp2))
{
if(pState->uVpp1 != pState->uVpp2)
{
LeaveCriticalSection(&gPddSocketCrit);
DEBUGMSG(ZONE_POWER, (TEXT("Bad Vpp2 Settings\r\n")));
return CERR_BAD_VPP;
}
// Get new socket power settings
if(pState->fVcc == BAD_VCC)
{
LeaveCriticalSection(&gPddSocketCrit);
DEBUGMSG(ZONE_POWER, (TEXT("Bad VCC Power Settings\r\n")));
return CERR_BAD_VCC;
}
if(pState->uVpp1 == BAD_VPP)
{
LeaveCriticalSection(&gPddSocketCrit);
DEBUGMSG(ZONE_POWER, (TEXT("Bad VPP Power Settings\r\n")));
return CERR_BAD_VPP;
}
DEBUGMSG(ZONE_POWER, (TEXT("New Power Settings: VCC %d VPP1 %d VPP2 %d\r\n"),
pState->fVcc, pState->uVpp1, pState->uVpp2));
SetPower(uSocket, pState->fVcc, pState->uVpp1, TRUE, 0);
}
memcpy(&v_SockState[uSocket], pState, sizeof(PDCARD_SOCKET_STATE));
PrintRegisters(uSocket);
LeaveCriticalSection(&gPddSocketCrit);
DEBUGMSG(ZONE_PDD, (TEXT("-PDCardSetSocket\r\n")));
return CERR_SUCCESS;
}
/*****************************************************************************
* FUNCTION : PDCardInquireAdapter
* DESCRIPTION : Gets the Adapter Info
* INPUTS :
* OUTPUTS : Returns the socket controller's characteristics and
* capabilities.
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
STATUS PDCardInquireAdapter(
PPDCARD_ADAPTER_INFO pAdapterInfo) // Pointer to PDCARD_ADAPTER_INFO structure.
{
DEBUGMSG(ZONE_PDD, (TEXT("+PDCardInquireAdapter\r\n")));
if (pAdapterInfo->uPowerEntries < NUM_POWER_ENTRIES)
{
pAdapterInfo->uPowerEntries = NUM_POWER_ENTRIES;
return CERR_BAD_ARG_LENGTH;
}
// Copy the adapter info
memcpy(pAdapterInfo, &v_AdapterInfo, sizeof(PDCARD_ADAPTER_INFO));
pAdapterInfo = (PPDCARD_ADAPTER_INFO)(((UINT)pAdapterInfo) + sizeof(PDCARD_ADAPTER_INFO));
// Copy the power entries at the end
memcpy(pAdapterInfo, &v_PowerEntries, sizeof(v_PowerEntries));
DEBUGMSG(ZONE_PDD, (TEXT("-PDCardInquireAdapter\r\n")));
return CERR_SUCCESS;
}
/*****************************************************************************
* FUNCTION : PDCardResetSocket
* DESCRIPTION : Resets the specified socket.
* INPUTS : Socket num
* OUTPUTS : Returns one of the CERR_* return codes in cardserv.h.
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
STATUS PDCardResetSocket(
UINT32 uSocket) // Socket number (first socket is 0)
{
DWORD t;
DEBUGMSG(ZONE_PDD, (TEXT("+PDCardResetSocket\r\n")));
if (uSocket >= NUM_SOCKETS) {
return CERR_BAD_SOCKET;
}
//If there is a card inserted, then reset it.
if (!(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pISR) & CC_PCMCIA_ISR_CD_MASK))
{
DEBUGMSG(ZONE_POWER, (TEXT("Resetting PC Card in socket %d\r\n"),uSocket));
if (READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR) & CC_PCMCIA_GCR_DRV_ENABLE)
{
EnterCriticalSection(&gPddSocketCrit);
WRITE_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR,
(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR) &
~CC_PCMCIA_GCR_DRV_ENABLE));
LeaveCriticalSection(&gPddSocketCrit);
// Must allow VCC to ramp up before hitting RESET
Sleep(310);
// Assert RESET for 1ms (actually will be 25-50 ms until we get Sleep fixed)
EnterCriticalSection(&gPddSocketCrit);
WRITE_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR,
(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR) |
(CC_PCMCIA_GCR_RESET | CC_PCMCIA_GCR_DRV_ENABLE)));
LeaveCriticalSection(&gPddSocketCrit);
Sleep(1);
EnterCriticalSection(&gPddSocketCrit);
WRITE_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR,
(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR) &
~CC_PCMCIA_GCR_RESET));
LeaveCriticalSection(&gPddSocketCrit);
DEBUGMSG(ZONE_POWER, (TEXT("PDCardResetSocket : Released Critical Section\r\n")));
// Wait (at least 20ms and up to 2 seconds) for RDY before accessing card
if (v_SockState[uSocket].fInterfaceType == CFG_IFACE_MEMORY)
{
Sleep(200);
for (t=0; t<PCMCIA_MAX_RDY_WAIT_TIME; t+= PCMCIA_RDY_POLL_INT)
{
if (!(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pISR) & CC_PCMCIA_ISR_RDY_MASK))
Sleep(PCMCIA_RDY_POLL_INT); // Still busy
}
if (t >= PCMCIA_MAX_RDY_WAIT_TIME)
DEBUGMSG(ZONE_POWER, (TEXT("Timed out waiting for card RDY; t=%d\r\n"),t));
}
else
{
Sleep(2000);
}
}
DEBUGMSG(ZONE_POWER, (TEXT("PDCardResetSocket : Completed Sequence\r\n")));
}
else
{
DEBUGMSG(ZONE_POWER, (TEXT("No PC Card: Tri-stating reset line\r\n")));
//No card, disable the card
EnterCriticalSection(&gPddSocketCrit);
WRITE_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR,
(READ_REGISTER_USHORT(PcmciaRegisters[uSocket].pGCR) & ~CC_PCMCIA_GCR_DRV_ENABLE));
LeaveCriticalSection(&gPddSocketCrit);
}
DEBUGMSG(ZONE_PDD, (TEXT("-PDCardResetSocket\r\n")));
return CERR_SUCCESS;
}
/*****************************************************************************
* FUNCTION : PDCardGetAdapter
* DESCRIPTION : When the PCMCIA system is in low power mode, the bit,
* ADP_STATE_POWERDOWN should be set. When the PCMCIA
* system is powered off, then the ADP_STATE_POWEROFF bit
* should be set. When the PCMCIA system is in a full power
* mode, then the state should either be 0 or
* ADP_STATE_MAINTAIN. This function will be called in
* critical power situations, so it should not block or yield.
* INPUTS :
* OUTPUTS : Returns one of the CERR_* return codes in cardserv.h
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
STATUS PDCardGetAdapter(
UINT32 uSocket,
PPDCARD_ADAPTER_STATE pState)
{
DEBUGMSG(ZONE_PDD, (TEXT("+PDCardGetAdapter\r\n")));
if ((uSocket >= NUM_SOCKETS)||(uSocket<0))
{
return CERR_BAD_SOCKET;
}
if (pState == NULL)
{
return CERR_BAD_ARGS;
}
DEBUGMSG(ZONE_PDD, (TEXT("PDCardGetAdapter, socket %d: %x \r\n"), uSocket,v_AdapterState[uSocket]));
{
*pState = v_AdapterState[uSocket];
}
DEBUGMSG(ZONE_PDD, (TEXT("-PDCardGetAdapter\r\n")));
return CERR_SUCCESS;
}
/*****************************************************************************
* FUNCTION : PDCardSetAdapter
* DESCRIPTION : If the bit, ADP_STATE_POWEROFF, is set, then the PCMCIA
* system should be powered off. If the ADP_STATE_POWERDOWN
* bit is set, then the PCMCIA system should be placed in
* power saving mode. In power save mode, it is expected
* that card insertion and removal events can be detected.
* If both of these bits are off, then the PCMCIA system
* should be placed in full power mode. If the
* ADP_STATE_KERNEL_MODE bit is set, we are being called from
* within the system power handler routine, and are not
* allowed to block or make any system calls.
* INPUTS :
* OUTPUTS : Returns one of the CERR_* return codes in cardserv.h
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
STATUS
PDCardSetAdapter(
UINT32 uSocket,
PPDCARD_ADAPTER_STATE pState
)
{
DEBUGMSG(ZONE_PDD, (TEXT("+PDCardSetAdapter\r\n")));
if ((uSocket >= NUM_SOCKETS) || (uSocket < 0 ))
{
return CERR_BAD_SOCKET;
}
if (pState == NULL)
{
return CERR_BAD_ARGS;
}
DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetAdapter, socket %d: %x \r\n"), uSocket,*pState));
if ( *pState & (ADP_STATE_POWEROFF|ADP_STATE_POWERDOWN) )
{
DEBUGMSG(ZONE_POWER, (TEXT("PDCardSetAdapter: Powering Down socket %u\r\n"),uSocket));
if (!(*pState & ADP_STATE_KERNEL_MODE))
EnterCriticalSection(&gPddSocketCrit);
SetPower(uSocket, 0, 0, FALSE, (*pState & ADP_STATE_KERNEL_MODE));
v_AdapterState[uSocket] = *pState;
if (!(*pState & ADP_STATE_KERNEL_MODE))
LeaveCriticalSection(&gPddSocketCrit);
}
else // Turn power on
{
DEBUGMSG(ZONE_PDD, (TEXT("PDCardSetAdapter: Powering On Socket %u\r\n"),uSocket));
if (!(*pState & ADP_STATE_KERNEL_MODE))
EnterCriticalSection(&gPddSocketCrit);
// Power on pcmcia subsystem.
// Set VCC and VPP on PCMCIA slot to original values before power up.
SetPower(uSocket, v_SockState[uSocket].fVcc, v_SockState[uSocket].uVpp1, TRUE,
(*pState & ADP_STATE_KERNEL_MODE));
v_AdapterState[uSocket] = *pState;
if (!(*pState & ADP_STATE_KERNEL_MODE))
LeaveCriticalSection(&gPddSocketCrit);
}
DEBUGMSG(ZONE_PDD, (TEXT("-PDCardSetAdapter\r\n")));
PrintRegisters(uSocket);
return CERR_SUCCESS;
}
/*****************************************************************************
* FUNCTION : SetPower()
* DESCRIPTION : This function will set the power for a socket
* INPUTS :
* OUTPUTS : BOOL value
* DESIGN NOTES : The caller MUST have the Socket's crit sect
* CAUTIONS :
*****************************************************************************/
BOOL SetPower(int uSock, int VCC_index, int VPP_index, BOOL bReEnable, BOOL bKernelMode)
{
DWORD dwDelayCount;
POWER_REGISTER_VALUES PowerValues;
DEBUGMSG(ZONE_PDD, (TEXT("+SetPower\r\n")));
PrintRegisters(0);
PrintRegisters(1);
PowerValues = ((uSock == 0) ? PowerSettingsA[VCC_index][VPP_index] : PowerSettingsB[VCC_index][VPP_index]);
//first lets turn off the buffers that transmit data through to the PCMCIA slots
// Tri state the outputs
WRITE_REGISTER_USHORT(PcmciaRegisters[uSock].pGCR,
(READ_REGISTER_USHORT(PcmciaRegisters[uSock].pGCR) & ~CC_PCMCIA_GCR_DRV_ENABLE));
// Set VCC and VPP on PCMCIA slots 0 and 1 to original values before power down.
if (!bKernelMode)
EnterCriticalSection(&gPddPowerCrit);
WRITE_REGISTER_USHORT(PcmciaRegisters[0].pSCR,
(READ_REGISTER_USHORT(PcmciaRegisters[0].pSCR) | PowerValues.SCR));
WRITE_REGISTER_USHORT(PcmciaRegisters[0].pPSR,
(READ_REGISTER_USHORT(PcmciaRegisters[0].pPSR) &
~(uSock?CC_PCMCIA_PSR_BVCC_BVPP:CC_PCMCIA_PSR_AVCC_AVPP))|PowerValues.PSR);
if ( !READ_REGISTER_USHORT(PcmciaRegisters[0].pPSR) )
WRITE_REGISTER_USHORT(PcmciaRegisters[0].pSCR,
READ_REGISTER_USHORT(PcmciaRegisters[0].pSCR)&~CC_PCMCIA_SCR_SHDN_ENB);
// Wait the maximum delay time
//For this, we must use BusyWait. There is a bit of setup involved
//set the delay counter for future calls to BusyWait
//this is used for a 20ms delay from power up to powering the LCD
dwDelayCount = AdjustMicroSecondsToLoopCount( 20000 );
BusyWait(dwDelayCount);
if (!bKernelMode)
LeaveCriticalSection(&gPddPowerCrit);
//now we need to re-enable the outputs
if (bReEnable)
{
WRITE_REGISTER_USHORT(PcmciaRegisters[uSock].pGCR,
(READ_REGISTER_USHORT(PcmciaRegisters[uSock].pGCR) |
CC_PCMCIA_GCR_DRV_ENABLE));
}
DEBUGMSG(ZONE_PDD, (TEXT("The power has been changed on socket %d to index[%d][%d]\r\n"), uSock, VCC_index, VPP_index));
DEBUGMSG(ZONE_PDD, (TEXT("PSR = 0x%X; SCR = 0x%X;\r\n"),PowerValues.PSR, PowerValues.SCR));
PrintRegisters(0);
PrintRegisters(1);
DEBUGMSG(ZONE_PDD, (TEXT("-SetPower\r\n")));
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -