充电器类型检测实现代码分析

代码路径:/kernel/msm-3.18/drivers/usb/phy/phy_msm_usb.c
msm_otg_probe
(1)工作队列初始化

INIT_WORK(&motg->sm_work, msm_otg_sm_work);
INIT_DELAYED_WORK(&motg->chg_work, msm_chg_detect_work);充电器类型检测的work
INIT_DELAYED_WORK(&motg->id_status_work, msm_id_status_w);batt id状态的work
  • 1
  • 2
  • 3
  • 4

(2)注册power supply

motg->usb_psy.name = "usb";//文件节点/sys/class/power_supply/usb
    motg->usb_psy.type = POWER_SUPPLY_TYPE_USB;
    motg->usb_psy.supplied_to = otg_pm_power_supplied_to;
    motg->usb_psy.num_supplicants = ARRAY_SIZE(otg_pm_power_supplied_to);
    motg->usb_psy.properties = otg_pm_power_props_usb;//所有支持的property
    motg->usb_psy.num_properties = ARRAY_SIZE(otg_pm_power_props_usb);
    motg->usb_psy.get_property = otg_power_get_property_usb;
    motg->usb_psy.set_property = otg_power_set_property_usb;
    motg->usb_psy.property_is_writeable
        = otg_power_property_is_writeable_usb;

    if (!msm_otg_register_power_supply(pdev, motg))
        psy = &motg->usb_psy;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

下面来重点分析两个工作队列sm_work和chg_detected_work

msm_otg_sm_work
case OTG_STATE_B_IDLE:
switch (motg->chg_state) {
    case USB_CHG_STATE_UNDEFINED://代码里面定义了USB chg detection涉及的多个状态
        motg->chg_state = USB_CHG_STATE_IN_PROGRESS;//状态设置为检测中
        msm_chg_detect_work(&motg->chg_work.work);//启动充电器类型检测的work
    case USB_CHG_STATE_DETECTED://充电器类型检测完毕,也就是说上面的chg detect work
完毕后一定会设置该状态。
switch (motg->chg_type) {
        case USB_DCP_CHARGER:
        /* fall through */
        case USB_PROPRIETARY_CHARGER:
            msm_otg_notify_charger(motg,dcp_max_current);
            if (!motg->is_ext_chg_dcp)
                otg->phy->state =OTG_STATE_B_CHARGER;
                    break;
        case USB_UNSUPPORTED_CHARGER:
            msm_otg_notify_charger(motg, 0);
            if (!motg->is_ext_chg_dcp)
otg->phy->state =OTG_STATE_B_CHARGER;
                    break;
        case USB_CDP_CHARGER:
            msm_otg_notify_charger(motg,IDEV_CHG_MAX);
                    /* fall through */
        case USB_SDP_CHARGER:
            msm_chg_check_dcd_flchg(motg);
msm_otg_start_peripheral(otg, 1);
            otg->phy->state =OTG_STATE_B_PERIPHERAL;
            mod_timer(&motg->chg_check_timer,CHG_RECHECK_DELAY);
            break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

根据不同的充电器类型都调用了msm_otg_notify_charger函数,该函数一个参数为电流

msm_otg_notify_charger(struct msm_otg *motg, unsigned mA)
dev_dbg(motg->phy.dev, "Requested curr from USB = %u, max-type-c:%u\n",mA, motg->typec_current_max);//打印log信息
/* Save bc1.2 max_curr if type-c charger later moves to diff mode */
->  motg->bc1p2_current_max = mA;
-->if (msm_otg_notify_chg_type(motg))//通知PMIC充电器类型
        dev_err(motg->phy.dev,"Failed notifying %d charger type to PMIC\n",motg->chg_type);
    msm_otg_notify_power_supply(motg, mA);//设置其他property属性
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
msm_chg_detect_work:
switch (motg->chg_state) {
    case USB_CHG_STATE_UNDEFINED:
    case USB_CHG_STATE_IN_PROGRESS:
        ……
        motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
        break;
    case USB_CHG_STATE_WAIT_FOR_DCD:
        msm_chg_enable_primary_det(motg);
        motg->chg_state = USB_CHG_STATE_DCD_DONE;
case USB_CHG_STATE_DCD_DONE:
        vout = msm_chg_check_primary_det(motg);
if (vout && !dm_vlgc) { /* VDAT_REF < DM < VLGC */
            if (line_state) { /* DP > VLGC */
                motg->chg_type = USB_PROPRIETARY_CHARGER;//到这里检测出第一种充电器类型proprietary,具体是啥类型也不清楚。
                motg->chg_state = USB_CHG_STATE_DETECTED;
                delay = 0;
            } else {
                msm_chg_enable_secondary_det(motg);//再做进一步的类型检测
                motg->chg_state = USB_CHG_STATE_PRIMARY_DONE;
            }
else { /* DM < VDAT_REF || DM > VLGC */
            if (line_state) /* DP > VLGC or/and DM > VLGC */
                motg->chg_type = USB_PROPRIETARY_CHARGER;
            else if (!dcd) {
                if (motg->pdata->enable_floated_charger== FLOATING_AS_DCP)
                    motg->chg_type = USB_DCP_CHARGER;//根据配置设置这种情况下的充电器类型到底是DCP还是unsupported的,enable_floated_charger可以在dtsi中配置。
                else if (motg->pdata->enable_floated_charger== FLOATING_AS_INVALID)
                    motg->chg_type =USB_UNSUPPORTED_CHARGER;
            } else {
                motg->chg_type = USB_SDP_CHARGER;//检测到SDP充电器
            }
            motg->chg_state = USB_CHG_STATE_DETECTED;//状态设置为检测完成。
            delay = 0;
        }
case USB_CHG_STATE_PRIMARY_DONE:
        vout = msm_chg_check_secondary_det(motg);
        if (vout)
            motg->chg_type = USB_DCP_CHARGER;
        else
            motg->chg_type = USB_CDP_CHARGER;//在secondary检测阶段区分是DCP还是CDP
        motg->chg_state = USB_CHG_STATE_SECONDARY_DONE;
case USB_CHG_STATE_SECONDARY_DONE:
        motg->chg_state = USB_CHG_STATE_DETECTED;// secondary检测完毕整个类型检测完毕,状态设置为detected
case USB_CHG_STATE_DETECTED://下面看检测完毕后又做了哪些工作?看注释!!!
/* Notify the charger type to power supply owner as soon as we determine the charger.*/
msm_otg_notify_chg_type(motg);
queue_work(motg->otg_wq, &motg->sm_work);再次去调度sm_work

猜你喜欢

转载自blog.csdn.net/loongembedded/article/details/80646208