diff options
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r-- | drivers/usb/musb/omap2430.c | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 02c39a72b27e..f4d95037db5d 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -45,6 +45,7 @@ struct omap2430_glue { | |||
45 | struct platform_device *musb; | 45 | struct platform_device *musb; |
46 | enum omap_musb_vbus_id_status status; | 46 | enum omap_musb_vbus_id_status status; |
47 | struct work_struct omap_musb_mailbox_work; | 47 | struct work_struct omap_musb_mailbox_work; |
48 | u32 __iomem *control_otghs; | ||
48 | }; | 49 | }; |
49 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | 50 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
50 | 51 | ||
@@ -52,6 +53,26 @@ struct omap2430_glue *_glue; | |||
52 | 53 | ||
53 | static struct timer_list musb_idle_timer; | 54 | static struct timer_list musb_idle_timer; |
54 | 55 | ||
56 | /** | ||
57 | * omap4_usb_phy_mailbox - write to usb otg mailbox | ||
58 | * @glue: struct omap2430_glue * | ||
59 | * @val: the value to be written to the mailbox | ||
60 | * | ||
61 | * On detection of a device (ID pin is grounded), this API should be called | ||
62 | * to set AVALID, VBUSVALID and ID pin is grounded. | ||
63 | * | ||
64 | * When OMAP is connected to a host (OMAP in device mode), this API | ||
65 | * is called to set AVALID, VBUSVALID and ID pin in high impedance. | ||
66 | * | ||
67 | * XXX: This function will be removed once we have a seperate driver for | ||
68 | * control module | ||
69 | */ | ||
70 | static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val) | ||
71 | { | ||
72 | if (glue->control_otghs) | ||
73 | writel(val, glue->control_otghs); | ||
74 | } | ||
75 | |||
55 | static void musb_do_idle(unsigned long _musb) | 76 | static void musb_do_idle(unsigned long _musb) |
56 | { | 77 | { |
57 | struct musb *musb = (void *)_musb; | 78 | struct musb *musb = (void *)_musb; |
@@ -247,6 +268,7 @@ EXPORT_SYMBOL_GPL(omap_musb_mailbox); | |||
247 | 268 | ||
248 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) | 269 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) |
249 | { | 270 | { |
271 | u32 val; | ||
250 | struct musb *musb = glue_to_musb(glue); | 272 | struct musb *musb = glue_to_musb(glue); |
251 | struct device *dev = musb->controller; | 273 | struct device *dev = musb->controller; |
252 | struct musb_hdrc_platform_data *pdata = dev->platform_data; | 274 | struct musb_hdrc_platform_data *pdata = dev->platform_data; |
@@ -262,7 +284,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
262 | musb->xceiv->last_event = USB_EVENT_ID; | 284 | musb->xceiv->last_event = USB_EVENT_ID; |
263 | if (musb->gadget_driver) { | 285 | if (musb->gadget_driver) { |
264 | pm_runtime_get_sync(dev); | 286 | pm_runtime_get_sync(dev); |
265 | usb_phy_init(musb->xceiv); | 287 | val = AVALID | VBUSVALID; |
288 | omap4_usb_phy_mailbox(glue, val); | ||
266 | omap2430_musb_set_vbus(musb, 1); | 289 | omap2430_musb_set_vbus(musb, 1); |
267 | } | 290 | } |
268 | break; | 291 | break; |
@@ -275,7 +298,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
275 | musb->xceiv->last_event = USB_EVENT_VBUS; | 298 | musb->xceiv->last_event = USB_EVENT_VBUS; |
276 | if (musb->gadget_driver) | 299 | if (musb->gadget_driver) |
277 | pm_runtime_get_sync(dev); | 300 | pm_runtime_get_sync(dev); |
278 | usb_phy_init(musb->xceiv); | 301 | val = IDDIG | AVALID | VBUSVALID; |
302 | omap4_usb_phy_mailbox(glue, val); | ||
279 | break; | 303 | break; |
280 | 304 | ||
281 | case OMAP_MUSB_ID_FLOAT: | 305 | case OMAP_MUSB_ID_FLOAT: |
@@ -292,7 +316,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
292 | if (musb->xceiv->otg->set_vbus) | 316 | if (musb->xceiv->otg->set_vbus) |
293 | otg_set_vbus(musb->xceiv->otg, 0); | 317 | otg_set_vbus(musb->xceiv->otg, 0); |
294 | } | 318 | } |
295 | usb_phy_shutdown(musb->xceiv); | 319 | val = SESSEND | IDDIG; |
320 | omap4_usb_phy_mailbox(glue, val); | ||
296 | break; | 321 | break; |
297 | default: | 322 | default: |
298 | dev_dbg(dev, "ID float\n"); | 323 | dev_dbg(dev, "ID float\n"); |
@@ -367,6 +392,7 @@ err1: | |||
367 | static void omap2430_musb_enable(struct musb *musb) | 392 | static void omap2430_musb_enable(struct musb *musb) |
368 | { | 393 | { |
369 | u8 devctl; | 394 | u8 devctl; |
395 | u32 val; | ||
370 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | 396 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
371 | struct device *dev = musb->controller; | 397 | struct device *dev = musb->controller; |
372 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | 398 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); |
@@ -376,7 +402,8 @@ static void omap2430_musb_enable(struct musb *musb) | |||
376 | switch (glue->status) { | 402 | switch (glue->status) { |
377 | 403 | ||
378 | case OMAP_MUSB_ID_GROUND: | 404 | case OMAP_MUSB_ID_GROUND: |
379 | usb_phy_init(musb->xceiv); | 405 | val = AVALID | VBUSVALID; |
406 | omap4_usb_phy_mailbox(glue, val); | ||
380 | if (data->interface_type != MUSB_INTERFACE_UTMI) | 407 | if (data->interface_type != MUSB_INTERFACE_UTMI) |
381 | break; | 408 | break; |
382 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 409 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
@@ -395,7 +422,8 @@ static void omap2430_musb_enable(struct musb *musb) | |||
395 | break; | 422 | break; |
396 | 423 | ||
397 | case OMAP_MUSB_VBUS_VALID: | 424 | case OMAP_MUSB_VBUS_VALID: |
398 | usb_phy_init(musb->xceiv); | 425 | val = IDDIG | AVALID | VBUSVALID; |
426 | omap4_usb_phy_mailbox(glue, val); | ||
399 | break; | 427 | break; |
400 | 428 | ||
401 | default: | 429 | default: |
@@ -405,11 +433,14 @@ static void omap2430_musb_enable(struct musb *musb) | |||
405 | 433 | ||
406 | static void omap2430_musb_disable(struct musb *musb) | 434 | static void omap2430_musb_disable(struct musb *musb) |
407 | { | 435 | { |
436 | u32 val; | ||
408 | struct device *dev = musb->controller; | 437 | struct device *dev = musb->controller; |
409 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | 438 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); |
410 | 439 | ||
411 | if (glue->status != OMAP_MUSB_UNKNOWN) | 440 | if (glue->status != OMAP_MUSB_UNKNOWN) { |
412 | usb_phy_shutdown(musb->xceiv); | 441 | val = SESSEND | IDDIG; |
442 | omap4_usb_phy_mailbox(glue, val); | ||
443 | } | ||
413 | } | 444 | } |
414 | 445 | ||
415 | static int omap2430_musb_exit(struct musb *musb) | 446 | static int omap2430_musb_exit(struct musb *musb) |
@@ -441,6 +472,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev) | |||
441 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | 472 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; |
442 | struct platform_device *musb; | 473 | struct platform_device *musb; |
443 | struct omap2430_glue *glue; | 474 | struct omap2430_glue *glue; |
475 | struct resource *res; | ||
444 | int ret = -ENOMEM; | 476 | int ret = -ENOMEM; |
445 | 477 | ||
446 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | 478 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
@@ -463,6 +495,12 @@ static int __devinit omap2430_probe(struct platform_device *pdev) | |||
463 | glue->musb = musb; | 495 | glue->musb = musb; |
464 | glue->status = OMAP_MUSB_UNKNOWN; | 496 | glue->status = OMAP_MUSB_UNKNOWN; |
465 | 497 | ||
498 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
499 | |||
500 | glue->control_otghs = devm_request_and_ioremap(&pdev->dev, res); | ||
501 | if (glue->control_otghs == NULL) | ||
502 | dev_dbg(&pdev->dev, "Failed to obtain control memory\n"); | ||
503 | |||
466 | pdata->platform_ops = &omap2430_ops; | 504 | pdata->platform_ops = &omap2430_ops; |
467 | 505 | ||
468 | platform_set_drvdata(pdev, glue); | 506 | platform_set_drvdata(pdev, glue); |