VBUS Channel 模块分析
1. 模块定位与核心价值
vbus_channel 是华为充电管理系统中的 VBUS 通道抽象层,负责管理和切换不同的 VBUS 输出通道。它是一个典型的策略模式实现,为多种 OTG 和无线反向充电场景提供统一的 VBUS 管理接口。
核心价值:
🔄 多通道抽象:统一管理 Charger、Boost GPIO、Pogopin Boost 三种 VBUS 输出方式
👥 多用户支持:支持 6 种用户场景(有线 OTG、无线发射、直充、PD、音频、触点)
🛡️ 故障保护:集成 OTG 短路保护(SCP)和过流保护(OCP)机制
🎯 路由分发:根据用户类型和通道类型智能路由到对应实现
2. 系统架构
2.1 三层架构设计
┌─────────────────────────────────────────────────────────────┐
│ 用户层 (6 种用户场景) │
├─────────────────────────────────────────────────────────────┤
│ WIRED_OTG │ WR_TX │ DC │ PD │ AUDIO │ POGOPIN │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ vbus_channel.c (抽象路由层) │
├─────────────────────────────────────────────────────────────┤
│ • vbus_ch_open() • vbus_ch_get_state() │
│ • vbus_ch_close() • vbus_ch_set_voltage() │
│ • vbus_ch_get_mode() • vbus_ch_ops_register() │
└──────────────────────┬──────────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌───────────┐ ┌──────────────┐ ┌──────────────────┐
│ CHARGER │ │ BOOST_GPIO │ │ POGOPIN_BOOST │
│ 实现层 │ │ 实现层 │ │ 实现层 │
├───────────┤ ├──────────────┤ ├──────────────────┤
│ Charger │ │ GPIO + 5V │ │ Pogopin + │
│ IC OTG │ │ Boost IC │ │ BuckBoost │
└───────────┘ └──────────────┘ └──────────────────┘
│ │ │
└──────────────┼──────────────┘
▼
┌──────────────────────────────┐
│ vbus_channel_error_handle │
│ (错误处理层) │
├──────────────────────────────┤
│ • OTG SCP 检测 │
│ • OTG OCP 检测 │
│ • DMD 故障上报 │
└──────────────────────────────┘
2.2 用户-通道类型矩阵
| 用户类型 | CHARGER | BOOST_GPIO | POGOPIN_BOOST | 典型场景 |
|---|
| WIRED_OTG | ✓ | ✓ | ✓ | 有线 OTG 外设供电 |
| WR_TX | ✓ | ✓ | - | 无线反向充电 |
| DC | ✓ | - | - | 直充模式 VBUS 控制 |
| PD | ✓ | ✓ | ✓ | PD 协议 OTG 场景 |
| AUDIO | ✓ | - | - | 音频配件供电 |
| POGOPIN | - | - | ✓ | 触点连接器供电 |
3. 核心数据结构
3.1 VBUS 通道操作结构
struct vbus_ch_ops {
const char *type_name;
int (*open)(unsigned int user, int flag);
int (*close)(unsigned int user, int flag, int force);
int (*get_state)(unsigned int user, int *state);
int (*get_mode)(unsigned int user, int *mode);
int (*set_switch_mode)(unsigned int user, int mode);
int (*set_voltage)(unsigned int user, int vol);
int (*get_voltage)(unsigned int user, int *vol);
};
3.2 VBUS 通道设备结构
struct vbus_ch_dev {
unsigned int total_ops;
struct vbus_ch_ops *ops[VBUS_CH_TYPE_END];
};
3.3 错误处理参数
struct otg_scp_para {
unsigned int vol_mv;
unsigned int check_times;
unsigned int delayed_time;
unsigned int fault_count;
bool work_flag;
struct delayed_work work;
};
struct otg_ocp_para {
unsigned int vol_mv;
unsigned int check_times;
unsigned int delayed_time;
unsigned int fault_count;
bool work_flag;
struct delayed_work work;
};
4. 三种实现详解
4.1 CHARGER 实现(vbus_channel_charger)
原理: 通过 Charger IC 的 OTG 功能输出 5V
关键流程:
static int charger_otg_start_config(int flag)
{
power_wakeup_lock(l_dev->otg_lock, false);
charger_otg_set_charger_enable(l_dev, false);
charger_otg_set_otg_enable(l_dev, true);
charger_otg_set_otg_current(l_dev, l_dev->otg_curr);
schedule_delayed_work(&l_dev->otg_work, msecs_to_jiffies(0));
return 0;
}
看门狗机制: 每 25 秒触发一次喂狗,防止 Charger IC 看门狗超时
#define CHARGER_OTG_WORK_TIME 25000
static void charger_otg_work(struct work_struct *work)
{
charger_otg_set_otg_enable(l_dev, true);
charger_otg_kick_watchdog(l_dev, true);
schedule_delayed_work(&l_dev->otg_work,
msecs_to_jiffies(CHARGER_OTG_WORK_TIME));
}
支持的 Charger IC:
bq2419x, bq2429x, bq2560x, bq25882, bq25892
hl7019, rt9466, rt9471
hi6522, hi6523, hi6526
bd99954, bq25713, schargerv700
4.2 BOOST_GPIO 实现(vbus_channel_boost_gpio)
原理: 通过 GPIO 控制外部 5V Boost IC 输出
硬件控制序列:
static int boost_gpio_start_config(int flag)
{
wlrx_plim_set_src(WLTRX_DRV_MAIN, WLRX_PLIM_SRC_OTG);
boost_gpio_start_config_wired_channel_control();
wireless_tx_cancel_work(PWR_SW_BY_OTG_ON);
msleep(100);
boost_5v_enable(BOOST_5V_ENABLE, BOOST_CTRL_BOOST_GPIO_OTG);
power_usleep(DT_USLEEP_10MS);
gpio_set_value(l_dev->gpio_en, BOOST_GPIO_SWITCH_ENABLE);
wireless_tx_restart_check(PWR_SW_BY_OTG_ON);
return 0;
}
硬件问题修复: 某些平台存在漏电问题,需要同时打开 Charger OTG
if (l_dev->charge_otg_ctl_flag) {
vbus_ch_open(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_CHARGER, false);
schedule_delayed_work(&l_dev->charge_otg_close_work,
msecs_to_jiffies(200));
}
过流保护: 支持 GPIO 中断检测 OCP
static irqreturn_t boost_gpio_otg_ocp_irq_handler(int irq, void *_l_dev)
{
schedule_work(&l_dev->otg_ocp_work);
return IRQ_HANDLED;
}
4.3 POGOPIN_BOOST 实现(vbus_channel_pogopin_boost)
原理: 通过 Pogopin 触点连接器输出,使用 BuckBoost IC
硬件拓扑:
Charger IC ──[MOS]── BuckBoost ──[Pogopin]── 外部设备
↑
[OTG_EN GPIO]
启动序列:
static int pogopin_boost_start_config(void)
{
gpio_set_value(l_dev->mos_en, MOS_GPIO_SWITCH_ENABLE);
if (pogopin_boost_get_fault_status(l_dev))
return 0;
if (l_dev->charge_otg_ctl && charge_get_charger_type() == CHARGER_REMOVED) {
vbus_ch_open(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_CHARGER, false);
}
pogopin_boost_5v_enable(l_dev, BOOST_5V_ENABLE);
if (l_dev->otg_en_flag)
gpio_set_value(l_dev->otg_en, OTG_GPIO_SWITCH_ENABLE);
return 0;
}
关闭序列: 反向操作,并增加 160ms 延迟确保 BuckBoost 完全关闭
static int pogopin_boost_stop_config(void)
{
gpio_set_value(l_dev->otg_en, OTG_GPIO_SWITCH_DISABLE);
pogopin_boost_5v_enable(l_dev, BOOST_5V_DISABLE);
msleep(160);
gpio_set_value(l_dev->mos_en, MOS_GPIO_SWITCH_DISABLE);
return 0;
}
5. 核心流程实现
5.1 打开 VBUS 通道流程
int vbus_ch_open(unsigned int user, unsigned int type, int flag)
{
struct vbus_ch_dev *l_dev = vbus_ch_get_dev();
if (user >= VBUS_CH_USER_END || type >= VBUS_CH_TYPE_END)
return -EPERM;
if (!l_dev->ops[type] || !l_dev->ops[type]->open)
return -EPERM;
return l_dev->ops[type]->open(user, flag);
}
用户位掩码管理: 每个实现维护一个用户位图
l_dev->user |= (1 << user);
5.2 关闭 VBUS 通道流程
int vbus_ch_close(unsigned int user, unsigned int type, int flag, int force)
{
struct vbus_ch_dev *l_dev = vbus_ch_get_dev();
if (force) {
return l_dev->ops[type]->close(user, flag, force);
}
l_dev->user &= (~(unsigned int)(1 << user));
if (l_dev->user == VBUS_CH_NO_OP_USER) {
return stop_config(flag);
}
return 0;
}
引用计数管理:
5.3 错误处理机制
5.3.1 OTG 短路检测(SCP)
static void otg_scp_check_work(struct work_struct *work)
{
struct otg_scp_para *info = &l_dev->otg_scp;
if (vbus_ch_eh_check_usb_state(l_dev))
return;
charge_get_vbus(&value);
if (value < (int)info->vol_mv) {
info->fault_count++;
} else {
info->fault_count = 0;
}
if (info->fault_count > info->check_times) {
l_dev->otg_scp_flag = true;
power_event_bnc_notify(..., POWER_NE_HW_PD_SOURCE_VBUS, &vbus_enable);
vbus_ch_eh_dmd_report(OTG_SCP_DMD_REPORT, &value);
return;
}
schedule_delayed_work(&info->work, msecs_to_jiffies(info->delayed_time));
}
检测参数:
电压阈值:3400mV(低于此值判定为短路)
检查次数:30 次
检查间隔:300ms
总检测时间:30 × 300ms = 9 秒
5.3.2 OTG 过流检测(OCP)
GPIO 中断方式:
static void boost_gpio_otg_ocp_work(struct work_struct *work)
{
power_event_bnc_notify(POWER_BNT_OTG, POWER_NE_OTG_OCP_HANDLE,
&l_dev->otg_ocp_int);
}
static irqreturn_t boost_gpio_otg_ocp_irq_handler(int irq, void *_l_dev)
{
schedule_work(&l_dev->otg_ocp_work);
return IRQ_HANDLED;
}
轮询检测方式:
static void otg_ocp_check_work(struct work_struct *work)
{
charge_get_vbus(&value);
if (value < (int)info->vol_mv) {
info->fault_count++;
} else {
info->fault_count = 0;
}
if (info->fault_count > info->check_times) {
power_event_bnc_notify(..., POWER_NE_HW_PD_SOURCE_VBUS, &vbus_enable);
vbus_ch_eh_dmd_report(OTG_OCP_DMD_REPORT, &value);
return;
}
schedule_delayed_work(&info->work, msecs_to_jiffies(info->delayed_time));
}
检测参数:
5.3.3 DMD 故障上报
static void vbus_ch_eh_dmd_report(unsigned int err_no, int *val)
{
char buf[VBUS_CH_EH_DMD_BUF_SIZE] = {0};
snprintf(buf, sizeof(buf), "otg %s, vbus=%dmV\n",
(err_no == OTG_SCP_DMD_REPORT) ? "scp" : "ocp",
*val);
power_dsm_report_dmd(POWER_DSM_BATTERY, err_no, buf);
}
6. 典型使用场景
6.1 有线 OTG 供电
vbus_ch_open(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_BOOST_GPIO, true);
vbus_ch_close(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_BOOST_GPIO, true, false);
硬件动作序列:
断开 BUCK 充电通道
使能 5V Boost IC
拉高 GPIO 切换到 OTG 输出
启动 SCP/OCP 检测
6.2 无线反向充电
vbus_ch_open(VBUS_CH_USER_WR_TX, VBUS_CH_TYPE_CHARGER, true);
vbus_ch_close(VBUS_CH_USER_WR_TX, VBUS_CH_TYPE_CHARGER, true, false);
Charger OTG 模式:
关闭充电功能
使能 Charger IC OTG
设置电流限制(1000mA)
启动看门狗喂狗任务
6.3 直充模式 VBUS 控制
vbus_ch_open(VBUS_CH_USER_DC, VBUS_CH_TYPE_CHARGER, false);
vbus_ch_close(VBUS_CH_USER_DC, VBUS_CH_TYPE_CHARGER, false, false);
6.4 多用户并发场景
vbus_ch_open(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_BOOST_GPIO, true);
vbus_ch_open(VBUS_CH_USER_PD, VBUS_CH_TYPE_BOOST_GPIO, false);
vbus_ch_close(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_BOOST_GPIO, false, false);
vbus_ch_close(VBUS_CH_USER_PD, VBUS_CH_TYPE_BOOST_GPIO, true, false);
7. 设计模式与优化
7.1 策略模式(Strategy Pattern)
抽象策略: struct vbus_ch_ops
struct vbus_ch_ops {
const char *type_name;
int (*open)(unsigned int user, int flag);
int (*close)(unsigned int user, int flag, int force);
};
具体策略:
charger_otg_ops - Charger IC 策略
boost_gpio_ops - GPIO Boost 策略
pogopin_boost_ops - Pogopin BuckBoost 策略
上下文: struct vbus_ch_dev 维护策略数组
7.2 注册-发现模式
vbus_ch_ops_register(&boost_gpio_ops);
vbus_ch_ops_register(&charger_otg_ops);
vbus_ch_ops_register(&pogopin_boost_ops);
vbus_ch_open(user, VBUS_CH_TYPE_BOOST_GPIO, flag);
7.3 引用计数管理
位掩码设计: 每个 user 对应一个 bit
#define VBUS_CH_USER_WIRED_OTG 0
#define VBUS_CH_USER_WR_TX 1
#define VBUS_CH_USER_DC 2
#define VBUS_CH_USER_PD 3
#define VBUS_CH_USER_AUDIO 4
#define VBUS_CH_USER_POGOPIN 5
unsigned int user;
优点:
O(1) 时间复杂度的添加/删除操作
内存占用小(只需 4 字节)
支持最多 32 个用户
7.4 看门狗保活机制
Charger IC 看门狗: 防止 IC 超时自动关闭 OTG
#define CHARGER_OTG_WORK_TIME 25000
static void charger_otg_work(struct work_struct *work)
{
charger_otg_set_otg_enable(l_dev, true);
charger_otg_kick_watchdog(l_dev, true);
schedule_delayed_work(&l_dev->otg_work,
msecs_to_jiffies(CHARGER_OTG_WORK_TIME));
}
系统看门狗: 同时喂系统级看门狗
power_platform_charge_feed_sys_wdt(CHARGER_OTG_SYS_WDT_TIMEOUT);
7.5 硬件缺陷规避设计
问题 1:漏电问题
if (l_dev->charge_otg_ctl_flag) {
vbus_ch_open(VBUS_CH_USER_WIRED_OTG, VBUS_CH_TYPE_CHARGER, false);
schedule_delayed_work(&l_dev->charge_otg_close_work,
msecs_to_jiffies(200));
}
问题 2:关断时序问题
pogopin_boost_5v_enable(l_dev, BOOST_5V_DISABLE);
msleep(160);
gpio_set_value(l_dev->mos_en, MOS_GPIO_SWITCH_DISABLE);
8. 调试方法
8.1 sysfs 接口
cat /sys/class/hw_power/vbus_channel/support_type
8.2 日志关键字
dmesg | grep vbus_ch
dmesg | grep "otg scp|otg ocp"
dmesg | grep "vbus_ch_boost_gpio|vbus_ch_charger|vbus_ch_pogopin"
8.3 典型日志分析
正常打开流程:
[ 100.123] vbus_ch: user=1 type=1 open
[ 100.124] vbus_ch_boost_gpio: start reverse_vbus flag=1
[ 100.225] vbus_ch_boost_gpio: gpio_123 high now
[ 100.226] vbus_ch_boost_gpio: user=1 open ok
短路保护触发:
[ 105.123] vbus_ch_eh: otg scp check start
[ 105.423] vbus_ch_eh: scp: value=3200, fault_count=1
[ 105.723] vbus_ch_eh: scp: value=3150, fault_count=2
...
[ 114.123] vbus_ch_eh: otg scp happen
[ 114.124] DMD report: otg scp, vbus=3150mV
8.4 动态调试
使能动态日志:
echo 'file vbus_channel*.c +p' > /sys/kernel/debug/dynamic_debug/control
echo 'func vbus_ch_open +p' > /sys/kernel/debug/dynamic_debug/control
8.5 故障诊断流程
问题:OTG 不工作
├─ 1. 检查 ops 是否注册成功
│ └─ dmesg | grep "ops register"
│
├─ 2. 检查用户类型是否合法
│ └─ cat /sys/class/hw_power/vbus_channel/support_type
│
├─ 3. 检查是否触发保护
│ ├─ dmesg | grep "otg scp"
│ └─ dmesg | grep "otg ocp"
│
├─ 4. 检查 GPIO 状态
│ └─ cat /sys/kernel/debug/gpio
│
└─ 5. 检查 Charger IC 状态
└─ cat /sys/class/power_supply/*/otg_enable
9. 总结
vbus_channel 模块是一个典型的硬件抽象层实现,通过以下设计达到了高度的灵活性和可扩展性:
核心特性:
✅ 多通道支持:CHARGER BOOST_GPIO POGOPIN_BOOST 三种实现
✅ 多用户管理:引用计数式的用户管理,支持并发访问
✅ 完善保护:SCP/OCP 双重保护,DMD 故障上报
✅ 策略模式:ops 注册机制,易于扩展新的实现
✅ 硬件适配:针对不同平台的硬件缺陷有专门的规避措施
应用价值:
🔌 统一的 VBUS 管理接口,屏蔽底层硬件差异
🛡️ 多层次的故障保护,提高 OTG 使用安全性
🔄 灵活的通道切换,支持多种充电和供电场景
📊 完整的日志和调试接口,便于问题定位
该模块充分体现了面向对象设计在 C 语言中的实践,是充电管理系统中硬件通道层的核心组件。