From: Madhusudhan Chikkature<[EMAIL PROTECTED]>

ARM: OMAP3: OMAP3430 SDP HSMMC2 support.

This patch adds the necessary routines to 3430 sdp hsmmc file to support slot2.

Signed-off-by: Madhusudhan Chikkature<[EMAIL PROTECTED]>
---
 arch/arm/mach-omap2/board-3430sdp.c |    4
 arch/arm/mach-omap2/hsmmc.c         |  185 ++++++++++++++++++++++++++++++++++++
 2 files changed, 189 insertions(+)

Index: linux-omap-2.6/arch/arm/mach-omap2/board-3430sdp.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/board-3430sdp.c     2008-08-11
14:57:04.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/board-3430sdp.c  2008-08-11
15:00:23.000000000 +0530
@@ -333,6 +333,10 @@ static struct omap_mmc_config sdp3430_mm
                .enabled        = 1,
                .wire4          = 1,
        },
+       .mmc [1] = {
+               .enabled        = 1,
+               .wire4          = 1,
+       },
 };

 static struct omap_board_config_kernel sdp3430_config[] __initdata = {
Index: linux-omap-2.6/arch/arm/mach-omap2/hsmmc.c
===================================================================
--- linux-omap-2.6.orig/arch/arm/mach-omap2/hsmmc.c     2008-08-11
14:57:04.000000000 +0530
+++ linux-omap-2.6/arch/arm/mach-omap2/hsmmc.c  2008-08-13 09:35:21.000000000 
+0530
@@ -33,8 +33,11 @@
 #define LDO_CLR                        0x00
 #define VSEL_S2_CLR            0x40
 #define GPIO_0_BIT_POS         (1 << 0)
+#define GPIO_1_BIT_POS         (1 << 1)
 #define MMC1_CD_IRQ            0
 #define MMC2_CD_IRQ            1
+#define VMMC2_DEV_GRP          0x2B
+#define VMMC2_DEDICATED                0x2E

 #define OMAP2_CONTROL_DEVCONF0 0x48002274
 #define OMAP2_CONTROL_DEVCONF1 0x490022E8
@@ -86,6 +89,41 @@ err:
        return ret;
 }

+/*
+ * MMC2 Slot Initialization.
+ */
+static int hsmmc2_late_init(struct device *dev)
+{
+       int ret = 0;
+
+       /*
+        * Configure TWL4030 GPIO parameters for MMC2 hotplug irq
+        */
+       ret = twl4030_request_gpio(MMC2_CD_IRQ);
+       if (ret != 0)
+               goto err;
+
+       ret = twl4030_set_gpio_edge_ctrl(MMC2_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(MMC2_CD_IRQ, TWL4030_GPIO_IS_ENABLE);
+       if (ret != 0)
+               goto err;
+
+       return ret;
+err:
+       dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
+
+       return ret;
+}
+
 static void hsmmc_cleanup(struct device *dev)
 {
        int ret = 0;
@@ -95,6 +133,15 @@ static void hsmmc_cleanup(struct device
                dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
 }

+static void hsmmc2_cleanup(struct device *dev)
+{
+       int ret = 0;
+
+       ret = twl4030_free_gpio(MMC2_CD_IRQ);
+       if (ret != 0)
+               dev_err(dev, "Failed to configure TWL4030 GPIO IRQ\n");
+}
+
 #ifdef CONFIG_PM

 /*
@@ -140,6 +187,48 @@ static int hsmmc_suspend(struct device *
        return ret;
 }

+/*
+ * To mask and unmask MMC Card Detect Interrupt
+ * mask : 1
+ * unmask : 0
+ */
+static int mask_cd2_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_1_BIT_POS) : (reg & ~GPIO_1_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_1_BIT_POS) : (reg & ~GPIO_1_BIT_POS);
+
+       ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, reg, TWL_GPIO_ISR1A);
+       if (ret != 0)
+               goto err;
+err:
+       return ret;
+}
+
+static int hsmmc2_suspend(struct device *dev, int slot)
+{
+       int ret = 0;
+
+       disable_irq(TWL4030_GPIO_IRQ_NO(MMC2_CD_IRQ));
+       ret = mask_cd2_interrupt(1);
+
+       return ret;
+}
+
 static int hsmmc_resume(struct device *dev, int slot)
 {
        int ret = 0;
@@ -150,6 +239,15 @@ static int hsmmc_resume(struct device *d
        return ret;
 }

+static int hsmmc2_resume(struct device *dev, int slot)
+{
+       int ret = 0;
+
+       enable_irq(TWL4030_GPIO_IRQ_NO(MMC2_CD_IRQ));
+       ret = mask_cd2_interrupt(0);
+
+       return ret;
+}
 #endif

 static int hsmmc_set_power(struct device *dev, int slot, int power_on,
@@ -255,6 +353,70 @@ err:
        return 1;
 }

+static int hsmmc2_set_power(struct device *dev, int slot, int power_on,
+                               int vdd)
+{
+       u32 vdd_sel = 0, devconf = 0;
+       int ret = 0;
+
+       if (power_on == 1) {
+               if (cpu_is_omap24xx())
+                       devconf = omap_readl(0x490022E8);
+               else
+                       devconf = omap_readl(0x480022D8);
+
+               switch (1 << vdd) {
+               case MMC_VDD_33_34:
+               case MMC_VDD_32_33:
+                       vdd_sel = VSEL_3V;
+                       if (cpu_is_omap24xx())
+                               devconf = (devconf | (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 << 6, 0x480022D8);
+
+               ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                                               P1_DEV_GRP, VMMC2_DEV_GRP);
+               if (ret != 0)
+                       goto err;
+
+               ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                                               0x05, VMMC2_DEDICATED);
+               if (ret != 0)
+                       goto err;
+
+               return ret;
+
+       } else if (power_on == 0) {
+
+               /* Power OFF */
+               ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                                               LDO_CLR, VMMC2_DEV_GRP);
+               if (ret != 0)
+                       goto err;
+
+               ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                                               VSEL_S2_CLR, VMMC2_DEDICATED);
+               if (ret != 0)
+                       goto err;
+       } else {
+               ret = -1;
+               goto err;
+       }
+
+       return 0;
+err:
+       return 1;
+}
+
 static struct omap_mmc_platform_data hsmmc_data = {
        .nr_slots                       = 1,
        .switch_slot                    = NULL,
@@ -278,9 +440,32 @@ static struct omap_mmc_platform_data hsm
        },
 };

+static struct omap_mmc_platform_data hsmmc2_data = {
+       .nr_slots                       = 1,
+       .switch_slot                    = NULL,
+       .init                           = hsmmc2_late_init,
+       .cleanup                        = hsmmc2_cleanup,
+#ifdef CONFIG_PM
+       .suspend                        = hsmmc2_suspend,
+       .resume                         = hsmmc2_resume,
+#endif
+       .slots[0] = {
+               .set_power              = hsmmc2_set_power,
+               .set_bus_mode           = NULL,
+               .get_ro                 = NULL,
+               .get_cover_state        = NULL,
+               .ocr_mask               = MMC_VDD_165_195,
+               .name                   = "first slot",
+
+               .card_detect_irq        = TWL4030_GPIO_IRQ_NO(MMC2_CD_IRQ),
+               .card_detect            = hsmmc_card_detect,
+       },
+};
+
 void __init hsmmc_init(void)
 {
        omap_set_mmc_info(1, &hsmmc_data);
+       omap_set_mmc_info(2, &hsmmc2_data);
 }

 #else


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

Reply via email to