Maemo patchset 20101501+0m5
[h-e-n] / drivers / usb / musb / tusb6010.c
index ee8fca9..784d1b9 100644 (file)
@@ -270,7 +270,7 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *buf)
  */
 static int tusb_draw_power(struct otg_transceiver *x, unsigned mA)
 {
-       struct musb     *musb = container_of(x, struct musb, xceiv);
+       struct musb     *musb = dev_get_drvdata(x->dev);
        void __iomem    *tbase = musb->ctrl_base;
        u32             reg;
 
@@ -420,7 +420,7 @@ static void musb_do_idle(unsigned long _musb)
 
        spin_lock_irqsave(&musb->lock, flags);
 
-       switch (musb->xceiv.state) {
+       switch (musb->xceiv->state) {
        case OTG_STATE_A_WAIT_BCON:
                if ((musb->a_wait_bcon != 0)
                        && (musb->idle_timeout == 0
@@ -484,7 +484,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
 
        /* Never idle if active, or when VBUS timeout is not set as host */
        if (musb->is_active || ((musb->a_wait_bcon == 0)
-                       && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) {
+                       && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
                DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
                del_timer(&musb_idle_timer);
                last_timer = jiffies;
@@ -533,8 +533,8 @@ static void tusb_source_power(struct musb *musb, int is_on)
                if (musb->set_clock)
                        musb->set_clock(musb->clock, 1);
                timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE);
-               musb->xceiv.default_a = 1;
-               musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
+               musb->xceiv->default_a = 1;
+               musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
                devctl |= MUSB_DEVCTL_SESSION;
 
                conf |= TUSB_DEV_CONF_USB_HOST_MODE;
@@ -547,24 +547,24 @@ static void tusb_source_power(struct musb *musb, int is_on)
                /* If ID pin is grounded, we want to be a_idle */
                otg_stat = musb_readl(tbase, TUSB_DEV_OTG_STAT);
                if (!(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS)) {
-                       switch (musb->xceiv.state) {
+                       switch (musb->xceiv->state) {
                        case OTG_STATE_A_WAIT_VRISE:
                        case OTG_STATE_A_WAIT_BCON:
-                               musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
+                               musb->xceiv->state = OTG_STATE_A_WAIT_VFALL;
                                break;
                        case OTG_STATE_A_WAIT_VFALL:
-                               musb->xceiv.state = OTG_STATE_A_IDLE;
+                               musb->xceiv->state = OTG_STATE_A_IDLE;
                                break;
                        default:
-                               musb->xceiv.state = OTG_STATE_A_IDLE;
+                               musb->xceiv->state = OTG_STATE_A_IDLE;
                        }
                        musb->is_active = 0;
-                       musb->xceiv.default_a = 1;
+                       musb->xceiv->default_a = 1;
                        MUSB_HST_MODE(musb);
                } else {
                        musb->is_active = 0;
-                       musb->xceiv.default_a = 0;
-                       musb->xceiv.state = OTG_STATE_B_IDLE;
+                       musb->xceiv->default_a = 0;
+                       musb->xceiv->state = OTG_STATE_B_IDLE;
                        MUSB_DEV_MODE(musb);
                }
 
@@ -598,7 +598,7 @@ static void tusb_source_power(struct musb *musb, int is_on)
  * and peripheral modes in non-OTG configurations by reconfiguring hardware
  * and then setting musb->board_mode. For now, only support OTG mode.
  */
-void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
+int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 {
        void __iomem    *tbase = musb->ctrl_base;
        u32             otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf;
@@ -641,7 +641,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
 #endif
 
        default:
-               DBG(2, "Trying to set unknown mode %i\n", musb_mode);
+               DBG(2, "Trying to set mode %i\n", musb_mode);
+               return -EINVAL;
        }
 
        musb_writel(tbase, TUSB_PHY_OTG_CTRL,
@@ -655,6 +656,8 @@ void musb_platform_set_mode(struct musb *musb, u8 musb_mode)
                !(otg_stat & TUSB_DEV_OTG_STAT_ID_STATUS))
                        INFO("Cannot be peripheral with mini-A cable "
                        "otg_stat: %08x\n", otg_stat);
+
+       return 0;
 }
 
 static inline unsigned long
@@ -672,7 +675,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
                else
                        default_a = is_host_enabled(musb);
                DBG(2, "Default-%c\n", default_a ? 'A' : 'B');
-               musb->xceiv.default_a = default_a;
+               musb->xceiv->default_a = default_a;
                tusb_source_power(musb, default_a);
 
                /* Don't allow idling immediately */
@@ -684,7 +687,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
        if (int_src & TUSB_INT_SRC_VBUS_SENSE_CHNG) {
 
                /* B-dev state machine:  no vbus ~= disconnect */
-               if ((is_otg_enabled(musb) && !musb->xceiv.default_a)
+               if ((is_otg_enabled(musb) && !musb->xceiv->default_a)
                                || !is_host_enabled(musb)) {
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
                        /* ? musb_root_disconnect(musb); */
@@ -699,9 +702,9 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
 
                        if (otg_stat & TUSB_DEV_OTG_STAT_SESS_END) {
                                DBG(1, "Forcing disconnect (no interrupt)\n");
-                               if (musb->xceiv.state != OTG_STATE_B_IDLE) {
+                               if (musb->xceiv->state != OTG_STATE_B_IDLE) {
                                        /* INTR_DISCONNECT can hide... */
-                                       musb->xceiv.state = OTG_STATE_B_IDLE;
+                                       musb->xceiv->state = OTG_STATE_B_IDLE;
                                        musb->int_usb |= MUSB_INTR_DISCONNECT;
                                }
                                musb->is_active = 0;
@@ -715,7 +718,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
                        DBG(2, "vbus change, %s, otg %03x\n",
                                otg_state_string(musb), otg_stat);
 
-                       switch (musb->xceiv.state) {
+                       switch (musb->xceiv->state) {
                        case OTG_STATE_A_IDLE:
                                DBG(2, "Got SRP, turning on VBUS\n");
                                musb_set_vbus(musb, 1);
@@ -763,7 +766,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
 
                DBG(4, "%s timer, %03x\n", otg_state_string(musb), otg_stat);
 
-               switch (musb->xceiv.state) {
+               switch (musb->xceiv->state) {
                case OTG_STATE_A_WAIT_VRISE:
                        /* VBUS has probably been valid for a while now,
                         * but may well have bounced out of range a bit
@@ -775,7 +778,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase)
                                        DBG(2, "devctl %02x\n", devctl);
                                        break;
                                }
-                               musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
+                               musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
                                musb->is_active = 0;
                                idle_timeout = jiffies
                                        + msecs_to_jiffies(musb->a_wait_bcon);
@@ -1089,6 +1092,7 @@ err:
 
 int __init musb_platform_init(struct musb *musb)
 {
+       struct otg_transceiver  xceiv;
        struct platform_device  *pdev;
        struct resource         *mem;
        void __iomem            *sync;
@@ -1100,6 +1104,8 @@ int __init musb_platform_init(struct musb *musb)
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        musb->async = mem->start;
 
+       musb->suspendm = false;
+
        /* dma address for sync dma */
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        if (!mem) {
@@ -1128,10 +1134,17 @@ int __init musb_platform_init(struct musb *musb)
        }
        musb->isr = tusb_interrupt;
 
+       memset(&xceiv, 0, sizeof(xceiv));
+       xceiv.label = "tusb6010";
+       xceiv.dev = musb->controller;
+
        if (is_host_enabled(musb))
                musb->board_set_vbus = tusb_source_power;
        if (is_peripheral_enabled(musb))
-               musb->xceiv.set_power = tusb_draw_power;
+               xceiv.set_power = tusb_draw_power;
+
+       otg_set_transceiver(&xceiv);
+       musb->xceiv = &xceiv;
 
        setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);