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_init(&ci->otg_fsm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); in ci_otg_init_timers()
428 ci->otg_fsm_hrtimer.function = ci_otg_hrtimer_func; in ci_otg_init_timers()
433 /* -------------------------------------------------------------*/
434 /* Operations that will be called from OTG Finite State Machine */
435 /* -------------------------------------------------------------*/
455 * A-device drive vbus: turn on vbus regulator and enable port power
467 if (ci->platdata->reg_vbus) { in ci_otg_drv_vbus()
468 ret = regulator_enable(ci->platdata->reg_vbus); in ci_otg_drv_vbus()
470 dev_err(ci->dev, in ci_otg_drv_vbus()
477 if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) in ci_otg_drv_vbus()
478 usb_phy_vbus_on(ci->usb_phy); in ci_otg_drv_vbus()
483 fsm->a_srp_det = 0; in ci_otg_drv_vbus()
484 fsm->power_up = 0; in ci_otg_drv_vbus()
486 if (ci->platdata->reg_vbus) in ci_otg_drv_vbus()
487 regulator_disable(ci->platdata->reg_vbus); in ci_otg_drv_vbus()
489 if (ci->platdata->flags & CI_HDRC_PHY_VBUS_CONTROL) in ci_otg_drv_vbus()
490 usb_phy_vbus_off(ci->usb_phy); in ci_otg_drv_vbus()
492 fsm->a_bus_drop = 1; in ci_otg_drv_vbus()
493 fsm->a_bus_req = 0; in ci_otg_drv_vbus()
523 if (!fsm->otg->host) in ci_otg_loc_sof()
526 udev = usb_hub_find_child(fsm->otg->host->root_hub, 1); in ci_otg_loc_sof()
533 pm_runtime_set_autosuspend_delay(&udev->dev, 0); in ci_otg_loc_sof()
539 * Start SRP pulsing by data-line pulsing,
540 * no v-bus pulsing followed
549 pm_runtime_get(ci->dev); in ci_otg_start_pulse()
572 usb_gadget_vbus_connect(&ci->gadget); in ci_otg_start_gadget()
574 usb_gadget_vbus_disconnect(&ci->gadget); in ci_otg_start_gadget()
596 if (ci->fsm.id && !(ci->driver) && in ci_otg_fsm_work()
597 ci->fsm.otg->state < OTG_STATE_A_IDLE) in ci_otg_fsm_work()
600 pm_runtime_get_sync(ci->dev); in ci_otg_fsm_work()
601 if (otg_statemachine(&ci->fsm)) { in ci_otg_fsm_work()
602 if (ci->fsm.otg->state == OTG_STATE_A_IDLE) { in ci_otg_fsm_work()
606 * a_idle to a_wait_vrise due to ID change(1->0), so in ci_otg_fsm_work()
607 * B-dev becomes A-dev can try to start new session in ci_otg_fsm_work()
611 if ((ci->fsm.id) || (ci->id_event) || in ci_otg_fsm_work()
612 (ci->fsm.power_up)) { in ci_otg_fsm_work()
621 if (ci->id_event) in ci_otg_fsm_work()
622 ci->id_event = false; in ci_otg_fsm_work()
623 } else if (ci->fsm.otg->state == OTG_STATE_B_IDLE) { in ci_otg_fsm_work()
624 if (ci->fsm.b_sess_vld) { in ci_otg_fsm_work()
625 ci->fsm.power_up = 0; in ci_otg_fsm_work()
632 } else if (ci->fsm.otg->state == OTG_STATE_A_HOST) { in ci_otg_fsm_work()
633 pm_runtime_mark_last_busy(ci->dev); in ci_otg_fsm_work()
634 pm_runtime_put_autosuspend(ci->dev); in ci_otg_fsm_work()
638 pm_runtime_put_sync(ci->dev); in ci_otg_fsm_work()
644 * called by otg fsm isr.
649 struct otg_fsm *fsm = &ci->fsm; in ci_otg_fsm_event()
655 switch (ci->fsm.otg->state) { in ci_otg_fsm_event()
658 fsm->b_conn = 1; in ci_otg_fsm_event()
659 fsm->a_bus_req = 1; in ci_otg_fsm_event()
665 fsm->b_sess_vld = 1; in ci_otg_fsm_event()
674 if (fsm->a_bus_suspend == 1) in ci_otg_fsm_event()
675 fsm->a_bus_suspend = 0; in ci_otg_fsm_event()
680 fsm->a_conn = 0; in ci_otg_fsm_event()
681 fsm->b_bus_req = 0; in ci_otg_fsm_event()
687 fsm->b_bus_suspend = 1; in ci_otg_fsm_event()
700 if (fsm->b_bus_suspend == 1) { in ci_otg_fsm_event()
702 fsm->b_bus_suspend = 0; in ci_otg_fsm_event()
708 fsm->b_conn = 0; in ci_otg_fsm_event()
711 if (ci->driver) { in ci_otg_fsm_event()
713 ci->gadget.is_a_peripheral = 1; in ci_otg_fsm_event()
720 fsm->b_conn = 0; in ci_otg_fsm_event()
726 fsm->a_conn = 1; in ci_otg_fsm_event()
736 * ci_otg_irq - otg fsm related irq handling
737 * and also update otg fsm variable by monitoring usb host and udc
745 struct otg_fsm *fsm = &ci->fsm; in ci_otg_fsm_irq()
749 fsm->id = (otgsc & OTGSC_ID) ? 1 : 0; in ci_otg_fsm_irq()
754 fsm->a_srp_det = 1; in ci_otg_fsm_irq()
755 fsm->a_bus_drop = 0; in ci_otg_fsm_irq()
758 if (fsm->id == 0) { in ci_otg_fsm_irq()
759 fsm->a_bus_drop = 0; in ci_otg_fsm_irq()
760 fsm->a_bus_req = 1; in ci_otg_fsm_irq()
761 ci->id_event = true; in ci_otg_fsm_irq()
766 fsm->b_sess_vld = 1; in ci_otg_fsm_irq()
769 fsm->b_ssend_srp = 0; in ci_otg_fsm_irq()
771 fsm->b_sess_vld = 0; in ci_otg_fsm_irq()
772 if (fsm->id) in ci_otg_fsm_irq()
778 fsm->a_vbus_vld = 1; in ci_otg_fsm_irq()
780 fsm->a_vbus_vld = 0; in ci_otg_fsm_irq()
781 fsm->b_conn = 0; in ci_otg_fsm_irq()
802 if (ci->phy) in ci_hdrc_otg_fsm_init()
803 ci->otg.phy = ci->phy; in ci_hdrc_otg_fsm_init()
805 ci->otg.usb_phy = ci->usb_phy; in ci_hdrc_otg_fsm_init()
807 ci->otg.gadget = &ci->gadget; in ci_hdrc_otg_fsm_init()
808 ci->fsm.otg = &ci->otg; in ci_hdrc_otg_fsm_init()
809 ci->fsm.power_up = 1; in ci_hdrc_otg_fsm_init()
810 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0; in ci_hdrc_otg_fsm_init()
811 ci->fsm.otg->state = OTG_STATE_UNDEFINED; in ci_hdrc_otg_fsm_init()
812 ci->fsm.ops = &ci_otg_ops; in ci_hdrc_otg_fsm_init()
813 ci->gadget.hnp_polling_support = 1; in ci_hdrc_otg_fsm_init()
814 ci->fsm.host_req_flag = devm_kzalloc(ci->dev, 1, GFP_KERNEL); in ci_hdrc_otg_fsm_init()
815 if (!ci->fsm.host_req_flag) in ci_hdrc_otg_fsm_init()
816 return -ENOMEM; in ci_hdrc_otg_fsm_init()
818 mutex_init(&ci->fsm.lock); in ci_hdrc_otg_fsm_init()
822 dev_err(ci->dev, "Couldn't init OTG timers\n"); in ci_hdrc_otg_fsm_init()
825 ci->enabled_otg_timer_bits = 0; in ci_hdrc_otg_fsm_init()
826 ci->next_otg_timer = NUM_OTG_FSM_TIMERS; in ci_hdrc_otg_fsm_init()
828 retval = sysfs_create_group(&ci->dev->kobj, &inputs_attr_group); in ci_hdrc_otg_fsm_init()
830 dev_dbg(ci->dev, in ci_hdrc_otg_fsm_init()
838 if (ci->fsm.id) { in ci_hdrc_otg_fsm_init()
839 ci->fsm.b_ssend_srp = in ci_hdrc_otg_fsm_init()
841 ci->fsm.b_sess_vld = in ci_hdrc_otg_fsm_init()
852 sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group); in ci_hdrc_otg_fsm_remove()