aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/omap2430.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r--drivers/usb/musb/omap2430.c52
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
53static struct timer_list musb_idle_timer; 54static 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 */
70static 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
55static void musb_do_idle(unsigned long _musb) 76static 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
248static void omap_musb_set_mailbox(struct omap2430_glue *glue) 269static 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:
367static void omap2430_musb_enable(struct musb *musb) 392static 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
406static void omap2430_musb_disable(struct musb *musb) 434static 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
415static int omap2430_musb_exit(struct musb *musb) 446static 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);