]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/ivtv/ivtv-controls.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / media / video / ivtv / ivtv-controls.c
index 06723bac99c59b2cf6972955d7cecc20dc96a33e..48e103be718340fe0db30394d5b2b989912c8697 100644 (file)
@@ -53,8 +53,6 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
        struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
        const char *name;
 
-       IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
-
        qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
        if (qctrl->id == 0)
                return -EINVAL;
@@ -94,19 +92,30 @@ int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
        struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
        struct v4l2_queryctrl qctrl;
 
-       IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
        qctrl.id = qmenu->id;
        ivtv_queryctrl(file, fh, &qctrl);
-       return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
+       return v4l2_ctrl_query_menu(qmenu, &qctrl,
+                       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;
-       s32 v = vctrl->value;
+       struct v4l2_queryctrl qctrl;
+       const char **menu_items = NULL;
+       int err;
 
-       IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
+       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:
@@ -124,18 +133,14 @@ int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl)
                return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
 
        default:
-               IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+               IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
                return -EINVAL;
        }
        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;
-
-       IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
-
        switch (vctrl->id) {
                /* Standard V4L2 controls */
        case V4L2_CID_BRIGHTNESS:
@@ -152,7 +157,7 @@ int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl)
        case V4L2_CID_AUDIO_LOUDNESS:
                return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
        default:
-               IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+               IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
                return -EINVAL;
        }
        return 0;
@@ -210,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;
@@ -219,7 +224,6 @@ int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
                }
                return err;
        }
-       IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
        if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
                return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS);
        return -EINVAL;
@@ -237,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;
@@ -246,7 +250,6 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
                }
                return err;
        }
-       IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
        if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
                static u32 freqs[3] = { 44100, 48000, 32000 };
                struct cx2341x_mpeg_params p = itv->params;
@@ -286,7 +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;
 
-       IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
+       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;