diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-06-25 08:34:21 +0200 |
---|---|---|
committer | Hans Verkuil <hverkuil@xs4all.nl> | 2008-06-25 08:34:21 +0200 |
commit | d85faf11b1d744c74c448af9265e260d65aa5f56 (patch) | |
tree | 4c5a97a685ee963fa65d3f20b2b49288f09d3386 | |
parent | ec60e6b02c25b351b679f2f9711e7885e75bf783 (diff) | |
parent | 8e1e0865374be3b41a1712ac4823598e21a817c7 (diff) | |
download | mediapointer-dvb-s2-d85faf11b1d744c74c448af9265e260d65aa5f56.tar.gz mediapointer-dvb-s2-d85faf11b1d744c74c448af9265e260d65aa5f56.tar.bz2 |
Merge: from http://linuxtv.org/hg/~awalls/v4l-dvb
From: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-controls.c | 43 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-controls.h | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-ioctl.c | 44 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-controls.c | 39 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-controls.h | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-ioctl.c | 61 | ||||
-rw-r--r-- | linux/drivers/media/video/videodev.c | 85 |
7 files changed, 188 insertions, 88 deletions
diff --git a/linux/drivers/media/video/cx18/cx18-controls.c b/linux/drivers/media/video/cx18/cx18-controls.c index 855313359..f46c7e5ed 100644 --- a/linux/drivers/media/video/cx18/cx18-controls.c +++ b/linux/drivers/media/video/cx18/cx18-controls.c @@ -101,16 +101,24 @@ int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) cx2341x_ctrl_get_menu(&cx->params, qmenu->id)); } -int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int cx18_try_ctrl(struct file *file, void *fh, + struct v4l2_ext_control *vctrl) { - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; + struct v4l2_queryctrl qctrl; + const char **menu_items = NULL; + int err; - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; + qctrl.id = vctrl->id; + err = cx18_queryctrl(file, fh, &qctrl); + if (err) + return err; + if (qctrl.type == V4L2_CTRL_TYPE_MENU) + menu_items = v4l2_ctrl_get_menu(qctrl.id); + return v4l2_ctrl_check(vctrl, &qctrl, menu_items); +} +static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) +{ switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -134,10 +142,8 @@ int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) return 0; } -int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -211,7 +217,7 @@ int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = cx18_g_ctrl(file, fh, &ctrl); + err = cx18_g_ctrl(cx, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -243,7 +249,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = cx18_s_ctrl(file, fh, &ctrl); + err = cx18_s_ctrl(cx, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -287,6 +293,19 @@ int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + err = cx18_try_ctrl(file, fh, &c->controls[i]); + if (err) { + c->error_idx = i; + break; + } + } + return err; + } if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&cx->params, atomic_read(&cx->ana_capturing), diff --git a/linux/drivers/media/video/cx18/cx18-controls.h b/linux/drivers/media/video/cx18/cx18-controls.h index 81b8996e5..e46323700 100644 --- a/linux/drivers/media/video/cx18/cx18-controls.h +++ b/linux/drivers/media/video/cx18/cx18-controls.h @@ -22,8 +22,6 @@ */ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); -int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); -int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int cx18_try_ext_ctrls(struct file *file, void *fh, diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 078f3cd7d..b3d72d4a4 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -128,25 +128,6 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) return set; } -static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) -{ - struct v4l2_register *regs = arg; - unsigned long flags; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) - return -EINVAL; - - spin_lock_irqsave(&cx18_cards_lock, flags); - if (cmd == VIDIOC_DBG_G_REGISTER) - regs->val = read_enc(regs->reg); - else - write_enc(regs->val, regs->reg); - spin_unlock_irqrestore(&cx18_cards_lock, flags); - return 0; -} - static int cx18_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) { @@ -364,6 +345,26 @@ static int cx18_g_chip_ident(struct file *file, void *fh, return -EINVAL; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) +{ + struct v4l2_register *regs = arg; + unsigned long flags; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) + return -EINVAL; + + spin_lock_irqsave(&cx18_cards_lock, flags); + if (cmd == VIDIOC_DBG_G_REGISTER) + regs->val = read_enc(regs->reg); + else + write_enc(regs->val, regs->reg); + spin_unlock_irqrestore(&cx18_cards_lock, flags); + return 0; +} + static int cx18_g_register(struct file *file, void *fh, struct v4l2_register *reg) { @@ -391,6 +392,7 @@ static int cx18_s_register(struct file *file, void *fh, return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); } +#endif static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p) { @@ -915,13 +917,13 @@ void cx18_set_funcs(struct video_device *vdev) vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap; vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap; vdev->vidioc_g_chip_ident = cx18_g_chip_ident; +#ifdef CONFIG_VIDEO_ADV_DEBUG vdev->vidioc_g_register = cx18_g_register; vdev->vidioc_s_register = cx18_s_register; +#endif vdev->vidioc_default = cx18_default; vdev->vidioc_queryctrl = cx18_queryctrl; vdev->vidioc_querymenu = cx18_querymenu; - vdev->vidioc_g_ctrl = cx18_g_ctrl; - vdev->vidioc_s_ctrl = cx18_s_ctrl; vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls; vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls; vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls; diff --git a/linux/drivers/media/video/ivtv/ivtv-controls.c b/linux/drivers/media/video/ivtv/ivtv-controls.c index 6a5b70912..48e103be7 100644 --- a/linux/drivers/media/video/ivtv/ivtv-controls.c +++ b/linux/drivers/media/video/ivtv/ivtv-controls.c @@ -98,10 +98,24 @@ int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) cx2341x_ctrl_get_menu(&itv->params, qmenu->id)); } -int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int ivtv_try_ctrl(struct file *file, void *fh, + struct v4l2_ext_control *vctrl) { - struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_queryctrl qctrl; + const char **menu_items = NULL; + int err; + + qctrl.id = vctrl->id; + err = ivtv_queryctrl(file, fh, &qctrl); + if (err) + return err; + if (qctrl.type == V4L2_CTRL_TYPE_MENU) + menu_items = v4l2_ctrl_get_menu(qctrl.id); + return v4l2_ctrl_check(vctrl, &qctrl, menu_items); +} +static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) +{ switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -125,10 +139,8 @@ int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) return 0; } -int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) { - struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -203,7 +215,7 @@ int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = ivtv_g_ctrl(file, fh, &ctrl); + err = ivtv_g_ctrl(itv, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -229,7 +241,7 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = ivtv_s_ctrl(file, fh, &ctrl); + err = ivtv_s_ctrl(itv, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -277,6 +289,19 @@ int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + err = ivtv_try_ctrl(file, fh, &c->controls[i]); + if (err) { + c->error_idx = i; + break; + } + } + return err; + } if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS); return -EINVAL; diff --git a/linux/drivers/media/video/ivtv/ivtv-controls.h b/linux/drivers/media/video/ivtv/ivtv-controls.h index 304204be6..1c7721e23 100644 --- a/linux/drivers/media/video/ivtv/ivtv-controls.h +++ b/linux/drivers/media/video/ivtv/ivtv-controls.h @@ -22,8 +22,6 @@ #define IVTV_CONTROLS_H int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); -int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); -int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 8d602cb6b..52e00a7f3 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -314,34 +314,6 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, return 0; } -static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) -{ - struct v4l2_register *regs = arg; - unsigned long flags; - volatile u8 __iomem *reg_start; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE) - reg_start = itv->reg_mem - IVTV_REG_OFFSET; - else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && - regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) - reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; - else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) - reg_start = itv->enc_mem; - else - return -EINVAL; - - spin_lock_irqsave(&ivtv_cards_lock, flags); - if (cmd == VIDIOC_DBG_G_REGISTER) { - regs->val = readl(regs->reg + reg_start); - } else { - writel(regs->val, regs->reg + reg_start); - } - spin_unlock_irqrestore(&ivtv_cards_lock, flags); - return 0; -} - static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; @@ -715,6 +687,34 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident return -EINVAL; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) +{ + struct v4l2_register *regs = arg; + unsigned long flags; + volatile u8 __iomem *reg_start; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE) + reg_start = itv->reg_mem - IVTV_REG_OFFSET; + else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && + regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) + reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; + else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) + reg_start = itv->enc_mem; + else + return -EINVAL; + + spin_lock_irqsave(&ivtv_cards_lock, flags); + if (cmd == VIDIOC_DBG_G_REGISTER) + regs->val = readl(regs->reg + reg_start); + else + writel(regs->val, regs->reg + reg_start); + spin_unlock_irqrestore(&ivtv_cards_lock, flags); + return 0; +} + static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; @@ -736,6 +736,7 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *re return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); } +#endif static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p) { @@ -1896,13 +1897,13 @@ void ivtv_set_funcs(struct video_device *vdev) vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out; vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap; vdev->vidioc_g_chip_ident = ivtv_g_chip_ident; +#ifdef CONFIG_VIDEO_ADV_DEBUG vdev->vidioc_g_register = ivtv_g_register; vdev->vidioc_s_register = ivtv_s_register; +#endif vdev->vidioc_default = ivtv_default; vdev->vidioc_queryctrl = ivtv_queryctrl; vdev->vidioc_querymenu = ivtv_querymenu; - vdev->vidioc_g_ctrl = ivtv_g_ctrl; - vdev->vidioc_s_ctrl = ivtv_s_ctrl; vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls; vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls; vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls; diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 273125f76..e54016432 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -748,6 +748,29 @@ static inline void v4l_print_ext_ctrls(unsigned int cmd, printk(KERN_CONT "\n"); }; +static inline int check_ext_ctrls(struct v4l2_ext_controls *c) +{ + __u32 i; + + /* zero the reserved fields */ + c->reserved[0] = c->reserved[1] = 0; + for (i = 0; i < c->count; i++) { + c->controls[i].reserved2[0] = 0; + c->controls[i].reserved2[1] = 0; + } + /* V4L2_CID_PRIVATE_BASE cannot be used as control class + * when using extended controls. */ + if (c->ctrl_class == V4L2_CID_PRIVATE_BASE) + return 0; + /* Check that all controls are from the same control class. */ + for (i = 0; i < c->count; i++) { + if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { + c->error_idx = i; + return 0; + } + } + return 1; +} static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) { @@ -1430,10 +1453,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_control *p = arg; - if (!vfd->vidioc_g_ctrl) + if (vfd->vidioc_g_ctrl) + ret = vfd->vidioc_g_ctrl(file, fh, p); + else if (vfd->vidioc_g_ext_ctrls) { + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls)) { + ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); + if (ret == 0) + p->value = ctrl.value; + } + } else break; - - ret = vfd->vidioc_g_ctrl(file, fh, p); if (!ret) dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); else @@ -1443,21 +1480,39 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_S_CTRL: { struct v4l2_control *p = arg; + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; - if (!vfd->vidioc_s_ctrl) + if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) break; + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - ret = vfd->vidioc_s_ctrl(file, fh, p); + if (vfd->vidioc_s_ctrl) { + ret = vfd->vidioc_s_ctrl(file, fh, p); + break; + } + if (!vfd->vidioc_s_ext_ctrls) + break; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls)) + ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); break; } case VIDIOC_G_EXT_CTRLS: { struct v4l2_ext_controls *p = arg; + p->error_idx = p->count; if (!vfd->vidioc_g_ext_ctrls) break; - ret = vfd->vidioc_g_ext_ctrls(file, fh, p); + if (check_ext_ctrls(p)) + ret = vfd->vidioc_g_ext_ctrls(file, fh, p); v4l_print_ext_ctrls(cmd, vfd, p, !ret); break; } @@ -1465,22 +1520,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_ext_controls *p = arg; - if (vfd->vidioc_s_ext_ctrls) { - v4l_print_ext_ctrls(cmd, vfd, p, 1); - + p->error_idx = p->count; + if (!vfd->vidioc_s_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (check_ext_ctrls(p)) ret = vfd->vidioc_s_ext_ctrls(file, fh, p); - } break; } case VIDIOC_TRY_EXT_CTRLS: { struct v4l2_ext_controls *p = arg; - if (vfd->vidioc_try_ext_ctrls) { - v4l_print_ext_ctrls(cmd, vfd, p, 1); - + p->error_idx = p->count; + if (!vfd->vidioc_try_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (check_ext_ctrls(p)) ret = vfd->vidioc_try_ext_ctrls(file, fh, p); - } break; } case VIDIOC_QUERYMENU: |