找回密码
 注册
查看: 2658|回复: 2
打印 上一主题 下一主题

USB port 如何识别不同的Charger类型

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2015-9-11 22:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
USB port 如何识别不同的Charger类型2 O) P/ z0 X9 B1 |" \6 @" e% c
2013年10月03日 ⁄ 综合 ⁄ 共 8924字        ⁄ 字号 [url=]小[/url] [url=]中[/url] [url=]大[/url] ⁄ 评论关闭3 \1 k6 G8 k8 e

3 J  i1 l( v8 H, R  L0 p* J/ L一,软件分析1.  USB charger types & Power supply types
# J- I5 d' M( s" tUSB_INVALID_CHARGER              Invalid USB charger.
6 E1 h- u" _' x6 q# V. S0 Z. e, _USB_SDP_CHARGER                       Standard downstream port. Refers to a downstream port  on USB2.0 compliant host/hub.
- r) q& [9 {* y' d$ H; e+ |& ~USB_DCP_CHARGER                      Dedicated charger port (AC charger/ Wall charger).
5 |) D7 K! Z) t, wUSB_CDP_CHARGER                      Charging downstream port. Enumeration can happen and IDEV_CHG_MAX can be drawn irrespective of USB state., G% {& Z3 k! u
USB_ACA_A_CHARGER                                
, h2 Q" _: H4 A* x& }" T% I$ h; rB-device is connected on accessory port with charger connected on charging port. This configuration allows charging in host mode.
7 U9 |! ?; q% W6 \USB_ACA_B_CHARGER                 No device (or A-device without VBUS) is connected on accessory port with charger connected on charging port.
  F/ z1 u% G6 yUSB_ACA_C_CHARGER                 A-device (with VBUS) is connected on accessory port with charger connected on charging port.. L+ x8 [; c" R" f
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
* v5 l) `9 y3 z5 P( F! @' B2 p+ @* Kports.% c. Q- a0 f$ z8 x# j
USB_PROPRIETARY_CHARGER   A proprietary charger pull DP and DM to specific voltages between 2.0-3.3v for identification.1 ]  W$ B7 A7 f  H, a' Y
! \6 J* U0 |. ?3 _9 I" B
POWER_SUPPLY_TYPE_USB,                     
4 z6 u2 }6 J5 {  ^1 e% S! H/* Standard Downstream Port */5 V- I9 @# b) ?) P
POWER_SUPPLY_TYPE_USB_DCP,           /* Dedicated Charging Port */
" X6 i- G5 p9 X3 ~POWER_SUPPLY_TYPE_USB_CDP,           /* Charging Downstream Port */
' R9 k: ?0 m7 r' uPOWER_SUPPLY_TYPE_USB_ACA,           /* Accessory Charger Adapters */; U( B! F  N* Z. e) ^3 g- Y
POWER_SUPPLY_TYPE_BMS,                     6 C, v0 ^% _- e# m
/* Battery Monitor System */
% l. o' u& W# a$ f1 @; C2 c" v) h
: \, ^: T" `2 t$ l( E6 S2. How to classify or identify charger?
2 s- A' c. C6 g, a! O( ]+ R) W
- x) D* a- E) A4 @
USB_SDP_CHARGER7 M) X& J# Y. M( h
POWER_SUPPLY_TYPE_USB
# v8 w) W7 U4 r' g
USB Charger
USB_CDP_CHARGER& b$ ~' [' b' F  U: H
POWER_SUPPLY_TYPE_USB_CDP
) T' ~2 U6 i$ f( h0 U; l
USB_ACA_DOCK_CHARGER" a" g6 V2 r, h+ ], q! }; e
POWER_SUPPLY_TYPE_USB_ACA
USB_ACA_A_CHARGER3 W5 D/ D8 B- @7 ?9 {; x  \, b
USB_ACA_B_CHARGER
% J& E: Y- Z3 l. Z& o" n7 ]
USB_ACA_C_CHARGER6 c$ v7 U( N! H+ m
USB_DCP_CHARGER
0 b/ A  i6 j  i8 K: h+ R+ Y
POWER_SUPPLY_TYPE_USB_DCP
AC Charger
USB_PROPRIETARY_CHARGER
0 l+ L7 _" ?0 u; k$ |

# j. R7 c0 e( L$ \1 K* {As for the DMS, refer to bold font items, so it is USB charger.
- w3 M1 p, u$ K, F1 x( q0 i
7 ]. C3 a) r+ V$ ?6 H3. Analysis about source codes. E' ^! u# Y- e4 q" H2 D
*******************************************************************$ Q1 K- [# D# ~, \4 `2 N
###用户空间的分析如下:
- U  Z. a) t$ A3 ?1. 检查 /sys/class/power_supply/pm8921-dc/online和
" G! g! ~3 A# \/sys/class/power_supply/usb/online 的值,可以知道是何充电器类型
0 q4 r3 V1 d7 {. ^/ _: w                @frameworks/base/services/jni/com_android_server_batteryservice.cpp中有- m6 G  G3 R% @6 |, \+ a, w
                int register_android_server_BatteryService(JNIEnv* env)         
7 f* L& z" G7 r# N                {" i* N; x, l: S) a! ^
                if (strcmp(buf, "Mains") == 0) { ///sys/class/power_supply/pm8921-dc/type == Mains9 o9 l" x' q/ n# o  e; Z
                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);- M( `: X3 T" N. _9 |
                    if (access(path, R_OK) == 0)
! G3 E7 g; n9 M                        gPaths.acOnlinePath = strdup(path);
4 f& R7 o2 l1 I0 v" T                }' {! F- K4 Z/ b! Q
                }- R) m5 L2 _5 o, }8 k: Y, ?  [
   如果/sys/class/power_supply/pm8921-dc/online==1,则插入的充电器是wall& c! E3 t- o  t
charger
. Z) V. B: Z0 J, F& E& _. t
      /sys/class/power_supply/usb/online==1,
  }: n/ X& j3 h3 y则插入的充电器是usb charger
$ L$ Z. B0 w  r7 ]5 o
   调试路径:/sys/kernel/debug/msm_otg$ g3 \% j6 V% s, k# G* [2 }: f  y
2. 分析frameworks/base/services/jni/com_android_server_batteryservice.cpp
, x- g: u: L9 D5 h9 w! [                a.函数register_android_server_BatteryService将为被frameworks/base/services/jni/onload.cpp中的JNI_OnLoad调用,用于关联java和C++之间的变量
9 n( x; r: |( E                b.jclass clazz = env->FindClass("com/android/server/BatteryService"); //根据java的路径找到batteryservice.java对应的jclass    1 A+ T" e+ A9 m4 n5 h: l" [2 @$ C, k& R
                  gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");! P% J9 [" b1 `
                  gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z"); //用于关联batteryservice.java中变量private
& ^6 R0 Z6 P( H/ B/ Y4 L* r4 Vboolean mAcOnline和gFieldIds.mAcOnline* d0 s8 j8 k9 i$ @- y
                c. android_server_BatteryService_update
* @) W, S5 Y( ]  J, x. g8 \                                static JNINativeMethod sMethods[] = {
5 L+ j. q! k* K8 E/ l' J8 a7 U$ S                                     /* name, signature, funcPtr */$ |8 Y# U! d- t6 p  z  ]9 D
                                                {"native_update", "()V", (void*)android_server_BatteryService_update},4 D5 n4 r0 h! Y3 J8 T, e
                                };
4 i4 N1 u' l! z0 u4 l; k5 A4 U2 U                   关联到native_update@frameworks/base/services/java/com/android/server/batteryservice.java' N) j/ A; g) s1 f8 W
3. 分析frameworks/base/services/java/com/android/server/batteryservice.java0 V* Q' c" ]+ `$ M
                a. mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply"); //注册监听该uevent
& e# y1 D  e; I: T8 B' k                b.     private UEventObserver mPowerSupplyObserver = new UEventObserver() {
( u: ]$ F9 \6 K: B/ j                                public void onUEvent(UEventObserver.UEvent event) { //如果就收到来自kernel的uevent,触发该函数  j  ?/ U7 @  ?# Q0 O, J, C
                                    update(); //-->native_update();和processValues();/ T, o8 Z' u. e
                                }" X& \9 _6 v" j& g6 D
                       };
9 Q& _- R' Q2 ~+ t7 \+ O/ Z* r                c. native_update函数会通过JNI调用得到更新的mAcOnline和mUsbOnline值. m, P) O: R* p5 `
                d. processValues会根据mAcOnline和mUsbOnline值对mPlugType赋值
) _# M- j% P7 x8 I$ B5 C                                if (mAcOnline) {: G2 Y1 }7 f- f5 i0 n/ @
                                    mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
! G) _7 k# F: d4 @; p                                } else if (mUsbOnline) {
8 T. Z/ P9 W9 S  {                                    mPlugType = BatteryManager.BATTERY_PLUGGED_USB;1 \& ]* C$ A# e3 `3 k% t! K
                                } else {
; L* l3 b/ `0 S% B# V                                    mPlugType = BATTERY_PLUGGED_NONE;0 y5 y2 H& Q: D8 b6 K- T. w7 R! N' v
                                }. l  W& O9 i: W
                e. sendIntent函数会准备Intent并且broadcast这个Intent
8 B) y9 z0 S; s8 M8 j, N                                Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); //public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";@batteryservice.java
9 w9 @) x0 m1 h$ C/ o                                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3 ?, Q' x% J: E) F% _8 J1 \9 b                                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);( t, w% `4 ^4 r" l
# _6 ?' z1 a) G& O, W3 x
                        intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
: B! |/ {  O8 I3 _% F/ ?; x9 a% e                                ActivityManagerNative.broadcastStickyIntent(intent, null);
0 x6 g0 g9 R! X% K4. 分析vendor/sEMC/packages/apps/debugmenu/src/com/sonyericsson/debugmenu/battery.java1 @6 _# d7 }/ v# s) _" F8 i$ @
                a. 接收intent. M* t* _+ v  g& S' B" ]
                    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
# Z2 P% A" u+ G" B6 ^; O                                @Override
! _) ^+ m$ b3 J; O; R                                public void onReceive(Context arg0, Intent intent) {
1 }2 s# Y. y# G6 O                                    if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {* L; h3 a9 F( v9 x- g. l4 d
                                        mPowerInformation.parseIntent(intent);3 X4 r! H9 ]8 l( F& P9 b
                                        updateViews();
! R  }# u0 G$ Y: `7 P, j- r                                    }% C8 e3 h5 q! S
                                }4 M6 ^+ a, Z; y- w, E/ f
                    };
0 n5 v# n( `% W* z                    public void registerBroadcastReceivers() {: s) A; x$ M' ^4 T, N  k0 }. O
                                IntentFilter mIntentFilter;
8 q) ^8 I5 E8 U& g4 ]                                mIntentFilter = new IntentFilter();& H3 U; Q9 y$ L0 M8 X% q( N9 ^
                                mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //只接收Intent.ACTION_BATTERY_CHANGED的intent
7 r+ F9 K/ J8 J                                // Register battery receiver.1 y9 ^( R! f: ~8 W( q
                                registerReceiver(mBatteryInfoReceiver, mIntentFilter);' c& C- K* g' ~) w) L, ~
                    }         
8 W* x) c3 b* \: i. X- g                b. parseIntent 得到最新的"plugged"值赋给mPlugged
) Q/ A! M8 u% X* v4 I                c. updateViews 更新charger类型显示
! h2 s4 b& ^- N) f  e; B  U###内核空间( |, u( j! \$ j( G4 h3 w6 r
1. 插入充电器触发的过程@kernel/drivers/usb/otg/msm_otg.c. ?. M7 W' C* @
                a. CONFIG_PM_RUNTIME 定义 @kernel/arch/ARM/configs/viskan_huashan_defconfig
4 `8 t% g2 J: l/ h$ E                b.msm_otg_runtime_resume-->msm_otg_resume-->??-->msm_otg_sm_work
# f5 K7 N& }0 `/ E                c.msm_otg_sm_work,先进入OTG_STATE_UNDEFINED case,然后进入OTG_STATE_B_IDLE
* \2 t! j3 J. N7 L; W: k  D! T" R9 |case-->motg->chg_state=USB_CHG_STATE_UNDEFINED-->启动msm_chg_detect_work" B4 g+ P) W/ |4 N
                d.msm_chg_detect_work 该函数主要完成USB charger类型的识别/ T4 e: `+ g( t" v- K1 {. e  g3 T
                                USB_CHG_STATE_UNDEFINED //其中psy = power_supply_get_by_name("usb");很关键,表明只是获取usb的power_supply,实际上就是chip->usb_psy@pm8921-charger.c. D0 K& l2 q  t9 q) b
                                USB_CHG_STATE_WAIT_FOR_DCD         //Waiting for Data pins contact.
5 [* w" n& M4 X) X                                然后多次(MSM_CHG_DCD_MAX_RETRIES=6)检测USB状态,启动queue_delayed_work(motg->wq,
! n+ s1 k+ m3 B  A&motg->chg_work, delay); //motg->chg_work=msm_chg_detect_work( l6 a4 ^% \- n1 G) g& ^# U
                                USB_CHG_STATE_DETECTED //最后USB charge类型检测完毕( Y0 r3 d) {- o* t' c9 v( |
                e. 启动queue_work(motg->wq, &motg->sm_work); //motg->sm_work=msm_otg_sm_work
  i1 h4 G& i. k' J0 O; u                f. 由于motg->chg_state==USB_CHG_STATE_DETECTED,. S3 {  T) B( l( T! C
                                motg->chg_type==USB_DCP_CHARGER -->msm_otg_notify_charger(motg,IDEV_CHG_MAX);//IDEV_CHG_MAX=15007 u4 {1 ^/ M& ^. u5 z1 Z# `  |  M4 @
2. 发送uevent到用户层
( {  y9 ^" W% W& t                a. msm_otg_notify_charger@kernel/drivers/usb/otg/msm_otg.c
& G( l: C  a: G# c0 }- D7 n                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; L( S5 ]5 L( Q* H2 g
                c. -->power_supply_set_supply_type@power_supply_core.c // set type of the power supply8 }3 m  x8 `- ?0 {4 W/ {4 k# p
                d. -->psy->set_property(psy, POWER_SUPPLY_PROP_TYPE,&ret);' t. v5 ~4 X! k" c2 |5 {
                                那么在用usb_psy.get_property和dc_psy.get_property
1 K7 [0 h+ F: m; ^" \* x(在函数中pm8921_charger_probe)读取property时' }6 D" f; N9 I! z: g* J2 f1 c
                                如果是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" D5 e0 e" s- B0 s
charger
4 H9 }4 w+ U& q2 D. {$ k                                如果是AC type,则在pm_power_get_property_mains读取POWER_SUPPLY_PROP_ONLINE的值,只有POWER_SUPPLY_TYPE_USB_DCP为AC
* E) d) @/ e! r/ d; O" u" \charger.
) C$ m1 h# w" ~' E" v9 S! }, }                e. psy=chip->[url=http://www.16rd.com/mailto:usb_psy@pm8921-charger.c,%E6%89%80%E4%BB%A5%E7%BB%A7%E7%BB%AD%E8%B0%83%E7%94%A8%E7%9A%84%E6%98%AFpm_power_set_property_usb@pm8921-charger.c]usb_psy@pm8921-charger.c,所以继续调用的是[/url]pm_power_set_property_usb@pm8921-charger.c3 L7 H5 r, j; X7 A9 @1 h6 G: y
                f. -->pm8921_set_usb_power_supply_type(val->intval)@pm8921-charger.c
9 d/ T- |1 T/ e4 a$ c$ b3 ?- B                                -->power_supply_changed(&the_chip->usb_psy);
& x# O/ H# |( U+ H6 g                                -->power_supply_changed(&the_chip->dc_psy);
& U( u/ w) y- z5 L0 B0 o( R                g. power_supply_changed@pm8921-charger.c , 就会马上发送uevent给user
! Q8 I7 N; ~6 [( n9 i# I" Jspace,然后user space通过sysfs得到USB
4 r* p: t8 H, A& w6 Vtype变化后的信息,参考用户空间的分析
$ U1 r( r  U% h+ }) D( }) A3 q# \% V9 e7 W2 k  `/ ]
二、硬件分析2 F6 l/ Q  @2 y: c

- N2 t! n3 I; X0 D0 [6 t) A8 W主要是通过特殊设计的电路,检测不同的pin的状态,从而确定是何种类型的Charger. 更details的内容省略。
5 U3 O1 w: x: B5 [1 v% ]3 y
8 E* J& i9 p% K

( t  D( F! X9 B+ b) k+ [; y: p; Y4 C! p
2 k) A" O& X: K: Z, i$ D9 R

该用户从未签到

3#
发表于 2015-10-20 22:16 | 只看该作者
        顶一下,问题有点长。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-5-30 04:57 , Processed in 0.140625 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表