omap2430.c (35eb304b5cd7b49d581bda79218b8134f3b689ea) omap2430.c (b96d3b08365f5a9603f50f3aadca6012f7eaffa1)
1/*
2 * Copyright (C) 2005-2007 by Texas Instruments
3 * Some code has been taken from tusb6010.c
4 * Copyrights for that are attributable to:
5 * Copyright (C) 2006 Nokia Corporation
6 * Tony Lindgren <tony@atomide.com>
7 *
8 * This file is part of the Inventra Controller Driver for Linux.

--- 118 unchanged lines hidden (view full) ---

127 dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
128 otg_state_string(musb->xceiv->state),
129 (unsigned long)jiffies_to_msecs(timeout - jiffies));
130 mod_timer(&musb_idle_timer, timeout);
131}
132
133static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
134{
1/*
2 * Copyright (C) 2005-2007 by Texas Instruments
3 * Some code has been taken from tusb6010.c
4 * Copyrights for that are attributable to:
5 * Copyright (C) 2006 Nokia Corporation
6 * Tony Lindgren <tony@atomide.com>
7 *
8 * This file is part of the Inventra Controller Driver for Linux.

--- 118 unchanged lines hidden (view full) ---

127 dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
128 otg_state_string(musb->xceiv->state),
129 (unsigned long)jiffies_to_msecs(timeout - jiffies));
130 mod_timer(&musb_idle_timer, timeout);
131}
132
133static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
134{
135 struct usb_otg *otg = musb->xceiv->otg;
135 u8 devctl;
136 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
137 int ret = 1;
138 /* HDRC controls CPEN, but beware current surges during device
139 * connect. They can trigger transient overcurrent conditions
140 * that must be ignored.
141 */
142

--- 19 unchanged lines hidden (view full) ---

162 break;
163 }
164 }
165
166 if (ret && musb->xceiv->set_vbus)
167 otg_set_vbus(musb->xceiv, 1);
168 } else {
169 musb->is_active = 1;
136 u8 devctl;
137 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
138 int ret = 1;
139 /* HDRC controls CPEN, but beware current surges during device
140 * connect. They can trigger transient overcurrent conditions
141 * that must be ignored.
142 */
143

--- 19 unchanged lines hidden (view full) ---

163 break;
164 }
165 }
166
167 if (ret && musb->xceiv->set_vbus)
168 otg_set_vbus(musb->xceiv, 1);
169 } else {
170 musb->is_active = 1;
170 musb->xceiv->default_a = 1;
171 otg->default_a = 1;
171 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
172 devctl |= MUSB_DEVCTL_SESSION;
173 MUSB_HST_MODE(musb);
174 }
175 } else {
176 musb->is_active = 0;
177
178 /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
179 * jumping right to B_IDLE...
180 */
181
172 musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
173 devctl |= MUSB_DEVCTL_SESSION;
174 MUSB_HST_MODE(musb);
175 }
176 } else {
177 musb->is_active = 0;
178
179 /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
180 * jumping right to B_IDLE...
181 */
182
182 musb->xceiv->default_a = 0;
183 otg->default_a = 0;
183 musb->xceiv->state = OTG_STATE_B_IDLE;
184 devctl &= ~MUSB_DEVCTL_SESSION;
185
186 MUSB_DEV_MODE(musb);
187 }
188 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
189
190 dev_dbg(musb->controller, "VBUS %s, devctl %02x "

--- 50 unchanged lines hidden (view full) ---

241 struct omap_musb_board_data *data = pdata->board_data;
242
243 switch (musb->xceiv_event) {
244 case USB_EVENT_ID:
245 dev_dbg(musb->controller, "ID GND\n");
246
247 if (!is_otg_enabled(musb) || musb->gadget_driver) {
248 pm_runtime_get_sync(musb->controller);
184 musb->xceiv->state = OTG_STATE_B_IDLE;
185 devctl &= ~MUSB_DEVCTL_SESSION;
186
187 MUSB_DEV_MODE(musb);
188 }
189 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
190
191 dev_dbg(musb->controller, "VBUS %s, devctl %02x "

--- 50 unchanged lines hidden (view full) ---

242 struct omap_musb_board_data *data = pdata->board_data;
243
244 switch (musb->xceiv_event) {
245 case USB_EVENT_ID:
246 dev_dbg(musb->controller, "ID GND\n");
247
248 if (!is_otg_enabled(musb) || musb->gadget_driver) {
249 pm_runtime_get_sync(musb->controller);
249 otg_init(musb->xceiv);
250 usb_phy_init(musb->xceiv);
250 omap2430_musb_set_vbus(musb, 1);
251 }
252 break;
253
254 case USB_EVENT_VBUS:
255 dev_dbg(musb->controller, "VBUS Connect\n");
256
257 if (musb->gadget_driver)
258 pm_runtime_get_sync(musb->controller);
251 omap2430_musb_set_vbus(musb, 1);
252 }
253 break;
254
255 case USB_EVENT_VBUS:
256 dev_dbg(musb->controller, "VBUS Connect\n");
257
258 if (musb->gadget_driver)
259 pm_runtime_get_sync(musb->controller);
259 otg_init(musb->xceiv);
260 usb_phy_init(musb->xceiv);
260 break;
261
262 case USB_EVENT_NONE:
263 dev_dbg(musb->controller, "VBUS Disconnect\n");
264
265 if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
266 if (musb->gadget_driver) {
267 pm_runtime_mark_last_busy(musb->controller);
268 pm_runtime_put_autosuspend(musb->controller);
269 }
270
271 if (data->interface_type == MUSB_INTERFACE_UTMI) {
272 if (musb->xceiv->set_vbus)
273 otg_set_vbus(musb->xceiv, 0);
274 }
261 break;
262
263 case USB_EVENT_NONE:
264 dev_dbg(musb->controller, "VBUS Disconnect\n");
265
266 if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
267 if (musb->gadget_driver) {
268 pm_runtime_mark_last_busy(musb->controller);
269 pm_runtime_put_autosuspend(musb->controller);
270 }
271
272 if (data->interface_type == MUSB_INTERFACE_UTMI) {
273 if (musb->xceiv->set_vbus)
274 otg_set_vbus(musb->xceiv, 0);
275 }
275 otg_shutdown(musb->xceiv);
276 usb_phy_shutdown(musb->xceiv);
276 break;
277 default:
278 dev_dbg(musb->controller, "ID float\n");
279 }
280}
281
282static int omap2430_musb_init(struct musb *musb)
283{
284 u32 l, status = 0;
285 struct device *dev = musb->controller;
286 struct musb_hdrc_platform_data *plat = dev->platform_data;
287 struct omap_musb_board_data *data = plat->board_data;
288
289 /* We require some kind of external transceiver, hooked
290 * up through ULPI. TWL4030-family PMICs include one,
291 * which needs a driver, drivers aren't always needed.
292 */
277 break;
278 default:
279 dev_dbg(musb->controller, "ID float\n");
280 }
281}
282
283static int omap2430_musb_init(struct musb *musb)
284{
285 u32 l, status = 0;
286 struct device *dev = musb->controller;
287 struct musb_hdrc_platform_data *plat = dev->platform_data;
288 struct omap_musb_board_data *data = plat->board_data;
289
290 /* We require some kind of external transceiver, hooked
291 * up through ULPI. TWL4030-family PMICs include one,
292 * which needs a driver, drivers aren't always needed.
293 */
293 musb->xceiv = otg_get_transceiver();
294 musb->xceiv = usb_get_transceiver();
294 if (!musb->xceiv) {
295 pr_err("HS USB OTG: no transceiver configured\n");
296 return -ENODEV;
297 }
298
299 INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);
300
301 status = pm_runtime_get_sync(dev);

--- 18 unchanged lines hidden (view full) ---

320 "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
321 musb_readl(musb->mregs, OTG_REVISION),
322 musb_readl(musb->mregs, OTG_SYSCONFIG),
323 musb_readl(musb->mregs, OTG_SYSSTATUS),
324 musb_readl(musb->mregs, OTG_INTERFSEL),
325 musb_readl(musb->mregs, OTG_SIMENABLE));
326
327 musb->nb.notifier_call = musb_otg_notifications;
295 if (!musb->xceiv) {
296 pr_err("HS USB OTG: no transceiver configured\n");
297 return -ENODEV;
298 }
299
300 INIT_WORK(&musb->otg_notifier_work, musb_otg_notifier_work);
301
302 status = pm_runtime_get_sync(dev);

--- 18 unchanged lines hidden (view full) ---

321 "sysstatus 0x%x, intrfsel 0x%x, simenable 0x%x\n",
322 musb_readl(musb->mregs, OTG_REVISION),
323 musb_readl(musb->mregs, OTG_SYSCONFIG),
324 musb_readl(musb->mregs, OTG_SYSSTATUS),
325 musb_readl(musb->mregs, OTG_INTERFSEL),
326 musb_readl(musb->mregs, OTG_SIMENABLE));
327
328 musb->nb.notifier_call = musb_otg_notifications;
328 status = otg_register_notifier(musb->xceiv, &musb->nb);
329 status = usb_register_notifier(musb->xceiv, &musb->nb);
329
330 if (status)
331 dev_dbg(musb->controller, "notification register failed\n");
332
333 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
334
335 return 0;
336

--- 7 unchanged lines hidden (view full) ---

344 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
345 struct device *dev = musb->controller;
346 struct musb_hdrc_platform_data *pdata = dev->platform_data;
347 struct omap_musb_board_data *data = pdata->board_data;
348
349 switch (musb->xceiv->last_event) {
350
351 case USB_EVENT_ID:
330
331 if (status)
332 dev_dbg(musb->controller, "notification register failed\n");
333
334 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
335
336 return 0;
337

--- 7 unchanged lines hidden (view full) ---

345 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
346 struct device *dev = musb->controller;
347 struct musb_hdrc_platform_data *pdata = dev->platform_data;
348 struct omap_musb_board_data *data = pdata->board_data;
349
350 switch (musb->xceiv->last_event) {
351
352 case USB_EVENT_ID:
352 otg_init(musb->xceiv);
353 usb_phy_init(musb->xceiv);
353 if (data->interface_type != MUSB_INTERFACE_UTMI)
354 break;
355 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
356 /* start the session */
357 devctl |= MUSB_DEVCTL_SESSION;
358 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
359 while (musb_readb(musb->mregs, MUSB_DEVCTL) &
360 MUSB_DEVCTL_BDEVICE) {
361 cpu_relax();
362
363 if (time_after(jiffies, timeout)) {
364 dev_err(dev, "configured as A device timeout");
365 break;
366 }
367 }
368 break;
369
370 case USB_EVENT_VBUS:
354 if (data->interface_type != MUSB_INTERFACE_UTMI)
355 break;
356 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
357 /* start the session */
358 devctl |= MUSB_DEVCTL_SESSION;
359 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
360 while (musb_readb(musb->mregs, MUSB_DEVCTL) &
361 MUSB_DEVCTL_BDEVICE) {
362 cpu_relax();
363
364 if (time_after(jiffies, timeout)) {
365 dev_err(dev, "configured as A device timeout");
366 break;
367 }
368 }
369 break;
370
371 case USB_EVENT_VBUS:
371 otg_init(musb->xceiv);
372 usb_phy_init(musb->xceiv);
372 break;
373
374 default:
375 break;
376 }
377}
378
379static void omap2430_musb_disable(struct musb *musb)
380{
381 if (musb->xceiv->last_event)
373 break;
374
375 default:
376 break;
377 }
378}
379
380static void omap2430_musb_disable(struct musb *musb)
381{
382 if (musb->xceiv->last_event)
382 otg_shutdown(musb->xceiv);
383 usb_phy_shutdown(musb->xceiv);
383}
384
385static int omap2430_musb_exit(struct musb *musb)
386{
387 del_timer_sync(&musb_idle_timer);
388 cancel_work_sync(&musb->otg_notifier_work);
389
390 omap2430_low_level_exit(musb);
384}
385
386static int omap2430_musb_exit(struct musb *musb)
387{
388 del_timer_sync(&musb_idle_timer);
389 cancel_work_sync(&musb->otg_notifier_work);
390
391 omap2430_low_level_exit(musb);
391 otg_put_transceiver(musb->xceiv);
392 usb_put_transceiver(musb->xceiv);
392
393 return 0;
394}
395
396static const struct musb_platform_ops omap2430_ops = {
397 .init = omap2430_musb_init,
398 .exit = omap2430_musb_exit,
399

--- 89 unchanged lines hidden (view full) ---

489{
490 struct omap2430_glue *glue = dev_get_drvdata(dev);
491 struct musb *musb = glue_to_musb(glue);
492
493 musb->context.otg_interfsel = musb_readl(musb->mregs,
494 OTG_INTERFSEL);
495
496 omap2430_low_level_exit(musb);
393
394 return 0;
395}
396
397static const struct musb_platform_ops omap2430_ops = {
398 .init = omap2430_musb_init,
399 .exit = omap2430_musb_exit,
400

--- 89 unchanged lines hidden (view full) ---

490{
491 struct omap2430_glue *glue = dev_get_drvdata(dev);
492 struct musb *musb = glue_to_musb(glue);
493
494 musb->context.otg_interfsel = musb_readl(musb->mregs,
495 OTG_INTERFSEL);
496
497 omap2430_low_level_exit(musb);
497 otg_set_suspend(musb->xceiv, 1);
498 usb_phy_set_suspend(musb->xceiv, 1);
498
499 return 0;
500}
501
502static int omap2430_runtime_resume(struct device *dev)
503{
504 struct omap2430_glue *glue = dev_get_drvdata(dev);
505 struct musb *musb = glue_to_musb(glue);
506
507 omap2430_low_level_init(musb);
508 musb_writel(musb->mregs, OTG_INTERFSEL,
509 musb->context.otg_interfsel);
510
499
500 return 0;
501}
502
503static int omap2430_runtime_resume(struct device *dev)
504{
505 struct omap2430_glue *glue = dev_get_drvdata(dev);
506 struct musb *musb = glue_to_musb(glue);
507
508 omap2430_low_level_init(musb);
509 musb_writel(musb->mregs, OTG_INTERFSEL,
510 musb->context.otg_interfsel);
511
511 otg_set_suspend(musb->xceiv, 0);
512 usb_phy_set_suspend(musb->xceiv, 0);
512
513 return 0;
514}
515
516static struct dev_pm_ops omap2430_pm_ops = {
517 .runtime_suspend = omap2430_runtime_suspend,
518 .runtime_resume = omap2430_runtime_resume,
519};

--- 29 unchanged lines hidden ---
513
514 return 0;
515}
516
517static struct dev_pm_ops omap2430_pm_ops = {
518 .runtime_suspend = omap2430_runtime_suspend,
519 .runtime_resume = omap2430_runtime_resume,
520};

--- 29 unchanged lines hidden ---