diff options
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r-- | drivers/usb/musb/omap2430.c | 89 |
1 files changed, 36 insertions, 53 deletions
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index acd5f9d71d03..1762354fe793 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/err.h> | 37 | #include <linux/err.h> |
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/usb/musb-omap.h> | 39 | #include <linux/usb/musb-omap.h> |
40 | #include <linux/usb/omap_control_usb.h> | ||
40 | 41 | ||
41 | #include "musb_core.h" | 42 | #include "musb_core.h" |
42 | #include "omap2430.h" | 43 | #include "omap2430.h" |
@@ -46,7 +47,7 @@ struct omap2430_glue { | |||
46 | struct platform_device *musb; | 47 | struct platform_device *musb; |
47 | enum omap_musb_vbus_id_status status; | 48 | enum omap_musb_vbus_id_status status; |
48 | struct work_struct omap_musb_mailbox_work; | 49 | struct work_struct omap_musb_mailbox_work; |
49 | u32 __iomem *control_otghs; | 50 | struct device *control_otghs; |
50 | }; | 51 | }; |
51 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | 52 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
52 | 53 | ||
@@ -54,26 +55,6 @@ struct omap2430_glue *_glue; | |||
54 | 55 | ||
55 | static struct timer_list musb_idle_timer; | 56 | static struct timer_list musb_idle_timer; |
56 | 57 | ||
57 | /** | ||
58 | * omap4_usb_phy_mailbox - write to usb otg mailbox | ||
59 | * @glue: struct omap2430_glue * | ||
60 | * @val: the value to be written to the mailbox | ||
61 | * | ||
62 | * On detection of a device (ID pin is grounded), this API should be called | ||
63 | * to set AVALID, VBUSVALID and ID pin is grounded. | ||
64 | * | ||
65 | * When OMAP is connected to a host (OMAP in device mode), this API | ||
66 | * is called to set AVALID, VBUSVALID and ID pin in high impedance. | ||
67 | * | ||
68 | * XXX: This function will be removed once we have a seperate driver for | ||
69 | * control module | ||
70 | */ | ||
71 | static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val) | ||
72 | { | ||
73 | if (glue->control_otghs) | ||
74 | writel(val, glue->control_otghs); | ||
75 | } | ||
76 | |||
77 | static void musb_do_idle(unsigned long _musb) | 58 | static void musb_do_idle(unsigned long _musb) |
78 | { | 59 | { |
79 | struct musb *musb = (void *)_musb; | 60 | struct musb *musb = (void *)_musb; |
@@ -255,11 +236,11 @@ static inline void omap2430_low_level_init(struct musb *musb) | |||
255 | void omap_musb_mailbox(enum omap_musb_vbus_id_status status) | 236 | void omap_musb_mailbox(enum omap_musb_vbus_id_status status) |
256 | { | 237 | { |
257 | struct omap2430_glue *glue = _glue; | 238 | struct omap2430_glue *glue = _glue; |
258 | struct musb *musb = glue_to_musb(glue); | ||
259 | 239 | ||
260 | glue->status = status; | 240 | if (glue && glue_to_musb(glue)) { |
261 | if (!musb) { | 241 | glue->status = status; |
262 | dev_err(glue->dev, "musb core is not yet ready\n"); | 242 | } else { |
243 | pr_err("%s: musb core is not yet ready\n", __func__); | ||
263 | return; | 244 | return; |
264 | } | 245 | } |
265 | 246 | ||
@@ -269,7 +250,6 @@ EXPORT_SYMBOL_GPL(omap_musb_mailbox); | |||
269 | 250 | ||
270 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) | 251 | static void omap_musb_set_mailbox(struct omap2430_glue *glue) |
271 | { | 252 | { |
272 | u32 val; | ||
273 | struct musb *musb = glue_to_musb(glue); | 253 | struct musb *musb = glue_to_musb(glue); |
274 | struct device *dev = musb->controller; | 254 | struct device *dev = musb->controller; |
275 | struct musb_hdrc_platform_data *pdata = dev->platform_data; | 255 | struct musb_hdrc_platform_data *pdata = dev->platform_data; |
@@ -285,8 +265,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
285 | musb->xceiv->last_event = USB_EVENT_ID; | 265 | musb->xceiv->last_event = USB_EVENT_ID; |
286 | if (musb->gadget_driver) { | 266 | if (musb->gadget_driver) { |
287 | pm_runtime_get_sync(dev); | 267 | pm_runtime_get_sync(dev); |
288 | val = AVALID | VBUSVALID; | 268 | omap_control_usb_set_mode(glue->control_otghs, |
289 | omap4_usb_phy_mailbox(glue, val); | 269 | USB_MODE_HOST); |
290 | omap2430_musb_set_vbus(musb, 1); | 270 | omap2430_musb_set_vbus(musb, 1); |
291 | } | 271 | } |
292 | break; | 272 | break; |
@@ -299,8 +279,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
299 | musb->xceiv->last_event = USB_EVENT_VBUS; | 279 | musb->xceiv->last_event = USB_EVENT_VBUS; |
300 | if (musb->gadget_driver) | 280 | if (musb->gadget_driver) |
301 | pm_runtime_get_sync(dev); | 281 | pm_runtime_get_sync(dev); |
302 | val = IDDIG | AVALID | VBUSVALID; | 282 | omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); |
303 | omap4_usb_phy_mailbox(glue, val); | ||
304 | break; | 283 | break; |
305 | 284 | ||
306 | case OMAP_MUSB_ID_FLOAT: | 285 | case OMAP_MUSB_ID_FLOAT: |
@@ -317,8 +296,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue) | |||
317 | if (musb->xceiv->otg->set_vbus) | 296 | if (musb->xceiv->otg->set_vbus) |
318 | otg_set_vbus(musb->xceiv->otg, 0); | 297 | otg_set_vbus(musb->xceiv->otg, 0); |
319 | } | 298 | } |
320 | val = SESSEND | IDDIG; | 299 | omap_control_usb_set_mode(glue->control_otghs, |
321 | omap4_usb_phy_mailbox(glue, val); | 300 | USB_MODE_DISCONNECT); |
322 | break; | 301 | break; |
323 | default: | 302 | default: |
324 | dev_dbg(dev, "ID float\n"); | 303 | dev_dbg(dev, "ID float\n"); |
@@ -366,10 +345,15 @@ static int omap2430_musb_init(struct musb *musb) | |||
366 | * up through ULPI. TWL4030-family PMICs include one, | 345 | * up through ULPI. TWL4030-family PMICs include one, |
367 | * which needs a driver, drivers aren't always needed. | 346 | * which needs a driver, drivers aren't always needed. |
368 | */ | 347 | */ |
369 | musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); | 348 | if (dev->parent->of_node) |
349 | musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent, | ||
350 | "usb-phy", 0); | ||
351 | else | ||
352 | musb->xceiv = devm_usb_get_phy_dev(dev, 0); | ||
353 | |||
370 | if (IS_ERR_OR_NULL(musb->xceiv)) { | 354 | if (IS_ERR_OR_NULL(musb->xceiv)) { |
371 | pr_err("HS USB OTG: no transceiver configured\n"); | 355 | pr_err("HS USB OTG: no transceiver configured\n"); |
372 | return -ENODEV; | 356 | return -EPROBE_DEFER; |
373 | } | 357 | } |
374 | 358 | ||
375 | musb->isr = omap2430_musb_interrupt; | 359 | musb->isr = omap2430_musb_interrupt; |
@@ -415,7 +399,6 @@ err1: | |||
415 | static void omap2430_musb_enable(struct musb *musb) | 399 | static void omap2430_musb_enable(struct musb *musb) |
416 | { | 400 | { |
417 | u8 devctl; | 401 | u8 devctl; |
418 | u32 val; | ||
419 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | 402 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
420 | struct device *dev = musb->controller; | 403 | struct device *dev = musb->controller; |
421 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | 404 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); |
@@ -425,8 +408,7 @@ static void omap2430_musb_enable(struct musb *musb) | |||
425 | switch (glue->status) { | 408 | switch (glue->status) { |
426 | 409 | ||
427 | case OMAP_MUSB_ID_GROUND: | 410 | case OMAP_MUSB_ID_GROUND: |
428 | val = AVALID | VBUSVALID; | 411 | omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST); |
429 | omap4_usb_phy_mailbox(glue, val); | ||
430 | if (data->interface_type != MUSB_INTERFACE_UTMI) | 412 | if (data->interface_type != MUSB_INTERFACE_UTMI) |
431 | break; | 413 | break; |
432 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 414 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
@@ -445,8 +427,7 @@ static void omap2430_musb_enable(struct musb *musb) | |||
445 | break; | 427 | break; |
446 | 428 | ||
447 | case OMAP_MUSB_VBUS_VALID: | 429 | case OMAP_MUSB_VBUS_VALID: |
448 | val = IDDIG | AVALID | VBUSVALID; | 430 | omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE); |
449 | omap4_usb_phy_mailbox(glue, val); | ||
450 | break; | 431 | break; |
451 | 432 | ||
452 | default: | 433 | default: |
@@ -456,14 +437,12 @@ static void omap2430_musb_enable(struct musb *musb) | |||
456 | 437 | ||
457 | static void omap2430_musb_disable(struct musb *musb) | 438 | static void omap2430_musb_disable(struct musb *musb) |
458 | { | 439 | { |
459 | u32 val; | ||
460 | struct device *dev = musb->controller; | 440 | struct device *dev = musb->controller; |
461 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); | 441 | struct omap2430_glue *glue = dev_get_drvdata(dev->parent); |
462 | 442 | ||
463 | if (glue->status != OMAP_MUSB_UNKNOWN) { | 443 | if (glue->status != OMAP_MUSB_UNKNOWN) |
464 | val = SESSEND | IDDIG; | 444 | omap_control_usb_set_mode(glue->control_otghs, |
465 | omap4_usb_phy_mailbox(glue, val); | 445 | USB_MODE_DISCONNECT); |
466 | } | ||
467 | } | 446 | } |
468 | 447 | ||
469 | static int omap2430_musb_exit(struct musb *musb) | 448 | static int omap2430_musb_exit(struct musb *musb) |
@@ -498,7 +477,6 @@ static int omap2430_probe(struct platform_device *pdev) | |||
498 | struct omap2430_glue *glue; | 477 | struct omap2430_glue *glue; |
499 | struct device_node *np = pdev->dev.of_node; | 478 | struct device_node *np = pdev->dev.of_node; |
500 | struct musb_hdrc_config *config; | 479 | struct musb_hdrc_config *config; |
501 | struct resource *res; | ||
502 | int ret = -ENOMEM; | 480 | int ret = -ENOMEM; |
503 | 481 | ||
504 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); | 482 | glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); |
@@ -521,29 +499,23 @@ static int omap2430_probe(struct platform_device *pdev) | |||
521 | glue->musb = musb; | 499 | glue->musb = musb; |
522 | glue->status = OMAP_MUSB_UNKNOWN; | 500 | glue->status = OMAP_MUSB_UNKNOWN; |
523 | 501 | ||
524 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
525 | |||
526 | glue->control_otghs = devm_ioremap_resource(&pdev->dev, res); | ||
527 | |||
528 | if (np) { | 502 | if (np) { |
529 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | 503 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
530 | if (!pdata) { | 504 | if (!pdata) { |
531 | dev_err(&pdev->dev, | 505 | dev_err(&pdev->dev, |
532 | "failed to allocate musb platfrom data\n"); | 506 | "failed to allocate musb platfrom data\n"); |
533 | ret = -ENOMEM; | ||
534 | goto err2; | 507 | goto err2; |
535 | } | 508 | } |
536 | 509 | ||
537 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 510 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
538 | if (!data) { | 511 | if (!data) { |
539 | dev_err(&pdev->dev, | 512 | dev_err(&pdev->dev, |
540 | "failed to allocate musb board data\n"); | 513 | "failed to allocate musb board data\n"); |
541 | ret = -ENOMEM; | ||
542 | goto err2; | 514 | goto err2; |
543 | } | 515 | } |
544 | 516 | ||
545 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); | 517 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); |
546 | if (!data) { | 518 | if (!config) { |
547 | dev_err(&pdev->dev, | 519 | dev_err(&pdev->dev, |
548 | "failed to allocate musb hdrc config\n"); | 520 | "failed to allocate musb hdrc config\n"); |
549 | goto err2; | 521 | goto err2; |
@@ -556,11 +528,22 @@ static int omap2430_probe(struct platform_device *pdev) | |||
556 | of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); | 528 | of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); |
557 | of_property_read_u32(np, "power", (u32 *)&pdata->power); | 529 | of_property_read_u32(np, "power", (u32 *)&pdata->power); |
558 | config->multipoint = of_property_read_bool(np, "multipoint"); | 530 | config->multipoint = of_property_read_bool(np, "multipoint"); |
531 | pdata->has_mailbox = of_property_read_bool(np, | ||
532 | "ti,has-mailbox"); | ||
559 | 533 | ||
560 | pdata->board_data = data; | 534 | pdata->board_data = data; |
561 | pdata->config = config; | 535 | pdata->config = config; |
562 | } | 536 | } |
563 | 537 | ||
538 | if (pdata->has_mailbox) { | ||
539 | glue->control_otghs = omap_get_control_dev(); | ||
540 | if (IS_ERR(glue->control_otghs)) { | ||
541 | dev_vdbg(&pdev->dev, "Failed to get control device\n"); | ||
542 | return -ENODEV; | ||
543 | } | ||
544 | } else { | ||
545 | glue->control_otghs = ERR_PTR(-ENODEV); | ||
546 | } | ||
564 | pdata->platform_ops = &omap2430_ops; | 547 | pdata->platform_ops = &omap2430_ops; |
565 | 548 | ||
566 | platform_set_drvdata(pdev, glue); | 549 | platform_set_drvdata(pdev, glue); |