struct v4l2_file_operations {
long (*ioctl) (struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
};
struct video_device {
/* device ops */
const struct v4l2_file_operations *fops;
/* ioctl callbacks */
const struct v4l2_ioctl_ops *ioctl_ops;
}
如果const struct v4l2_ioctl_ops *ioctl_ops不为空的话,(*unlocked_ioctl) 必须为video_ioctl2, .unlocked_ioctl = video_ioctl2, video_ioctl2会在内部去调用const struct v4l2_ioctl_ops *ioctl_ops结构体里面的函数,如果const struct v4l2_ioctl_ops *ioctl_ops为空,则需要实现函数long (*ioctl) (struct file *, unsigned int, unsigned long),long (*ioctl) (struct file *, unsigned int, unsigned long)里面会调用由
v4l2_int_device_register
->struct v4l2_int_device
->static struct v4l2_int_slave
->static struct v4l2_int_ioctl_desc
函数 static inline int __must_check video_register_device(struct video_device *vdev, int type, int nr)的参数type可以设置VFL_TYPE_GRABBER,VFL_TYPE_VBI,VFL_TYPE_RADIO,VFL_TYPE_SUBDEV,常用的为VFL_TYPE_GRABBER对应video_capture、video_out、video_overlay
VFL_TYPE_RADIO对应radio(收音机), 对应的设备节点名字,通过如下代码判断,最终会在video_register_device里面创建字符设备
switch (type) {
case VFL_TYPE_GRABBER:
name_base = "video";
break;
case VFL_TYPE_VBI:
name_base = "vbi";
break;
case VFL_TYPE_RADIO:
name_base = "radio";
break;
case VFL_TYPE_SUBDEV:
name_base = "v4l-subdev";
break;
default:
printk(KERN_ERR "%s called with unknown type: %d\n",
__func__, type);
return -EINVAL;
}
long (*ioctl) (struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
};
struct video_device {
/* device ops */
const struct v4l2_file_operations *fops;
/* ioctl callbacks */
const struct v4l2_ioctl_ops *ioctl_ops;
}
如果const struct v4l2_ioctl_ops *ioctl_ops不为空的话,(*unlocked_ioctl) 必须为video_ioctl2, .unlocked_ioctl = video_ioctl2, video_ioctl2会在内部去调用const struct v4l2_ioctl_ops *ioctl_ops结构体里面的函数,如果const struct v4l2_ioctl_ops *ioctl_ops为空,则需要实现函数long (*ioctl) (struct file *, unsigned int, unsigned long),long (*ioctl) (struct file *, unsigned int, unsigned long)里面会调用由
v4l2_int_device_register
->struct v4l2_int_device
->static struct v4l2_int_slave
->static struct v4l2_int_ioctl_desc
注册的函数
static struct v4l2_int_ioctl_desc 结构体需要由用户自己去填充,该结构体一般是用在video_capture,如摄像头
函数 static inline int __must_check video_register_device(struct video_device *vdev, int type, int nr)的参数type可以设置VFL_TYPE_GRABBER,VFL_TYPE_VBI,VFL_TYPE_RADIO,VFL_TYPE_SUBDEV,常用的为VFL_TYPE_GRABBER对应video_capture、video_out、video_overlay
VFL_TYPE_RADIO对应radio(收音机), 对应的设备节点名字,通过如下代码判断,最终会在video_register_device里面创建字符设备
switch (type) {
case VFL_TYPE_GRABBER:
name_base = "video";
break;
case VFL_TYPE_VBI:
name_base = "vbi";
break;
case VFL_TYPE_RADIO:
name_base = "radio";
break;
case VFL_TYPE_SUBDEV:
name_base = "v4l-subdev";
break;
default:
printk(KERN_ERR "%s called with unknown type: %d\n",
__func__, type);
return -EINVAL;
}