3. 启用HDR传感器模式

任务目标

在Qualcomm Camera平台(如SM8550/SM8650)上,通过Camera Sensor驱动使能HDR传感器模式(如Staggered HDR或DCG HDR),并验证动态范围扩展效果。本案例聚焦于传感器驱动层HDR模式的正确配置与使能路径,不涉及ISP端多帧融合或ToneMapping调优。

必要环境/依赖

  • 高通平台Camera内核驱动源码树(kernel/msm-camera)
  • 目标平台:SM8550(或兼容平台),Linux内核版本 5.15+
  • 传感器:支持HDR模式的RAW sensor(如Sony IMX890、Samsung GN2等,本案例以IMX890为例)
  • 验证工具:camx用户空间测试程序或camera daemon日志

核心实现

传感器HDR模式使能的关键路径位于内核驱动中:sensor_init阶段通过sensor_lib结构体中的sensor_hdr_mode字段配置HDR类型,并在stream on时通过I2C写入对应寄存器序列。以下代码展示在IMX890驱动中使能Staggered HDR模式的最小完整实现:

// imx890_hdr_enable.c — 在既有IMX890驱动文件中添加HDR模式支持
#include "msm_sensor.h"

// HDR模式寄存器配置序列(Staggered HDR,2曝光)
static struct msm_camera_i2c_reg_conf imx890_hdr_regs[] = {
    {0x0100, 0x00, 0x00}, // 关闭streaming
    {0x0B00, 0x00, 0x00}, // 选择grouped hold模式
    {0x0B05, 0x01, 0x00}, // 使能grouped hold
    {0x0B06, 0x00, 0x00}, // 关闭HDR(先复位)
    {0x0B01, 0x00, 0x00}, // 关闭HDR组合模式
    {0x0B02, 0x00, 0x00}, // 关闭HDR曝光模式
    {0x0B03, 0x00, 0x00}, // 关闭HDR增益模式
    {0x0B04, 0x00, 0x00}, // 关闭HDR数字增益
    {0x0B06, 0x01, 0x00}, // 使能HDR(Staggered)
    {0x0B01, 0x01, 0x00}, // 使能HDR组合模式(2帧合成)
    {0x0B02, 0x01, 0x00}, // 使能HDR曝光模式(长短曝光)
    {0x0B03, 0x01, 0x00}, // 使能HDR增益模式(独立增益)
    {0x0B04, 0x01, 0x00}, // 使能HDR数字增益
    {0x0100, 0x01, 0x00}, // 重新开启streaming
};

static int imx890_hdr_enable(struct msm_sensor_ctrl_t *s_ctrl, int enable)
{
    int rc = 0;
    struct msm_camera_i2c_conf_array *conf;
    uint32_t size;

    if (enable) {
        conf = s_ctrl->sensor_i2c_conf;
        size = ARRAY_SIZE(imx890_hdr_regs);
        rc = msm_camera_i2c_write_conf_array(
            s_ctrl->sensor_i2c_client, imx890_hdr_regs, size,
            MSM_CAMERA_I2C_BYTE_DATA);
        if (rc < 0) {
            pr_err("%s: HDR enable failed\n", __func__);
            return rc;
        }
        s_ctrl->sensor_hdr_mode = SENSOR_HDR_STAGGER;
    } else {
        // 关闭HDR,恢复线性模式
        u8 linear_regs[] = {0x0B06, 0x00, 0x0B01, 0x00};
        rc = msm_camera_i2c_write_conf_array(
            s_ctrl->sensor_i2c_client, linear_regs, 2,
            MSM_CAMERA_I2C_BYTE_DATA);
        s_ctrl->sensor_hdr_mode = SENSOR_HDR_NONE;
    }
    return rc;
}

// 在sensor_init中注册HDR模式支持
static int imx890_sensor_init(struct msm_sensor_ctrl_t *s_ctrl)
{
    // ... 既有初始化代码 ...
    s_ctrl->sensor_hdr_support = true;
    s_ctrl->sensor_hdr_mode = SENSOR_HDR_NONE; // 默认关闭
    s_ctrl->func_tbl->sensor_hdr_enable = imx890_hdr_enable;
    return 0;
}

驱动集成与编译

// 在imx890驱动probe函数中调用sensor_init后,添加HDR能力注册
static int imx890_probe(struct platform_device *pdev)
{
    // ... 既有probe代码 ...
    s_ctrl->sensor_hdr_support = true;
    s_ctrl->sensor_hdr_modes = SENSOR_HDR_STAGGER | SENSOR_HDR_NONE;
    return 0;
}

// 编译命令(内核源码树根目录)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- msm-camera/msm_sensor.o

用户空间使能与验证

// 通过camx测试程序使能HDR模式
camx_test --sensor-id 0 --hdr-mode stagger --mode 0

// 检查驱动日志确认HDR已使能
dmesg | grep -i "hdr\|imx890"
// 预期输出(示例,非实测):
// [ 1234.567] imx890: HDR enable success, mode=stagger

验证方法与判定标准

  1. 寄存器验证:通过I2C读取工具(如i2cget)确认0x0B06寄存器值为0x01,0x0B01值为0x01,表明HDR模式已激活。
  2. 动态范围测试:使用标准动态范围测试卡(如ISO 15739测试图),在相同曝光条件下分别拍摄HDR关闭与开启的图像,对比最亮区域(>1000 lux)与最暗区域(<1 lux)的细节保留情况。HDR开启时,高光区域过曝像素比例应降低至少30%(相对HDR关闭状态)。
  3. 帧率确认:Staggered HDR模式下,帧率应降至线性模式的1/2(因2帧合成),通过camx_test --dump-stats确认实际输出帧率符合预期。
  4. 日志确认:内核日志中出现HDR enable success且无I2C错误,用户空间camx日志显示hdr_mode=stagger。

常见问题

  • HDR使能后图像异常:检查ISP端是否配置了对应的HDR合成模式,传感器HDR与ISP处理必须匹配。
  • I2C写入失败:确认传感器供电时序正确,且寄存器地址与数据位宽(本案例为8位)匹配。
  • 帧率未减半:确认传感器实际工作在Staggered模式而非DCG模式,检查0x0B06寄存器值是否为0x01(Staggered)而非0x02(DCG)。