🚀 Linux USB 全栈解析:OTG + Type-C + PD 内核架构(架构师级)
一、为什么需要 Type-C + PD(OTG 的进化)
传统 OTG(Micro-USB):
- 靠 ID 引脚决定角色
- 只能 USB2.0
- 供电能力弱
- 角色切换简单(Host / Device)
👉 局限明显
Type-C + PD 带来的变化:
| 能力 | OTG(旧) | Type-C + PD |
|---|---|---|
| 角色判断 | ID 引脚 | CC 引脚 |
| 电源能力 | 5V | 最多 100W+ |
| 数据角色 | 固定 | 可动态交换 |
| 电源角色 | 固定 | 可交换(PR_SWAP) |
| 协议复杂度 | 低 | 非常高 |
👉 核心变化一句话总结:
Type-C + PD = 数据角色 + 电源角色 + 协议协商的统一控制系统
二、整体架构总览(系统级)
id="full_stack"
┌────────────────────────────┐
│ User Space │
│ (configfs / udev / etc) │
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ USB Gadget / Host │
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ usb_role_switch(核心) │
└────────────┬─────────────┘
↓
┌───────────────┴────────────────┐
↓ ↓
┌──────────────┐ ┌──────────────┐
│ Type-C Core │ │ extcon │
└──────┬───────┘ └──────┬───────┘
↓ ↓
┌──────────────┐ ┌──────────────┐
│ TCPC Driver │ │ ID/VBUS GPIO│
└──────┬───────┘ └──────┬───────┘
↓ ↓
┌────────────────────────────┐
│ USB PHY │
└────────────┬─────────────┘
↓
┌────────────────────────────┐
│ DWC2 / DWC3 Controller │
└────────────────────────────┘
三、Type-C 核心机制(硬件 + 协议)
1. CC 引脚(核心)
Type-C 使用:
- CC1
- CC2
2. 电阻模型
| 角色 | 电阻 |
|---|---|
| Source(供电) | Rp |
| Sink(用电) | Rd |
3. 判断逻辑
text
检测 CC 电平
→ 判断插入方向
→ 判断角色(DFP / UFP)
4. 角色定义
| 名称 | 含义 |
|---|---|
| DFP | Downstream Facing Port(Host) |
| UFP | Upstream Facing Port(Device) |
👉 对应 Linux:
- DFP → USB_ROLE_HOST
- UFP → USB_ROLE_DEVICE
四、Power Delivery(PD)协议深度解析
1. PD 是什么?
👉 一个运行在 CC 线上的协议
2. 作用
- 电压协商(5V → 9V → 20V)
- 电流协商
- 角色交换
3. 三大核心能力
① Power Role(供电角色)
- Source
- Sink
② Data Role(数据角色)
- Host
- Device
③ VCONN(线缆供电)
4. 关键协议
| 协议 | 作用 |
|---|---|
| PR_SWAP | 电源角色交换 |
| DR_SWAP | 数据角色交换 |
| VCONN_SWAP | 线缆供电切换 |
5. 协商流程(简化)
text
Source → 发送 Source_Capabilities
Sink → 选择电压
→ Request
→ Accept
→ PS_RDY
五、Linux Type-C 子系统架构
1. 代码路径
id="typec_path"
drivers/usb/typec/
2. 核心结构
c
struct typec_port {
enum typec_data_role data_role;
enum typec_power_role power_role;
};
3. 注册流程
c
typec_register_port()
4. 角色切换
c
typec_set_data_role()
typec_set_pwr_role()
六、TCPC(Type-C Port Controller)
1. 常见芯片
- FUSB302
- TCPM(软件协议栈)
- RT1711
2. Linux 位置
id="tcpc_path"
drivers/usb/typec/tcpm/
3. 核心模块
👉 TCPM(Type-C Port Manager)
4. 状态机
text
UNATTACHED
→ ATTACHED
→ NEGOTIATING
→ READY
5. 关键函数
c
tcpm_set_state()
tcpm_pd_send_request()
七、Type-C → USB Role 切换链路(核心)
完整链路
text
CC 检测
→ TCPC 中断
→ TCPM 状态机
→ typec_set_data_role()
→ usb_role_switch_set_role()
→ dwc3_set_mode()
👉 这是整个系统最关键的一条链路
八、usb_role_switch 深度机制
1. 作用
👉 统一 OTG / Type-C 的角色控制
2. 关键接口
c
usb_role_switch_set_role()
3. 数据流
text
typec/extcon
→ role_switch
→ controller
九、DWC3 在 Type-C 场景的关键点
1. DRD 模式
c
DWC3_GCTL_PRTCAP_OTG
2. 切换
c
dwc3_set_mode()
3. 注意点
- 必须支持 runtime PM
- PHY 必须同步切换
- cache / DMA 必须正确
十、Gadget / Host 协同
Device 模式
text
UDC → gadget driver → configfs
Host 模式
text
xHCI → 枚举 → driver bind
十一、Type-C + PD + OTG 全链路时序
插入一个支持 PD 的设备:
text
1. CC 检测
2. TCPC 触发中断
3. TCPM 状态机运行
4. PD 协商电压
5. 确定 power role
6. 确定 data role
7. typec_set_data_role()
8. usb_role_switch
9. dwc3_set_mode
10. Host 或 Gadget 启动
十二、设备树(Type-C + PD)
示例
dts
usb@xxx {
dr_mode = "otg";
usb-role-switch;
};
typec_port {
compatible = "usb-c-connector";
power-role = "dual";
data-role = "dual";
};
十三、工程级 Debug(Type-C + PD)
1. 查看 Type-C 状态
bash
ls /sys/class/typec/
2. 查看角色
bash
cat /sys/class/usb_role/*/role
3. 查看 PD
bash
dmesg | grep tcpm
4. 常见问题
❌ 不识别 Type-C
👉 TCPC 驱动问题
❌ 不协商电压
👉 PD 协议问题
❌ 不切换 role
👉 typec → role_switch 断链
❌ 卡死
👉 PHY / 时钟 / 电源域
十四、架构师级总结(核心认知)
1. 三层模型
text
物理层:PHY / CC / VBUS
协议层:Type-C / PD
软件层:Linux 子系统
2. OTG vs Type-C 本质区别
text
OTG:硬件决定角色
Type-C:协议决定角色
3. Linux 核心机制
text
Type-C → role_switch → controller
🔥 最核心一句话(架构级理解)
Type-C + PD 本质是一个"多角色、多协议、多电源协同状态机系统",Linux 通过 typec + tcpm + usb_role_switch 将其统一抽象为 USB 角色切换问题。