Chinaunix首页 | 论坛 | 博客
  • 博客访问: 193517
  • 博文数量: 40
  • 博客积分: 1031
  • 博客等级: 少尉
  • 技术积分: 321
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-18 11:35
文章分类
文章存档

2022年(1)

2020年(1)

2017年(1)

2016年(5)

2015年(1)

2013年(1)

2011年(13)

2010年(16)

2009年(1)

我的朋友

分类: LINUX

2010-12-22 00:19:07

地址: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
阅读(2559) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~