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

1 // SPDX-License-Identifier: GPL-2.0
3 * otg_fsm.c - ChipIdea USB IP core OTG FSM driver
11 * This file mainly handles OTG fsm, it includes OTG fsm operations
15 * - ADP
16 * - OTG test device
19 #include <linux/usb/otg.h>
27 #include "otg.h"
30 /* Add for otg: interact with user space app */
40 t = scnprintf(next, size, "%d\n", ci->fsm.a_bus_req); in a_bus_req_show()
41 size -= t; in a_bus_req_show()
44 return PAGE_SIZE - size; in a_bus_req_show()
54 return -1; in a_bus_req_store()
56 mutex_lock(&ci->fsm.lock); in a_bus_req_store()
58 ci->fsm.a_bus_req = 0; in a_bus_req_store()
61 if (ci->fsm.a_bus_drop) { in a_bus_req_store()
62 mutex_unlock(&ci->fsm.lock); in a_bus_req_store()
65 ci->fsm.a_bus_req = 1; in a_bus_req_store()
66 if (ci->fsm.otg->state == OTG_STATE_A_PERIPHERAL) { in a_bus_req_store()
67 ci->gadget.host_request_flag = 1; in a_bus_req_store()
68 mutex_unlock(&ci->fsm.lock); in a_bus_req_store()
74 mutex_unlock(&ci->fsm.lock); in a_bus_req_store()
89 t = scnprintf(next, size, "%d\n", ci->fsm.a_bus_drop); in a_bus_drop_show()
90 size -= t; in a_bus_drop_show()
93 return PAGE_SIZE - size; in a_bus_drop_show()
103 return -1; in a_bus_drop_store()
105 mutex_lock(&ci->fsm.lock); in a_bus_drop_store()
107 ci->fsm.a_bus_drop = 0; in a_bus_drop_store()
109 ci->fsm.a_bus_drop = 1; in a_bus_drop_store()
110 ci->fsm.a_bus_req = 0; in a_bus_drop_store()
114 mutex_unlock(&ci->fsm.lock); in a_bus_drop_store()
129 t = scnprintf(next, size, "%d\n", ci->fsm.b_bus_req); in b_bus_req_show()
130 size -= t; in b_bus_req_show()
133 return PAGE_SIZE - size; in b_bus_req_show()
143 return -1; in b_bus_req_store()
145 mutex_lock(&ci->fsm.lock); in b_bus_req_store()
147 ci->fsm.b_bus_req = 0; in b_bus_req_store()
149 ci->fsm.b_bus_req = 1; in b_bus_req_store()
150 if (ci->fsm.otg->state == OTG_STATE_B_PERIPHERAL) { in b_bus_req_store()
151 ci->gadget.host_request_flag = 1; in b_bus_req_store()
152 mutex_unlock(&ci->fsm.lock); in b_bus_req_store()
158 mutex_unlock(&ci->fsm.lock); in b_bus_req_store()
171 return -1; in a_clr_err_store()
173 mutex_lock(&ci->fsm.lock); in a_clr_err_store()
175 ci->fsm.a_clr_err = 1; in a_clr_err_store()
178 mutex_unlock(&ci->fsm.lock); in a_clr_err_store()
199 * by enum otg_fsm_timer in include/linux/usb/otg-fsm.h
226 spin_lock_irqsave(&ci->lock, flags); in ci_otg_add_timer()
229 ci->hr_timeouts[t] = ktime_add(ktime_get(), in ci_otg_add_timer()
231 ci->enabled_otg_timer_bits |= (1 << t); in ci_otg_add_timer()
232 if ((ci->next_otg_timer == NUM_OTG_FSM_TIMERS) || in ci_otg_add_timer()
233 ktime_after(ci->hr_timeouts[ci->next_otg_timer], in ci_otg_add_timer()
234 ci->hr_timeouts[t])) { in ci_otg_add_timer()
235 ci->next_otg_timer = t; in ci_otg_add_timer()
236 hrtimer_start_range_ns(&ci->otg_fsm_hrtimer, in ci_otg_add_timer()
237 ci->hr_timeouts[t], NSEC_PER_MSEC, in ci_otg_add_timer()
240 spin_unlock_irqrestore(&ci->lock, flags); in ci_otg_add_timer()
252 !(ci->enabled_otg_timer_bits & (1 << t))) in ci_otg_del_timer()
255 spin_lock_irqsave(&ci->lock, flags); in ci_otg_del_timer()
256 ci->enabled_otg_timer_bits &= ~(1 << t); in ci_otg_del_timer()
257 if (ci->next_otg_timer == t) { in ci_otg_del_timer()
258 if (ci->enabled_otg_timer_bits == 0) { in ci_otg_del_timer()
259 spin_unlock_irqrestore(&ci->lock, flags); in ci_otg_del_timer()
261 hrtimer_cancel(&ci->otg_fsm_hrtimer); in ci_otg_del_timer()
262 spin_lock_irqsave(&ci->lock, flags); in ci_otg_del_timer()
263 ci->next_otg_timer = NUM_OTG_FSM_TIMERS; in ci_otg_del_timer()
266 enabled_timer_bits = ci->enabled_otg_timer_bits; in ci_otg_del_timer()
270 ktime_before(ci->hr_timeouts[next_timer], in ci_otg_del_timer()
271 ci->hr_timeouts[cur_timer])) in ci_otg_del_timer()
277 ci->next_otg_timer = next_timer; in ci_otg_del_timer()
278 hrtimer_start_range_ns(&ci->otg_fsm_hrtimer, in ci_otg_del_timer()
279 ci->hr_timeouts[next_timer], NSEC_PER_MSEC, in ci_otg_del_timer()
282 spin_unlock_irqrestore(&ci->lock, flags); in ci_otg_del_timer()
285 /* OTG FSM timer handlers */
288 ci->fsm.a_wait_vrise_tmout = 1; in a_wait_vrise_tmout()
294 ci->fsm.a_wait_vfall_tmout = 1; in a_wait_vfall_tmout()
300 ci->fsm.a_wait_bcon_tmout = 1; in a_wait_bcon_tmout()
306 ci->fsm.a_aidl_bdis_tmout = 1; in a_aidl_bdis_tmout()
312 ci->fsm.b_ase0_brst_tmout = 1; in b_ase0_brst_tmout()
318 ci->fsm.a_bidl_adis_tmout = 1; in a_bidl_adis_tmout()
324 ci->fsm.a_bus_suspend = 1; in b_aidl_bdis_tmout()
330 ci->fsm.b_se0_srp = 1; in b_se0_srp_tmout()
336 ci->fsm.b_srp_done = 1; in b_srp_fail_tmout()
342 ci->fsm.b_srp_done = 1; in b_data_pls_tmout()
343 ci->fsm.b_bus_req = 0; in b_data_pls_tmout()
344 if (ci->fsm.power_up) in b_data_pls_tmout()
345 ci->fsm.power_up = 0; in b_data_pls_tmout()
347 pm_runtime_put(ci->dev); in b_data_pls_tmout()
353 ci->fsm.b_ssend_srp = 1; in b_ssend_srp_tmout()
355 if (ci->fsm.otg->state == OTG_STATE_B_IDLE) in b_ssend_srp_tmout()
363 * by enum otg_fsm_timer in include/linux/usb/otg-fsm.h
390 int ret = -EINVAL; in ci_otg_hrtimer_func()
392 spin_lock_irqsave(&ci->lock, flags); in ci_otg_hrtimer_func()
393 enabled_timer_bits = ci->enabled_otg_timer_bits; in ci_otg_hrtimer_func()
394 ci->next_otg_timer = NUM_OTG_FSM_TIMERS; in ci_otg_hrtimer_func()
398 if (ktime_compare(now, ci->hr_timeouts[cur_timer]) >= 0) { in ci_otg_hrtimer_func()
399 ci->enabled_otg_timer_bits &= ~(1 << cur_timer); in ci_otg_hrtimer_func()
404 ktime_before(ci->hr_timeouts[cur_timer], in ci_otg_hrtimer_func()
405 ci->hr_timeouts[next_timer])) in ci_otg_hrtimer_func()
411 timeout = &ci->hr_timeouts[next_timer]; in ci_otg_hrtimer_func()
412 hrtimer_start_range_ns(&ci->otg_fsm_hrtimer, *timeout, in ci_otg_hrtimer_func()
414 ci->next_otg_timer = next_timer; in ci_otg_hrtimer_func()
416 spin_unlock_irqrestore(&ci->lock, flags); in ci_otg_hrtimer_func()
427 hrtimer_setup(&ci->otg_fsm_hrtimer, ci_otg_hrtimer_func, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); in ci_otg_init_timers()
432 /* -------------------------------------------------------------*/
433 /* Operations that will be called from OTG Finite State Machine */
434 /* -------------------------------------------------------------*/
454 * A-device drive vbus: turn on vbus regulator and enable port power
466 if (ci->platdata->reg_vbus) { in ci_otg_drv_vbus()
467 ret = regulator_enable(ci->platdata->reg_vbus); in ci_otg_drv_vbus()
469 dev_err(ci->dev, in ci_otg_drv_vbus()
476 if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) in ci_otg_drv_vbus()
477 usb_phy_vbus_on(ci->usb_phy); in ci_otg_drv_vbus()
482 fsm->a_srp_det = 0; in ci_otg_drv_vbus()
483 fsm->power_up = 0; in ci_otg_drv_vbus()
485 if (ci->platdata->reg_vbus) in ci_otg_drv_vbus()
486 regulator_disable(ci->platdata->reg_vbus); in ci_otg_drv_vbus()
488 if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) in ci_otg_drv_vbus()
489 usb_phy_vbus_off(ci->usb_phy); in ci_otg_drv_vbus()
491 fsm->a_bus_drop = 1; in ci_otg_drv_vbus()
492 fsm->a_bus_req = 0; in ci_otg_drv_vbus()
522 if (!fsm->otg->host) in ci_otg_loc_sof()
525 udev = usb_hub_find_child(fsm->otg->host->root_hub, 1); in ci_otg_loc_sof()
532 pm_runtime_set_autosuspend_delay(&udev->dev, 0); in ci_otg_loc_sof()
538 * Start SRP pulsing by data-line pulsing,
539 * no v-bus pulsing followed
548 pm_runtime_get(ci->dev); in ci_otg_start_pulse()
571 usb_gadget_vbus_connect(&ci->gadget); in ci_otg_start_gadget()
573 usb_gadget_vbus_disconnect(&ci->gadget); in ci_otg_start_gadget()
595 if (ci->fsm.id && !(ci->driver) && in ci_otg_fsm_work()
596 ci->fsm.otg->state < OTG_STATE_A_IDLE) in ci_otg_fsm_work()
599 pm_runtime_get_sync(ci->dev); in ci_otg_fsm_work()
600 if (otg_statemachine(&ci->fsm)) { in ci_otg_fsm_work()
601 if (ci->fsm.otg->state == OTG_STATE_A_IDLE) { in ci_otg_fsm_work()
605 * a_idle to a_wait_vrise due to ID change(1->0), so in ci_otg_fsm_work()
606 * B-dev becomes A-dev can try to start new session in ci_otg_fsm_work()
610 if ((ci->fsm.id) || (ci->id_event) || in ci_otg_fsm_work()
611 (ci->fsm.power_up)) { in ci_otg_fsm_work()
620 if (ci->id_event) in ci_otg_fsm_work()
621 ci->id_event = false; in ci_otg_fsm_work()
622 } else if (ci->fsm.otg->state == OTG_STATE_B_IDLE) { in ci_otg_fsm_work()
623 if (ci->fsm.b_sess_vld) { in ci_otg_fsm_work()
624 ci->fsm.power_up = 0; in ci_otg_fsm_work()
631 } else if (ci->fsm.otg->state == OTG_STATE_A_HOST) { in ci_otg_fsm_work()
632 pm_runtime_mark_last_busy(ci->dev); in ci_otg_fsm_work()
633 pm_runtime_put_autosuspend(ci->dev); in ci_otg_fsm_work()
637 pm_runtime_put_sync(ci->dev); in ci_otg_fsm_work()
643 * called by otg fsm isr.
648 struct otg_fsm *fsm = &ci->fsm; in ci_otg_fsm_event()
654 switch (ci->fsm.otg->state) { in ci_otg_fsm_event()
657 fsm->b_conn = 1; in ci_otg_fsm_event()
658 fsm->a_bus_req = 1; in ci_otg_fsm_event()
664 fsm->b_sess_vld = 1; in ci_otg_fsm_event()
673 if (fsm->a_bus_suspend == 1) in ci_otg_fsm_event()
674 fsm->a_bus_suspend = 0; in ci_otg_fsm_event()
679 fsm->a_conn = 0; in ci_otg_fsm_event()
680 fsm->b_bus_req = 0; in ci_otg_fsm_event()
686 fsm->b_bus_suspend = 1; in ci_otg_fsm_event()
699 if (fsm->b_bus_suspend == 1) { in ci_otg_fsm_event()
701 fsm->b_bus_suspend = 0; in ci_otg_fsm_event()
707 fsm->b_conn = 0; in ci_otg_fsm_event()
710 if (ci->driver) { in ci_otg_fsm_event()
712 ci->gadget.is_a_peripheral = 1; in ci_otg_fsm_event()
719 fsm->b_conn = 0; in ci_otg_fsm_event()
725 fsm->a_conn = 1; in ci_otg_fsm_event()
735 * ci_otg_irq - otg fsm related irq handling
736 * and also update otg fsm variable by monitoring usb host and udc
744 struct otg_fsm *fsm = &ci->fsm; in ci_otg_fsm_irq()
748 fsm->id = (otgsc & OTGSC_ID) ? 1 : 0; in ci_otg_fsm_irq()
753 fsm->a_srp_det = 1; in ci_otg_fsm_irq()
754 fsm->a_bus_drop = 0; in ci_otg_fsm_irq()
757 if (fsm->id == 0) { in ci_otg_fsm_irq()
758 fsm->a_bus_drop = 0; in ci_otg_fsm_irq()
759 fsm->a_bus_req = 1; in ci_otg_fsm_irq()
760 ci->id_event = true; in ci_otg_fsm_irq()
765 fsm->b_sess_vld = 1; in ci_otg_fsm_irq()
768 fsm->b_ssend_srp = 0; in ci_otg_fsm_irq()
770 fsm->b_sess_vld = 0; in ci_otg_fsm_irq()
771 if (fsm->id) in ci_otg_fsm_irq()
777 fsm->a_vbus_vld = 1; in ci_otg_fsm_irq()
779 fsm->a_vbus_vld = 0; in ci_otg_fsm_irq()
780 fsm->b_conn = 0; in ci_otg_fsm_irq()
801 if (ci->phy) in ci_hdrc_otg_fsm_init()
802 ci->otg.phy = ci->phy; in ci_hdrc_otg_fsm_init()
804 ci->otg.usb_phy = ci->usb_phy; in ci_hdrc_otg_fsm_init()
806 ci->otg.gadget = &ci->gadget; in ci_hdrc_otg_fsm_init()
807 ci->fsm.otg = &ci->otg; in ci_hdrc_otg_fsm_init()
808 ci->fsm.power_up = 1; in ci_hdrc_otg_fsm_init()
809 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; in ci_hdrc_otg_fsm_init()
810 ci->fsm.otg->state = OTG_STATE_UNDEFINED; in ci_hdrc_otg_fsm_init()
811 ci->fsm.ops = &ci_otg_ops; in ci_hdrc_otg_fsm_init()
812 ci->gadget.hnp_polling_support = 1; in ci_hdrc_otg_fsm_init()
813 ci->fsm.host_req_flag = devm_kzalloc(ci->dev, 1, GFP_KERNEL); in ci_hdrc_otg_fsm_init()
814 if (!ci->fsm.host_req_flag) in ci_hdrc_otg_fsm_init()
815 return -ENOMEM; in ci_hdrc_otg_fsm_init()
817 mutex_init(&ci->fsm.lock); in ci_hdrc_otg_fsm_init()
821 dev_err(ci->dev, "Couldn't init OTG timers\n"); in ci_hdrc_otg_fsm_init()
824 ci->enabled_otg_timer_bits = 0; in ci_hdrc_otg_fsm_init()
825 ci->next_otg_timer = NUM_OTG_FSM_TIMERS; in ci_hdrc_otg_fsm_init()
827 retval = sysfs_create_group(&ci->dev->kobj, &inputs_attr_group); in ci_hdrc_otg_fsm_init()
829 dev_dbg(ci->dev, in ci_hdrc_otg_fsm_init()
837 if (ci->fsm.id) { in ci_hdrc_otg_fsm_init()
838 ci->fsm.b_ssend_srp = in ci_hdrc_otg_fsm_init()
840 ci->fsm.b_sess_vld = in ci_hdrc_otg_fsm_init()
851 sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group); in ci_hdrc_otg_fsm_remove()