RK3588 kernel-6.1:drivers/usb/phy 功能与实现要点
源码基准:rk3588/kernel-6.1/drivers/usb/phy/。与之配套的 struct usb_phy API 定义在 include/linux/usb/phy.h。
1. 目录在内核 USB 栈里的位置
drivers/usb/Makefile:在USB_SUPPORT打开时编译phy/。CONFIG_USB_PHY:drivers/usb/phy/Kconfig中由各个收发器选项select,并select EXTCON,以便充电器/VBUS 等可走 extcon 链路。- 服务对象:主要是 USB 控制器驱动(EHCI/OHCI/MUSB/DWC2/Gadget UDC 等),而不是枚举得到的
usb_device/usb_gadget功能驱动。控制器通过usb_get_phy/devm_usb_get_phy*取得收发器,在init/shutdown/省电/OTG/供电能力 等路径调用钩子。
与 RK3588 的常见误解:Rockchip 片上 USB2/USB3 combo PHY / Inno PHY 等通常在 drivers/phy/rockchip/(Linux Generic PHY 框架:phy_get、phy_power_on),由 dwc3、ehci-platform 等通过 generic_phy 或 drm/时钟门控 衔接。RK3588 默认配置文件不一定启用 drivers/usb/phy 里的具体芯片驱动;本目录更多是 TI/OMAP/Freescale/Marvell/Tegra 等传统收发器与 NOP ULPI 的历史集合。
2. 核心框架:phy.c
职责可以概括为三类:注册与查找、事件通知、充电器 / extcon 协作。
2.1 全局链表与查找
- 维护
phy_list(带phy_lock),每个usb_phy通过head挂在链表上。 usb_add_phy/usb_add_phy_dev/usb_remove_phy:收发器驱动在 probe 时把自己暴露给子系统。usb_get_phy(type):按enum usb_phy_type(USB_PHY_TYPE_USB2/USB_PHY_TYPE_USB3)查找第一个匹配的 PHY。devm_usb_get_phy_by_phandle/devm_usb_get_phy_by_node:配合 DTphys/usb-phy绑定(OF 节点与已注册usb_phy->dev->of_node匹配)。__of_usb_find_phy(内部):OF 节点不可用时返回-EPROBE_DEFER,便于控制器defer probe。
2.2 usb_phy 结构与钩子(摘自 usb/phy.h)
控制器与子系统真正使用的是 struct usb_phy 中的:
- 生命周期:
init、shutdown、set_suspend、set_wakeup - 供电:
set_vbus、set_power(常与共存的usb_phy_set_charger_current结合) - 链路:
notify_connect、notify_disconnect - ULPI:
io_ops->read/write、io_priv(控制器侧 viewport,收发器寄存器经usb_phy_io_read/write访问)
另有 struct usb_otg *otg:部分驱动通过 usb_otg 绑定 usb_gadget 与 usb_hcd,在 OTG 状态机里切换角色。
2.3 原子 notifier:usb_phy_events
atomic_notifier_head notifier:收发器或 NOP 驱动在 VBUS、ID、charger、枚举完成 等时机调用 usb_phy_set_event 或直接向 notifier 广播;控制器/Gadget 栈注册 usb_register_notifier 即可异步获知线缆/角色变化。
2.4 充电器类型与 extcon:usb_add_extcon
若 PHY 设备树带 extcon phandle:
- 若实现了
vbus_nb:按EXTCON_USB监听 VBUS。 - 否则注册
type_nb,针对EXTCON_CHG_USB_{SDP,CDP,DCP,ACA},在回调里__usb_phy_get_charger_type,更新chg_type/chg_state并schedule_work(chg_work)。 - 可选
id_nb与EXTCON_USB_HOST(第二 extconid_edev或复用同一edev)。
usb_phy_notify_charger_work:根据 USB_CHARGER_PRESENT/ABSENT 计算 usb_phy_get_charger_current,再 atomic_notifier_call_chain,并 kobject_uevent 向 userspace 上报 USB_CHARGER_STATE/USB_CHARGER_TYPE(配合 usb_phy_uevent)。
与上层:枚举后 SDP 电流协商可走 usb_phy_set_power → 内部 usb_phy_set_charger_current。
3. 设备树辅助:of.c
of_usb_get_phy_mode(np):读phy_type字符串(utmi/utmi_wide/ulpi/serial/hsic),返回enum usb_phy_interface。- 供控制器驱动确定 MAC 与 PHY 之间的 数字接口形态(与
drivers/usb/phy里具体收发器驱动 是正交的:一边是控制器配置,一边是外置 PHY)。
4. 典型收发器驱动(按 Makefile)
| 选项 | 文件 | 作用概要 |
|---|---|---|
NOP_USB_XCEIV |
phy-generic.c |
「空」收发器:片内 PHY 或无需寄存器编程的外置 PHY;可提供 时钟、复位 GPIO、VBUS GPIO、供电 regulator、OTG gadget 绑定 与 VBUS IRQ |
USB_ULPI |
phy-ulpi.c |
通过 usb_phy_io_ops 写 ULPI 寄存器(OTG/Func/IFC 等),识别 ISP1504、USB331x、TUSB1210 等 ID |
USB_ULPI_VIEWPORT |
phy-ulpi-viewport.c |
带 viewport 的控制器(如 Chipidea)访问 ULPI 总线的通用读写 |
USB_GPIO_VBUS |
phy-gpio-vbus-usb.c |
仅用 GPIO 感知 peripheral-only VBUS |
USB_MXS_PHY |
phy-mxs-usb.c |
Freescale MXS |
USB_TEGRA_PHY |
phy-tegra-usb.c |
Tegra USB PHY |
AM335X_PHY_USB |
phy-am335x.c + phy-am335x-control.c |
AM335x |
USB_ISP1301 / ISP1301_OMAP |
phy-isp1301.c / phy-isp1301-omap.c |
I²C ULPI 前端 |
FSL_USB2_OTG |
phy-fsl-usb.c |
Freescale OTG FSM |
USB_MV_OTG |
phy-mv-usb.c |
Marvell OTG |
KEYSTONE_USB_PHY |
phy-keystone.c |
Keystone(依赖 NOP) |
| 其它 | phy-twl6030-usb.c、phy-omap-otg.c、phy-keystone.c、phy-jz4770.c、phy-ab8500-usb.c、phy-tahvo.c |
各 PMIC/SoC 专用 |
4.1 NOP / Generic(phy-generic.c)——最常见的「胶水」
usb_phy_generic_register:无 DT 时可由别的代码注册简易 platform 设备。nop_set_suspend:可选 gate PHY 时钟。nop_gpio_vbus_thread:GPIO VBUS 变化时更新usb_otgstate,atomic_notifier_call_chain发USB_EVENT_VBUS,并nop_set_vbus_draw限制从 VBUS 汲取电流。usb_gen_phy_init/usb_gen_phy_shutdown:导出给组合 PHY 驱动复用(使能vcc、clk、复位脉冲)。
5. 与 Generic PHY(drivers/phy) 的关系(概念)
drivers/usb/phy(本目录) |
drivers/phy/*(Generic PHY) |
|
|---|---|---|
| 核心类型 | struct usb_phy |
struct phy |
| 典型 API | usb_phy_init、usb_get_phy |
phy_power_on、phy_set_mode |
| DT | phys、usb-phy phandle |
phy-* 绑定、#phy-cells |
现代 SoC(含 RK3588)常把 SerDes/PIPE/USB2 analog 做成 phy-rockchip-*,由 DWC3 glue 取 struct phy *;这与 usb_phy 是 两套并行框架,仅在个别驱动里会做桥接或共存。
6. 小结
phy.c:USB 收发器类驱动 的注册中心,向控制器提供 查找、refcount(put/get)、notifier、charger/extcon、uevent。of.c:从 DT 解析phy_type,辅助控制器配置 UTMI/ULPI 等接口模式。- 各
phy-*.c:把具体芯片或 SoC 段落塞进struct usb_phy的钩子;NOP 覆盖「几乎不编程」的常见情形;ULPI 覆盖外置并行收发器。 - RK3588 读者:若目标是 板级 USB bring-up,请同时查阅
drivers/phy/rockchip/与drivers/usb/dwc3/;drivers/usb/phy更多是内核树里 通用 USB PHY 子系统 与 经典嵌入式平台 的参考实现。
正在加载留言…