Lines Matching +full:otg +full:- +full:rev

1 // SPDX-License-Identifier: GPL-2.0+
6 * Jerry Huang <Chang-[email protected]>
33 #include "phy-fsl-usb.h"
42 #define DRIVER_VERSION "Rev. 1.55"
44 #define DRIVER_DESC "Freescale USB OTG Transceiver Driver"
47 static const char driver_name[] = "fsl-usb2-otg";
110 fsl_writel(temp, &usb_dr_regs->ulpiview); in write_ulpi()
114 /* -------------------------------------------------------------*/
115 /* Operations that will be called from OTG Finite State Machine */
122 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_chrg_vbus()
132 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_chrg_vbus()
140 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_dischrg_vbus()
150 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_dischrg_vbus()
153 /* A-device driver vbus, controlled through PP bit in PORTSC */
159 tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; in fsl_otg_drv_vbus()
160 fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); in fsl_otg_drv_vbus()
162 tmp = fsl_readl(&usb_dr_regs->portsc) & in fsl_otg_drv_vbus()
164 fsl_writel(tmp, &usb_dr_regs->portsc); in fsl_otg_drv_vbus()
169 * Pull-up D+, signalling connect by periperal. Also used in
170 * data-line pulsing in SRP
176 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_loc_conn()
183 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_loc_conn()
195 tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; in fsl_otg_loc_sof()
201 fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); in fsl_otg_loc_sof()
205 /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */
212 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_start_pulse()
214 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_start_pulse()
236 fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1); in fsl_otg_pulse_vbus()
238 fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr); in fsl_otg_pulse_vbus()
243 fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0); in b_vbus_pulse_end()
251 fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr); in b_vbus_pulse_end()
259 if ((fsl_otg_dev->phy.otg->state == OTG_STATE_B_SRP_INIT) && in b_srp_end()
260 fsl_otg_dev->fsm.b_sess_vld) in b_srp_end()
261 fsl_otg_dev->fsm.b_srp_done = 1; in b_srp_end()
272 if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) in a_wait_enum()
273 fsl_otg_add_timer(&fsl_otg_dev->fsm, a_wait_enum_tmr); in a_wait_enum()
275 otg_statemachine(&fsl_otg_dev->fsm); in a_wait_enum()
289 (unsigned long)&fsm->a_wait_vrise_tmout); in fsl_otg_init_timers()
291 return -ENOMEM; in fsl_otg_init_timers()
294 (unsigned long)&fsm->a_wait_bcon_tmout); in fsl_otg_init_timers()
296 return -ENOMEM; in fsl_otg_init_timers()
299 (unsigned long)&fsm->a_aidl_bdis_tmout); in fsl_otg_init_timers()
301 return -ENOMEM; in fsl_otg_init_timers()
304 (unsigned long)&fsm->b_ase0_brst_tmout); in fsl_otg_init_timers()
306 return -ENOMEM; in fsl_otg_init_timers()
309 (unsigned long)&fsm->b_se0_srp); in fsl_otg_init_timers()
311 return -ENOMEM; in fsl_otg_init_timers()
314 (unsigned long)&fsm->b_srp_done); in fsl_otg_init_timers()
316 return -ENOMEM; in fsl_otg_init_timers()
321 return -ENOMEM; in fsl_otg_init_timers()
326 return -ENOMEM; in fsl_otg_init_timers()
331 return -ENOMEM; in fsl_otg_init_timers()
336 return -ENOMEM; in fsl_otg_init_timers()
405 timer->count = timer->expires; in fsl_otg_add_timer()
408 timer->count = timer->expires; in fsl_otg_add_timer()
409 list_add_tail(&timer->list, &active_timers); in fsl_otg_add_timer()
431 list_del(&timer->list); in fsl_otg_del_timer()
450 command = fsl_readl(&usb_dr_regs->usbcmd); in otg_reset_controller()
452 fsl_writel(command, &usb_dr_regs->usbcmd); in otg_reset_controller()
453 while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) in otg_reset_controller()
460 struct usb_otg *otg = fsm->otg; in fsl_otg_start_host() local
463 container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_start_host()
466 if (!otg->host) in fsl_otg_start_host()
467 return -ENODEV; in fsl_otg_start_host()
468 dev = otg->host->controller; in fsl_otg_start_host()
474 fsm->a_vbus_vld = in fsl_otg_start_host()
475 !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); in fsl_otg_start_host()
478 if (otg_dev->host_working) in fsl_otg_start_host()
483 if (dev->driver->pm && dev->driver->pm->resume) { in fsl_otg_start_host()
484 retval = dev->driver->pm->resume(dev); in fsl_otg_start_host()
485 if (fsm->id) { in fsl_otg_start_host()
486 /* default-b */ in fsl_otg_start_host()
499 otg_dev->host_working = 1; in fsl_otg_start_host()
503 if (!otg_dev->host_working) in fsl_otg_start_host()
507 if (dev && dev->driver) { in fsl_otg_start_host()
508 if (dev->driver->pm && dev->driver->pm->suspend) in fsl_otg_start_host()
509 retval = dev->driver->pm->suspend(dev); in fsl_otg_start_host()
510 if (fsm->id) in fsl_otg_start_host()
511 /* default-b */ in fsl_otg_start_host()
514 otg_dev->host_working = 0; in fsl_otg_start_host()
527 struct usb_otg *otg = fsm->otg; in fsl_otg_start_gadget() local
530 if (!otg->gadget || !otg->gadget->dev.parent) in fsl_otg_start_gadget()
531 return -ENODEV; in fsl_otg_start_gadget()
534 dev = otg->gadget->dev.parent; in fsl_otg_start_gadget()
537 if (dev->driver->resume) in fsl_otg_start_gadget()
538 dev->driver->resume(dev); in fsl_otg_start_gadget()
540 if (dev->driver->suspend) in fsl_otg_start_gadget()
541 dev->driver->suspend(dev, otg_suspend_state); in fsl_otg_start_gadget()
549 * to the OTG. Suspend host for OTG role detection.
551 static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) in fsl_otg_set_host() argument
555 if (!otg) in fsl_otg_set_host()
556 return -ENODEV; in fsl_otg_set_host()
558 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_set_host()
560 return -ENODEV; in fsl_otg_set_host()
562 otg->host = host; in fsl_otg_set_host()
564 otg_dev->fsm.a_bus_drop = 0; in fsl_otg_set_host()
565 otg_dev->fsm.a_bus_req = 1; in fsl_otg_set_host()
570 otg->host->otg_port = fsl_otg_initdata.otg_port; in fsl_otg_set_host()
571 otg->host->is_b_host = otg_dev->fsm.id; in fsl_otg_set_host()
577 otg_dev->host_working = 1; in fsl_otg_set_host()
578 schedule_delayed_work(&otg_dev->otg_event, 100); in fsl_otg_set_host()
582 if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & in fsl_otg_set_host()
584 /* Mini-A cable connected */ in fsl_otg_set_host()
585 struct otg_fsm *fsm = &otg_dev->fsm; in fsl_otg_set_host()
587 otg->state = OTG_STATE_UNDEFINED; in fsl_otg_set_host()
588 fsm->protocol = PROTO_UNDEF; in fsl_otg_set_host()
592 otg_dev->host_working = 0; in fsl_otg_set_host()
594 otg_statemachine(&otg_dev->fsm); in fsl_otg_set_host()
599 /* Called by initialization code of udc. Register udc to OTG. */
600 static int fsl_otg_set_peripheral(struct usb_otg *otg, in fsl_otg_set_peripheral() argument
605 if (!otg) in fsl_otg_set_peripheral()
606 return -ENODEV; in fsl_otg_set_peripheral()
608 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_set_peripheral()
612 return -ENODEV; in fsl_otg_set_peripheral()
615 if (!otg->default_a) in fsl_otg_set_peripheral()
616 otg->gadget->ops->vbus_draw(otg->gadget, 0); in fsl_otg_set_peripheral()
617 usb_gadget_vbus_disconnect(otg->gadget); in fsl_otg_set_peripheral()
618 otg->gadget = 0; in fsl_otg_set_peripheral()
619 otg_dev->fsm.b_bus_req = 0; in fsl_otg_set_peripheral()
620 otg_statemachine(&otg_dev->fsm); in fsl_otg_set_peripheral()
624 otg->gadget = gadget; in fsl_otg_set_peripheral()
625 otg->gadget->is_a_peripheral = !otg_dev->fsm.id; in fsl_otg_set_peripheral()
627 otg_dev->fsm.b_bus_req = 1; in fsl_otg_set_peripheral()
629 /* start the gadget right away if the ID pin says Mini-B */ in fsl_otg_set_peripheral()
630 pr_debug("ID pin=%d\n", otg_dev->fsm.id); in fsl_otg_set_peripheral()
631 if (otg_dev->fsm.id == 1) { in fsl_otg_set_peripheral()
632 fsl_otg_start_host(&otg_dev->fsm, 0); in fsl_otg_set_peripheral()
633 otg_drv_vbus(&otg_dev->fsm, 0); in fsl_otg_set_peripheral()
634 fsl_otg_start_gadget(&otg_dev->fsm, 1); in fsl_otg_set_peripheral()
643 * When the Mini-A cable is disconnected from the board,
644 * the pin-detect interrupt happens before the disconnect
647 * roles, the pin-detect interrupts are delayed, and handled
653 struct otg_fsm *fsm = &og->fsm; in fsl_otg_event()
655 if (fsm->id) { /* switch to gadget */ in fsl_otg_event()
662 /* B-device start SRP */
663 static int fsl_otg_start_srp(struct usb_otg *otg) in fsl_otg_start_srp() argument
667 if (!otg || otg->state != OTG_STATE_B_IDLE) in fsl_otg_start_srp()
668 return -ENODEV; in fsl_otg_start_srp()
670 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_start_srp()
672 return -ENODEV; in fsl_otg_start_srp()
674 otg_dev->fsm.b_bus_req = 1; in fsl_otg_start_srp()
675 otg_statemachine(&otg_dev->fsm); in fsl_otg_start_srp()
681 static int fsl_otg_start_hnp(struct usb_otg *otg) in fsl_otg_start_hnp() argument
685 if (!otg) in fsl_otg_start_hnp()
686 return -ENODEV; in fsl_otg_start_hnp()
688 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_start_hnp()
690 return -ENODEV; in fsl_otg_start_hnp()
695 otg_dev->fsm.a_bus_req = 0; in fsl_otg_start_hnp()
696 otg_statemachine(&otg_dev->fsm); in fsl_otg_start_hnp()
702 * Interrupt handler. OTG/host/peripheral share the same int line.
703 * OTG driver clears OTGSC interrupts and leaves USB interrupts
709 struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; in fsl_otg_isr()
710 struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; in fsl_otg_isr() local
713 otg_sc = fsl_readl(&usb_dr_regs->otgsc); in fsl_otg_isr()
716 /* Only clear otg interrupts */ in fsl_otg_isr()
717 fsl_writel(otg_sc, &usb_dr_regs->otgsc); in fsl_otg_isr()
720 fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; in fsl_otg_isr()
721 otg->default_a = (fsm->id == 0); in fsl_otg_isr()
723 /* process OTG interrupts */ in fsl_otg_isr()
726 fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; in fsl_otg_isr()
727 otg->default_a = (fsm->id == 0); in fsl_otg_isr()
729 if (fsm->id) in fsl_otg_isr()
730 fsm->b_conn = 0; in fsl_otg_isr()
732 fsm->a_conn = 0; in fsl_otg_isr()
734 if (otg->host) in fsl_otg_isr()
735 otg->host->is_b_host = fsm->id; in fsl_otg_isr()
736 if (otg->gadget) in fsl_otg_isr()
737 otg->gadget->is_a_peripheral = !fsm->id; in fsl_otg_isr()
738 VDBG("ID int (ID is %d)\n", fsm->id); in fsl_otg_isr()
740 if (fsm->id) { /* switch to gadget */ in fsl_otg_isr()
742 &((struct fsl_otg *)dev_id)->otg_event, in fsl_otg_isr()
746 ((struct fsl_otg *)dev_id)-> in fsl_otg_isr()
772 /* Initialize the global variable fsl_otg_dev and request IRQ for OTG */
781 /* allocate space to fsl otg device */ in fsl_otg_conf()
784 return -ENOMEM; in fsl_otg_conf()
786 fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); in fsl_otg_conf()
787 if (!fsl_otg_tc->phy.otg) { in fsl_otg_conf()
789 return -ENOMEM; in fsl_otg_conf()
792 INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); in fsl_otg_conf()
795 status = fsl_otg_init_timers(&fsl_otg_tc->fsm); in fsl_otg_conf()
797 pr_info("Couldn't init OTG timers\n"); in fsl_otg_conf()
800 mutex_init(&fsl_otg_tc->fsm.lock); in fsl_otg_conf()
802 /* Set OTG state machine operations */ in fsl_otg_conf()
803 fsl_otg_tc->fsm.ops = &fsl_otg_ops; in fsl_otg_conf()
805 /* initialize the otg structure */ in fsl_otg_conf()
806 fsl_otg_tc->phy.label = DRIVER_DESC; in fsl_otg_conf()
807 fsl_otg_tc->phy.dev = &pdev->dev; in fsl_otg_conf()
809 fsl_otg_tc->phy.otg->usb_phy = &fsl_otg_tc->phy; in fsl_otg_conf()
810 fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; in fsl_otg_conf()
811 fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; in fsl_otg_conf()
812 fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; in fsl_otg_conf()
813 fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; in fsl_otg_conf()
817 /* Store the otg transceiver */ in fsl_otg_conf()
818 status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); in fsl_otg_conf()
820 pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); in fsl_otg_conf()
827 kfree(fsl_otg_tc->phy.otg); in fsl_otg_conf()
832 /* OTG Initialization */
841 struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); in usb_otg_start()
844 fsm = &p_otg->fsm; in usb_otg_start()
848 fsm->otg = p_otg->phy.otg; in usb_otg_start()
853 return -ENXIO; in usb_otg_start()
858 usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); in usb_otg_start()
859 p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; in usb_otg_start()
860 pdata->regs = (void *)usb_dr_regs; in usb_otg_start()
862 if (pdata->init && pdata->init(pdev) != 0) in usb_otg_start()
863 return -EINVAL; in usb_otg_start()
866 if (pdata->big_endian_mmio) { in usb_otg_start()
876 p_otg->irq = platform_get_irq(pdev, 0); in usb_otg_start()
877 if (p_otg->irq < 0) in usb_otg_start()
878 return p_otg->irq; in usb_otg_start()
879 status = request_irq(p_otg->irq, fsl_otg_isr, in usb_otg_start()
882 dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", in usb_otg_start()
883 p_otg->irq, status); in usb_otg_start()
884 iounmap(p_otg->dr_mem_map); in usb_otg_start()
885 kfree(p_otg->phy.otg); in usb_otg_start()
891 temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); in usb_otg_start()
893 fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); in usb_otg_start()
896 temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); in usb_otg_start()
898 fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); in usb_otg_start()
901 while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) in usb_otg_start()
905 temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); in usb_otg_start()
906 fsl_writel(temp, &p_otg->dr_mem_map->usbmode); in usb_otg_start()
909 temp = fsl_readl(&p_otg->dr_mem_map->portsc); in usb_otg_start()
911 switch (pdata->phy_mode) { in usb_otg_start()
924 fsl_writel(temp, &p_otg->dr_mem_map->portsc); in usb_otg_start()
926 if (pdata->have_sysif_regs) { in usb_otg_start()
928 temp = __raw_readl(&p_otg->dr_mem_map->control); in usb_otg_start()
930 __raw_writel(temp, &p_otg->dr_mem_map->control); in usb_otg_start()
934 temp = fsl_readl(&p_otg->dr_mem_map->otgsc); in usb_otg_start()
937 fsl_writel(temp, &p_otg->dr_mem_map->otgsc); in usb_otg_start()
940 * The identification (id) input is FALSE when a Mini-A plug is inserted in usb_otg_start()
941 * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. in usb_otg_start()
944 if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { in usb_otg_start()
945 p_otg->phy.otg->state = OTG_STATE_UNDEFINED; in usb_otg_start()
946 p_otg->fsm.id = 1; in usb_otg_start()
948 p_otg->phy.otg->state = OTG_STATE_A_IDLE; in usb_otg_start()
949 p_otg->fsm.id = 0; in usb_otg_start()
952 pr_debug("initial ID pin=%d\n", p_otg->fsm.id); in usb_otg_start()
954 /* enable OTG ID pin interrupt */ in usb_otg_start()
955 temp = fsl_readl(&p_otg->dr_mem_map->otgsc); in usb_otg_start()
958 fsl_writel(temp, &p_otg->dr_mem_map->otgsc); in usb_otg_start()
967 if (!dev_get_platdata(&pdev->dev)) in fsl_otg_probe()
968 return -ENODEV; in fsl_otg_probe()
970 /* configure the OTG */ in fsl_otg_probe()
973 dev_err(&pdev->dev, "Couldn't configure OTG module\n"); in fsl_otg_probe()
977 /* start OTG */ in fsl_otg_probe()
980 dev_err(&pdev->dev, "Can't init FSL OTG device\n"); in fsl_otg_probe()
989 struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); in fsl_otg_remove()
991 usb_remove_phy(&fsl_otg_dev->phy); in fsl_otg_remove()
992 free_irq(fsl_otg_dev->irq, fsl_otg_dev); in fsl_otg_remove()
997 kfree(fsl_otg_dev->phy.otg); in fsl_otg_remove()
1000 if (pdata->exit) in fsl_otg_remove()
1001 pdata->exit(pdev); in fsl_otg_remove()