找回密码
 注册
关于网站域名变更的通知
查看: 2697|回复: 2
打印 上一主题 下一主题

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
USB port 如何识别不同的Charger类型& S5 y6 F9 U' r+ V$ }
2013年10月03日 ⁄ 综合 ⁄ 共 8924字        ⁄ 字号 [url=]小[/url] [url=]中[/url] [url=]大[/url] ⁄ 评论关闭
( {+ Q8 J& b4 u
6 w1 C# W: Q. Q5 H, s# E8 u4 h一,软件分析1.  USB charger types & Power supply types
0 I* k0 D- Y* cUSB_INVALID_CHARGER              Invalid USB charger.
* B$ Y' L3 a6 w" QUSB_SDP_CHARGER                       Standard downstream port. Refers to a downstream port  on USB2.0 compliant host/hub.4 H9 `. m- C' s+ z6 j( c# o) V1 k
USB_DCP_CHARGER                      Dedicated charger port (AC charger/ Wall charger).0 S1 ]8 j: C/ _8 S* {; n9 g
USB_CDP_CHARGER                      Charging downstream port. Enumeration can happen and IDEV_CHG_MAX can be drawn irrespective of USB state.0 Y# I+ p6 a7 s  F0 y
USB_ACA_A_CHARGER                                
3 g% x- G+ {) }' NB-device is connected on accessory port with charger connected on charging port. This configuration allows charging in host mode.4 `% M; {% [- k7 t0 f& G
USB_ACA_B_CHARGER                 No device (or A-device without VBUS) is connected on accessory port with charger connected on charging port.
( h" g/ L) w" N( T  Y5 \1 P; x4 yUSB_ACA_C_CHARGER                 A-device (with VBUS) is connected on accessory port with charger connected on charging port.9 q6 G9 x7 R, d# @
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
" n, n. _- W/ Uports.- D" B; P& i' m( y) `0 {
USB_PROPRIETARY_CHARGER   A proprietary charger pull DP and DM to specific voltages between 2.0-3.3v for identification.+ ^9 H; i0 S& M- y
8 o& b8 W4 F2 q; n7 o& G$ C
POWER_SUPPLY_TYPE_USB,                      2 U: x7 E4 X- [, X" P
/* Standard Downstream Port */7 W/ B( R. _) N( @% T" Y, U( `2 O
POWER_SUPPLY_TYPE_USB_DCP,           /* Dedicated Charging Port */
3 z$ B2 g  E" r8 e7 WPOWER_SUPPLY_TYPE_USB_CDP,           /* Charging Downstream Port */
8 H! J% M# b; E8 u1 P5 dPOWER_SUPPLY_TYPE_USB_ACA,           /* Accessory Charger Adapters */
/ x9 K* r3 n6 pPOWER_SUPPLY_TYPE_BMS,                     ! y; A% }5 n- a5 {: e2 E
/* Battery Monitor System */6 @% a! B: _+ J9 T3 m& H) @; e5 M5 d* c

+ P. O! j) {+ c; u7 u  }4 W2. How to classify or identify charger?% K& J) [& x9 I: |. ?
0 d' h3 ?$ u! E, b- y' d; S
USB_SDP_CHARGER+ ~" `: n9 X% s; w
POWER_SUPPLY_TYPE_USB  C) G+ l; _' _+ C0 ?* a( B/ C
USB Charger
USB_CDP_CHARGER5 g( Z( Z' V2 Z
POWER_SUPPLY_TYPE_USB_CDP
; X8 [  @) q# G5 H
USB_ACA_DOCK_CHARGER" e. L) b- d- b( w7 X
POWER_SUPPLY_TYPE_USB_ACA
USB_ACA_A_CHARGER6 H) C0 n+ `) D! S9 x  }
USB_ACA_B_CHARGER# U( X$ f: {0 s/ F
USB_ACA_C_CHARGER
. T; P* M, g5 }" j' x4 n
USB_DCP_CHARGER: x  ~# A1 b2 n* Z
POWER_SUPPLY_TYPE_USB_DCP
AC Charger
USB_PROPRIETARY_CHARGER
) M4 y9 a/ L0 t' n/ Q

, a( O. {9 V0 gAs for the DMS, refer to bold font items, so it is USB charger.
) Y+ q2 |8 m" {$ g4 E# [& c' N & N, C/ _+ ?3 ~- v0 N. ^
3. Analysis about source codes
. b! B/ a. S& Y' Q! E2 q- c$ ]*******************************************************************
- ~- ~$ m! T! Q, R###用户空间的分析如下:
% q( z* ?% B2 \# h% a( y( d1 X1. 检查 /sys/class/power_supply/pm8921-dc/online和
1 i( r$ J  h+ Y# L( ~/sys/class/power_supply/usb/online 的值,可以知道是何充电器类型) m5 T, A7 r2 z( }4 w+ |2 U7 @
                @frameworks/base/services/jni/com_android_server_batteryservice.cpp中有
" c# o' G( n2 ]6 k3 p                int register_android_server_BatteryService(JNIEnv* env)         
, g% I# M( Q! k  i                {
$ C: c4 x8 a0 N- H( a7 O                if (strcmp(buf, "Mains") == 0) { ///sys/class/power_supply/pm8921-dc/type == Mains
' D5 _* {/ V1 j* z7 u4 B                    snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);& q( d8 i/ q4 `. d& R% y' V
                    if (access(path, R_OK) == 0)- }( x1 |9 @/ u" N
                        gPaths.acOnlinePath = strdup(path);
% U* h$ z6 G4 v. @                }/ R; E$ C0 P  f, Z. b: M- L: S
                }
) M8 {/ s5 R) `   如果/sys/class/power_supply/pm8921-dc/online==1,则插入的充电器是wall
  H( k0 V/ N2 o. tcharger

$ N% L; ^; f0 m4 X& P: \( |      /sys/class/power_supply/usb/online==1, 6 |5 P# K; U2 u' [% U: U! G/ L
则插入的充电器是usb charger
% I8 e  s5 s* I! A$ j7 w8 B9 @, @! D. h
   调试路径:/sys/kernel/debug/msm_otg3 ]0 R$ D+ b$ t% @
2. 分析frameworks/base/services/jni/com_android_server_batteryservice.cpp3 U. v: s2 n! A: m/ C
                a.函数register_android_server_BatteryService将为被frameworks/base/services/jni/onload.cpp中的JNI_OnLoad调用,用于关联java和C++之间的变量! u) s% S, N6 }
                b.jclass clazz = env->FindClass("com/android/server/BatteryService"); //根据java的路径找到batteryservice.java对应的jclass   
! ^4 b0 q7 v% O! k2 p                  gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
# w8 c8 t. R9 Z( e                  gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z"); //用于关联batteryservice.java中变量private8 Y3 B% }0 Z, j2 M
boolean mAcOnline和gFieldIds.mAcOnline
4 ~+ u. p9 g+ o) i# A! u                c. android_server_BatteryService_update* z7 a/ m2 l$ W2 Z
                                static JNINativeMethod sMethods[] = {
6 n& B# _* q' U* {8 n. l, ]                                     /* name, signature, funcPtr */
/ P) f& q0 I# ^5 U( I" M  j7 G                                                {"native_update", "()V", (void*)android_server_BatteryService_update},- A1 K8 [9 u6 T
                                };8 Z. L' ~- M$ {7 n0 |; J
                   关联到native_update@frameworks/base/services/java/com/android/server/batteryservice.java
1 p2 N7 @  q" n4 u6 N6 z$ {3. 分析frameworks/base/services/java/com/android/server/batteryservice.java
. l- W' M+ {' {8 R1 C                a. mPowerSupplyObserver.startObserving("SUBSYSTEM=power_supply"); //注册监听该uevent1 n) \6 }1 G2 \1 i9 R7 L  @' m8 e
                b.     private UEventObserver mPowerSupplyObserver = new UEventObserver() {
# ^+ U$ K8 X( E7 z                                public void onUEvent(UEventObserver.UEvent event) { //如果就收到来自kernel的uevent,触发该函数+ Q0 L" E0 G! c. M
                                    update(); //-->native_update();和processValues();8 ~( Z3 ?8 t$ ?9 |. |$ g
                                }
  W# p* g+ u4 O) a8 R: f/ ~                       };
6 W  V8 O; w: D; X" M! ]" F                c. native_update函数会通过JNI调用得到更新的mAcOnline和mUsbOnline值
& O" g( @* D: {5 z" F                d. processValues会根据mAcOnline和mUsbOnline值对mPlugType赋值
' ]& q/ \0 Y3 f% a                                if (mAcOnline) {
/ x5 A! @- T& l' v4 F                                    mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
# t1 J* G  c; W. K- I6 o                                } else if (mUsbOnline) {
3 p5 I2 M) {4 D  y: F                                    mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
3 ]; O' L- \# L  E, u1 l                                } else {
6 |4 d: c7 d* i3 S8 S% a& a; o                                    mPlugType = BATTERY_PLUGGED_NONE;+ v" _# ^- ~6 k
                                }
- c/ B+ c2 P4 f% D- [1 Y* B% A- ^& _7 a                e. sendIntent函数会准备Intent并且broadcast这个Intent
/ C9 x% A& z1 v! x- O                                Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); //public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";@batteryservice.java
6 N* H  S% E1 A+ A; q! L) R! _9 J                                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1 Z* w& p" ?& s( ]6 q1 d                                        | Intent.FLAG_RECEIVER_REPLACE_PENDING);. L- U# T0 K6 t: Z( o  D3 w
9 u% T! e. D1 H0 N/ ^, o
                        intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);. G6 G" ^+ }0 O' I/ u6 c/ e: a
                                ActivityManagerNative.broadcastStickyIntent(intent, null);
5 o, T$ \. T. Y; u( t  f- C! q4. 分析vendor/sEMC/packages/apps/debugmenu/src/com/sonyericsson/debugmenu/battery.java: P9 T4 i7 X9 B7 d$ X+ I: z$ a: a8 V
                a. 接收intent
3 `$ o9 S+ {! C- ]3 G) E" c" S                    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {3 s5 I* M& N# j7 r* {$ F
                                @Override7 q" e$ j7 e& F) b0 K! [# ~6 S4 g
                                public void onReceive(Context arg0, Intent intent) {+ m" m& Z/ h) b: R! j" u
                                    if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
# h7 A8 ]* t5 e+ _$ L- t" H3 l4 I                                        mPowerInformation.parseIntent(intent);
. D. l9 E+ c2 F, K3 |  Q( k                                        updateViews();
7 }2 z# t' p$ v0 k                                    }/ v& ^, |& P* L8 y
                                }3 H* m( c- b7 g* m) |! R$ c: s
                    };8 I- e) g+ L. u2 |' F
                    public void registerBroadcastReceivers() {
! }6 V- V* w$ ^* @                                IntentFilter mIntentFilter;" X: Z" w! X( o8 S
                                mIntentFilter = new IntentFilter();
8 }% c* _9 H+ k8 L* g% d                                mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //只接收Intent.ACTION_BATTERY_CHANGED的intent+ ^6 x, Y0 {$ z! v8 B8 X
                                // Register battery receiver.
7 ^2 c" P2 D+ P                                registerReceiver(mBatteryInfoReceiver, mIntentFilter);2 x. z) `9 J/ X) z" M3 ~/ ~
                    }         
( U# v5 C8 l1 O# G9 U                b. parseIntent 得到最新的"plugged"值赋给mPlugged0 E# }5 \7 S( t+ o8 t
                c. updateViews 更新charger类型显示
3 F5 W! w. ?) A###内核空间
) x5 j+ G5 o+ Z+ j* v* k9 j* R1. 插入充电器触发的过程@kernel/drivers/usb/otg/msm_otg.c
8 v( q; W' \2 [                a. CONFIG_PM_RUNTIME 定义 @kernel/arch/ARM/configs/viskan_huashan_defconfig5 n' r& v. z# n1 X+ c
                b.msm_otg_runtime_resume-->msm_otg_resume-->??-->msm_otg_sm_work
* k, U7 y6 |0 |( u                c.msm_otg_sm_work,先进入OTG_STATE_UNDEFINED case,然后进入OTG_STATE_B_IDLE: s+ t+ u! G0 C4 X& C7 W# ?; A
case-->motg->chg_state=USB_CHG_STATE_UNDEFINED-->启动msm_chg_detect_work
3 t/ B6 r" x+ @/ j8 h, _                d.msm_chg_detect_work 该函数主要完成USB charger类型的识别
$ s8 M0 A( O& [' s' D6 r                                USB_CHG_STATE_UNDEFINED //其中psy = power_supply_get_by_name("usb");很关键,表明只是获取usb的power_supply,实际上就是chip->usb_psy@pm8921-charger.c
) q7 ]" q% @5 Q                                USB_CHG_STATE_WAIT_FOR_DCD         //Waiting for Data pins contact.
% E- `. A+ H1 o: i6 ?                                然后多次(MSM_CHG_DCD_MAX_RETRIES=6)检测USB状态,启动queue_delayed_work(motg->wq,
; b8 D# k, P8 [& f* |&motg->chg_work, delay); //motg->chg_work=msm_chg_detect_work
' g6 w; V' I( _' l5 p4 F% |                                USB_CHG_STATE_DETECTED //最后USB charge类型检测完毕9 q, E: R$ t! e% [& @. d
                e. 启动queue_work(motg->wq, &motg->sm_work); //motg->sm_work=msm_otg_sm_work; r" p0 o' R5 ?% b
                f. 由于motg->chg_state==USB_CHG_STATE_DETECTED,( R( \  f$ i3 w4 E8 U4 L
                                motg->chg_type==USB_DCP_CHARGER -->msm_otg_notify_charger(motg,IDEV_CHG_MAX);//IDEV_CHG_MAX=1500
+ N9 d- j; ]' J6 E  h  N2. 发送uevent到用户层
5 s6 Y* U& x  u6 l) X                a. msm_otg_notify_charger@kernel/drivers/usb/otg/msm_otg.c! J0 Z: `6 }3 A2 @0 O# z6 X( N! H; S
                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
7 X2 F  ^( c  Y( h2 r; Y                c. -->power_supply_set_supply_type@power_supply_core.c // set type of the power supply
$ I: X& U9 Q- [                d. -->psy->set_property(psy, POWER_SUPPLY_PROP_TYPE,&ret);$ o; X$ W" o+ }# ~
                                那么在用usb_psy.get_property和dc_psy.get_property
! ?0 P) {' ]1 J1 s/ D% F3 g(在函数中pm8921_charger_probe)读取property时4 V+ [8 {1 y  E# }- H; f: Q
                                如果是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
' K6 s5 N3 y) D% V4 z, lcharger! U2 t5 Q9 v1 U/ ^3 i
                                如果是AC type,则在pm_power_get_property_mains读取POWER_SUPPLY_PROP_ONLINE的值,只有POWER_SUPPLY_TYPE_USB_DCP为AC9 F! Q5 `% c6 _3 p
charger.5 z) b: J" C  I
                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.c/ Z8 b+ i5 ]+ p  D' L! }
                f. -->pm8921_set_usb_power_supply_type(val->intval)@pm8921-charger.c
: {3 z( g" Q( V/ \* n: i# h                                -->power_supply_changed(&the_chip->usb_psy);1 L: m% `9 ]1 y2 G, v
                                -->power_supply_changed(&the_chip->dc_psy);
6 k# S! ~. f* A                g. power_supply_changed@pm8921-charger.c , 就会马上发送uevent给user
& a! f/ E( q0 }+ r5 W- t! }space,然后user space通过sysfs得到USB
7 X( p' O  D: ctype变化后的信息,参考用户空间的分析
3 C0 t. ~- J) }. D% T5 a% W' y
* r: Q8 o0 @$ V二、硬件分析  t# W& p- h- f% |

, W& f" j( ~: x- D  c, C" |主要是通过特殊设计的电路,检测不同的pin的状态,从而确定是何种类型的Charger. 更details的内容省略。
& r; b3 }  U- B& Q2 |# O& D: v/ j3 z* A' ?
. `9 _; m: N+ E& k, X

  w, o6 g$ U! t5 i& k- M- }

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-10-2 10:12 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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