Merge branch 'omap-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind...
[pandora-kernel.git] / arch / arm / mach-omap2 / board-omap4panda.c
index db69bca..702f2a6 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
+#include <linux/leds.h>
 #include <linux/gpio.h>
 #include <linux/usb/otg.h>
 #include <linux/i2c/twl.h>
 
 #include <plat/board.h>
 #include <plat/common.h>
-#include <plat/control.h>
-#include <plat/timer-gp.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
+#include "timer-gp.h"
+
 #include "hsmmc.h"
+#include "control.h"
+
+#define GPIO_HUB_POWER         1
+#define GPIO_HUB_NRESET                62
+
+static struct gpio_led gpio_leds[] = {
+       {
+               .name                   = "pandaboard::status1",
+               .default_trigger        = "heartbeat",
+               .gpio                   = 7,
+       },
+       {
+               .name                   = "pandaboard::status2",
+               .default_trigger        = "mmc0",
+               .gpio                   = 8,
+       },
+};
 
+static struct gpio_led_platform_data gpio_led_info = {
+       .leds           = gpio_leds,
+       .num_leds       = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+       .name   = "leds-gpio",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &gpio_led_info,
+       },
+};
+
+static struct platform_device *panda_devices[] __initdata = {
+       &leds_gpio,
+};
 
 static void __init omap4_panda_init_irq(void)
 {
@@ -47,6 +81,56 @@ static void __init omap4_panda_init_irq(void)
        omap_gpio_init();
 }
 
+static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+       .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+       .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+       .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+       .phy_reset  = false,
+       .reset_gpio_port[0]  = -EINVAL,
+       .reset_gpio_port[1]  = -EINVAL,
+       .reset_gpio_port[2]  = -EINVAL
+};
+
+static void __init omap4_ehci_init(void)
+{
+       int ret;
+
+
+       /* disable the power to the usb hub prior to init */
+       ret = gpio_request(GPIO_HUB_POWER, "hub_power");
+       if (ret) {
+               pr_err("Cannot request GPIO %d\n", GPIO_HUB_POWER);
+               goto error1;
+       }
+       gpio_export(GPIO_HUB_POWER, 0);
+       gpio_direction_output(GPIO_HUB_POWER, 0);
+       gpio_set_value(GPIO_HUB_POWER, 0);
+
+       /* reset phy+hub */
+       ret = gpio_request(GPIO_HUB_NRESET, "hub_nreset");
+       if (ret) {
+               pr_err("Cannot request GPIO %d\n", GPIO_HUB_NRESET);
+               goto error2;
+       }
+       gpio_export(GPIO_HUB_NRESET, 0);
+       gpio_direction_output(GPIO_HUB_NRESET, 0);
+       gpio_set_value(GPIO_HUB_NRESET, 0);
+       gpio_set_value(GPIO_HUB_NRESET, 1);
+
+       usb_ehci_init(&ehci_pdata);
+
+       /* enable power to hub */
+       gpio_set_value(GPIO_HUB_POWER, 1);
+       return;
+
+error2:
+       gpio_free(GPIO_HUB_POWER);
+error1:
+       pr_err("Unable to initialize EHCI power/reset\n");
+       return;
+
+}
+
 static struct omap_musb_board_data musb_board_data = {
        .interface_type         = MUSB_INTERFACE_UTMI,
        .mode                   = MUSB_PERIPHERAL,
@@ -56,7 +140,7 @@ static struct omap_musb_board_data musb_board_data = {
 static struct omap2_hsmmc_info mmc[] = {
        {
                .mmc            = 1,
-               .wires          = 8,
+               .caps           = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
                .gpio_wp        = -EINVAL,
        },
        {}      /* Terminator */
@@ -67,10 +151,6 @@ static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
                .supply = "vmmc",
                .dev_name = "mmci-omap-hs.0",
        },
-       {
-               .supply = "vmmc",
-               .dev_name = "mmci-omap-hs.1",
-       },
 };
 
 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
@@ -89,7 +169,14 @@ static int omap4_twl6030_hsmmc_late_init(struct device *dev)
 
 static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
 {
-       struct omap_mmc_platform_data *pdata = dev->platform_data;
+       struct omap_mmc_platform_data *pdata;
+
+       /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
+       if (!dev) {
+               pr_err("Failed omap4_twl6030_hsmmc_set_late_init\n");
+               return;
+       }
+       pdata = dev->platform_data;
 
        pdata->init =   omap4_twl6030_hsmmc_late_init;
 }
@@ -156,7 +243,7 @@ static struct regulator_init_data omap4_panda_vmmc = {
                                        | REGULATOR_CHANGE_MODE
                                        | REGULATOR_CHANGE_STATUS,
        },
-       .num_consumer_supplies  = 2,
+       .num_consumer_supplies  = 1,
        .consumer_supplies      = omap4_panda_vmmc_supply,
 };
 
@@ -274,13 +361,13 @@ static int __init omap4_panda_i2c_init(void)
 }
 static void __init omap4_panda_init(void)
 {
-       int status;
-
        omap4_panda_i2c_init();
+       platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
        omap_serial_init();
        omap4_twl6030_hsmmc_init(mmc);
        /* OMAP4 Panda uses internal transceiver so register nop transceiver */
        usb_nop_xceiv_register();
+       omap4_ehci_init();
        /* FIXME: allow multi-omap to boot until musb is updated for omap4 */
        if (!cpu_is_omap44xx())
                usb_musb_init(&musb_board_data);