📄 sdhceventhandlers.cpp
字号:
pSlot->SlotIndex));
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// GetCardRegisters - Get card registers
// Input: pBaseDevice - the base device
// BaseDeviceType - base device type
// pSlot - the slot
// Output:
// Return: SD_API_STATUS code
// Notes: This function retreives important card registers for the device type
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS GetCardRegisters(PSDCARD_DEVICE_CONTEXT pBaseDevice,
SDCARD_DEVICE_TYPE BaseDeviceType,
PSDBUS_HC_SLOT_CONTEXT pSlot)
{
SD_API_STATUS status; // status
SD_COMMAND_RESPONSE response; // response
UCHAR scrReg[SD_SCR_REGISTER_SIZE]; // temporary buffer
USHORT oidValue; // oid value
SD_CARD_STATUS cardStatus; // card status
#if USE_MMCPLUS
g_bIsMMC = FALSE;
g_bIsHSMMC = FALSE;
#endif
// must get CID first in order to get the cards into the IDENT state.
// Check for SD I/O - only cards; will not have CID.
if (Device_SD_IO != BaseDeviceType) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Getting registers from slot %d \n"),
pSlot->SlotIndex));
// for MMC, SD Memory and SD Combo cards, retreive the CID
status = SendSDCommand(pSlot->hDevice,
SD_CMD_ALL_SEND_CID,
0x00000000,
ResponseR2,
&response);
if (!SD_API_SUCCESS(status)){
return status;
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Got CID from device in slot %d \n"),
pSlot->SlotIndex));
// update shadow registers
UpdateCachedRegisterFromResponse(pBaseDevice,
SD_INFO_REGISTER_CID,
&response);
}
// fetch/set the RCA
if (Device_MMC != BaseDeviceType) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Getting RCA from SD card in slot %d .... \n"),
pSlot->SlotIndex));
// get the RCA
status = SendSDCommand(pSlot->hDevice,
SD_CMD_SEND_RELATIVE_ADDR,
0x00000000,
ResponseR6,
&response);
if (!SD_API_SUCCESS(status)){
return status;
}
// update shadow registers
UpdateCachedRegisterFromResponse(pBaseDevice,
SD_INFO_REGISTER_RCA,
&response);
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Got RCA (0x%04X) from SD card in slot %d \n"),
pBaseDevice->RelativeAddress,
pSlot->SlotIndex));
} else {
// get OEM ID from the CID
GetOEMIDFromCID(&oidValue, pBaseDevice);
// for MMC cards set the RCA
// take the unique OEM ID and add the slot number to it to form a system unique address
pBaseDevice->RelativeAddress = (SD_CARD_RCA)(oidValue + pSlot->SlotIndex);
// add 1 if this is zero
if (pBaseDevice->RelativeAddress == 0) {
pBaseDevice->RelativeAddress++;
}
// for MMC cards, we must set the RCA
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Setting MMC RCA to 0x%04X .... \n"),
pBaseDevice->RelativeAddress));
// set the RCA
status = SendSDCommand(pSlot->hDevice,
SD_CMD_MMC_SET_RCA,
((DWORD)pBaseDevice->RelativeAddress) << 16,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)){
return status;
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: RCA set for MMC device in slot %d \n"), pSlot->SlotIndex));
}
// now that the RCA has been fetched/set, we can move on to do other things.........
// check for SD I/O - Only cards. They will not have a CSD or card status
if (Device_SD_IO != BaseDeviceType) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Getting CSD in slot %d .... \n"), pSlot->SlotIndex));
// get the CSD
status = SendSDCommand(pSlot->hDevice,
SD_CMD_SEND_CSD,
((DWORD)pBaseDevice->RelativeAddress) << 16,
ResponseR2,
&response);
if (!SD_API_SUCCESS(status)){
return status;
}
#if USE_MMCPLUS
if ( Device_MMC == BaseDeviceType )
g_bIsMMC = TRUE;
#endif
// update shadow registers
UpdateCachedRegisterFromResponse(pBaseDevice,
SD_INFO_REGISTER_CSD,
&response);
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Got CSD from device in slot %d \n"), pSlot->SlotIndex));
// get the card status
status = SendSDCommand(pSlot->hDevice,
SD_CMD_SEND_STATUS,
((DWORD)pBaseDevice->RelativeAddress) << 16,
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)){
return status;
}
SDGetCardStatusFromResponse(&response, &cardStatus);
if (cardStatus & SD_STATUS_CARD_IS_LOCKED) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: card in slot %d is locked\n"), pSlot->SlotIndex));
pBaseDevice->SDCardInfo.SDMMCInformation.CardIsLocked = TRUE;
}
}
// now in order to get the SCR register we must be in the trans state
// also in order to do a few other things, so lets select the card now and leave it
// selected
// send CMD 7 to select the card and keep it selected, this is required for SDIO cards
// too as mentioned in I/O working group newsgroup
status = SendSDCommand(pSlot->hDevice,
SD_CMD_SELECT_DESELECT_CARD,
((DWORD)pBaseDevice->RelativeAddress) << 16,
ResponseR1b,
&response);
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to select card in slot %d \n"),
pSlot->SlotIndex));
return status;
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver:Card in slot %d is now selected \n"), pSlot->SlotIndex));
#if USE_MMCPLUS
if (g_bIsHSMMC == TRUE)
{
if(wcscmp(GET_HC_NAME_FROM_SLOT(pSlot),TEXT("HSMMC"))==0)
{
//RETAILMSG(1,(TEXT("HSMMC\n")));
status = SendSDCommand(pSlot->hDevice,
HSMMC_CMD_SWITCH,
(3<<24) | (185<<16) | (1<<8) ,
ResponseR1 ,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(0,(TEXT("Switch Command For Clock setting is failed %x\n"),status));
return status;
}
status = SendSDCommand(pSlot->hDevice,
HSMMC_CMD_SWITCH,
(3<<24) | (183<<16) | (2<<8) ,
ResponseR1 ,
&response);
if (!SD_API_SUCCESS(status))
{
RETAILMSG(0,(TEXT("Switch Command is failed %x\n"),status));
return status;
}
}
else
{
//RETAILMSG(1,(TEXT("SD/MMC\n")));
}
//RETAILMSG(0,(TEXT("Switch for HSMMC is done \n")));
}
#endif
/*
for ( int i= 0 ; i<SD_CSD_REGISTER_SIZE ; i++)
{
RETAILMSG(1,(TEXT("CSD[%d] = %x\r\n"),i,response.ResponseBuffer[i] ));
}*/
// only SD Memory and Combo cards have an SCR
if ((Device_SD_Memory == BaseDeviceType) ||
(Device_SD_Combo == BaseDeviceType)) {
// if the card is unlocked, get the SCR
if (!pBaseDevice->SDCardInfo.SDMMCInformation.CardIsLocked) {
// get the SD Configuration register
status = SendSDAppCmd(pSlot->hDevice,
SD_ACMD_SEND_SCR,
0,
SD_READ,
ResponseR1,
&response,
1, // 1 block
SD_SCR_REGISTER_SIZE, // 64 bits
scrReg);
// If the memory card is locked then the SCR becomes inaccessable. If we fail
// to read the SCR then just set up the cached SCR register to default to
// a 1bit access mode.
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get SCR from device in slot %d \n"),
pSlot->SlotIndex));
memset(pBaseDevice->CachedRegisters.SCR, 0, sizeof(pBaseDevice->CachedRegisters.SCR));
} else {
// this is a spec discrepency, since the SCR register is not associated with
// an address, the byte order it ambiguous. All the cards we have seen store the data
// most significant byte first as it arrives.
for (ULONG ii = 0 ; ii < sizeof(pBaseDevice->CachedRegisters.SCR); ii++) {
pBaseDevice->CachedRegisters.SCR[ii] = scrReg[(SD_SCR_REGISTER_SIZE - 1) - ii];
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Got SCR from device in slot %d \n"), pSlot->SlotIndex));
}
}
}
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// DeactivateCardDetect - Deativate Card Detect resistors on SD devices
// Input: pBaseDevice - the base device
// BaseDeviceType - the base device type
// pSlot - the slot
// Output:
// Return : SD_API_STATUS code
// Notes: This function deactivates the card detect resistor for SDIO,
// SD and or Combo cards
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS DeactivateCardDetect(PSDCARD_DEVICE_CONTEXT pBaseDevice,
SDCARD_DEVICE_TYPE BaseDeviceType,
PSDBUS_HC_SLOT_CONTEXT pSlot)
{
UCHAR regValue; // intermediate value
SD_API_STATUS status; // status
SD_COMMAND_RESPONSE response; // response
BOOL fDisableSDIO; // disable SDIO portion?
if (Device_SD_IO == BaseDeviceType) {
fDisableSDIO = TRUE;
}
else if (Device_SD_Combo == BaseDeviceType) {
fDisableSDIO = TRUE;
// *** Combo Card Issue ***
// SDIO 1.00 requires that both memory and SDIO portions of combo
// cards be deactivated.
// SDIO 1.10 only requires one of memory or SDIO combo to be disabled. (4.6)
// Some 1.10 cards have a problem where only one can be disabled--disabling
// both simultaneously will fail.
//
// Our solution is to disable both for < 1.10 and only disable memory
// for >= 1.10.
BYTE bSDIORevision; // SDIO spec version
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE) pBaseDevice,
SD_IO_READ, 0, SD_IO_REG_CCCR, FALSE, &bSDIORevision, sizeof(bSDIORevision));
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR,
(TEXT("SDBusDriver: Failed to read SDIO revision in slot %d. We will treat it as a 1.0 combo card \n"),
pSlot->SlotIndex));
}
else {
bSDIORevision >>= 4; // SDIO revision is in the upper four bits.
if (bSDIORevision != 0x0) {
fDisableSDIO = FALSE;
}
}
}
else {
DEBUGCHK(Device_SD_Memory == BaseDeviceType ||
Device_MMC == BaseDeviceType);
fDisableSDIO = FALSE;
}
// for SD memory or combo, send ACMD42 to turn off card detect resistor
if ( (Device_SD_Memory == BaseDeviceType) ||
(Device_SD_Combo == BaseDeviceType) ) {
// send ACMD42
status = SendSDAppCommand(pSlot->hDevice,
SD_ACMD_SET_CLR_CARD_DETECT,
0x00000000, // bit 0 - cleared to disconnect pullup resistor
ResponseR1,
&response);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -