Lines Matching +full:otg +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0+
6 * Jerry Huang <Chang-Ming.Huang@freescale.com>
32 #include "phy-fsl-usb.h"
43 #define DRIVER_DESC "Freescale USB OTG Transceiver Driver"
46 static const char driver_name[] = "fsl-usb2-otg";
109 fsl_writel(temp, &usb_dr_regs->ulpiview); in write_ulpi()
113 /* -------------------------------------------------------------*/
114 /* Operations that will be called from OTG Finite State Machine */
121 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_chrg_vbus()
131 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_chrg_vbus()
139 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_dischrg_vbus()
149 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_dischrg_vbus()
152 /* A-device driver vbus, controlled through PP bit in PORTSC */
158 tmp = fsl_readl(&usb_dr_regs->portsc) & ~PORTSC_W1C_BITS; in fsl_otg_drv_vbus()
159 fsl_writel(tmp | PORTSC_PORT_POWER, &usb_dr_regs->portsc); in fsl_otg_drv_vbus()
161 tmp = fsl_readl(&usb_dr_regs->portsc) & in fsl_otg_drv_vbus()
163 fsl_writel(tmp, &usb_dr_regs->portsc); in fsl_otg_drv_vbus()
168 * Pull-up D+, signalling connect by periperal. Also used in
169 * data-line pulsing in SRP
175 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_loc_conn()
182 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_loc_conn()
194 tmp = fsl_readl(&fsl_otg_dev->dr_mem_map->portsc) & ~PORTSC_W1C_BITS; in fsl_otg_loc_sof()
200 fsl_writel(tmp, &fsl_otg_dev->dr_mem_map->portsc); in fsl_otg_loc_sof()
204 /* Start SRP pulsing by data-line pulsing, followed with v-bus pulsing. */
211 tmp = fsl_readl(&usb_dr_regs->otgsc) & ~OTGSC_INTSTS_MASK; in fsl_otg_start_pulse()
213 fsl_writel(tmp, &usb_dr_regs->otgsc); in fsl_otg_start_pulse()
235 fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 1); in fsl_otg_pulse_vbus()
237 fsl_otg_add_timer(&fsl_otg_dev->fsm, b_vbus_pulse_tmr); in fsl_otg_pulse_vbus()
242 fsl_otg_chrg_vbus(&fsl_otg_dev->fsm, 0); in b_vbus_pulse_end()
250 fsl_otg_add_timer(&fsl_otg_dev->fsm, b_srp_wait_tmr); in b_vbus_pulse_end()
258 if ((fsl_otg_dev->phy.otg->state == OTG_STATE_B_SRP_INIT) && in b_srp_end()
259 fsl_otg_dev->fsm.b_sess_vld) in b_srp_end()
260 fsl_otg_dev->fsm.b_srp_done = 1; in b_srp_end()
271 if (!fsl_otg_dev->phy.otg->host->b_hnp_enable) in a_wait_enum()
272 fsl_otg_add_timer(&fsl_otg_dev->fsm, a_wait_enum_tmr); in a_wait_enum()
274 otg_statemachine(&fsl_otg_dev->fsm); in a_wait_enum()
288 (unsigned long)&fsm->a_wait_vrise_tmout); in fsl_otg_init_timers()
290 return -ENOMEM; in fsl_otg_init_timers()
293 (unsigned long)&fsm->a_wait_bcon_tmout); in fsl_otg_init_timers()
295 return -ENOMEM; in fsl_otg_init_timers()
298 (unsigned long)&fsm->a_aidl_bdis_tmout); in fsl_otg_init_timers()
300 return -ENOMEM; in fsl_otg_init_timers()
303 (unsigned long)&fsm->b_ase0_brst_tmout); in fsl_otg_init_timers()
305 return -ENOMEM; in fsl_otg_init_timers()
308 (unsigned long)&fsm->b_se0_srp); in fsl_otg_init_timers()
310 return -ENOMEM; in fsl_otg_init_timers()
313 (unsigned long)&fsm->b_srp_done); in fsl_otg_init_timers()
315 return -ENOMEM; in fsl_otg_init_timers()
320 return -ENOMEM; in fsl_otg_init_timers()
325 return -ENOMEM; in fsl_otg_init_timers()
330 return -ENOMEM; in fsl_otg_init_timers()
335 return -ENOMEM; in fsl_otg_init_timers()
404 timer->count = timer->expires; in fsl_otg_add_timer()
407 timer->count = timer->expires; in fsl_otg_add_timer()
408 list_add_tail(&timer->list, &active_timers); in fsl_otg_add_timer()
430 list_del(&timer->list); in fsl_otg_del_timer()
449 command = fsl_readl(&usb_dr_regs->usbcmd); in otg_reset_controller()
451 fsl_writel(command, &usb_dr_regs->usbcmd); in otg_reset_controller()
452 while (fsl_readl(&usb_dr_regs->usbcmd) & (1 << 1)) in otg_reset_controller()
459 struct usb_otg *otg = fsm->otg; in fsl_otg_start_host() local
462 container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_start_host()
465 if (!otg->host) in fsl_otg_start_host()
466 return -ENODEV; in fsl_otg_start_host()
467 dev = otg->host->controller; in fsl_otg_start_host()
473 fsm->a_vbus_vld = in fsl_otg_start_host()
474 !!(fsl_readl(&usb_dr_regs->otgsc) & OTGSC_STS_A_VBUS_VALID); in fsl_otg_start_host()
477 if (otg_dev->host_working) in fsl_otg_start_host()
482 if (dev->driver->pm && dev->driver->pm->resume) { in fsl_otg_start_host()
483 retval = dev->driver->pm->resume(dev); in fsl_otg_start_host()
484 if (fsm->id) { in fsl_otg_start_host()
485 /* default-b */ in fsl_otg_start_host()
498 otg_dev->host_working = 1; in fsl_otg_start_host()
502 if (!otg_dev->host_working) in fsl_otg_start_host()
506 if (dev && dev->driver) { in fsl_otg_start_host()
507 if (dev->driver->pm && dev->driver->pm->suspend) in fsl_otg_start_host()
508 retval = dev->driver->pm->suspend(dev); in fsl_otg_start_host()
509 if (fsm->id) in fsl_otg_start_host()
510 /* default-b */ in fsl_otg_start_host()
513 otg_dev->host_working = 0; in fsl_otg_start_host()
526 struct usb_otg *otg = fsm->otg; in fsl_otg_start_gadget() local
529 if (!otg->gadget || !otg->gadget->dev.parent) in fsl_otg_start_gadget()
530 return -ENODEV; in fsl_otg_start_gadget()
533 dev = otg->gadget->dev.parent; in fsl_otg_start_gadget()
536 if (dev->driver->resume) in fsl_otg_start_gadget()
537 dev->driver->resume(dev); in fsl_otg_start_gadget()
539 if (dev->driver->suspend) in fsl_otg_start_gadget()
540 dev->driver->suspend(dev, otg_suspend_state); in fsl_otg_start_gadget()
548 * to the OTG. Suspend host for OTG role detection.
550 static int fsl_otg_set_host(struct usb_otg *otg, struct usb_bus *host) in fsl_otg_set_host() argument
554 if (!otg) in fsl_otg_set_host()
555 return -ENODEV; in fsl_otg_set_host()
557 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_set_host()
559 return -ENODEV; in fsl_otg_set_host()
561 otg->host = host; in fsl_otg_set_host()
563 otg_dev->fsm.a_bus_drop = 0; in fsl_otg_set_host()
564 otg_dev->fsm.a_bus_req = 1; in fsl_otg_set_host()
569 otg->host->otg_port = fsl_otg_initdata.otg_port; in fsl_otg_set_host()
570 otg->host->is_b_host = otg_dev->fsm.id; in fsl_otg_set_host()
576 otg_dev->host_working = 1; in fsl_otg_set_host()
577 schedule_delayed_work(&otg_dev->otg_event, 100); in fsl_otg_set_host()
581 if (!(fsl_readl(&otg_dev->dr_mem_map->otgsc) & in fsl_otg_set_host()
583 /* Mini-A cable connected */ in fsl_otg_set_host()
584 struct otg_fsm *fsm = &otg_dev->fsm; in fsl_otg_set_host()
586 otg->state = OTG_STATE_UNDEFINED; in fsl_otg_set_host()
587 fsm->protocol = PROTO_UNDEF; in fsl_otg_set_host()
591 otg_dev->host_working = 0; in fsl_otg_set_host()
593 otg_statemachine(&otg_dev->fsm); in fsl_otg_set_host()
598 /* Called by initialization code of udc. Register udc to OTG. */
599 static int fsl_otg_set_peripheral(struct usb_otg *otg, in fsl_otg_set_peripheral() argument
604 if (!otg) in fsl_otg_set_peripheral()
605 return -ENODEV; in fsl_otg_set_peripheral()
607 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_set_peripheral()
611 return -ENODEV; in fsl_otg_set_peripheral()
614 if (!otg->default_a) in fsl_otg_set_peripheral()
615 otg->gadget->ops->vbus_draw(otg->gadget, 0); in fsl_otg_set_peripheral()
616 usb_gadget_vbus_disconnect(otg->gadget); in fsl_otg_set_peripheral()
617 otg->gadget = 0; in fsl_otg_set_peripheral()
618 otg_dev->fsm.b_bus_req = 0; in fsl_otg_set_peripheral()
619 otg_statemachine(&otg_dev->fsm); in fsl_otg_set_peripheral()
623 otg->gadget = gadget; in fsl_otg_set_peripheral()
624 otg->gadget->is_a_peripheral = !otg_dev->fsm.id; in fsl_otg_set_peripheral()
626 otg_dev->fsm.b_bus_req = 1; in fsl_otg_set_peripheral()
628 /* start the gadget right away if the ID pin says Mini-B */ in fsl_otg_set_peripheral()
629 pr_debug("ID pin=%d\n", otg_dev->fsm.id); in fsl_otg_set_peripheral()
630 if (otg_dev->fsm.id == 1) { in fsl_otg_set_peripheral()
631 fsl_otg_start_host(&otg_dev->fsm, 0); in fsl_otg_set_peripheral()
632 otg_drv_vbus(&otg_dev->fsm, 0); in fsl_otg_set_peripheral()
633 fsl_otg_start_gadget(&otg_dev->fsm, 1); in fsl_otg_set_peripheral()
642 * When the Mini-A cable is disconnected from the board,
643 * the pin-detect interrupt happens before the disconnect
646 * roles, the pin-detect interrupts are delayed, and handled
652 struct otg_fsm *fsm = &og->fsm; in fsl_otg_event()
654 if (fsm->id) { /* switch to gadget */ in fsl_otg_event()
661 /* B-device start SRP */
662 static int fsl_otg_start_srp(struct usb_otg *otg) in fsl_otg_start_srp() argument
666 if (!otg || otg->state != OTG_STATE_B_IDLE) in fsl_otg_start_srp()
667 return -ENODEV; in fsl_otg_start_srp()
669 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_start_srp()
671 return -ENODEV; in fsl_otg_start_srp()
673 otg_dev->fsm.b_bus_req = 1; in fsl_otg_start_srp()
674 otg_statemachine(&otg_dev->fsm); in fsl_otg_start_srp()
680 static int fsl_otg_start_hnp(struct usb_otg *otg) in fsl_otg_start_hnp() argument
684 if (!otg) in fsl_otg_start_hnp()
685 return -ENODEV; in fsl_otg_start_hnp()
687 otg_dev = container_of(otg->usb_phy, struct fsl_otg, phy); in fsl_otg_start_hnp()
689 return -ENODEV; in fsl_otg_start_hnp()
694 otg_dev->fsm.a_bus_req = 0; in fsl_otg_start_hnp()
695 otg_statemachine(&otg_dev->fsm); in fsl_otg_start_hnp()
701 * Interrupt handler. OTG/host/peripheral share the same int line.
702 * OTG driver clears OTGSC interrupts and leaves USB interrupts
708 struct otg_fsm *fsm = &((struct fsl_otg *)dev_id)->fsm; in fsl_otg_isr()
709 struct usb_otg *otg = ((struct fsl_otg *)dev_id)->phy.otg; in fsl_otg_isr() local
712 otg_sc = fsl_readl(&usb_dr_regs->otgsc); in fsl_otg_isr()
715 /* Only clear otg interrupts */ in fsl_otg_isr()
716 fsl_writel(otg_sc, &usb_dr_regs->otgsc); in fsl_otg_isr()
718 /*FIXME: ID change not generate when init to 0 */ in fsl_otg_isr()
719 fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; in fsl_otg_isr()
720 otg->default_a = (fsm->id == 0); in fsl_otg_isr()
722 /* process OTG interrupts */ in fsl_otg_isr()
725 fsm->id = (otg_sc & OTGSC_STS_USB_ID) ? 1 : 0; in fsl_otg_isr()
726 otg->default_a = (fsm->id == 0); in fsl_otg_isr()
728 if (fsm->id) in fsl_otg_isr()
729 fsm->b_conn = 0; in fsl_otg_isr()
731 fsm->a_conn = 0; in fsl_otg_isr()
733 if (otg->host) in fsl_otg_isr()
734 otg->host->is_b_host = fsm->id; in fsl_otg_isr()
735 if (otg->gadget) in fsl_otg_isr()
736 otg->gadget->is_a_peripheral = !fsm->id; in fsl_otg_isr()
737 VDBG("ID int (ID is %d)\n", fsm->id); in fsl_otg_isr()
739 if (fsm->id) { /* switch to gadget */ in fsl_otg_isr()
741 &((struct fsl_otg *)dev_id)->otg_event, in fsl_otg_isr()
745 ((struct fsl_otg *)dev_id)-> in fsl_otg_isr()
771 /* Initialize the global variable fsl_otg_dev and request IRQ for OTG */
780 /* allocate space to fsl otg device */ in fsl_otg_conf()
783 return -ENOMEM; in fsl_otg_conf()
785 fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); in fsl_otg_conf()
786 if (!fsl_otg_tc->phy.otg) { in fsl_otg_conf()
788 return -ENOMEM; in fsl_otg_conf()
791 INIT_DELAYED_WORK(&fsl_otg_tc->otg_event, fsl_otg_event); in fsl_otg_conf()
794 status = fsl_otg_init_timers(&fsl_otg_tc->fsm); in fsl_otg_conf()
796 pr_info("Couldn't init OTG timers\n"); in fsl_otg_conf()
799 mutex_init(&fsl_otg_tc->fsm.lock); in fsl_otg_conf()
801 /* Set OTG state machine operations */ in fsl_otg_conf()
802 fsl_otg_tc->fsm.ops = &fsl_otg_ops; in fsl_otg_conf()
804 /* initialize the otg structure */ in fsl_otg_conf()
805 fsl_otg_tc->phy.label = DRIVER_DESC; in fsl_otg_conf()
806 fsl_otg_tc->phy.dev = &pdev->dev; in fsl_otg_conf()
808 fsl_otg_tc->phy.otg->usb_phy = &fsl_otg_tc->phy; in fsl_otg_conf()
809 fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host; in fsl_otg_conf()
810 fsl_otg_tc->phy.otg->set_peripheral = fsl_otg_set_peripheral; in fsl_otg_conf()
811 fsl_otg_tc->phy.otg->start_hnp = fsl_otg_start_hnp; in fsl_otg_conf()
812 fsl_otg_tc->phy.otg->start_srp = fsl_otg_start_srp; in fsl_otg_conf()
816 /* Store the otg transceiver */ in fsl_otg_conf()
817 status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); in fsl_otg_conf()
819 pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); in fsl_otg_conf()
826 kfree(fsl_otg_tc->phy.otg); in fsl_otg_conf()
831 /* OTG Initialization */
840 struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); in usb_otg_start()
843 fsm = &p_otg->fsm; in usb_otg_start()
847 fsm->otg = p_otg->phy.otg; in usb_otg_start()
852 return -ENXIO; in usb_otg_start()
857 usb_dr_regs = ioremap(res->start, sizeof(struct usb_dr_mmap)); in usb_otg_start()
858 p_otg->dr_mem_map = (struct usb_dr_mmap *)usb_dr_regs; in usb_otg_start()
859 pdata->regs = (void *)usb_dr_regs; in usb_otg_start()
861 if (pdata->init && pdata->init(pdev) != 0) in usb_otg_start()
862 return -EINVAL; in usb_otg_start()
865 if (pdata->big_endian_mmio) { in usb_otg_start()
875 p_otg->irq = platform_get_irq(pdev, 0); in usb_otg_start()
876 if (p_otg->irq < 0) in usb_otg_start()
877 return p_otg->irq; in usb_otg_start()
878 status = request_irq(p_otg->irq, fsl_otg_isr, in usb_otg_start()
881 dev_dbg(p_otg->phy.dev, "can't get IRQ %d, error %d\n", in usb_otg_start()
882 p_otg->irq, status); in usb_otg_start()
883 iounmap(p_otg->dr_mem_map); in usb_otg_start()
884 kfree(p_otg->phy.otg); in usb_otg_start()
890 temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); in usb_otg_start()
892 fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); in usb_otg_start()
895 temp = fsl_readl(&p_otg->dr_mem_map->usbcmd); in usb_otg_start()
897 fsl_writel(temp, &p_otg->dr_mem_map->usbcmd); in usb_otg_start()
900 while (fsl_readl(&p_otg->dr_mem_map->usbcmd) & USB_CMD_CTRL_RESET) in usb_otg_start()
904 temp = USB_MODE_STREAM_DISABLE | (pdata->es ? USB_MODE_ES : 0); in usb_otg_start()
905 fsl_writel(temp, &p_otg->dr_mem_map->usbmode); in usb_otg_start()
908 temp = fsl_readl(&p_otg->dr_mem_map->portsc); in usb_otg_start()
910 switch (pdata->phy_mode) { in usb_otg_start()
923 fsl_writel(temp, &p_otg->dr_mem_map->portsc); in usb_otg_start()
925 if (pdata->have_sysif_regs) { in usb_otg_start()
927 temp = __raw_readl(&p_otg->dr_mem_map->control); in usb_otg_start()
929 __raw_writel(temp, &p_otg->dr_mem_map->control); in usb_otg_start()
933 temp = fsl_readl(&p_otg->dr_mem_map->otgsc); in usb_otg_start()
936 fsl_writel(temp, &p_otg->dr_mem_map->otgsc); in usb_otg_start()
939 * The identification (id) input is FALSE when a Mini-A plug is inserted in usb_otg_start()
940 * in the devices Mini-AB receptacle. Otherwise, this input is TRUE. in usb_otg_start()
941 * Also: record initial state of ID pin in usb_otg_start()
943 if (fsl_readl(&p_otg->dr_mem_map->otgsc) & OTGSC_STS_USB_ID) { in usb_otg_start()
944 p_otg->phy.otg->state = OTG_STATE_UNDEFINED; in usb_otg_start()
945 p_otg->fsm.id = 1; in usb_otg_start()
947 p_otg->phy.otg->state = OTG_STATE_A_IDLE; in usb_otg_start()
948 p_otg->fsm.id = 0; in usb_otg_start()
951 pr_debug("initial ID pin=%d\n", p_otg->fsm.id); in usb_otg_start()
953 /* enable OTG ID pin interrupt */ in usb_otg_start()
954 temp = fsl_readl(&p_otg->dr_mem_map->otgsc); in usb_otg_start()
957 fsl_writel(temp, &p_otg->dr_mem_map->otgsc); in usb_otg_start()
966 if (!dev_get_platdata(&pdev->dev)) in fsl_otg_probe()
967 return -ENODEV; in fsl_otg_probe()
969 /* configure the OTG */ in fsl_otg_probe()
972 dev_err(&pdev->dev, "Couldn't configure OTG module\n"); in fsl_otg_probe()
976 /* start OTG */ in fsl_otg_probe()
979 dev_err(&pdev->dev, "Can't init FSL OTG device\n"); in fsl_otg_probe()
988 struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); in fsl_otg_remove()
990 usb_remove_phy(&fsl_otg_dev->phy); in fsl_otg_remove()
991 free_irq(fsl_otg_dev->irq, fsl_otg_dev); in fsl_otg_remove()
996 kfree(fsl_otg_dev->phy.otg); in fsl_otg_remove()
999 if (pdata->exit) in fsl_otg_remove()
1000 pdata->exit(pdev); in fsl_otg_remove()