diff mbox

davinci: Add MMC/SD support for da850/omap-l138

Message ID 1248154247-5120-1-git-send-email-sudhakar.raj@ti.com (mailing list archive)
State Rejected
Headers show

Commit Message

Rajashekhara, Sudhakar July 21, 2009, 5:30 a.m. UTC
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 <sudhakar.raj@ti.com>
---
 This patch has been tested on OMAP-L138 EVM.

 arch/arm/mach-davinci/board-da850-evm.c    |   55 ++++++++++++++++++++++++++++
 arch/arm/mach-davinci/da850.c              |   20 ++++++++++
 arch/arm/mach-davinci/devices-da8xx.c      |   38 +++++++++++++++++++
 arch/arm/mach-davinci/include/mach/da8xx.h |    4 ++
 arch/arm/mach-davinci/include/mach/mux.h   |    8 ++++
 5 files changed, 125 insertions(+), 0 deletions(-)

Comments

Kevin Hilman Aug. 10, 2009, 11:12 p.m. UTC | #1
Sudhakar Rajashekhara <sudhakar.raj@ti.com> writes:

> 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 <sudhakar.raj@ti.com>
> ---
>  This patch has been tested on OMAP-L138 EVM.
>
>  arch/arm/mach-davinci/board-da850-evm.c    |   55 ++++++++++++++++++++++++++++
>  arch/arm/mach-davinci/da850.c              |   20 ++++++++++
>  arch/arm/mach-davinci/devices-da8xx.c      |   38 +++++++++++++++++++
>  arch/arm/mach-davinci/include/mach/da8xx.h |    4 ++
>  arch/arm/mach-davinci/include/mach/mux.h   |    8 ++++
>  5 files changed, 125 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
> index d989346..ae4a2f0 100644
> --- a/arch/arm/mach-davinci/board-da850-evm.c
> +++ b/arch/arm/mach-davinci/board-da850-evm.c
> @@ -17,6 +17,7 @@
>  #include <linux/console.h>
>  #include <linux/i2c.h>
>  #include <linux/i2c/at24.h>
> +#include <linux/gpio.h>
>  
>  #include <asm/mach-types.h>
>  #include <asm/mach/arch.h>
> @@ -38,6 +39,49 @@ static struct davinci_uart_config da850_evm_uart_config __initdata = {
>  	.enabled_uarts = 0x7,
>  };
>  
> +#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
> +static int da850_evm_mmc_get_ro(int index)
> +{
> +	/* GPIO 4[1] is used for MMC/SD WP - 16 * 4 + 1 = 65 */
> +	int val, status, gpio_num = 65;
> +
> +	status = gpio_request(gpio_num, "MMC WP\n");
> +	if (status < 0) {
> +		printk(KERN_WARNING "%s can not open GPIO %d\n", __func__,
> +					gpio_num);
> +		return 0;
> +	}
> +	gpio_direction_input(gpio_num);
> +	val = gpio_get_value(gpio_num);
> +	gpio_free(gpio_num);
> +	return val;
> +}
> +
> +static int da850_evm_mmc_get_cd(int index)
> +{
> +	/* GPIO 4[0] is used for MMC/SD WP - 16 * 4 + 0 = 64 */
> +	int val, status, gpio_num = 64;
> +
> +	status = gpio_request(gpio_num, "MMC CD\n");
> +	if (status < 0) {
> +		printk(KERN_WARNING "%s can not open GPIO %d\n", __func__,
> +					gpio_num);
> +		return 0;
> +	}
> +	gpio_direction_input(gpio_num);
> +	val = gpio_get_value(gpio_num);
> +	gpio_free(gpio_num);
> +	return !val;
> +}
> +
> +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,
> +};
> +#endif
> +

Rather than do the gpio_request()/free() every time, I think you should
just #define the GPIO numbers, do the request() and gpio_direction_input()
in da850_evm_init() after you mux.

Then, the mmc_get_* funcs can simply 'return gpio_get_value(<gpio>);'

Kevin

>  static __init void da850_evm_init(void)
>  {
>  	struct davinci_soc_info *soc_info = &davinci_soc_info;
> @@ -76,6 +120,17 @@ static __init void da850_evm_init(void)
>  	if (ret)
>  		pr_warning("da830_evm_init: watchdog registration failed: %d\n",
>  				ret);
> +#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
> +	ret = da8xx_pinmux_setup(da850_mmcsd0_pins);
> +	if (ret)
> +		pr_warning("da850_evm_init: mmcsd0 mux setup failed: %d\n",
> +				ret);
> +
> +	ret = da8xx_register_mmcsd0(&da850_mmc_config);
> +	if (ret)
> +		pr_warning("da850_evm_init: mmcsd0 registration failed: %d\n",
> +				ret);
> +#endif
>  
>  	davinci_serial_init(&da850_evm_uart_config);
>  
> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
> index 4a43ae2..4b5ac24 100644
> --- a/arch/arm/mach-davinci/da850.c
> +++ b/arch/arm/mach-davinci/da850.c
> @@ -289,6 +289,12 @@ static struct clk emac_clk = {
>  	.lpsc		= DA8XX_LPSC1_CPGMAC,
>  };
>  
> +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),
> @@ -326,6 +332,7 @@ static struct davinci_clk da850_clks[] = {
>  	CLK(NULL,		"arm",		&arm_clk),
>  	CLK(NULL,		"rmii",		&rmii_clk),
>  	CLK("davinci_emac.1",	NULL,		&emac_clk),
> +	CLK("davinci_mmc.0",	NULL,		&mmcsd_clk),
>  	CLK(NULL,		NULL,		NULL),
>  };
>  
> @@ -370,6 +377,13 @@ static const struct mux_config da850_pins[] = {
>  	MUX_CFG(DA850, MII_RXD_2,	3,	20,	15,	8,	false)
>  	MUX_CFG(DA850, MII_RXD_1,	3,	24,	15,	8,	false)
>  	MUX_CFG(DA850, MII_RXD_0,	3,	28,	15,	8,	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)
>  #endif
>  };
>  
> @@ -406,6 +420,12 @@ const short da850_cpgmac_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,
> +	-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 11c0971..f70850b 100644
> --- a/arch/arm/mach-davinci/devices-da8xx.c
> +++ b/arch/arm/mach-davinci/devices-da8xx.c
> @@ -285,3 +285,41 @@ int __init da8xx_register_emac(void)
>  {
>  	return platform_device_register(&da8xx_emac_device);
>  }
> +
> +#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
> +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);
> +}
> +#endif
> diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
> index a8cb570..e597900 100644
> --- a/arch/arm/mach-davinci/include/mach/da8xx.h
> +++ b/arch/arm/mach-davinci/include/mach/da8xx.h
> @@ -15,6 +15,7 @@
>  #include <mach/edma.h>
>  #include <mach/i2c.h>
>  #include <mach/emac.h>
> +#include <mach/mmc.h>
>  
>  /*
>   * The cp_intc interrupt controller for the da8xx isn't in the same
> @@ -36,6 +37,7 @@
>  #define DA8XX_TIMER64P1_BASE	0x01c21000
>  #define DA8XX_GPIO_BASE		0x01e26000
>  #define DA8XX_PSC1_BASE		0x01e27000
> +#define DA8XX_MMCSD0_BASE	0x01c40000
>  
>  #define PINMUX0			0x00
>  #define PINMUX1			0x04
> @@ -65,6 +67,7 @@ int da8xx_register_edma(void);
>  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_mmcsd0(struct davinci_mmc_config *config);
>  
>  extern struct platform_device da8xx_serial_device;
>  extern struct emac_platform_data da8xx_emac_pdata;
> @@ -100,6 +103,7 @@ extern const short da850_uart2_pins[];
>  extern const short da850_i2c0_pins[];
>  extern const short da850_i2c1_pins[];
>  extern const short da850_cpgmac_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 368fca6..09dbede 100644
> --- a/arch/arm/mach-davinci/include/mach/mux.h
> +++ b/arch/arm/mach-davinci/include/mach/mux.h
> @@ -747,6 +747,14 @@ enum davinci_da850_index {
>  	DA850_MII_RXD_2,
>  	DA850_MII_RXD_1,
>  	DA850_MII_RXD_0,
> +
> +	/* 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,
>  };
>  
>  #ifdef CONFIG_DAVINCI_MUX
> -- 
> 1.5.6
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source@linux.davincidsp.com
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
diff mbox

Patch

diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index d989346..ae4a2f0 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -17,6 +17,7 @@ 
 #include <linux/console.h>
 #include <linux/i2c.h>
 #include <linux/i2c/at24.h>
+#include <linux/gpio.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -38,6 +39,49 @@  static struct davinci_uart_config da850_evm_uart_config __initdata = {
 	.enabled_uarts = 0x7,
 };
 
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+static int da850_evm_mmc_get_ro(int index)
+{
+	/* GPIO 4[1] is used for MMC/SD WP - 16 * 4 + 1 = 65 */
+	int val, status, gpio_num = 65;
+
+	status = gpio_request(gpio_num, "MMC WP\n");
+	if (status < 0) {
+		printk(KERN_WARNING "%s can not open GPIO %d\n", __func__,
+					gpio_num);
+		return 0;
+	}
+	gpio_direction_input(gpio_num);
+	val = gpio_get_value(gpio_num);
+	gpio_free(gpio_num);
+	return val;
+}
+
+static int da850_evm_mmc_get_cd(int index)
+{
+	/* GPIO 4[0] is used for MMC/SD WP - 16 * 4 + 0 = 64 */
+	int val, status, gpio_num = 64;
+
+	status = gpio_request(gpio_num, "MMC CD\n");
+	if (status < 0) {
+		printk(KERN_WARNING "%s can not open GPIO %d\n", __func__,
+					gpio_num);
+		return 0;
+	}
+	gpio_direction_input(gpio_num);
+	val = gpio_get_value(gpio_num);
+	gpio_free(gpio_num);
+	return !val;
+}
+
+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,
+};
+#endif
+
 static __init void da850_evm_init(void)
 {
 	struct davinci_soc_info *soc_info = &davinci_soc_info;
@@ -76,6 +120,17 @@  static __init void da850_evm_init(void)
 	if (ret)
 		pr_warning("da830_evm_init: watchdog registration failed: %d\n",
 				ret);
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+	ret = da8xx_pinmux_setup(da850_mmcsd0_pins);
+	if (ret)
+		pr_warning("da850_evm_init: mmcsd0 mux setup failed: %d\n",
+				ret);
+
+	ret = da8xx_register_mmcsd0(&da850_mmc_config);
+	if (ret)
+		pr_warning("da850_evm_init: mmcsd0 registration failed: %d\n",
+				ret);
+#endif
 
 	davinci_serial_init(&da850_evm_uart_config);
 
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 4a43ae2..4b5ac24 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -289,6 +289,12 @@  static struct clk emac_clk = {
 	.lpsc		= DA8XX_LPSC1_CPGMAC,
 };
 
+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),
@@ -326,6 +332,7 @@  static struct davinci_clk da850_clks[] = {
 	CLK(NULL,		"arm",		&arm_clk),
 	CLK(NULL,		"rmii",		&rmii_clk),
 	CLK("davinci_emac.1",	NULL,		&emac_clk),
+	CLK("davinci_mmc.0",	NULL,		&mmcsd_clk),
 	CLK(NULL,		NULL,		NULL),
 };
 
@@ -370,6 +377,13 @@  static const struct mux_config da850_pins[] = {
 	MUX_CFG(DA850, MII_RXD_2,	3,	20,	15,	8,	false)
 	MUX_CFG(DA850, MII_RXD_1,	3,	24,	15,	8,	false)
 	MUX_CFG(DA850, MII_RXD_0,	3,	28,	15,	8,	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)
 #endif
 };
 
@@ -406,6 +420,12 @@  const short da850_cpgmac_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,
+	-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 11c0971..f70850b 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -285,3 +285,41 @@  int __init da8xx_register_emac(void)
 {
 	return platform_device_register(&da8xx_emac_device);
 }
+
+#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
+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);
+}
+#endif
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index a8cb570..e597900 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -15,6 +15,7 @@ 
 #include <mach/edma.h>
 #include <mach/i2c.h>
 #include <mach/emac.h>
+#include <mach/mmc.h>
 
 /*
  * The cp_intc interrupt controller for the da8xx isn't in the same
@@ -36,6 +37,7 @@ 
 #define DA8XX_TIMER64P1_BASE	0x01c21000
 #define DA8XX_GPIO_BASE		0x01e26000
 #define DA8XX_PSC1_BASE		0x01e27000
+#define DA8XX_MMCSD0_BASE	0x01c40000
 
 #define PINMUX0			0x00
 #define PINMUX1			0x04
@@ -65,6 +67,7 @@  int da8xx_register_edma(void);
 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_mmcsd0(struct davinci_mmc_config *config);
 
 extern struct platform_device da8xx_serial_device;
 extern struct emac_platform_data da8xx_emac_pdata;
@@ -100,6 +103,7 @@  extern const short da850_uart2_pins[];
 extern const short da850_i2c0_pins[];
 extern const short da850_i2c1_pins[];
 extern const short da850_cpgmac_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 368fca6..09dbede 100644
--- a/arch/arm/mach-davinci/include/mach/mux.h
+++ b/arch/arm/mach-davinci/include/mach/mux.h
@@ -747,6 +747,14 @@  enum davinci_da850_index {
 	DA850_MII_RXD_2,
 	DA850_MII_RXD_1,
 	DA850_MII_RXD_0,
+
+	/* 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,
 };
 
 #ifdef CONFIG_DAVINCI_MUX