?? sddevice.cpp
字號(hào):
if (fSDMemory && SD_API_SUCCESS(status)) {
status = SDSynchronousBusRequest_I(SD_CMD_GO_IDLE_STATE,
0x00000000,SD_COMMAND,NoResponse,NULL,0,0,NULL,(DWORD)SD_SLOTRESET_REQUEST);
if (SD_API_SUCCESS(status)) {
DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("CSDSlot: Go Idle Failed during deselection: Status: 0x%08X \n"),
status));
}
}
}
m_RelativeAddress = 0;
m_bCardDeselectRequest = FALSE;
}
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// 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 CSDDevice::DeactivateCardDetect()
{
UCHAR regValue; // intermediate value
SD_API_STATUS status; // status
SD_COMMAND_RESPONSE response; // response
BOOL fDisableSDIO; // disable SDIO portion?
ASSERT(m_FuncionIndex == 0);
if (Device_SD_IO == m_DeviceType ) {
fDisableSDIO = TRUE;
}
else if (Device_SD_Combo == m_DeviceType) {
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_I(SD_IO_READ, 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"),
m_sdSlot.GetSlotIndex()));
}
else {
bSDIORevision >>= 4; // SDIO revision is in the upper four bits.
if (bSDIORevision != 0x0) {
fDisableSDIO = FALSE;
}
}
}
else {
DEBUGCHK(Device_SD_Memory == m_DeviceType ||
Device_MMC == m_DeviceType);
fDisableSDIO = FALSE;
}
// for SD memory or combo, send ACMD42 to turn off card detect resistor
if ( (Device_SD_Memory == m_DeviceType) ||
(Device_SD_Combo == m_DeviceType) ) {
// send ACMD42
status = SendSDAppCommand(SD_ACMD_SET_CLR_CARD_DETECT,
0x00000000, // bit 0 - cleared to disconnect pullup resistor
ResponseR1,
&response);
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor in slot %d \n"), m_sdSlot.GetSlotIndex()));
return status;
}
}
// for SD I/O or SD Combo cards, write to the Bus Interface control register and clear the CD bit
if (fDisableSDIO) {
regValue = SD_IO_BUS_CONTROL_CD_DETECT_DISABLE;
status = SDReadWriteRegistersDirect_I(SD_IO_WRITE,
SD_IO_REG_BUS_CONTROL,
TRUE, // read after write
®Value,
1);
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor for SDIO Device in slot %d \n"), m_sdSlot.GetSlotIndex()));
return status;
}
}
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// UpdateCachedRegisterFromResponse - update the device shadow registers from the
// information in the response buffer
// Input: pDevice - the device who's shadowed register should be updated
// Register - the information to update
// pResponse - the response containing the register data
// Output:
// Return
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
VOID CSDDevice::UpdateCachedRegisterFromResponse(SD_INFO_TYPE Register,PSD_COMMAND_RESPONSE pResponse)
{
switch (Register) {
case SD_INFO_REGISTER_CID:
memcpy(m_CachedRegisters.CID, pResponse->ResponseBuffer, SD_CID_REGISTER_SIZE);
break;
case SD_INFO_REGISTER_RCA:
// RCA is in bytes 3,4
m_RelativeAddress = (SD_CARD_RCA)pResponse->ResponseBuffer[3];
m_RelativeAddress |= ((SD_CARD_RCA)pResponse->ResponseBuffer[4]) << 8;
break;
case SD_INFO_REGISTER_OCR:
m_CachedRegisters.OCR[3] = pResponse->ResponseBuffer[4];
m_CachedRegisters.OCR[2] = pResponse->ResponseBuffer[3];
m_CachedRegisters.OCR[1] = pResponse->ResponseBuffer[2];
m_CachedRegisters.OCR[0] = pResponse->ResponseBuffer[1];
break;
case SD_INFO_REGISTER_CSD:
memcpy(m_CachedRegisters.CSD, pResponse->ResponseBuffer, SD_CSD_REGISTER_SIZE);
break;
case SD_INFO_REGISTER_IO_OCR:
m_CachedRegisters.IO_OCR[2] = pResponse->ResponseBuffer[3];
m_CachedRegisters.IO_OCR[1] = pResponse->ResponseBuffer[2];
m_CachedRegisters.IO_OCR[0] = pResponse->ResponseBuffer[1];
break;
default:
DEBUGCHK(FALSE);
}
}
SD_API_STATUS CSDDevice::SetOperationVoltage(SDCARD_DEVICE_TYPE DeviceType,BOOL SetHCPower)
{
SD_API_STATUS status = SD_API_STATUS_DEVICE_UNSUPPORTED;
if (SetHCPower) {
DWORD ocrValue;
ASSERT(m_FuncionIndex == 0 );
if (m_DeviceType == Device_SD_Memory || m_DeviceType == Device_MMC) {
ocrValue = (DWORD)m_CachedRegisters.OCR[0] & ~0xF;
ocrValue |= ((DWORD)m_CachedRegisters.OCR[1]) << 8;
ocrValue |= ((DWORD)m_CachedRegisters.OCR[2]) << 16;
}
else if (m_DeviceType == Device_SD_IO || m_DeviceType == Device_SD_Combo) {
ocrValue = (DWORD)m_CachedRegisters.IO_OCR[0] & ~0xF;
ocrValue |= ((DWORD)m_CachedRegisters.IO_OCR[1]) << 8;
ocrValue |= ((DWORD)m_CachedRegisters.IO_OCR[2]) << 16;
}
else
ASSERT(FALSE);
m_OperatingVoltage = m_sdSlot.SDGetOperationalVoltageRange(ocrValue);
}
// check to see if the voltages can be supported
if (0 != m_OperatingVoltage ) {
// power up the card
status = SetCardPower(DeviceType, m_OperatingVoltage, SetHCPower);
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SetCardPower - Set the card power
// Input: DeviceType - the device type
// OperatingVoltageMask - operating voltage mask
// pSlot - the slot
// SetHCPower - flag to indicate whether the power should be set in the HC
// (combo cards do not need to reset power if the I/O portion
// was already powered).
//
// Output:
// Return: SD_API_STATUS code
// Notes:
// This function sets the card power and polls the card until it is
// not busy
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::SetCardPower(SDCARD_DEVICE_TYPE DeviceType,DWORD OperatingVoltageMask,BOOL SetHCPower)
{
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
SD_COMMAND_RESPONSE response; // response
UCHAR command; // command
SD_RESPONSE_TYPE responseType; // response type
ULONG powerUpRetries; // power up retries
BOOL appcmd = FALSE; // command is an app cmd
ULONG powerUpInterval; // powerup interval
ULONG totalPowerUpTime; // total powerup time
ULONG powerUpIntervalByDevice; // powerup interval by device
switch (DeviceType) {
case Device_MMC:
command = SD_CMD_MMC_SEND_OPCOND;
responseType = ResponseR3;
powerUpIntervalByDevice = DEFAULT_POWER_UP_MMC_POLL_INTERVAL;
break;
case Device_SD_IO:
command = SD_CMD_IO_OP_COND;
responseType = ResponseR4;
powerUpIntervalByDevice = DEFAULT_POWER_UP_SDIO_POLL_INTERVAL;
break;
case Device_SD_Memory:
command = SD_ACMD_SD_SEND_OP_COND;
responseType = ResponseR3;
appcmd = TRUE;
powerUpIntervalByDevice = DEFAULT_POWER_UP_SD_POLL_INTERVAL;
break;
default:
DEBUGCHK(FALSE);
return SD_API_STATUS_INVALID_PARAMETER;
}
// check to see if we need to apply power
if (SetHCPower) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Setting slot %d power to 0x%08X \n"),
m_sdSlot.GetSlotIndex(), OperatingVoltageMask));
// set slot power
status = m_sdSlot.SDSetSlotPower(OperatingVoltageMask);
if (!SD_API_SUCCESS(status)) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Host failed to set slot power 0x%08X on slot:%d \n"),
status, m_sdSlot.GetSlotIndex()));
return status;
}
m_sdSlot.DelayForPowerUp();
}
if (Device_SD_IO != DeviceType) {
// put the card into idle again
status = SendSDCommand(SD_CMD_GO_IDLE_STATE, 0x00000000, NoResponse, NULL);
if (!SD_API_SUCCESS(status)){
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Go Idle Failed during powerup: Status: 0x%08X on slot:%d \n"),status,
m_sdSlot.GetSlotIndex()));
return status;
}
if ((Device_SD_Memory == DeviceType || Device_MMC==DeviceType) && IsValid20Card()) {
OperatingVoltageMask |= 0x40000000; // HCS
}
}
totalPowerUpTime = CSDHostContainer::RegValueDWORD(POWER_UP_POLL_TIME_KEY, DEFAULT_POWER_UP_TOTAL_WAIT_TIME);
powerUpInterval = CSDHostContainer::RegValueDWORD(POWER_UP_POLL_TIME_INTERVAL_KEY, powerUpIntervalByDevice);
powerUpRetries = totalPowerUpTime/powerUpInterval;
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Power Set, checking card in slot %d, MaxRetries: %d, Time: %d MS, Interval: %d MS \n"),
m_sdSlot.GetSlotIndex(), powerUpRetries, totalPowerUpTime , powerUpInterval));
while (powerUpRetries != 0) {
if (appcmd) {
// send it as an APP cmd
status = SendSDAppCommand(command,
OperatingVoltageMask,
responseType,
&response);
} else {
#ifdef _MMC_SPEC_42_
/**
* Description : To support MMC Spec 4.2
*/
OperatingVoltageMask |= (1<<30);
#endif
// send the command to get the ready bit
status = SendSDCommand(command,
OperatingVoltageMask,
responseType,
&response);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -