linux v4l2 驱动框架,一个基于v4l2框架的输出驱动分析

地址:linux-2.6.19\drivers\media\video\mxc\output\Mx27_v4l2_output.c

三个结构分析,mxc_v4l2out_fops 向上层注册其操作,但其上层不是操作系统而是v4l2

static struct file_operations mxc_v4l2out_fops = {

.owner = THIS_MODULE,

.open = mxc_v4l2out_open,

.release = mxc_v4l2out_close,

.ioctl = mxc_v4l2out_ioctl,

.mmap = mxc_v4l2out_mmap,

.poll = mxc_v4l2out_poll,

};

设备结构有两个, 因为即使平台设备,又是v4l2设备,,,分别想两个地方注册。

static struct video_device mxc_v4l2out_template = {//v4l2设备

.owner = THIS_MODULE,

.name = "MXC Video Output",

.type = 0,

.type2 = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING,

.hardware = 39,

.fops = &mxc_v4l2out_fops,

.release = video_device_release,

};

static struct platform_device mxc_v4l2out_device = {//平台设备

.name = "MXC Video Output",

.dev = {

.release = camera_platform_release,

},

.id = 0,

};

平台驱动:

static struct platform_driver mxc_v4l2out_driver = {

.driver = {

.name = "MXC Video Output",

.owner = THIS_MODULE,

.bus = &platform_bus_type,

},

.probe = mxc_v4l2out_probe,

.remove = NULL,

};

mxc_v4l2out_init-》platform_driver_register(&mxc_v4l2out_driver);注册平台设备,注册成功有主要就是调用驱动的prode...这里就是mxc_v4l2out_probe

结构体:

/*!

* common v4l2 driver structure.

*/

typedef struct _vout_data {

struct video_device *video_dev;

/*!

* semaphore guard against SMP multithreading

*/

struct semaphore busy_lock;

/*!

* number of process that have device open

*/

int open_count;

v4l_tear_protect tear_protection;

/*!

* params lock for this camera

*/

struct semaphore param_lock;

struct timer_list output_timer;

unsigned long start_jiffies;

u32 frame_count;

v4l_queue ready_q;

v4l_queue done_q;

s8 next_rdy_ipu_buf;

s8 next_done_ipu_buf;

s8 ipu_buf[2];

volatile v4lout_state state;

int cur_disp_output;

int output_fb_num[MXC_V4L2_OUT_NUM_OUTPUTS];

int output_enabled[MXC_V4L2_OUT_NUM_OUTPUTS];

struct v4l2_framebuffer v4l2_fb;

ipu_channel_t display_ch;

ipu_channel_t post_proc_ch;

/*!

* FRAME_NUM-buffering, so we need a array

*/

int buffer_cnt;

dma_addr_t queue_buf_paddr[MAX_FRAME_NUM];

void *queue_buf_vaddr[MAX_FRAME_NUM];

u32 queue_buf_size;

struct v4l2_buffer v4l2_bufs[MAX_FRAME_NUM];

u32 sdc_fg_buf_size;

dma_addr_t display_bufs[2];

void *display_bufs_vaddr[2];

dma_addr_t rot_pp_bufs[2];

void *rot_pp_bufs_vaddr[2];

u32 rot_pp_buf_size;

/*!

* Poll wait queue

*/

wait_queue_head_t v4l_bufq;

/*!

* v4l2 format

*/

struct v4l2_format v2f;

struct v4l2_mxc_offset offset;

ipu_rotate_mode_t rotate;

/* crop */

struct v4l2_rect crop_bounds[MXC_V4L2_OUT_NUM_OUTPUTS];

struct v4l2_rect crop_current;

}

vout_data;mxc_v4l2out_probe中有*(vout->video_dev) = mxc_v4l2out_template把v4l2设备付给 * common v4l2 driver structure.中的video_dev成员

video_register_device向v4l2注册设备。。。分析其代码:

内核中注释:

video_register_device - register video4linux devices

* @vfd: video device structure we want to register

* @type: type of device to register

* @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...

* -1 == first free)

*

v4l2设备分四种不通的类型:video ,vtx,vbi,radio分别有占不同的

static struct video_device *video_device[VIDEO_NUM_DEVICES];全局的vide_device结构,静态在本文件有效

其中分配一个指针,,指向注册的设备,这样设备就注册成功了(videodev.c)

回到prode中video_set_drvdata(vout->video_dev, vout);继续吧驱动放到dev->priv中。

接下来分析驱动是如何被调用的:

在videodev.c中,videodev_init-》register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)向操作系统注册了fops..所以,只要是#define VIDEO_MAJOR 81,,都要由这个ops来调用,,其中子设备就是通过video_register_device来向该高层注册的

分析ops中的video_open:

file->f_op = fops_get(vfl->fops);

if(file->f_op->open)

err = file->f_op->open(inode,file);

把子设备相应的fops付给file->f_op,这样在read,write时候就会调用子设备的read,wrtie了。接下来就是调用子设备的open

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值