aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2011-04-18 16:02:00 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-02 19:59:38 -0400
commit83722bc9430424de1614ff31696f73a40b3d81a9 (patch)
tree4ff0ffe40e080ee03b9ede04b3e943b79335335f /drivers/usb/gadget
parent0807c500a1a6d7fa20cbd7bbe7fea14a66112463 (diff)
USB: extend ehci-fsl and fsl_udc_core driver for OTG operation
Signed-off-by: Anatolij Gustschin <agust@denx.de> Cc: Li Yang <leoli@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/fsl_udc_core.c147
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.h2
2 files changed, 134 insertions, 15 deletions
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 28b3a9f25f3b..999eafe89653 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -353,6 +353,19 @@ static void dr_controller_stop(struct fsl_udc *udc)
353{ 353{
354 unsigned int tmp; 354 unsigned int tmp;
355 355
356 pr_debug("%s\n", __func__);
357
358 /* if we're in OTG mode, and the Host is currently using the port,
359 * stop now and don't rip the controller out from under the
360 * ehci driver
361 */
362 if (udc->gadget.is_otg) {
363 if (!(fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)) {
364 pr_debug("udc: Leaving early\n");
365 return;
366 }
367 }
368
356 /* disable all INTR */ 369 /* disable all INTR */
357 fsl_writel(0, &dr_regs->usbintr); 370 fsl_writel(0, &dr_regs->usbintr);
358 371
@@ -1668,6 +1681,9 @@ static void port_change_irq(struct fsl_udc *udc)
1668{ 1681{
1669 u32 speed; 1682 u32 speed;
1670 1683
1684 if (udc->bus_reset)
1685 udc->bus_reset = 0;
1686
1671 /* Bus resetting is finished */ 1687 /* Bus resetting is finished */
1672 if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { 1688 if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
1673 /* Get the speed */ 1689 /* Get the speed */
@@ -1775,6 +1791,8 @@ static void reset_irq(struct fsl_udc *udc)
1775 1791
1776 if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { 1792 if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
1777 VDBG("Bus reset"); 1793 VDBG("Bus reset");
1794 /* Bus is reseting */
1795 udc->bus_reset = 1;
1778 /* Reset all the queues, include XD, dTD, EP queue 1796 /* Reset all the queues, include XD, dTD, EP queue
1779 * head and TR Queue */ 1797 * head and TR Queue */
1780 reset_queues(udc); 1798 reset_queues(udc);
@@ -1852,6 +1870,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
1852 1870
1853 /* Reset Received */ 1871 /* Reset Received */
1854 if (irq_src & USB_STS_RESET) { 1872 if (irq_src & USB_STS_RESET) {
1873 VDBG("reset int");
1855 reset_irq(udc); 1874 reset_irq(udc);
1856 status = IRQ_HANDLED; 1875 status = IRQ_HANDLED;
1857 } 1876 }
@@ -1909,11 +1928,30 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1909 goto out; 1928 goto out;
1910 } 1929 }
1911 1930
1912 /* Enable DR IRQ reg and Set usbcmd reg Run bit */ 1931 if (udc_controller->transceiver) {
1913 dr_controller_run(udc_controller); 1932 /* Suspend the controller until OTG enable it */
1914 udc_controller->usb_state = USB_STATE_ATTACHED; 1933 udc_controller->stopped = 1;
1915 udc_controller->ep0_state = WAIT_FOR_SETUP; 1934 printk(KERN_INFO "Suspend udc for OTG auto detect\n");
1916 udc_controller->ep0_dir = 0; 1935
1936 /* connect to bus through transceiver */
1937 if (udc_controller->transceiver) {
1938 retval = otg_set_peripheral(udc_controller->transceiver,
1939 &udc_controller->gadget);
1940 if (retval < 0) {
1941 ERR("can't bind to transceiver\n");
1942 driver->unbind(&udc_controller->gadget);
1943 udc_controller->gadget.dev.driver = 0;
1944 udc_controller->driver = 0;
1945 return retval;
1946 }
1947 }
1948 } else {
1949 /* Enable DR IRQ reg and set USBCMD reg Run bit */
1950 dr_controller_run(udc_controller);
1951 udc_controller->usb_state = USB_STATE_ATTACHED;
1952 udc_controller->ep0_state = WAIT_FOR_SETUP;
1953 udc_controller->ep0_dir = 0;
1954 }
1917 printk(KERN_INFO "%s: bind to driver %s\n", 1955 printk(KERN_INFO "%s: bind to driver %s\n",
1918 udc_controller->gadget.name, driver->driver.name); 1956 udc_controller->gadget.name, driver->driver.name);
1919 1957
@@ -2374,17 +2412,30 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2374 spin_lock_init(&udc_controller->lock); 2412 spin_lock_init(&udc_controller->lock);
2375 udc_controller->stopped = 1; 2413 udc_controller->stopped = 1;
2376 2414
2415#ifdef CONFIG_USB_OTG
2416 if (pdata->operating_mode == FSL_USB2_DR_OTG) {
2417 udc_controller->transceiver = otg_get_transceiver();
2418 if (!udc_controller->transceiver) {
2419 ERR("Can't find OTG driver!\n");
2420 ret = -ENODEV;
2421 goto err_kfree;
2422 }
2423 }
2424#endif
2425
2377 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2426 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2378 if (!res) { 2427 if (!res) {
2379 ret = -ENXIO; 2428 ret = -ENXIO;
2380 goto err_kfree; 2429 goto err_kfree;
2381 } 2430 }
2382 2431
2383 if (!request_mem_region(res->start, res->end - res->start + 1, 2432 if (pdata->operating_mode == FSL_USB2_DR_DEVICE) {
2384 driver_name)) { 2433 if (!request_mem_region(res->start, res->end - res->start + 1,
2385 ERR("request mem region for %s failed\n", pdev->name); 2434 driver_name)) {
2386 ret = -EBUSY; 2435 ERR("request mem region for %s failed\n", pdev->name);
2387 goto err_kfree; 2436 ret = -EBUSY;
2437 goto err_kfree;
2438 }
2388 } 2439 }
2389 2440
2390 dr_regs = ioremap(res->start, resource_size(res)); 2441 dr_regs = ioremap(res->start, resource_size(res));
@@ -2455,9 +2506,11 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2455 goto err_free_irq; 2506 goto err_free_irq;
2456 } 2507 }
2457 2508
2458 /* initialize usb hw reg except for regs for EP, 2509 if (!udc_controller->transceiver) {
2459 * leave usbintr reg untouched */ 2510 /* initialize usb hw reg except for regs for EP,
2460 dr_controller_setup(udc_controller); 2511 * leave usbintr reg untouched */
2512 dr_controller_setup(udc_controller);
2513 }
2461 2514
2462 fsl_udc_clk_finalize(pdev); 2515 fsl_udc_clk_finalize(pdev);
2463 2516
@@ -2477,6 +2530,9 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
2477 if (ret < 0) 2530 if (ret < 0)
2478 goto err_free_irq; 2531 goto err_free_irq;
2479 2532
2533 if (udc_controller->transceiver)
2534 udc_controller->gadget.is_otg = 1;
2535
2480 /* setup QH and epctrl for ep0 */ 2536 /* setup QH and epctrl for ep0 */
2481 ep0_setup(udc_controller); 2537 ep0_setup(udc_controller);
2482 2538
@@ -2521,7 +2577,8 @@ err_iounmap:
2521err_iounmap_noclk: 2577err_iounmap_noclk:
2522 iounmap(dr_regs); 2578 iounmap(dr_regs);
2523err_release_mem_region: 2579err_release_mem_region:
2524 release_mem_region(res->start, res->end - res->start + 1); 2580 if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
2581 release_mem_region(res->start, res->end - res->start + 1);
2525err_kfree: 2582err_kfree:
2526 kfree(udc_controller); 2583 kfree(udc_controller);
2527 udc_controller = NULL; 2584 udc_controller = NULL;
@@ -2555,7 +2612,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev)
2555 dma_pool_destroy(udc_controller->td_pool); 2612 dma_pool_destroy(udc_controller->td_pool);
2556 free_irq(udc_controller->irq, udc_controller); 2613 free_irq(udc_controller->irq, udc_controller);
2557 iounmap(dr_regs); 2614 iounmap(dr_regs);
2558 release_mem_region(res->start, res->end - res->start + 1); 2615 if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
2616 release_mem_region(res->start, res->end - res->start + 1);
2559 2617
2560 device_unregister(&udc_controller->gadget.dev); 2618 device_unregister(&udc_controller->gadget.dev);
2561 /* free udc --wait for the release() finished */ 2619 /* free udc --wait for the release() finished */
@@ -2598,6 +2656,62 @@ static int fsl_udc_resume(struct platform_device *pdev)
2598 return 0; 2656 return 0;
2599} 2657}
2600 2658
2659static int fsl_udc_otg_suspend(struct device *dev, pm_message_t state)
2660{
2661 struct fsl_udc *udc = udc_controller;
2662 u32 mode, usbcmd;
2663
2664 mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK;
2665
2666 pr_debug("%s(): mode 0x%x stopped %d\n", __func__, mode, udc->stopped);
2667
2668 /*
2669 * If the controller is already stopped, then this must be a
2670 * PM suspend. Remember this fact, so that we will leave the
2671 * controller stopped at PM resume time.
2672 */
2673 if (udc->stopped) {
2674 pr_debug("gadget already stopped, leaving early\n");
2675 udc->already_stopped = 1;
2676 return 0;
2677 }
2678
2679 if (mode != USB_MODE_CTRL_MODE_DEVICE) {
2680 pr_debug("gadget not in device mode, leaving early\n");
2681 return 0;
2682 }
2683
2684 /* stop the controller */
2685 usbcmd = fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP;
2686 fsl_writel(usbcmd, &dr_regs->usbcmd);
2687
2688 udc->stopped = 1;
2689
2690 pr_info("USB Gadget suspended\n");
2691
2692 return 0;
2693}
2694
2695static int fsl_udc_otg_resume(struct device *dev)
2696{
2697 pr_debug("%s(): stopped %d already_stopped %d\n", __func__,
2698 udc_controller->stopped, udc_controller->already_stopped);
2699
2700 /*
2701 * If the controller was stopped at suspend time, then
2702 * don't resume it now.
2703 */
2704 if (udc_controller->already_stopped) {
2705 udc_controller->already_stopped = 0;
2706 pr_debug("gadget was already stopped, leaving early\n");
2707 return 0;
2708 }
2709
2710 pr_info("USB Gadget resume\n");
2711
2712 return fsl_udc_resume(NULL);
2713}
2714
2601/*------------------------------------------------------------------------- 2715/*-------------------------------------------------------------------------
2602 Register entry point for the peripheral controller driver 2716 Register entry point for the peripheral controller driver
2603--------------------------------------------------------------------------*/ 2717--------------------------------------------------------------------------*/
@@ -2610,6 +2724,9 @@ static struct platform_driver udc_driver = {
2610 .driver = { 2724 .driver = {
2611 .name = (char *)driver_name, 2725 .name = (char *)driver_name,
2612 .owner = THIS_MODULE, 2726 .owner = THIS_MODULE,
2727 /* udc suspend/resume called from OTG driver */
2728 .suspend = fsl_udc_otg_suspend,
2729 .resume = fsl_udc_otg_resume,
2613 }, 2730 },
2614}; 2731};
2615 2732
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index 5647cc21b84c..1d51be83fda8 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -476,6 +476,7 @@ struct fsl_udc {
476 unsigned vbus_active:1; 476 unsigned vbus_active:1;
477 unsigned stopped:1; 477 unsigned stopped:1;
478 unsigned remote_wakeup:1; 478 unsigned remote_wakeup:1;
479 unsigned already_stopped:1;
479 unsigned big_endian_desc:1; 480 unsigned big_endian_desc:1;
480 481
481 struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ 482 struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */
@@ -487,6 +488,7 @@ struct fsl_udc {
487 dma_addr_t ep_qh_dma; /* dma address of QH */ 488 dma_addr_t ep_qh_dma; /* dma address of QH */
488 489
489 u32 max_pipes; /* Device max pipes */ 490 u32 max_pipes; /* Device max pipes */
491 u32 bus_reset; /* Device is bus resetting */
490 u32 resume_state; /* USB state to resume */ 492 u32 resume_state; /* USB state to resume */
491 u32 usb_state; /* USB current state */ 493 u32 usb_state; /* USB current state */
492 u32 ep0_state; /* Endpoint zero state */ 494 u32 ep0_state; /* Endpoint zero state */