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

📄 sddevice.cpp

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

#ifdef _MMC_SPEC_42_
		/*************************************************************************/
		/****** Date : 07.05.04                                         	******/
		/****** Developer : HS.JANG											******/
		/****** Description : to distinguish the hsmmc slot from normal slot******/
		/*************************************************************************/

		if ( m_dwMMCSpecVer == Device_HSMMC40 )
		{
			MMC_PARSED_REGISTER_EXTCSD temp;
			SD_COMMAND_RESPONSE response;

			// set data bus width as default.
			// It is needed after wakeup. hsjang 070822
			status = SendSDCommand(	SD_ACMD_SET_BUS_WIDTH,
					(3<<24) | (183<<16) | (0<<8) ,
					ResponseR1b,
					&response);

			if (!SD_API_SUCCESS(status))
			{
				RETAILMSG(1,(TEXT("[SDBUS-ERR] SelectCardInterface:Switch Command is failed %x\n"),status));			
				return status;
			}

			// if the MMC card is on SPEC40, EXT_CSD value is needed.	 	
			GetEXTCSDFromHSMMC();
			memcpy(&temp,m_ucEXTCSD,MMC_EXTCSD_REGISTER_SIZE);			

			if((m_sdSlot.Capabilities & SD_SLOT_HIGH_SPEED_CAPABLE)!=0)  
			{
				RETAILMSG(1,(TEXT("[SDBUS] HSMMC card in HSMMC slot\n")));
				// 08.04.04 by KYS
				// Because HSMMC Ch0 support only 4 data bus width,
				// In order to distinguish the bus width, Read the capabilities of HostController!
				if ((m_sdSlot.Capabilities & SD_SLOT_SD_8BIT_CAPABLE)!=0) {
					m_CardInterfaceEx.InterfaceModeEx.bit.hsmmc8Bit = 1;
				} else {
					RETAILMSG(1,(TEXT("[SDBUS] This MMC Card spec is 4.xx. But this slot support only 4bit\r\n")));
				}
				m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
				if ( temp.CardType != 0x1 )
				{
					RETAILMSG(1,(TEXT("[SDBUS] This HSMMC card supports up to 52Mhz\n")));
					m_CardInterfaceEx.ClockRate = HSMMC_FULL_SPEED_RATE;
				}
				else
				{
					RETAILMSG(1,(TEXT("[SDBUS] This HSMMC card only supports up to 26Mhz\n")));
#if (BSP_TYPE == BSP_SMDK2443)
					m_CardInterfaceEx.ClockRate = SD_FULL_SPEED_RATE;

#elif (BSP_TYPE == BSP_SMDK2450)
					m_CardInterfaceEx.ClockRate = MMCPLUS_SPEED_RATE;
#endif
				}
			}
			else
			{
				RETAILMSG(1,(TEXT("[SDBUS] HSMMC card in **NOT** HSMMC slot\n")));
				m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
				m_CardInterfaceEx.ClockRate = MMC_FULL_SPEED_RATE;
			}
		}
		else
			/*************************************************************************/
#endif		
		{
			m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0;
			m_CardInterfaceEx.ClockRate = MMC_FULL_SPEED_RATE;
		}


	}

	// select the actual interface speed and type based on the card type 
	if (Device_SD_IO == m_DeviceType) {
		CSDDevice * pParentDevice = m_sdSlot.GetFunctionDevice( 0 );
		if (pParentDevice) {
			// check for a low speed device
			if (pParentDevice->m_SDCardInfo.SDIOInformation.pCommonInformation->CardCapability & SD_IO_CARD_CAP_LOW_SPEED) {
				// drop it down to low speed
				m_CardInterfaceEx.ClockRate = SD_LOW_SPEED_RATE;
				// check for 4 bit support at low speed
				if (!(pParentDevice->m_SDCardInfo.SDIOInformation.pCommonInformation->CardCapability & SD_IO_CARD_CAP_4_BIT_LOW_SPEED)) {
					// drop to 1 bit mode if the low speed device doesn't support
					// 4 bit operation
					m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0 ;
				}
			} 
			pParentDevice->DeRef();
		}
		else {
			ASSERT(FALSE);
			status = SD_API_STATUS_UNSUCCESSFUL;
		}

	}
	else if (Device_SD_Memory == m_DeviceType || Device_SD_Combo == m_DeviceType) {

		// get the bus width bits from the SCR to check for 4 bit
		// all cards must minimally support 1 bit mode
		bitSlice = GetBitSlice(m_CachedRegisters.SCR, sizeof(m_CachedRegisters.SCR), SD_SCR_BUS_WIDTH_BIT_SLICE , SD_SCR_BUS_WIDTH_SLICE_SIZE);

		if (!(bitSlice & SD_SCR_BUS_WIDTH_4_BIT)) {
			// card only supports 1 bit mode
			DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: SD Memory Card only supports 1 bit mode! \n"),
						m_FuncionIndex));
			m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0 ;
		}

		// SD cards have their Max transfer rate set to 25 Mhz, we do not need to check the CSD register

	} else if (Device_MMC == m_DeviceType) {

		// for MMC cards we need to check the Max Transfer Rate reported by the card
		// the data rate is in kbits/sec
		if ((CSDRegister.MaxDataTransferRate * 1000) < MMC_FULL_SPEED_RATE) {
			// set for a lower rate
			m_CardInterfaceEx.ClockRate = CSDRegister.MaxDataTransferRate * 1000;   
		} 

		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: MMC Card Max Transfer Rate: %d Hz \n"),
					m_CardInterfaceEx.ClockRate));
	} else {
		DEBUGCHK(FALSE);
		return SD_API_STATUS_INVALID_PARAMETER;
	}

	if (SD_API_SUCCESS(status)) {
		// get any interface overrides via the registry
		GetInterfaceOverrides();
		// sanity check the overrides
		if ((!(m_sdSlot.Capabilities & SD_SLOT_SD_4BIT_CAPABLE)) && (m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit)) {
			if ( (!(m_sdSlot.Capabilities & SD_SLOT_SDMEM_4BIT_CAPABLE)) &&(!( m_sdSlot.Capabilities & SD_SLOT_SDIO_4BIT_CAPABLE)) ) {
				DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: override to 4 bit on non-4-bit capable host, not allowed! \n")));
				return SD_API_STATUS_INVALID_PARAMETER;
			}
		}    

		// get the write protect status
		if (Device_SD_Memory == m_DeviceType) {
			SD_CARD_INTERFACE sdCardInterface;
			status = m_sdSlot.GetHost().SlotOptionHandler(m_sdSlot.GetSlotIndex(), SDHCDGetWriteProtectStatus, &sdCardInterface, sizeof(sdCardInterface));
			m_CardInterfaceEx.InterfaceModeEx.bit.sdWriteProtected = (sdCardInterface.WriteProtected?1:0);
			if (m_CardInterfaceEx.InterfaceModeEx.bit.sdWriteProtected) {
				DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Card in slot %d is write protected \n"),m_sdSlot.GetSlotIndex()));
			}

		}
	}
	DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Interface for slot %d , Mode :%x, Clock:%d \n"),
				m_sdSlot.GetSlotIndex(),m_CardInterfaceEx.InterfaceModeEx.uInterfaceMode,m_CardInterfaceEx.ClockRate));  


	ASSERT(SD_API_SUCCESS(status));
	return status;

}
///////////////////////////////////////////////////////////////////////////////
//  GetInterfaceOverrides - get card interface overrides from the user
//  Input:  pDevice - the device
//          
//  Output: 
//  Return: 
//  Notes:  This function gets the overrides from the device path in the 
//          registry.  This function only uses a path built from the card's 
//          OEM, MANF or CARDIDs.  It will not search a class path. For multi-
//          function and combo devices, overrides detected in the MANF and CARDID 
//          path ex:[HKLM\Drivers\SDCARD\ClientDrivers\Custom\MANF-xxxx-CARDID-xxxx]
//          will override the interface settings for the entire card (all functions).
//          
///////////////////////////////////////////////////////////////////////////////
VOID CSDDevice::GetInterfaceOverrides()
{
	WCHAR regPath[MAX_KEY_PATH_LENGTH]; // regpath
	DWORD clockRate;                    // clockrate override
	DWORD interfaceMode;                // interface mode override

	// get the card registry path
	if (!SD_API_SUCCESS(GetCustomRegPath(regPath, dim(regPath), TRUE))) {
		return;
	}

	CReg regDevice(HKEY_LOCAL_MACHINE, regPath);
	if (regDevice.IsOK()) {
		// check for clock rate override
		clockRate = regDevice.ValueDW(SDCARD_CLOCK_RATE_OVERRIDE, -1);
		if (clockRate != -1) {
			DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides clock rate to : %d\n"),
						regPath,clockRate));
			m_CardInterfaceEx.ClockRate = clockRate;
		}

		// check for interface mode override
		interfaceMode = regDevice.ValueDW(SDCARD_INTERFACE_MODE_OVERRIDE, -1);
		if (interfaceMode != -1) {
			if (interfaceMode == SDCARD_INTERFACE_OVERRIDE_1BIT) {
				m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 0 ;
				DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides interface mode to 1 bit \n"),regPath));
			} else if (interfaceMode == SDCARD_INTERFACE_OVERRIDE_4BIT) {
				m_CardInterfaceEx.InterfaceModeEx.bit.sd4Bit = 1;
				DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: RegPath: %s overrides interface mode to 4 bit \n"),regPath));
			}
		}
	}
}


///////////////////////////////////////////////////////////////////////////////
//  GetCustomRegPath - get a device's custom registry path
//  Input:  pDevice - the device instance
//          cchPath - number of characters in pPath
//          BasePath - if TRUE return only the card's base path not
//                     its function path (single or multifunction I/O cards)
//                     this parameter is ignored for memory cards
//  Output: pPath   - the path returned
//  Notes:  
//      returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::GetCustomRegPath(LPTSTR                 pPath,
		DWORD                  cchPath,
		BOOL                   BasePath) 
{
	SD_PARSED_REGISTER_CID  ParsedRegisters;                // parsed registers
	SD_API_STATUS           status = SD_API_STATUS_SUCCESS; // intermediate status

	DEBUGCHK(pPath);

	// for Memory or MMC get the CID
	if ( (Device_SD_Memory == m_DeviceType) ||(Device_MMC == m_DeviceType) || (Device_SD_Combo==m_DeviceType) ) {
		// get the parsed CID registers
		status = SDCardInfoQuery_I( SD_INFO_REGISTER_CID,&ParsedRegisters, sizeof(ParsedRegisters));
#define TEMP_CHAR_BUFFER_SIZE 3
		if (SD_API_SUCCESS(status)) {
			TCHAR szOEMID0[TEMP_CHAR_BUFFER_SIZE];
			TCHAR szOEMID1[TEMP_CHAR_BUFFER_SIZE];
			TCHAR szProductName0[TEMP_CHAR_BUFFER_SIZE];
			TCHAR szProductName1[TEMP_CHAR_BUFFER_SIZE];
			TCHAR szProductName2[TEMP_CHAR_BUFFER_SIZE];
			TCHAR szProductName3[TEMP_CHAR_BUFFER_SIZE];
			TCHAR szProductName4[TEMP_CHAR_BUFFER_SIZE];

			// the OEM application ID and product name should only contain 7 bit ASCII characters, 
			// but some cards use other characters in the 127-255 range).  This causes a problem because
			// the registry path is made up of these characters, and should not contain any characters 
			// outside of the 32-126 range.
			// the following code will check each of the characters, and replace them with two digit 
			// hexadecimal string representation if necessary

			if( ParsedRegisters.OEMApplicationID[0] >= 32 && ParsedRegisters.OEMApplicationID[0] < 127 )
				StringCchPrintf( szOEMID0, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.OEMApplicationID[0] );
			else
				StringCchPrintf( szOEMID0, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.OEMApplicationID[0] );

			if( ParsedRegisters.OEMApplicationID[1] >= 32 && ParsedRegisters.OEMApplicationID[1] < 127 )
				StringCchPrintf( szOEMID1, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.OEMApplicationID[1] );
			else
				StringCchPrintf( szOEMID1, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.OEMApplicationID[1] );

			if( ParsedRegisters.ProductName[0] >= 32 && ParsedRegisters.ProductName[0] < 127 )
				StringCchPrintf( szProductName0, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[0] );
			else
				StringCchPrintf( szProductName0, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[0] );

			if( ParsedRegisters.ProductName[1] >= 32 && ParsedRegisters.ProductName[1] < 127 )
				StringCchPrintf( szProductName1, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[1] );
			else
				StringCchPrintf( szProductName1, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[1] );

			if( ParsedRegisters.ProductName[2] >= 32 && ParsedRegisters.ProductName[2] < 127 )
				StringCchPrintf( szProductName2, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[2] );
			else
				StringCchPrintf( szProductName2, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[2] );

			if( ParsedRegisters.ProductName[3] >= 32 && ParsedRegisters.ProductName[3] < 127 )
				StringCchPrintf( szProductName3, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[3] );
			else
				StringCchPrintf( szProductName3, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[3] );

			if( ParsedRegisters.ProductName[4] >= 32 && ParsedRegisters.ProductName[4] < 127 )
				StringCchPrintf( szProductName4, TEMP_CHAR_BUFFER_SIZE, TEXT("%c"), (TCHAR)ParsedRegisters.ProductName[4] );
			else
				StringCchPrintf( szProductName4, TEMP_CHAR_BUFFER_SIZE, TEXT("%02x"), (TCHAR)ParsedRegisters.ProductName[4] );

			// build up the string
			HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\CID-%d-%s%s-%s%s%s%s%s"),
					SDCARD_CUSTOM_DEVICE_REG_PATH,
					ParsedRegisters.ManufacturerID,
					szOEMID0, szOEMID1,
					szProductName0, szProductName1, szProductName2, szProductName3, szProductName4 );
			DEBUGCHK(SUCCEEDED(hr));

			DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom MMC/SD path: %s \n"),pPath));
		}
	}
	else if (Device_SD_IO == m_DeviceType) {
		if (BasePath) {
			// build the custom registry path for the card as a whole
			HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X"),
					SDCARD_CUSTOM_DEVICE_REG_PATH,
					m_SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
					m_SDCardInfo.SDIOInformation.pCommonInformation->CardID);  
			DEBUGCHK(SUCCEEDED(hr));
		} else {
			// build the custom registry path for the SDIO card function
			HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X-FUNC-%d"),
					SDCARD_CUSTOM_DEVICE_REG_PATH,
					m_SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
					m_SDCardInfo.SDIOInformation.pCommonInformation->CardID,
					m_SDCardInfo.SDIOInformation.Function);
			DEBUGCHK(SUCCEEDED(hr));
		}

		DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom SDIO path: %s \n"),pPath));
	}
	else {
		DEBUG_ASSERT(FALSE);
		status = SD_API_STATUS_INVALID_PARAMETER;
	}

	return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDLoadDevice - load the associated device driver
//  Input:  pDevice - the

⌨️ 快捷键说明

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