From 69acdf1e5a9146ec6667f6c4b439acd38c18f5ea Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 4 Nov 2008 21:59:37 -0300 Subject: V4L/DVB (9530): Add new pixel format VYUY 16 bits wide. There were already 3 YUV formats defined : - YUYV - YVYU - UYVY The only left combination is VYUY, which is added in this patch. Signed-off-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4669d7e72e75..ec311d4616cd 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -293,6 +293,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ -- cgit v1.2.3 From 0877258d98154565def498833ccb208234c85084 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 14 Dec 2008 16:21:16 -0300 Subject: V4L/DVB (9897): v4l2: Add camera zoom controls The zoom controls move the zoom lens group to a an absolute position, as a relative displacement or at a given speed until reaching physical device limits. Positive values move the zoom lens group towards the telephoto direction, negative values towards the wide-angle direction. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index ec311d4616cd..e450a92a622b 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1118,6 +1118,10 @@ enum v4l2_exposure_auto_type { #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + /* * T U N I N G */ -- cgit v1.2.3 From 046425f8c4ac431db00c09a6d9fba16560b8e5b9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 14 Dec 2008 16:22:05 -0300 Subject: V4L/DVB (9898): v4l2: Add privacy control The privacy control prevents video from being acquired by the camera. A true value indicates that no image can be captured. Devices that implement the privacy control must support read access and may support write access. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e450a92a622b..6e6743bd0f92 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1122,6 +1122,8 @@ enum v4l2_exposure_auto_type { #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + /* * T U N I N G */ -- cgit v1.2.3 From 92f45badbbaccdbc1be25085292a1e258948e221 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 21 Dec 2008 10:35:25 -0300 Subject: V4L/DVB (9932): v4l2-compat32: fix 32-64 compatibility module Added all missing v4l1/2 ioctls and fix several broken conversions. Partially based on work done by Cody Pisto . Tested-by: Brandon Jenkins Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-compat-ioctl32.c | 781 ++++++++++++++++++------------ include/linux/videodev2.h | 2 + 2 files changed, 467 insertions(+), 316 deletions(-) (limited to 'include/linux') diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 9b50b43b76a2..5084773d4f10 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c @@ -7,12 +7,14 @@ * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be) + * Copyright (C) 2008 Hans Verkuil * * These routines maintain argument size conversion between 32bit and 64bit * ioctls. */ #include +#define __OLD_VIDIOC_ /* To allow fixing old calls*/ #include #include #include @@ -58,7 +60,6 @@ static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user return 0; } - struct video_buffer32 { compat_caddr_t base; compat_int_t height, width, depth, bytesperline; @@ -99,7 +100,7 @@ static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __u } struct video_clip32 { - s32 x, y, width, height; /* Its really s32 in videodev.h */ + s32 x, y, width, height; /* It's really s32 in videodev.h */ compat_caddr_t next; }; @@ -108,25 +109,72 @@ struct video_window32 { compat_caddr_t clips; compat_int_t clipcount; }; -#endif -static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int get_video_window32(struct video_window *kp, struct video_window32 __user *up) { - int ret = -ENOIOCTLCMD; + struct video_clip __user *uclips; + struct video_clip __user *kclips; + compat_caddr_t p; + int nclips; - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, cmd, arg); - else if (file->f_op->ioctl) { - lock_kernel(); - ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg); - unlock_kernel(); + if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32))) + return -EFAULT; + + if (get_user(nclips, &up->clipcount)) + return -EFAULT; + + if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32)) || + get_user(kp->x, &up->x) || + get_user(kp->y, &up->y) || + get_user(kp->width, &up->width) || + get_user(kp->height, &up->height) || + get_user(kp->chromakey, &up->chromakey) || + get_user(kp->flags, &up->flags) || + get_user(kp->clipcount, &up->clipcount)) + return -EFAULT; + + nclips = kp->clipcount; + kp->clips = NULL; + + if (nclips == 0) + return 0; + if (get_user(p, &up->clips)) + return -EFAULT; + uclips = compat_ptr(p); + + /* If nclips < 0, then it is a clipping bitmap of size + VIDEO_CLIPMAP_SIZE */ + if (nclips < 0) { + if (!access_ok(VERIFY_READ, uclips, VIDEO_CLIPMAP_SIZE)) + return -EFAULT; + kp->clips = compat_alloc_user_space(VIDEO_CLIPMAP_SIZE); + if (copy_in_user(kp->clips, uclips, VIDEO_CLIPMAP_SIZE)) + return -EFAULT; + return 0; } - return ret; -} + /* Otherwise it is an array of video_clip structs. */ + if (!access_ok(VERIFY_READ, uclips, nclips * sizeof(struct video_clip))) + return -EFAULT; + kp->clips = compat_alloc_user_space(nclips * sizeof(struct video_clip)); + kclips = kp->clips; + while (nclips--) { + int err; + + err = copy_in_user(&kclips->x, &uclips->x, sizeof(kclips->x)); + err |= copy_in_user(&kclips->y, &uclips->y, sizeof(kclips->y)); + err |= copy_in_user(&kclips->width, &uclips->width, sizeof(kclips->width)); + err |= copy_in_user(&kclips->height, &uclips->height, sizeof(kclips->height)); + kclips->next = NULL; + if (err) + return -EFAULT; + kclips++; + uclips++; + } + return 0; +} -#ifdef CONFIG_VIDEO_V4L1_COMPAT /* You get back everything except the clips... */ static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) { @@ -141,8 +189,55 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u return -EFAULT; return 0; } + +struct video_code32 { + char loadwhat[16]; /* name or tag of file being passed */ + compat_int_t datasize; + unsigned char *data; +}; + +static int get_microcode32(struct video_code *kp, struct video_code32 __user *up) +{ + if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || + copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) || + get_user(kp->datasize, &up->datasize) || + copy_from_user(kp->data, up->data, up->datasize)) + return -EFAULT; + return 0; +} + +#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) +#define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32) +#define VIDIOCGWIN32 _IOR('v', 9, struct video_window32) +#define VIDIOCSWIN32 _IOW('v', 10, struct video_window32) +#define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32) +#define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32) +#define VIDIOCGFREQ32 _IOR('v', 14, u32) +#define VIDIOCSFREQ32 _IOW('v', 15, u32) +#define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32) + +#define VIDIOCCAPTURE32 _IOW('v', 8, s32) +#define VIDIOCSYNC32 _IOW('v', 18, s32) +#define VIDIOCSWRITEMODE32 _IOW('v', 25, s32) + #endif +static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret = -ENOIOCTLCMD; + + if (file->f_op->unlocked_ioctl) + ret = file->f_op->unlocked_ioctl(file, cmd, arg); + else if (file->f_op->ioctl) { + lock_kernel(); + ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg); + unlock_kernel(); + } + + return ret; +} + + struct v4l2_clip32 { struct v4l2_rect c; compat_caddr_t next; @@ -229,12 +324,27 @@ static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vb return 0; } +static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up) +{ + if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format))) + return -EFAULT; + return 0; +} + +static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up) +{ + if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format))) + return -EFAULT; + return 0; +} + struct v4l2_format32 { enum v4l2_buf_type type; union { - struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ - struct v4l2_window32 win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ - struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ + struct v4l2_pix_format pix; + struct v4l2_window32 win; + struct v4l2_vbi_format vbi; + struct v4l2_sliced_vbi_format sliced; __u8 raw_data[200]; /* user-defined */ } fmt; }; @@ -246,15 +356,27 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user return -EFAULT; switch (kp->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); case V4L2_BUF_TYPE_VIDEO_OVERLAY: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + return get_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced); + case V4L2_BUF_TYPE_PRIVATE: + if (copy_from_user(kp, up, sizeof(kp->fmt.raw_data))) + return -EFAULT; + return 0; + case 0: + return -EINVAL; default: - printk(KERN_INFO "compat_ioctl: unexpected VIDIOC_FMT type %d\n", + printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n", kp->type); - return -ENXIO; + return -EINVAL; } } @@ -265,31 +387,30 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user return -EFAULT; switch (kp->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: + case V4L2_BUF_TYPE_VIDEO_OUTPUT: return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); case V4L2_BUF_TYPE_VIDEO_OVERLAY: + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + return put_v4l2_sliced_vbi_format(&kp->fmt.sliced, &up->fmt.sliced); + case V4L2_BUF_TYPE_PRIVATE: + if (copy_to_user(up, kp, sizeof(up->fmt.raw_data))) + return -EFAULT; + return 0; + case 0: + return -EINVAL; default: - return -ENXIO; + printk(KERN_INFO "compat_ioctl32: unexpected VIDIOC_FMT type %d\n", + kp->type); + return -EINVAL; } } -static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) -{ - if (copy_from_user(kp, up, sizeof(struct v4l2_standard))) - return -EFAULT; - return 0; - -} - -static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) -{ - if (copy_to_user(up, kp, sizeof(struct v4l2_standard))) - return -EFAULT; - return 0; -} - struct v4l2_standard32 { __u32 index; __u32 id[2]; /* __u64 would get the alignment wrong */ @@ -321,21 +442,6 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 return 0; } -static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) -{ - if (copy_from_user(kp, up, sizeof(struct v4l2_tuner))) - return -EFAULT; - return 0; - -} - -static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) -{ - if (copy_to_user(up, kp, sizeof(struct v4l2_tuner))) - return -EFAULT; - return 0; -} - struct v4l2_buffer32 { __u32 index; enum v4l2_buf_type type; @@ -459,149 +565,143 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame return 0; } -static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) -{ - if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) - return -EFAULT; - return 0; -} - -static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) +struct v4l2_input32 { + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ + v4l2_std_id std; + __u32 status; + __u32 reserved[4]; +} __attribute__ ((packed)); + +/* The 64-bit v4l2_input struct has extra padding at the end of the struct. + Otherwise it is identical to the 32-bit version. */ +static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up) { - if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) + if (copy_from_user(kp, up, sizeof(struct v4l2_input32))) return -EFAULT; return 0; } -static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) +static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up) { - if (copy_from_user(kp, up, sizeof(struct v4l2_input))) + if (copy_to_user(up, kp, sizeof(struct v4l2_input32))) return -EFAULT; return 0; } -static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) -{ - if (copy_to_user(up, kp, sizeof(struct v4l2_input))) - return -EFAULT; - return 0; -} - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -struct video_code32 { - char loadwhat[16]; /* name or tag of file being passed */ - compat_int_t datasize; - unsigned char *data; +struct v4l2_ext_controls32 { + __u32 ctrl_class; + __u32 count; + __u32 error_idx; + __u32 reserved[2]; + compat_caddr_t controls; /* actually struct v4l2_ext_control32 * */ }; -static inline int microcode32(struct video_code *kp, struct video_code32 __user *up) +static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) { - if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || - copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) || - get_user(kp->datasize, &up->datasize) || - copy_from_user(kp->data, up->data, up->datasize)) + struct v4l2_ext_control __user *ucontrols; + struct v4l2_ext_control __user *kcontrols; + int n; + compat_caddr_t p; + + if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) || + get_user(kp->ctrl_class, &up->ctrl_class) || + get_user(kp->count, &up->count) || + get_user(kp->error_idx, &up->error_idx) || + copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved))) + return -EFAULT; + n = kp->count; + if (n == 0) { + kp->controls = NULL; + return 0; + } + if (get_user(p, &up->controls)) + return -EFAULT; + ucontrols = compat_ptr(p); + if (!access_ok(VERIFY_READ, ucontrols, n * sizeof(struct v4l2_ext_control))) + return -EFAULT; + kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control)); + kp->controls = kcontrols; + while (--n >= 0) { + if (copy_in_user(&kcontrols->id, &ucontrols->id, sizeof(__u32))) + return -EFAULT; + if (copy_in_user(&kcontrols->reserved2, &ucontrols->reserved2, sizeof(ucontrols->reserved2))) return -EFAULT; + /* Note: if the void * part of the union ever becomes relevant + then we need to know the type of the control in order to do + the right thing here. Luckily, that is not yet an issue. */ + if (copy_in_user(&kcontrols->value, &ucontrols->value, sizeof(ucontrols->value))) + return -EFAULT; + ucontrols++; + kcontrols++; + } return 0; } -#define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) -#define VIDIOCSTUNER32 _IOW('v', 5, struct video_tuner32) -#define VIDIOCGWIN32 _IOR('v', 9, struct video_window32) -#define VIDIOCSWIN32 _IOW('v', 10, struct video_window32) -#define VIDIOCGFBUF32 _IOR('v', 11, struct video_buffer32) -#define VIDIOCSFBUF32 _IOW('v', 12, struct video_buffer32) -#define VIDIOCGFREQ32 _IOR('v', 14, u32) -#define VIDIOCSFREQ32 _IOW('v', 15, u32) -#define VIDIOCSMICROCODE32 _IOW('v', 27, struct video_code32) - -#endif - -/* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */ -#define VIDIOC_ENUMINPUT32 (VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4)) -#define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32) -#define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32) -#define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32) -#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) -#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32) -/* VIDIOC_OVERLAY is now _IOW, but was _IOWR */ -#define VIDIOC_OVERLAY32 _IOWR ('V', 14, compat_int_t) -#define VIDIOC_QBUF32 _IOWR ('V', 15, struct v4l2_buffer32) -#define VIDIOC_DQBUF32 _IOWR ('V', 17, struct v4l2_buffer32) -#define VIDIOC_STREAMON32 _IOW ('V', 18, compat_int_t) -#define VIDIOC_STREAMOFF32 _IOW ('V', 19, compat_int_t) -#define VIDIOC_ENUMSTD32 _IOWR ('V', 25, struct v4l2_standard32) -/* VIDIOC_S_CTRL is now _IOWR, but was _IOW */ -#define VIDIOC_S_CTRL32 _IOW ('V', 28, struct v4l2_control) -#define VIDIOC_G_INPUT32 _IOR ('V', 38, compat_int_t) -#define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t) -#define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32) - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -enum { - MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) -}; - -static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg) +static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up) { - struct video_window32 __user *up = compat_ptr(arg); - struct video_window __user *vw; - struct video_clip __user *p; - int nclips; - u32 n; - - if (!access_ok(VERIFY_READ, up, sizeof(struct video_window32))) - return -EFAULT; + struct v4l2_ext_control __user *ucontrols; + struct v4l2_ext_control __user *kcontrols = kp->controls; + int n = kp->count; + compat_caddr_t p; + + if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) || + put_user(kp->ctrl_class, &up->ctrl_class) || + put_user(kp->count, &up->count) || + put_user(kp->error_idx, &up->error_idx) || + copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved))) + return -EFAULT; + if (!kp->count) + return 0; - if (get_user(nclips, &up->clipcount)) + if (get_user(p, &up->controls)) return -EFAULT; - - /* Peculiar interface... */ - if (nclips < 0) - nclips = VIDEO_CLIPMAP_SIZE; - - if (nclips > MaxClips) - return -ENOMEM; - - vw = compat_alloc_user_space(sizeof(struct video_window) + - nclips * sizeof(struct video_clip)); - - p = nclips ? (struct video_clip __user *)(vw + 1) : NULL; - - if (get_user(n, &up->x) || put_user(n, &vw->x) || - get_user(n, &up->y) || put_user(n, &vw->y) || - get_user(n, &up->width) || put_user(n, &vw->width) || - get_user(n, &up->height) || put_user(n, &vw->height) || - get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) || - get_user(n, &up->flags) || put_user(n, &vw->flags) || - get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) || - get_user(n, &up->clips) || put_user(p, &vw->clips)) + ucontrols = compat_ptr(p); + if (!access_ok(VERIFY_WRITE, ucontrols, n * sizeof(struct v4l2_ext_control))) return -EFAULT; - if (nclips) { - struct video_clip32 __user *u = compat_ptr(n); - int i; - if (!u) - return -EINVAL; - for (i = 0; i < nclips; i++, u++, p++) { - s32 v; - if (!access_ok(VERIFY_READ, u, sizeof(struct video_clip32)) || - !access_ok(VERIFY_WRITE, p, sizeof(struct video_clip32)) || - get_user(v, &u->x) || - put_user(v, &p->x) || - get_user(v, &u->y) || - put_user(v, &p->y) || - get_user(v, &u->width) || - put_user(v, &p->width) || - get_user(v, &u->height) || - put_user(v, &p->height) || - put_user(NULL, &p->next)) - return -EFAULT; - } + while (--n >= 0) { + if (copy_in_user(&ucontrols->id, &kcontrols->id, sizeof(__u32))) + return -EFAULT; + if (copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2, + sizeof(ucontrols->reserved2))) + return -EFAULT; + /* Note: if the void * part of the union ever becomes relevant + then we need to know the type of the control in order to do + the right thing here. Luckily, that is not yet an issue. */ + if (copy_in_user(&ucontrols->value, &kcontrols->value, sizeof(ucontrols->value))) + return -EFAULT; + ucontrols++; + kcontrols++; } - - return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw); + return 0; } -#endif + +#define VIDIOC_G_FMT32 _IOWR('V', 4, struct v4l2_format32) +#define VIDIOC_S_FMT32 _IOWR('V', 5, struct v4l2_format32) +#define VIDIOC_QUERYBUF32 _IOWR('V', 9, struct v4l2_buffer32) +#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) +#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32) +#define VIDIOC_QBUF32 _IOWR('V', 15, struct v4l2_buffer32) +#define VIDIOC_DQBUF32 _IOWR('V', 17, struct v4l2_buffer32) +#define VIDIOC_ENUMSTD32 _IOWR('V', 25, struct v4l2_standard32) +#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) +#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) +#define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) +#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) +#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) + +#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32) +#define VIDIOC_OVERLAY32_OLD _IOWR('V', 14, s32) +#define VIDIOC_STREAMON32 _IOW ('V', 18, s32) +#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) +#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) +#define VIDIOC_S_INPUT32 _IOWR('V', 39, s32) +#define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32) +#define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32) static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -616,45 +716,51 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg struct v4l2_format v2f; struct v4l2_buffer v2b; struct v4l2_framebuffer v2fb; - struct v4l2_standard v2s; struct v4l2_input v2i; - struct v4l2_tuner v2t; + struct v4l2_standard v2s; + struct v4l2_ext_controls v2ecs; unsigned long vx; + int vi; } karg; void __user *up = compat_ptr(arg); int compatible_arg = 1; int err = 0; - int realcmd = cmd; /* First, convert the command. */ switch (cmd) { #ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCGTUNER32: realcmd = cmd = VIDIOCGTUNER; break; - case VIDIOCSTUNER32: realcmd = cmd = VIDIOCSTUNER; break; - case VIDIOCGWIN32: realcmd = cmd = VIDIOCGWIN; break; - case VIDIOCGFBUF32: realcmd = cmd = VIDIOCGFBUF; break; - case VIDIOCSFBUF32: realcmd = cmd = VIDIOCSFBUF; break; - case VIDIOCGFREQ32: realcmd = cmd = VIDIOCGFREQ; break; - case VIDIOCSFREQ32: realcmd = cmd = VIDIOCSFREQ; break; - case VIDIOCSMICROCODE32: realcmd = cmd = VIDIOCSMICROCODE; break; + case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; + case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; + case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; + case VIDIOCSWIN32: cmd = VIDIOCSWIN; break; + case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; + case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; + case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; + case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; + case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; #endif - case VIDIOC_G_FMT32: realcmd = cmd = VIDIOC_G_FMT; break; - case VIDIOC_S_FMT32: realcmd = cmd = VIDIOC_S_FMT; break; - case VIDIOC_QUERYBUF32: realcmd = cmd = VIDIOC_QUERYBUF; break; - case VIDIOC_QBUF32: realcmd = cmd = VIDIOC_QBUF; break; - case VIDIOC_DQBUF32: realcmd = cmd = VIDIOC_DQBUF; break; - case VIDIOC_STREAMON32: realcmd = cmd = VIDIOC_STREAMON; break; - case VIDIOC_STREAMOFF32: realcmd = cmd = VIDIOC_STREAMOFF; break; - case VIDIOC_G_FBUF32: realcmd = cmd = VIDIOC_G_FBUF; break; - case VIDIOC_S_FBUF32: realcmd = cmd = VIDIOC_S_FBUF; break; - case VIDIOC_OVERLAY32: realcmd = cmd = VIDIOC_OVERLAY; break; - case VIDIOC_ENUMSTD32: realcmd = VIDIOC_ENUMSTD; break; - case VIDIOC_ENUMINPUT32: realcmd = VIDIOC_ENUMINPUT; break; - case VIDIOC_S_CTRL32: realcmd = cmd = VIDIOC_S_CTRL; break; - case VIDIOC_G_INPUT32: realcmd = cmd = VIDIOC_G_INPUT; break; - case VIDIOC_S_INPUT32: realcmd = cmd = VIDIOC_S_INPUT; break; - case VIDIOC_TRY_FMT32: realcmd = cmd = VIDIOC_TRY_FMT; break; - }; + case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; + case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; + case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; + case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break; + case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break; + case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break; + case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break; + case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break; + case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break; + case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; + case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break; + case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break; + case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break; + case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; + case VIDIOC_OVERLAY32_OLD: cmd = VIDIOC_OVERLAY; break; + case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; + case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; + case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; + case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; + case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; + case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; + } switch (cmd) { #ifdef CONFIG_VIDEO_V4L1_COMPAT @@ -662,7 +768,6 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOCGTUNER: err = get_video_tuner32(&karg.vt, up); compatible_arg = 0; - break; case VIDIOCSFBUF: @@ -670,19 +775,42 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg compatible_arg = 0; break; + case VIDIOCSWIN: + err = get_video_window32(&karg.vw, up); + compatible_arg = 0; + break; + + case VIDIOCGWIN: + case VIDIOCGFBUF: + case VIDIOCGFREQ: + compatible_arg = 0; + break; + + case VIDIOCSMICROCODE: + err = get_microcode32(&karg.vc, up); + compatible_arg = 0; + break; case VIDIOCSFREQ: + err = get_user(karg.vx, (u32 __user *)up); + compatible_arg = 0; + break; + + case VIDIOCCAPTURE: + case VIDIOCSYNC: + case VIDIOCSWRITEMODE: #endif - case VIDIOC_S_INPUT: case VIDIOC_OVERLAY: case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: - err = get_user(karg.vx, (u32 __user *)up); - compatible_arg = 1; + case VIDIOC_S_INPUT: + case VIDIOC_S_OUTPUT: + err = get_user(karg.vi, (s32 __user *)up); + compatible_arg = 0; break; - case VIDIOC_S_FBUF: - err = get_v4l2_framebuffer32(&karg.v2fb, up); + case VIDIOC_G_INPUT: + case VIDIOC_G_OUTPUT: compatible_arg = 0; break; @@ -700,122 +828,108 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg compatible_arg = 0; break; - case VIDIOC_ENUMSTD: - err = get_v4l2_standard(&karg.v2s, up); + case VIDIOC_S_FBUF: + err = get_v4l2_framebuffer32(&karg.v2fb, up); compatible_arg = 0; break; - case VIDIOC_ENUMSTD32: - err = get_v4l2_standard32(&karg.v2s, up); + case VIDIOC_G_FBUF: compatible_arg = 0; break; - case VIDIOC_ENUMINPUT: - err = get_v4l2_input(&karg.v2i, up); + case VIDIOC_ENUMSTD: + err = get_v4l2_standard32(&karg.v2s, up); compatible_arg = 0; break; - case VIDIOC_ENUMINPUT32: + case VIDIOC_ENUMINPUT: err = get_v4l2_input32(&karg.v2i, up); compatible_arg = 0; break; - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - err = get_v4l2_tuner(&karg.v2t, up); + case VIDIOC_G_EXT_CTRLS: + case VIDIOC_S_EXT_CTRLS: + case VIDIOC_TRY_EXT_CTRLS: + err = get_v4l2_ext_controls32(&karg.v2ecs, up); compatible_arg = 0; break; - -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCGWIN: - case VIDIOCGFBUF: - case VIDIOCGFREQ: -#endif - case VIDIOC_G_FBUF: - case VIDIOC_G_INPUT: - compatible_arg = 0; - break; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCSMICROCODE: - err = microcode32(&karg.vc, up); - compatible_arg = 0; - break; -#endif - }; + } if (err) - goto out; + return err; if (compatible_arg) - err = native_ioctl(file, realcmd, (unsigned long)up); + err = native_ioctl(file, cmd, (unsigned long)up); else { mm_segment_t old_fs = get_fs(); set_fs(KERNEL_DS); - err = native_ioctl(file, realcmd, (unsigned long)&karg); + err = native_ioctl(file, cmd, (unsigned long)&karg); set_fs(old_fs); } - if (err == 0) { - switch (cmd) { + + /* Special case: even after an error we need to put the + results back for these ioctls since the error_idx will + contain information on which control failed. */ + switch (cmd) { + case VIDIOC_G_EXT_CTRLS: + case VIDIOC_S_EXT_CTRLS: + case VIDIOC_TRY_EXT_CTRLS: + if (put_v4l2_ext_controls32(&karg.v2ecs, up)) + err = -EFAULT; + break; + } + if (err) + return err; + + switch (cmd) { #ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCGTUNER: - err = put_video_tuner32(&karg.vt, up); - break; + case VIDIOCGTUNER: + err = put_video_tuner32(&karg.vt, up); + break; - case VIDIOCGWIN: - err = put_video_window32(&karg.vw, up); - break; + case VIDIOCGWIN: + err = put_video_window32(&karg.vw, up); + break; - case VIDIOCGFBUF: - err = put_video_buffer32(&karg.vb, up); - break; + case VIDIOCGFBUF: + err = put_video_buffer32(&karg.vb, up); + break; + case VIDIOCGFREQ: + err = put_user(((u32)karg.vx), (u32 __user *)up); + break; #endif - case VIDIOC_G_FBUF: - err = put_v4l2_framebuffer32(&karg.v2fb, up); - break; - - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - err = put_v4l2_format32(&karg.v2f, up); - break; - - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: - err = put_v4l2_buffer32(&karg.v2b, up); - break; - - case VIDIOC_ENUMSTD: - err = put_v4l2_standard(&karg.v2s, up); - break; - - case VIDIOC_ENUMSTD32: - err = put_v4l2_standard32(&karg.v2s, up); - break; - - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - err = put_v4l2_tuner(&karg.v2t, up); - break; - - case VIDIOC_ENUMINPUT: - err = put_v4l2_input(&karg.v2i, up); - break; - - case VIDIOC_ENUMINPUT32: - err = put_v4l2_input32(&karg.v2i, up); - break; + case VIDIOC_S_INPUT: + case VIDIOC_S_OUTPUT: + case VIDIOC_G_INPUT: + case VIDIOC_G_OUTPUT: + err = put_user(((s32)karg.vi), (s32 __user *)up); + break; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCGFREQ: -#endif - case VIDIOC_G_INPUT: - err = put_user(((u32)karg.vx), (u32 __user *)up); - break; - }; + case VIDIOC_G_FBUF: + err = put_v4l2_framebuffer32(&karg.v2fb, up); + break; + + case VIDIOC_G_FMT: + case VIDIOC_S_FMT: + case VIDIOC_TRY_FMT: + err = put_v4l2_format32(&karg.v2f, up); + break; + + case VIDIOC_QUERYBUF: + case VIDIOC_QBUF: + case VIDIOC_DQBUF: + err = put_v4l2_buffer32(&karg.v2b, up); + break; + + case VIDIOC_ENUMSTD: + err = put_v4l2_standard32(&karg.v2s, up); + break; + + case VIDIOC_ENUMINPUT: + err = put_v4l2_input32(&karg.v2i, up); + break; } -out: return err; } @@ -828,26 +942,48 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { #ifdef CONFIG_VIDEO_V4L1_COMPAT - case VIDIOCSWIN32: - ret = do_set_window(file, cmd, arg); - break; + case VIDIOCGCAP: + case VIDIOCGCHAN: + case VIDIOCSCHAN: case VIDIOCGTUNER32: case VIDIOCSTUNER32: + case VIDIOCGPICT: + case VIDIOCSPICT: + case VIDIOCCAPTURE32: case VIDIOCGWIN32: + case VIDIOCSWIN32: case VIDIOCGFBUF32: case VIDIOCSFBUF32: + case VIDIOCKEY: case VIDIOCGFREQ32: case VIDIOCSFREQ32: case VIDIOCGAUDIO: case VIDIOCSAUDIO: + case VIDIOCSYNC32: + case VIDIOCMCAPTURE: + case VIDIOCGMBUF: + case VIDIOCGUNIT: + case VIDIOCGCAPTURE: + case VIDIOCSCAPTURE: + case VIDIOCSPLAYMODE: + case VIDIOCSWRITEMODE32: + case VIDIOCGPLAYINFO: + case VIDIOCSMICROCODE32: case VIDIOCGVBIFMT: case VIDIOCSVBIFMT: +#endif +#ifdef __OLD_VIDIOC_ + case VIDIOC_OVERLAY32_OLD: + case VIDIOC_S_PARM_OLD: + case VIDIOC_S_CTRL_OLD: + case VIDIOC_G_AUDIO_OLD: + case VIDIOC_G_AUDOUT_OLD: + case VIDIOC_CROPCAP_OLD: #endif case VIDIOC_QUERYCAP: + case VIDIOC_RESERVED: case VIDIOC_ENUM_FMT: case VIDIOC_G_FMT32: - case VIDIOC_CROPCAP: - case VIDIOC_S_CROP: case VIDIOC_S_FMT32: case VIDIOC_REQBUFS: case VIDIOC_QUERYBUF32: @@ -862,43 +998,56 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_S_PARM: case VIDIOC_G_STD: case VIDIOC_S_STD: - case VIDIOC_G_TUNER: - case VIDIOC_S_TUNER: - case VIDIOC_ENUMSTD: case VIDIOC_ENUMSTD32: - case VIDIOC_ENUMINPUT: case VIDIOC_ENUMINPUT32: case VIDIOC_G_CTRL: case VIDIOC_S_CTRL: - case VIDIOC_S_CTRL32: - case VIDIOC_S_FREQUENCY: - case VIDIOC_G_FREQUENCY: + case VIDIOC_G_TUNER: + case VIDIOC_S_TUNER: + case VIDIOC_G_AUDIO: + case VIDIOC_S_AUDIO: case VIDIOC_QUERYCTRL: + case VIDIOC_QUERYMENU: case VIDIOC_G_INPUT32: case VIDIOC_S_INPUT32: + case VIDIOC_G_OUTPUT32: + case VIDIOC_S_OUTPUT32: + case VIDIOC_ENUMOUTPUT: + case VIDIOC_G_AUDOUT: + case VIDIOC_S_AUDOUT: + case VIDIOC_G_MODULATOR: + case VIDIOC_S_MODULATOR: + case VIDIOC_S_FREQUENCY: + case VIDIOC_G_FREQUENCY: + case VIDIOC_CROPCAP: + case VIDIOC_G_CROP: + case VIDIOC_S_CROP: + case VIDIOC_G_JPEGCOMP: + case VIDIOC_S_JPEGCOMP: + case VIDIOC_QUERYSTD: case VIDIOC_TRY_FMT32: - case VIDIOC_S_HW_FREQ_SEEK: + case VIDIOC_ENUMAUDIO: + case VIDIOC_ENUMAUDOUT: + case VIDIOC_G_PRIORITY: + case VIDIOC_S_PRIORITY: + case VIDIOC_G_SLICED_VBI_CAP: + case VIDIOC_LOG_STATUS: + case VIDIOC_G_EXT_CTRLS32: + case VIDIOC_S_EXT_CTRLS32: + case VIDIOC_TRY_EXT_CTRLS32: case VIDIOC_ENUM_FRAMESIZES: case VIDIOC_ENUM_FRAMEINTERVALS: + case VIDIOC_G_ENC_INDEX: + case VIDIOC_ENCODER_CMD: + case VIDIOC_TRY_ENCODER_CMD: + case VIDIOC_DBG_S_REGISTER: + case VIDIOC_DBG_G_REGISTER: + case VIDIOC_G_CHIP_IDENT: + case VIDIOC_S_HW_FREQ_SEEK: ret = do_video_ioctl(file, cmd, arg); break; #ifdef CONFIG_VIDEO_V4L1_COMPAT - /* Little v, the video4linux ioctls (conflict?) */ - case VIDIOCGCAP: - case VIDIOCGCHAN: - case VIDIOCSCHAN: - case VIDIOCGPICT: - case VIDIOCSPICT: - case VIDIOCCAPTURE: - case VIDIOCKEY: - case VIDIOCSYNC: - case VIDIOCMCAPTURE: - case VIDIOCGMBUF: - case VIDIOCGUNIT: - case VIDIOCGCAPTURE: - case VIDIOCSCAPTURE: - /* BTTV specific... */ case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 6e6743bd0f92..e2cfd6add78c 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1465,6 +1465,8 @@ struct v4l2_chip_ident { #define VIDIOC_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_chip_ident) #endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +/* Reminder: when adding new ioctls please add support for them to + drivers/media/video/v4l2-compat-ioctl32.c as well! */ #ifdef __OLD_VIDIOC_ /* for compatibility, will go away some day */ -- cgit v1.2.3 From 4b00eb25340c1a9b9eedaf0bc5b0f0d18eddb028 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 19 Dec 2008 11:17:56 -0300 Subject: V4L/DVB (9944): videodev2.h: fix typo. The comment said CX2584X instead of CX2341X. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e2cfd6add78c..754c8d9685a4 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1051,7 +1051,7 @@ enum v4l2_mpeg_video_bitrate_mode { #define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) #define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) -/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */ +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { -- cgit v1.2.3 From 531c98e71805b32e9ea35a218119100bbd2b7615 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Dec 2008 13:18:27 -0300 Subject: V4L/DVB (9953): em28xx: Add suport for debugging AC97 anciliary chips The em28xx driver can be coupled to an anciliary AC97 chip. This patch allows read/write AC97 registers directly. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-core.c | 4 ++-- drivers/media/video/em28xx/em28xx-video.c | 19 +++++++++++++++++++ drivers/media/video/em28xx/em28xx.h | 3 +++ include/linux/videodev2.h | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index c647dcb20a57..5964998daf2e 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c @@ -259,7 +259,7 @@ static int em28xx_is_ac97_ready(struct em28xx *dev) * em28xx_read_ac97() * write a 16 bit value to the specified AC97 address (LSB first!) */ -static int em28xx_read_ac97(struct em28xx *dev, u8 reg) +int em28xx_read_ac97(struct em28xx *dev, u8 reg) { int ret; u8 addr = (reg & 0x7f) | 0x80; @@ -285,7 +285,7 @@ static int em28xx_read_ac97(struct em28xx *dev, u8 reg) * em28xx_write_ac97() * write a 16 bit value to the specified AC97 address (LSB first!) */ -static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) +int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) { int ret; u8 addr = reg & 0x7f; diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 4701b6589b10..4ea4920c927a 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1221,6 +1221,17 @@ static int vidioc_g_register(struct file *file, void *priv, struct em28xx *dev = fh->dev; int ret; + if (reg->match_type == V4L2_CHIP_MATCH_AC97) { + mutex_lock(&dev->lock); + ret = em28xx_read_ac97(dev, reg->reg); + mutex_unlock(&dev->lock); + if (ret < 0) + return ret; + + reg->val = ret; + return 0; + } + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) return -EINVAL; @@ -1256,6 +1267,14 @@ static int vidioc_s_register(struct file *file, void *priv, __le64 buf; int rc; + if (reg->match_type == V4L2_CHIP_MATCH_AC97) { + mutex_lock(&dev->lock); + rc = em28xx_write_ac97(dev, reg->reg, reg->val); + mutex_unlock(&dev->lock); + + return rc; + } + buf = cpu_to_le64(reg->val); mutex_lock(&dev->lock); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 80d1d55d80f9..100f27819cdc 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -564,6 +564,9 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); +int em28xx_read_ac97(struct em28xx *dev, u8 reg); +int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); + int em28xx_audio_analog_set(struct em28xx *dev); int em28xx_audio_setup(struct em28xx *dev); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 754c8d9685a4..e31144d22237 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1376,6 +1376,7 @@ struct v4l2_streamparm { #define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */ #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ struct v4l2_register { __u32 match_type; /* Match type */ -- cgit v1.2.3 From 91962fa713bd8bf47434b02ac661fdc201365fa5 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 18 Dec 2008 11:45:00 -0300 Subject: V4L/DVB (10078): video: add NV16 and NV61 pixel formats This patch adds support for NV16 and NV61 pixel formats. These pixel formats use two planes; one for 8-bit Y values and one for interleaved 8-bit U and V values. NV16/NV61 formats are very similar to NV12/NV21 with the exception that NV16/NV61 are using the same number of lines for both planes. The difference between NV16 and NV61 is the U and V byte order. The fourcc values are extrapolated from the NV12/NV21 case. Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e31144d22237..1f126e30766c 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -305,6 +305,8 @@ struct v4l2_pix_format { /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ /* The following formats are not defined in the V4L2 specification */ #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ -- cgit v1.2.3