diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2010-10-22 12:27:48 -0400 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2010-10-26 05:32:49 -0400 |
commit | 75305d768d296a07fd02df9af3e5de326df1c72e (patch) | |
tree | e816a4d3bcfa1f06488bdbaad1d9a5deb3fdca09 /arch/arm/mach-at91/at91sam9g45_devices.c | |
parent | a2a571b74a3881963d8d09deb272d13afe5b49e3 (diff) |
at91/atmel-mci: inclusion of sd/mmc driver in at91sam9g45 chip and board
This adds the support of atmel-mci sd/mmc driver in at91sam9g45 devices and
board files. This also configures the DMA controller slave interface for
at_hdmac dmaengine driver.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'arch/arm/mach-at91/at91sam9g45_devices.c')
-rw-r--r-- | arch/arm/mach-at91/at91sam9g45_devices.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 1276babf84d5..1e8f275c17f6 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/i2c-gpio.h> | 17 | #include <linux/i2c-gpio.h> |
18 | #include <linux/atmel-mci.h> | ||
18 | 19 | ||
19 | #include <linux/fb.h> | 20 | #include <linux/fb.h> |
20 | #include <video/atmel_lcdc.h> | 21 | #include <video/atmel_lcdc.h> |
@@ -25,6 +26,7 @@ | |||
25 | #include <mach/at91sam9g45_matrix.h> | 26 | #include <mach/at91sam9g45_matrix.h> |
26 | #include <mach/at91sam9_smc.h> | 27 | #include <mach/at91sam9_smc.h> |
27 | #include <mach/at_hdmac.h> | 28 | #include <mach/at_hdmac.h> |
29 | #include <mach/atmel-mci.h> | ||
28 | 30 | ||
29 | #include "generic.h" | 31 | #include "generic.h" |
30 | 32 | ||
@@ -350,6 +352,169 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} | |||
350 | 352 | ||
351 | 353 | ||
352 | /* -------------------------------------------------------------------- | 354 | /* -------------------------------------------------------------------- |
355 | * MMC / SD | ||
356 | * -------------------------------------------------------------------- */ | ||
357 | |||
358 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
359 | static u64 mmc_dmamask = DMA_BIT_MASK(32); | ||
360 | static struct mci_platform_data mmc0_data, mmc1_data; | ||
361 | |||
362 | static struct resource mmc0_resources[] = { | ||
363 | [0] = { | ||
364 | .start = AT91SAM9G45_BASE_MCI0, | ||
365 | .end = AT91SAM9G45_BASE_MCI0 + SZ_16K - 1, | ||
366 | .flags = IORESOURCE_MEM, | ||
367 | }, | ||
368 | [1] = { | ||
369 | .start = AT91SAM9G45_ID_MCI0, | ||
370 | .end = AT91SAM9G45_ID_MCI0, | ||
371 | .flags = IORESOURCE_IRQ, | ||
372 | }, | ||
373 | }; | ||
374 | |||
375 | static struct platform_device at91sam9g45_mmc0_device = { | ||
376 | .name = "atmel_mci", | ||
377 | .id = 0, | ||
378 | .dev = { | ||
379 | .dma_mask = &mmc_dmamask, | ||
380 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
381 | .platform_data = &mmc0_data, | ||
382 | }, | ||
383 | .resource = mmc0_resources, | ||
384 | .num_resources = ARRAY_SIZE(mmc0_resources), | ||
385 | }; | ||
386 | |||
387 | static struct resource mmc1_resources[] = { | ||
388 | [0] = { | ||
389 | .start = AT91SAM9G45_BASE_MCI1, | ||
390 | .end = AT91SAM9G45_BASE_MCI1 + SZ_16K - 1, | ||
391 | .flags = IORESOURCE_MEM, | ||
392 | }, | ||
393 | [1] = { | ||
394 | .start = AT91SAM9G45_ID_MCI1, | ||
395 | .end = AT91SAM9G45_ID_MCI1, | ||
396 | .flags = IORESOURCE_IRQ, | ||
397 | }, | ||
398 | }; | ||
399 | |||
400 | static struct platform_device at91sam9g45_mmc1_device = { | ||
401 | .name = "atmel_mci", | ||
402 | .id = 1, | ||
403 | .dev = { | ||
404 | .dma_mask = &mmc_dmamask, | ||
405 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
406 | .platform_data = &mmc1_data, | ||
407 | }, | ||
408 | .resource = mmc1_resources, | ||
409 | .num_resources = ARRAY_SIZE(mmc1_resources), | ||
410 | }; | ||
411 | |||
412 | /* Consider only one slot : slot 0 */ | ||
413 | void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) | ||
414 | { | ||
415 | |||
416 | if (!data) | ||
417 | return; | ||
418 | |||
419 | /* Must have at least one usable slot */ | ||
420 | if (!data->slot[0].bus_width) | ||
421 | return; | ||
422 | |||
423 | #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) | ||
424 | { | ||
425 | struct at_dma_slave *atslave; | ||
426 | struct mci_dma_data *alt_atslave; | ||
427 | |||
428 | alt_atslave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL); | ||
429 | atslave = &alt_atslave->sdata; | ||
430 | |||
431 | /* DMA slave channel configuration */ | ||
432 | atslave->dma_dev = &at_hdmac_device.dev; | ||
433 | atslave->reg_width = AT_DMA_SLAVE_WIDTH_32BIT; | ||
434 | atslave->cfg = ATC_FIFOCFG_HALFFIFO | ||
435 | | ATC_SRC_H2SEL_HW | ATC_DST_H2SEL_HW; | ||
436 | atslave->ctrla = ATC_SCSIZE_16 | ATC_DCSIZE_16; | ||
437 | if (mmc_id == 0) /* MCI0 */ | ||
438 | atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI0) | ||
439 | | ATC_DST_PER(AT_DMA_ID_MCI0); | ||
440 | |||
441 | else /* MCI1 */ | ||
442 | atslave->cfg |= ATC_SRC_PER(AT_DMA_ID_MCI1) | ||
443 | | ATC_DST_PER(AT_DMA_ID_MCI1); | ||
444 | |||
445 | data->dma_slave = alt_atslave; | ||
446 | } | ||
447 | #endif | ||
448 | |||
449 | |||
450 | /* input/irq */ | ||
451 | if (data->slot[0].detect_pin) { | ||
452 | at91_set_gpio_input(data->slot[0].detect_pin, 1); | ||
453 | at91_set_deglitch(data->slot[0].detect_pin, 1); | ||
454 | } | ||
455 | if (data->slot[0].wp_pin) | ||
456 | at91_set_gpio_input(data->slot[0].wp_pin, 1); | ||
457 | |||
458 | if (mmc_id == 0) { /* MCI0 */ | ||
459 | |||
460 | /* CLK */ | ||
461 | at91_set_A_periph(AT91_PIN_PA0, 0); | ||
462 | |||
463 | /* CMD */ | ||
464 | at91_set_A_periph(AT91_PIN_PA1, 1); | ||
465 | |||
466 | /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ | ||
467 | at91_set_A_periph(AT91_PIN_PA2, 1); | ||
468 | if (data->slot[0].bus_width == 4) { | ||
469 | at91_set_A_periph(AT91_PIN_PA3, 1); | ||
470 | at91_set_A_periph(AT91_PIN_PA4, 1); | ||
471 | at91_set_A_periph(AT91_PIN_PA5, 1); | ||
472 | if (data->slot[0].bus_width == 8) { | ||
473 | at91_set_A_periph(AT91_PIN_PA6, 1); | ||
474 | at91_set_A_periph(AT91_PIN_PA7, 1); | ||
475 | at91_set_A_periph(AT91_PIN_PA8, 1); | ||
476 | at91_set_A_periph(AT91_PIN_PA9, 1); | ||
477 | } | ||
478 | } | ||
479 | |||
480 | mmc0_data = *data; | ||
481 | at91_clock_associate("mci0_clk", &at91sam9g45_mmc0_device.dev, "mci_clk"); | ||
482 | platform_device_register(&at91sam9g45_mmc0_device); | ||
483 | |||
484 | } else { /* MCI1 */ | ||
485 | |||
486 | /* CLK */ | ||
487 | at91_set_A_periph(AT91_PIN_PA31, 0); | ||
488 | |||
489 | /* CMD */ | ||
490 | at91_set_A_periph(AT91_PIN_PA22, 1); | ||
491 | |||
492 | /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ | ||
493 | at91_set_A_periph(AT91_PIN_PA23, 1); | ||
494 | if (data->slot[0].bus_width == 4) { | ||
495 | at91_set_A_periph(AT91_PIN_PA24, 1); | ||
496 | at91_set_A_periph(AT91_PIN_PA25, 1); | ||
497 | at91_set_A_periph(AT91_PIN_PA26, 1); | ||
498 | if (data->slot[0].bus_width == 8) { | ||
499 | at91_set_A_periph(AT91_PIN_PA27, 1); | ||
500 | at91_set_A_periph(AT91_PIN_PA28, 1); | ||
501 | at91_set_A_periph(AT91_PIN_PA29, 1); | ||
502 | at91_set_A_periph(AT91_PIN_PA30, 1); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | mmc1_data = *data; | ||
507 | at91_clock_associate("mci1_clk", &at91sam9g45_mmc1_device.dev, "mci_clk"); | ||
508 | platform_device_register(&at91sam9g45_mmc1_device); | ||
509 | |||
510 | } | ||
511 | } | ||
512 | #else | ||
513 | void __init at91_add_device_mci(short mmc_id, struct mci_platform_data *data) {} | ||
514 | #endif | ||
515 | |||
516 | |||
517 | /* -------------------------------------------------------------------- | ||
353 | * NAND / SmartMedia | 518 | * NAND / SmartMedia |
354 | * -------------------------------------------------------------------- */ | 519 | * -------------------------------------------------------------------- */ |
355 | 520 | ||