太好了!既然确认可以通过软件配置寄存器来切换 GMSL 模式,那我来给你提供具体的配置方案。
MAX96712 GMSL1 模式寄存器配置
关键寄存器配置
根据 MAX96712 数据手册,切换 GMSL1 模式主要需要配置以下寄存器:
| 寄存器地址 | 寄存器名称 | GMSL1 配置值 | 说明 |
|---|---|---|---|
0x6E |
GMSL_PORT_CONFIG | 0x00 |
设置为 GMSL1 模式 (bit0=0) |
0x10 |
LINK_CONTROL | 0x04 |
配置 Lane 数 (根据实际需求) |
0x0D |
FWD_CTL1 | 0x40 |
转发控制 |
0x20 |
RX_PORT_CFG | 0x00 |
接收端口配置 |
驱动代码修改
在 drivers/media/platform/max96712.c 中修改初始化序列:
// MAX96712 GMSL1 模式初始化配置
static const struct reg_default max96712_gmsl1_init[] = {
// 强制切换到 GMSL1 模式
{0x6E, 0x00}, // GMSL_PORT_CONFIG: bit0=0 -> GMSL1
// 链路配置 (根据实际 Lane 数调整)
{0x10, 0x04}, // LINK_CONTROL: 1 Lane
// {0x10, 0x08}, // LINK_CONTROL: 2 Lane (如需 2 Lane)
// 转发控制
{0x0D, 0x40}, // FWD_CTL1
// 接收端口配置
{0x20, 0x00}, // RX_PORT_CFG
// 其他必要配置
{0x00, 0x00}, // 设备 ID 读取验证
};
// 在 probe 或初始化函数中调用
static int max96712_init_gmsl1(struct i2c_client *client)
{
int ret;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(max96712_gmsl1_init); i++) {
ret = regmap_write(max96712->regmap,
max96712_gmsl1_init[i].reg,
max96712_gmsl1_init[i].def);
if (ret) {
dev_err(&client->dev, "Failed to write reg 0x%x\n",
max96712_gmsl1_init[i].reg);
return ret;
}
msleep(10); // 寄存器写入后延时
}
return 0;
}
设备树配置 (DTS)
如果需要配置 GPIO 控制,在设备树中添加:
&i2c2 {
max96712@52 {
compatible = "maxim,max96712";
reg = <0x52>;
// GMSL 模式配置
maxim,gmsl-mode = <1>; // 1=GMSL1, 2=GMSL2
// Lane 数配置
maxim,num-lanes = <1>;
// 如果需要 GPIO 控制
gmsl-mode-gpio = <&gpio 123 GPIO_ACTIVE_HIGH>;
};
};
验证步骤
- 编译并加载驱动
cd /path/to/kernel/drivers/media/platform
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
sudo insmod max96712.ko
- 查看链路状态
dmesg | grep -i "max96712\|link\|gmsl"
- 关键日志检查
link lock success- 链路锁定成功
video lock success- 视频锁定成功
hs reception error- 高速接收错误 (模式不匹配)
link timeout- 链路超时
- 手动读取寄存器验证
# 使用 i2c-tools 读取寄存器确认配置
i2cget -y 2 0x52 0x6E # 应返回 0x00 (GMSL1)
i2cget -y 2 0x52 0x10 # 查看 Lane 配置
MAX96705 串行器配合配置
同时需要确保 MAX96705 串行器也配置为 GMSL1 模式:
// MAX96705 GMSL1 初始化配置示例
static const struct reg_default max96705_gmsl1_init[] = {
{0x01, 0x00}, // 配置为 GMSL1 模式
{0x02, 0x04}, // Lane 数配置 (与解串器一致)
{0x03, 0x01}, // 使能输出
};
常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| Link Lock 失败 | GMSL 模式不匹配 | 确认 0x6E 寄存器值为 0x00 |
| HS Reception Error | Lane 数不匹配 | 检查串行器/解串器 Lane 配置一致 |
| 无视频数据 | 时序配置错误 | 检查像素时钟和帧率配置 |
| I2C 通信失败 | 地址冲突 | 确认 I2C 地址 (0x52/0x54 等) |
下一步建议
- 先单 Lane 测试:建议先用 1 Lane 配置测试,稳定后再尝试多 Lane
- 保存原始配置:修改前备份原驱动文件
- 逐步验证:每修改一个寄存器就验证一次链路状态
如果配置后仍有问题,可以把 dmesg 日志贴出来,我帮你分析具体是哪个环节出了问题。
参考帖子:
- RDK S100 Fakra GMSL接入自己的摄像头 - MAX96705 驱动移植详细讨论
- RDK S100调试红外摄像头dump数据报错 - Lane 配置问题案例