123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933 |
- /*
- * Copyright (c) 2019 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file hotplug usb interface
- */
- #ifdef SYS_LOG_DOMAIN
- #undef SYS_LOG_DOMAIN
- #endif
- #define SYS_LOG_DOMAIN "hotpug_manager"
- #include <os_common_api.h>
- #include <msg_manager.h>
- #include <mem_manager.h>
- #include <sys_manager.h>
- #include <string.h>
- #include <fs_manager.h>
- #include <hotplug_manager.h>
- #include <init.h>
- #include <stdio.h>
- #include <device.h>
- #include <stdio.h>
- #include <usb/usb_otg.h>
- #include <usb/usb_device.h>
- #ifdef CONFIG_USB_HOST
- #include <usb/usb_host.h>
- #endif
- #include <usb/class/usb_msc.h>
- #ifdef CONFIG_USB_DEVICE
- #ifdef CONFIG_PM_DEVICE
- #include <pm/device.h>
- #include <sys_wakelock.h>
- static bool usb_wake_unlock;
- #endif
- #endif
- #define USB_HOTPLUG_NONE 0
- /* host mode: peripheral device connected */
- #define USB_HOTPLUG_A_IN 1
- /* host mode: peripheral device disconnected */
- #define USB_HOTPLUG_A_OUT 2
- /* device mode: connected to host */
- #define USB_HOTPLUG_B_IN 3
- /* device mode: disconnected from host */
- #define USB_HOTPLUG_B_OUT 4
- /* device mode: connected to charger */
- #define USB_HOTPLUG_C_IN 5
- /* device mode: disconnected from charger */
- #define USB_HOTPLUG_C_OUT 6
- /* usb hotplug suspend: stop detection */
- #define USB_HOTPLUG_SUSPEND 7
- static uint8_t usb_hotplug_state;
- #if CONFIG_LOG
- static char *state_string[] = {
- "undefined",
- "b_idle",
- "b_srp_init",
- "b_peripheral",
- "b_wait_acon",
- "b_host",
- "a_idle",
- "a_wait_vrise",
- "a_wait_bcon",
- "a_host",
- "a_suspend",
- "a_peripheral",
- "a_wait_vfall",
- "a_vbus_err"
- };
- #endif
- static uint8_t otg_state;
- #ifdef CONFIG_USB_DEVICE
- /* distinguish pc/charger: nearly 10s */
- #define USB_CONNECT_COUNT_MAX (10000/ CONFIG_MONITOR_PERIOD)
- static uint16_t usb_connect_count;
- /* optimize: if no_plugin */
- #define KEEP_IN_B_IDLE_RETRY 10
- static uint8_t keep_in_b_idle;
- /* doing b_peripheral exit process */
- static uint8_t otg_b_peripheral_exiting;
- #endif /* CONFIG_USB_DEVICE */
- #ifdef CONFIG_USB_HOST
- /* timeout: nearly 1s */
- #define OTG_A_WAIT_BCON_MAX (K_SECONDS(1) / CONFIG_MONITOR_PERIOD)
- static uint8_t otg_a_wait_bcon_count;
- /* timeout: nearly 4s */
- #define OTG_A_IDLE_MAX (K_SECONDS(4) / CONFIG_MONITOR_PERIOD)
- static uint8_t otg_a_idle_count;
- /* doing a_host exit process */
- static uint8_t otg_a_host_exiting;
- #endif /* CONFIG_USB_HOST */
- #ifdef CONFIG_USB_HOTPLUG_THREAD_ENABLED
- #define STACK_SZ CONFIG_USB_HOTPLUG_STACKSIZE
- #define THREAD_PRIO CONFIG_USB_HOTPLUG_PRIORITY
- static uint8_t usb_hotplug_stack[CONFIG_USB_HOTPLUG_STACKSIZE];
- #ifdef CONFIG_USB_HOST
- static void host_scan_thread(void *p1, void *p2, void *p3)
- {
- ARG_UNUSED(p1);
- ARG_UNUSED(p2);
- ARG_UNUSED(p3);
- usbh_scan_device();
- }
- static inline int usb_thread_init_host_scan(void)
- {
- k_tid_t tid;
- usbh_prepare_scan();
- /* Start a thread to offload USB scan/enumeration */
- tid = os_thread_create(usb_hotplug_stack, STACK_SZ,
- host_scan_thread,
- NULL, NULL, NULL,
- THREAD_PRIO, 0, 0);
- os_thread_name_set(tid, "host_scan");
- return 0;
- }
- static inline int usb_thread_exit_host_scan(void)
- {
- return usbh_disconnect();
- }
- #endif /* CONFIG_USB_HOST */
- #ifdef CONFIG_USB_MASS_STORAGE_SHARE_THREAD
- int usb_mass_storage_start(void)
- {
- k_tid_t tid;
- SYS_LOG_INF("shared");
- tid = os_thread_create(usb_hotplug_stack, STACK_SZ,
- usb_mass_storage_thread,
- NULL, NULL, NULL,
- CONFIG_MASS_STORAGE_PRIORITY, 0, 0);
- os_thread_name_set(tid, "mass_storage");
- return 0;
- }
- #endif /* CONFIG_USB_MASS_STORAGE_SHARE_THREAD */
- #endif /* CONFIG_USB_HOTPLUG_THREAD_ENABLED */
- static int usb_hotplug_dpdm_switch(bool host_mode)
- {
- #ifdef BOARD_USB_SWITCH_GPIO_NAME
- static struct device *usb_switch_gpio_dev;
- static uint8_t usb_switch_gpio_value;
- uint32_t value;
- int ret;
- if (usb_switch_gpio_dev == NULL) {
- usb_switch_gpio_dev = device_get_binding(BOARD_USB_SWITCH_GPIO_NAME);
- gpio_pin_configure(usb_switch_gpio_dev, BOARD_USB_SWITCH_EN_GPIO,
- GPIO_DIR_OUT);
- }
- value = BOARD_USB_SWITCH_HOST_EN_GPIO_VALUE;
- if (!host_mode) {
- value = !value;
- }
- /* already */
- if (value == usb_switch_gpio_value) {
- return 0;
- }
- usb_switch_gpio_value = value;
- ret = gpio_pin_write(usb_switch_gpio_dev, BOARD_USB_SWITCH_EN_GPIO,
- value);
- if (ret) {
- return ret;
- }
- #endif
- return 0;
- }
- static void usb_hotplug_status_cb(enum usb_dc_status_code status, uint8_t *param)
- {
- /* Check the USB status and do needed action if required */
- switch (status) {
- case USB_DC_HIGHSPEED:
- SYS_LOG_DBG("USB HS detected");
- usb_disable();
- break;
- case USB_DC_SOF:
- SYS_LOG_DBG("USB SOF detected");
- usb_disable();
- break;
- default:
- break;
- }
- }
- u8_t usb_hotplug_get_otgstate(void)
- {
- return otg_state;
- }
- static const struct usb_cfg_data usb_hotplug_config = {
- .cb_usb_status = usb_hotplug_status_cb,
- };
- static inline int usb_hotplug_detect_device(void)
- {
- int ret;
- ret = usb_enable((struct usb_cfg_data *)&usb_hotplug_config);
- if (ret < 0) {
- SYS_LOG_ERR("enable");
- return ret;
- }
- return 0;
- }
- #ifdef CONFIG_USB_HOST
- static inline int usb_hotplug_host_plugin(void)
- {
- usb_thread_init_host_scan();
- return 0;
- }
- static inline int usb_hotplug_host_plugout(void)
- {
- usb_hotplug_state = USB_HOTPLUG_A_OUT;
- return usb_thread_exit_host_scan();
- }
- #ifdef CONFIG_USB_HOST_STORAGE
- extern void usb_stor_set_access(bool accessed);
- extern bool usb_host_storage_enabled(void);
- int usb_hotplug_disk_accessed(bool access)
- {
- usb_stor_set_access(access);
- #ifdef CONFIG_FS_MANAGER
- if (access) {
- fs_manager_disk_init("USB:");
- } else {
- fs_manager_disk_uninit("USB:");
- }
- #endif
- return 0;
- }
- static inline int usb_hotplug_host_storage_plugin(void)
- {
- usb_hotplug_state = USB_HOTPLUG_A_IN;
- return 0;
- }
- #endif /* CONFIG_USB_HOST_STORAGE */
- #endif /* CONFIG_USB_HOST */
- #ifdef CONFIG_USB_DEVICE
- static inline int usb_hotplug_device_plugin(void)
- {
- usb_hotplug_state = USB_HOTPLUG_B_IN;
- return 0;
- }
- static inline int usb_hotplug_device_plugout(void)
- {
- usb_hotplug_state = USB_HOTPLUG_B_OUT;
- return 0;
- }
- static inline int usb_hotplug_charger_plugin(void)
- {
- usb_hotplug_state = USB_HOTPLUG_C_IN;
- return 0;
- }
- static inline int usb_hotplug_charger_plugout(void)
- {
- usb_hotplug_state = USB_HOTPLUG_C_OUT;
- return 0;
- }
- #endif /* CONFIG_USB_DEVICE */
- static inline uint8_t usb_hotplug_get_vbus(void)
- {
- #ifdef CONFIG_USB_DEVICE
- return usb_phy_get_vbus();
- #else
- return USB_VBUS_LOW; /* Host-only mode: never enter b_idle */
- #endif
- }
- static inline void usb_hotplug_update_state(void)
- {
- uint8_t vbus = usb_hotplug_get_vbus();
- #ifdef CONFIG_USB_DEVICE
- bool dc_attached;
- uint8_t i;
- #endif
- #ifdef CONFIG_USB_DEVICE
- #ifdef CONFIG_PM_DEVICE
- if (system_is_ready()) {
- if (vbus == USB_VBUS_HIGH) {
- if (!usb_wake_unlock) {
- sys_wake_lock_ext(PARTIAL_WAKE_LOCK,USB_WAKE_LOCK_USER);
- usb_wake_unlock = true;
- }
- } else {
- if (usb_wake_unlock) {
- sys_wake_unlock_ext(PARTIAL_WAKE_LOCK,USB_WAKE_LOCK_USER);
- usb_wake_unlock = false;
- }
- }
- }
- #endif
- #endif
- switch (otg_state) {
- #ifdef CONFIG_USB_DEVICE
- case OTG_STATE_B_IDLE:
- if (vbus == USB_VBUS_LOW) {
- keep_in_b_idle = 0;
- otg_state = OTG_STATE_A_IDLE;
- #ifndef CONFIG_USB_HOST
- usb_phy_reset();
- #endif
- usb_hotplug_charger_plugout();
- break;
- }
- if (keep_in_b_idle >= KEEP_IN_B_IDLE_RETRY) {
- break;
- }
- usb_phy_reset();
- usb_phy_enter_b_idle();
- k_sleep(K_MSEC(3)); /* necessary */
- repeat:
- dc_attached = usb_phy_dc_attached();
- for (i = 0; i < 4; i++) {
- k_busy_wait(1000);
- if (dc_attached != usb_phy_dc_attached()) {
- SYS_LOG_INF("dc_attached: %d, i: %d",
- dc_attached, i);
- goto repeat;
- }
- }
- if (dc_attached) {
- keep_in_b_idle = 0;
- otg_state = OTG_STATE_B_WAIT_ACON;
- usb_hotplug_detect_device();
- } else {
- if (++keep_in_b_idle >= KEEP_IN_B_IDLE_RETRY) {
- SYS_LOG_INF("b_idle");
- }
- usb_phy_enter_a_idle();
- usb_hotplug_charger_plugin();
- }
- break;
- case OTG_STATE_B_WAIT_ACON:
- if (vbus == USB_VBUS_LOW) {
- usb_connect_count = 0;
- otg_state = OTG_STATE_A_IDLE;
- /* exit device mode */
- usb_disable();
- usb_hotplug_charger_plugout();
- break;
- }
- if (usb_phy_dc_connected()) {
- usb_connect_count = 0;
- otg_state = OTG_STATE_B_PERIPHERAL;
- /* enter device mode */
- usb_hotplug_device_plugin();
- break;
- }
- if (++usb_connect_count >= USB_CONNECT_COUNT_MAX) {
- SYS_LOG_DBG("connected to charger");
- keep_in_b_idle = KEEP_IN_B_IDLE_RETRY;
- usb_connect_count = 0;
- otg_state = OTG_STATE_B_IDLE;
- /* exit device mode */
- usb_disable();
- usb_hotplug_charger_plugin();
- break;
- }
- break;
- case OTG_STATE_B_PERIPHERAL:
- if (otg_b_peripheral_exiting) {
- /* wait for exit done */
- if (usb_phy_dc_detached()) {
- otg_state = OTG_STATE_A_IDLE;
- otg_b_peripheral_exiting = 0;
- }
- break;
- }
- if (vbus == USB_VBUS_LOW) {
- /* exit device mode */
- usb_hotplug_device_plugout();
- otg_b_peripheral_exiting = 1;
- /* wait for exit done */
- if (usb_phy_dc_detached()) {
- otg_state = OTG_STATE_A_IDLE;
- otg_b_peripheral_exiting = 0;
- }
- break;
- }
- if (usb_device_unconfigured()) {
- usb_hotplug_device_plugout();
- otg_b_peripheral_exiting = 1;
- SYS_LOG_INF("usb unconfigured");
- break;
- }
- #ifdef CONFIG_USB_MASS_STORAGE
- if (usb_mass_storage_ejected()) {
- usb_hotplug_device_plugout();
- otg_b_peripheral_exiting = 1;
- SYS_LOG_INF("usb msc ejected");
- break;
- }
- #endif
- break;
- #endif /* CONFIG_USB_DEVICE */
- #ifdef CONFIG_USB_HOST
- case OTG_STATE_A_IDLE:
- if (vbus == USB_VBUS_HIGH) {
- otg_a_idle_count = 0;
- otg_state = OTG_STATE_B_IDLE;
- usbh_vbus_set(false);
- break;
- }
- /* Enable Vbus */
- usbh_vbus_set(true);
- if (usb_phy_hc_attached()) {
- otg_a_idle_count = 0;
- otg_state = OTG_STATE_A_WAIT_BCON;
- usb_phy_enter_a_wait_bcon();
- break;
- }
- /* reset Vbus */
- if (++otg_a_idle_count >= OTG_A_IDLE_MAX) {
- otg_a_idle_count = 0;
- usbh_vbus_set(false);
- break;
- }
- break;
- case OTG_STATE_A_WAIT_BCON:
- if (vbus == USB_VBUS_HIGH) {
- otg_a_wait_bcon_count = 0;
- otg_state = OTG_STATE_B_IDLE;
- /* exit host mode */
- usbh_vbus_set(false);
- break;
- }
- if (usb_phy_hc_connected()) {
- otg_a_wait_bcon_count = 0;
- otg_state = OTG_STATE_A_HOST;
- /* enter host mode */
- usb_hotplug_host_plugin();
- break;
- }
- if (++otg_a_wait_bcon_count >= OTG_A_WAIT_BCON_MAX) {
- otg_a_wait_bcon_count = 0;
- otg_state = OTG_STATE_A_IDLE;
- usbh_vbus_set(false);
- break;
- }
- break;
- case OTG_STATE_A_HOST:
- if (vbus == USB_VBUS_HIGH) {
- if (otg_a_host_exiting) {
- if (!usb_hotplug_host_plugout()) {
- otg_a_host_exiting = 0;
- otg_state = OTG_STATE_B_IDLE;
- }
- break;
- }
- /* exit host mode */
- usbh_vbus_set(false);
- if (usb_hotplug_host_plugout()) {
- otg_a_host_exiting = 1;
- } else {
- otg_state = OTG_STATE_B_IDLE;
- }
- break;
- }
- /* handle disconnect and connnect quickly */
- if (otg_a_host_exiting) {
- if (!usb_hotplug_host_plugout()) {
- otg_a_host_exiting = 0;
- otg_state = OTG_STATE_A_IDLE;
- }
- break;
- }
- if (usb_phy_hc_disconnected()) {
- /* exit host mode */
- usbh_vbus_set(false);
- if (usb_hotplug_host_plugout()) {
- otg_a_host_exiting = 1;
- } else {
- otg_state = OTG_STATE_A_IDLE;
- }
- break;
- }
- #ifdef CONFIG_USB_HOST_STORAGE
- if (usb_host_storage_enabled()) {
- usb_hotplug_host_storage_plugin();
- break;
- }
- #endif
- break;
- #else /* CONFIG_USB_HOST */
- case OTG_STATE_A_IDLE:
- if (vbus == USB_VBUS_HIGH) {
- otg_state = OTG_STATE_B_IDLE;
- break;
- }
- break;
- #endif
- default:
- break;
- }
- }
- static int usb_hotplug_loop(void)
- {
- enum usb_otg_state old_state = otg_state;
- usb_hotplug_update_state();
- if (otg_state == old_state) {
- return 0;
- }
- SYS_LOG_INF("%s -> %s", state_string[old_state],
- state_string[otg_state]);
- switch (otg_state) {
- case OTG_STATE_B_IDLE:
- usb_hotplug_dpdm_switch(false);
- break;
- case OTG_STATE_A_IDLE:
- usb_hotplug_dpdm_switch(true);
- #ifdef CONFIG_USB_HOST
- usb_phy_reset();
- usb_phy_enter_a_idle();
- #endif
- break;
- default:
- break;
- }
- return 0;
- }
- static inline int usb_hotplug_init(void)
- {
- uint8_t vbus = usb_hotplug_get_vbus();
- #ifdef CONFIG_USB_DEVICE
- /* suspend comes before hotplug and keep_in_b_idle maybe not reset */
- keep_in_b_idle = 0;
- #endif
- if (vbus == USB_VBUS_HIGH) {
- usb_hotplug_dpdm_switch(false);
- #ifdef CONFIG_USB_HOST
- usbh_vbus_set(false);
- #endif
- otg_state = OTG_STATE_B_IDLE;
- } else {
- usb_hotplug_dpdm_switch(true);
- #ifdef CONFIG_USB_HOST
- usb_phy_enter_a_idle();
- #endif
- otg_state = OTG_STATE_A_IDLE;
- }
- SYS_LOG_INF("state %s", state_string[otg_state]);
- /* For a_idle, detect later */
- if (otg_state == OTG_STATE_B_IDLE) {
- usb_hotplug_loop();
- }
- return 0;
- }
- /*
- * Check if USB is attached to charger or host
- */
- bool usb_hotplug_device_mode(void)
- {
- if ((otg_state == OTG_STATE_B_WAIT_ACON) ||
- (otg_state == OTG_STATE_B_PERIPHERAL)) {
- return true;
- }
- return false;
- }
- int usb_hotplug_suspend(void)
- {
- usb_hotplug_state = USB_HOTPLUG_SUSPEND;
- #ifdef CONFIG_USB_HOST
- usbh_vbus_set(false);
- if (otg_state == OTG_STATE_A_HOST) {
- /* should be fast */
- while (usbh_disconnect()) {
- k_sleep(K_MSEC(10));
- SYS_LOG_INF("");
- }
- }
- #endif
- usb_phy_exit();
- return 0;
- }
- int usb_hotplug_resume(void)
- {
- usb_hotplug_state = HOTPLUG_NONE;
- #ifdef CONFIG_USB_HOST
- if (otg_state == OTG_STATE_A_HOST) {
- /* broadcast when resume */
- struct app_msg msg = {0};
- msg.type = MSG_HOTPLUG_EVENT;
- msg.cmd = HOTPLUG_USB_HOST;
- msg.value = HOTPLUG_OUT;
- SYS_LOG_INF("host");
- return send_async_msg("main", &msg);
- }
- #endif
- return usb_hotplug_init();
- }
- #ifdef CONFIG_USB_HOST
- /* check and enumerate USB device directly */
- int usb_hotplug_host_check(void)
- {
- int timeout = 100; /* 1s */
- if (otg_state != OTG_STATE_A_IDLE) {
- return -EINVAL;
- }
- do {
- usb_hotplug_loop();
- switch (otg_state) {
- case OTG_STATE_A_WAIT_BCON:
- goto attached;
- case OTG_STATE_A_IDLE:
- break;
- default:
- goto exit;
- }
- k_sleep(K_MSEC(10));
- } while (--timeout);
- /* timeout */
- if (timeout == 0) {
- return -ENODEV;
- }
- attached:
- timeout = 10; /* 1s */
- do {
- usb_hotplug_loop();
- switch (otg_state) {
- case OTG_STATE_A_HOST:
- usbh_prepare_scan();
- usbh_scan_device();
- /* fall through */
- default:
- goto exit;
- case OTG_STATE_A_WAIT_BCON:
- break;
- }
- /* should be same as CONFIG_MONITOR_PERIOD */
- k_sleep(K_MSEC(100));
- } while (--timeout);
- /* timeout */
- if (timeout == 0) {
- return -ENODEV;
- }
- exit:
- return 0;
- }
- #endif
- static int hotplug_usb_get_type(void)
- {
- switch (usb_hotplug_state) {
- case USB_HOTPLUG_A_IN:
- case USB_HOTPLUG_A_OUT:
- return HOTPLUG_USB_HOST;
- case USB_HOTPLUG_B_IN:
- case USB_HOTPLUG_B_OUT:
- return HOTPLUG_USB_DEVICE;
- }
- /* never */
- return 0;
- }
- static int hotplug_usb_detect(void)
- {
- uint8_t old_state = usb_hotplug_state;
- if (usb_hotplug_state == USB_HOTPLUG_SUSPEND) {
- return HOTPLUG_NONE;
- }
- usb_hotplug_loop();
- if (usb_hotplug_state == old_state) {
- return HOTPLUG_NONE;
- }
- switch (usb_hotplug_state) {
- case USB_HOTPLUG_A_IN:
- case USB_HOTPLUG_B_IN:
- return HOTPLUG_IN;
- case USB_HOTPLUG_A_OUT:
- case USB_HOTPLUG_B_OUT:
- return HOTPLUG_OUT;
- }
- return HOTPLUG_NONE;
- }
- static int hotplug_usb_process(int device_state)
- {
- int res = -1;
- SYS_LOG_INF("%d", usb_hotplug_state);
- switch (usb_hotplug_state) {
- case USB_HOTPLUG_A_IN:
- #ifdef CONFIG_FS_MANAGER
- res = fs_manager_disk_init("USB:");
- #endif
- break;
- case USB_HOTPLUG_A_OUT:
- #ifdef CONFIG_FS_MANAGER
- res = fs_manager_disk_uninit("USB:");
- #endif
- break;
- case USB_HOTPLUG_B_IN:
- case USB_HOTPLUG_B_OUT:
- res = 0;
- break;
- default:
- break;
- }
- return res;
- }
- #ifdef CONFIG_USB_DEVICE
- static int hotplug_usb_device_get_state(void)
- {
- if (otg_b_peripheral_exiting == 1) {
- return HOTPLUG_OUT;
- }
- if (otg_state == OTG_STATE_B_PERIPHERAL) {
- return HOTPLUG_IN;
- }
- return HOTPLUG_OUT;
- }
- static const struct hotplug_device_t hotplug_usb_device = {
- .type = HOTPLUG_USB_DEVICE,
- .get_state = hotplug_usb_device_get_state,
- .get_type = hotplug_usb_get_type,
- .hotplug_detect = hotplug_usb_detect,
- .fs_process = hotplug_usb_process,
- };
- #endif /* CONFIG_USB_DEVICE */
- #ifdef CONFIG_USB_HOST
- static int hotplug_usb_host_get_state(void)
- {
- if (otg_state == OTG_STATE_A_HOST) {
- return HOTPLUG_IN;
- }
- return HOTPLUG_OUT;
- }
- static int __unused hotplug_usb_host_detect(void)
- {
- return HOTPLUG_NONE;
- }
- static const struct hotplug_device_t hotplug_usb_host = {
- .type = HOTPLUG_USB_HOST,
- .get_state = hotplug_usb_host_get_state,
- #ifndef CONFIG_USB
- .get_type = hotplug_usb_get_type,
- .hotplug_detect = hotplug_usb_detect,
- .fs_process = hotplug_usb_process,
- #else
- .hotplug_detect = hotplug_usb_host_detect,
- #endif
- };
- #endif /* CONFIG_USB_HOST */
- int hotplug_usb_init(void)
- {
- #ifdef CONFIG_USB_DEVICE
- hotplug_device_register(&hotplug_usb_device);
- #endif
- #ifdef CONFIG_USB_HOST
- hotplug_device_register(&hotplug_usb_host);
- #endif
- return 0;
- }
- #ifdef CONFIG_USB_HOTPLUG
- static struct k_timer usb_hotplug_timer;
- static void usb_hotplug_expiry_fn(struct k_timer *timer)
- {
- switch (otg_state) {
- case OTG_STATE_B_WAIT_ACON:
- case OTG_STATE_B_PERIPHERAL:
- if (!usb_phy_get_vbus() && !usb_phy_dc_detached()) {
- usb_phy_dc_disconnect();
- }
- break;
- default:
- break;
- }
- }
- #endif /* CONFIG_USB_HOTPLUG */
- int usb_hotplug_pre_init(const struct device *dev)
- {
- ARG_UNUSED(dev);
- #ifdef CONFIG_USB_HOTPLUG
- k_timer_init(&usb_hotplug_timer, usb_hotplug_expiry_fn, NULL);
- k_timer_start(&usb_hotplug_timer, K_SECONDS(1), K_MSEC(400));
- #endif
- usb_phy_init();
- #ifdef CONFIG_USB_HOST
- /* turn off Vbus by default */
- usbh_vbus_set(false);
- #endif
- usb_hotplug_init();
- return 0;
- }
- #define USB_HOTPLUG_PRE_INIT_PRIORITY CONFIG_APPLICATION_INIT_PRIORITY
- SYS_INIT(usb_hotplug_pre_init, POST_KERNEL, USB_HOTPLUG_PRE_INIT_PRIORITY);
|