V4L2驱动框架主设备号:81次设备号:0-6364-67192-223224-255/dev/videoX应用层————————————char驱动————————————V4L2————————————具体的驱动————————————硬件应用层的操作都需要有底层V4L2驱动的支持。
内核中有一些非常完善的例子。
比如:linux-2.6.26内核目录drivers/media/video/vivi.c中的驱动代码实例。
1、V4L2驱动注册、注销函数static int__init videodev_init(void)//注册256个视频设备{.mmap=v4l2_mmap,.unlocked_ioctl=v4l2_ioctl,#ifdef CONFIG_COMPAT.compat_ioctl=v4l2_compat_ioctl32,#endif.release=v4l2_release,.poll=v4l2_poll,.llseek=no_llseek,};v4l2_read定义如下static ssize_t v4l2_read(struct file*filp,char__user*buf,size_t sz,loff_t*off) {struct video_device*vdev=video_devdata(filp);int ret=-ENODEV;if(!vdev->fops->read)return-EINVAL;if(vdev->lock&&mutex_lock_interruptible(vdev->lock))return-ERESTARTSYS;if(video_is_registered(vdev))ret=vdev->fops->read(filp,buf,sz,off);if(vdev->lock)mutex_unlock(vdev->lock);return ret;}函数内部调用的vdev->fops->read由具体的V4L2驱动实现驱动开发定义最重要的数据结构体struct video_device,/*device info*/char name[32];int vfl_type;/*'minor'is set to-1if the registration failed*/int minor;u16num;/*use bitops to set/clear/test flags*/unsigned long flags;/*attribute to differentiate multiple indices on one physical device*/int index;/*V4L2file handles*/spinlock_t fh_lock;/*Lock for all v4l2_fhs*/struct list_head fh_list;/*List of struct v4l2_fh*/int debug;/*Activates debug level*//*Video standard vars*/v4l2_std_id tvnorms;/*Supported tv norms*/v4l2_std_id current_norm;/*Current tvnorm*//*callbacks*/void(*release)(struct video_device*vdev);/*ioctl callbacks*/const struct v4l2_ioctl_ops*ioctl_ops;/*serialization lock*/struct mutex*lock;};============================================================= ===================struct v4l2_file_operations{struct module*owner;ssize_t(*read)(struct file*,char__user*,size_t,loff_t*);ssize_t(*write)(struct file*,const char__user*,size_t,loff_t*);unsigned int(*poll)(struct file*,struct poll_table_struct*);long(*ioctl)(struct file*,unsigned int,unsigned long);long(*unlocked_ioctl)(struct file*,unsigned int,unsigned long);int(*mmap)(struct file*,struct vm_area_struct*);int(*open)(struct file*);int(*release)(struct file*);};============================================================= ===================struct device{struct device*parent;struct device_private*p;struct kobject kobj;const char*init_name;/*initial name of the device*/struct device_type*type;struct mutex mutex;/*mutex to synchronize calls to its driver.*/ struct bus_type*bus;/*type of bus device is on*/struct device_driver*driver;/*which driver has allocated this device*/ void*platform_data;/*Platform specific data,device core doesn't touch it*/struct dev_pm_info power;#ifdef CONFIG_NUMAint numa_node;/*NUMA node this device is close to*/#endifu64*dma_mask;/*dma mask(if dma'able device)*/u64coherent_dma_mask;/*Like dma_mask,but foralloc_coherent mappings as not all hardware supports64bit ses for consistent allocations such descriptors.*/struct device_dma_parameters*dma_parms;struct list_head dma_pools;/*dma pools(if dma'ble)*/struct dma_coherent_mem*dma_mem;/*internal for coherent mem override*//*arch specific additions*/struct dev_archdata archdata;#ifdef CONFIG_OFstruct device_node*of_node;#endifdev_t devt;/*dev_t,creates the sysfs"dev"*/spinlock_t devres_lock;struct list_head devres_head;struct klist_node knode_class;struct class*class;const struct attribute_group**groups;/*optional groups*/void(*release)(struct device*dev);};============================================================= ===================struct cdev{struct kobject kobj;struct module*owner;const struct file_operations*ops;struct list_head list;dev_t dev;unsigned int count;};============================================================= ===================struct v4l2_device{struct device*dev;/*dev->driver_data points to this struct.Note:dev might be NULL if there is no parent device as is the case with e.g.ISA devices.*/struct list_head subdevs;/*used to keep track of the registered subdevs*/spinlock_t lock;/*lock this struct;can be used by the driver as well if this struct is embedded into a larger struct.*/char name[V4L2_DEVICE_NAME_SIZE];/*unique device name,by default the driver name+bus ID*/void(*notify)(struct v4l2_subdev*sd,unsigned int notification,void*arg);/*notify callback called by some sub-devices.*/struct v4l2_ctrl_handler*ctrl_handler;/*The control handler.May be NULL.*/struct mutex ioctl_lock;/*BKL replacement mutex.Temporary solution only.*/};================================================================================struct v4l2_ioctl_ops{/*ioctl callbacks*//*VIDIOC_QUERYCAP handler*/int(*vidioc_querycap)(struct file*file,void*fh,struct v4l2_capability*cap);/*Priority handling*/int(*vidioc_g_priority)(struct file*file,void*fh,enum v4l2_priority*p);int(*vidioc_s_priority)(struct file*file,void*fh,enum v4l2_priority p);/*VIDIOC_ENUM_FMT handlers*/int(*vidioc_enum_fmt_vid_cap)(struct file*file,void*fh,structv4l2_fmtdesc*f);int(*vidioc_enum_fmt_vid_overlay)(struct file*file,void*fh,structv4l2_fmtdesc*f);int(*vidioc_enum_fmt_vid_out)(struct file*file,void*fh,structv4l2_fmtdesc*f);int(*vidioc_enum_fmt_type_private)(struct file*file,void*fh,structv4l2_fmtdesc*f);/*VIDIOC_G_FMT handlers*/int(*vidioc_g_fmt_vid_cap)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_g_fmt_vid_overlay)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_g_fmt_vid_out)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_g_fmt_vid_out_overlay)(struct file*file,void*fh,structv4l2_format*f);int(*vidioc_g_fmt_vbi_cap)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_g_fmt_vbi_out)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_g_fmt_sliced_vbi_cap)(struct file*file,void*fh,struct v4l2_format *f);int(*vidioc_g_fmt_sliced_vbi_out)(struct file*file,void*fh,struct v4l2_format *f);int(*vidioc_g_fmt_type_private)(struct file*file,void*fh,struct v4l2_format*f);/*VIDIOC_S_FMT handlers*/int(*vidioc_s_fmt_vid_cap)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_s_fmt_vid_overlay)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_s_fmt_vid_out)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_s_fmt_vid_out_overlay)(struct file*file,void*fh,structv4l2_format*f);int(*vidioc_s_fmt_vbi_cap)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_s_fmt_vbi_out)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_s_fmt_sliced_vbi_cap)(struct file*file,void*fh,struct v4l2_format *f);int(*vidioc_s_fmt_sliced_vbi_out)(struct file*file,void*fh,struct v4l2_format *f);int(*vidioc_s_fmt_type_private)(struct file*file,void*fh,struct v4l2_format*f);/*VIDIOC_TRY_FMT handlers*/int(*vidioc_try_fmt_vid_cap)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_try_fmt_vid_overlay)(struct file*file,void*fh,struct v4l2_format *f);int(*vidioc_try_fmt_vid_out)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_try_fmt_vid_out_overlay)(struct file*file,void*fh,structv4l2_format*f);int(*vidioc_try_fmt_vbi_cap)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_try_fmt_vbi_out)(struct file*file,void*fh,struct v4l2_format*f);int(*vidioc_try_fmt_sliced_vbi_cap)(struct file*file,void*fh,structv4l2_format*f);int(*vidioc_try_fmt_sliced_vbi_out)(struct file*file,void*fh,structv4l2_format*f);int(*vidioc_try_fmt_type_private)(struct file*file,void*fh,struct v4l2_format *f);/*Buffer handlers*/int(*vidioc_reqbufs)(struct file*file,void*fh,struct v4l2_requestbuffers*b);int(*vidioc_querybuf)(struct file*file,void*fh,struct v4l2_buffer*b);int(*vidioc_qbuf)(struct file*file,void*fh,struct v4l2_buffer*b);int(*vidioc_dqbuf)(struct file*file,void*fh,struct v4l2_buffer*b);int(*vidioc_overlay)(struct file*file,void*fh,unsigned int i);int(*vidioc_g_fbuf)(struct file*file,void*fh,struct v4l2_framebuffer*a);int(*vidioc_s_fbuf)(struct file*file,void*fh,struct v4l2_framebuffer*a);/*Stream on/off*/int(*vidioc_streamon)(struct file*file,void*fh,enum v4l2_buf_type i);int(*vidioc_streamoff)(struct file*file,void*fh,enum v4l2_buf_type i);/*Standard handling ENUMSTD is handled by videodev.c*/int(*vidioc_g_std)(struct file*file,void*fh,v4l2_std_id*norm);int(*vidioc_s_std)(struct file*file,void*fh,v4l2_std_id*norm);int(*vidioc_querystd)(struct file*file,void*fh,v4l2_std_id*a);/*Input handling*/int(*vidioc_enum_input)(struct file*file,void*fh,struct v4l2_input*inp);int(*vidioc_g_input)(struct file*file,void*fh,unsigned int*i);int(*vidioc_s_input)(struct file*file,void*fh,unsigned int i);/*Output handling*/int(*vidioc_enum_output)(struct file*file,void*fh,struct v4l2_output*a);int(*vidioc_g_output)(struct file*file,void*fh,unsigned int*i);int(*vidioc_s_output)(struct file*file,void*fh,unsigned int i);/*Control handling*/int(*vidioc_queryctrl)(struct file*file,void*fh,struct v4l2_queryctrl*a);int(*vidioc_g_ctrl)(struct file*file,void*fh,struct v4l2_control*a);int(*vidioc_s_ctrl)(struct file*file,void*fh,struct v4l2_control*a);int(*vidioc_g_ext_ctrls)(struct file*file,void*fh,struct v4l2_ext_controls *a);int(*vidioc_s_ext_ctrls)(struct file*file,void*fh,struct v4l2_ext_controls *a);int(*vidioc_try_ext_ctrls)(struct file*file,void*fh,struct v4l2_ext_controls *a);int(*vidioc_querymenu)(struct file*file,void*fh,struct v4l2_querymenu *a);/*Audio ioctls*/int(*vidioc_enumaudio)(struct file*file,void*fh,struct v4l2_audio*a);int(*vidioc_g_audio)(struct file*file,void*fh,struct v4l2_audio*a);int(*vidioc_s_audio)(struct file*file,void*fh,struct v4l2_audio*a);/*Audio out ioctls*/int(*vidioc_enumaudout)(struct file*file,void*fh,struct v4l2_audioout *a);int(*vidioc_g_audout)(struct file*file,void*fh,struct v4l2_audioout*a);int(*vidioc_s_audout)(struct file*file,void*fh,struct v4l2_audioout*a);int(*vidioc_g_modulator)(struct file*file,void*fh,struct v4l2_modulator *a);int(*vidioc_s_modulator)(struct file*file,void*fh,struct v4l2_modulator *a);/*Crop ioctls*/int(*vidioc_cropcap)(struct file*file,void*fh,struct v4l2_cropcap*a);int(*vidioc_g_crop)(struct file*file,void*fh,struct v4l2_crop*a);int(*vidioc_s_crop)(struct file*file,void*fh,struct v4l2_crop*a);/*Compression ioctls*/int(*vidioc_g_jpegcomp)(struct file*file,void*fh,structv4l2_jpegcompression*a);int(*vidioc_s_jpegcomp)(struct file*file,void*fh,structv4l2_jpegcompression*a);int(*vidioc_g_enc_index)(struct file*file,void*fh,struct v4l2_enc_idx *a);int(*vidioc_encoder_cmd)(struct file*file,void*fh,structv4l2_encoder_cmd*a);int(*vidioc_try_encoder_cmd)(struct file*file,void*fh,structv4l2_encoder_cmd*a);/*Stream type-dependent parameter ioctls*/int(*vidioc_g_parm)(struct file*file,void*fh,struct v4l2_streamparm *a);int(*vidioc_s_parm)(struct file*file,void*fh,struct v4l2_streamparm *a);/*Tuner ioctls*/int(*vidioc_g_tuner)(struct file*file,void*fh,struct v4l2_tuner*a);int(*vidioc_s_tuner)(struct file*file,void*fh,struct v4l2_tuner*a);int(*vidioc_g_frequency)(struct file*file,void*fh,struct v4l2_frequency *a);int(*vidioc_s_frequency)(struct file*file,void*fh,struct v4l2_frequency *a);/*Sliced VBI cap*/int(*vidioc_g_sliced_vbi_cap)(struct file*file,void*fh,structv4l2_sliced_vbi_cap*a);/*Log status ioctl*/int(*vidioc_log_status)(struct file*file,void*fh);int(*vidioc_s_hw_freq_seek)(struct file*file,void*fh,structv4l2_hw_freq_seek*a);/*Debugging ioctls*/#ifdef CONFIG_VIDEO_ADV_DEBUGint(*vidioc_g_register)(struct file*file,void*fh,struct v4l2_dbg_register *reg);int(*vidioc_s_register)(struct file*file,void*fh,struct v4l2_dbg_register *reg);#endifint(*vidioc_g_chip_ident)(struct file*file,void*fh,structv4l2_dbg_chip_ident*chip);int(*vidioc_enum_framesizes)(struct file*file,void*fh,structv4l2_frmsizeenum*fsize);int(*vidioc_enum_frameintervals)(struct file*file,void*fh,structv4l2_frmivalenum*fival);/*DV Timings IOCTLs*/int(*vidioc_enum_dv_presets)(struct file*file,void*fh,structv4l2_dv_enum_preset*preset);int(*vidioc_s_dv_preset)(struct file*file,void*fh,struct v4l2_dv_preset *preset);int(*vidioc_g_dv_preset)(struct file*file,void*fh,struct v4l2_dv_preset *preset);int(*vidioc_query_dv_preset)(struct file*file,void*fh,structv4l2_dv_preset*qpreset);int(*vidioc_s_dv_timings)(struct file*file,void*fh,struct v4l2_dv_timings *timings);int(*vidioc_g_dv_timings)(struct file*file,void*fh,struct v4l2_dv_timings *timings);int(*vidioc_subscribe_event)(struct v4l2_fh*fh,structv4l2_event_subscription*sub);int(*vidioc_unsubscribe_event)(struct v4l2_fh*fh,structv4l2_event_subscription*sub);/*For other private ioctls*/long(*vidioc_default)(struct file*file,void*fh,int cmd,void*arg);};============================================================= ===================__u32pixelformat;/*Format fourcc*/__u32reserved[4];};//每一个subdev驱动程序实例应该创建这个结构,无论是独立或在一个更大的结构之中。