kal_bool usbc_cosim_core_task_init(void) { usbc_core_t* pUsbCore; kal_char usbc_class_mutex_name[50]; #ifdef IPCORE_NOT_PRESENT hmu_boot_init(); #endif usbc_set_op_mode(USBC_OP_MODE_NORMAL); kal_mem_set(usbc_core_get_instance(), 0, sizeof(usbc_core_t)); usbc_core_clear_register(); usbc_core_clear_status(); pUsbCore = usbc_core_get_instance(); // create enhance mutex sprintf(usbc_class_mutex_name, "USBC_CLASS_REMOTE_WK_MUTEX"); pUsbCore->usbc_class_remote_wk_mutex = kal_create_enh_mutex(usbc_class_mutex_name); sprintf(usbc_class_mutex_name, "USBC_CLASS_RENOTIFY_MUTEX"); pUsbCore->usbc_class_renotify_mutex = kal_create_enh_mutex(usbc_class_mutex_name); sprintf(usbc_class_mutex_name, "USBC_CLASS_FUNC_ACCESS_MUTEX"); pUsbCore->usbc_class_func_access_mutex = kal_create_enh_mutex(usbc_class_mutex_name); if ( NULL == pUsbCore->usbc_class_remote_wk_mutex || NULL == pUsbCore->usbc_class_renotify_mutex || NULL == pUsbCore->usbc_class_func_access_mutex ) { ASSERT(0); } // initial an evnet scheduler pUsbCore->usbc_es_wk_notify_g = evshed_create( "USBC_WK_NOTIFY", /* timer_name: event scheduler name */ MOD_USBCORE, /* dest_mod_id: system sends timeout message to this module when event scheduler timeout happens */ 0, /* fuzz */ 255); /* max_delay_ticks */ if (pUsbCore->usbc_es_wk_notify_g) { evshed_set_index(pUsbCore->usbc_es_wk_notify_g, USBC_WK_NOTIFY_INDEX); } else { ASSERT(0); } usbc_normal_hif_factory(); usbc_cosim_hif_factory(); usbc_stack_checkin(USB_CLASS_NUM, NULL); return KAL_TRUE; }
/*------------------------------------------------------------------------------ * Private implementation. *----------------------------------------------------------------------------*/ static void usbc_core_indicate_state(usbc_usb_state_e state) { usbc_core_t *pUsbCore = usbc_core_get_instance(); kal_uint8 idx; pUsbCore->state = state; for (idx = 0; idx < pUsbCore->total_class_devices; idx++) { if ( USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[idx].state && NULL != pUsbCore->class_device[idx].notify_usb_state ) { if ( (state == USBC_USB_STATE_SUSPENDING || state == USBC_USB_STATE_SUSPENDED) && pUsbCore->class_device[idx].is_func_suspend ) { // do not suspend the class device again if it has been in function suspend state } else if ( state == USBC_USB_STATE_RESUME && pUsbCore->class_device[idx].is_func_suspend ) { // do not resume the class device which was function suspended while device resuming // the class device will be resumed later while function resuming } else { usbc_trace_info(USBCORE_NOTIFY_CLASS_START, pUsbCore->class_device[idx].class_type, state); pUsbCore->class_device[idx].notify_usb_state(idx,state); usbc_trace_info(USBCORE_NOTIFY_CLASS_END, pUsbCore->class_device[idx].class_type, state); } } } }
static kal_uint8 acquire_pipe_queue(kal_uint8 class_device_id, usbc_pipe_type_e type) { usbc_core_t* pUsbCore = usbc_core_get_instance(); kal_uint8 pipe_queue = INVALID_PIPE_QUEUE_ID; kal_uint8 i = 0; for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ ) { if ( (pUsbCore->tx_queue[i].class_device_id == class_device_id) && (pUsbCore->tx_queue[i].pipe_type == type) && (pUsbCore->tx_queue[i].state == USBC_CORE_QUEUE_STATE_INITIATED)) { pipe_queue = i; break; } } if ( pipe_queue != INVALID_PIPE_QUEUE_ID ) { return pipe_queue; } for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ ) { if ( (pUsbCore->rx_queue[i].class_device_id == class_device_id) && (pUsbCore->rx_queue[i].pipe_type == type) && (pUsbCore->rx_queue[i].state == USBC_CORE_QUEUE_STATE_INITIATED)) { pipe_queue = (i | PIPE_QUEUE_RX_MASK); break; } } return pipe_queue; }
void usbc_core_notify_function_state_suspending(kal_uint8 class_device_id) { kal_uint8 func_suspend_list; kal_uint8 func_wk_list = usbc_core_get_function_remote_wk_list(); usbc_core_t *pUsbCore = usbc_core_get_instance(); usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_p; // Notify the specific function of USB suspended if ( !pUsbCore->class_device[class_device_id].is_func_suspend ) { usbc_core_indicate_function_state(class_device_id, USBC_USB_STATE_SUSPENDING); usbc_core_indicate_function_state(class_device_id, USBC_USB_STATE_SUSPENDED); pUsbCore->class_device[class_device_id].is_func_suspend = KAL_TRUE; } // If all functions of the device are suspended, we notify L4 to do power saving func_suspend_list = usbc_core_get_function_suspend_list(); if( !USBC_IS_IN_EXCEPTION_MODE() && func_suspend_list == ((0x01 << pUsbCore->total_class_devices)-1) ) { rsp_msg_p = (usbcore_usbidle_l4_power_saving_req_struct*)construct_local_para(sizeof(usbcore_usbidle_l4_power_saving_req_struct), TD_RESET); ASSERT(rsp_msg_p); rsp_msg_p->notify_suspend = KAL_TRUE; rsp_msg_p->notify_suspend_with_remote_wk = (func_wk_list==0)? KAL_FALSE:KAL_TRUE; usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 1, 1, 1, (rsp_msg_p->notify_suspend_with_remote_wk? 0:1)); usb_idle_set_l4_power_saving(KAL_TRUE); msg_send6(MOD_USBCORE, // src module MOD_USBIDLE, // dst module 0, // sap id MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4, (local_para_struct*)rsp_msg_p, 0); //msg id } }
void usbc_set_wk_notify_timer(kal_uint8 class_device_id) { eventid eid; kal_uint8 nInterface; usbc_core_t* pUsbCore = usbc_core_get_instance(); /* * To prevent race condition of event cancelling and set, * there shall be only one such event for simplicity. */ ASSERT(NULL != pUsbCore->usbc_es_wk_notify_g); usbc_trace_info(USBCORE_REMOTE_WK_SET_NOTIFY_TIMER, class_device_id); USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_renotify_mutex); // usb a bitmap to maintain the list of function wakeup notification pUsbCore->func_notify_list[class_device_id] = KAL_TRUE; // get the firtst interface ot the function nInterface = usbc_class_device_get_1st_interface(class_device_id); // send function remote wakeup notification via HIF driver usbc_normal_hif_ss_wk_notify(nInterface); if (NULL == pUsbCore->wk_eventid) { eid = evshed_set_event( pUsbCore->usbc_es_wk_notify_g, usbc_wk_notify_timeout, // timeout handler NULL, /* event_hf_param */ USBC_WK_NOTIFY_CHECK_TICKS); /* elapse_time */ ASSERT(eid); } USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_renotify_mutex); }
void usbc_wk_notify_timeout() { usbc_core_t* pUsbCore = usbc_core_get_instance(); kal_uint8 class_device_id = 0; kal_uint8 i; USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_renotify_mutex); for(i=0; i<pUsbCore->total_class_devices; i++) { if(pUsbCore->func_notify_list[i] == KAL_TRUE) { class_device_id = i; pUsbCore->func_notify_list[i] = KAL_FALSE; break; } } if (i == pUsbCore->total_class_devices) { pUsbCore->wk_eventid = NULL; USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_renotify_mutex); return; } USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_renotify_mutex); // check the access of the function if ( !pUsbCore->is_func_be_accessed[class_device_id] ) { usbc_set_wk_notify_timer(class_device_id); } }
void usbc_core_notify_func_wk_ability(kal_uint8 class_device_id, kal_bool ability) { usbc_core_t *pUsbCore = usbc_core_get_instance(); kal_bool isCapableWk = KAL_FALSE; // check the capability of the class device if ( NULL != pUsbCore->class_device[class_device_id].query_func_wk_status) { isCapableWk = ((pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) & (kal_uint8)0x01) == 0x01)? KAL_TRUE:KAL_FALSE; } if( ability && !isCapableWk ) { usbc_trace_error(USBCORE_NOTIFY_WK_ABILITY_INVALID, pUsbCore->class_device[class_device_id].class_type); ASSERT(0); return; } if ( USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[class_device_id].state && NULL != pUsbCore->class_device[class_device_id].notify_func_wk_ability ) { usbc_trace_info(USBCORE_NOTIFY_WK_ABILITY_START, pUsbCore->class_device[class_device_id].class_type); pUsbCore->class_device[class_device_id].notify_func_wk_ability(class_device_id, ability); usbc_trace_info(USBCORE_NOTIFY_WK_ABILITY_END, pUsbCore->class_device[class_device_id].class_type); } }
void usbc_core_notify_state_resume() { kal_bool remote_wakeup_enabled = (usbc_core_get_function_remote_wk_list()==0)? KAL_FALSE:KAL_TRUE; if( USBC_IS_IN_EXCEPTION_MODE() ) { usbc_core_indicate_state(USBC_USB_STATE_RESUME); return; } // nofity USBIDLE that it does not have to gate the clock of USB IP usbc_trace_info(USBCORE_DEV_SUSPEND_CLOCK, 0, 0); usb_idle_set_clockGating(KAL_FALSE); // Notify USB resume event to USB classes usbc_core_indicate_state(USBC_USB_STATE_RESUME); // Update function pointer for set GPDs to hardware normally usbc_trace_info(USBCORE_UPDATE_API_BUFF_GPD, 0); usbc_normal_hif_factory(); // Set GPDs that are buffered in DRAM to hardware usbc_normal_hif_restore_gpd_pwrsave(); // Set USBCORE task to wait for both indication events and tick events usbc_trace_info(USBCORE_SUSPEND_START_POLL); usbc_core_get_instance()->hmu_indication = HIF_DRV_EG_HIF_TICK_EVENT | HIF_DRV_EG_USBC_IND_EVENT; // Ask USBIDLE to notify L4 to turn RF power on or go back to normal operation state usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 0, 0, 0, (remote_wakeup_enabled? 1:0)); usb_idle_set_l4_power_saving(KAL_FALSE); usb_idle_event_notify_to_l4(KAL_FALSE, remote_wakeup_enabled); }
void* usbc_class_device_get_context(kal_uint8 class_device_id) { usbc_core_t *pUsbCore = usbc_core_get_instance(); usbc_core_class_device_t *pClassDevice = &(pUsbCore->class_device[class_device_id]); usbc_class_device_instance_t *pClassDeviceInstance = &(pClassDevice->device_instance); return pClassDeviceInstance->context; }
static void usbc_core_handle_set_address() { usbc_core_t* pUsbCore = usbc_core_get_instance(); kal_uint16 wValue = pUsbCore->setup_packet.wValue; usbc_core_printf("=========>usbcore_handle_set_address\r\n"); usbc_trace_info(USBCORE_SET_ADDRESS, (wValue & 0x7f)); usbc_core_set_usb_address(wValue & 0x7f); usbc_core_set_control_request(NULL, 0, USBC_CONTROL_REQUEST_TYPE_RECEIVE); }
void usbc_core_notify_speed_change(usbc_usb_speed_e speed) { usbc_core_t *pUsbCore = usbc_core_get_instance(); kal_uint8 idx = 0; for (idx = 0; idx < pUsbCore->total_class_devices; idx++) { if (USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[idx].state && NULL != pUsbCore->class_device[idx].notify_usb_speed) { pUsbCore->class_device[idx].notify_usb_speed(idx, speed); } } }
void usbc_core_notify_alternate_setting(kal_uint8 intf_idx, kal_uint8 alternate_setting) { usbc_core_t *pUsbCore = usbc_core_get_instance(); usbc_core_class_interface_t *intf = &pUsbCore->class_interface[intf_idx]; if (USBC_CORE_CLASS_INTERFACE_STATE_ACTIVE == intf->state && NULL != intf->notify_alternate_setting) { intf->notify_alternate_setting( intf->class_device_id, intf->interface_type, intf->alternate_setting); } }
usbc_class_device_instance_t* usbc_class_device_register( kal_uint8 class_device_id, usbc_class_device_info_t *device_info) { usbc_core_t *pUsbCore = usbc_core_get_instance(); if (pUsbCore == NULL) { ASSERT(0); return NULL; } USBC_NON_EXCEPTION_MODE_CHECK(); return usbc_core_device_register(class_device_id, pUsbCore, device_info); }
usbc_interface_association_descriptor_t* usbc_get_iad_number(kal_uint8 config_num, kal_uint8 *iad_num_p) { usbc_core_t* usbc_inst = usbc_core_get_instance(); ASSERT(config_num < MAX_USBCORE_CONFIG_NUM); ASSERT(usbc_inst->resource_iad_number[config_num] < MAX_USBCORE_IAD_NUM); usbc_inst->resource_iad_number[config_num]++; if (iad_num_p) { *iad_num_p = usbc_inst->resource_iad_number[config_num] - 1; } return (&usbc_inst->iad_descriptor[config_num][usbc_inst->resource_iad_number[config_num] - 1]); }
usbc_interface_info_t* usbc_get_interface_number(kal_uint8 config_num, kal_uint8 *if_num_p) { usbc_core_t* usbc_inst = usbc_core_get_instance(); ASSERT(config_num < MAX_USBCORE_CONFIG_NUM); ASSERT(usbc_inst->resource_interface_number[config_num] < MAX_USBCORE_INTERFACE_NUM); usbc_inst->resource_interface_number[config_num]++; if (if_num_p) { *if_num_p = usbc_inst->resource_interface_number[config_num] - 1; } return (&usbc_inst->if_info[config_num][usbc_inst->resource_interface_number[config_num] - 1]); }
usbc_endpoint_info_t* usbc_get_endpoint_rx_number(kal_uint8 config_num, kal_uint8 *rx_ep_num_p) { usbc_core_t* usbc_inst = usbc_core_get_instance(); ASSERT(config_num < MAX_USBCORE_CONFIG_NUM); ASSERT(usbc_inst->resource_ep_rx_number[config_num] < MAX_USBCORE_QUEUE_NUM); usbc_inst->resource_ep_rx_number[config_num]++; if (rx_ep_num_p) { *rx_ep_num_p = usbc_inst->resource_ep_rx_number[config_num]; } return (&usbc_inst->ep_rx_info[config_num][usbc_inst->resource_ep_rx_number[config_num] - 1]); }
kal_uint8 usbc_get_string_number(void *string) { usbc_core_t* usbc_inst = usbc_core_get_instance(); usbc_string_descriptor_t* string_dscr; ASSERT(string); ASSERT(usbc_inst->resource_string_number < MAX_USBCORE_STRING_DESCRIPTOR_NUM); string_dscr = (usbc_string_descriptor_t*)string; usbc_inst->resource_string_number++; usbc_inst->string_descriptor[usbc_inst->resource_string_number - 1] = string_dscr; return (usbc_inst->resource_string_number - 1); }
void usbc_resource_reset(void) { usbc_core_t* usbc_inst = usbc_core_get_instance(); kal_uint8 idx; for (idx = 0; idx < MAX_USBCORE_CONFIG_NUM; idx++) { usbc_inst->resource_interface_number[idx] = 0; usbc_inst->resource_iad_number[idx] = 0; usbc_inst->resource_ep_tx_number[idx] = 0; usbc_inst->resource_ep_rx_number[idx] = 0; } usbc_inst->resource_string_number = 0; }
static void release_class_device(kal_uint8 class_device_id) { usbc_core_t* pUsbCore = usbc_core_get_instance(); kal_uint8 i = 0; pUsbCore->class_device[class_device_id].state = USBC_CORE_CLASS_DEVICE_STATE_INITIATED; for ( i=0; i<pUsbCore->total_class_interfaces; i++ ) { if (pUsbCore->class_interface[i].class_device_id == class_device_id) { pUsbCore->class_interface[i].state = USBC_CORE_CLASS_INTERFACE_STATE_INITIATED; } } }
void usbc_core_notify_stall(kal_bool is_tx, kal_uint8 queue_idx, kal_bool stall) { usbc_core_t *pUsbCore = usbc_core_get_instance(); usbc_core_queue_t *pQueue; if (is_tx) { pQueue = &pUsbCore->tx_queue[queue_idx]; } else { pQueue = &pUsbCore->rx_queue[queue_idx]; } if (pQueue->state > USBC_CORE_QUEUE_STATE_INITIATED && NULL != pQueue->notify_stall) { pQueue->notify_stall(pQueue->class_device_id, stall); } }
static void release_pipe_queue(kal_uint8 class_device_id) { usbc_core_t* pUsbCore = usbc_core_get_instance(); kal_uint8 i = 0; for ( i=0; i< MAX_USBCORE_QUEUE_NUM; i++ ) { if (pUsbCore->tx_queue[i].class_device_id == class_device_id) { pUsbCore->tx_queue[i].state = USBC_CORE_QUEUE_STATE_INITIATED; } if (pUsbCore->rx_queue[i].class_device_id == class_device_id) { pUsbCore->rx_queue[i].state = USBC_CORE_QUEUE_STATE_INITIATED; } } }
void usbc_core_notify_state_suspending() { kal_uint8 func_list; usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_p; // notify USBCLASS of USB suspended usbc_core_indicate_state(USBC_USB_STATE_SUSPENDING); usbc_core_indicate_state(USBC_USB_STATE_SUSPENDED); if( USBC_IS_IN_EXCEPTION_MODE() ) { return; } // Updatea function pointer for setting GPDs in DRAM buffer usbc_trace_info(USBCORE_UPDATE_API_BUFF_GPD, 1); usbc_suspended_hif_factory(); // Notify USBIDLE task to gate USB clock usbc_trace_info(USBCORE_DEV_SUSPEND_CLOCK, 1, 1); usb_idle_set_clockGating(KAL_TRUE); // notify USBIDLE that it has to gate the clock of USB IP msg_send4(MOD_USBCORE, // src module MOD_USBIDLE, // dst module 0, // sap id MSG_ID_USBCORE_SUSPEND_TO_IDLE); //msg id // Ask USBIDLE to notify L4 to turn RF power off or go to fast dormancy func_list = usbc_core_get_function_remote_wk_list(); rsp_msg_p = (usbcore_usbidle_l4_power_saving_req_struct*)construct_local_para(sizeof(usbcore_usbidle_l4_power_saving_req_struct), TD_RESET); ASSERT(rsp_msg_p); rsp_msg_p->notify_suspend = KAL_TRUE; rsp_msg_p->notify_suspend_with_remote_wk = (func_list==0)? KAL_FALSE:KAL_TRUE; usbc_trace_info(USBCORE_DEV_SUSPEND_L4, 1, 1, 1, (rsp_msg_p->notify_suspend_with_remote_wk? 1:0)); usb_idle_set_l4_power_saving(KAL_TRUE); msg_send6(MOD_USBCORE, // src module MOD_USBIDLE, // dst module 0, // sap id MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4, (local_para_struct*)rsp_msg_p, 0); //msg id // Set USBCORE task to wait for indication events only usbc_trace_info(USBCORE_SUSPEND_STOP_POLL); usbc_core_get_instance()->hmu_indication = HIF_DRV_EG_USBC_IND_EVENT; // Set USBCORE task to wait for indication events only }
kal_bool usbc_class_device_deregister(kal_uint8 class_device_id) { usbc_core_t* pUsbCore = usbc_core_get_instance(); USBC_NON_EXCEPTION_MODE_CHECK(); if ( (class_device_id >= pUsbCore->total_class_devices) || (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) ) { ASSERT(0); return KAL_FALSE; } release_pipe_queue(class_device_id); release_class_device(class_device_id); return KAL_TRUE; }
kal_bool usbc_class_device_set_hif_disconnect(kal_uint8 class_device_id) { usbc_core_t* pUsbCore = usbc_core_get_instance(); USBC_NON_EXCEPTION_MODE_CHECK(); USBC_CLASS_DEVICE_CONTEXT_CHECK(); if ( (class_device_id >= pUsbCore->total_class_devices) || (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) ) { ASSERT(0); return KAL_FALSE; } usbc_normal_hif_disconnect(); return KAL_TRUE; }
void usbc_class_device_netifx_suspend_notify(kal_uint8 class_device_id, kal_bool suspend, kal_bool remote_wakeup) { usbcore_usbidle_l4_power_saving_req_struct *rsp_msg_p; usbc_core_t* pUsbCore = usbc_core_get_instance(); if ( 1 #ifdef __USB_RNDIS_SUPPORT__ && (pUsbCore->class_device[class_device_id].class_type != USB_CLASS_RNDIS) #endif #ifdef __USB_MBIM_SUPPORT__ && (pUsbCore->class_device[class_device_id].class_type != USB_CLASS_MBIM) #endif #ifdef __USB_ECM_SUPPORT__ && (pUsbCore->class_device[class_device_id].class_type != USB_CLASS_ECM) #endif ) { ASSERT(0); return; } // In current implemnntation, only notifying L4 of USB suspended/resuming with remote wakeup is allowed ASSERT(remote_wakeup); if( suspend ) { rsp_msg_p = (usbcore_usbidle_l4_power_saving_req_struct*)construct_local_para(sizeof(usbcore_usbidle_l4_power_saving_req_struct), TD_RESET); ASSERT(rsp_msg_p); rsp_msg_p->notify_suspend = suspend; rsp_msg_p->notify_suspend_with_remote_wk = remote_wakeup; usb_idle_set_l4_power_saving(KAL_TRUE); msg_send6(MOD_USBCORE, // src module MOD_USBIDLE, // dst module 0, // sap id MSG_ID_USBCORE_IDLE_NOTIFY_TO_L4, (local_para_struct*)rsp_msg_p, 0); } else { usb_idle_set_l4_power_saving(KAL_FALSE); usb_idle_event_notify_to_l4(suspend, remote_wakeup); } }
kal_bool usbc_core_get_queue_info( kal_uint8 class_device_id, kal_uint8 queue_no, usbc_core_queue_t **queue, hif_queue_type_e *queue_type) { usbc_core_t *pUsbCore = usbc_core_get_instance(); kal_uint8 core_queue_no; if ((class_device_id >= pUsbCore->total_class_devices) || (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED)) { ASSERT(0); return KAL_FALSE; } if ((queue_no & ~PIPE_QUEUE_RX_MASK) > MAX_USBCORE_QUEUE_NUM) { ASSERT(0); return KAL_FALSE; } if ((queue_no & PIPE_QUEUE_RX_MASK) != PIPE_QUEUE_RX_MASK) { core_queue_no = queue_no; *queue_type = HIFQ_TYPE_TX; *queue = &(pUsbCore->tx_queue[core_queue_no]); } else { core_queue_no = queue_no & ~PIPE_QUEUE_RX_MASK; *queue_type = HIFQ_TYPE_RX; *queue = &(pUsbCore->rx_queue[core_queue_no]); } if ((*queue)->class_device_id != class_device_id) { ASSERT(0); return KAL_FALSE; } if ((*queue)->state != USBC_CORE_QUEUE_STATE_ACTIVE) { ASSERT(0); return KAL_FALSE; } return KAL_TRUE; }
void usbc_mode_switch(usb_mode_e mode){ kal_uint32 idx; usbc_core_t* usbc_inst = usbc_core_get_instance(); usbc_class_reinit_func_t class_reinit; usbc_ind_t ind_to_enqueue; // Do mode switch immediately if it is not in HISR, or enqueue a mode switch event for USBCORE task if (!kal_if_hisr()) { #if 1 if (mode == USB_MODE_MSD_OSDRTY){ /* wait 3 second for OSD known issue */ kal_sleep_task(600); } #endif /* 1. set disconnect */ hifusb_set_disconnect(); usbc_empty_ind_queue(); /* 2. Set switch mode */ usbc_inst->is_mode_switch = KAL_TRUE; usbc_inst->mode = mode; /* 3. Send re-init callback to all usb class */ _SET_NODE_VALUE(0); usbc_stack_checkin(USB_CLASS_NUM, NULL); for (idx = 0; idx < USB_CLASS_NUM; idx++) { class_reinit = _get_class_reinit_func(idx); _SET_NODE_REG_TABLE(idx, NULL); if (class_reinit) { usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_START, idx); class_reinit(KAL_TRUE); usbc_trace_info(USBCORE_ALL_NODE_CHECKIN_REINIT_CLASS_END, idx); } else { EXT_ASSERT(KAL_FALSE, 2, 0, 0); } } } else { ind_to_enqueue.type = USBC_IND_MODE_SWITCH; ind_to_enqueue.ext = 0; ind_to_enqueue.data = (kal_uint8)mode; usbc_enqueue_ind(&ind_to_enqueue); hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT); } }
static void usbc_cosim_hif_attach(void) { usbc_core_t *pUsbCore = usbc_core_get_instance(); /* fake USB HW info for ESL COSIM */ hifusb_boot_info_t usb_boot_info; hifusb_get_boot_info(&usb_boot_info); usbc_esl_printf("Emulare USB speed change and reset...\n"); usbc_core_speed_change(pUsbCore, (usbc_usb_speed_e)usb_boot_info.usb_speed); // emulate speed change notify usbc_core_notify_speed_change((usbc_usb_speed_e)usb_boot_info.usb_speed); usbc_core_set_hif_configuration(); // emulate reset notify usbc_core_notify_state_reset(); usbc_esl_printf("Emulare HIF USB set address...\n"); /* emulate SetAddress */ usbc_core_set_usb_address(usb_boot_info.usb_addr & 0x7f); // set USB address usbc_esl_printf("Emulare USB set configuration...\n"); /* emulate SetConfig */ usbc_core_set_usb_configuration(usb_boot_info.usb_config_val); //set USB configuration, assume there is only one configuration in META mode }
/*! * @brief This function is used to notify function suspend or function resume to a specific class device */ static void usbc_core_indicate_function_state(kal_uint8 class_device_id, usbc_usb_state_e state) { usbc_core_t *pUsbCore = usbc_core_get_instance(); if ( state != USBC_USB_STATE_SUSPENDING && state != USBC_USB_STATE_SUSPENDED && state != USBC_USB_STATE_RESUME ) { ASSERT(0); return; } if ( USBC_CORE_CLASS_DEVICE_STATE_REGISTERED == pUsbCore->class_device[class_device_id].state && NULL != pUsbCore->class_device[class_device_id].notify_usb_state ) { usbc_trace_info(USBCORE_NOTIFY_CLASS_START, pUsbCore->class_device[class_device_id].class_type, state); pUsbCore->class_device[class_device_id].notify_usb_state(class_device_id, state); usbc_trace_info(USBCORE_NOTIFY_CLASS_END, pUsbCore->class_device[class_device_id].class_type, state); } }
kal_bool usbc_class_device_submit_control_request( kal_uint8 class_device_id, kal_uint8* buffer, kal_uint32 length, usbc_control_request_type_e type) { usbc_core_t* pUsbCore = usbc_core_get_instance(); if (!USBC_IS_IN_EXCEPTION_MODE()) { USBC_CLASS_DEVICE_CONTEXT_CHECK(); } if ( (class_device_id >= pUsbCore->total_class_devices) || (pUsbCore->class_device[class_device_id].state != USBC_CORE_CLASS_DEVICE_STATE_REGISTERED) ) { ASSERT(0); return KAL_FALSE; } usbc_core_set_control_request(buffer, length, type); return KAL_TRUE; }