314284b156
The new API no longer uses the extra cd parameter that was used to store the card presence state. Instead, this information is returned via the function's return value. board_mmc_getcd() returns -1 to indicate that no card-detection mechanism is implemented; 0 indicates that no card is present and 1 is returned if it was detected that a card is present. The rationale for this change can be found in the following email thread: http://lists.denx.de/pipermail/u-boot/2011-November/110180.html In summary, the old API was not consistent with the rest of the MMC API which always passes a struct mmc as the first parameter. Furthermore the cd parameter was used to mean "card absence" in some implementations and "card presence" in others. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Tested-by: Jason Liu <jason.hui@linaro.org>
78 lines
2.4 KiB
Plaintext
78 lines
2.4 KiB
Plaintext
How to use SD/MMC cards with Atmel SoCs having MCI hardware
|
|
-----------------------------------------------------------
|
|
2010-08-16 Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
|
|
|
|
This is a new approach to use Atmel MCI hardware with the
|
|
general MMC framework. Therefore it benefits from that
|
|
framework's abilities to handle SDHC Cards and the ability
|
|
to write blocks.
|
|
|
|
- AT91SAM9XE512 (tested, will definitely work with XE128 and XE256)
|
|
- AT91SAM9260 (not tested, but MCI is to AT91SAM9XE)
|
|
- AT91SAM9G20 (not tested, should work)
|
|
|
|
It should work with all other ATMEL devices that have MCI,
|
|
including AVR32.
|
|
|
|
The generic driver does NOT assign port pins to the MCI block
|
|
nor does it start the MCI clock. This has to be handled in a
|
|
board/SoC specific manner before the driver is initialized:
|
|
|
|
example: this is added to at91sam9260_devices.c:
|
|
|
|
#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
|
|
void at91_mci_hw_init(void)
|
|
{
|
|
at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCCK */
|
|
#if defined(CONFIG_ATMEL_MCI_PORTB)
|
|
at91_set_b_periph(AT91_PIO_PORTA, 1, PUP); /* MCCDB */
|
|
at91_set_b_periph(AT91_PIO_PORTA, 0, PUP); /* MCDB0 */
|
|
at91_set_b_periph(AT91_PIO_PORTA, 5, PUP); /* MCDB1 */
|
|
at91_set_b_periph(AT91_PIO_PORTA, 4, PUP); /* MCDB2 */
|
|
at91_set_b_periph(AT91_PIO_PORTA, 3, PUP); /* MCDB3 */
|
|
#else
|
|
at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* MCCDA */
|
|
at91_set_a_periph(AT91_PIO_PORTA, 6, PUP); /* MCDA0 */
|
|
at91_set_a_periph(AT91_PIO_PORTA, 9, PUP); /* MCDA1 */
|
|
at91_set_a_periph(AT91_PIO_PORTA, 10, PUP); /* MCDA2 */
|
|
at91_set_a_periph(AT91_PIO_PORTA, 11, PUP); /* MCDA3 */
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
the board specific file need added:
|
|
...
|
|
#ifdef CONFIG_GENERIC_ATMEL_MCI
|
|
# include <mmc.h>
|
|
#endif
|
|
...
|
|
#ifdef CONFIG_GENERIC_ATMEL_MCI
|
|
/* this is a weak define that we are overriding */
|
|
int board_mmc_init(bd_t *bd)
|
|
{
|
|
/* Enable clock */
|
|
at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI);
|
|
at91_mci_hw_init();
|
|
|
|
/* This calls the atmel_mci_init in gen_atmel_mci.c */
|
|
return atmel_mci_init((void *)AT91_BASE_MCI);
|
|
}
|
|
|
|
/* this is a weak define that we are overriding */
|
|
int board_mmc_getcd(struct mmc *mmc)
|
|
{
|
|
return !at91_get_gpio_value(CONFIG_SYS_MMC_CD_PIN);
|
|
}
|
|
|
|
#endif
|
|
|
|
and the board definition files needs:
|
|
|
|
/* SD/MMC card */
|
|
#define CONFIG_MMC 1
|
|
#define CONFIG_GENERIC_MMC 1
|
|
#define CONFIG_GENERIC_ATMEL_MCI 1
|
|
#define CONFIG_ATMEL_MCI_PORTB 1 /* Atmel XE-EK uses port B */
|
|
#define CONFIG_SYS_MMC_CD_PIN AT91_PIN_PC9
|
|
#define CONFIG_CMD_MMC 1
|