From 700691f27ed9b0891cece9032e4de8c0b482c625 Mon Sep 17 00:00:00 2001 From: Sudhakar Rajashekhara Date: Thu, 13 Aug 2009 15:16:23 -0400 Subject: [PATCH] davinci: Add MMC/SD support for da850/omap-l138 There are two instances of MMC/SD on da850/omap-l138. Connector for the first instance is available on the EVM. This patch adds support for this instance. This patch also adds support for card detect and write protect switches on da850/omap-l138 EVM. Signed-off-by: Sudhakar Rajashekhara Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da850-evm.c | 42 ++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 23 ++++++++++++ arch/arm/mach-davinci/devices-da8xx.c | 36 +++++++++++++++++++ arch/arm/mach-davinci/include/mach/da8xx.h | 4 +++ arch/arm/mach-davinci/include/mach/mux.h | 10 ++++++ 5 files changed, 115 insertions(+) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index b1df784ed702..eb998ce6d465 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -33,6 +33,9 @@ #define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15) #define DA850_LCD_PWR_PIN GPIO_TO_PIN(8, 10) +#define DA850_MMCSD_CD_PIN GPIO_TO_PIN(4, 0) +#define DA850_MMCSD_WP_PIN GPIO_TO_PIN(4, 1) + static struct davinci_i2c_platform_data da850_evm_i2c_0_pdata = { .bus_freq = 100, /* kHz */ .bus_delay = 0, /* usec */ @@ -63,6 +66,23 @@ static struct snd_platform_data da850_evm_snd_data = { .rxnumevt = 1, }; +static int da850_evm_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_MMCSD_WP_PIN); +} + +static int da850_evm_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_evm_mmc_get_ro, + .get_cd = da850_evm_mmc_get_cd, + .wires = 4, + .version = MMC_CTLR_VERSION_2, +}; + static int da850_lcd_hw_init(void) { int status; @@ -134,6 +154,28 @@ static __init void da850_evm_init(void) pr_warning("da830_evm_init: watchdog registration failed: %d\n", ret); + ret = da8xx_pinmux_setup(da850_mmcsd0_pins); + if (ret) + pr_warning("da850_evm_init: mmcsd0 mux setup failed: %d\n", + ret); + + ret = gpio_request(DA850_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("da850_evm_init: can not open GPIO %d\n", + DA850_MMCSD_CD_PIN); + gpio_direction_input(DA850_MMCSD_CD_PIN); + + ret = gpio_request(DA850_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("da850_evm_init: can not open GPIO %d\n", + DA850_MMCSD_WP_PIN); + gpio_direction_input(DA850_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("da850_evm_init: mmcsd0 registration failed: %d\n", + ret); + davinci_serial_init(&da850_evm_uart_config); /* diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index e6e605bf1516..9debd57deb71 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -304,6 +304,12 @@ static struct clk lcdc_clk = { .psc_ctlr = 1, }; +static struct clk mmcsd_clk = { + .name = "mmcsd", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC0_MMC_SD, +}; + static struct davinci_clk da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -343,6 +349,7 @@ static struct davinci_clk da850_clks[] = { CLK("davinci_emac.1", NULL, &emac_clk), CLK("davinci-mcasp.0", NULL, &mcasp_clk), CLK("da8xx_lcdc.0", NULL, &lcdc_clk), + CLK("davinci_mmc.0", NULL, &mmcsd_clk), CLK(NULL, NULL, NULL), }; @@ -434,9 +441,18 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, LCD_HSYNC, 19, 0, 15, 2, false) MUX_CFG(DA850, LCD_VSYNC, 19, 4, 15, 2, false) MUX_CFG(DA850, NLCD_AC_ENB_CS, 19, 24, 15, 2, false) + /* MMC/SD0 function */ + MUX_CFG(DA850, MMCSD0_DAT_0, 10, 8, 15, 2, false) + MUX_CFG(DA850, MMCSD0_DAT_1, 10, 12, 15, 2, false) + MUX_CFG(DA850, MMCSD0_DAT_2, 10, 16, 15, 2, false) + MUX_CFG(DA850, MMCSD0_DAT_3, 10, 20, 15, 2, false) + MUX_CFG(DA850, MMCSD0_CLK, 10, 0, 15, 2, false) + MUX_CFG(DA850, MMCSD0_CMD, 10, 4, 15, 2, false) /* GPIO function */ MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) MUX_CFG(DA850, GPIO8_10, 18, 28, 15, 8, false) + MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) + MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) #endif }; @@ -491,6 +507,13 @@ const short da850_lcdcntl_pins[] __initdata = { -1 }; +const short da850_mmcsd0_pins[] __initdata = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO4_0, DA850_GPIO4_1, + -1 +}; + /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */ static u8 da850_default_priorities[DA850_N_CP_INTC_IRQ] = { [IRQ_DA8XX_COMMTX] = 7, diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 094eb8ed8e76..58ad5b66fd60 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -412,3 +412,39 @@ int __init da8xx_register_lcdc(void) { return platform_device_register(&da850_lcdc_device); } + +static struct resource da8xx_mmcsd0_resources[] = { + { /* registers */ + .start = DA8XX_MMCSD0_BASE, + .end = DA8XX_MMCSD0_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DA8XX_MMCSDINT0, + .end = IRQ_DA8XX_MMCSDINT0, + .flags = IORESOURCE_IRQ, + }, + { /* DMA RX */ + .start = EDMA_CTLR_CHAN(0, 16), + .end = EDMA_CTLR_CHAN(0, 16), + .flags = IORESOURCE_DMA, + }, + { /* DMA TX */ + .start = EDMA_CTLR_CHAN(0, 17), + .end = EDMA_CTLR_CHAN(0, 17), + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device da8xx_mmcsd0_device = { + .name = "davinci_mmc", + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_mmcsd0_resources), + .resource = da8xx_mmcsd0_resources, +}; + +int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config) +{ + da8xx_mmcsd0_device.dev.platform_data = config; + return platform_device_register(&da8xx_mmcsd0_device); +} diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 0af3fb6077a3..0af141ffc3b4 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -16,6 +16,7 @@ #include #include #include +#include /* * The cp_intc interrupt controller for the da8xx isn't in the same @@ -38,6 +39,7 @@ #define DA8XX_GPIO_BASE 0x01e26000 #define DA8XX_PSC1_BASE 0x01e27000 #define DA8XX_LCD_CNTRL_BASE 0x01e13000 +#define DA8XX_MMCSD0_BASE 0x01c40000 #define PINMUX0 0x00 #define PINMUX1 0x04 @@ -68,6 +70,7 @@ int da8xx_register_i2c(int instance, struct davinci_i2c_platform_data *pdata); int da8xx_register_watchdog(void); int da8xx_register_emac(void); int da8xx_register_lcdc(void); +int da8xx_register_mmcsd0(struct davinci_mmc_config *config); void __init da8xx_init_mcasp(int id, struct snd_platform_data *pdata); extern struct platform_device da8xx_serial_device; @@ -106,6 +109,7 @@ extern const short da850_i2c1_pins[]; extern const short da850_cpgmac_pins[]; extern const short da850_mcasp_pins[]; extern const short da850_lcdcntl_pins[]; +extern const short da850_mmcsd0_pins[]; int da8xx_pinmux_setup(const short pins[]); diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index 30bf329d5373..b2335640c222 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -798,9 +798,19 @@ enum davinci_da850_index { DA850_LCD_VSYNC, DA850_NLCD_AC_ENB_CS, + /* MMC/SD0 function */ + DA850_MMCSD0_DAT_0, + DA850_MMCSD0_DAT_1, + DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, + DA850_MMCSD0_CLK, + DA850_MMCSD0_CMD, + /* GPIO function */ DA850_GPIO2_15, DA850_GPIO8_10, + DA850_GPIO4_0, + DA850_GPIO4_1, }; #ifdef CONFIG_DAVINCI_MUX