恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

RK3588 Type-C PD充电调试实战:DTS配置与内核驱动全解析

  • 首页
  • 资讯中心
  • /
  • RK3588 Type-C PD充电调试实战:DTS配置与内核驱动全解析

相关资讯

paperclip 的多重含义:从回形针到 AI 对齐与效率工具 2026/9/29 19:59:58
Superpowers技能包实战:从安装到自定义开发全解析 2026/9/29 19:59:58
ego-planner参数逐项拆解:从启动配置到实战避障调参 2026/9/29 19:59:58

最新资讯

Linux命令行串口调试:stty与minicom实战指南
IAP升级死机?中断向量表重映射的三大禁忌与排查指南
ROS安装卡顿?三步换清华源实操指南,apt/rosdep全加速
企业级Agent落地实战:30章开源手册拆解与平台选型指南
嵌入式Debug四类排查法:从硬件到应用层的系统化调试指南
FPGA时序约束与收敛实战:从XDC编写到违例根因定位

今日推荐

模型优化器实战:从FP32到INT8的推理加速与精度平衡
LangGraph+FastAPI构建可审计AI编码助手
基于图像预处理与几何特征的人脸脸型发型搭配系统实现

本周热门

从像素到笔画:srt-whiteboard-animation骨架笔迹追踪实现(Zhang-Suen细化+8邻接追踪)
网站建设的英语怎么说?别只背单词,看完这套安全完整流程才敢上线
新手入门看这篇:建设网站加盟避坑指南与SEO实操

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

RK3588 Type-C PD充电调试实战:DTS配置与内核驱动全解析

发布时间:2026/9/29 19:59:58
RK3588 Type-C PD充电调试实战:DTS配置与内核驱动全解析 最近在调一块 RK3588 平台的 Android 12 整机第一块硬骨头就是 Type-C口的 PD 充电。表面上看不就是个充电口嘛接上充电器能用就行。真调起来才发现插上支持 PD 的氮化镓充电器系统能识别有外接电源但电流死活锁在 5V/1.5A换一台机器又能协商到 20V/5A再换一根线直接没有触发 CC 中断整机完全没反应。这中间的差异基本都出在 DTS 配置和内核驱动处理上。这篇文章围绕 [RK3588-Android12] 平台上 USB Type-C PD 充电这条完整链路展开把设备树里 PHY、TCPC/TCPM、charger 这三者的关系讲清楚再带上实际改过的内核驱动代码思路最后把调试过程和踩过的坑整理成速查表。不管你是正在给手头 RK3588 开发板添加 PD 支持还是在定制 ROM 里完善 Type-C 功能这篇都值得收藏对着抄。1. 先搞清楚 RK3588 上 Type-C PD 充电的整体链路在动 DTS 之前必须先理解 RK3588 这颗 SoC 在 Type-C PD 充电里到底扮演什么角色以及外围芯片需要做什么。很多人上来就改 DTS改完发现没效果大概率是因为没搞清“谁在协商 PD 协议”“谁在管 VBUS”“谁在告诉充电芯片要输出多少伏”。1.1 USB Type-C 物理层与 PD 协议栈的分工RK3588 本身集成了多个 USB 控制器和 PHY包括 USB 2.0 PHY用于 OTG/主机检测、BC1.2 检测和 USB 3.0/3.1 combo PHY用于 SuperSpeed 数据传输。但 Type-C 的口子要支持 PD 充电光靠 SoC 内部 PHY 是不够的因为 PD 协议跑在 CCConfiguration Channel线上这是一根独立的单线协议由 TCPCType-C Port Controller芯片负责收发 BMC 编码信号。实际硬件链路上USB Type-C 插座上的 CC1/CC2 引脚会连接到一颗 TCPC 芯片比如 FUSB302、HUSB311、TUSB422 这类TCPC 再通过 I2C 与主控通信。RK3588 主控这边运行的是 TCPMType-C Port Manager软件栈负责策略决策比如要不要进入 PD 协商、请求多大的电压电流、如何切换 Device/Host 模式。简单类比TCPC 是“收发信使”只负责按协议把消息发出去、收回来TCPM 是“决策大脑”决定给充电器发什么请求拿到结果后怎么交给充电芯片。DTS 里要做的事就是把这几个环节的拓扑关系描述清楚TCPC 挂在哪条 I2C 上、中断脚是哪个、PHY 怎么跟 TCPC 对应、充电器和电池节点如何接收协商结果。任何一环没有对齐都会导致 PD 协商失败或充电电流上不去。1.2 DTS 里需要关注的三个关键对象在 RK3588 的 BSP 设备树里围绕 Type-C PD 充电主要有三个对象这三个对象如果没配对整个充电链路就是断的第一个是 USB PHY 节点。RK3588 的 usb2phy 提供 OTG 检测和 BC1.2 检测能力USB3 的 combo PHY 负责高速数据通道这些节点里通常还引用了extcon用来做角色切换和充电检测的通知机制。第二个是 TCPC 控制器节点。它通常挂在某个 I2C 总线下面compatible 对应具体的 TCPC 芯片型号包含 reg 地址、中断 GPIO、pinctrl、以及 vbus-supply 电源属性。TCPM 通过这个节点与 TCPC 建立联系。第三个是充电器/电池节点。RK3588 配套的 PMIC比如 RK806以及外置充电 IC比如南芯 SC8886、英集芯 IP2326 之类会注册为 power_supply 设备。PD 协商出来的电压电流最终要写进这个充电节点否则 PMIC 只会按默认的普通 USB 充电方式走 5V/1.5A 甚至 500mA。DTS 设计思路的核心就是把这三个对象通过extcon、phandle、ports/endpoint等机制串联起来。下面我会逐个节点展开讲并给出可直接参考的配置片段。2. DTS 关键节点逐项解析这一节是全文的实操基础。我以 RK3588 常见的 EVB 设备树为蓝本把几个核心节点的配置方式和注意事项拆开讲。注意不同 SDK 版本有些节点名和属性名会有细微差异但核心逻辑一致你只需要在具体代码里搜索同名节点替换即可。2.1 usb2phy 节点中的 Type-C 相关配置RK3588 的 DTS 里usb2phy 节点一般长这样usb2phy0 { status okay; }; u2phy0_otg { vbus-supply vcc5v0_otg; rockchip,vbus-always-on; status okay; };这里有几个细节值得注意。u2phy0_otg节点对应 OTG 口系统通过它检测外部设备的插入同时用来做连接器角色切换。vbus-supply是 VBUS 的电源对象在 Device 模式被充电下这个电源通常由外部提供驱动会读取它的状态来判断是否已经插入 VBUS在 Host 模式下则由主板主动输出 VBUS。rockchip,vbus-always-on这个属性看名字就知道是不管角色怎么切VBUS 一直保持输出。但有些方案会把 Type-C 做 DRP双角色端口既要能充电也要能对外放电这时候一般不建议直接vbus-always-on而是让 TCPM 根据角色切换动态控制 VBUS否则可能出现“Device 模式下还在往外吐电”的尴尬情况。第二个需要关注的是 usb2phy 里的extcon引用常见写法是在 USB 3.0 控制器节点里引用usbdrd3_0 { status okay; extcon usbdrdphy0; }; usbdrdphy0 { status okay; extcon usbdrdphy0; };这段配置把 USB3 controller 与物理层驱动绑定在一起extcon用来上报 ID/充电检测事件。Android 上层就是通过 extcon 的变化感知到“这是一个 USB 充电器还是一个 Type-C 耳机”等设备类型。如果这里没有配对最典型的症状是插入充电器后log 里能看到 TCPC 的 CC 中断但是 Android 系统里的sys/class/power_supply/usb/type始终显示 N/A充电图标也不出来。2.2 外接 TCPC 控制器的 DTS 节点RK3588 的 TCPC 芯片一般挂在 I2C 上下面是一个常见的 FUSB302 节点配置很多国产板子直接照抄这个模板i2c6 { status okay; fusb0: fusb30x22 { compatible fcs,fusb302; reg 0x22; interrupt-parent gpio3; interrupts RK_PB5 IRQ_TYPE_LEVEL_LOW; pinctrl-names default; pinctrl-0 fusb0_int_l; vbus-supply vbus5v0_typec; status okay; ports { #address-cells 1; #size-cells 0; port0 { reg 0; tcpm_typec0: endpoint0 { remote-endpoint typec0_ep; }; }; }; }; };reg 0x22是 TCPC 芯片的 I2C 地址不同的 TCPC 可能用不同地址需要查芯片手册。interrupts RK_PB5 IRQ_TYPE_LEVEL_LOW是 CC 中断脚这个是排查“插拔没反应”的关键。很多板子的 TCPC 中断脚和别的外设复用了导致中断信号被占用CC 检测就一直收不到。ports/port0/endpoint这一段是 Type-C 图形框架的绑定方式用来把 TCPC 和 USB controller 的 typec 端口连接起来。如果你的 BSP 里没有这段也可以工作但部分依赖 typec class 的 Android 功能可能没法完整运行。从硬件调试经验来看TCPC 节点最常踩的坑有三个I2C 地址不对导致驱动 probe 失败中断 GPIO 被复用导致插拔无响应pinctrl 里的中断引脚上下拉配置不对导致一直误触发中断。前两个靠对照原理图就能解决第三个需要抓cat /proc/interrupts看看中断是不是疯狂增加。2.3 extcon、TCPM 与充电器的关联TCPC 驱动跑起来后内核里会注册一个 Type-C port并且通过 typec class 上报状态。RK3588 平台为了能对 PD 协商做策略控制BSP 里一般会额外带一个tcpm_policy或者名为rockchip,tcpm-policy的节点用来配置 PD 策略参数tcpm_policy { compatible rockchip,tcpm-policy; tcpm_policy_support; pinctrl-names default; ... };这个策略驱动的本质是让 PD 协商不单靠内核 tcpm 默认逻辑而是允许厂商限定电压电流范围。比如你的板子只能承受 9V/2A不想让充电器协商到 20V/5A就在这个节点里把 max 电压电流写死。后面我会在第 3 节专门讲怎么改。充电器节点也需要仔细确认。RK3588 EVB 上常用 RK806 PMICPMIC 内部集成了充电功能DTS 里会注册类似rk806_charger的节点如果是外置充电 IC则要确保它的 I2C 地址和中断配置正确。关键在于PD 协商出的结果要能传递到充电 IC。内核里常见的传递路径是tcpm 驱动获取到 PDO 之后调用power_supply_set_property或者直接通过charger_manager更新充电电流电压参数。2.4 DTS 配置完成后如何验证DTS 配置完不是直接make dtbs就完事了。我习惯按下面几个步骤验证第一步确认设备树有没有被正确编译进 boot 镜像。RK3588 Android12 通常用./build.sh -d rk3588-evb1-lp4-v10这样的方式选择 DTS然后去 kernel 目录执行make dtbs再重新打包 boot.img。第二步板子起来后检查设备树实际挂载情况。执行# 查看tcpc设备是否挂载成功 ls /sys/bus/i2c/devices/6-0022/ # 查看typec端口状态 ls /sys/class/typec/port0/如果 6-0022 目录不存在说明驱动 probe 失败或 I2C 地址不对回到 2.2 节排查。第三步插入 PD 充电器立刻看内核日志dmesg | grep -iE tcpm|fusb|tcpc|pd正常情况会看到CC1: 0 - 2之类的状态变化然后进入 PD 协商状态机最终出现类似POWER_SUPPLY_PROP_ONLINE的上报。如果这个过程卡住多半是中断或 I2C 通信问题。后面第 4 节会专门展开。3. 内核驱动修改从 PD 协商到充电策略DTS 只是把硬件的拓扑关系描述清楚真正决定“能协商到多少伏多少安”“协商完怎么充电”的是内核驱动。RK3588 Android12 的 PD 相关驱动主要分布在drivers/usb/typec/tcpm/和drivers/power/supply/这两个目录下面。3.1 tcpm 核心状态机与驱动代码位置Linux 内核标准 tcpm 驱动位于drivers/usb/typec/tcpm/tcpm.c它实现了一整套 Type-C 连接状态机包括 none/unattached/attached 等基础状态以及整套 PD 消息收发逻辑。RK3588 BSP 一般会在这个基础上做一些定制比如修改tcpm_pd_check_request、tcpm_pd_build_request这些函数从而改变 RDORequest Data Object的生成策略。实际调试时最常用的路径是插入充电器tcpm 进入SNK_DISCOVERY然后通过 Source Capabilities 消息获得充电器支持的 PDO 列表再据此构建 RDO 发起请求。如果你希望固定请求某个电压可以直接在驱动里修改选择逻辑也可以跑一个用户态策略。这里我推荐能用 DTS 配置解决的尽量不要改内核代码否则每次升级内核都要重新打补丁。3.2 修改默认 PD 协商电压电流上限RK3588 SDK 通常支持通过 tcpm_policy 驱动或者 DTS 属性限制 PD 协商范围。比如tcpm_policy { compatible rockchip,tcpm-policy; max_voltage_mv 9000; max_current_ma 2000; max_power_mw 18000; };这段配置的意思是PD 协商时最多请求 9V/2A即使充电器支持 20V/5A也不会去请求超过这个范围的档位。别小看这个限制很多电源路径设计、电感选型、PCB 走线都是按特定功率做的超过设计上限轻则发热严重重则烧板。如果你需要去掉上限比如做 100W 大功率充电就把这几个值调大同时检查硬件功率路径、电池充电 IC 的电流采样电阻、VBUS 走线是否满足要求。要注意的是光改 tcpm_policy 不一定够外置充电 IC 的充电电流上限通常也要同步修改否则 PD 请求上去了充电 IC 还是按老策略限流白白浪费了协商能力。3.3 充电器驱动与 PMIC 的功率传递PD 协商成功只是第一步关键是执行。在内核里tcpm 拿到协商结果后会把请求电压电流通过tcpm_psy_set_prop或者power_supply_changed广播出去充电 IC 驱动需要监听这些事件并切换自己的输出。RK3588 BSP 中如果使用 RK806 PMIC充电状态可以在sysfs里直接查看cat /sys/class/power_supply/rk806_charger/uevent关注这几个字段POWER_SUPPLY_STATUS充电状态Discharging/Charging/FullPOWER_SUPPLY_CONSTANT_CHARGE_CURRENT_MAX最大恒流充电电流POWER_SUPPLY_CONSTANT_CHARGE_VOLTAGE_MAX最大恒压充电电压如果你的平台是外置充电 IC比如南芯 SC8886那么充电电流的目标值往往写在充电 IC 的寄存器里驱动通过 I2C 写入。PD 请求到 9V/3A但是充电 IC 端寄存器只配了 2A那实际充电电流还是 2A。这也是“PD 协商到高压但充电速度不快”的一个隐藏原因。下表是常见调试对象和对应 sysfs 路径调试对象路径/接口常见问题PD 协商状态dmesg里的 tcpm 状态机日志卡在 SNK_DISCOVERY不进入协商Type-C 端口状态/sys/class/typec/port0/data_role角色切换失败一直是 device充电器信息/sys/class/power_supply/usb/ueventtype 为 N/A充电器类型识别失败实际充电电流PMIC 或充电 IC 对应的 power_supply 节点电流上不去与 PD 请求值不一致3.4 一个典型实战修改让 PD 快充优先兜底 QC2.0PD 不是唯一的快充协议市面上很多充电器同时支持 PD 和 QC2.0/QC3.0。在 RK3588 平台上做产品时有一个很常见的需求优先走 PD 协商如果在规定时间内协商失败就退回 QC 或者普通 5V 充电避免用户插一个“假 PD”充电器导致充电功率过低。实现思路不复杂。在 tcpm_policy 驱动或对应的 charger 驱动里加一个超时判断比如 1 秒内没有收到 Source Capabilities就发送tcpm_psy_set_online通知上层切换到 QC 流程。这里要特别提醒QC 握手是通过 D/D- 电压实现的与 PD 的 CC 线完全独立切换时要注意 VBUS 电压爬升曲线避免直接从 5V 跳到 12V 导致后端器件过压。我实际调过的一个案子就是 PD 协商超时后直接切 QC2.0通过 USB 控制器的 D/D- 开关把 D 拉高到 0.6V、D- 拉高到 0.6V让充电器输出 12V。因为 RK3588 的 usb2phy 内部带了 BC1.2 模块这套逻辑在驱动里实现起来并不难。关键是切换时机和电压调节节奏要控制好不然容易引起充电器保护。4. 调试方法、常见问题与排查技巧实录PD 充电的调试比普通 USB 充电复杂得多因为协议协商是异步的状态多而且跟线缆质量、充电器固件、CC 引脚接触电阻都有关。我建议每个人在动手前先把日志抓取工具准备好省得到时候两眼一抹黑。4.1 用 tcpm 状态机与日志定位协商卡点插入 PD 充电器后快速执行下面这条命令把协议交互过程完整体现出来logcat -d | grep -iE tcpc|tcpm|typec|pd dmesg | grep -iE tcpm|fusb|tcpci正常的 PD 协商流程中日志会呈现一条清晰的状态链CC1: 0 - 2表示检测到线缆插入CC 电平从开路变成拉低SNK_ATTACHED表示以 Sink受电方身份接入PD_DISCOVERY表示开始运行 PD 发现流程Source_Caps收到充电器能力列表SEND_RDO发送请求并收到 AcceptSNK_READY表示协商完成可以开始充电如果日志卡在SNK_DISCOVERY大概率是 PD 消息收发失败。这时候先判断是中断问题还是 I2C 通信问题看dmesg里有没有频繁的 I2C read/write error有的话重点查 TCPC 供电和 I2C 上拉没有的话用示波器抓 CC 线的拨动波形看 TCPC 的 INT 脚有没有产生下降沿。如果日志里压根没有CC1: 0 - 2那问题基本出在 TCPC 驱动没有正确响应中断先回 DTS 查中断 GPIO 和 pinctrl。还有一种可能是 CC 引脚对地短路或者接触不良这个只能换线、换座子验证。4.2 常见问题速查表我整理了一份问题速查表覆盖了日常调试中最容易遇到的几类问题现象可能原因排查/解决建议插 PD 充电器无任何反应TCPC 中断没触发VBUS 没供上查 DTS 中断脚dmesg 看是否有 CC 状态变化用万用表量 VBUS 有无 5V能识别充电器但电流锁在 5V/1.5APD 协商失败退回默认 USB 充电抓 tcpm 日志看是否收到 Source_Caps检查 TCPC I2C 通信稳定性协商到 9V/2A但系统显示充电极慢充电 IC 寄存器限流读充电 IC current limit 寄存器检查 PMIC 充电配置插拔过程中偶发系统重启角色切换时 VBUS 冲突检查 VBUS 供电设计避免 Device/Host 切换时电源反灌DTS 中不要乱开 vbus-always-on扩展坞插上去无法识别 USB 设备TCPM 角色切换没切到 Host看 typec/data_role 是否切换到 host检查 USB3 PHY 的 extcon 引用拔线后系统仍认为在充电CC 中断丢失extcon 没有上报拔插事件查 TCPC 拔插中断确认 extcon 驱动是否调用了 extcon_set_state其中“插拔过程中偶发系统重启”这个问题最隐蔽因为它不是协议问题而是电源设计问题。当角色从 Device 切到 Host 时VBUS 要从“接收外部电源”突然变成“对外输出 5V”如果电源路径上的 MOS 管切换时序没做好就会导致 VBUS 和系统电源短暂短路触发 PMIC 过流保护表现就是整机断电重启。遇到这种情况优先抓 PMIC 的中断日志确认是不是 OVP 或 OCP 触发。4.3 调试工具与实际项目中的避坑经验软件层面我强烈建议准备一个 PD 协议分析仪不需要太贵能解析 PD 消息、显示电压电流波形就行。没有分析仪的时候也可以用 USB 电流电压表就是那种小屏幕显示电压电流的功率计配合 dmesg 日志能解决 80% 的问题。硬件层面一个容易被忽略的点是 CC 引脚上的 5.1k 下拉电阻和 Rd/Ra 检测。Type-C 设备作为 Sink 时CC1/CC2 需要分别接 5.1k 下拉电阻到地TCPC 靠检测这个电阻来识别插入方向。很多公版原理图在 Type-C 座子设计时没有仔细核对这两颗电阻的精度用了 1% 甚至 5% 的电阻导致 CC 电压偏离指定范围TCPC 误判方向。我遇到过一块板子正插能充电反插就概率性没反应最后查出来就是其中一颗 5.1k 电阻虚焊。另外一个经验是RK3588 Android12 平台在修改 DTS 后一定要清掉旧的 dtb 缓存。有些编译系统会缓存 dtb导致你改了 DTS 重新打包但实际跑的还是旧设备树。检查方法很简单开机后在板子上执行cat /proc/device-tree/model cat /proc/device-tree/chosen/rk-dts-root/status 2/dev/null || true再看 dmesg 里打印的 DTS 文件名确认是不是你刚改的那个。4.4 内核配置裁剪对 PD 功能的影响最后提一个很容易被忽略的地方内核 Kconfig 裁剪。很多定制 ROM 为了精简内核会把不用的驱动关掉但 Type-C 相关配置一旦被裁剪BD 问题非常隐蔽。下面是 RK3588 Android12 PD 功能相关的主要配置项CONFIG_TYPECy CONFIG_TYPEC_TCPMy CONFIG_TYPEC_TCPCIy CONFIG_TYPEC_FUSB302y CONFIG_POWER_SUPPLYy CONFIG_CHARGER_RK806y CONFIG_RK_HEADSET_DETy如果确认 DTS 没问题但驱动始终不 probe就去查内核 .config 里这些选项有没有被关掉。CONFIG_TYPEC_FUSB302对应 FUSB302 这类 TCPC 芯片的驱动如果你用的是别的型号可能需要CONFIG_TYPEC_HUSB311等对应配置。另一个经常被误关的是CONFIG_RK_HEADSET_DET它负责 Type-C 耳机和模拟音频切换和 PD 充电共享一部分 extcon 逻辑关掉之后 Type-C 口的功能会变得很奇怪。另外Android 12 上还有一个隐藏依赖/sys/class/typec/port0/下的接口会由CONFIG_TYPEC和CONFIG_TYPEC_CLASS控制。如果系统里没有这个目录Android 的 UsbManager 和 Settings 里的充电相关显示都会失效即使内核驱动本身能正常协商。这个坑排查起来很费时间因为 Mar 上看起来一切正常就是上层功能不刷新。这块整套调下来我个人最大的体会是PD 充电不是“改个 DTS 就能跑”的模块它是一个完整的状态机系统DTS 负责布线内核驱动负责决策充电 IC 负责执行链路上一环抠不紧最终就表现为充电慢、不充电、插拔重启这类看似玄学的问题。建议你拿到一个新板子时先把基础 Sink 功能跑通——只是单纯接受充电器供电不做 Host、不做数据确认 PD 能协商到目标电压电流之后再去扩展 DRP、PPS、OTG 这些花活。这样出了问题每一步的边界都很清楚定位起来会轻松很多。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号