[Resending: PATCH 2/4] MMC/SD board specific update for OMAP2430/3430

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds OMAP2430/3430 MMC board specific file.

Signed-off-by: Madhusudhan Chikkature<madhu.cr@xxxxxx>

---
 arch/arm/mach-omap2/Makefile          |    6 
 arch/arm/mach-omap2/board-2430sdp.c   |   11 +
 arch/arm/mach-omap2/board-3430sdp.c   |   11 +
 arch/arm/mach-omap2/board-sdp-hsmmc.c |  277 ++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-omap/mmc.h       |    4 
 5 files changed, 307 insertions(+), 2 deletions(-)

Index: linux-omap-2.6/arch/arm/mach-omap2/Makefile
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/Makefile	2007-12-10 11:08:36.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/Makefile	2007-12-18 14:07:13.846584221 +0530
@@ -24,9 +24,11 @@
 obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o
 obj-$(CONFIG_MACH_OMAP_2430SDP)		+= board-2430sdp.o \
 					   board-2430sdp-flash.o \
-					   board-2430sdp-usb.o
+					board-2430sdp-usb.o \
+					board-sdp-hsmmc.o
 obj-$(CONFIG_MACH_OMAP_2430OSK)		+= board-2430osk.o
-obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o
+obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o \
+					board-sdp-hsmmc.o
 obj-$(CONFIG_MACH_OMAP_APOLLON)		+= board-apollon.o \
 					   board-apollon-mmc.o	\
 					   board-apollon-keys.o
Index: linux-omap-2.6/arch/arm/mach-omap2/board-2430sdp.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/board-2430sdp.c	2007-12-10 11:08:36.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/board-2430sdp.c	2007-12-18 13:58:22.427542663 +0530
@@ -54,6 +54,8 @@
 #define TWL4030_MSECURE_GPIO	118
 #define SECONDARY_LCD_GPIO	147
 
+extern void __init sdp_mmc_init(void);
+
 static struct mtd_partition sdp2430_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
@@ -355,10 +357,18 @@
 	.console_speed = 115200,
 };
 
+static struct omap_mmc_config sdp2430_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled	= 1,
+		.wire4		= 1,
+	},
+};
+
 static struct omap_board_config_kernel sdp2430_config[] __initdata = {
 	{OMAP_TAG_UART, &sdp2430_uart_config},
 	{OMAP_TAG_LCD, &sdp2430_lcd_config},
 	{OMAP_TAG_SERIAL_CONSOLE, &sdp2430_serial_console_config},
+	{OMAP_TAG_MMC, &sdp2430_mmc_config },
 };
 
 static int __init omap2430_i2c_init(void)
@@ -384,6 +394,7 @@
 	spi_register_board_info(sdp2430_spi_board_info,
 				ARRAY_SIZE(sdp2430_spi_board_info));
 	ads7846_dev_init();
+	sdp_mmc_init();
 
 	/* turn off secondary LCD backlight */
 	omap_set_gpio_direction(SECONDARY_LCD_GPIO, 0);
Index: linux-omap-2.6/arch/arm/mach-omap2/board-3430sdp.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/board-3430sdp.c	2007-12-10 11:08:36.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/board-3430sdp.c	2007-12-18 13:58:22.427542663 +0530
@@ -50,6 +50,8 @@
 #define ENABLE_VAUX3_DEDICATED	0x03
 #define ENABLE_VAUX3_DEV_GRP	0x20
 
+extern void __init sdp_mmc_init(void);
+
 static struct mtd_partition sdp3430_partitions[] = {
 	/* bootloader (U-Boot, etc) in first sector */
 	{
@@ -296,8 +298,16 @@
 	.enabled_uarts	= ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
+static struct omap_mmc_config sdp3430_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled	= 1,
+		.wire4		= 1,
+	},
+};
+
 static struct omap_board_config_kernel sdp3430_config[] = {
 	{ OMAP_TAG_UART,	&sdp3430_uart_config },
+	{ OMAP_TAG_MMC,		&sdp3430_mmc_config },
 };
 static int __init omap3430_i2c_init(void)
 {
@@ -316,6 +326,7 @@
 				ARRAY_SIZE(sdp3430_spi_board_info));
 	ads7846_dev_init();
 	omap_serial_init();
+	sdp_mmc_init();
 }
 
 static void __init omap_3430sdp_map_io(void)
Index: linux-omap-2.6/arch/arm/mach-omap2/board-sdp-hsmmc.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6/arch/arm/mach-omap2/board-sdp-hsmmc.c	2007-12-18 14:13:31.848526448 +0530
@@ -0,0 +1,277 @@
+/*
+ * linux/arch/arm/mach-omap2/board-sdp-hsmmc.c
+ *
+ * Copyright (C) 2007 Texas Instruments
+ * Author: Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/hardware.h>
+#include <asm/arch/twl4030.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/board.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MMC_OMAP
+
+#define VMMC1_DEV_GRP		0x27
+#define P1_DEV_GRP		0x20
+#define VMMC1_DEDICATED		0x2A
+#define VSEL_3V			0x02
+#define VSEL_18V		0x00
+#define TWL_GPIO_PUPDCTR1	0x13
+#define TWL_GPIO_IMR1A		0x1C
+#define TWL_GPIO_ISR1A		0x19
+#define LDO_CLR			0x00
+#define VSEL_S2_CLR		0x40
+#define GPIO_0_BIT_POS		1 << 0
+#define MMC1_CD_IRQ		0
+#define MMC2_CD_IRQ		1
+
+static irqreturn_t mmc_omap_cd_handler(int irq, void *dev_id)
+{
+	int detect;
+
+	detect = twl4030_get_gpio_datain(MMC1_CD_IRQ);
+	omap_mmc_notify_card_detect(dev_id, 0, detect);
+	return IRQ_HANDLED;
+}
+
+/*
+ * MMC Slot Initialization.
+ */
+static int sdp_mmc_late_init(struct device *dev)
+{
+	int ret = 0;
+
+	/*
+	 * Configure TWL4030 GPIO parameters for MMC hotplug irq
+	 */
+	ret = twl4030_request_gpio(MMC1_CD_IRQ);
+	if (ret != 0)
+		goto err;
+
+	ret = twl4030_set_gpio_edge_ctrl(MMC1_CD_IRQ,
+			TWL4030_GPIO_EDGE_RISING | TWL4030_GPIO_EDGE_FALLING);
+	if (ret != 0)
+		goto err;
+
+	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x02,
+						TWL_GPIO_PUPDCTR1);
+	if (ret != 0)
+		goto err;
+
+	ret = twl4030_set_gpio_debounce(MMC1_CD_IRQ, TWL4030_GPIO_IS_ENABLE);
+	if (ret != 0)
+		goto err;
+
+	ret = request_irq(TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ),
+		mmc_omap_cd_handler, IRQF_DISABLED, "MMC1_CD_IRQ", dev);
+	if (ret < 0)
+		goto err;
+
+	return ret;
+err:
+	dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
+
+	return ret;
+}
+
+static void sdp_mmc_cleanup(struct device *dev)
+{
+	int ret = 0;
+
+	ret = twl4030_free_gpio(MMC1_CD_IRQ);
+	free_irq(TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ), dev);
+	if (ret != 0)
+		dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
+}
+
+#ifdef CONFIG_PM
+
+/*
+ * To mask and unmask MMC Card Detect Interrupt
+ * mask : 1
+ * unmask : 0
+ */
+static int mask_cd_interrupt(int mask)
+{
+	u8 reg = 0, ret = 0;
+
+	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg, TWL_GPIO_IMR1A);
+	if (ret != 0)
+		goto err;
+
+	reg = (mask == 1) ? (reg | GPIO_0_BIT_POS) : (reg & ~GPIO_0_BIT_POS);
+
+	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, reg, TWL_GPIO_IMR1A);
+	if (ret != 0)
+		goto err;
+
+	ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &reg, TWL_GPIO_ISR1A);
+	if (ret != 0)
+		goto err;
+
+	reg = (mask == 1) ? (reg | GPIO_0_BIT_POS) : (reg & ~GPIO_0_BIT_POS);
+
+	ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, reg, TWL_GPIO_ISR1A);
+	if (ret != 0)
+		goto err;
+err:
+	return ret;
+}
+
+static int sdp_mmc_suspend(struct device *dev, int slot)
+{
+	int ret = 0;
+
+	disable_irq(TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ));
+	ret = mask_cd_interrupt(1);
+
+	return ret;
+}
+
+static int sdp_mmc_resume(struct device *dev, int slot)
+{
+	int ret = 0;
+
+	enable_irq(TWL4030_GPIO_IRQ_NO(MMC1_CD_IRQ));
+	ret = mask_cd_interrupt(0);
+
+	return ret;
+}
+
+#endif
+
+static int sdp_mmc_set_power(struct device *dev, int slot, int power_on,
+				int vdd)
+{
+	u32 vdd_sel = 0, devconf = 0, reg = 0;
+	int ret = 0;
+
+	/* REVISIT: Using address directly till the control.h defines
+	 * are settled.
+	 */
+#if defined(CONFIG_ARCH_OMAP2430)
+	#define OMAP2_CONTROL_PBIAS 0x490024A0
+#else
+	#define OMAP2_CONTROL_PBIAS 0x48002520
+#endif
+
+	if (power_on == 1) {
+		if (cpu_is_omap24xx())
+			devconf = omap_readl(0x490022E8);
+		else
+			devconf = omap_readl(0x48002274);
+
+		switch (1 << vdd) {
+		case MMC_VDD_33_34:
+		case MMC_VDD_32_33:
+			vdd_sel = VSEL_3V;
+			if (cpu_is_omap24xx())
+				devconf = (reg | (1 << 31));
+			break;
+		case MMC_VDD_165_195:
+			vdd_sel = VSEL_18V;
+			if (cpu_is_omap24xx())
+				devconf = (devconf & ~(1 << 31));
+		}
+
+		if (cpu_is_omap24xx())
+			omap_writel(devconf, 0x490022E8);
+		else
+			omap_writel(devconf | 1 << 24, 0x48002274);
+
+		omap_writel(omap_readl(OMAP2_CONTROL_PBIAS) | 1 << 2,
+			OMAP2_CONTROL_PBIAS);
+		omap_writel(omap_readl(OMAP2_CONTROL_PBIAS) & ~(1 << 1),
+			OMAP2_CONTROL_PBIAS);
+
+		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+						P1_DEV_GRP, VMMC1_DEV_GRP);
+		if (ret != 0)
+			goto err;
+
+		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+						vdd_sel, VMMC1_DEDICATED);
+		if (ret != 0)
+			goto err;
+
+		msleep(100);
+		reg = omap_readl(OMAP2_CONTROL_PBIAS);
+		reg = (vdd_sel == VSEL_18V) ? ((reg | 0x6) & ~0x1)
+						: (reg | 0x7);
+		omap_writel(reg, OMAP2_CONTROL_PBIAS);
+
+		return ret;
+
+	} else if (power_on == 0) {
+		/* Power OFF */
+
+		/* For MMC1, Toggle PBIAS before every power up sequence */
+		omap_writel(omap_readl(OMAP2_CONTROL_PBIAS) & ~(1 << 1),
+					OMAP2_CONTROL_PBIAS);
+		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+						LDO_CLR, VMMC1_DEV_GRP);
+		if (ret != 0)
+			goto err;
+
+		ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+						VSEL_S2_CLR, VMMC1_DEDICATED);
+		if (ret != 0)
+			goto err;
+
+		/* 100ms delay required for PBIAS configuration */
+		msleep(100);
+		omap_writel(omap_readl(OMAP2_CONTROL_PBIAS) | 0x7,
+			OMAP2_CONTROL_PBIAS);
+	} else {
+		ret = -1;
+		goto err;
+	}
+
+	return 0;
+err:
+	return 1;
+}
+
+static struct omap_mmc_platform_data sdp_mmc_data = {
+	.nr_slots			= 1,
+	.switch_slot			= NULL,
+	.init				= sdp_mmc_late_init,
+	.cleanup			= sdp_mmc_cleanup,
+#ifdef CONFIG_PM
+	.suspend			= sdp_mmc_suspend,
+	.resume				= sdp_mmc_resume,
+#endif
+	.slots[0] = {
+		.set_power		= sdp_mmc_set_power,
+		.set_bus_mode		= NULL,
+		.get_ro			= NULL,
+		.get_cover_state	= NULL,
+		.ocr_mask		= MMC_VDD_32_33 | MMC_VDD_33_34 |
+						MMC_VDD_165_195,
+		.name			= "first slot",
+	},
+};
+
+void __init sdp_mmc_init(void)
+{
+	omap_set_mmc_info(1, &sdp_mmc_data);
+}
+
+#else
+
+void __init sdp_mmc_init(void)
+{
+
+}
+
+#endif
Index: linux-omap-2.6/include/asm-arm/arch-omap/mmc.h
===================================================================
--- linux-omap-2.6.orig/include/asm-arm/arch-omap/mmc.h	2007-12-10 11:08:36.000000000 +0530
+++ linux-omap-2.6/include/asm-arm/arch-omap/mmc.h	2007-12-18 13:58:22.428542631 +0530
@@ -36,6 +36,10 @@
 	int (* init)(struct device *dev);
 	void (* cleanup)(struct device *dev);
 
+	/* To handle board related suspend/resume functionality for MMC */
+	int (*suspend)(struct device *dev, int slot);
+	int (*resume)(struct device *dev, int slot);
+
 	struct omap_mmc_slot_data {
 		int (* set_bus_mode)(struct device *dev, int slot, int bus_mode);
 		int (* set_power)(struct device *dev, int slot, int power_on, int vdd);

-
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux