]>
Commit | Line | Data |
---|---|---|
1592ef85 RM |
1 | How to use SD/MMC cards with Atmel SoCs having MCI hardware |
2 | ----------------------------------------------------------- | |
3 | 2010-08-16 Reinhard Meyer <reinhard.meyer@emk-elektronik.de> | |
4 | ||
5 | This is a new approach to use Atmel MCI hardware with the | |
6 | general MMC framework. Therefore it benefits from that | |
7 | framework's abilities to handle SDHC Cards and the ability | |
8 | to write blocks. | |
9 | ||
10 | - AT91SAM9XE512 (tested, will definitely work with XE128 and XE256) | |
11 | - AT91SAM9260 (not tested, but MCI is to AT91SAM9XE) | |
12 | - AT91SAM9G20 (not tested, should work) | |
13 | ||
14 | It should work with all other ATMEL devices that have MCI, | |
15 | including AVR32. | |
16 | ||
17 | The generic driver does NOT assign port pins to the MCI block | |
18 | nor does it start the MCI clock. This has to be handled in a | |
19 | board/SoC specific manner before the driver is initialized: | |
20 | ||
21 | example: this is added to at91sam9260_devices.c: | |
22 | ||
23 | #if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI) | |
24 | void at91_mci_hw_init(void) | |
25 | { | |
26 | at91_set_a_periph(AT91_PIO_PORTA, 8, PUP); /* MCCK */ | |
27 | #if defined(CONFIG_ATMEL_MCI_PORTB) | |
28 | at91_set_b_periph(AT91_PIO_PORTA, 1, PUP); /* MCCDB */ | |
29 | at91_set_b_periph(AT91_PIO_PORTA, 0, PUP); /* MCDB0 */ | |
30 | at91_set_b_periph(AT91_PIO_PORTA, 5, PUP); /* MCDB1 */ | |
31 | at91_set_b_periph(AT91_PIO_PORTA, 4, PUP); /* MCDB2 */ | |
32 | at91_set_b_periph(AT91_PIO_PORTA, 3, PUP); /* MCDB3 */ | |
33 | #else | |
34 | at91_set_a_periph(AT91_PIO_PORTA, 7, PUP); /* MCCDA */ | |
35 | at91_set_a_periph(AT91_PIO_PORTA, 6, PUP); /* MCDA0 */ | |
36 | at91_set_a_periph(AT91_PIO_PORTA, 9, PUP); /* MCDA1 */ | |
37 | at91_set_a_periph(AT91_PIO_PORTA, 10, PUP); /* MCDA2 */ | |
38 | at91_set_a_periph(AT91_PIO_PORTA, 11, PUP); /* MCDA3 */ | |
39 | #endif | |
40 | } | |
41 | #endif | |
42 | ||
43 | the board specific file need added: | |
44 | ... | |
45 | #ifdef CONFIG_GENERIC_ATMEL_MCI | |
46 | # include <mmc.h> | |
47 | #endif | |
48 | ... | |
49 | #ifdef CONFIG_GENERIC_ATMEL_MCI | |
50 | /* this is a weak define that we are overriding */ | |
51 | int board_mmc_init(bd_t *bd) | |
52 | { | |
53 | /* Enable clock */ | |
54 | at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI); | |
55 | at91_mci_hw_init(); | |
56 | ||
57 | /* This calls the atmel_mci_init in gen_atmel_mci.c */ | |
58 | return atmel_mci_init((void *)AT91_BASE_MCI); | |
59 | } | |
60 | ||
61 | /* this is a weak define that we are overriding */ | |
62 | int board_mmc_getcd(u8 *cd, struct mmc *mmc) | |
63 | { | |
64 | /* | |
65 | * the only currently existing use of this function | |
66 | * (fsl_esdhc.c) suggests this function must return | |
67 | * *cs = TRUE if a card is NOT detected -> in most | |
68 | * cases the value of the pin when the detect switch | |
69 | * closes to GND | |
70 | */ | |
71 | *cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0; | |
72 | return 0; | |
73 | } | |
74 | ||
75 | #endif | |
76 | ||
77 | and the board definition files needs: | |
78 | ||
79 | /* SD/MMC card */ | |
80 | #define CONFIG_MMC 1 | |
81 | #define CONFIG_GENERIC_MMC 1 | |
82 | #define CONFIG_GENERIC_ATMEL_MCI 1 | |
83 | #define CONFIG_ATMEL_MCI_PORTB 1 /* Atmel XE-EK uses port B */ | |
84 | #define CONFIG_SYS_MMC_CD_PIN AT91_PIN_PC9 | |
85 | #define CONFIG_CMD_MMC 1 |