4. Sensor驱动核心数据结构

在RK平台Camera Sensor驱动开发中,核心数据结构是连接硬件寄存器、驱动逻辑与ISP图像调优的桥梁。本章深入剖析四个关键数据结构:struct v4l2_subdev、struct rkmodule_inf、struct rk_sensor_reg 和 struct rk_sensor_mode,理解它们的设计意图与协作关系是驱动开发与ISP联调的基础。

学习提示: 这四个结构体分别对应V4L2框架标准层、RK平台私有扩展层、寄存器操作层和模式配置层。建议结合源码逐字段理解,并在实际驱动中追踪它们的初始化与调用链路。

4.1 struct v4l2_subdev:V4L2子设备抽象

struct v4l2_subdev 是V4L2框架中所有子设备(包括Sensor、Flash、AF等)的通用抽象。Sensor驱动通过注册该结构体,将硬件控制接口暴露给上层ISP和应用程序。

字段 类型 说明
name char[32] 设备名称,如 "imx415 0-001a"
grp_id u32 组ID,用于多Sensor绑定
entity struct media_entity 媒体实体,用于管道管理
ops struct v4l2_subdev_ops * 核心操作函数集(core/video/pad等)
ctrl_handler struct v4l2_ctrl_handler * 控制句柄,管理曝光/增益/白平衡等
host_priv void * 私有数据指针,指向Sensor驱动自定义结构
dev struct device * 内核设备指针

在Sensor驱动中,host_priv 字段通常指向包含 struct rkmodule_inf 和 struct rk_sensor_mode 的私有结构体,实现标准框架与平台扩展的桥接。

// 典型注册流程
static struct v4l2_subdev sensor_subdev;

// 初始化子设备
v4l2_subdev_init(&sensor_subdev, &sensor_subdev_ops);
sensor_subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sensor_subdev.ctrl_handler = &sensor_ctrl_handler;
sensor_subdev.host_priv = sensor_priv;  // 指向私有数据

// 注册到V4L2框架
media_entity_pads_init(&sensor_subdev.entity, 1, &sensor_pad);
v4l2_async_register_subdev(&sensor_subdev);
关键点: v4l2_subdev 的 ops 中必须实现 core.s_power、video.s_stream、pad.set_fmt 等回调,这些是ISP调优时控制Sensor工作的入口。
struct v4l2_subdev 在驱动中的位置 应用层 / ISP V4L2 框架 struct v4l2_subdev 私有数据 (host_priv) Sensor 硬件 ops 回调:s_power s_stream / set_fmt

4.2 struct rkmodule_inf:RK平台模块信息扩展

struct rkmodule_inf 是RK平台在V4L2标准之上定义的私有扩展结构,用于传递Sensor模块的硬件特性、调优参数和平台特定配置。它通常嵌入在Sensor驱动的私有数据中,通过 host_priv 访问。

struct rkmodule_inf {
    struct module_otp_info otp_info;      // OTP校准信息
    struct module_cis_info cis_info;      // CIS模组信息
    struct module_gpio_info gpio_info;    // GPIO控制信息
    struct module_awb_info awb_info;      // AWB增益校准
    struct module_lsc_info lsc_info;      // 镜头阴影校正
    struct module_af_info af_info;        // 自动对焦信息
    struct module_pdaf_info pdaf_info;    // 相位对焦信息
    u32 module_index;                     // 模组索引
    u32 sensor_index;                     // Sensor索引
    u32 flip;                             // 镜像翻转标志
};
子结构 主要字段 调优用途
module_otp_info otp_valid, golden_value, module_id 读取OTP校准数据,修正增益偏差
module_cis_info sensor_name, i2c_addr, mclk 标识Sensor型号与时钟配置
module_gpio_info pwdn_gpio, reset_gpio, power_gpio 电源与复位时序控制
module_awb_info r_gain, gr_gain, gb_gain, b_gain 白平衡增益校准值
module_lsc_info lsc_table, lsc_size 镜头阴影校正表
注意事项: rkmodule_inf 中的数据通常来自模组OTP或设备树配置。在驱动初始化阶段必须正确解析并填充,否则ISP调优时无法获取准确的校准参数,导致图像偏色或亮度不均。
struct rkmodule_inf 数据流向 OTP / 设备树 驱动初始化 struct rkmodule_inf otp / cis / awb / lsc ISP 调优 3A 算法 图像后处理

4.3 struct rk_sensor_reg:寄存器操作原子单元

struct rk_sensor_reg 是Sensor驱动中最基础的寄存器操作结构,用于描述一条I2C写操作。它被广泛应用于初始化序列、模式切换、增益/曝光设置等场景。

struct rk_sensor_reg {
    u16 reg_addr;   // 寄存器地址(16位)
    u16 reg_val;    // 寄存器值(16位)
    u8  reg_len;    // 地址长度:1字节或2字节
    u8  val_len;    // 值长度:1字节或2字节
    u8  delay;      // 写完后延时(ms)
};
字段 取值范围 说明
reg_addr 0x0000 ~ 0xFFFF Sensor内部寄存器地址
reg_val 0x00 ~ 0xFFFF 要写入的值
reg_len 1 或 2 地址字节数,常见8位Sensor用1,16位用2
val_len 1 或 2 值字节数,8位寄存器用1,16位用2
delay 0 ~ 100 写入后等待时间,用于时序敏感寄存器

驱动中通常以数组形式定义初始化序列,并通过工具函数批量写入:

// 初始化序列示例(IMX415部分寄存器)
static const struct rk_sensor_reg imx415_init_regs[] = {
    {0x3000, 0x00, 2, 1, 0},   // 软件复位
    {0x3002, 0x00, 2, 1, 10},  // 复位后等待10ms
    {0x3010, 0x01, 2, 1, 0},   // 设置输出模式
    {0x3020, 0x33, 2, 1, 0},   // PLL配置
    {0x3030, 0x10, 2, 1, 0},   // 帧长设置高位
    {0x3031, 0xE0, 2, 1, 0},   // 帧长设置低位
    {0x3040, 0x05, 2, 1, 0},   // 曝光设置
    {RK_SENSOR_REG_END, 0x00, 0, 0, 0}  // 结束标记
};

// 批量写入函数
int rk_sensor_write_regs(struct i2c_client *client,
                         const struct rk_sensor_reg *regs) {
    int ret = 0;
    while (regs->reg_addr != RK_SENSOR_REG_END) {
        ret = rk_sensor_write_reg(client, regs->reg_addr,
                                  regs->reg_val, regs->reg_len,
                                  regs->val_len);
        if (ret)
            break;
        if (regs->delay)
            msleep(regs->delay);
        regs++;
    }
    return ret;
}
实践要点: 在ISP调优过程中,曝光和增益的实时调整就是通过构造 struct rk_sensor_reg 数组并调用写入函数实现的。注意 delay 字段在切换帧率或模式时至关重要,过短的延时可能导致寄存器写入失败。

4.4 struct rk_sensor_mode:Sensor工作模式描述

struct rk_sensor_mode 定义了Sensor的完整工作模式,包括分辨率、帧率、输出格式、时钟配置等。每个模式对应一组寄存器序列,驱动根据应用需求切换不同模式。

struct rk_sensor_mode {
    u32 width;                          // 图像宽度(像素)
    u32 height;                         // 图像高度(像素)
    u32 max_fps;                        // 最大帧率(fps * 1000)
    u32 hts_def;                        // 默认水平总像素
    u32 vts_def;                        // 默认垂直总像素
    u32 mipi_freq;                      // MIPI时钟频率(MHz)
    u32 bpp;                            // 位深(10/12/14)
    u32 bus_type;                       // 总线类型:MIPI/DVP
    u32 lane_num;                       // MIPI通道数
    const struct rk_sensor_reg *regs;   // 模式对应的寄存器序列
    const char *desc;                   // 模式描述
};
字段 示例值 调优关联
width / height 3840 x 2160 决定ISP输入尺寸和裁剪窗口
max_fps 30000(30fps) 影响曝光时间和帧间隔
hts_def / vts_def 4400 / 2250 计算实际帧率和曝光行数
mipi_freq 800 MIPI PHY配置,影响带宽
bpp 10 RAW数据位深,ISP处理精度
regs 寄存器数组指针 模式切换时写入的寄存器序列
// 模式定义示例
static const struct rk_sensor_mode imx415_modes[] = {
    {
        .width = 3840,
        .height = 2160,
        .max_fps = 30000,
        .hts_def = 4400,
        .vts_def = 2250,
        .mipi_freq = 800,
        .bpp = 10,
        .bus_type = RK_SENSOR_BUS_MIPI,
        .lane_num = 4,
        .regs = imx415_4k_regs,
        .desc = "3840x2160 30fps 10bit",
    },
    {
        .width = 1920,
        .height = 1080,
        .max_fps = 60000,
        .hts_def = 2200,
        .vts_def = 1125,
        .mipi_freq = 800,
        .bpp = 10,
        .bus_type = RK_SENSOR_BUS_MIPI,
        .lane_num = 4,
        .regs = imx415_1080p_regs,
        .desc = "1920x1080 60fps 10bit",
    },
};
调优技巧: 在ISP调优时,hts_def 和 vts_def 直接影响曝光行数的计算。如果发现实际帧率与预期不符,应优先检查这两个值是否与Sensor datasheet一致。另外,bpp 必须与ISP的RAW格式配置匹配,否则会出现数据错位。

4.5 四个数据结构的协作关系

在RK平台Sensor驱动中,这四个结构体形成清晰的层次化协作关系:

  1. 框架层: struct v4l2_subdev 作为V4L2标准接口,负责与上层ISP和应用程序通信。
  2. 扩展层: struct rkmodule_inf 通过 host_priv 挂载到 v4l2_subdev,提供RK平台特有的模组信息。
  3. 配置层: struct rk_sensor_mode 定义Sensor的工作模式,包含分辨率、帧率等参数。
  4. 操作层: struct rk_sensor_reg 是寄存器操作的最小单元,被模式切换和实时控制调用。
四个核心数据结构的协作架构 struct v4l2_subdev(框架层) struct rkmodule_inf(扩展层) struct rk_sensor_mode(配置层) struct rk_sensor_reg(操作层) V4L2标准接口 ops / ctrl_handler 模组OTP/校准信息 AWB/LSC/GPIO 分辨率/帧率/格式 MIPI配置 I2C寄存器写入 地址/值/延时
总结: 掌握这四个数据结构,就掌握了RK平台Sensor驱动的骨架。v4l2_subdev 是门面,rkmodule_inf 是身份证,rk_sensor_mode 是工作证,rk_sensor_reg 是执行者。在后续的ISP调优实战中,我们将反复操作这些结构体,实现从驱动到图像的完整链路。