kal_bool usbc_class_device_submit_io_request_ext(
    kal_uint8 class_device_id, kal_uint8 queue_no,
    usbc_io_request_t  *io_request, 
    usbc_io_ext_info_t *info)
{
    usbc_core_queue_t  *pQueue = NULL;
    hif_queue_type_e    core_queue_hif_type;

    USBC_NON_EXCEPTION_MODE_CHECK();
    USBC_CLASS_DEVICE_CONTEXT_CHECK();

    if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
        return KAL_FALSE;
    }

    switch (info->type) {
    case USBC_IO_TX_NO_FLUSH:
        core_queue_hif_type = HIFQ_TYPE_TX_NO_FLUSH;
        break;

    default:
        ASSERT(KAL_FALSE);
        return KAL_FALSE;
    }

    return usbc_class_device_submit_io_request_priv(core_queue_hif_type, pQueue, io_request);
}
示例#2
0
static void usbc_cosim_hif_factory(void)
{
    USBC_NON_EXCEPTION_MODE_CHECK();

    usbc_esl_printf("Use DRVHIF ESL APIs...\n");
    usbc_core_set_property = hifusb_set_property_emulate;
    usbc_core_set_usbhif_address = hifusb_set_usb_address_emulate;
    usbc_core_set_usbhif_configuration = hifusb_set_usb_configuration_emulate;
    usbc_core_set_usbhif_connect = usbc_cosim_hif_connect;
    usbc_core_set_usbhif_disconnect = usbc_cosim_hif_disconnect;
}
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);
}
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;
}
kal_bool usbc_class_device_change_notify_complete(
    kal_uint8 class_device_id, kal_uint8 queue_no,
    void (*notify_complete)(kal_uint8 class_device_id, usbc_io_request_t* io_request))
{
    usbc_core_queue_t* pQueue = NULL;
    hif_queue_type_e core_queue_hif_type;

    USBC_NON_EXCEPTION_MODE_CHECK();
    USBC_CLASS_DEVICE_CONTEXT_CHECK();

    if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
        return KAL_FALSE;
    }

    pQueue->notify_complete = notify_complete;

    return KAL_TRUE;
}
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_submit_io_request(
    kal_uint8 class_device_id, kal_uint8 queue_no,
    usbc_io_request_t* io_request)
{
    usbc_core_queue_t  *pQueue = NULL;
    hif_queue_type_e    core_queue_hif_type;

    HIF_SWLA_START("UD1");

    USBC_NON_EXCEPTION_MODE_CHECK();
    USBC_CLASS_DEVICE_CONTEXT_CHECK();

    if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
        HIF_SWLA_STOP("UD1");
        return KAL_FALSE;
    }

    HIF_SWLA_STOP("UD1");
    return usbc_class_device_submit_io_request_priv(core_queue_hif_type, pQueue, io_request);
}
kal_bool usbc_class_device_func_remote_wk(kal_uint8 class_device_id)
{

    usbc_core_t* pUsbCore = usbc_core_get_instance();
    kal_bool isDeviceSuspend;
    usbc_ind_t          ind_to_enqueue;
    usbc_func_state_e    state;

    usbc_trace_info(USBCORE_REMOTE_WK_START, class_device_id);

    USBC_NON_EXCEPTION_MODE_CHECK();
    USBC_CLASS_DEVICE_CONTEXT_CHECK();

    /* Check whether the requested function is capable to wakeup the host and remote wakeup is enabled.
       Return KAL_FALSE if the function is not valid to wakeup host
     */
    if ( pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id) != 0x03 )
    {
        usbc_trace_error(USBCORE_REMOTE_WK_INVALID, class_device_id, pUsbCore->class_device[class_device_id].query_func_wk_status(class_device_id));
        ASSERT(0);
        return KAL_FALSE;
    }

    // check for the remote wakeup once a function at the same time
    USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_remote_wk_mutex);

    // reset the status of function accessing of class device id
    USBC_CLASS_REMOTE_WK_LOCK(pUsbCore->usbc_class_func_access_mutex);
    pUsbCore->is_func_be_accessed[class_device_id] = KAL_FALSE;
    USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_func_access_mutex);

    isDeviceSuspend = (pUsbCore->state == USBC_USB_STATE_SUSPENDED)? KAL_TRUE:KAL_FALSE;

    /* If it is resumed from device suspend,
            then send hifusb_remote_wakeup first and wait for the resume callback to know LPM state to U0.
       If it is resumed from function suspend,
            then send notification to resume the suspended function in USB Core context.
     */
    if ( isDeviceSuspend )
    {
        usbc_trace_info(USBCORE_REMOTE_WK_DEVICE, class_device_id);
        usb_idle_set_clockGating(KAL_FALSE);    // nofity USBIDLE that it does not have to gate the clock of USB IP 
        usbc_normal_hif_remote_wakeup();
    }

    //else if ( pUsbCore->class_device[class_device_id].is_func_suspend )
    if ( pUsbCore->class_device[class_device_id].is_func_suspend )
    {
        // block until device resume
        while ( isDeviceSuspend )
        {
            kal_sleep_task(USBC_DEV_RESUME_DURATION_TICK);
            isDeviceSuspend = (pUsbCore->state == USBC_USB_STATE_SUSPENDED)? KAL_TRUE:KAL_FALSE;
            usbc_trace_warn(USBCORE_REMOTE_WK_DEVICE_WAIT, class_device_id);
        }

        usbc_trace_info(USBCORE_REMOTE_WK_FUNC, class_device_id);
        // send callback to notify class device of resuming
        state = USBC_FUNC_STATE_RESUME;
        // Enqueue USB function state which will be handled in USB context later.
        ind_to_enqueue.type = USBC_IND_FUNC_EVENT;
        ind_to_enqueue.ext = class_device_id;
        ind_to_enqueue.data = (kal_uint8)state;
        usbc_enqueue_ind(&ind_to_enqueue);
        // Wake up USBCORE task to process indications.
        hmu_hifeg_set(HIF_DRV_EG_USBC_IND_EVENT);
    }

    // release for the remote wakeup of a function
    USBC_CLASS_REMOTE_WK_UNLOCK(pUsbCore->usbc_class_remote_wk_mutex);

    // call HIF driver API to send function wakeup notification, and resend if needed
    if ( pUsbCore->speed == USBC_USB_SPEED_USB30 )
    {
        usbc_set_wk_notify_timer(class_device_id);
    }

    return KAL_TRUE;
}
kal_bool usbc_class_device_flush_io_request(
    kal_uint8 class_device_id, kal_uint8 queue_no)
{
    usbc_core_queue_t* pQueue = NULL;
    hif_queue_type_e core_queue_hif_type;
    hif_flush_type_e core_queue_flush_type;
    qbm_gpd* first_gpd  = NULL;
    qbm_gpd* last_gpd   = NULL;
    kal_uint32 num = 0;

    USBC_NON_EXCEPTION_MODE_CHECK();
    USBC_CLASS_DEVICE_CONTEXT_CHECK();

    if (!usbc_core_get_queue_info(class_device_id, queue_no, &pQueue, &core_queue_hif_type)) {
        return KAL_FALSE;
    }

    if ( pQueue->notify_complete == NULL )
    {
        core_queue_flush_type = HIFQ_FLUSH_FREE;
    } else {
        core_queue_flush_type = HIFQ_FLUSH_DEQ;
    }

    // Flush GPDs that are buffered in DRAM, and give GPDs back to uppoer layers
    num = hifusbq_pwrsave_flush_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd);
    if ( num != 0 )
    {
#ifdef __USBCORE_DEBUG__
        usbc_core_printf("[USBCORE] flush type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd);
        //usbc_core_dump_gpd_list(first_gpd, last_gpd);
#endif
        if ( pQueue->notify_complete != NULL )
        {
            if ( first_gpd == NULL )
            {
                /* just indicate a notification */
                usbc_data_trace(USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, 0x00, 0x00);
                pQueue->notify_complete(pQueue->class_device_id, NULL);
            } else {
                usbc_io_request_t* request = NULL;
                usbc_data_trace(USBCORE_CLASS_FLUSH_SW_QUEUE, queue_no, num, first_gpd, last_gpd);
                request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
                request->next_request = NULL;
                request->first_gpd = first_gpd;
                request->last_gpd = last_gpd;
                pQueue->notify_complete(pQueue->class_device_id, request);
            }
        }
    }

    // Flush GPDs that are configured in hardware, and give GPDs back to uppoer layers
    num = hifusbq_flush_gpd(core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), core_queue_flush_type, (void**)&first_gpd, (void**)&last_gpd);
    if ( num != 0 )
    {
#ifdef __USBCORE_DEBUG__
        usbc_core_printf("[USBCORE] flush type %d queue no %d first gpd %x last gpd %x\r\n", core_queue_hif_type, HIFUSB_EPNO_2_QNO(pQueue->ep_no), first_gpd, last_gpd);
        //usbc_core_dump_gpd_list(first_gpd, last_gpd);
#endif
        if ( pQueue->notify_complete != NULL )
        {
            if ( first_gpd == NULL )
            {
                /* just indicate a notification */
                usbc_data_trace(USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, 0x00, 0x00);
                pQueue->notify_complete(pQueue->class_device_id, NULL);
            } else {
                usbc_io_request_t* request = NULL;
                usbc_data_trace(USBCORE_CLASS_FLUSH_HW_QUEUE, queue_no, num, first_gpd, last_gpd);
                request = (usbc_io_request_t*)QBM_DES_GET_SW_CTRL_FIELD(first_gpd);
                request->next_request = NULL;
                request->first_gpd = first_gpd;
                request->last_gpd = last_gpd;
                pQueue->notify_complete(pQueue->class_device_id, request);
            }
        }
    }

    return KAL_TRUE;
}