rk camera驱动调试学习学习。

1驱动调试准备工作

需要对ISP2.0的数据流流程图有大致的了解。

ISP从sensor端获取数据流之后,通过3A处理,最后由ISPP输出四路数据流给到用户。

另外,调试驱动之前需要准备以下资料

2驱动数据结构类型简要介绍

2.1CIS设备注册(DTS)

以rv1126 isp和os04a10举例说明,开始为ircut(红外滤光片切换器 ),如果没有这个可以不加

2.1.1ircut(红外滤光片切换器 )注册

2.1.2sensor注册

sensor相关配置,主频配置电源配置

包括其中的3路电源,由datasheet配置

模组和lens名构成了后续isp的IQ名,sensor只有一个端口连接mipi dphy

2.1.3csi_phy注册

这里由2个端口,端口0跟sensor端口保持一致,用来接收sensor数据;端口1跟isp端口保持一致,用来传数据给isp

端口1和isp相连

2.1.4isp注册

isp端口0接收的是mipi的端口1

端口1输出给ispp

2.1.5ispp注册

ispp端口接收isp1端口数据

2.2CIS驱动说明

Camera Sensor采用I2C与主控进行交互,目前sensor driver按照I2C设备驱动方式实现,sensor driver同时采用v4l2 subdev的方式实现与host driver之间的交互。

2.2.1数据类型简要说明-结构体i2c_driver

关于结构体i2c_driver

1struct i2c_driver {
2    ...
3    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
4    int (*remove)(struct i2c_client *)
5    ...
6    struct device_driver driver;
7    const struct i2c_device_id *id_table;
8    ...
9};

举例说明

2.2.2数据类型简要说明-结构体struct v4l2_subdev_ops

结构体如下

1struct v4l2_subdev_ops {
2    const struct v4l2_subdev_core_ops *core;
3    ...
4    const struct v4l2_subdev_video_ops *video;
5    ...
6    const struct v4l2_subdev_pad_ops *pad;
7};

具体说明

2.2.3数据类型简要说明-结构体struct v4l2_subdev_core_ops

结构体

1struct v4l2_subdev_core_ops {
2    ...
3    int (*s_power)(struct v4l2_subdev *sd, int on);
4    long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
5#ifdef CONFIG_COMPAT
6    long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd, unsigned long arg);
7#endif
8    ...
9};

示例说明

RK目前的ioctl号

2.2.4数据类型简要说明-结构体struct v4l2_subdev_video_ops

结构体说明

1struct v4l2_subdev_video_ops {
2    ...
3    int (*s_stream)(struct v4l2_subdev *sd, int enable);
4    ...
5    int (*g_frame_interval)(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *interval);
6    int (*g_mbus_config)(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg);
7};

示例说明

2.2.5数据类型简要说明-结构体struct v4l2_subdev_pad_ops

结构体说明

 1struct v4l2_subdev_pad_ops {
 2    ...
 3    int (*enum_mbus_core)(struct v4l2_subdev *sd, 
 4                          struct v4l2_subdev_pad_config *cfg,
 5                          struct v4l2_subdev_mbus_code_enum *code);
 6    int (*enum_frame_size)(struct v4l2_subdev *sd, 
 7                          struct v4l2_subdev_pad_config *cfg,
 8                          struct v4l2_subdev_frame_size_enum *fse);
 9    int (*get_fmt)(struct v4l2_subdev *sd,
10                   struct v4l2_subdev_pad_config *cfg,
11                   struct v4l2_subdev_format* format);
12    int (*set_fmt)(struct v4l2_subdev *sd,
13                   struct v4l2_subdev_pad_config *cfg,
14                   struct v4l2_subdev_format* format);
15    int (*enum_frame_interval)(struct v4l2_subdev *sd,
16                               struct v4l2_subdev_pad_config *cfg,
17                               struct v4l2_subdev_frame_interval_enum *file);
18    int (*get_selection)(struct v4l2_subdev *sd,
19                         struct v4l2_subdev_pad_config *cfg,
20                         struct v4l2_subdev_selection *sel);
21};

示例说明

2.2.5数据类型简要说明-结构体struct v4l2_ctrl_ops

结构体说明

1struct v4l2_ctrl_ops {
2    int (*s_ctrl)(struct v4l2_ctrl *ctrl);
3};

2.2.6数据类型简要说明-结构体-struct xxxx_mode

结构体说明,这个结构体在sensor驱动中常常可以见到,虽然它不是v4l2标准要求的

 1struct xxxx_mode {
 2    u32 bus_fmt;
 3    u32 width;
 4    u32 height;
 5    struct v4l2_fract max_fps;
 6    u32 hts_def;
 7    u32 vts_def;
 8    u32 exp_def;
 9    const struct regval *reg_list;
10    u32 hdr_mode;
11    u32 vc[PAD_MAX];
12};

示例说明

2.2.7数据类型简要说明-结构体-struct v4l2_mbus_framefmt

结构体说明

 1struct v4l2_mbus_framefmt {
 2    __u32 width;
 3    __u32 height;
 4    __u32 code;
 5    __u32 field;
 6    __u32 colorspace;
 7    __u16 ycbcr_enc;
 8    __u16 quantization;
 9    __u16 xfer_func;
10    __u16 reserved[11];
11};

2.2.8数据类型简要说明-结构体-struct rkmodule_base_inf

结构体说明

1struct rkmodule_base_inf{
2    char sensor[RKMODULE_NAME_LEN];
3    char module[RKMODULE_NAME_LEN];
4    char lens[RKMODULE_NAME_LEN];
5} __attribute__ ((packed));

2.2.9数据类型简要说明-结构体-struct rkmodule_fac_inf

结构体说明

1struct rkmodule_fac_inf {
2    __32 flag;
3    char module[RKMODULE_NAME_LEN];
4    char lens[RKMODULE_NAME_LEN];
5    __u32 year;
6    __u32 month;
7    __u32 day;
8} __attribute__ ((packed));

考虑到不是所有sensor都会用到OTP功能,这里不具体展开

2.2.10数据类型简要说明-结构体-struct preisp_hdrae_exp_s

结构体说明,HDR曝光参数

 1struct preisp_hdrae_exp_s {
 2    unsigned int long_exp_reg;
 3    unsigned int long_gain_reg;
 4    unsigned int middle_exp_reg;
 5    unsigned int middle_gain_reg;
 6    unsigned int short_exp_reg;
 7    unsigned int short_gain_reg;
 8    unsigned int long_exp_val;
 9    unsigned int long_gain_reg;
10    unsigned int middle_exp_val;
11    unsigned int middle_gain_val;
12    unsigned int short_exp_val;
13    unsigned int short_gain_val;
14    unsigned int long_cg_mode;
15    unsigned int middle_cg_mode;
16    unsigned int short_cg_mode;
17};

3API简要介绍

3.1xxx_set_fmt

设置sensor输出格式

语法说明

1static int xxx_set_fmt(struct v4l2_subdev *sd,
2                       struct v4l2_subdev_pad_config *cfg,
3                       struct v4l2_subdev_format *fmt);

3.2xxx_get_fmt

获取sensor输出格式

语法说明

1static int xxx_get_fmt(struct v4l2_subdev *sd,
2                       struct v4l2_subdev_pad_config *cfg,
3                       struct v4l2_subdev_format *fmt);

3.3xxx_enum_mbus_code

枚举sensor输出bus format

语法说明

1static int xxx_enum_mbus_code(struct v4l2_subdev *sd,
2                              struct v4l2_subdev_pad_config *cfg,
3                              struct v4l2_subdev_mbus_code_enum *code);

3.4xxx_enum_frame_size

枚举sensor输出大小

语法

1static int xxx_enum_frame_size(struct v4l2_subdev *sd,
2                               struct v4l2_subdev_pad_config *cfg,
3                               struct v4l2_subdev_frame_size_enum *fse);

3.5xxx_g_frame_interval

获取sensor输出fps

语法

1static int xxx_g_frame_interval(struct v4l2_subdev *sd,
2                                struct v4l2_subdev_frame_interval *fi);

3.6xxx_s_stream

设置stream输入输出

语法

1static int xxx_s_stream(struct v4l2_subdev *sd, int on);

3.7xxx_runtime_resume

sensor商店时的回调函数

语法

1static int xxx_runtime_resume(struct device *dev);

3.8xxx_runtime_suspend

sensor下电是的回调函数

语法

1static int xxx_runtime_suspend(struct device *dev);

3.9xxx_set_ctrl

设置各个control的值

语法

1static int xxx_set_ctrl(struct v4l2_ctrl *ctrl);

3.10xxx_enum_frame_interval

枚举sensor支持的帧间间隔参数

语法

1static int xxx_enum_frame_interval(struct v4l2_subdev *sd,
2                                   struct v4l2_subdev_pad_config *cfg,
3                                   struct v4l2_subdev_frame_interval_enum *fie);

3.11xxx_g_mbus_config

获取支持的总线配置,比如使用mipi时,当sensor支持多种MIPI传输模式时,可以根据Sensor当前使用的MIPI模式上传参数

语法

1static int xxx_g_mbus_config(struct v4l2_subdev *sd,
2                             struct v4l2_mbus_config *cfg);

3.12xxx_get_selection

配置剪裁参数,isp输入的宽度要求16对其,高度8对齐,对于sensor输出的分辨率不符合对齐或Sensor输出分辨率不足标准分辨率,可实现这个函数对输入isp的分辨率做剪裁。

语法

1static int xxx_get_selection(struct v4l2_subdev *sd,
2                             struct v4l2_subdev_pad_config *cfg,
3                             struct v4l2_subdev_selection *sel);

4以imx415 sensor驱动为例详解

对应如下

4.1probe函数细节

4.1.1获取模组和sensor名字

4.1.2获取MCLK

4.1.3GPIO和PINCTRL初始化

4.1.4控制上电和控制V4L2设备初始化

4.1.5media实体初始化

4.2实现3个回调函数

4.2.1结构体v4l2_subdev_core_ops

4.2.2结构体struct v4l2_subdev_video_ops

4.2.3结构体struct v4l2_subdev_pad_ops

4.2.4结构体struct v4l2_ctrl_ops

关于这里设计的公式计算

曝光相应计算公式 $$ line_time = HTS/PIXEL_PATE\
PIXEL_PATE=HTSVTSFPS\
HTS=sensor_width_out+HBLANK\
VTS=sensor_g=height_out+VBLANK\
$$