3. 传感器驱动适配:OV/IMX 系列移植与接口配置

传感器驱动适配是 Camera HAL 层移植中最核心、最易出错的环节。高通平台通过 Camera Sensor Module (CSM) 和 Camera Subsystem (CSIPHY) 抽象了底层硬件差异,但 OV 与 IMX 系列在 I2C 协议、MIPI CSI 时序、电源上电序列上存在显著差异。本节将拆解这三部分的具体适配方法。

适配原则: 优先使用 Sensor 厂商提供的 Linux/Android 驱动模板,再根据高通平台 cam_sensor 驱动框架进行接口封装。不要从零编写 I2C 读写逻辑,而是复用高通 cam_sensor_cmn 库。

3.1 I2C 配置:寄存器地址与数据格式

OV 与 IMX 系列在 I2C 寄存器地址宽度、数据位宽、读写时序上存在差异。下表总结了常见差异点:

参数 OV 系列 (OmniVision) IMX 系列 (Sony)
寄存器地址宽度 16-bit (多数型号) 16-bit 或 8-bit (IMX219 为 16-bit)
数据位宽 8-bit (部分支持 16-bit) 8-bit (标准模式)
I2C 速率 400kHz (Fast Mode) 400kHz / 1MHz (Fast Mode Plus)
写操作格式 Addr(16bit) + Data(8bit) Addr(16bit) + Data(8bit) 或 Addr(8bit) + Data(8bit)
读操作格式 重复起始 + 读命令 停止 + 起始 + 读命令 (部分型号)

在高通驱动中,通过 i2c_freq_mode 和 addr_type 字段配置:

/* 示例:OV5648 的 I2C 配置结构体 */
static struct cam_sensor_i2c_reg_setting ov5648_settings = {
    .addr_type = CAM_SENSOR_I2C_TYPE_WORD,   /* 16-bit 地址 */
    .data_type = CAM_SENSOR_I2C_TYPE_BYTE,   /* 8-bit 数据 */
    .size = ARRAY_SIZE(ov5648_init_regs),
    .reg_setting = ov5648_init_regs,
    .delay = 0,
};

/* IMX219 的 I2C 配置 */
static struct cam_sensor_i2c_reg_setting imx219_settings = {
    .addr_type = CAM_SENSOR_I2C_TYPE_WORD,
    .data_type = CAM_SENSOR_I2C_TYPE_BYTE,
    .size = ARRAY_SIZE(imx219_init_regs),
    .reg_setting = imx219_init_regs,
    .delay = 5,  /* 5ms 延迟 */
};
常见陷阱: OV 传感器在写序列时通常不需要页切换 (page switch),而 IMX 系列 (如 IMX258) 在访问不同寄存器区域时需先写页寄存器。忽略页切换会导致寄存器写入失败,表现为 sensor 无法初始化。

3.2 MIPI CSI 接口:Lane 映射与时序配置

MIPI CSI-2 接口配置包括 Lane 数量、Lane 映射、时钟频率和 HS 时序。高通平台通过 csiphy 设备树节点和 cam_sensor_csi_params 结构体管理。

下图展示了 CSI 接口从 Sensor 到 ISP 的链路结构:

MIPI CSI-2 链路结构:Sensor → CSIPHY → CSID → ISP Sensor OV / IMX CSIPHY D-PHY 层 CSID 协议解析 ISP 处理 Lane 映射配置要点 • Lane 数量:2-lane (IMX219) / 4-lane (OV5648, IMX258) • Lane 映射:Sensor 输出 Lane 0-3 到 CSIPHY 物理 Lane 0-3,支持任意重映射 • 时钟 Lane:必须连接到 CSIPHY 的 CLK 引脚,不可映射到数据 Lane • HS 时序:T_HS_PREPARE、T_HS_ZERO、T_HS_TRAIL 需匹配 Sensor 数据手册

设备树中 Lane 映射配置示例:

/* 设备树:CSIPHY Lane 映射 */
&csiphy0 {
    cell-index = <0>;
    compatible = "qcom,csiphy-v1.0";
    reg = <0x0ac4a000 0x1000>;
    reg-names = "csiphy";

    /* Lane 映射:sensor_lane -> csiphy_lane */
    lane-mapping = <
        0 0   /* sensor lane 0 -> csiphy lane 0 */
        1 1   /* sensor lane 1 -> csiphy lane 1 */
        2 2   /* sensor lane 2 -> csiphy lane 2 */
        3 3   /* sensor lane 3 -> csiphy lane 3 */
    >;

    /* 时钟频率配置 */
    csiphy-clk-frequency = <480000000>;  /* 480MHz */
};
调试技巧: 使用高通 cam_sensor_dbg 工具读取 CSIPHY 状态寄存器,检查 Lane 是否进入 HS 模式。若 Lane 状态始终为 LP-11,说明 Lane 映射或电源序列有问题。

3.3 电源序列:上电与下电时序

OV 与 IMX 系列对上电时序要求严格,尤其是 AVDD、DVDD、IOVDD 的先后顺序和延迟时间。高通平台通过 cam_sensor_power_setting 结构体描述电源序列。

下表对比了两种典型电源序列:

步骤 OV5648 (OmniVision) IMX219 (Sony)
1 AVDD (2.8V) → 延迟 1ms IOVDD (1.8V) → 延迟 0.5ms
2 DVDD (1.5V) → 延迟 1ms AVDD (2.8V) → 延迟 1ms
3 IOVDD (1.8V) → 延迟 1ms DVDD (1.2V) → 延迟 1ms
4 MCLK 使能 → 延迟 1ms MCLK 使能 → 延迟 2ms
5 XSHUTDOWN 拉高 → 延迟 10ms XCLR 拉高 → 延迟 5ms
6 I2C 初始化序列 I2C 初始化序列

高通驱动中电源序列配置:

/* OV5648 上电序列 */
static struct cam_sensor_power_setting ov5648_power_up[] = {
    {
        .seq_type = CAM_SENSOR_POWER_SEQ_AVDD,
        .seq_val = 2800000,   /* 2.8V */
        .config_val = 0,
        .delay = 1,           /* 1ms */
    },
    {
        .seq_type = CAM_SENSOR_POWER_SEQ_DVDD,
        .seq_val = 1500000,   /* 1.5V */
        .config_val = 0,
        .delay = 1,
    },
    {
        .seq_type = CAM_SENSOR_POWER_SEQ_IOVDD,
        .seq_val = 1800000,   /* 1.8V */
        .config_val = 0,
        .delay = 1,
    },
    {
        .seq_type = CAM_SENSOR_POWER_SEQ_MCLK,
        .seq_val = 24000000,  /* 24MHz */
        .config_val = 0,
        .delay = 1,
    },
    {
        .seq_type = CAM_SENSOR_POWER_SEQ_RESET,
        .seq_val = 1,         /* 拉高 */
        .config_val = 0,
        .delay = 10,          /* 10ms */
    },
};
关键提醒: IMX 系列对 DVDD 和 IOVDD 的电压精度要求为 ±2%,超出范围可能导致 sensor 无法输出图像或产生噪点。务必使用 PMIC 的 LDO 供电,不要直接使用 GPIO 模拟电源。

3.4 时钟配置:MCLK 与 PLL 设置

Sensor 需要外部 MCLK (主时钟) 和内部 PLL 配置来生成像素时钟。高通平台通过 cam_sensor_mclk 和 cam_sensor_pll 管理。

常见 MCLK 频率:

  • OV 系列: 24MHz (多数型号),部分支持 27MHz
  • IMX 系列: 24MHz (IMX219/258),部分支持 27MHz (IMX477)

PLL 配置通过 I2C 寄存器写入,高通驱动不直接计算 PLL 参数,而是由 Sensor 厂商提供预计算好的寄存器表。适配时只需确保 MCLK 频率与寄存器表匹配。

/* 时钟配置检查:确保 MCLK 频率匹配 */
static int ov5648_check_mclk(struct cam_sensor_ctrl_t *s_ctrl)
{
    uint32_t mclk_freq = s_ctrl->soc_info.mclk_freq;

    if (mclk_freq != 24000000) {
        CAM_ERR(CAM_SENSOR, "OV5648 requires 24MHz MCLK, got %u Hz",
                mclk_freq);
        return -EINVAL;
    }
    return 0;
}

3.5 适配验证流程

完成驱动移植后,按以下步骤验证:

  1. I2C 探测: 使用 i2cdetect 确认 sensor I2C 地址响应
  2. 电源测量: 用示波器测量 AVDD/DVDD/IOVDD 上电时序是否符合预期
  3. MCLK 测量: 确认 MCLK 频率误差在 ±1% 以内
  4. CSI 信号检查: 使用逻辑分析仪抓取 CSI Lane 数据,确认 HS 模式进入
  5. 图像采集: 通过高通 cam_test 工具采集 RAW 图像,检查无坏行/坏列
性能指标: 驱动适配完成后,I2C 初始化序列应在 50ms 内完成,CSI 链路建立时间应小于 100ms,首次帧输出延迟不超过 200ms。