typec role switch流程

发布时间 2023-07-23 11:18:55作者: 轻轻的吻
  • smblite_lib_typec_port_type_set
  • schedule_delayed_work(&chg->role_reversal_check, msecs_to_jiffies(ROLE_REVERSAL_DELAY_MS));
  • smblite_lib_typec_role_check_work
  • static void smblite_lib_typec_role_check_work(struct work_struct *work)
    {
            struct smb_charger *chg = container_of(work, struct smb_charger,
                                            role_reversal_check.work);
            int rc = 0;
    
            if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) {
                    chg->pr_swap_in_progress = false;
                    vote(chg->awake_votable, TYPEC_SWAP_VOTER, false, 0);
                    return;
            }
    
            mutex_lock(&chg->typec_lock);
    
            switch (chg->dr_mode) {
            case TYPEC_PORT_SNK:
                    if (chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
                            smblite_lib_dbg(chg, PR_MISC, "Role reversal not latched to UFP in %d msecs. Resetting to DRP mode\n",
                                                    ROLE_REVERSAL_DELAY_MS);
                            rc = smblite_lib_force_dr_mode(chg, TYPEC_PORT_DRP);
                            if (rc < 0)
                                    smblite_lib_err(chg, "Couldn't to set DRP mode, rc=%d\n",
                                                    rc);
                    } else {
                            chg->power_role = POWER_SUPPLY_TYPEC_PR_SINK;
                            typec_set_pwr_role(chg->typec_port, TYPEC_SINK);
                            typec_set_data_role(chg->typec_port, TYPEC_DEVICE);
                            smblite_lib_dbg(chg, PR_MISC, "Role changed successfully to SINK");
                    }
                    break;
            case TYPEC_PORT_SRC:
                    if (chg->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
                            || chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) {
                            smblite_lib_dbg(chg, PR_MISC, "Role reversal not latched to DFP in %d msecs. Resetting to DRP mode\n",
                                                    ROLE_REVERSAL_DELAY_MS);
                            chg->pr_swap_in_progress = false;
                            chg->typec_role_swap_failed = true;
                            rc = smblite_lib_force_dr_mode(chg,
                                                            TYPEC_PORT_DRP);
                            if (rc < 0)
                                    smblite_lib_err(chg, "Couldn't to set DRP mode, rc=%d\n",
                                                            rc);
                    } else {
                            chg->power_role = POWER_SUPPLY_TYPEC_PR_SOURCE;
                            typec_set_pwr_role(chg->typec_port, TYPEC_SOURCE);
                            typec_set_data_role(chg->typec_port, TYPEC_HOST);
                            smblite_lib_dbg(chg, PR_MISC, "Role changed successfully to SOURCE");
                    }
                    break;
            default:
                    pr_debug("Already in DRP mode\n");
                    break;
            }
    
            chg->pr_swap_in_progress = false;
            vote(chg->awake_votable, TYPEC_SWAP_VOTER, false, 0);
            mutex_unlock(&chg->typec_lock);
    }