3. RK平台Sensor驱动框架:模板、设备树与注册流程

在瑞芯微RK平台上开发Camera Sensor驱动,核心是理解官方提供的驱动模板、设备树(Device Tree)配置以及Platform Driver的注册机制。本章将拆解这三部分,帮助开发者快速搭建标准化的Sensor驱动框架。

3.1 RK提供的Sensor驱动模板结构

RK平台为Sensor驱动提供了标准模板,通常位于内核源码 drivers/media/i2c/ 目录下,文件名如 ov5645.c 或 imx258.c。模板采用分层设计,主要包含以下核心模块:

模块/文件 功能描述 关键函数/结构体
驱动入口 定义platform_driver结构体,完成注册与注销 module_platform_driver()
设备树匹配 通过of_match_table匹配dts节点 of_match_table, sensor_of_match[]
上电序列 控制Sensor的电源、时钟、复位时序 sensor_power_on(), sensor_power_off()
初始化序列 通过I2C写入寄存器数组,配置Sensor工作模式 sensor_init(), regval_table[]
V4L2子设备 实现v4l2_subdev_ops,提供视频操作接口 sensor_subdev_ops, sensor_video_ops
媒体控制器 定义实体、pad、链接,用于pipeline管理 media_entity, media_pad
模板核心思想: 驱动开发者只需填充寄存器表、电源控制函数和V4L2回调,即可完成一个标准Sensor驱动的移植,无需重复编写框架代码。

3.2 设备树(dts)配置详解

设备树是RK平台硬件描述的核心,Sensor节点通常挂载在I2C总线下。以下是一个典型的Sensor dts配置示例:

// rk3588-evb.dts 或 board.dtsi
&i2c4 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&i2c4m2_xfer>;

    ov5645: ov5645@3c {
        compatible = "ovti,ov5645";
        reg = <0x3c>;
        clocks = <&cru CLK_MIPI_CAMARAOUT_M4>;
        clock-names = "xvclk";
        power-domains = <&power RK3588_PD_VI>;

        // 电源控制
        avdd-supply = <&vcc_1v8>;
        dvdd-supply = <&vcc_1v2>;
        dovdd-supply = <&vcc_1v8>;

        // 复位与电源引脚
        reset-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>;
        pwdn-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>;

        // 旋转与镜像
        rotation = <90>;
        orientation = <0>;

        // 物理信息
        rockchip,camera-module-index = <0>;
        rockchip,camera-module-facing = "back";
        rockchip,camera-module-name = "YT-OV5645";
        rockchip,camera-module-lens-name = "Largan-50013A1";

        port {
            ov5645_out: endpoint {
                remote-endpoint = <&mipi_in_ucam0>;
                data-lanes = <1 2>;
            };
        };
    };
};
配置要点: data-lanes 必须与Sensor输出能力匹配(如1-lane、2-lane或4-lane);rotation 和 orientation 影响ISP的预处理方向,错误配置会导致图像颠倒。

dts中关键属性的作用对照表:

属性 类型 说明
compatible 字符串 驱动匹配的关键字,必须与驱动中 of_match_table 一致
reg u32 Sensor的I2C从设备地址(7位)
clocks phandle Sensor主时钟(xvclk)的时钟源
avdd/dvdd/dovdd-supply phandle 模拟/数字/IO电源的regulator句柄
reset-gpios gpio 复位引脚,低电平有效
pwdn-gpios gpio 掉电引脚,高电平进入掉电模式
data-lanes 数组 MIPI CSI使用的数据通道编号

3.3 Platform Driver注册流程

RK平台的Sensor驱动基于 platform_driver 框架,注册流程分为以下步骤:

  1. 定义platform_driver结构体:填充 .probe、.remove、.driver.of_match_table 等成员。
  2. 调用module_platform_driver宏:在模块初始化/退出时自动完成注册与注销。
  3. probe函数执行:解析dts、获取资源、初始化I2C、注册V4L2子设备。
  4. 注册v4l2_subdev:将Sensor设备注册到V4L2框架,供ISP或应用层调用。
  5. 注册media_entity:建立媒体拓扑,定义输入输出pad。

以下是一个简化的probe函数流程代码:

static int sensor_probe(struct platform_device *pdev)
{
    struct sensor_dev *sensor;
    struct i2c_client *client;
    int ret;

    // 1. 分配私有数据结构
    sensor = devm_kzalloc(&pdev->dev, sizeof(*sensor), GFP_KERNEL);
    if (!sensor)
        return -ENOMEM;

    // 2. 获取I2C client(从dts解析)
    client = to_i2c_client(pdev->dev.parent);
    sensor->client = client;

    // 3. 解析dts属性(电源、时钟、GPIO等)
    ret = sensor_parse_dt(sensor);
    if (ret)
        return ret;

    // 4. 上电并初始化Sensor
    ret = sensor_power_on(sensor);
    if (ret)
        return ret;

    ret = sensor_init(sensor);
    if (ret)
        goto power_off;

    // 5. 注册V4L2子设备
    v4l2_i2c_subdev_init(&sensor->sd, client, &sensor_subdev_ops);
    sensor->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

    // 6. 注册媒体实体
    sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
    sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
    ret = media_entity_pads_init(&sensor->sd.entity, 1, &sensor->pad);
    if (ret)
        goto power_off;

    dev_info(&pdev->dev, "Sensor probe success\n");
    return 0;

power_off:
    sensor_power_off(sensor);
    return ret;
}
常见错误: 在probe中未正确释放电源或时钟资源,会导致系统挂起或Sensor无法再次上电。务必在错误路径中调用 sensor_power_off()。

3.4 驱动框架整体架构图

下图展示了从设备树到V4L2子设备的完整驱动框架流程:

RK Sensor驱动框架架构图 RK Sensor驱动框架架构图 设备树 (dts) platform_driver probe() 函数 of_match 调用 probe() 内部流程 解析dts属性 获取电源/时钟 上电 & 初始化 注册V4L2子设备 v4l2_subdev 注册完成 说明:整个流程从dts解析开始,经过platform_driver匹配,最终在probe中完成Sensor初始化并注册到V4L2框架。

3.5 关键数据结构与回调

驱动模板中必须实现的核心数据结构包括:

  • struct v4l2_subdev_ops:包含 .core、.video、.pad 等操作集。
  • struct v4l2_subdev_video_ops:实现 s_stream()(启动/停止流)、g_frame_interval() 等。
  • struct v4l2_subdev_pad_ops:实现 set_fmt()、get_fmt()、enum_mbus_code() 等。
  • struct media_entity_operations:定义 link_validate() 回调,用于pipeline链路验证。
性能调优提示: 在 s_stream(1) 中尽量减少I2C写入次数,可将多个寄存器配置合并为批量写入(如使用 regmap_multi_reg_write()),显著缩短启动延迟。

通过以上模板、dts配置和注册流程,开发者可以快速在RK平台上适配新的Camera Sensor,并为后续的ISP调优和性能优化打下坚实基础。