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

📄 sdhcslot.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:

#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
		case SDHCDSetSlotInterfaceEx: {
										  DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE_EX));
										  PSD_CARD_INTERFACE_EX pInterface = (PSD_CARD_INTERFACE_EX) pData;

										  DEBUGMSG(SDCARD_ZONE_INFO, 
												  (TEXT("CSDHCSlotBase::SlotOptionHandler: Clock Setting: %d\n"), 
												   pInterface->ClockRate));

										  SetInterface((PSD_CARD_INTERFACE_EX)pInterface);
										  break;
									  }
#endif

		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;
											 pInterface->WriteProtected = IsWriteProtected();
											 RETAILMSG(0,(TEXT("Write Protected 0x%x \n"),pInterface->WriteProtected ));
											 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(0,(TEXT("dwMaxClockRate = %d\n"),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));

	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);
		RETAILMSG(0,( 
					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.
#if (BSP_TYPE == BSP_SMDK2443)
VOID 
CSDHCSlotBase::SetInterface(
		PSD_CARD_INTERFACE pInterface
		)
{            
	PREFAST_DEBUGCHK(pInterface);
	Validate();
	BYTE hostctl = 0;
	RETAILMSG(0,(TEXT("CSDHCSlotBase::SetInterface %d\n"),pInterface->InterfaceMode));
	if (SD_INTERFACE_SD_MMC_1BIT == pInterface->InterfaceMode) {
		DEBUGMSG(SDCARD_ZONE_INIT, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 1 bit mode \n")));
		RETAILMSG(1, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 1 bit mode , Clock Rate =%d \n"),pInterface->ClockRate));		
		//        WriteByte(SDHC_HOST_CONTROL, 0);
		hostctl = 0;
		m_f4BitMode = FALSE;
	} else if (SD_INTERFACE_SD_4BIT == pInterface->InterfaceMode) {
		DEBUGMSG(SDCARD_ZONE_INIT, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 4 bit mode \n")));
		RETAILMSG(1, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 4 bit mode , Clock Rate =%d \n"),pInterface->ClockRate));
		//       WriteByte(SDHC_HOST_CONTROL, HOSTCTL_DAT_WIDTH);
		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("SHCSDSlotOptionHandler - Setting for 8 bit mode , Clock Rate =%d \n"),pInterface->ClockRate));		
		//        WriteByte(SDHC_HOST_CONTROL, HOSTCTL_DAT_WIDTH_8BIT|HOSTCTL_HIGHSPEED);
		hostctl |= HOSTCTL_DAT_WIDTH_8BIT;
		m_f4BitMode = TRUE;
	}else {
		DEBUGCHK(FALSE);
	}

	if(pInterface->ClockRate > 25000000)
	{
		hostctl |= HOSTCTL_HIGHSPEED;
	}

	WriteByte(SDHC_HOST_CONTROL, hostctl);
	SetClockRate(&pInterface->ClockRate);
}

#elif (BSP_TYPE == BSP_SMDK2450)
VOID 
CSDHCSlotBase::SetInterface(
		PSD_CARD_INTERFACE_EX pInterface
		)
{            
	PREFAST_DEBUGCHK(pInterface);
	Validate();

#if 0
	BYTE bHostCtr = 0;
	m_f4BitMode = (pInterface->InterfaceModeEx.bit.sd4Bit!=0);
	bHostCtr |= (m_f4BitMode?HOSTCTL_DAT_WIDTH:0);
	bHostCtr |= (pInterface->InterfaceModeEx.bit.sdHighSpeed!=0?HOSTCTL_HIGH_SPEED:0);
#endif
	BYTE hostctl = 0;
	if (1 == pInterface->InterfaceModeEx.bit.hsmmc8Bit) {
		DEBUGMSG(SDCARD_ZONE_INIT, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 8 bit mode\n")));
		RETAILMSG(1, 
				(TEXT("[HSMMC0] Setting for 8 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));
		hostctl |= HOSTCTL_DAT_WIDTH_8BIT;
		m_f4BitMode = TRUE;
	} else if (SD_INTERFACE_SD_MMC_1BIT == pInterface->InterfaceModeEx.bit.sd4Bit) {
		DEBUGMSG(SDCARD_ZONE_INIT, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 1 bit mode\n")));
		RETAILMSG(1, 
				(TEXT("[HSMMC0] Setting for 1 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));		
		hostctl = 0;
		m_f4BitMode = FALSE;
	} else if (SD_INTERFACE_SD_4BIT == pInterface->InterfaceModeEx.bit.sd4Bit) {
		DEBUGMSG(SDCARD_ZONE_INIT, 
				(TEXT("SHCSDSlotOptionHandler - Setting for 4 bit mode\n")));
		RETAILMSG(1, 
				(TEXT("[HSMMC0] Setting for 4 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));
		hostctl |= HOSTCTL_DAT_WIDTH;
		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 > 26000000) || (pInterface->InterfaceModeEx.bit.sdHighSpeed!=0) )
	{
		RETAILMSG(1, (TEXT("[HSMMC0] Setting for high speed mode.\n")));
		hostctl |= HOSTCTL_HIGH_SPEED;
	}
#endif

	DEBUGMSG(SDCARD_ZONE_INIT, 
			(TEXT("SHCSDSlotOptionHandler - Setting Host Control Register %x \n"),bHostCtr));
	//    WriteByte(SDHC_HOST_CONTROL, bHostCtr);
	WriteByte(SDHC_HOST_CONTROL, hostctl);
	SetClockRate(&pInterface->ClockRate);
}
#endif


VOID
CSDHCSlotBase::SetPowerState(
		CEDEVICE_POWER_STATE cpsNew
		)
{
	DEBUGCHK(VALID_DX(cpsNew));

	m_fIsPowerManaged = TRUE;

	if (DX_D1_OR_D2(cpsNew)) {
		cpsNew = D0;
	}

	if (m_cpsCurrent != cpsNew) {
		SetHardwarePowerState(cpsNew);
	}
}


VOID
CSDHCSlotBase::PowerDown(

⌨️ 快捷键说明

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