Ejemplo n.º 1
0
void usbc_core_notify_state_reset()
{
    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_RESET);
        usbc_core_clear_status();
        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);

    // Update function pointer for set GPDs to hardware normally
    usbc_trace_info(USBCORE_UPDATE_API_BUFF_GPD, 0);
    usbc_normal_hif_factory();

    // Notify USB reset event to USB classes and clear USB status
    usbc_core_indicate_state(USBC_USB_STATE_RESET);
    usbc_core_clear_status();

    // 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);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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_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;
}