aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/omap2430.c
diff options
context:
space:
mode:
authorDavid Brownell <dbrownell@users.sourceforge.net>2009-03-31 15:30:04 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:40 -0400
commit84e250ffa76dddc1bad84e04248a27f442c25986 (patch)
treeb253b1e2b030b160d2c458aece9c8122446e433f /drivers/usb/musb/omap2430.c
parentcc835e321a9f3fa5e083436872e198095f4805b9 (diff)
musb: proper hookup to transceiver drivers
Let the otg_transceiver in MUSB be managed by an external driver; don't assume it's integrated. OMAP3 chips need it to be external, and there may be ways to interact with the transceiver which add functionality to the system. Platform init code is responsible for setting up the transeciver, probably using the NOP transceiver for integrated transceivers. External ones will use whatever the board init code provided, such as twl4030 or something more hands-off. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r--drivers/usb/musb/omap2430.c62
1 files changed, 23 insertions, 39 deletions
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 60924ce08493..a2f443859358 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -61,17 +61,17 @@ static void musb_do_idle(unsigned long _musb)
61 61
62 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 62 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
63 63
64 switch (musb->xceiv.state) { 64 switch (musb->xceiv->state) {
65 case OTG_STATE_A_WAIT_BCON: 65 case OTG_STATE_A_WAIT_BCON:
66 devctl &= ~MUSB_DEVCTL_SESSION; 66 devctl &= ~MUSB_DEVCTL_SESSION;
67 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 67 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
68 68
69 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 69 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
70 if (devctl & MUSB_DEVCTL_BDEVICE) { 70 if (devctl & MUSB_DEVCTL_BDEVICE) {
71 musb->xceiv.state = OTG_STATE_B_IDLE; 71 musb->xceiv->state = OTG_STATE_B_IDLE;
72 MUSB_DEV_MODE(musb); 72 MUSB_DEV_MODE(musb);
73 } else { 73 } else {
74 musb->xceiv.state = OTG_STATE_A_IDLE; 74 musb->xceiv->state = OTG_STATE_A_IDLE;
75 MUSB_HST_MODE(musb); 75 MUSB_HST_MODE(musb);
76 } 76 }
77 break; 77 break;
@@ -89,7 +89,7 @@ static void musb_do_idle(unsigned long _musb)
89 musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16; 89 musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
90 usb_hcd_poll_rh_status(musb_to_hcd(musb)); 90 usb_hcd_poll_rh_status(musb_to_hcd(musb));
91 /* NOTE: it might really be A_WAIT_BCON ... */ 91 /* NOTE: it might really be A_WAIT_BCON ... */
92 musb->xceiv.state = OTG_STATE_A_HOST; 92 musb->xceiv->state = OTG_STATE_A_HOST;
93 } 93 }
94 break; 94 break;
95#endif 95#endif
@@ -97,9 +97,9 @@ static void musb_do_idle(unsigned long _musb)
97 case OTG_STATE_A_HOST: 97 case OTG_STATE_A_HOST:
98 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 98 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
99 if (devctl & MUSB_DEVCTL_BDEVICE) 99 if (devctl & MUSB_DEVCTL_BDEVICE)
100 musb->xceiv.state = OTG_STATE_B_IDLE; 100 musb->xceiv->state = OTG_STATE_B_IDLE;
101 else 101 else
102 musb->xceiv.state = OTG_STATE_A_WAIT_BCON; 102 musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
103#endif 103#endif
104 default: 104 default:
105 break; 105 break;
@@ -118,7 +118,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout)
118 118
119 /* Never idle if active, or when VBUS timeout is not set as host */ 119 /* Never idle if active, or when VBUS timeout is not set as host */
120 if (musb->is_active || ((musb->a_wait_bcon == 0) 120 if (musb->is_active || ((musb->a_wait_bcon == 0)
121 && (musb->xceiv.state == OTG_STATE_A_WAIT_BCON))) { 121 && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
122 DBG(4, "%s active, deleting timer\n", otg_state_string(musb)); 122 DBG(4, "%s active, deleting timer\n", otg_state_string(musb));
123 del_timer(&musb_idle_timer); 123 del_timer(&musb_idle_timer);
124 last_timer = jiffies; 124 last_timer = jiffies;
@@ -163,8 +163,8 @@ static void omap_set_vbus(struct musb *musb, int is_on)
163 163
164 if (is_on) { 164 if (is_on) {
165 musb->is_active = 1; 165 musb->is_active = 1;
166 musb->xceiv.default_a = 1; 166 musb->xceiv->default_a = 1;
167 musb->xceiv.state = OTG_STATE_A_WAIT_VRISE; 167 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
168 devctl |= MUSB_DEVCTL_SESSION; 168 devctl |= MUSB_DEVCTL_SESSION;
169 169
170 MUSB_HST_MODE(musb); 170 MUSB_HST_MODE(musb);
@@ -175,8 +175,8 @@ static void omap_set_vbus(struct musb *musb, int is_on)
175 * jumping right to B_IDLE... 175 * jumping right to B_IDLE...
176 */ 176 */
177 177
178 musb->xceiv.default_a = 0; 178 musb->xceiv->default_a = 0;
179 musb->xceiv.state = OTG_STATE_B_IDLE; 179 musb->xceiv->state = OTG_STATE_B_IDLE;
180 devctl &= ~MUSB_DEVCTL_SESSION; 180 devctl &= ~MUSB_DEVCTL_SESSION;
181 181
182 MUSB_DEV_MODE(musb); 182 MUSB_DEV_MODE(musb);
@@ -188,10 +188,6 @@ static void omap_set_vbus(struct musb *musb, int is_on)
188 otg_state_string(musb), 188 otg_state_string(musb),
189 musb_readb(musb->mregs, MUSB_DEVCTL)); 189 musb_readb(musb->mregs, MUSB_DEVCTL));
190} 190}
191static int omap_set_power(struct otg_transceiver *x, unsigned mA)
192{
193 return 0;
194}
195 191
196static int musb_platform_resume(struct musb *musb); 192static int musb_platform_resume(struct musb *musb);
197 193
@@ -202,24 +198,6 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
202 devctl |= MUSB_DEVCTL_SESSION; 198 devctl |= MUSB_DEVCTL_SESSION;
203 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); 199 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
204 200
205 switch (musb_mode) {
206#ifdef CONFIG_USB_MUSB_HDRC_HCD
207 case MUSB_HOST:
208 otg_set_host(&musb->xceiv, musb->xceiv.host);
209 break;
210#endif
211#ifdef CONFIG_USB_GADGET_MUSB_HDRC
212 case MUSB_PERIPHERAL:
213 otg_set_peripheral(&musb->xceiv, musb->xceiv.gadget);
214 break;
215#endif
216#ifdef CONFIG_USB_MUSB_OTG
217 case MUSB_OTG:
218 break;
219#endif
220 default:
221 return -EINVAL;
222 }
223 return 0; 201 return 0;
224} 202}
225 203
@@ -231,6 +209,16 @@ int __init musb_platform_init(struct musb *musb)
231 omap_cfg_reg(AE5_2430_USB0HS_STP); 209 omap_cfg_reg(AE5_2430_USB0HS_STP);
232#endif 210#endif
233 211
212 /* We require some kind of external transceiver, hooked
213 * up through ULPI. TWL4030-family PMICs include one,
214 * which needs a driver, drivers aren't always needed.
215 */
216 musb->xceiv = otg_get_transceiver();
217 if (!musb->xceiv) {
218 pr_err("HS USB OTG: no transceiver configured\n");
219 return -ENODEV;
220 }
221
234 musb_platform_resume(musb); 222 musb_platform_resume(musb);
235 223
236 l = omap_readl(OTG_SYSCONFIG); 224 l = omap_readl(OTG_SYSCONFIG);
@@ -257,8 +245,6 @@ int __init musb_platform_init(struct musb *musb)
257 245
258 if (is_host_enabled(musb)) 246 if (is_host_enabled(musb))
259 musb->board_set_vbus = omap_set_vbus; 247 musb->board_set_vbus = omap_set_vbus;
260 if (is_peripheral_enabled(musb))
261 musb->xceiv.set_power = omap_set_power;
262 musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON; 248 musb->a_wait_bcon = MUSB_TIMEOUT_A_WAIT_BCON;
263 249
264 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); 250 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
@@ -282,8 +268,7 @@ int musb_platform_suspend(struct musb *musb)
282 l |= ENABLEWAKEUP; /* enable wakeup */ 268 l |= ENABLEWAKEUP; /* enable wakeup */
283 omap_writel(l, OTG_SYSCONFIG); 269 omap_writel(l, OTG_SYSCONFIG);
284 270
285 if (musb->xceiv.set_suspend) 271 otg_set_suspend(musb->xceiv, 1);
286 musb->xceiv.set_suspend(&musb->xceiv, 1);
287 272
288 if (musb->set_clock) 273 if (musb->set_clock)
289 musb->set_clock(musb->clock, 0); 274 musb->set_clock(musb->clock, 0);
@@ -300,8 +285,7 @@ static int musb_platform_resume(struct musb *musb)
300 if (!musb->clock) 285 if (!musb->clock)
301 return 0; 286 return 0;
302 287
303 if (musb->xceiv.set_suspend) 288 otg_set_suspend(musb->xceiv, 0);
304 musb->xceiv.set_suspend(&musb->xceiv, 0);
305 289
306 if (musb->set_clock) 290 if (musb->set_clock)
307 musb->set_clock(musb->clock, 1); 291 musb->set_clock(musb->clock, 1);