]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - arch/arm/mach-omap2/usb-musb.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / arch / arm / mach-omap2 / usb-musb.c
index 72605584bfff42d0917803ae20657f5ff648899e..5298949d4b110a9303826e7655ed3d13bbee4e97 100644 (file)
 #include <mach/irqs.h>
 #include <mach/am35xx.h>
 #include <plat/usb.h>
+#include "control.h"
 
-#ifdef CONFIG_USB_MUSB_SOC
+#if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X)
+
+static void am35x_musb_reset(void)
+{
+       u32     regval;
+
+       /* Reset the musb interface */
+       regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+
+       regval |= AM35XX_USBOTGSS_SW_RST;
+       omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+
+       regval &= ~AM35XX_USBOTGSS_SW_RST;
+       omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET);
+
+       regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
+}
+
+static void am35x_musb_phy_power(u8 on)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(100);
+       u32 devconf2;
+
+       if (on) {
+               /*
+                * Start the on-chip PHY and its PLL.
+                */
+               devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+               devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN);
+               devconf2 |= CONF2_PHY_PLLON;
+
+               omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+
+               pr_info(KERN_INFO "Waiting for PHY clock good...\n");
+               while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2)
+                               & CONF2_PHYCLKGD)) {
+                       cpu_relax();
+
+                       if (time_after(jiffies, timeout)) {
+                               pr_err(KERN_ERR "musb PHY clock good timed out\n");
+                               break;
+                       }
+               }
+       } else {
+               /*
+                * Power down the on-chip PHY.
+                */
+               devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+               devconf2 &= ~CONF2_PHY_PLLON;
+               devconf2 |=  CONF2_PHYPWRDN | CONF2_OTGPWRDN;
+               omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+       }
+}
+
+static void am35x_musb_clear_irq(void)
+{
+       u32 regval;
+
+       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+       regval |= AM35XX_USBOTGSS_INT_CLR;
+       omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR);
+       regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
+}
+
+static void am35x_musb_set_mode(u8 musb_mode)
+{
+       u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
+
+       devconf2 &= ~CONF2_OTGMODE;
+       switch (musb_mode) {
+#ifdef CONFIG_USB_MUSB_HDRC_HCD
+       case MUSB_HOST:         /* Force VBUS valid, ID = 0 */
+               devconf2 |= CONF2_FORCE_HOST;
+               break;
+#endif
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+       case MUSB_PERIPHERAL:   /* Force VBUS valid, ID = 1 */
+               devconf2 |= CONF2_FORCE_DEVICE;
+               break;
+#endif
+#ifdef CONFIG_USB_MUSB_OTG
+       case MUSB_OTG:          /* Don't override the VBUS/ID comparators */
+               devconf2 |= CONF2_NO_OVERRIDE;
+               break;
+#endif
+       default:
+               pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode);
+       }
+
+       omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
+}
 
 static struct resource musb_resources[] = {
        [0] = { /* start and end set dynamically */
@@ -40,10 +133,12 @@ static struct resource musb_resources[] = {
        [1] = { /* general IRQ */
                .start  = INT_243X_HS_USB_MC,
                .flags  = IORESOURCE_IRQ,
+               .name   = "mc",
        },
        [2] = { /* DMA IRQ */
                .start  = INT_243X_HS_USB_DMA,
                .flags  = IORESOURCE_IRQ,
+               .name   = "dma",
        },
 };
 
@@ -75,7 +170,7 @@ static struct musb_hdrc_platform_data musb_plat = {
 static u64 musb_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device musb_device = {
-       .name           = "musb_hdrc",
+       .name           = "musb-omap2430",
        .id             = -1,
        .dev = {
                .dma_mask               = &musb_dmamask,
@@ -91,8 +186,13 @@ void __init usb_musb_init(struct omap_musb_board_data *board_data)
        if (cpu_is_omap243x()) {
                musb_resources[0].start = OMAP243X_HS_BASE;
        } else if (cpu_is_omap3517() || cpu_is_omap3505()) {
+               musb_device.name = "musb-am35x";
                musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE;
                musb_resources[1].start = INT_35XX_USBOTG_IRQ;
+               board_data->set_phy_power = am35x_musb_phy_power;
+               board_data->clear_irq = am35x_musb_clear_irq;
+               board_data->set_mode = am35x_musb_set_mode;
+               board_data->reset = am35x_musb_reset;
        } else if (cpu_is_omap34xx()) {
                musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE;
        } else if (cpu_is_omap44xx()) {