Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
[safe/jmp/linux-2.6] / arch / arm / mach-omap2 / board-omap3evm.c
index e0cac96..b952610 100644 (file)
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/leds.h>
+#include <linux/interrupt.h>
 
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/usb/otg.h>
+#include <linux/smsc911x.h>
+
+#include <linux/regulator/machine.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
 #include <plat/board.h>
-#include <plat/mux.h>
 #include <plat/usb.h>
 #include <plat/common.h>
 #include <plat/mcspi.h>
+#include <plat/display.h>
 
+#include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
-#include "mmc-twl4030.h"
+#include "hsmmc.h"
 
 #define OMAP3_EVM_TS_GPIO      175
+#define OMAP3_EVM_EHCI_VBUS    22
+#define OMAP3_EVM_EHCI_SELECT  61
 
 #define OMAP3EVM_ETHR_START    0x2c000000
 #define OMAP3EVM_ETHR_SIZE     1024
+#define OMAP3EVM_ETHR_ID_REV   0x50
 #define OMAP3EVM_ETHR_GPIO_IRQ 176
-#define OMAP3EVM_SMC911X_CS    5
+#define OMAP3EVM_SMSC911X_CS   5
+
+static u8 omap3_evm_version;
+
+u8 get_omap3_evm_rev(void)
+{
+       return omap3_evm_version;
+}
+EXPORT_SYMBOL(get_omap3_evm_rev);
 
-static struct resource omap3evm_smc911x_resources[] = {
+static void __init omap3_evm_get_revision(void)
+{
+       void __iomem *ioaddr;
+       unsigned int smsc_id;
+
+       /* Ethernet PHY ID is stored at ID_REV register */
+       ioaddr = ioremap_nocache(OMAP3EVM_ETHR_START, SZ_1K);
+       if (!ioaddr)
+               return;
+       smsc_id = readl(ioaddr + OMAP3EVM_ETHR_ID_REV) & 0xFFFF0000;
+       iounmap(ioaddr);
+
+       switch (smsc_id) {
+       /*SMSC9115 chipset*/
+       case 0x01150000:
+               omap3_evm_version = OMAP3EVM_BOARD_GEN_1;
+               break;
+       /*SMSC 9220 chipset*/
+       case 0x92200000:
+       default:
+               omap3_evm_version = OMAP3EVM_BOARD_GEN_2;
+       }
+}
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource omap3evm_smsc911x_resources[] = {
        [0] =   {
                .start  = OMAP3EVM_ETHR_START,
                .end    = (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1),
@@ -58,24 +99,34 @@ static struct resource omap3evm_smc911x_resources[] = {
        [1] =   {
                .start  = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
                .end    = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
-               .flags  = IORESOURCE_IRQ,
+               .flags  = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
        },
 };
 
-static struct platform_device omap3evm_smc911x_device = {
-       .name           = "smc911x",
+static struct smsc911x_platform_config smsc911x_config = {
+       .phy_interface  = PHY_INTERFACE_MODE_MII,
+       .irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+       .irq_type       = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+       .flags          = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
+};
+
+static struct platform_device omap3evm_smsc911x_device = {
+       .name           = "smsc911x",
        .id             = -1,
-       .num_resources  = ARRAY_SIZE(omap3evm_smc911x_resources),
-       .resource       = &omap3evm_smc911x_resources[0],
+       .num_resources  = ARRAY_SIZE(omap3evm_smsc911x_resources),
+       .resource       = &omap3evm_smsc911x_resources[0],
+       .dev            = {
+               .platform_data = &smsc911x_config,
+       },
 };
 
-static inline void __init omap3evm_init_smc911x(void)
+static inline void __init omap3evm_init_smsc911x(void)
 {
        int eth_cs;
        struct clk *l3ck;
        unsigned int rate;
 
-       eth_cs = OMAP3EVM_SMC911X_CS;
+       eth_cs = OMAP3EVM_SMSC911X_CS;
 
        l3ck = clk_get(NULL, "l3_ck");
        if (IS_ERR(l3ck))
@@ -83,16 +134,240 @@ static inline void __init omap3evm_init_smc911x(void)
        else
                rate = clk_get_rate(l3ck);
 
-       if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMC911x irq") < 0) {
-               printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
+       if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) {
+               printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
                        OMAP3EVM_ETHR_GPIO_IRQ);
                return;
        }
 
        gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
+       platform_device_register(&omap3evm_smsc911x_device);
+}
+
+#else
+static inline void __init omap3evm_init_smsc911x(void) { return; }
+#endif
+
+/*
+ * OMAP3EVM LCD Panel control signals
+ */
+#define OMAP3EVM_LCD_PANEL_LR          2
+#define OMAP3EVM_LCD_PANEL_UD          3
+#define OMAP3EVM_LCD_PANEL_INI         152
+#define OMAP3EVM_LCD_PANEL_ENVDD       153
+#define OMAP3EVM_LCD_PANEL_QVGA                154
+#define OMAP3EVM_LCD_PANEL_RESB                155
+#define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO        210
+#define OMAP3EVM_DVI_PANEL_EN_GPIO     199
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_evm_display_init(void)
+{
+       int r;
+
+       r = gpio_request(OMAP3EVM_LCD_PANEL_RESB, "lcd_panel_resb");
+       if (r) {
+               printk(KERN_ERR "failed to get lcd_panel_resb\n");
+               return;
+       }
+       gpio_direction_output(OMAP3EVM_LCD_PANEL_RESB, 1);
+
+       r = gpio_request(OMAP3EVM_LCD_PANEL_INI, "lcd_panel_ini");
+       if (r) {
+               printk(KERN_ERR "failed to get lcd_panel_ini\n");
+               goto err_1;
+       }
+       gpio_direction_output(OMAP3EVM_LCD_PANEL_INI, 1);
+
+       r = gpio_request(OMAP3EVM_LCD_PANEL_QVGA, "lcd_panel_qvga");
+       if (r) {
+               printk(KERN_ERR "failed to get lcd_panel_qvga\n");
+               goto err_2;
+       }
+       gpio_direction_output(OMAP3EVM_LCD_PANEL_QVGA, 0);
+
+       r = gpio_request(OMAP3EVM_LCD_PANEL_LR, "lcd_panel_lr");
+       if (r) {
+               printk(KERN_ERR "failed to get lcd_panel_lr\n");
+               goto err_3;
+       }
+       gpio_direction_output(OMAP3EVM_LCD_PANEL_LR, 1);
+
+       r = gpio_request(OMAP3EVM_LCD_PANEL_UD, "lcd_panel_ud");
+       if (r) {
+               printk(KERN_ERR "failed to get lcd_panel_ud\n");
+               goto err_4;
+       }
+       gpio_direction_output(OMAP3EVM_LCD_PANEL_UD, 1);
+
+       r = gpio_request(OMAP3EVM_LCD_PANEL_ENVDD, "lcd_panel_envdd");
+       if (r) {
+               printk(KERN_ERR "failed to get lcd_panel_envdd\n");
+               goto err_5;
+       }
+       gpio_direction_output(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+
+       return;
+
+err_5:
+       gpio_free(OMAP3EVM_LCD_PANEL_UD);
+err_4:
+       gpio_free(OMAP3EVM_LCD_PANEL_LR);
+err_3:
+       gpio_free(OMAP3EVM_LCD_PANEL_QVGA);
+err_2:
+       gpio_free(OMAP3EVM_LCD_PANEL_INI);
+err_1:
+       gpio_free(OMAP3EVM_LCD_PANEL_RESB);
+
+}
+
+static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
+{
+       if (dvi_enabled) {
+               printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+               return -EINVAL;
+       }
+       gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0);
+
+       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+               gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+       else
+               gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+
+       lcd_enabled = 1;
+       return 0;
+}
+
+static void omap3_evm_disable_lcd(struct omap_dss_device *dssdev)
+{
+       gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1);
+
+       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
+               gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1);
+       else
+               gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0);
+
+       lcd_enabled = 0;
+}
+
+static struct omap_dss_device omap3_evm_lcd_device = {
+       .name                   = "lcd",
+       .driver_name            = "sharp_ls_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 18,
+       .platform_enable        = omap3_evm_enable_lcd,
+       .platform_disable       = omap3_evm_disable_lcd,
+};
+
+static int omap3_evm_enable_tv(struct omap_dss_device *dssdev)
+{
+       return 0;
+}
+
+static void omap3_evm_disable_tv(struct omap_dss_device *dssdev)
+{
+}
+
+static struct omap_dss_device omap3_evm_tv_device = {
+       .name                   = "tv",
+       .driver_name            = "venc",
+       .type                   = OMAP_DISPLAY_TYPE_VENC,
+       .phy.venc.type          = OMAP_DSS_VENC_TYPE_SVIDEO,
+       .platform_enable        = omap3_evm_enable_tv,
+       .platform_disable       = omap3_evm_disable_tv,
+};
+
+static int omap3_evm_enable_dvi(struct omap_dss_device *dssdev)
+{
+       if (lcd_enabled) {
+               printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+               return -EINVAL;
+       }
+
+       gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 1);
+
+       dvi_enabled = 1;
+       return 0;
 }
 
-static struct twl4030_hsmmc_info mmc[] = {
+static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev)
+{
+       gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 0);
+
+       dvi_enabled = 0;
+}
+
+static struct omap_dss_device omap3_evm_dvi_device = {
+       .name                   = "dvi",
+       .driver_name            = "generic_panel",
+       .type                   = OMAP_DISPLAY_TYPE_DPI,
+       .phy.dpi.data_lines     = 24,
+       .platform_enable        = omap3_evm_enable_dvi,
+       .platform_disable       = omap3_evm_disable_dvi,
+};
+
+static struct omap_dss_device *omap3_evm_dss_devices[] = {
+       &omap3_evm_lcd_device,
+       &omap3_evm_tv_device,
+       &omap3_evm_dvi_device,
+};
+
+static struct omap_dss_board_info omap3_evm_dss_data = {
+       .num_devices    = ARRAY_SIZE(omap3_evm_dss_devices),
+       .devices        = omap3_evm_dss_devices,
+       .default_device = &omap3_evm_lcd_device,
+};
+
+static struct platform_device omap3_evm_dss_device = {
+       .name           = "omapdss",
+       .id             = -1,
+       .dev            = {
+               .platform_data = &omap3_evm_dss_data,
+       },
+};
+
+static struct regulator_consumer_supply omap3evm_vmmc1_supply = {
+       .supply                 = "vmmc",
+};
+
+static struct regulator_consumer_supply omap3evm_vsim_supply = {
+       .supply                 = "vmmc_aux",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data omap3evm_vmmc1 = {
+       .constraints = {
+               .min_uV                 = 1850000,
+               .max_uV                 = 3150000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &omap3evm_vmmc1_supply,
+};
+
+/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
+static struct regulator_init_data omap3evm_vsim = {
+       .constraints = {
+               .min_uV                 = 1800000,
+               .max_uV                 = 3000000,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_VOLTAGE
+                                       | REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &omap3evm_vsim_supply,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
                .wires          = 4,
@@ -130,15 +405,27 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
                unsigned gpio, unsigned ngpio)
 {
        /* gpio + 0 is "mmc0_cd" (input/IRQ) */
-       omap_cfg_reg(L8_34XX_GPIO63);
+       omap_mux_init_gpio(63, OMAP_PIN_INPUT);
        mmc[0].gpio_cd = gpio + 0;
-       twl4030_mmc_init(mmc);
+       omap2_hsmmc_init(mmc);
+
+       /* link regulators to MMC adapters */
+       omap3evm_vmmc1_supply.dev = mmc[0].dev;
+       omap3evm_vsim_supply.dev = mmc[0].dev;
 
        /*
         * Most GPIOs are for USB OTG.  Some are mostly sent to
         * the P2 connector; notably LEDA for the LCD backlight.
         */
 
+       /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
+       gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL");
+       gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+
+       /* gpio + 7 == DVI Enable */
+       gpio_request(gpio + 7, "EN_DVI");
+       gpio_direction_output(gpio + 7, 0);
+
        /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
        gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
 
@@ -161,20 +448,23 @@ static struct twl4030_usb_data omap3evm_usb_data = {
 
 static int board_keymap[] = {
        KEY(0, 0, KEY_LEFT),
-       KEY(0, 1, KEY_RIGHT),
-       KEY(0, 2, KEY_A),
-       KEY(0, 3, KEY_B),
-       KEY(1, 0, KEY_DOWN),
+       KEY(0, 1, KEY_DOWN),
+       KEY(0, 2, KEY_ENTER),
+       KEY(0, 3, KEY_M),
+
+       KEY(1, 0, KEY_RIGHT),
        KEY(1, 1, KEY_UP),
-       KEY(1, 2, KEY_E),
-       KEY(1, 3, KEY_F),
-       KEY(2, 0, KEY_ENTER),
-       KEY(2, 1, KEY_I),
+       KEY(1, 2, KEY_I),
+       KEY(1, 3, KEY_N),
+
+       KEY(2, 0, KEY_A),
+       KEY(2, 1, KEY_E),
        KEY(2, 2, KEY_J),
-       KEY(2, 3, KEY_K),
-       KEY(3, 0, KEY_M),
-       KEY(3, 1, KEY_N),
-       KEY(3, 2, KEY_O),
+       KEY(2, 3, KEY_O),
+
+       KEY(3, 0, KEY_B),
+       KEY(3, 1, KEY_F),
+       KEY(3, 2, KEY_K),
        KEY(3, 3, KEY_P)
 };
 
@@ -203,6 +493,47 @@ static struct twl4030_codec_data omap3evm_codec_data = {
        .audio = &omap3evm_audio_data,
 };
 
+static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = {
+       .supply         = "vdda_dac",
+       .dev            = &omap3_evm_dss_device.dev,
+};
+
+/* VDAC for DSS driving S-Video */
+static struct regulator_init_data omap3_evm_vdac = {
+       .constraints = {
+               .min_uV                 = 1800000,
+               .max_uV                 = 1800000,
+               .apply_uV               = true,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &omap3_evm_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_consumer_supply omap3_evm_vpll2_supply = {
+       .supply         = "vdvi",
+       .dev            = &omap3_evm_lcd_device.dev,
+};
+
+static struct regulator_init_data omap3_evm_vpll2 = {
+       .constraints = {
+               .name                   = "VDVI",
+               .min_uV                 = 1800000,
+               .max_uV                 = 1800000,
+               .apply_uV               = true,
+               .valid_modes_mask       = REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+               .valid_ops_mask         = REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &omap3_evm_vpll2_supply,
+};
+
 static struct twl4030_platform_data omap3evm_twldata = {
        .irq_base       = TWL4030_IRQ_BASE,
        .irq_end        = TWL4030_IRQ_END,
@@ -213,6 +544,8 @@ static struct twl4030_platform_data omap3evm_twldata = {
        .usb            = &omap3evm_usb_data,
        .gpio           = &omap3evm_gpio_data,
        .codec          = &omap3evm_codec_data,
+       .vdac           = &omap3_evm_vdac,
+       .vpll2          = &omap3_evm_vpll2,
 };
 
 static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
@@ -226,6 +559,13 @@ static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
 
 static int __init omap3_evm_i2c_init(void)
 {
+       /*
+        * REVISIT: These entries can be set in omap3evm_twl_data
+        * after a merge with MFD tree
+        */
+       omap3evm_twldata.vmmc1 = &omap3evm_vmmc1;
+       omap3evm_twldata.vsim = &omap3evm_vsim;
+
        omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
                        ARRAY_SIZE(omap3evm_i2c_boardinfo));
        omap_register_i2c_bus(2, 400, NULL, 0);
@@ -233,24 +573,13 @@ static int __init omap3_evm_i2c_init(void)
        return 0;
 }
 
-static struct platform_device omap3_evm_lcd_device = {
-       .name           = "omap3evm_lcd",
-       .id             = -1,
-};
-
-static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
-       .ctrl_name      = "internal",
-};
-
 static void ads7846_dev_init(void)
 {
        if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
                printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
 
        gpio_direction_input(OMAP3_EVM_TS_GPIO);
-
-       omap_set_gpio_debounce(OMAP3_EVM_TS_GPIO, 1);
-       omap_set_gpio_debounce_time(OMAP3_EVM_TS_GPIO, 0xa);
+       gpio_set_debounce(OMAP3_EVM_TS_GPIO, 310);
 }
 
 static int ads7846_get_pendown_state(void)
@@ -269,6 +598,7 @@ struct ads7846_platform_data ads7846_config = {
        .get_pendown_state      = ads7846_get_pendown_state,
        .keep_vref_on           = 1,
        .settle_delay_usecs     = 150,
+       .wakeup                         = true,
 };
 
 static struct omap2_mcspi_device_config ads7846_mcspi_config = {
@@ -289,7 +619,6 @@ struct spi_board_info omap3evm_spi_board_info[] = {
 };
 
 static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
-       { OMAP_TAG_LCD,         &omap3_evm_lcd_config },
 };
 
 static void __init omap3_evm_init_irq(void)
@@ -299,16 +628,49 @@ static void __init omap3_evm_init_irq(void)
        omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
        omap_init_irq();
        omap_gpio_init();
-       omap3evm_init_smc911x();
 }
 
 static struct platform_device *omap3_evm_devices[] __initdata = {
-       &omap3_evm_lcd_device,
-       &omap3evm_smc911x_device,
+       &omap3_evm_dss_device,
+};
+
+static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
+
+       .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+       .phy_reset  = true,
+       /* PHY reset GPIO will be runtime programmed based on EVM version */
+       .reset_gpio_port[0]  = -EINVAL,
+       .reset_gpio_port[1]  = -EINVAL,
+       .reset_gpio_port[2]  = -EINVAL
+};
+
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+       OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP |
+                               OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW |
+                               OMAP_PIN_OFF_WAKEUPENABLE),
+       OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP |
+                               OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW),
+       { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux      NULL
+#endif
+
+static struct omap_musb_board_data musb_board_data = {
+       .interface_type         = MUSB_INTERFACE_ULPI,
+       .mode                   = MUSB_OTG,
+       .power                  = 100,
 };
 
 static void __init omap3_evm_init(void)
 {
+       omap3_evm_get_revision();
+       omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
+
        omap3_evm_i2c_init();
 
        platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
@@ -317,18 +679,46 @@ static void __init omap3_evm_init(void)
                                ARRAY_SIZE(omap3evm_spi_board_info));
 
        omap_serial_init();
-#ifdef CONFIG_NOP_USB_XCEIV
+
        /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
        usb_nop_xceiv_register();
-#endif
-       usb_musb_init();
+
+       if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
+               /* enable EHCI VBUS using GPIO22 */
+               omap_mux_init_gpio(22, OMAP_PIN_INPUT_PULLUP);
+               gpio_request(OMAP3_EVM_EHCI_VBUS, "enable EHCI VBUS");
+               gpio_direction_output(OMAP3_EVM_EHCI_VBUS, 0);
+               gpio_set_value(OMAP3_EVM_EHCI_VBUS, 1);
+
+               /* Select EHCI port on main board */
+               omap_mux_init_gpio(61, OMAP_PIN_INPUT_PULLUP);
+               gpio_request(OMAP3_EVM_EHCI_SELECT, "select EHCI port");
+               gpio_direction_output(OMAP3_EVM_EHCI_SELECT, 0);
+               gpio_set_value(OMAP3_EVM_EHCI_SELECT, 0);
+
+               /* setup EHCI phy reset config */
+               omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
+               ehci_pdata.reset_gpio_port[1] = 21;
+
+               /* EVM REV >= E can supply 500mA with EXTVBUS programming */
+               musb_board_data.power = 500;
+               musb_board_data.extvbus = 1;
+       } else {
+               /* setup EHCI phy reset on MDC */
+               omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
+               ehci_pdata.reset_gpio_port[1] = 135;
+       }
+       usb_musb_init(&musb_board_data);
+       usb_ehci_init(&ehci_pdata);
        ads7846_dev_init();
+       omap3evm_init_smsc911x();
+       omap3_evm_display_init();
 }
 
 static void __init omap3_evm_map_io(void)
 {
        omap2_set_globals_343x();
-       omap2_map_common_io();
+       omap34xx_map_common_io();
 }
 
 MACHINE_START(OMAP3EVM, "OMAP3 EVM")