示例#1
0
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;
}
示例#2
0
/*------------------------------------------------------------------------------
 * 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;
}
示例#4
0
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);
    }
}
示例#7
0
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);
    }
}
示例#8
0
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;
}
示例#10
0
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);
}
示例#11
0
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);
        }
    }
}
示例#12
0
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;
        }
    }
}
示例#20
0
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;
        }
    }
}
示例#22
0
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;
}
示例#27
0
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);
	}
}
示例#28
0
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
}
示例#29
0
/*!
 *  @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;
}