RK3588 kernel-6.1 drivers/usb/roles 代码功能与实现原理

RK3588 kernel-6.1 drivers/usb/roles 代码功能与实现原理

1. 目录与产物

路径:rk3588/kernel-6.1/drivers/usb/roles/

文件 Makefile 目标 作用
class.c roles.oCONFIG_USB_ROLE_SWITCH,模块名 roles.ko USB Role Switch 框架:注册 usb_role classusb_role_switch_registersysfslookup API
intel-xhci-usb-role-switch.c CONFIG_USB_ROLES_INTEL_XHCI(依赖 ACPI + X86 Intel Atom 等平台:MMIO DUAL_ROLE_CFG* 切换 xHCI ↔ dwc3 gadget

公开 API 声明:include/linux/usb/role.h


2. 要解决什么问题(Kconfig 语义)

同一 Type‑C / OTG 物理口可能:

  • 内部是一个 DRD 控制器(如 DWC3):控制器驱动内部切换 Host/Device;仍可通过 usb_role_switch 统一 对外接口 / sysfs / DT connection
  • Host 与 Device 是两颗独立控制器,中间经 MUX 连到连接器:需要 软件选定 数据通路接到哪一侧。

Role Switch 抽象的就是:把「当前口是 Host 还是 Device」变成可查询、可设置的内核对象,供 Type‑C(TCPM/extcon)、PMIC、电源策略USB 控制器 probe 协作。


3. 核心对象:struct usb_role_switchclass.c

内部字段要点:

  • enum usb_role roleUSB_ROLE_NONE / HOST / DEVICE
  • set(sw, role):必选,由 注册方(SoC glue、MUX 驱动等)实现 写硬件/ACPI
  • get(sw):可选;缺省时 usb_role_switch_get_role 返回 缓存的 sw->role(上次 set 成功值
  • mutex lock串行化 set/get
  • registeredunregisterset_role 返回 -EOPNOTSUPP
  • allow_userspace_control:为真时 sysfs role 可写(见下文)

可选 usb2_port / usb3_port / udc:文档说明用于指向 主机口设备UDC,便于后续 symlink(代码里仍有 TODO)。


4. 注册与 sysfs

usb_role_switch_register(parent, desc)

  • 创建子设备,名 {name}-role-switch(默认 {parent_name}-role-switch
  • classusb_role
  • device_typeusb_role_switch

属性 role

  • none / host / deviceusb_role_string
  • :仅在 allow_userspace_control 时可见(is_visible);写入经 sysfs_match_string 解析后调用 usb_role_switch_set_role
  • set_role 成功kobject_uevent(KOBJ_CHANGE),便于 udev

usb_role_switch_uevent:导出环境变量 USB_ROLE_SWITCH= 设备名。


5. 查找与模块引用

  • usb_role_switch_get(dev)
    • dev 的父 fwnodeusb-role-switch 属性 → 按 父节点switch
    • 否则 device_connection_find_match(dev, "usb-role-switch", …)
  • fwnode_usb_role_switch_get:DT graph / connection 等价路径
  • usb_role_switch_find_by_fwnode:按 switch 自身 fwnode 查找

找到后对 sw->module try_module_getputmodule_put

原理DWC2 dual-roleDWC3 drd.cType‑C 等通过 DT usb-role-switch 连接拿到 struct usb_role_switch *,在 线缆插入、TCPM 决策 时调用 usb_role_switch_set_role,与 dwc3_set_modephy_set_mode 等衔接。


6. Intel 参考驱动:intel-xhci-usb-role-switch.c

平台:Cherry Trail / Broxton 等 ACPI platform_deviceMMIO 寄存器 DUAL_ROLE_CFG0/1

  • intel_xhci_usb_set_role:按角色写 SW_IDPINSW_VBUS_VALIDDRD_CONFIG_*SW_SWITCH_EN;与 ACPI global lock 互斥(避免与 AML 竞争);轮询 CFG1 HOST_MODE 确认切换完成
  • intel_xhci_usb_get_role:读 CFG0 推导 Host/Device/NONE

通过 software_node 提供 fwnode,便于 connection 与其它驱动匹配;allow_userspace_control = true

RK3588:一般 不走该 Intel 驱动;角色切换多在 dwc3 + typec/extcon 路径完成,但若 DTS 引用 usb-role-switch,仍会用到 roles.ko 框架 API


7. 与其它目录的关系(概念)

1
2
3
4
5
6
7
8
9
10
TCPM / extcon / PMIC(策略)
│ usb_role_switch_set_role()

drivers/usb/roles/class.c

├─► SoC-specific set() ──► MUX / DRD 寄存器 / ACPI

└─► sysfs(可选用户态)

DWC3 gadget host dr_mode ► 常与 role switch 同步

8. 延伸阅读(本仓库)

文档
drivers-usb-typec分析.md
drivers-usb-dwc3详细分析.md

内核文档可参考:Documentation/driver-api/usb/usb-role-switch.rst(若树中存在)。


基于 rk3588/kernel-6.1/drivers/usb/rolesinclude/linux/usb/role.h 归纳。

文章互动

阅读 --

留言

0 条留言

正在加载留言…