| 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_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 |