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調用,用于關聯java和C++之間的變量
??????????????? 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) { //如果就收到來自kernel的uevent,觸發該函數
??????????????????????????????? ??? update(); //-->native_update();和processValues();
??????????????????????????????? }
??????????????? ?????? };
??????????????? c. native_update函數會通過JNI調用得到更新的mAcOnline和mUsbOnline值
??????????????? d. processValues會根據mAcOnline和mUsbOnline值對mPlugType賦值
??????????????????????????????? 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_CHANGED的intent
??????????????????????????????? // 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");很關鍵,表明只是獲取usb的power_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,該函數中充電類型只歸納成4種:POWER_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_property和dc_psy.get_property
(在函數中pm8921_charger_probe)讀取property時
????????????????????????????????如果是USB type,則在pm_power_get_property_usb讀取POWER_SUPPLY_PROP_ONLINE的值,其中POWER_SUPPLY_TYPE_USB,POWER_SUPPLY_TYPE_USB_CDP和POWER_SUPPLY_TYPE_USB_ACA都被歸納成USB
charger
????????????????????????????????如果是AC type,則在pm_power_get_property_mains讀取POWER_SUPPLY_PROP_ONLINE的值,只有POWER_SUPPLY_TYPE_USB_DCP為AC
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?,?就會馬上發送uevent給user
space,然后user space通過sysfs得到USB
type變化后的信息,參考用戶空間的分析
?
二、硬件分析
主要是通過特殊設計的電路,檢測不同的pin的狀態,從而確定是何種類型的Charger. 更details的內容省略。
總結
以上是生活随笔為你收集整理的USB port 如何识别不同的Charger类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 性能分析工具dumpsy
- 下一篇: BQ24296充电管理芯片使用过程中的注