DM6467linux下视频采集芯片驱动的分析


主要做一些笔记,不对的地方请批评指正。
对芯片驱动的编写主要是根据vid_decoder_if.h提供的接口进行编程。
主要是对结构体decoder_device的实现,decoder_device 结构体封装了具体的实现方法。

/* decoder device structure */
struct decoder_device {
/* Name of the decoder device */
u8 name[DECODER_MAX_NAME];

/* Decoder interface type i.e. BT656 */
vid_capture_interface_type if_type;

/* Id of the channel to which decoder is connected */
int channel_id;

/* decoder capabilities */
u32 capabilities;

/* Pointer to initialize function to initialize decoder */
int (*initialize) (void *dec, int flag);

/* Set of functions pointers for standard related functions */
struct standard_ops *std_ops;

/* Set of functions pointers for control related functions */
struct control_ops *ctrl_ops;


/* Set of functions pointers for input related functions */
struct input_ops *input_ops;

/* Set of functions pointers for format related functions */
struct format_ops *fmt_ops;

/* Set of functions  pointers for device specific configs */
struct param_ops *params_ops;

/* Pointer to deinitialize function */
int (*deinitialize) (void *dec);

/* This function will be called whenever the sliced vbi data has to be get from the decoder */
int (*read_vbi_data) (struct v4l2_sliced_vbi_data *data, void *dec);


/* This function will be called whenver all the sliced vbi services needs to be get from the decoder */
int (*get_sliced_vbi_cap) (struct v4l2_sliced_vbi_cap *cap, void *dec);

        int  (*get_video_sync_status)(void *dec);




};


最后还提供接口向V4L2注册以及反注册
/* Function to register decoder to the VPIF-V4L2 layer */
int vpif_register_decoder(struct decoder_device *decoder);


/* Function to un-register decoder to the VPIF-V4L2 layer */
int vpif_unregister_decoder(struct decoder_device *decoder);


例如在sii9013中decoder_device的实例为:


 468 static struct decoder_device sii9013_dev[SII9013_NUM_CHANNELS] = {
 469         {
 470          .name = "SII9013",          
 471          .if_type = INTERFACE_TYPE_BT1120, 
 472          .channel_id = 0,
 473          .capabilities = 0,
 474          .initialize = sii9013_initialize,
 475          .std_ops = &standards_ops,  
 476          .ctrl_ops = &controls_ops,  
 477          .input_ops = &inputs_ops,
 478          .fmt_ops = NULL,
 479          .params_ops = &params_ops,
 480          .deinitialize = sii9013_deinitialize,
 481          .get_video_sync_status = sii9013_video_sync_status}
 482 };
 
 在9013中实现了一下几个操作方式:
 445 static struct param_ops params_ops = {
 446         .setparams = sii9013_setparams,
 447         .getparams = sii9013_getparams
 448 };
 
 
 sii9013_setparams 主要是从用户空间获取用户传递过来的参数进行设置,
 同时也调用sii9013_setinput和sii9013_setstd,
 在sii9013_setinput中主要是设置视频格式参数的索引。
 sii9013_setstd根据v4l2_std_id来获取相应的结构standard,
 最后sii9013_setstd根据standard调用sii9013_set_vid_reg来设置相关的寄存器。   
 sii9013_getparams主要是想用户空间传递相关的参数。
 
 449 static struct control_ops controls_ops = {
 450         .count = SII9013_MAX_NO_CONTROLS,
 451         .queryctrl = sii9013_querycontrol,
 452         .setcontrol = sii9013_setcontrol,
 453         .getcontrol = sii9013_getcontrol
 454 };
 
 control_ops 这个结构体在9013中只打印一些信息,没有什么作用,相当于空。
 
 455 static struct input_ops inputs_ops = {
 456         .count = SII9013_MAX_NO_INPUTS,
 457         .enuminput = sii9013_enuminput,
 458         .setinput = sii9013_setinput,
 459         .getinput = sii9013_getinput
 460 };
 
 sii9013_enuminput 将获取输入信息,将信息copy 到v4l2_input。
 sii9013_setinput中主要是设置视频格式参数的索引。
 sii9013_getinput是获取视频格式参数的索引。
 
  461 static struct standard_ops standards_ops = {
 462         .count = SII9013_MAX_NO_STANDARDS,
 463         .enumstd = sii9013_enumstd,
 464         .setstd = sii9013_setstd,
 465         .getstd = sii9013_getstd,
 466         .querystd = sii9013_querystd,
 467 };
 sii9013_enumstd 获取输入的格式信息,并将信息复制到v4l2_standard;
 sii9013_setstd根据v4l2_std_id来获取相应的结构standard,
 最后sii9013_setstd根据standard调用sii9013_set_vid_reg来设置相关的寄存器。
 sii9013_getstd 设置v4l2_std_id。
 sii9013_querystd 读取sii9013 10个输入寄存器,然后 sii9013_analysestd通过读取得到的寄存器的值进行判断是哪一种格式。
 
 最后在初始化9013的时候调用davincihd_capture.c 提供的vpif_register_decoder接口注册采集驱动设备。
 1901 static int sii9013_i2c_init(void)
1902 {
1903     int err = 0;
1904     int i = 0, j = 0;
1905 
1906     /* Take instance of driver */
1907     struct i2c_driver *driver;
1908         
1909     i2c_add_driver(&i2c_driver_sii9013_second);
1910         
1911     for (i = 0; i < SII9013_NUM_CHANNELS; i++) {
1912         driver = &sii9013_channel_info[i].i2c_dev.driver;
1913 
1914         driver->driver.name = "sii9013";
1915         driver->id = I2C_DRIVERID_MISC;
1916         
1917         driver->attach_adapter = sii9013_i2c_probe_adapter;
1918         driver->detach_client = sii9013_i2c_detach_client;
1919 
1920         err = vpif_register_decoder(&sii9013_dev[i]);
1921         if (err < 0) {
1922             for (j = i - 1; j > 0; j--) {
1923                 vpif_unregister_decoder(&sii9013_dev[j]);
1924             }
1925             return err;
1926         }
1927     }    
1928     return err;
1929 }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值