⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdhcslot.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        PDWORD pdwVddSetting = (PDWORD) pData;
        SetVoltage(*pdwVddSetting);
        break;
    }

    case SDHCDSetSlotInterface: {
        DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE));
        PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;
//-----------------------------------------------------------------
// 2007.10.08 D.Baek
#ifdef __MMCmicro_SUPPORT__
		if(pInterface->IsMMCmicro == TRUE)
		{
			g_bIsMMCmicro = TRUE;
		}else
		{
			g_bIsMMCmicro = FALSE;
		}
#endif
//-----------------------------------------------------------------
		
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("CSDHCSlotBase::SlotOptionHandler: Clock Setting: %d\n"), pInterface->ClockRate));
        RETAILMSG(CRC_DEBUG,(TEXT("CSDHCSlotBase::SlotOptionHandler -> SetInterface()\r\n"))); // jylee
        SetInterface(pInterface);
        RETAILMSG(0,(TEXT("CSDHCSlotBase::SlotOptionHandler -> SetInterface is exited\r\n"))); // jylee
        break;
    }

    case SDHCDEnableSDIOInterrupts:
    case SDHCDAckSDIOInterrupt:
        EnableSDIOInterrupts(TRUE);
        break;

    case SDHCDDisableSDIOInterrupts:
        EnableSDIOInterrupts(FALSE);
        break;

    case SDHCDGetWriteProtectStatus: {
        DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE));
        PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;
        // For the case of s3c6400
        // PRESENT_STATE_REGISTER[19] = 0 : Write protected
        // PRESENT_STATE_REGISTER[19] = 1 : Write enabled
        // STATE_WRITE_PROTECT = 0x00080000
        if(IsWriteProtected())
        {
              pInterface->WriteProtected = false;
        }else
        {
        	pInterface->WriteProtected = true;
        }
        RETAILMSG(0,(TEXT("Write Protected 0x%x\n"),(ReadDword(SDHC_PRESENT_STATE) & STATE_WRITE_PROTECT))); // jylee
        RETAILMSG(0,(TEXT("Write Protected 0x%x \n"),pInterface->WriteProtected )); // jylee
        break;
    }

    case SDHCDQueryBlockCapability: {
        DEBUGCHK(cbData == sizeof(SD_HOST_BLOCK_CAPABILITY));
        PSD_HOST_BLOCK_CAPABILITY pBlockCaps =
            (PSD_HOST_BLOCK_CAPABILITY)pData;

        DEBUGMSG(SDCARD_ZONE_INFO,
            (TEXT("CSDHCSlotBase::SlotOptionHandler: Read Block Length: %d , Read Blocks: %d\n"),
            pBlockCaps->ReadBlockSize, pBlockCaps->ReadBlocks));
        DEBUGMSG(SDCARD_ZONE_INFO,
            (TEXT("CSDHCSlotBase::SlotOptionHandler: Write Block Length: %d , Write Blocks: %d\n"),
            pBlockCaps->WriteBlockSize, pBlockCaps->WriteBlocks));

        pBlockCaps->ReadBlockSize = max(pBlockCaps->ReadBlockSize, SDHC_MIN_BLOCK_LENGTH);
        pBlockCaps->ReadBlockSize = min(pBlockCaps->ReadBlockSize, (USHORT) m_dwMaxBlockLen);

        pBlockCaps->WriteBlockSize = max(pBlockCaps->WriteBlockSize, SDHC_MIN_BLOCK_LENGTH);
        pBlockCaps->WriteBlockSize = min(pBlockCaps->WriteBlockSize, (USHORT) m_dwMaxBlockLen);
        break;
    }

    case SDHCDGetSlotPowerState: {
        DEBUGCHK(cbData == sizeof(CEDEVICE_POWER_STATE));
        PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
        *pcps = GetPowerState();
        break;
    }

    case SDHCDSetSlotPowerState: {
        DEBUGCHK(cbData == sizeof(CEDEVICE_POWER_STATE));
        PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
        SetPowerState(*pcps);
        break;
    }

    case SDHCDWakeOnSDIOInterrupts: {
        DEBUGCHK(cbData == sizeof(BOOL));
        PBOOL pfWake = (PBOOL) pData;

        if (m_fCanWakeOnSDIOInterrupts) {
            DWORD dwWakeupControl = m_dwDefaultWakeupControl;

            if (*pfWake) {
                dwWakeupControl |= WAKEUP_INTERRUPT;
            }

            m_bWakeupControl = (BYTE) dwWakeupControl;
        }
        else {
            status = SD_API_STATUS_UNSUCCESSFUL;
        }
        break;
    }

    case SDHCDGetSlotInfo: {
        DEBUGCHK(cbData == sizeof(SDCARD_HC_SLOT_INFO));
        PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO) pData;
        status = GetSlotInfo(pSlotInfo);
        break;
    }

    default:
        status = SD_API_STATUS_INVALID_PARAMETER;
    }

    return status;
}


DWORD
CSDHCSlotBase::DetermineMaxClockRate(
                                    )
{
    DEBUGCHK(m_pregDevice->IsOK());

    // We allow the registry to override what is in the capabilities register.
    DWORD dwMaxClockRate = m_pregDevice->ValueDW(SDHC_FREQUENCY_KEY);
    if (dwMaxClockRate == 0) {
        SSDHC_CAPABILITIES caps = GetCapabilities();

        dwMaxClockRate = caps.bits.ClkFreq * 1000000;
        if (dwMaxClockRate == 0) {
            // No clock frequency specified. Use the highest possible that
            // could have been specified so that a working clock divisor
            // will be chosen.
            dwMaxClockRate = SDHC_MAX_CLOCK_FREQUENCY;
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: No base clock frequency specified\n")));
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Using default frequency of %u\n"),
                dwMaxClockRate));
        }
    }

	RETAILMSG(CRC_DEBUG,(TEXT("[DetemineMaxClockRate] dwMaxClockRate = %d\n\r"),dwMaxClockRate));
    return dwMaxClockRate;
}


DWORD
CSDHCSlotBase::DetermineMaxBlockLen(
                                   )
{
    static const USHORT sc_rgusBlockLen[] = {
        SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_0,
        SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_1,
        SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_2
    };

    SSDHC_CAPABILITIES caps = GetCapabilities();

    // Determine the maximum block length
    DEBUGCHK(caps.bits.MaxBlockLen < dim(sc_rgusBlockLen));
    DWORD dwMaxBlockLen = sc_rgusBlockLen[caps.bits.MaxBlockLen];
    DEBUGCHK(dwMaxBlockLen <= SDHC_MAX_BLOCK_LENGTH);
    return dwMaxBlockLen;
}


DWORD
CSDHCSlotBase::DetermineTimeoutControl(
                                      )
{
    // We try to come as close to the desired timeout without going below it.

    DEBUGCHK(m_pregDevice->IsOK());

    SSDHC_CAPABILITIES caps = GetCapabilities();

    // Determine the DAT line timeout divisor.
    // We allow the registry to override what is in the capabilities register.
    DWORD dwTimeoutClock = m_pregDevice->ValueDW(SDHC_TIMEOUT_FREQUENCY_KEY);
    if (dwTimeoutClock == 0) {
        dwTimeoutClock = caps.bits.TOFreq * 1000;

        if (dwTimeoutClock == 0) {
            dwTimeoutClock = SDHC_MAX_CLOCK_FREQUENCY;
            DEBUGMSG(SDCARD_ZONE_ERROR,(_T("SDHC: No timeout frequency specified. Using default of %u\n"),dwTimeoutClock));
        }
        else if (caps.bits.TimeoutUnit == 1) {
            // listing is in MHz, not KHz
            dwTimeoutClock *= 1000;
        }
    }

    DEBUGCHK(dwTimeoutClock != 0);

    DWORD dwTimeoutInMS = m_pregDevice->ValueDW(SDHC_TIMEOUT_KEY, SDHC_DEFAULT_TIMEOUT);

    DOUBLE dTimeoutControl = SdhcTimeoutSecondsToControl(dwTimeoutClock, dwTimeoutInMS / 1000.0);
    DWORD dwTimeoutControl;

    if (dTimeoutControl < 0) {
        dwTimeoutControl = 0;
    }
    else {
        dTimeoutControl = ceil(dTimeoutControl);
        dwTimeoutControl= (DWORD) dTimeoutControl;
    }

    dwTimeoutControl = min(dwTimeoutControl, SDHC_TIMEOUT_CONTROL_MAX);

#ifdef DEBUG
    {
        TCHAR szTimeout[4];
        DOUBLE dActualTimeout = SdhcTimeoutControlToSeconds(dwTimeoutClock,dwTimeoutControl);
        _sntprintf(szTimeout, dim(szTimeout), _T("%0.1f"), dActualTimeout);
		DEBUGCHK(szTimeout[dim(szTimeout) - 1] == 0);
        szTimeout[dim(szTimeout) - 1] = 0; // Null-terminate

        DEBUGMSG(SDCARD_ZONE_INIT, (_T("SDHC: Using timeout control value of 0x%x for %s seconds\n"),
            dwTimeoutControl, szTimeout));
    }
#endif

	dwTimeoutControl	= 0xe;
    return dwTimeoutControl;
}


DWORD
CSDHCSlotBase::DetermineWakeupSources(
                                     )
{
    DEBUGCHK(m_pregDevice->IsOK());
    DWORD dwWakeupSources = m_pregDevice->ValueDW(SDHC_WAKEUP_SOURCES_KEY);
    dwWakeupSources &= WAKEUP_ALL_SOURCES;

    // Waking on SDIO interrupts must be enabled by the bus driver.
    dwWakeupSources &= ~WAKEUP_INTERRUPT;

    return dwWakeupSources;
}


VOID
CSDHCSlotBase::SetVoltage(
                          DWORD dwVddSetting
                          )
{
    Validate();

	RETAILMSG(0,(TEXT("CSDHCSlotBase::SetVoltage  0x%X\n"),dwVddSetting)); // jylee

    UCHAR ucVoltageSelection = SDBUS_POWER_ON;
    UCHAR ucOldVoltage;

    DEBUGCHK(dwVddSetting & m_dwVddWindows);

    if ( dwVddSetting &
         (SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4) ) {
        ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_3_3V;
    }
    else if ( dwVddSetting &
              (SD_VDD_WINDOW_2_9_TO_3_0 | SD_VDD_WINDOW_3_0_TO_3_1) ) {
        ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_3_0V;
    }
    else if ( dwVddSetting &
              (SD_VDD_WINDOW_1_7_TO_1_8 | SD_VDD_WINDOW_1_8_TO_1_9) ) {
        ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_1_8V;
    }

    ucOldVoltage = ReadByte(SDHC_POWER_CONTROL);
    if (ucOldVoltage != ucVoltageSelection) {
        // SD Bus Power must be initially set to 0 when changing voltages
        WriteByte(SDHC_POWER_CONTROL, 0);
        WriteByte(SDHC_POWER_CONTROL, ucVoltageSelection);
        WriteByte(SDHC_POWER_CONTROL, ucVoltageSelection);
        RETAILMSG(0,( // jylee
            TEXT("CSDHCSlotBase::SetVoltage: Set SDHC_POWER_CONTROL reg = 0x%02x     %d\n"),
            ReadByte(SDHC_POWER_CONTROL),GetPowerSupplyRampUpMs()));

        DEBUGMSG(SDCARD_ZONE_INFO,(
            TEXT("CSDHCSlotBase::SetVoltage: Set SDHC_POWER_CONTROL reg = 0x%02x\n"),
            ucVoltageSelection));

        Sleep(GetPowerSupplyRampUpMs());
    }
}


// Set up the controller according to the interface parameters.
VOID
CSDHCSlotBase::SetInterface(
                            PSD_CARD_INTERFACE pInterface
                            )
{
    PREFAST_DEBUGCHK(pInterface);
    Validate();
    BYTE hostctl = 0;

    if (SD_INTERFACE_SD_MMC_1BIT == pInterface->InterfaceMode) {
        DEBUGMSG(SDCARD_ZONE_INIT,  (TEXT("SHCSDSlotOptionHandler - Setting for 1 bit mode \n\r")));
        RETAILMSG(1,(TEXT("[HSMMC] Set to the 1 Bit Data Bus\r\n"))); // jylee
		hostctl = 0;
        m_f4BitMode = FALSE;
    } else if (SD_INTERFACE_SD_4BIT == pInterface->InterfaceMode) {
        DEBUGMSG(SDCARD_ZONE_INIT,
            (TEXT("CSDHCSlotOptionHandler - Setting for 4 bit mode \n")));
        RETAILMSG(1,(TEXT("[HSMMC] Set to the 4 Bit Data Bus\r\n"))); // jylee
		hostctl |= HOSTCTL_DAT_WIDTH;
        m_f4BitMode = TRUE;
    } else if (SD_INTERFACE_MMC_8BIT == pInterface->InterfaceMode) {
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SHCSDSlotOptionHandler - Setting for 8 bit mode \n")));
        RETAILMSG(1,(TEXT("[HSMMC] Set to the 8 Bit Data Bus\r\n"))); // jylee
		hostctl |= HOSTCTL_DAT_WIDTH_8BIT;
        m_f4BitMode = TRUE;
    }else {
        DEBUGCHK(FALSE);
    }

//--------------------------------------------------------------------------------------------
// 2007.09.01 D.Baek
// In the S3C6400, the high-speed enable bit of HOST_CONTROL register must be disabled
// even if the card inserted operates at high-speed mode. This is limited only to the S3C6400.
#if 0
	if(pInterface->ClockRate > 25000000)
	{
		hostctl |= HOSTCTL_HIGHSPEED;
		RETAILMSG(0,(TEXT("Set the \"High Speed Enable\" bit is set\r\n"))); // jylee
	}
#endif
	RETAILMSG(0,(TEXT("HOST_CONTROL : 0x%x\r\n"),hostctl)); // jylee
	SetClockRate(&pInterface->ClockRate);
	WriteByte(SDHC_HOST_CONTROL, hostctl);
}


VOID
CSDHCSlotBase::SetPowerState(
                             CEDEVICE_POWER_STATE cpsNew

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -