FreeBSD/sys/boot/arm/at91/libat91/sd-card.c
//*----------------------------------------------------------------------------
//* \fn    MCI_SDCard_GetOCR
//* \brief Wait for card to power up and determine whether it's SDHC or not.
//*----------------------------------------------------------------------------
\fn    MCI_SDCard_GetOCR
\brief Wait for card to power up and determine whether it's SDHC or not.
\ fn MCI_SDCard_GetOCR \ brief Wait for card to power up and determine whether it ' s SDHC or not .
static int
MCI_SDCard_GetOCR()
{
	unsigned int response;
	unsigned int arg = AT91C_MMC_HOST_VOLTAGE_RANGE;
	int          timeout = AT91C_MCI_TIMEOUT;
	MCI_SendCommand(GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT);
	 Arg is vvpp where vv is voltage range and pp is an arbitrary bit
	 pattern that gets echoed back in the response. The only voltage
	 ranges defined are:
	   0x01 = 2.7 - 3.6
	   0x02 = "reserved for low voltage" whatever that means.
	 If the card fails to respond then it's not v2.0. If it responds by
	 echoing back exactly the arg we sent, then it's a v2.0 card and can
	 run at our voltage.  That means that when we send the ACMD41 (in
	 MCI_SDCard_GetOCR) we can include the HCS bit to inquire about SDHC.
	if (MCI_SendCommand(SD_SEND_IF_COND_CMD, 0x01AA) == 0) {
		MCI_Device.IsSDv2 = (AT91C_BASE_MCI->MCI_RSPR[0] == 0x01AA);
	}
	 If we've determined the card supports v2.0 functionality, set the
	 HCS/CCS bit to indicate that we support SDHC.  This will cause a
	 v2.0 card to report whether it is SDHC in the ACMD41 response.
	if (MCI_Device.IsSDv2) {
		arg |= AT91C_CCS;
	}
	 The RCA to be used for CMD55 in Idle state shall be the card's 
	 default RCA=0x0000.
	MCI_Device.RCA = 0x0;
	 Repeat ACMD41 until the card comes out of power-up-busy state.
	do {
		if (MCI_SDCard_SendAppCommand(SDCARD_APP_OP_COND_CMD, arg)) {
			return 1;
		}
		response = AT91C_BASE_MCI->MCI_RSPR[0];
	} while (!(response & AT91C_CARD_POWER_UP_DONE) && (--timeout > 0));
	 A v2.0 card sets CCS (card capacity status) in the response if it's SDHC.
	if (MCI_Device.IsSDv2) {
		MCI_Device.IsSDHC = ((response & AT91C_CCS) == AT91C_CCS);
	}
	return (0);
}
static int MCI_SDCard_GetOCR ( ) { unsigned int response ; unsigned int arg = AT91C_MMC_HOST_VOLTAGE_RANGE ; int timeout = AT91C_MCI_TIMEOUT ; MCI_SendCommand ( GO_IDLE_STATE_CMD , AT91C_NO_ARGUMENT ) ; if ( MCI_SendCommand ( SD_SEND_IF_COND_CMD , 0x01AA ) == 0 ) { MCI_Device . IsSDv2 = ( AT91C_BASE_MCI -> MCI_RSPR [ 0 ] == 0x01AA ) ; } if ( MCI_Device . IsSDv2 ) { arg |= AT91C_CCS ; } MCI_Device . RCA = 0x0 ; do { if ( MCI_SDCard_SendAppCommand ( SDCARD_APP_OP_COND_CMD , arg ) ) { return 1 ; } response = AT91C_BASE_MCI -> MCI_RSPR [ 0 ] ; } while ( ! ( response & AT91C_CARD_POWER_UP_DONE ) && ( -- timeout > 0 ) ) ; if ( MCI_Device . IsSDv2 ) { MCI_Device . IsSDHC = ( ( response & AT91C_CCS ) == AT91C_CCS ) ; } return ( 0 ) ; }
\fn    MCI_SDCard_GetOCR
\brief Wait for card to power up and determine whether it's SDHC or not.
\ fn MCI_SDCard_GetOCR \ brief Wait for card to power up and determine whether it ' s SDHC or not .
// Force card to idle state. // Begin probe for SDHC by sending CMD8; only v2.0 cards respond to it. // // Arg is vvpp where vv is voltage range and pp is an arbitrary bit // pattern that gets echoed back in the response. The only voltage // ranges defined are: //   0x01 = 2.7 - 3.6 //   0x02 = "reserved for low voltage" whatever that means. // // If the card fails to respond then it's not v2.0. If it responds by // echoing back exactly the arg we sent, then it's a v2.0 card and can // run at our voltage.  That means that when we send the ACMD41 (in // MCI_SDCard_GetOCR) we can include the HCS bit to inquire about SDHC. // If we've determined the card supports v2.0 functionality, set the // HCS/CCS bit to indicate that we support SDHC.  This will cause a // v2.0 card to report whether it is SDHC in the ACMD41 response. // The RCA to be used for CMD55 in Idle state shall be the card's  // default RCA=0x0000. // Repeat ACMD41 until the card comes out of power-up-busy state. // A v2.0 card sets CCS (card capacity status) in the response if it's SDHC.