USB port 如何識別不同的Charger類型


基於Qualcom 8960/8921平台

一,軟件分析

1.  USB charger types & Power supply types

USB_INVALID_CHARGER              Invalid USB charger.

USB_SDP_CHARGER                       Standard downstream port. Refers to a downstream port  on USB2.0 compliant host/hub.

USB_DCP_CHARGER                      Dedicated charger port (AC charger/ Wall charger).

USB_CDP_CHARGER                      Charging downstream port. Enumeration can happen and IDEV_CHG_MAX can be drawn irrespective of USB state.

USB_ACA_A_CHARGER                                B-device is connected on accessory port with charger connected on charging port. This configuration allows charging in host mode.

USB_ACA_B_CHARGER                 No device (or A-device without VBUS) is connected on accessory port with charger connected on charging port.

USB_ACA_C_CHARGER                 A-device (with VBUS) is connected on accessory port with charger connected on charging port.

USB_ACA_DOCK_CHARGER        A docking station that has one upstream port and one or more downstream ports. Capable of supplying IDEV_CHG_MAX irrespective of devices connected on 
accessory ports.

USB_PROPRIETARY_CHARGER   A proprietary charger pull DP and DM to specific voltages between 2.0-3.3v for identification.

 

POWER_SUPPLY_TYPE_USB,                      /* Standard Downstream Port */

POWER_SUPPLY_TYPE_USB_DCP,           /* Dedicated Charging Port */

POWER_SUPPLY_TYPE_USB_CDP,           /* Charging Downstream Port */

POWER_SUPPLY_TYPE_USB_ACA,           /* Accessory Charger Adapters */

POWER_SUPPLY_TYPE_BMS,                     /* Battery Monitor System */

 

2. How to classify or identify charger?

 

USB_SDP_CHARGER

POWER_SUPPLY_TYPE_USB

USB Charger

USB_CDP_CHARGER

POWER_SUPPLY_TYPE_USB_CDP

USB_ACA_DOCK_CHARGER

POWER_SUPPLY_TYPE_USB_ACA

USB_ACA_A_CHARGER

USB_ACA_B_CHARGER

USB_ACA_C_CHARGER

USB_DCP_CHARGER

POWER_SUPPLY_TYPE_USB_DCP

AC Charger

USB_PROPRIETARY_CHARGER

 

As for the DMS, refer to bold font items, so it is USB charger.

 

3. Analysis about source codes

*******************************************************************

###用戶空間的分析如下:

1. 檢查 /sys/class/power_supply/pm8921-dc/online /sys/class/power_supply/usb/online 的值,可以知道是何充電器類型

                @frameworks/base/services/jni/com_android_server_batteryservice.cpp中有

                int register_android_server_BatteryService(JNIEnv* env)          

                

                if (strcmp(buf, "Mains") == 0) { ///sys/class/power_supply/pm8921-dc/type == Mains

                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);

                    if (access(path, R_OK) == 0)

                        gPaths.acOnlinePath = strdup(path);

                }

                

   如果/sys/class/power_supply/pm8921-dc/online==1,則插入的充電器是wall
charger

      /sys/class/power_supply/usb/online==1, 則插入的充電器是usb charger

   調試路徑:/sys/kernel/debug/msm_otg

2. 分析frameworks/base/services/jni/com_android_server_batteryservice.cpp

                a.函數register_android_server_BatteryService將為被frameworks/base/services/jni/onload.cpp中的JNI_OnLoad調用,用於關聯javaC++之間的變量

                b.jclass clazz = env->FindClass("com/android/server/BatteryService"); //根據java的路徑找到batteryservice.java對應的jclass    

                  gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");

                  gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z"); //用於關聯batteryservice.java中變量private
boolean mAcOnline
gFieldIds.mAcOnline

                c. android_server_BatteryService_update

                                static JNINativeMethod sMethods[] = {

                                     /* name, signature, funcPtr */

                                                {"native_update", "()V", (void*)android_server_BatteryService_update},

                                };

                   關聯到native_update@frameworks/base/services/java/com/android/server/batteryservice.java

3. 分析frameworks/base/services/java/com/android/server/batteryservice.java

                a. mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply"); //注冊監聽該uevent

                b.     private UEventObserver mPowerSupplyObserver = new UEventObserver() {

                                public void onUEvent(UEventObserver.UEvent event) { //如果就收到來自kerneluevent,觸發該函數

                                    update(); //-->native_update();processValues();

                                }

                       };

                c. native_update函數會通過JNI調用得到更新的mAcOnlinemUsbOnline

                d. processValues會根據mAcOnlinemUsbOnlinemPlugType賦值

                                if (mAcOnline) {

                                    mPlugType = BatteryManager.BATTERY_PLUGGED_AC;

                                } else if (mUsbOnline) {

                                    mPlugType = BatteryManager.BATTERY_PLUGGED_USB;

                                } else {

                                    mPlugType = BATTERY_PLUGGED_NONE;

                                }

                e. sendIntent函數會准備Intent並且broadcast這個Intent

                                Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); //public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";@batteryservice.java

                                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY

                                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);

 

                        intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);

                                ActivityManagerNative.broadcastStickyIntent(intent, null);

4. 分析vendor/semc/packages/apps/debugmenu/src/com/sonyericsson/debugmenu/battery.java

                a. 接收intent

                    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {

                                @Override

                                public void onReceive(Context arg0, Intent intent) {

                                    if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {

                                        mPowerInformation.parseIntent(intent);

                                        updateViews();

                                    }

                                }

                    };

                    public void registerBroadcastReceivers() {

                                IntentFilter mIntentFilter;

                                mIntentFilter = new IntentFilter();

                                mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //只接收Intent.ACTION_BATTERY_CHANGEDintent

                                // Register battery receiver.

                                registerReceiver(mBatteryInfoReceiver, mIntentFilter);

                    }         

                b. parseIntent 得到最新的"plugged"值賦給mPlugged

                c. updateViews 更新charger類型顯示

###內核空間

1. 插入充電器觸發的過程@kernel/drivers/usb/otg/msm_otg.c

                a. CONFIG_PM_RUNTIME 定義 @kernel/arch/arm/configs/viskan_huashan_defconfig

                b.msm_otg_runtime_resume-->msm_otg_resume-->??-->msm_otg_sm_work

                c.msm_otg_sm_work,先進入OTG_STATE_UNDEFINED case,然后進入OTG_STATE_B_IDLE
case-->motg->chg_state=USB_CHG_STATE_UNDEFINED-->
啟動msm_chg_detect_work

                d.msm_chg_detect_work 該函數主要完成USB charger類型的識別

                                USB_CHG_STATE_UNDEFINED //其中psy = power_supply_get_by_name("usb");很關鍵,表明只是獲取usbpower_supply,實際上就是chip->usb_psy@pm8921-charger.c

                                USB_CHG_STATE_WAIT_FOR_DCD         //Waiting for Data pins contact.

                                然后多次(MSM_CHG_DCD_MAX_RETRIES=6)檢測USB狀態,啟動queue_delayed_work(motg->wq,
&motg->chg_work, delay); //motg->chg_work=msm_chg_detect_work

                                USB_CHG_STATE_DETECTED //最后USB charge類型檢測完畢

                e. 啟動queue_work(motg->wq, &motg->sm_work); //motg->sm_work=msm_otg_sm_work

                f. 由於motg->chg_state==USB_CHG_STATE_DETECTED,

                                motg->chg_type==USB_DCP_CHARGER -->msm_otg_notify_charger(motg,IDEV_CHG_MAX);//IDEV_CHG_MAX=1500

2. 發送uevent到用戶層

                a. msm_otg_notify_charger@kernel/drivers/usb/otg/msm_otg.c

                b. -->msm_otg_notify_chg_type@msm_otg.c,該函數中充電類型只歸納成4POWER_SUPPLY_TYPE_USB,POWER_SUPPLY_TYPE_USB_CDP,POWER_SUPPLY_TYPE_USB_DCP,POWER_SUPPLY_TYPE_USB_ACA,POWER_SUPPLY_TYPE_BATTERY

                c. -->power_supply_set_supply_type@power_supply_core.c // set type of
the power supply

                d. -->psy->set_property(psy, POWER_SUPPLY_PROP_TYPE,&ret);

                                那么在用usb_psy.get_propertydc_psy.get_property
(
在函數中pm8921_charger_probe)讀取property

                                如果是USB type,則在pm_power_get_property_usb讀取POWER_SUPPLY_PROP_ONLINE的值,其中POWER_SUPPLY_TYPE_USBPOWER_SUPPLY_TYPE_USB_CDPPOWER_SUPPLY_TYPE_USB_ACA都被歸納成USB
charger

                                如果是AC type,則在pm_power_get_property_mains讀取POWER_SUPPLY_PROP_ONLINE的值,只有POWER_SUPPLY_TYPE_USB_DCPAC
charger
.

                e. psy=chip->usb_psy@pm8921-charger.c,所以繼續調用的是pm_power_set_property_usb@pm8921-charger.c

                f. -->pm8921_set_usb_power_supply_type(val->intval)@pm8921-charger.c

                                -->power_supply_changed(&the_chip->usb_psy);

                                -->power_supply_changed(&the_chip->dc_psy);

                g. power_supply_changed@pm8921-charger.c , 就會馬上發送ueventuser
space,
然后user space通過sysfs得到USB
type
變化后的信息,參考用戶空間的分析

 

二、硬件分析

主要是通過特殊設計的電路,檢測不同的pin的狀態,從而確定是何種類型的Charger. 更details的內容省略。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM