]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge branch 'hsmmc-init' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Wed, 17 Dec 2008 20:03:39 +0000 (20:03 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 17 Dec 2008 20:03:39 +0000 (20:03 +0000)
33 files changed:
arch/arm/mach-omap1/board-h2-mmc.c
arch/arm/mach-omap1/board-h2.c
arch/arm/mach-omap1/board-h3-mmc.c
arch/arm/mach-omap1/board-h3.c
arch/arm/mach-omap1/board-innovator.c
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-omap1/board-palmte.c
arch/arm/mach-omap1/board-palmz71.c
arch/arm/mach-omap1/board-sx1-mmc.c
arch/arm/mach-omap1/board-sx1.c
arch/arm/mach-omap1/board-voiceblue.c
arch/arm/mach-omap1/clock.h
arch/arm/mach-omap1/devices.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/clock24xx.h
arch/arm/mach-omap2/clock34xx.h
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/mmc-twl4030.c [new file with mode: 0644]
arch/arm/mach-omap2/mmc-twl4030.h [new file with mode: 0644]
arch/arm/plat-omap/devices.c
arch/arm/plat-omap/include/mach/board-h2.h
arch/arm/plat-omap/include/mach/board.h
arch/arm/plat-omap/include/mach/control.h
arch/arm/plat-omap/include/mach/mmc.h
drivers/mmc/host/omap.c

index ab9ee5820c489f935784fa1148764190ede72fdf..409fa56d0a87dce20d99f2075c6121a2815e26e3 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
 #include <mach/mmc.h>
 #include <mach/gpio.h>
 
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
-static int h2_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
-#ifdef CONFIG_MMC_DEBUG
-       dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
-               power_on ? "on" : "off", vdd);
-#endif
-       if (slot != 0) {
-               dev_err(dev, "No such slot %d\n", slot + 1);
-               return -ENODEV;
-       }
+       if (power_on)
+               gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 1);
+       else
+               gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
 
        return 0;
 }
 
-static int h2_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
+static int mmc_late_init(struct device *dev)
 {
-#ifdef CONFIG_MMC_DEBUG
-       dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
-               bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
-       if (slot != 0) {
-               dev_err(dev, "No such slot %d\n", slot + 1);
-               return -ENODEV;
-       }
+       int ret;
 
-       return 0;
-}
+       ret = gpio_request(H2_TPS_GPIO_MMC_PWR_EN, "MMC power");
+       if (ret < 0)
+               return ret;
 
-static int h2_mmc_get_cover_state(struct device *dev, int slot)
-{
-       BUG_ON(slot != 0);
-
-       return slot_cover_open;
-}
-
-void h2_mmc_slot_cover_handler(void *arg, int state)
-{
-       if (mmc_device == NULL)
-               return;
-
-       slot_cover_open = state;
-       omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int h2_mmc_late_init(struct device *dev)
-{
-       int ret = 0;
-
-       mmc_device = dev;
+       gpio_direction_output(H2_TPS_GPIO_MMC_PWR_EN, 0);
 
        return ret;
 }
 
-static void h2_mmc_cleanup(struct device *dev)
+static void mmc_shutdown(struct device *dev)
 {
+       gpio_free(H2_TPS_GPIO_MMC_PWR_EN);
 }
 
-static struct omap_mmc_platform_data h2_mmc_data = {
+/*
+ * H2 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
        .nr_slots                       = 1,
-       .switch_slot                    = NULL,
-       .init                           = h2_mmc_late_init,
-       .cleanup                        = h2_mmc_cleanup,
+       .init                           = mmc_late_init,
+       .shutdown                       = mmc_shutdown,
+       .dma_mask                       = 0xffffffff,
        .slots[0]       = {
-               .set_power              = h2_mmc_set_power,
-               .set_bus_mode           = h2_mmc_set_bus_mode,
-               .get_ro                 = NULL,
-               .get_cover_state        = h2_mmc_get_cover_state,
+               .set_power              = mmc_set_power,
                .ocr_mask               = MMC_VDD_28_29 | MMC_VDD_30_31 |
                                          MMC_VDD_32_33 | MMC_VDD_33_34,
                .name                   = "mmcblk",
        },
 };
 
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
 void __init h2_mmc_init(void)
 {
-       omap_set_mmc_info(1, &h2_mmc_data);
+       mmc_data[0] = &mmc1_data;
+       omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
 }
 
 #else
@@ -104,7 +82,4 @@ void __init h2_mmc_init(void)
 {
 }
 
-void h2_mmc_slot_cover_handler(void *arg, int state)
-{
-}
 #endif
index c5b4a3b718cf2591ead78b5c1aca18ed1fa90cce..b240c5f861da440080c77715e284b87ce604d601 100644 (file)
@@ -345,10 +345,25 @@ static void __init h2_init_smc91x(void)
        }
 }
 
+static int tps_setup(struct i2c_client *client, void *context)
+{
+       tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V |
+                               TPS_LDO1_ENABLE | TPS_VLDO1_3_0V);
+
+       return 0;
+}
+
+static struct tps65010_board tps_board = {
+       .base           = H2_TPS_GPIO_BASE,
+       .outmask        = 0x0f,
+       .setup          = tps_setup,
+};
+
 static struct i2c_board_info __initdata h2_i2c_board_info[] = {
        {
                I2C_BOARD_INFO("tps65010", 0x48),
                .irq            = OMAP_GPIO_IRQ(58),
+               .platform_data  = &tps_board,
        }, {
                I2C_BOARD_INFO("isp1301_omap", 0x2d),
                .irq            = OMAP_GPIO_IRQ(2),
@@ -378,15 +393,6 @@ static struct omap_usb_config h2_usb_config __initdata = {
        .pins[1]        = 3,
 };
 
-static struct omap_mmc_config h2_mmc_config __initdata = {
-       .mmc[0] = {
-               .enabled        = 1,
-               .wire4          = 1,
-       },
-};
-
-extern struct omap_mmc_platform_data h2_mmc_data;
-
 static struct omap_uart_config h2_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
@@ -397,7 +403,6 @@ static struct omap_lcd_config h2_lcd_config __initdata = {
 
 static struct omap_board_config_kernel h2_config[] __initdata = {
        { OMAP_TAG_USB,         &h2_usb_config },
-       { OMAP_TAG_MMC,         &h2_mmc_config },
        { OMAP_TAG_UART,        &h2_uart_config },
        { OMAP_TAG_LCD,         &h2_lcd_config },
 };
index 36085819098cbdd687665e42946fd0bfcb8a125c..fdfe793d56f2893e61d025ab63113846dc3ef51c 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/platform_device.h>
+
+#include <linux/i2c/tps65010.h>
+
 #include <mach/mmc.h>
 #include <mach/gpio.h>
 
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
-static int h3_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
-#ifdef CONFIG_MMC_DEBUG
-       dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
-               power_on ? "on" : "off", vdd);
-#endif
-       if (slot != 0) {
-               dev_err(dev, "No such slot %d\n", slot + 1);
-               return -ENODEV;
-       }
+       if (power_on)
+               gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 1);
+       else
+               gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
 
        return 0;
 }
 
-static int h3_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
-       int ret = 0;
-
-#ifdef CONFIG_MMC_DEBUG
-       dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
-               bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
-       if (slot != 0) {
-               dev_err(dev, "No such slot %d\n", slot + 1);
-               return -ENODEV;
-       }
-
-       /* Treated on upper level */
-
-       return bus_mode;
-}
-
-static int h3_mmc_get_cover_state(struct device *dev, int slot)
-{
-       BUG_ON(slot != 0);
-
-       return slot_cover_open;
-}
-
-void h3_mmc_slot_cover_handler(void *arg, int state)
-{
-       if (mmc_device == NULL)
-               return;
-
-       slot_cover_open = state;
-       omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int h3_mmc_late_init(struct device *dev)
-{
-       int ret = 0;
-
-       mmc_device = dev;
-
-       return ret;
-}
-
-static void h3_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data h3_mmc_data = {
+/*
+ * H3 could use the following functions tested:
+ * - mmc_get_cover_state that uses OMAP_MPUIO(1)
+ * - mmc_get_wp that maybe uses OMAP_MPUIO(3)
+ */
+static struct omap_mmc_platform_data mmc1_data = {
        .nr_slots                       = 1,
-       .switch_slot                    = NULL,
-       .init                           = h3_mmc_late_init,
-       .cleanup                        = h3_mmc_cleanup,
+       .dma_mask                       = 0xffffffff,
        .slots[0]       = {
-               .set_power              = h3_mmc_set_power,
-               .set_bus_mode           = h3_mmc_set_bus_mode,
-               .get_ro                 = NULL,
-               .get_cover_state        = h3_mmc_get_cover_state,
+               .set_power              = mmc_set_power,
                .ocr_mask               = MMC_VDD_28_29 | MMC_VDD_30_31 |
                                          MMC_VDD_32_33 | MMC_VDD_33_34,
                .name                   = "mmcblk",
        },
 };
 
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
 void __init h3_mmc_init(void)
 {
-       omap_set_mmc_info(1, &h3_mmc_data);
+       int ret;
+
+       ret = gpio_request(H3_TPS_GPIO_MMC_PWR_EN, "MMC power");
+       if (ret < 0)
+               return;
+       gpio_direction_output(H3_TPS_GPIO_MMC_PWR_EN, 0);
+
+       mmc_data[0] = &mmc1_data;
+       omap1_init_mmc(mmc_data, OMAP16XX_NR_MMC);
 }
 
 #else
@@ -108,7 +69,4 @@ void __init h3_mmc_init(void)
 {
 }
 
-void h3_mmc_slot_cover_handler(void *arg, int state)
-{
-}
 #endif
index 0332203bd53d49b32130f00a7c669869a1cb672f..5157eea9be3547fa1a5a14ee3cfe94769481a144 100644 (file)
@@ -447,15 +447,6 @@ static struct omap_usb_config h3_usb_config __initdata = {
        .pins[1]        = 3,
 };
 
-static struct omap_mmc_config h3_mmc_config __initdata = {
-       .mmc[0] = {
-               .enabled        = 1,
-               .wire4          = 1,
-       },
-};
-
-extern struct omap_mmc_platform_data h3_mmc_data;
-
 static struct omap_uart_config h3_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
@@ -466,7 +457,6 @@ static struct omap_lcd_config h3_lcd_config __initdata = {
 
 static struct omap_board_config_kernel h3_config[] __initdata = {
        { OMAP_TAG_USB,         &h3_usb_config },
-       { OMAP_TAG_MMC,         &h3_mmc_config },
        { OMAP_TAG_UART,        &h3_uart_config },
        { OMAP_TAG_LCD,         &h3_lcd_config },
 };
index a21e365a7a8797dc86964bdb500ebab9e9201e5c..af2fb9070083386d7eb9c2716298a548506437e2 100644 (file)
@@ -39,6 +39,7 @@
 #include <mach/common.h>
 #include <mach/mcbsp.h>
 #include <mach/omap-alsa.h>
+#include <mach/mmc.h>
 
 static int innovator_keymap[] = {
        KEY(0, 0, KEY_F1),
@@ -360,16 +361,49 @@ static struct omap_lcd_config innovator1610_lcd_config __initdata = {
 };
 #endif
 
-static struct omap_mmc_config innovator_mmc_config __initdata = {
-       .mmc [0] = {
-               .enabled        = 1,
-               .wire4          = 1,
-               .wp_pin         = OMAP_MPUIO(3),
-               .power_pin      = -1,   /* FPGA F3 UIO42 */
-               .switch_pin     = -1,   /* FPGA F4 UIO43 */
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static int mmc_set_power(struct device *dev, int slot, int power_on,
+                               int vdd)
+{
+       if (power_on)
+               fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
+                               OMAP1510_FPGA_POWER);
+       else
+               fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
+                               OMAP1510_FPGA_POWER);
+
+       return 0;
+}
+
+/*
+ * Innovator could use the following functions tested:
+ * - mmc_get_wp that uses OMAP_MPUIO(3)
+ * - mmc_get_cover_state that uses FPGA F4 UIO43
+ */
+static struct omap_mmc_platform_data mmc1_data = {
+       .nr_slots                       = 1,
+       .slots[0]       = {
+               .set_power              = mmc_set_power,
+               .wires                  = 4,
+               .name                   = "mmcblk",
        },
 };
 
+static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC];
+
+void __init innovator_mmc_init(void)
+{
+       mmc_data[0] = &mmc1_data;
+       omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
+}
+
+#else
+static inline void innovator_mmc_init(void)
+{
+}
+#endif
+
 static struct omap_uart_config innovator_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
@@ -377,7 +411,6 @@ static struct omap_uart_config innovator_uart_config __initdata = {
 static struct omap_board_config_kernel innovator_config[] = {
        { OMAP_TAG_USB,         NULL },
        { OMAP_TAG_LCD,         NULL },
-       { OMAP_TAG_MMC,         &innovator_mmc_config },
        { OMAP_TAG_UART,        &innovator_uart_config },
 };
 
@@ -412,6 +445,7 @@ static void __init innovator_init(void)
        omap_board_config_size = ARRAY_SIZE(innovator_config);
        omap_serial_init();
        omap_register_i2c_bus(1, 100, NULL, 0);
+       innovator_mmc_init();
 }
 
 static void __init innovator_map_io(void)
index b26782471e59c3c8f25f3f856c81fc3cbc8ad515..4970c402a59431d14c439e7ccfd650de3658539f 100644 (file)
@@ -35,6 +35,7 @@
 #include <mach/aic23.h>
 #include <mach/omapfb.h>
 #include <mach/lcd_mipid.h>
+#include <mach/mmc.h>
 
 #define ADS7846_PENDOWN_GPIO   15
 
@@ -173,26 +174,68 @@ static struct omap_usb_config nokia770_usb_config __initdata = {
        .pins[0]        = 6,
 };
 
-static struct omap_mmc_config nokia770_mmc_config __initdata = {
-       .mmc[0] = {
-               .enabled        = 0,
-               .wire4          = 0,
-               .wp_pin         = -1,
-               .power_pin      = -1,
-               .switch_pin     = -1,
-       },
-       .mmc[1] = {
-               .enabled        = 0,
-               .wire4          = 0,
-               .wp_pin         = -1,
-               .power_pin      = -1,
-               .switch_pin     = -1,
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+#define NOKIA770_GPIO_MMC_POWER                41
+#define NOKIA770_GPIO_MMC_SWITCH       23
+
+static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on,
+                               int vdd)
+{
+       if (power_on)
+               gpio_set_value(NOKIA770_GPIO_MMC_POWER, 1);
+       else
+               gpio_set_value(NOKIA770_GPIO_MMC_POWER, 0);
+
+       return 0;
+}
+
+static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
+{
+       return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH);
+}
+
+static struct omap_mmc_platform_data nokia770_mmc2_data = {
+       .nr_slots                       = 1,
+       .dma_mask                       = 0xffffffff,
+       .slots[0]       = {
+               .set_power              = nokia770_mmc_set_power,
+               .get_cover_state        = nokia770_mmc_get_cover_state,
+               .name                   = "mmcblk",
        },
 };
 
+static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC];
+
+static void __init nokia770_mmc_init(void)
+{
+       int ret;
+
+       ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power");
+       if (ret < 0)
+               return;
+       gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0);
+
+       ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover");
+       if (ret < 0) {
+               gpio_free(NOKIA770_GPIO_MMC_POWER);
+               return;
+       }
+       gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH);
+
+       /* Only the second MMC controller is used */
+       nokia770_mmc_data[1] = &nokia770_mmc2_data;
+       omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC);
+}
+
+#else
+static inline void nokia770_mmc_init(void)
+{
+}
+#endif
+
 static struct omap_board_config_kernel nokia770_config[] __initdata = {
        { OMAP_TAG_USB,         NULL },
-       { OMAP_TAG_MMC,         &nokia770_mmc_config },
 };
 
 #if    defined(CONFIG_OMAP_DSP)
@@ -335,6 +378,7 @@ static void __init omap_nokia770_init(void)
        omap_dsp_init();
        ads7846_dev_init();
        mipid_dev_init();
+       nokia770_mmc_init();
 }
 
 static void __init omap_nokia770_map_io(void)
index 4141e3917d7cfcbabb011a60984e48626cdd3860..75e32d35afd9301888e55f8dbb177ffc566268c0 100644 (file)
@@ -316,7 +316,6 @@ static void palmte_get_power_status(struct apm_power_info *info, int *battery)
 
 static struct omap_board_config_kernel palmte_config[] __initdata = {
        { OMAP_TAG_USB,         &palmte_usb_config },
-       { OMAP_TAG_MMC,         &palmte_mmc_config },
        { OMAP_TAG_LCD,         &palmte_lcd_config },
        { OMAP_TAG_UART,        &palmte_uart_config },
 };
index 801fb5f62ed77c18f1e0a96bc3b55611946f2e42..cc05257eb1cddd7720b182dd7fd52444e8510636 100644 (file)
@@ -267,16 +267,6 @@ static struct omap_usb_config palmz71_usb_config __initdata = {
        .pins[0]        = 2,
 };
 
-static struct omap_mmc_config palmz71_mmc_config __initdata = {
-       .mmc[0] = {
-               .enabled        = 1,
-               .wire4          = 0,
-               .wp_pin         = PALMZ71_MMC_WP_GPIO,
-               .power_pin      = -1,
-               .switch_pin     = PALMZ71_MMC_IN_GPIO,
-       },
-};
-
 static struct omap_lcd_config palmz71_lcd_config __initdata = {
        .ctrl_name = "internal",
 };
@@ -287,7 +277,6 @@ static struct omap_uart_config palmz71_uart_config __initdata = {
 
 static struct omap_board_config_kernel palmz71_config[] __initdata = {
        {OMAP_TAG_USB,  &palmz71_usb_config},
-       {OMAP_TAG_MMC,  &palmz71_mmc_config},
        {OMAP_TAG_LCD,  &palmz71_lcd_config},
        {OMAP_TAG_UART, &palmz71_uart_config},
 };
index 0be4ebaa2842a120e2be29e96ce8906ec32fb105..66a4d7d5255d2f767c18cf370b074e4472ff451c 100644 (file)
  * published by the Free Software Foundation.
  */
 
+#include <linux/platform_device.h>
+
 #include <mach/hardware.h>
 #include <mach/mmc.h>
 #include <mach/gpio.h>
 
-#ifdef CONFIG_MMC_OMAP
-static int slot_cover_open;
-static struct device *mmc_device;
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
 
-static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
+static int mmc_set_power(struct device *dev, int slot, int power_on,
                                int vdd)
 {
        int err;
        u8 dat = 0;
 
-#ifdef CONFIG_MMC_DEBUG
-       dev_dbg(dev, "Set slot %d power: %s (vdd %d)\n", slot + 1,
-               power_on ? "on" : "off", vdd);
-#endif
-
-       if (slot != 0) {
-               dev_err(dev, "No such slot %d\n", slot + 1);
-               return -ENODEV;
-       }
-
        err = sx1_i2c_read_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, &dat);
        if (err < 0)
                return err;
@@ -48,68 +38,23 @@ static int sx1_mmc_set_power(struct device *dev, int slot, int power_on,
        return sx1_i2c_write_byte(SOFIA_I2C_ADDR, SOFIA_POWER1_REG, dat);
 }
 
-static int sx1_mmc_set_bus_mode(struct device *dev, int slot, int bus_mode)
-{
-#ifdef CONFIG_MMC_DEBUG
-       dev_dbg(dev, "Set slot %d bus_mode %s\n", slot + 1,
-               bus_mode == MMC_BUSMODE_OPENDRAIN ? "open-drain" : "push-pull");
-#endif
-       if (slot != 0) {
-               dev_err(dev, "No such slot %d\n", slot + 1);
-               return -ENODEV;
-       }
-
-       return 0;
-}
-
-static int sx1_mmc_get_cover_state(struct device *dev, int slot)
-{
-       BUG_ON(slot != 0);
-
-       return slot_cover_open;
-}
-
-void sx1_mmc_slot_cover_handler(void *arg, int state)
-{
-       if (mmc_device == NULL)
-               return;
-
-       slot_cover_open = state;
-       omap_mmc_notify_cover_event(mmc_device, 0, state);
-}
-
-static int sx1_mmc_late_init(struct device *dev)
-{
-       int ret = 0;
-
-       mmc_device = dev;
-
-       return ret;
-}
-
-static void sx1_mmc_cleanup(struct device *dev)
-{
-}
-
-static struct omap_mmc_platform_data sx1_mmc_data = {
+/* Cover switch is at OMAP_MPUIO(3) */
+static struct omap_mmc_platform_data mmc1_data = {
        .nr_slots                       = 1,
-       .switch_slot                    = NULL,
-       .init                           = sx1_mmc_late_init,
-       .cleanup                        = sx1_mmc_cleanup,
        .slots[0]       = {
-               .set_power              = sx1_mmc_set_power,
-               .set_bus_mode           = sx1_mmc_set_bus_mode,
-               .get_ro                 = NULL,
-               .get_cover_state        = sx1_mmc_get_cover_state,
+               .set_power              = mmc_set_power,
                .ocr_mask               = MMC_VDD_28_29 | MMC_VDD_30_31 |
                                          MMC_VDD_32_33 | MMC_VDD_33_34,
                .name                   = "mmcblk",
        },
 };
 
+static struct omap_mmc_platform_data *mmc_data[OMAP15XX_NR_MMC];
+
 void __init sx1_mmc_init(void)
 {
-       omap_set_mmc_info(1, &sx1_mmc_data);
+       mmc_data[0] = &mmc1_data;
+       omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC);
 }
 
 #else
@@ -118,7 +63,4 @@ void __init sx1_mmc_init(void)
 {
 }
 
-void sx1_mmc_slot_cover_handler(void *arg, int state)
-{
-}
 #endif
index 93bd395b997270029af5c9e525f897d051b3d938..8171fe0ca082aeb8e0fb59999cd0e5eb6a1cadc7 100644 (file)
@@ -378,15 +378,6 @@ static struct omap_usb_config sx1_usb_config __initdata = {
        .pins[2]        = 0,
 };
 
-/*----------- MMC -------------------------*/
-
-static struct omap_mmc_config sx1_mmc_config __initdata = {
-       .mmc [0] = {
-               .enabled        = 1,
-               .wire4          = 0,
-       },
-};
-
 /*----------- LCD -------------------------*/
 
 static struct platform_device sx1_lcd_device = {
@@ -414,7 +405,6 @@ static struct omap_uart_config sx1_uart_config __initdata = {
 
 static struct omap_board_config_kernel sx1_config[] __initdata = {
        { OMAP_TAG_USB, &sx1_usb_config },
-       { OMAP_TAG_MMC, &sx1_mmc_config },
        { OMAP_TAG_LCD, &sx1_lcd_config },
        { OMAP_TAG_UART,        &sx1_uart_config },
 };
index 92c9de1090a9df3a1ee3304b5bc704362428e69e..c224f3c642353b2705c82c69d91e5537500acad2 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/notifier.h>
@@ -140,21 +141,12 @@ static struct omap_usb_config voiceblue_usb_config __initdata = {
        .pins[2]        = 6,
 };
 
-static struct omap_mmc_config voiceblue_mmc_config __initdata = {
-       .mmc[0] = {
-               .enabled        = 1,
-               .power_pin      = 2,
-               .switch_pin     = -1,
-       },
-};
-
 static struct omap_uart_config voiceblue_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
 static struct omap_board_config_kernel voiceblue_config[] = {
        { OMAP_TAG_USB,  &voiceblue_usb_config },
-       { OMAP_TAG_MMC,  &voiceblue_mmc_config },
        { OMAP_TAG_UART, &voiceblue_uart_config },
 };
 
index 5635b511ab6f0b5d1546fef5dec6ed52d70e3c96..c1dcdf18d8ddecaeaf14706cb839a1a424aae22f 100644 (file)
@@ -705,7 +705,6 @@ static struct clk bclk_16xx = {
 
 static struct clk mmc1_ck = {
        .name           = "mmc_ck",
-       .id             = 1,
        /* Functional clock is direct from ULPD, interface clock is ARMPER */
        .parent         = &armper_ck.clk,
        .rate           = 48000000,
@@ -720,7 +719,7 @@ static struct clk mmc1_ck = {
 
 static struct clk mmc2_ck = {
        .name           = "mmc_ck",
-       .id             = 2,
+       .id             = 1,
        /* Functional clock is direct from ULPD, interface clock is ARMPER */
        .parent         = &armper_ck.clk,
        .rate           = 48000000,
index e382b438c64ed5d42d49f05e1586ab03c3218aa5..77382d8b6b2f61a4d0c4a93fb4357ba48220d061 100644 (file)
@@ -22,6 +22,7 @@
 #include <mach/board.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
+#include <mach/mmc.h>
 
 /*-------------------------------------------------------------------------*/
 
@@ -99,6 +100,95 @@ static inline void omap_init_mbox(void)
 static inline void omap_init_mbox(void) { }
 #endif
 
+/*-------------------------------------------------------------------------*/
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+
+static inline void omap1_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+                       int controller_nr)
+{
+       if (controller_nr == 0) {
+               omap_cfg_reg(MMC_CMD);
+               omap_cfg_reg(MMC_CLK);
+               omap_cfg_reg(MMC_DAT0);
+               if (cpu_is_omap1710()) {
+                       omap_cfg_reg(M15_1710_MMC_CLKI);
+                       omap_cfg_reg(P19_1710_MMC_CMDDIR);
+                       omap_cfg_reg(P20_1710_MMC_DATDIR0);
+               }
+               if (mmc_controller->slots[0].wires == 4) {
+                       omap_cfg_reg(MMC_DAT1);
+                       /* NOTE: DAT2 can be on W10 (here) or M15 */
+                       if (!mmc_controller->slots[0].nomux)
+                               omap_cfg_reg(MMC_DAT2);
+                       omap_cfg_reg(MMC_DAT3);
+               }
+       }
+
+       /* Block 2 is on newer chips, and has many pinout options */
+       if (cpu_is_omap16xx() && controller_nr == 1) {
+               if (!mmc_controller->slots[1].nomux) {
+                       omap_cfg_reg(Y8_1610_MMC2_CMD);
+                       omap_cfg_reg(Y10_1610_MMC2_CLK);
+                       omap_cfg_reg(R18_1610_MMC2_CLKIN);
+                       omap_cfg_reg(W8_1610_MMC2_DAT0);
+                       if (mmc_controller->slots[1].wires == 4) {
+                               omap_cfg_reg(V8_1610_MMC2_DAT1);
+                               omap_cfg_reg(W15_1610_MMC2_DAT2);
+                               omap_cfg_reg(R10_1610_MMC2_DAT3);
+                       }
+
+                       /* These are needed for the level shifter */
+                       omap_cfg_reg(V9_1610_MMC2_CMDDIR);
+                       omap_cfg_reg(V5_1610_MMC2_DATDIR0);
+                       omap_cfg_reg(W19_1610_MMC2_DATDIR1);
+               }
+
+               /* Feedback clock must be set on OMAP-1710 MMC2 */
+               if (cpu_is_omap1710())
+                       omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
+                                       MOD_CONF_CTRL_1);
+       }
+}
+
+void __init omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+                       int nr_controllers)
+{
+       int i;
+
+       for (i = 0; i < nr_controllers; i++) {
+               unsigned long base, size;
+               unsigned int irq = 0;
+
+               if (!mmc_data[i])
+                       continue;
+
+               omap1_mmc_mux(mmc_data[i], i);
+
+               switch (i) {
+               case 0:
+                       base = OMAP1_MMC1_BASE;
+                       irq = INT_MMC;
+                       break;
+               case 1:
+                       if (!cpu_is_omap16xx())
+                               return;
+                       base = OMAP1_MMC2_BASE;
+                       irq = INT_1610_MMC2;
+                       break;
+               default:
+                       continue;
+               }
+               size = OMAP1_MMC_SIZE;
+
+               omap_mmc_add(i, base, size, irq, mmc_data[i]);
+       };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if defined(CONFIG_OMAP_STI)
 
 #define OMAP1_STI_BASE         0xfffea000
index f12c43e4932fb5069a2ed492f43252a262ab45cc..bbd12bc10fdc1dc39d642227059999d74de5aec8 100644 (file)
@@ -27,10 +27,15 @@ obj-$(CONFIG_ARCH_OMAP3)            += clock34xx.o
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)                += board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)             += board-h4.o
-obj-$(CONFIG_MACH_OMAP_2430SDP)                += board-2430sdp.o
+obj-$(CONFIG_MACH_OMAP_2430SDP)                += board-2430sdp.o \
+                                          mmc-twl4030.o
 obj-$(CONFIG_MACH_OMAP_APOLLON)                += board-apollon.o
-obj-$(CONFIG_MACH_OMAP3_BEAGLE)                += board-omap3beagle.o
-obj-$(CONFIG_MACH_OMAP_LDP)            += board-ldp.o
-obj-$(CONFIG_MACH_OVERO)               += board-overo.o
-obj-$(CONFIG_MACH_OMAP3_PANDORA)       += board-omap3pandora.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE)                += board-omap3beagle.o \
+                                          mmc-twl4030.o
+obj-$(CONFIG_MACH_OMAP_LDP)            += board-ldp.o \
+                                          mmc-twl4030.o
+obj-$(CONFIG_MACH_OVERO)               += board-overo.o \
+                                          mmc-twl4030.o
+obj-$(CONFIG_MACH_OMAP3_PANDORA)       += board-omap3pandora.o \
+                                          mmc-twl4030.o
 
index 6748de6e19a83099ee0e6717b432aada47d773f1..83fa37211d77c1a1b04b1c68f0f913d5ea47d97c 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
+#include <linux/i2c/twl4030.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -35,6 +36,7 @@
 #include <mach/common.h>
 #include <mach/gpmc.h>
 
+#include "mmc-twl4030.h"
 
 #define        SDP2430_FLASH_CS        0
 #define        SDP2430_SMC91X_CS       5
@@ -197,12 +199,58 @@ static struct omap_board_config_kernel sdp2430_config[] = {
        {OMAP_TAG_UART, &sdp2430_uart_config},
 };
 
+
+static struct twl4030_gpio_platform_data sdp2430_gpio_data = {
+       .gpio_base      = OMAP_MAX_GPIO_LINES,
+       .irq_base       = TWL4030_GPIO_IRQ_BASE,
+       .irq_end        = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_platform_data sdp2430_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+
+       /* platform_data for children goes here */
+       .gpio           = &sdp2430_gpio_data,
+};
+
+static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("twl4030", 0x48),
+               .flags = I2C_CLIENT_WAKE,
+               .irq = INT_24XX_SYS_NIRQ,
+               .platform_data = &sdp2430_twldata,
+       },
+};
+
+static int __init omap2430_i2c_init(void)
+{
+       omap_register_i2c_bus(1, 400, NULL, 0);
+       omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo,
+                       ARRAY_SIZE(sdp2430_i2c_boardinfo));
+       return 0;
+}
+
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+               .ext_clock      = 1,
+       },
+       {}      /* Terminator */
+};
+
 static void __init omap_2430sdp_init(void)
 {
+       omap2430_i2c_init();
+
        platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
        omap_board_config = sdp2430_config;
        omap_board_config_size = ARRAY_SIZE(sdp2430_config);
        omap_serial_init();
+       twl4030_mmc_init(mmc);
 }
 
 static void __init omap_2430sdp_map_io(void)
index d83035b436d5f7d234bceaf5ad966f75aa37a026..bf1e5d32c2a3415d4efcbf972dd0fb45b5917195 100644 (file)
@@ -261,16 +261,6 @@ static struct omap_uart_config apollon_uart_config __initdata = {
        .enabled_uarts = (1 << 0) | (0 << 1) | (0 << 2),
 };
 
-static struct omap_mmc_config apollon_mmc_config __initdata = {
-       .mmc [0] = {
-               .enabled        = 1,
-               .wire4          = 1,
-               .wp_pin         = -1,
-               .power_pin      = -1,
-               .switch_pin     = -1,
-       },
-};
-
 static struct omap_usb_config apollon_usb_config __initdata = {
        .register_dev   = 1,
        .hmc_mode       = 0x14, /* 0:dev 1:host1 2:disable */
@@ -284,7 +274,6 @@ static struct omap_lcd_config apollon_lcd_config __initdata = {
 
 static struct omap_board_config_kernel apollon_config[] = {
        { OMAP_TAG_UART,        &apollon_uart_config },
-       { OMAP_TAG_MMC,         &apollon_mmc_config },
        { OMAP_TAG_USB,         &apollon_usb_config },
        { OMAP_TAG_LCD,         &apollon_lcd_config },
 };
index 9ba097868e72b78657a3608ef79fef647276b166..3b34c20d1df41ef5920cdc4e63a9c03cabbd6475 100644 (file)
@@ -41,19 +41,8 @@ static struct omap_uart_config generic_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
-static struct omap_mmc_config generic_mmc_config __initdata = {
-       .mmc [0] = {
-               .enabled        = 0,
-               .wire4          = 0,
-               .wp_pin         = -1,
-               .power_pin      = -1,
-               .switch_pin     = -1,
-       },
-};
-
 static struct omap_board_config_kernel generic_config[] = {
        { OMAP_TAG_UART,        &generic_uart_config },
-       { OMAP_TAG_MMC,         &generic_mmc_config },
 };
 
 static void __init omap_generic_init(void)
index 7de0506e1e29729dae45effb0919edb6b9777910..5e9b14675b1e7bc81ff3d9c607d5d004b4bb51e0 100644 (file)
@@ -373,23 +373,12 @@ static struct omap_uart_config h4_uart_config __initdata = {
        .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
-static struct omap_mmc_config h4_mmc_config __initdata = {
-       .mmc [0] = {
-               .enabled        = 1,
-               .wire4          = 1,
-               .wp_pin         = -1,
-               .power_pin      = -1,
-               .switch_pin     = -1,
-       },
-};
-
 static struct omap_lcd_config h4_lcd_config __initdata = {
        .ctrl_name      = "internal",
 };
 
 static struct omap_board_config_kernel h4_config[] = {
        { OMAP_TAG_UART,        &h4_uart_config },
-       { OMAP_TAG_MMC,         &h4_mmc_config },
        { OMAP_TAG_LCD,         &h4_lcd_config },
 };
 
index 43c7ac4b7f8f3f104ca7b456b620a6ea07553f61..aa6972781e4a946c9b2a0c1c4ff969635b683944 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/clk.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
+#include <linux/i2c/twl4030.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -38,6 +39,8 @@
 #include <asm/delay.h>
 #include <mach/control.h>
 
+#include "mmc-twl4030.h"
+
 #define SDP3430_SMC91X_CS      3
 
 static struct resource ldp_smc911x_resources[] = {
@@ -109,14 +112,48 @@ static struct omap_board_config_kernel ldp_config[] __initdata = {
        { OMAP_TAG_UART,        &ldp_uart_config },
 };
 
+static struct twl4030_gpio_platform_data ldp_gpio_data = {
+       .gpio_base      = OMAP_MAX_GPIO_LINES,
+       .irq_base       = TWL4030_GPIO_IRQ_BASE,
+       .irq_end        = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_platform_data ldp_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+
+       /* platform_data for children goes here */
+       .gpio           = &ldp_gpio_data,
+};
+
+static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("twl4030", 0x48),
+               .flags = I2C_CLIENT_WAKE,
+               .irq = INT_34XX_SYS_NIRQ,
+               .platform_data = &ldp_twldata,
+       },
+};
+
 static int __init omap_i2c_init(void)
 {
-       omap_register_i2c_bus(1, 2600, NULL, 0);
+       omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo,
+                       ARRAY_SIZE(ldp_i2c_boardinfo));
        omap_register_i2c_bus(2, 400, NULL, 0);
        omap_register_i2c_bus(3, 400, NULL, 0);
        return 0;
 }
 
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+       },
+       {}      /* Terminator */
+};
+
 static void __init omap_ldp_init(void)
 {
        omap_i2c_init();
@@ -124,6 +161,7 @@ static void __init omap_ldp_init(void)
        omap_board_config = ldp_config;
        omap_board_config_size = ARRAY_SIZE(ldp_config);
        omap_serial_init();
+       twl4030_mmc_init(mmc);
 }
 
 static void __init omap_ldp_map_io(void)
index baa79674e9d551ebde498af3a29595ad2a0b5e8c..9e5ada01b5fab3e4c93d9a560b6c4ae561e141e3 100644 (file)
@@ -38,7 +38,9 @@
 #include <mach/common.h>
 #include <mach/gpmc.h>
 #include <mach/nand.h>
+#include <mach/mux.h>
 
+#include "mmc-twl4030.h"
 
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
@@ -103,6 +105,78 @@ static struct omap_uart_config omap3_beagle_uart_config __initdata = {
        .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
+static struct twl4030_hsmmc_info mmc[] = {
+       {
+               .mmc            = 1,
+               .wires          = 8,
+               .gpio_wp        = 29,
+       },
+       {}      /* Terminator */
+};
+
+static struct gpio_led gpio_leds[];
+
+static int beagle_twl_gpio_setup(struct device *dev,
+               unsigned gpio, unsigned ngpio)
+{
+       /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+
+       /* REVISIT: need ehci-omap hooks for external VBUS
+        * power switch and overcurrent detect
+        */
+
+       gpio_request(gpio + 1, "EHCI_nOC");
+       gpio_direction_input(gpio + 1);
+
+       /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
+       gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
+       gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
+
+       /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+       gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+       return 0;
+}
+
+static struct twl4030_gpio_platform_data beagle_gpio_data = {
+       .gpio_base      = OMAP_MAX_GPIO_LINES,
+       .irq_base       = TWL4030_GPIO_IRQ_BASE,
+       .irq_end        = TWL4030_GPIO_IRQ_END,
+       .use_leds       = true,
+       .pullups        = BIT(1),
+       .pulldowns      = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+                               | BIT(15) | BIT(16) | BIT(17),
+       .setup          = beagle_twl_gpio_setup,
+};
+
+static struct twl4030_platform_data beagle_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+
+       /* platform_data for children goes here */
+       .gpio           = &beagle_gpio_data,
+};
+
+static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("twl4030", 0x48),
+               .flags = I2C_CLIENT_WAKE,
+               .irq = INT_34XX_SYS_NIRQ,
+               .platform_data = &beagle_twldata,
+       },
+};
+
+static int __init omap3_beagle_i2c_init(void)
+{
+       omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
+                       ARRAY_SIZE(beagle_i2c_boardinfo));
+#ifdef CONFIG_I2C2_OMAP_BEAGLE
+       omap_register_i2c_bus(2, 400, NULL, 0);
+#endif
+       omap_register_i2c_bus(3, 400, NULL, 0);
+       return 0;
+}
+
 static void __init omap3_beagle_init_irq(void)
 {
        omap2_init_common_hw();
@@ -130,6 +204,11 @@ static struct gpio_led gpio_leds[] = {
                .default_trigger        = "mmc0",
                .gpio                   = 149,
        },
+       {
+               .name                   = "beagleboard::pmu_stat",
+               .gpio                   = -EINVAL,      /* gets replaced */
+               .active_low             = true,
+       },
 };
 
 static struct gpio_led_platform_data gpio_led_info = {
@@ -218,11 +297,22 @@ static void __init omap3beagle_flash_init(void)
 
 static void __init omap3_beagle_init(void)
 {
+       omap3_beagle_i2c_init();
        platform_add_devices(omap3_beagle_devices,
                        ARRAY_SIZE(omap3_beagle_devices));
        omap_board_config = omap3_beagle_config;
        omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
        omap_serial_init();
+
+       omap_cfg_reg(AH8_34XX_GPIO29);
+       mmc[0].gpio_cd = gpio + 0;
+       twl4030_mmc_init(mmc);
+
+       omap_cfg_reg(J25_34XX_GPIO170);
+       gpio_request(170, "DVI_nPD");
+       /* REVISIT leave DVI powered down until it's needed ... */
+       gpio_direction_output(170, true);
+
        omap3beagle_flash_init();
 }
 
index 7236c7be05b37ab429553f16d78ecf2df738bc96..b3196107afdbca5ff4a56de60fdfaf8e1b85e772 100644 (file)
 #include <mach/hardware.h>
 #include <mach/mcspi.h>
 
+#include "mmc-twl4030.h"
+
 #define OMAP3_PANDORA_TS_GPIO          94
 
+static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = 126,
+               .ext_clock      = 0,
+       },
+       {
+               .mmc            = 2,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = 127,
+               .ext_clock      = 1,
+       },
+       {}      /* Terminator */
+};
+
 static struct omap_uart_config omap3pandora_uart_config __initdata = {
        .enabled_uarts  = (1 << 2), /* UART3 */
 };
 
+static int omap3pandora_twl_gpio_setup(struct device *dev,
+               unsigned gpio, unsigned ngpio)
+{
+       /* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
+       omap3pandora_mmc[0].gpio_cd = gpio + 0;
+       omap3pandora_mmc[1].gpio_cd = gpio + 1;
+       twl4030_mmc_init(omap3pandora_mmc);
+
+       return 0;
+}
+
 static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
        .gpio_base      = OMAP_MAX_GPIO_LINES,
        .irq_base       = TWL4030_GPIO_IRQ_BASE,
        .irq_end        = TWL4030_GPIO_IRQ_END,
+       .setup          = omap3pandora_twl_gpio_setup,
 };
 
 static struct twl4030_usb_data omap3pandora_usb_data = {
index e09aa59a399c19979065f9f2c66a8a30e07698a3..82b3dc557c96736764f6fdbb235cf1f930a0a2a3 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
+#include <linux/i2c/twl4030.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -44,6 +45,8 @@
 #include <mach/hardware.h>
 #include <mach/nand.h>
 
+#include "mmc-twl4030.h"
+
 #define NAND_BLOCK_SIZE SZ_128K
 #define GPMC_CS0_BASE  0x60
 #define GPMC_CS_SIZE   0x30
@@ -139,8 +142,31 @@ static struct omap_uart_config overo_uart_config __initdata = {
        .enabled_uarts  = ((1 << 0) | (1 << 1) | (1 << 2)),
 };
 
+static struct twl4030_gpio_platform_data overo_gpio_data = {
+       .gpio_base      = OMAP_MAX_GPIO_LINES,
+       .irq_base       = TWL4030_GPIO_IRQ_BASE,
+       .irq_end        = TWL4030_GPIO_IRQ_END,
+};
+
+static struct twl4030_platform_data overo_twldata = {
+       .irq_base       = TWL4030_IRQ_BASE,
+       .irq_end        = TWL4030_IRQ_END,
+       .gpio           = &overo_gpio_data,
+};
+
+static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
+       {
+               I2C_BOARD_INFO("twl4030", 0x48),
+               .flags = I2C_CLIENT_WAKE,
+               .irq = INT_34XX_SYS_NIRQ,
+               .platform_data = &overo_twldata,
+       },
+};
+
 static int __init overo_i2c_init(void)
 {
+       omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo,
+                       ARRAY_SIZE(overo_i2c_boardinfo));
        /* i2c2 pins are used for gpio */
        omap_register_i2c_bus(3, 400, NULL, 0);
        return 0;
@@ -171,6 +197,22 @@ static struct platform_device *overo_devices[] __initdata = {
        &overo_lcd_device,
 };
 
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+       {
+               .mmc            = 1,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+       },
+       {
+               .mmc            = 2,
+               .wires          = 4,
+               .gpio_cd        = -EINVAL,
+               .gpio_wp        = -EINVAL,
+       },
+       {}      /* Terminator */
+};
+
 static void __init overo_init(void)
 {
        overo_i2c_init();
@@ -178,6 +220,7 @@ static void __init overo_init(void)
        omap_board_config = overo_config;
        omap_board_config_size = ARRAY_SIZE(overo_config);
        omap_serial_init();
+       twl4030_mmc_init(mmc);
        overo_flash_init();
 
        if ((gpio_request(OVERO_GPIO_W2W_NRESET,
index 242a19d86ccd025f1a36d6baede741e0a7b5d03c..ff6cd14d254db7a9a098dd87b7000f1cbac1e09b 100644 (file)
@@ -2522,7 +2522,6 @@ static struct clk usbhs_ick = {
 
 static struct clk mmchs1_ick = {
        .name           = "mmchs_ick",
-       .id             = 1,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .clkdm_name     = "core_l4_clkdm",
@@ -2533,7 +2532,6 @@ static struct clk mmchs1_ick = {
 
 static struct clk mmchs1_fck = {
        .name           = "mmchs_fck",
-       .id             = 1,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .clkdm_name     = "core_l3_clkdm",
@@ -2544,7 +2542,7 @@ static struct clk mmchs1_fck = {
 
 static struct clk mmchs2_ick = {
        .name           = "mmchs_ick",
-       .id             = 2,
+       .id             = 1,
        .parent         = &l4_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .clkdm_name     = "core_l4_clkdm",
@@ -2555,7 +2553,7 @@ static struct clk mmchs2_ick = {
 
 static struct clk mmchs2_fck = {
        .name           = "mmchs_fck",
-       .id             = 2,
+       .id             = 1,
        .parent         = &func_96m_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
@@ -2595,7 +2593,6 @@ static struct clk mdm_intc_ick = {
 
 static struct clk mmchsdb1_fck = {
        .name           = "mmchsdb_fck",
-       .id             = 1,
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .clkdm_name     = "core_l4_clkdm",
@@ -2606,7 +2603,7 @@ static struct clk mmchsdb1_fck = {
 
 static struct clk mmchsdb2_fck = {
        .name           = "mmchsdb_fck",
-       .id             = 2,
+       .id             = 1,
        .parent         = &func_32k_ck,
        .flags          = CLOCK_IN_OMAP243X,
        .clkdm_name     = "core_l4_clkdm",
index 7217a0824ec4150555e746cbb68d593a8a865a49..a826094d89b57caade4c88c0e992638243396e7c 100644 (file)
@@ -1374,7 +1374,7 @@ static struct clk core_96m_fck = {
 
 static struct clk mmchs3_fck = {
        .name           = "mmchs_fck",
-       .id             = 3,
+       .id             = 2,
        .parent         = &core_96m_fck,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430ES2_EN_MMC3_SHIFT,
@@ -1385,7 +1385,7 @@ static struct clk mmchs3_fck = {
 
 static struct clk mmchs2_fck = {
        .name           = "mmchs_fck",
-       .id             = 2,
+       .id             = 1,
        .parent         = &core_96m_fck,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_MMC2_SHIFT,
@@ -1406,7 +1406,6 @@ static struct clk mspro_fck = {
 
 static struct clk mmchs1_fck = {
        .name           = "mmchs_fck",
-       .id             = 1,
        .parent         = &core_96m_fck,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
        .enable_bit     = OMAP3430_EN_MMC1_SHIFT,
@@ -1722,7 +1721,7 @@ static struct clk usbtll_ick = {
 
 static struct clk mmchs3_ick = {
        .name           = "mmchs_ick",
-       .id             = 3,
+       .id             = 2,
        .parent         = &core_l4_ick,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430ES2_EN_MMC3_SHIFT,
@@ -1774,7 +1773,7 @@ static struct clk des2_ick = {
 
 static struct clk mmchs2_ick = {
        .name           = "mmchs_ick",
-       .id             = 2,
+       .id             = 1,
        .parent         = &core_l4_ick,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MMC2_SHIFT,
@@ -1785,7 +1784,6 @@ static struct clk mmchs2_ick = {
 
 static struct clk mmchs1_ick = {
        .name           = "mmchs_ick",
-       .id             = 1,
        .parent         = &core_l4_ick,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_MMC1_SHIFT,
index 90af2ac469aaccc74401ceea7fe5487e63a7dd6b..9d7216ff6c9f58d4d5ffbb4a85a3bfc4f764c74e 100644 (file)
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
+#include <mach/control.h>
 #include <mach/tc.h>
 #include <mach/board.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
 #include <mach/eac.h>
+#include <mach/mmc.h>
 
 #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
 #define OMAP2_MBOX_BASE                IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
@@ -295,6 +298,171 @@ static void omap_init_sha1_md5(void)
 static inline void omap_init_sha1_md5(void) { }
 #endif
 
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP3
+
+#define MMCHS_SYSCONFIG                        0x0010
+#define MMCHS_SYSCONFIG_SWRESET                (1 << 1)
+#define MMCHS_SYSSTATUS                        0x0014
+#define MMCHS_SYSSTATUS_RESETDONE      (1 << 0)
+
+static struct platform_device dummy_pdev = {
+       .dev = {
+               .bus = &platform_bus_type,
+       },
+};
+
+/**
+ * omap_hsmmc_reset() - Full reset of each HS-MMC controller
+ *
+ * Ensure that each MMC controller is fully reset.  Controllers
+ * left in an unknown state (by bootloader) may prevent retention
+ * or OFF-mode.  This is especially important in cases where the
+ * MMC driver is not enabled, _or_ built as a module.
+ *
+ * In order for reset to work, interface, functional and debounce
+ * clocks must be enabled.  The debounce clock comes from func_32k_clk
+ * and is not under SW control, so we only enable i- and f-clocks.
+ **/
+static void __init omap_hsmmc_reset(void)
+{
+       u32 i, nr_controllers = cpu_is_omap34xx() ? OMAP34XX_NR_MMC :
+               OMAP24XX_NR_MMC;
+
+       for (i = 0; i < nr_controllers; i++) {
+               u32 v, base = 0;
+               struct clk *iclk, *fclk;
+               struct device *dev = &dummy_pdev.dev;
+
+               switch (i) {
+               case 0:
+                       base = OMAP2_MMC1_BASE;
+                       break;
+               case 1:
+                       base = OMAP2_MMC2_BASE;
+                       break;
+               case 2:
+                       base = OMAP3_MMC3_BASE;
+                       break;
+               }
+
+               dummy_pdev.id = i;
+               iclk = clk_get(dev, "mmchs_ick");
+               if (iclk && clk_enable(iclk))
+                       iclk = NULL;
+
+               fclk = clk_get(dev, "mmchs_fck");
+               if (fclk && clk_enable(fclk))
+                       fclk = NULL;
+
+               if (!iclk || !fclk) {
+                       printk(KERN_WARNING
+                              "%s: Unable to enable clocks for MMC%d, "
+                              "cannot reset.\n",  __func__, i);
+                       break;
+               }
+
+               omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
+               v = omap_readl(base + MMCHS_SYSSTATUS);
+               while (!(omap_readl(base + MMCHS_SYSSTATUS) &
+                        MMCHS_SYSSTATUS_RESETDONE))
+                       cpu_relax();
+
+               if (fclk) {
+                       clk_disable(fclk);
+                       clk_put(fclk);
+               }
+               if (iclk) {
+                       clk_disable(iclk);
+                       clk_put(iclk);
+               }
+       }
+}
+#else
+static inline void omap_hsmmc_reset(void) {}
+#endif
+
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+       defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+
+static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
+                       int controller_nr)
+{
+       if (cpu_is_omap2420() && controller_nr == 0) {
+               omap_cfg_reg(H18_24XX_MMC_CMD);
+               omap_cfg_reg(H15_24XX_MMC_CLKI);
+               omap_cfg_reg(G19_24XX_MMC_CLKO);
+               omap_cfg_reg(F20_24XX_MMC_DAT0);
+               omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
+               omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
+               if (mmc_controller->slots[0].wires == 4) {
+                       omap_cfg_reg(H14_24XX_MMC_DAT1);
+                       omap_cfg_reg(E19_24XX_MMC_DAT2);
+                       omap_cfg_reg(D19_24XX_MMC_DAT3);
+                       omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
+                       omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
+                       omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
+               }
+
+               /*
+                * Use internal loop-back in MMC/SDIO Module Input Clock
+                * selection
+                */
+               if (mmc_controller->slots[0].internal_clock) {
+                       u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+                       v |= (1 << 24);
+                       omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+               }
+       }
+}
+
+void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+                       int nr_controllers)
+{
+       int i;
+
+       for (i = 0; i < nr_controllers; i++) {
+               unsigned long base, size;
+               unsigned int irq = 0;
+
+               if (!mmc_data[i])
+                       continue;
+
+               omap2_mmc_mux(mmc_data[i], i);
+
+               switch (i) {
+               case 0:
+                       base = OMAP2_MMC1_BASE;
+                       irq = INT_24XX_MMC_IRQ;
+                       break;
+               case 1:
+                       base = OMAP2_MMC2_BASE;
+                       irq = INT_24XX_MMC2_IRQ;
+                       break;
+               case 2:
+                       if (!cpu_is_omap34xx())
+                               return;
+                       base = OMAP3_MMC3_BASE;
+                       irq = INT_34XX_MMC3_IRQ;
+                       break;
+               default:
+                       continue;
+               }
+
+               if (cpu_is_omap2420())
+                       size = OMAP2420_MMC_SIZE;
+               else
+                       size = HSMMC_SIZE;
+
+               omap_mmc_add(i, base, size, irq, mmc_data[i]);
+       };
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
 #define OMAP_HDQ_BASE  0x480B2000
@@ -334,6 +502,7 @@ static int __init omap2_init_devices(void)
        /* please keep these calls, and their implementations above,
         * in alphabetical order so they're easier to sort through.
         */
+       omap_hsmmc_reset();
        omap_init_mbox();
        omap_init_mcspi();
        omap_hdq_init();
diff --git a/arch/arm/mach-omap2/mmc-twl4030.c b/arch/arm/mach-omap2/mmc-twl4030.c
new file mode 100644 (file)
index 0000000..437f520
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * linux/arch/arm/mach-omap2/mmc-twl4030.c
+ *
+ * Copyright (C) 2007-2008 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * 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/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c/twl4030.h>
+
+#include <mach/hardware.h>
+#include <mach/control.h>
+#include <mach/mmc.h>
+#include <mach/board.h>
+
+#include "mmc-twl4030.h"
+
+#if defined(CONFIG_TWL4030_CORE) && \
+       (defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
+
+#define LDO_CLR                        0x00
+#define VSEL_S2_CLR            0x40
+
+#define VMMC1_DEV_GRP          0x27
+#define VMMC1_CLR              0x00
+#define VMMC1_315V             0x03
+#define VMMC1_300V             0x02
+#define VMMC1_285V             0x01
+#define VMMC1_185V             0x00
+#define VMMC1_DEDICATED                0x2A
+
+#define VMMC2_DEV_GRP          0x2B
+#define VMMC2_CLR              0x40
+#define VMMC2_315V             0x0c
+#define VMMC2_300V             0x0b
+#define VMMC2_285V             0x0a
+#define VMMC2_260V             0x08
+#define VMMC2_185V             0x06
+#define VMMC2_DEDICATED                0x2E
+
+#define VMMC_DEV_GRP_P1                0x20
+
+static u16 control_pbias_offset;
+static u16 control_devconf1_offset;
+
+#define HSMMC_NAME_LEN 9
+
+static struct twl_mmc_controller {
+       struct omap_mmc_platform_data   *mmc;
+       u8              twl_vmmc_dev_grp;
+       u8              twl_mmc_dedicated;
+       char            name[HSMMC_NAME_LEN];
+} hsmmc[] = {
+       {
+               .twl_vmmc_dev_grp               = VMMC1_DEV_GRP,
+               .twl_mmc_dedicated              = VMMC1_DEDICATED,
+       },
+       {
+               .twl_vmmc_dev_grp               = VMMC2_DEV_GRP,
+               .twl_mmc_dedicated              = VMMC2_DEDICATED,
+       },
+};
+
+static int twl_mmc_card_detect(int irq)
+{
+       unsigned i;
+
+       for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
+               struct omap_mmc_platform_data *mmc;
+
+               mmc = hsmmc[i].mmc;
+               if (!mmc)
+                       continue;
+               if (irq != mmc->slots[0].card_detect_irq)
+                       continue;
+
+               /* NOTE: assumes card detect signal is active-low */
+               return !gpio_get_value_cansleep(mmc->slots[0].switch_pin);
+       }
+       return -ENOSYS;
+}
+
+static int twl_mmc_get_ro(struct device *dev, int slot)
+{
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       /* NOTE: assumes write protect signal is active-high */
+       return gpio_get_value_cansleep(mmc->slots[0].gpio_wp);
+}
+
+/*
+ * MMC Slot Initialization.
+ */
+static int twl_mmc_late_init(struct device *dev)
+{
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+       int ret = 0;
+       int i;
+
+       ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
+       if (ret)
+               goto done;
+       ret = gpio_direction_input(mmc->slots[0].switch_pin);
+       if (ret)
+               goto err;
+
+       for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
+               if (hsmmc[i].name == mmc->slots[0].name) {
+                       hsmmc[i].mmc = mmc;
+                       break;
+               }
+       }
+
+       return 0;
+
+err:
+       gpio_free(mmc->slots[0].switch_pin);
+done:
+       mmc->slots[0].card_detect_irq = 0;
+       mmc->slots[0].card_detect = NULL;
+
+       dev_err(dev, "err %d configuring card detect\n", ret);
+       return ret;
+}
+
+static void twl_mmc_cleanup(struct device *dev)
+{
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       gpio_free(mmc->slots[0].switch_pin);
+}
+
+#ifdef CONFIG_PM
+
+static int twl_mmc_suspend(struct device *dev, int slot)
+{
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       disable_irq(mmc->slots[0].card_detect_irq);
+       return 0;
+}
+
+static int twl_mmc_resume(struct device *dev, int slot)
+{
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       enable_irq(mmc->slots[0].card_detect_irq);
+       return 0;
+}
+
+#else
+#define twl_mmc_suspend        NULL
+#define twl_mmc_resume NULL
+#endif
+
+/*
+ * Sets the MMC voltage in twl4030
+ */
+static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
+{
+       int ret;
+       u8 vmmc, dev_grp_val;
+
+       switch (1 << vdd) {
+       case MMC_VDD_35_36:
+       case MMC_VDD_34_35:
+       case MMC_VDD_33_34:
+       case MMC_VDD_32_33:
+       case MMC_VDD_31_32:
+       case MMC_VDD_30_31:
+               if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+                       vmmc = VMMC1_315V;
+               else
+                       vmmc = VMMC2_315V;
+               break;
+       case MMC_VDD_29_30:
+               if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+                       vmmc = VMMC1_315V;
+               else
+                       vmmc = VMMC2_300V;
+               break;
+       case MMC_VDD_27_28:
+       case MMC_VDD_26_27:
+               if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+                       vmmc = VMMC1_285V;
+               else
+                       vmmc = VMMC2_285V;
+               break;
+       case MMC_VDD_25_26:
+       case MMC_VDD_24_25:
+       case MMC_VDD_23_24:
+       case MMC_VDD_22_23:
+       case MMC_VDD_21_22:
+       case MMC_VDD_20_21:
+               if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+                       vmmc = VMMC1_285V;
+               else
+                       vmmc = VMMC2_260V;
+               break;
+       case MMC_VDD_165_195:
+               if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP)
+                       vmmc = VMMC1_185V;
+               else
+                       vmmc = VMMC2_185V;
+               break;
+       default:
+               vmmc = 0;
+               break;
+       }
+
+       if (vmmc)
+               dev_grp_val = VMMC_DEV_GRP_P1;  /* Power up */
+       else
+               dev_grp_val = LDO_CLR;          /* Power down */
+
+       ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                                       dev_grp_val, c->twl_vmmc_dev_grp);
+       if (ret)
+               return ret;
+
+       ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                                       vmmc, c->twl_mmc_dedicated);
+
+       return ret;
+}
+
+static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
+                               int vdd)
+{
+       u32 reg;
+       int ret = 0;
+       struct twl_mmc_controller *c = &hsmmc[0];
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       if (power_on) {
+               if (cpu_is_omap2430()) {
+                       reg = omap_ctrl_readl(OMAP243X_CONTROL_DEVCONF1);
+                       if ((1 << vdd) >= MMC_VDD_30_31)
+                               reg |= OMAP243X_MMC1_ACTIVE_OVERWRITE;
+                       else
+                               reg &= ~OMAP243X_MMC1_ACTIVE_OVERWRITE;
+                       omap_ctrl_writel(reg, OMAP243X_CONTROL_DEVCONF1);
+               }
+
+               if (mmc->slots[0].internal_clock) {
+                       reg = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+                       reg |= OMAP2_MMCSDIO1ADPCLKISEL;
+                       omap_ctrl_writel(reg, OMAP2_CONTROL_DEVCONF0);
+               }
+
+               reg = omap_ctrl_readl(control_pbias_offset);
+               reg |= OMAP2_PBIASSPEEDCTRL0;
+               reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+               omap_ctrl_writel(reg, control_pbias_offset);
+
+               ret = twl_mmc_set_voltage(c, vdd);
+
+               /* 100ms delay required for PBIAS configuration */
+               msleep(100);
+               reg = omap_ctrl_readl(control_pbias_offset);
+               reg |= (OMAP2_PBIASLITEPWRDNZ0 | OMAP2_PBIASSPEEDCTRL0);
+               if ((1 << vdd) <= MMC_VDD_165_195)
+                       reg &= ~OMAP2_PBIASLITEVMODE0;
+               else
+                       reg |= OMAP2_PBIASLITEVMODE0;
+               omap_ctrl_writel(reg, control_pbias_offset);
+       } else {
+               reg = omap_ctrl_readl(control_pbias_offset);
+               reg &= ~OMAP2_PBIASLITEPWRDNZ0;
+               omap_ctrl_writel(reg, control_pbias_offset);
+
+               ret = twl_mmc_set_voltage(c, 0);
+
+               /* 100ms delay required for PBIAS configuration */
+               msleep(100);
+               reg = omap_ctrl_readl(control_pbias_offset);
+               reg |= (OMAP2_PBIASSPEEDCTRL0 | OMAP2_PBIASLITEPWRDNZ0 |
+                       OMAP2_PBIASLITEVMODE0);
+               omap_ctrl_writel(reg, control_pbias_offset);
+       }
+
+       return ret;
+}
+
+static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd)
+{
+       int ret;
+       struct twl_mmc_controller *c = &hsmmc[1];
+       struct omap_mmc_platform_data *mmc = dev->platform_data;
+
+       if (power_on) {
+               if (mmc->slots[0].internal_clock) {
+                       u32 reg;
+
+                       reg = omap_ctrl_readl(control_devconf1_offset);
+                       reg |= OMAP2_MMCSDIO2ADPCLKISEL;
+                       omap_ctrl_writel(reg, control_devconf1_offset);
+               }
+               ret = twl_mmc_set_voltage(c, vdd);
+       } else {
+               ret = twl_mmc_set_voltage(c, 0);
+       }
+
+       return ret;
+}
+
+static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
+
+void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
+{
+       struct twl4030_hsmmc_info *c;
+       int nr_hsmmc = ARRAY_SIZE(hsmmc_data);
+
+       if (cpu_is_omap2430()) {
+               control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
+               control_devconf1_offset = OMAP243X_CONTROL_DEVCONF1;
+               nr_hsmmc = 2;
+       } else {
+               control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
+               control_devconf1_offset = OMAP343X_CONTROL_DEVCONF1;
+       }
+
+       for (c = controllers; c->mmc; c++) {
+               struct twl_mmc_controller *twl = hsmmc + c->mmc - 1;
+               struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1];
+
+               if (!c->mmc || c->mmc > nr_hsmmc) {
+                       pr_debug("MMC%d: no such controller\n", c->mmc);
+                       continue;
+               }
+               if (mmc) {
+                       pr_debug("MMC%d: already configured\n", c->mmc);
+                       continue;
+               }
+
+               mmc = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
+               if (!mmc) {
+                       pr_err("Cannot allocate memory for mmc device!\n");
+                       return;
+               }
+
+               sprintf(twl->name, "mmc%islot%i", c->mmc, 1);
+               mmc->slots[0].name = twl->name;
+               mmc->nr_slots = 1;
+               mmc->slots[0].ocr_mask = MMC_VDD_165_195 |
+                                       MMC_VDD_26_27 | MMC_VDD_27_28 |
+                                       MMC_VDD_29_30 |
+                                       MMC_VDD_30_31 | MMC_VDD_31_32;
+               mmc->slots[0].wires = c->wires;
+               mmc->slots[0].internal_clock = !c->ext_clock;
+               mmc->dma_mask = 0xffffffff;
+
+               /* note: twl4030 card detect GPIOs normally switch VMMCx ... */
+               if (gpio_is_valid(c->gpio_cd)) {
+                       mmc->init = twl_mmc_late_init;
+                       mmc->cleanup = twl_mmc_cleanup;
+                       mmc->suspend = twl_mmc_suspend;
+                       mmc->resume = twl_mmc_resume;
+
+                       mmc->slots[0].switch_pin = c->gpio_cd;
+                       mmc->slots[0].card_detect_irq = gpio_to_irq(c->gpio_cd);
+                       mmc->slots[0].card_detect = twl_mmc_card_detect;
+               } else
+                       mmc->slots[0].switch_pin = -EINVAL;
+
+               /* write protect normally uses an OMAP gpio */
+               if (gpio_is_valid(c->gpio_wp)) {
+                       gpio_request(c->gpio_wp, "mmc_wp");
+                       gpio_direction_input(c->gpio_wp);
+
+                       mmc->slots[0].gpio_wp = c->gpio_wp;
+                       mmc->slots[0].get_ro = twl_mmc_get_ro;
+               } else
+                       mmc->slots[0].gpio_wp = -EINVAL;
+
+               /* NOTE:  we assume OMAP's MMC1 and MMC2 use
+                * the TWL4030's VMMC1 and VMMC2, respectively;
+                * and that OMAP's MMC3 isn't used.
+                */
+
+               switch (c->mmc) {
+               case 1:
+                       mmc->slots[0].set_power = twl_mmc1_set_power;
+                       break;
+               case 2:
+                       mmc->slots[0].set_power = twl_mmc2_set_power;
+                       break;
+               default:
+                       pr_err("MMC%d configuration not supported!\n", c->mmc);
+                       continue;
+               }
+               hsmmc_data[c->mmc - 1] = mmc;
+       }
+
+       omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC);
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/mmc-twl4030.h b/arch/arm/mach-omap2/mmc-twl4030.h
new file mode 100644 (file)
index 0000000..e1c8076
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * MMC definitions for OMAP2
+ *
+ * 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.
+ */
+
+struct twl4030_hsmmc_info {
+       u8      mmc;            /* controller 1/2/3 */
+       u8      wires;          /* 1/4/8 wires */
+       int     gpio_cd;        /* or -EINVAL */
+       int     gpio_wp;        /* or -EINVAL */
+       int     ext_clock:1;    /* use external pin for input clock */
+};
+
+#if    defined(CONFIG_TWL4030_CORE) && \
+       (defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+        defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
+
+void twl4030_mmc_init(struct twl4030_hsmmc_info *);
+
+#else
+
+static inline void twl4030_mmc_init(struct twl4030_hsmmc_info *info)
+{
+}
+
+#endif
index 0cb2b22388e93454a7fe78b69e465fee6a519379..ac15c23fd5da840e5816e6223b3456d60b24c0c6 100644 (file)
@@ -192,202 +192,48 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
 
 /*-------------------------------------------------------------------------*/
 
-#if    defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
        defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
-#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-#define        OMAP_MMC1_BASE          0x4809c000
-#define        OMAP_MMC1_END           (OMAP_MMC1_BASE + 0x1fc)
-#define        OMAP_MMC1_INT           INT_24XX_MMC_IRQ
+#define OMAP_MMC_NR_RES                2
 
-#define        OMAP_MMC2_BASE          0x480b4000
-#define        OMAP_MMC2_END           (OMAP_MMC2_BASE + 0x1fc)
-#define        OMAP_MMC2_INT           INT_24XX_MMC2_IRQ
-
-#else
-
-#define        OMAP_MMC1_BASE          0xfffb7800
-#define        OMAP_MMC1_END           (OMAP_MMC1_BASE + 0x7f)
-#define OMAP_MMC1_INT          INT_MMC
-
-#define        OMAP_MMC2_BASE          0xfffb7c00      /* omap16xx only */
-#define        OMAP_MMC2_END           (OMAP_MMC2_BASE + 0x7f)
-#define        OMAP_MMC2_INT           INT_1610_MMC2
-
-#endif
-
-static struct omap_mmc_platform_data mmc1_data;
-
-static u64 mmc1_dmamask = 0xffffffff;
-
-static struct resource mmc1_resources[] = {
-       {
-               .start          = OMAP_MMC1_BASE,
-               .end            = OMAP_MMC1_END,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = OMAP_MMC1_INT,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device mmc_omap_device1 = {
-       .name           = "mmci-omap",
-       .id             = 1,
-       .dev = {
-               .dma_mask       = &mmc1_dmamask,
-               .platform_data  = &mmc1_data,
-       },
-       .num_resources  = ARRAY_SIZE(mmc1_resources),
-       .resource       = mmc1_resources,
-};
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
-       defined(CONFIG_ARCH_OMAP34XX)
-
-static struct omap_mmc_platform_data mmc2_data;
-
-static u64 mmc2_dmamask = 0xffffffff;
-
-static struct resource mmc2_resources[] = {
-       {
-               .start          = OMAP_MMC2_BASE,
-               .end            = OMAP_MMC2_END,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = OMAP_MMC2_INT,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device mmc_omap_device2 = {
-       .name           = "mmci-omap",
-       .id             = 2,
-       .dev = {
-               .dma_mask       = &mmc2_dmamask,
-               .platform_data  = &mmc2_data,
-       },
-       .num_resources  = ARRAY_SIZE(mmc2_resources),
-       .resource       = mmc2_resources,
-};
-#endif
-
-static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
-{
-       if (cpu_is_omap2430() || cpu_is_omap34xx())
-               return;
-
-       if (mmc_conf->mmc[0].enabled) {
-               if (cpu_is_omap24xx()) {
-                       omap_cfg_reg(H18_24XX_MMC_CMD);
-                       omap_cfg_reg(H15_24XX_MMC_CLKI);
-                       omap_cfg_reg(G19_24XX_MMC_CLKO);
-                       omap_cfg_reg(F20_24XX_MMC_DAT0);
-                       omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
-                       omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
-               } else {
-                       omap_cfg_reg(MMC_CMD);
-                       omap_cfg_reg(MMC_CLK);
-                       omap_cfg_reg(MMC_DAT0);
-                       if (cpu_is_omap1710()) {
-                               omap_cfg_reg(M15_1710_MMC_CLKI);
-                               omap_cfg_reg(P19_1710_MMC_CMDDIR);
-                               omap_cfg_reg(P20_1710_MMC_DATDIR0);
-                       }
-               }
-               if (mmc_conf->mmc[0].wire4) {
-                       if (cpu_is_omap24xx()) {
-                               omap_cfg_reg(H14_24XX_MMC_DAT1);
-                               omap_cfg_reg(E19_24XX_MMC_DAT2);
-                               omap_cfg_reg(D19_24XX_MMC_DAT3);
-                               omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
-                               omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
-                               omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
-                       } else {
-                               omap_cfg_reg(MMC_DAT1);
-                               /* NOTE:  DAT2 can be on W10 (here) or M15 */
-                               if (!mmc_conf->mmc[0].nomux)
-                                       omap_cfg_reg(MMC_DAT2);
-                               omap_cfg_reg(MMC_DAT3);
-                       }
-               }
-       }
-
-#ifdef CONFIG_ARCH_OMAP16XX
-       /* block 2 is on newer chips, and has many pinout options */
-       if (mmc_conf->mmc[1].enabled) {
-               if (!mmc_conf->mmc[1].nomux) {
-                       omap_cfg_reg(Y8_1610_MMC2_CMD);
-                       omap_cfg_reg(Y10_1610_MMC2_CLK);
-                       omap_cfg_reg(R18_1610_MMC2_CLKIN);
-                       omap_cfg_reg(W8_1610_MMC2_DAT0);
-                       if (mmc_conf->mmc[1].wire4) {
-                               omap_cfg_reg(V8_1610_MMC2_DAT1);
-                               omap_cfg_reg(W15_1610_MMC2_DAT2);
-                               omap_cfg_reg(R10_1610_MMC2_DAT3);
-                       }
-
-                       /* These are needed for the level shifter */
-                       omap_cfg_reg(V9_1610_MMC2_CMDDIR);
-                       omap_cfg_reg(V5_1610_MMC2_DATDIR0);
-                       omap_cfg_reg(W19_1610_MMC2_DATDIR1);
-               }
-
-               /* Feedback clock must be set on OMAP-1710 MMC2 */
-               if (cpu_is_omap1710())
-                       omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
-                                    MOD_CONF_CTRL_1);
-       }
-#endif
-}
-
-static void __init omap_init_mmc(void)
+/*
+ * Register MMC devices. Called from mach-omap1 and mach-omap2 device init.
+ */
+int __init omap_mmc_add(int id, unsigned long base, unsigned long size,
+               unsigned int irq, struct omap_mmc_platform_data *data)
 {
-       const struct omap_mmc_config    *mmc_conf;
-
-       /* NOTE:  assumes MMC was never (wrongly) enabled */
-       mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
-       if (!mmc_conf)
-               return;
-
-       omap_init_mmc_conf(mmc_conf);
-
-       if (mmc_conf->mmc[0].enabled) {
-               mmc1_data.conf = mmc_conf->mmc[0];
-               (void) platform_device_register(&mmc_omap_device1);
-       }
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
-       defined(CONFIG_ARCH_OMAP34XX)
-       if (mmc_conf->mmc[1].enabled) {
-               mmc2_data.conf = mmc_conf->mmc[1];
-               (void) platform_device_register(&mmc_omap_device2);
-       }
-#endif
-}
+       struct platform_device *pdev;
+       struct resource res[OMAP_MMC_NR_RES];
+       int ret;
+
+       pdev = platform_device_alloc("mmci-omap", id);
+       if (!pdev)
+               return -ENOMEM;
+
+       memset(res, 0, OMAP_MMC_NR_RES * sizeof(struct resource));
+       res[0].start = base;
+       res[0].end = base + size - 1;
+       res[0].flags = IORESOURCE_MEM;
+       res[1].start = res[1].end = irq;
+       res[1].flags = IORESOURCE_IRQ;
+
+       ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+       if (ret == 0)
+               ret = platform_device_add_data(pdev, data, sizeof(*data));
+       if (ret)
+               goto fail;
+
+       ret = platform_device_add(pdev);
+       if (ret)
+               goto fail;
+       return 0;
 
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
-{
-       switch (host) {
-       case 1:
-               mmc1_data = *info;
-               break;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
-       defined(CONFIG_ARCH_OMAP34XX)
-       case 2:
-               mmc2_data = *info;
-               break;
-#endif
-       default:
-               BUG();
-       }
+fail:
+       platform_device_put(pdev);
+       return ret;
 }
 
-#else
-static inline void omap_init_mmc(void) {}
-void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -532,7 +378,6 @@ static int __init omap_init_devices(void)
         */
        omap_init_dsp();
        omap_init_kp();
-       omap_init_mmc();
        omap_init_uwire();
        omap_init_wdt();
        omap_init_rng();
index 2a050e9be65f9089612eaadef6446831e891b293..15531c8dc0e63bf3110503da7b43905f723bf29f 100644 (file)
 #ifndef __ASM_ARCH_OMAP_H2_H
 #define __ASM_ARCH_OMAP_H2_H
 
-/* Placeholder for H2 specific defines */
-
 /* At OMAP1610 Innovator the Ethernet is directly connected to CS1 */
 #define OMAP1610_ETHR_START            0x04000300
 
+#define H2_TPS_GPIO_BASE               (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */)
+#      define H2_TPS_GPIO_MMC_PWR_EN   (H2_TPS_GPIO_BASE + 3)
+
 extern void h2_mmc_init(void);
-extern void h2_mmc_slot_cover_handler(void *arg, int state);
 
 #endif /*  __ASM_ARCH_OMAP_H2_H */
 
index c23c12ccb3532c912285a70ef012dd6b030ff5b1..9466772fc7c88c11fabaa42a4025efa1fef704c6 100644 (file)
@@ -16,7 +16,6 @@
 
 /* Different peripheral ids */
 #define OMAP_TAG_CLOCK         0x4f01
-#define OMAP_TAG_MMC           0x4f02
 #define OMAP_TAG_SERIAL_CONSOLE 0x4f03
 #define OMAP_TAG_USB           0x4f04
 #define OMAP_TAG_LCD           0x4f05
@@ -35,27 +34,6 @@ struct omap_clock_config {
        u8 system_clock_type;
 };
 
-struct omap_mmc_conf {
-       unsigned enabled:1;
-       /* nomux means "standard" muxing is wrong on this board, and that
-        * board-specific code handled it before common init logic.
-        */
-       unsigned nomux:1;
-       /* switch pin can be for card detect (default) or card cover */
-       unsigned cover:1;
-       /* 4 wire signaling is optional, and is only used for SD/SDIO */
-       unsigned wire4:1;
-       /* use the internal clock */
-       unsigned internal_clock:1;
-       s16 power_pin;
-       s16 switch_pin;
-       s16 wp_pin;
-};
-
-struct omap_mmc_config {
-       struct omap_mmc_conf mmc[2];
-};
-
 struct omap_serial_console_config {
        u8 console_uart;
        u32 console_speed;
index dc9886760577b4be3510571863f38cf03ba0e04c..269147f3836f50985809c3ab5b9a3f81a944e2f4 100644 (file)
@@ -74,6 +74,7 @@
 #define OMAP243X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
 #define OMAP243X_CONTROL_IVA2_BOOTMOD  (OMAP2_CONTROL_GENERAL + 0x0194)
 #define OMAP243X_CONTROL_IVA2_GEMCFG   (OMAP2_CONTROL_GENERAL + 0x0198)
+#define OMAP243X_CONTROL_PBIAS_LITE    (OMAP2_CONTROL_GENERAL + 0x0230)
 
 /* 24xx-only CONTROL_GENERAL register offsets */
 #define OMAP24XX_CONTROL_DEBOBS                (OMAP2_CONTROL_GENERAL + 0x0000)
 #define OMAP343X_CONTROL_TEST_KEY_13   (OMAP2_CONTROL_GENERAL + 0x00fc)
 #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
 #define OMAP343X_CONTROL_IVA2_BOOTMOD  (OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP343X_CONTROL_PBIAS_LITE    (OMAP2_CONTROL_GENERAL + 0x02b0)
 #define OMAP343X_CONTROL_TEMP_SENSOR   (OMAP2_CONTROL_GENERAL + 0x02b4)
 
 /*
  * and the security mode (secure, non-secure, don't care)
  */
 /* CONTROL_DEVCONF0 bits */
+#define OMAP2_MMCSDIO1ADPCLKISEL       (1 << 24) /* MMC1 loop back clock */
 #define OMAP24XX_USBSTANDBYCTRL                (1 << 15)
 #define OMAP2_MCBSP2_CLKS_MASK         (1 << 6)
 #define OMAP2_MCBSP1_CLKS_MASK         (1 << 2)
 
 /* CONTROL_DEVCONF1 bits */
+#define OMAP243X_MMC1_ACTIVE_OVERWRITE (1 << 31)
+#define OMAP2_MMCSDIO2ADPCLKISEL       (1 << 6) /* MMC2 loop back clock */
 #define OMAP2_MCBSP5_CLKS_MASK         (1 << 4) /* > 242x */
 #define OMAP2_MCBSP4_CLKS_MASK         (1 << 2) /* > 242x */
 #define OMAP2_MCBSP3_CLKS_MASK         (1 << 0) /* > 242x */
 #define OMAP2_SYSBOOT_1_MASK           (1 << 1)
 #define OMAP2_SYSBOOT_0_MASK           (1 << 0)
 
+/* CONTROL_PBIAS_LITE bits */
+#define OMAP343X_PBIASLITESUPPLY_HIGH1 (1 << 15)
+#define OMAP343X_PBIASLITEVMODEERROR1  (1 << 11)
+#define OMAP343X_PBIASSPEEDCTRL1       (1 << 10)
+#define OMAP343X_PBIASLITEPWRDNZ1      (1 << 9)
+#define OMAP343X_PBIASLITEVMODE1       (1 << 8)
+#define OMAP343X_PBIASLITESUPPLY_HIGH0 (1 << 7)
+#define OMAP343X_PBIASLITEVMODEERROR0  (1 << 3)
+#define OMAP2_PBIASSPEEDCTRL0          (1 << 2)
+#define OMAP2_PBIASLITEPWRDNZ0         (1 << 1)
+#define OMAP2_PBIASLITEVMODE0          (1 << 0)
+
 #ifndef __ASSEMBLY__
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
 extern void __iomem *omap_ctrl_base_get(void);
index fc15d13058fc74e5116490b4e704be355dd7b576..031250f028050b4e95bb805194ba36484b6e4229 100644 (file)
 
 #include <mach/board.h>
 
+#define OMAP15XX_NR_MMC                1
+#define OMAP16XX_NR_MMC                2
+#define OMAP1_MMC_SIZE         0x080
+#define OMAP1_MMC1_BASE                0xfffb7800
+#define OMAP1_MMC2_BASE                0xfffb7c00      /* omap16xx only */
+
+#define OMAP24XX_NR_MMC                2
+#define OMAP34XX_NR_MMC                3
+#define OMAP2420_MMC_SIZE      OMAP1_MMC_SIZE
+#define HSMMC_SIZE             0x200
+#define OMAP2_MMC1_BASE                0x4809c000
+#define OMAP2_MMC2_BASE                0x480b4000
+#define OMAP3_MMC3_BASE                0x480ad000
+#define HSMMC3                 (1 << 2)
+#define HSMMC2                 (1 << 1)
+#define HSMMC1                 (1 << 0)
+
 #define OMAP_MMC_MAX_SLOTS     2
 
 struct omap_mmc_platform_data {
-       struct omap_mmc_conf    conf;
 
-       /* number of slots on board */
+       /* number of slots per controller */
        unsigned nr_slots:2;
 
        /* set if your board has components or wiring that limits the
@@ -41,7 +57,31 @@ struct omap_mmc_platform_data {
        int (*suspend)(struct device *dev, int slot);
        int (*resume)(struct device *dev, int slot);
 
+       u64 dma_mask;
+
        struct omap_mmc_slot_data {
+
+               /* 4 wire signaling is optional, and is used for SD/SDIO/HSMMC;
+                * 8 wire signaling is also optional, and is used with HSMMC
+                */
+               u8 wires;
+
+               /*
+                * nomux means "standard" muxing is wrong on this board, and
+                * that board-specific code handled it before common init logic.
+                */
+               unsigned nomux:1;
+
+               /* switch pin can be for card detect (default) or card cover */
+               unsigned cover:1;
+
+               /* use the internal clock */
+               unsigned internal_clock:1;
+               s16 power_pin;
+
+               int switch_pin;                 /* gpio (card detect) */
+               int gpio_wp;                    /* gpio (write protect) */
+
                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);
                int (* get_ro)(struct device *dev, int slot);
@@ -49,8 +89,8 @@ struct omap_mmc_platform_data {
                /* return MMC cover switch state, can be NULL if not supported.
                 *
                 * possible return values:
-                *   0 - open
-                *   1 - closed
+                *   0 - closed
+                *   1 - open
                 */
                int (* get_cover_state)(struct device *dev, int slot);
 
@@ -66,9 +106,31 @@ struct omap_mmc_platform_data {
        } slots[OMAP_MMC_MAX_SLOTS];
 };
 
-extern void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info);
-
 /* called from board-specific card detection service routine */
 extern void omap_mmc_notify_cover_event(struct device *dev, int slot, int is_closed);
 
+#if    defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+       defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
+void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+                               int nr_controllers);
+void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+                               int nr_controllers);
+int omap_mmc_add(int id, unsigned long base, unsigned long size,
+                       unsigned int irq, struct omap_mmc_platform_data *data);
+#else
+static inline void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data,
+                               int nr_controllers)
+{
+}
+static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
+                               int nr_controllers)
+{
+}
+static inline int omap_mmc_add(int id, unsigned long base, unsigned long size,
+               unsigned int irq, struct omap_mmc_platform_data *data)
+{
+       return 0;
+}
+
+#endif
 #endif
index 1b9fc3c6b8752240c591aa23ed6a7d0f13bbea44..67d7b7fef084f1a064d4f7834a37af0059c96f99 100644 (file)
@@ -1015,7 +1015,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data
        }
 
        if (is_read) {
-               if (host->id == 1) {
+               if (host->id == 0) {
                        sync_dev = OMAP_DMA_MMC_RX;
                        dma_dev_name = "MMC1 read";
                } else {
@@ -1023,7 +1023,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host *host, struct mmc_data
                        dma_dev_name = "MMC2 read";
                }
        } else {
-               if (host->id == 1) {
+               if (host->id == 0) {
                        sync_dev = OMAP_DMA_MMC_TX;
                        dma_dev_name = "MMC1 write";
                } else {
@@ -1317,7 +1317,7 @@ static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id)
        host->slots[id] = slot;
 
        mmc->caps = 0;
-       if (host->pdata->conf.wire4)
+       if (host->pdata->slots[id].wires >= 4)
                mmc->caps |= MMC_CAP_4_BIT_DATA;
 
        mmc->ops = &mmc_omap_ops;
@@ -1451,6 +1451,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
        host->irq = irq;
 
        host->use_dma = 1;
+       host->dev->dma_mask = &pdata->dma_mask;
        host->dma_ch = -1;
 
        host->irq = irq;