是USB-On-The-Go 的縮寫,
為USB 規格中的一個延伸,
擁有USB OTG功能的系統,(例如: 手機)
可以根據ID pin狀態的不同,
自行切換為host端或者client端,
已達到不同的目的使用.
例如:
a. 以手機接電腦,
手機會切換為client端,
這時可以把手機當隨身碟使用
b. 以手機接隨身碟,
手機會轉為host端,
讓手機能夠不透過電腦直接存取隨身碟裡面資料,
Google Git 上面可找到otg.c
可以讓我們
從驅動程式原始碼認識USB OTG
| /** | |
| * ci_otg_work - perform otg (vbus/id) event handle | |
| * @work: work struct | |
| */ | |
| static void ci_otg_work(struct work_struct *work) | |
| { | |
| struct ci_hdrc *ci = container_of(work, struct ci_hdrc, work); | |
| if (ci_otg_is_fsm_mode(ci) && !ci_otg_fsm_work(ci)) { | |
| enable_irq(ci->irq); | |
| return; | |
| } | |
| if (ci->id_event) { | |
| ci->id_event = false; | |
| ci_handle_id_switch(ci); | |
| } else if (ci->b_sess_valid_event) { | |
| ci->b_sess_valid_event = false; | |
| ci_handle_vbus_change(ci); | |
| } else | |
| dev_err(ci->dev, "unexpected event occurs at %s\n", __func__); | |
| enable_irq(ci->irq); | |
| } | |
系統偵測到事件觸發,
執行ci_handle_id_switch(ci);
| #define CI_VBUS_STABLE_TIMEOUT_MS 5000 | |
| static void ci_handle_id_switch(struct ci_hdrc *ci) | |
| { | |
| enum ci_role role = ci_otg_role(ci); | |
| if (role != ci->role) { | |
| dev_dbg(ci->dev, "switching from %s to %s\n", | |
| ci_role(ci)->name, ci->roles[role]->name); | |
| ci_role_stop(ci); | |
| /* wait vbus lower than OTGSC_BSV */ | |
| hw_wait_reg(ci, OP_OTGSC, OTGSC_BSV, 0, | |
| CI_VBUS_STABLE_TIMEOUT_MS); | |
| ci_role_start(ci, role); | |
| } | |
| } |
根據ID pin 腳位的不同
會選擇USB功能為:
CI_ROLE_GADGET (client)
CI_ROLE_HOST (host)
| /** | |
| * ci_otg_role - pick role based on ID pin state | |
| * @ci: the controller | |
| */ | |
| enum ci_role ci_otg_role(struct ci_hdrc *ci) | |
| { | |
| enum ci_role role = hw_read_otgsc(ci, OTGSC_ID) | |
| ? CI_ROLE_GADGET | |
| : CI_ROLE_HOST; | |
| return role; | |
| } | |
接著driver 會將此變化傳到應用層,
如果是Android 系統,
USB功能的變化就會傳給Android 做相對應的處理
如果是Android 系統,
USB功能的變化就會傳給Android 做相對應的處理

沒有留言:
張貼留言