Camera Driver - 全网最详细Nvidia Camera Kernel Driver V2.0详解

需要做哪些工作

要实现一个新的MIPI Sensor的驱动,我们需要实现如下图中红框的两个部分:
1 - DTS 
2 - V4L2 device driver 
 

如何做

我们依旧以官方文档中的imx185为例, 主要是如下2个文件的实现:

source/nvidia-oot/drivers/media/i2c/nv_imx185.c
source/nvidia-oot/drivers/media/i2c/imx185_mode_tbls.h 

|-   function  list                                                                                                                                                                                          
||     imx185_get_frame_length_regs                                                                                          
||     imx185_get_coarse_time_regs_shs1                                                                                                                  
||     imx185_get_coarse_time_regs_shs2                                                                                                                                                                
||     imx185_get_gain_reg                                                                                                                                  
||     imx185_read_reg                                                                                                                                                                     
||     imx185_write_reg                 
||     imx185_write_table                                                                                                                                                   
||     imx185_set_group_hold                                                                                                                                      
||     imx185_set_gain                                                                                                                               
||     imx185_set_coarse_time                                                                                                    
||     imx185_set_coarse_time_hdr                                                                                                                         
||     imx185_set_frame_rate                                                                                                                                                   
||     imx185_set_exposure                                                                                                                                              
||     imx185_fill_string_ctrl                                                                                                                                                                
||     imx185_power_on                                                                                                                                                                 
||     imx185_power_off                                                                                                                                                                  
||     imx185_power_get                                                                                                                                                      
||     imx185_power_put                                                                                                                                                                      
||     imx185_parse_dt                                                                                                                                                                                
||     imx185_set_mode                                                                                                                        
||     imx185_start_streaming                                                                                                                                                                             
||     imx185_stop_streaming                                                                                                                                                                 
||     imx185_fuse_id_setup                                                                                                                                                                          
||     imx185_board_setup                                                                                                                                                                          
||     imx185_open                                                                                                                                
||     imx185_probe                                                                                                                                         
||     imx185_remove

实现通用操作函数集

这些函数是对sensor的最基本控制,必须要实现 

700 static struct camera_common_sensor_ops imx185_common_ops = {
701     .numfrmfmts = ARRAY_SIZE(imx185_frmfmt),
702     .frmfmt_table = imx185_frmfmt,
703     .power_on = imx185_power_on,
704     .power_off = imx185_power_off,
705     .write_reg = imx185_write_reg,
706     .read_reg = imx185_read_reg,
707     .parse_dt = imx185_parse_dt,
708     .power_get = imx185_power_get,
709     .power_put = imx185_power_put,
710     .set_mode = imx185_set_mode,
711     .start_streaming = imx185_start_streaming,
712     .stop_streaming = imx185_stop_streaming,
713 };

实现曝光控制函数集

Jetson V4L2 相机框架目前支持的自定义 V4L2  ctrl

财产

价值

TEGRA_CAMERA_CID_GAIN

传感器增益,64 位 Q 格式值。该值为n ,比例为 1: n

例如,值 3 表示比例为 1:3,即产生 3 倍放大。

属性值对(仅限版本 2.0)gain_factor中描述的属性控制 Q 格式和控件的范围。

有关详细信息,请参阅增益控制

TEGRA_CAMERA_CID_FRAME_RATE

帧速率,以帧/秒为单位。

TEGRA_CAMERA_CID_EXPOSURE

曝光时间,以秒为单位。更多信息,请参阅曝光控制

TEGRA_CAMERA_CID_EXPOSURE_SHORT

可选。曝光时间(以秒为单位)。用于 HDR 传感器的短曝光帧。更多信息,请参阅曝光控制

TEGRA_CAMERA_CID_HDR_ENABLE

可选。布尔值;指示传感器是在 HDR 传感器模式下运行 (true) 还是在正常传感器模式下运行 (false)。

TEGRA_CAMERA_CID_EEPROM_DATA

读取模块的 EEPROM 数据。

TEGRA_CAMERA_CID_OTP_DATA

可选。读取模块的一次性可编程 (OTP) 内存数据。

TEGRA_CAMERA_CID_FUSE_ID

可选。读取传感器chip ID。

TEGRA_CAMERA_CID_GROUP_HOLD

布尔值。用于控制支持此功能的传感器的传感器组保持(寄存器保持)。

由 Jetson V4L2 相机框架提供。

TEGRA_CAMERA_CID_SENSOR_MODE_ID

可选。强制 Jetson V4L2 相机框架使用特定的传感器模式,绕过其默认模式选择逻辑。

值是从零开始的索引,即传感器设备树.dtsi 文件中指定的传感器模式索引。

TEGRA_CAMERA_CID_VI_BYPASS_MODE

布尔值。设置为 true 可绕过内核驱动程序中的 VI 设置。使用相机核心库时,默认值为 true。

由 NVIDIA V4L2 媒体控制器框架内核驱动程序提供。

TEGRA_CAMERA_CID_OVERRIDE_ENABLE

覆盖默认传感器模式表中的增益和曝光设置。

由 NVIDIA V4L2 媒体控制器框架内核驱动程序提供。

imx185实现的ctrl list

 59 static const u32 ctrl_cid_list[] = {
 60     TEGRA_CAMERA_CID_GAIN,
 61     TEGRA_CAMERA_CID_EXPOSURE,
 62     TEGRA_CAMERA_CID_FRAME_RATE,
 63     TEGRA_CAMERA_CID_FUSE_ID,
 64     TEGRA_CAMERA_CID_HDR_EN,
 65     TEGRA_CAMERA_CID_SENSOR_MODE_ID,
 66 };
 67

绑定注册V4L2 Ctrl对应的函数

464 static struct tegracam_ctrl_ops imx185_ctrl_ops = {
465     .numctrls = ARRAY_SIZE(ctrl_cid_list),
466     .ctrl_cid_list = ctrl_cid_list,
467     .string_ctrl_size = {0, IMX185_FUSE_ID_STR_SIZE},
468     .set_gain = imx185_set_gain,
469     .set_exposure = imx185_set_exposure,
470     .set_frame_rate = imx185_set_frame_rate,
471     .set_group_hold = imx185_set_group_hold,
472     .fill_string_ctrl = imx185_fill_string_ctrl,
473 };

描述Sensor的结构体

 68 struct imx185 {
 69     struct i2c_client   *i2c_client;
 70     struct v4l2_subdev  *subdev;
 71     u8 fuse_id[IMX185_FUSE_ID_SIZE];
 72     u32             frame_length;
 73     s64 last_wdr_et_val;
 74     struct camera_common_data   *s_data;
 75     struct tegracam_device      *tc_dev;
 76 };

属性

i2c_client

i2c_client句柄,用于访问传感器 I2C 客户端实例。

subdev

V4L2 子设备的句柄,用于执行子设备操作(ops)。

fuse_id

在此字符数组中保存传感器的chip ID 信息。

frame_length

保留先前的值frame_length

last_wdr_et_val

保留 WDR 模式的先前曝光时间。

s_data

指向 struct 的指针camera_common_data,该结构体保存了所有传感器驱动程序使用的信息。 camera_common.h详情请参阅。

tc_dev

指向 struct tegracam_device,Jetson V4L2 相机框架使用它来控制相机设备。tegracam_core.h详情请参阅。

probe() 关键调用栈

nv_imx185_probe()

  1. → devm_kzalloc()     //创建主结构体 imx185和tegracam_device。

  2. 初始化操作函数集,包括camera_common_sensor_ops,  v4l2_subdev_internal_ops,  tegracam_ctrl_ops。

  3. → tegracam_device_register()    //注册tegracam设备,解析dts,获取power 属性,解析port属性,解析use_sensor_mode_id,解析i2c属性,注册debugfs,获取sensor_mode,signal_props,image_props,获取sensor尺寸格式,mclk,把tc_dev添加到已注册设备链表。

  4. → imx185_board_setup    //() 初始化外设资源,设置mclk,上下电sensor,读取chip id。

  5. → tegracam_v4l2subdev_register()     //V4L2 框架注册subdev,sd初始化, i2c client初始化, 异步注册v4l2 subdev, media entity初始化。

模式列表

模式表可以引用数千个寄存器。这会增加传感器开始流式传输之前的延迟,延迟时间相当于对所有寄存器进行编程所需的时间。在极端情况下,接收引擎可能会在传感器输出第一帧之前超时。

有几种可能的方法可以纠正这个问题:

  • 减少模式表中引用的寄存器数量。您或许可以从传感器供应商处获取较小的模式表。大多数寄存器通常设置为默认值,无需更新。

  • 将寄存器按小组排列,并设置连续的寄存器地址。NVIDIA 内核驱动程序支持regmap()批量写入多达 16 个连续寄存器,这可以减少 I2C/SPI 事务的数量。请咨询传感器供应商,确保执行此操作不会影响传感器的运行。

  • 请求捕获引擎延长延迟时间,以防止超时。您可以将设备树属性添加set_mode_delay_ms到传感器.dtsi文件,以延长第一帧的等待时间。

  • 具体书写格式照葫芦画瓢即可,每种mode的寄存器值从sensor 厂商FAE处获取。

      26 static imx185_reg imx185_start[] = {
      27     {0x3000, 0x00 },
      28     {IMX185_TABLE_WAIT_MS, IMX185_WAIT_MS_START},
      29     {0x3002, 0x00},
      30     {0x3049, 0x02},
      31     {IMX185_TABLE_WAIT_MS, IMX185_WAIT_MS_STREAM},
      32     { IMX185_TABLE_END, 0x00 }
      33 };
      34
      35 static imx185_reg imx185_stop[] = {
      36     {0x3000, 0x01 },
      37     {IMX185_TABLE_WAIT_MS, IMX185_WAIT_MS_STOP},
      38     {IMX185_TABLE_END, 0x00 }
      39 };
      40
      41 static imx185_reg tp_colorbars[] = {
      42     {0x300A, 0x00},/*BLC for PG*/
      43     {0x300E, 0x00},
      44     {0x3089, 0x00},
      45     {0x308C, 0x13},
      46     /*
      47      * bit 0: PG mode enable
      48      * bit 1: Back Ground Transient:
      49      * bit [4-7]: PG mode setting, Set at 0h to Fh, suggest 1 or 5
      50      * raw12 max output FFEh
      51      */
      52     {IMX185_TABLE_WAIT_MS, IMX185_WAIT_MS_STOP},
      53     {IMX185_TABLE_END, 0x00}
      54 };
    .
    .
    .
     954 enum {
     955     IMX185_MODE_1920X1080_CROP_30FPS,
     956     IMX185_MODE_1920X1080_CROP_10BIT_30FPS,
     957     IMX185_MODE_1920X1080_CROP_60FPS,
     958     IMX185_MODE_1920X1080_CROP_10BIT_60FPS,
     959     IMX185_MODE_1920X1080_CROP_HDR_30FPS,
     960     IMX185_MODE_START_STREAM,
     961     IMX185_MODE_STOP_STREAM,
     962     IMX185_MODE_TEST_PATTERN
     963 };
     964
     965 static imx185_reg *mode_table[] = {
     966     [IMX185_MODE_1920X1080_CROP_30FPS] = imx185_1920x1080_crop_30fps,
     967     [IMX185_MODE_1920X1080_CROP_10BIT_30FPS] =
     968         imx185_1920x1080_crop_10bit_30fps,
     969     [IMX185_MODE_1920X1080_CROP_60FPS] = imx185_1920x1080_crop_60fps,
     970     [IMX185_MODE_1920X1080_CROP_10BIT_60FPS] =
     971         imx185_1920x1080_crop_10bit_60fps,
     972     [IMX185_MODE_1920X1080_CROP_HDR_30FPS] =
     973         imx185_1920x1080_hdr_crop_30fps,
     974     [IMX185_MODE_START_STREAM] = imx185_start,
     975     [IMX185_MODE_STOP_STREAM] = imx185_stop,
     976     [IMX185_MODE_TEST_PATTERN] = tp_colorbars,
     977 };
     987 /*
     988  * WARNING: frmfmt ordering need to match mode definition in
     989  * device tree!
     990  */
     991 static const struct camera_common_frmfmt imx185_frmfmt[] = {
     992     {{1920, 1080}, imx185_30fps, 1, 0,
     993             IMX185_MODE_1920X1080_CROP_30FPS},
     994     {{1920, 1080}, imx185_30fps, 1, 0,
     995             IMX185_MODE_1920X1080_CROP_10BIT_30FPS},
     996     {{1920, 1080}, imx185_60fps, 1, 0,
     997             IMX185_MODE_1920X1080_CROP_60FPS},
     998     {{1920, 1080}, imx185_60fps, 1, 0,
     999             IMX185_MODE_1920X1080_CROP_10BIT_60FPS},
    1000     {{1920, 1080}, imx185_30fps, 1, 1,
    1001             IMX185_MODE_1920X1080_CROP_HDR_30FPS},
    1002     /* Add modes with no device tree support after below */
    1003 };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值