V4L/DVB (8113): ivtv/cx18: remove s/g_ctrl, now all controls are handled through...
[pandora-kernel.git] / drivers / media / video / cx18 / cx18-controls.c
index 87cf410..f46c7e5 100644 (file)
@@ -51,12 +51,11 @@ static const u32 *ctrl_classes[] = {
        NULL
 };
 
-static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl)
+int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
 {
+       struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
        const char *name;
 
-       CX18_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
-
        qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
        if (qctrl->id == 0)
                return -EINVAL;
@@ -91,21 +90,35 @@ static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl)
        return 0;
 }
 
-static int cx18_querymenu(struct cx18 *cx, struct v4l2_querymenu *qmenu)
+int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
 {
+       struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
        struct v4l2_queryctrl qctrl;
 
        qctrl.id = qmenu->id;
-       cx18_queryctrl(cx, &qctrl);
-       return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
+       cx18_queryctrl(file, fh, &qctrl);
+       return v4l2_ctrl_query_menu(qmenu, &qctrl,
+                       cx2341x_ctrl_get_menu(&cx->params, qmenu->id));
 }
 
-static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
+static int cx18_try_ctrl(struct file *file, void *fh,
+                                       struct v4l2_ext_control *vctrl)
 {
-       s32 v = vctrl->value;
-
-       CX18_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
+       struct v4l2_queryctrl qctrl;
+       const char **menu_items = NULL;
+       int err;
+
+       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:
@@ -123,7 +136,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
                return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
 
        default:
-               CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+               CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
                return -EINVAL;
        }
        return 0;
@@ -131,8 +144,6 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
 
 static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
 {
-       CX18_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
-
        switch (vctrl->id) {
                /* Standard V4L2 controls */
        case V4L2_CID_BRIGHTNESS:
@@ -149,7 +160,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
        case V4L2_CID_AUDIO_LOUDNESS:
                return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
        default:
-               CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+               CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
                return -EINVAL;
        }
        return 0;
@@ -194,113 +205,110 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt
        return 0;
 }
 
-int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
 {
+       struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
        struct v4l2_control ctrl;
 
-       switch (cmd) {
-       case VIDIOC_QUERYMENU:
-               CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
-               return cx18_querymenu(cx, arg);
-
-       case VIDIOC_QUERYCTRL:
-               return cx18_queryctrl(cx, arg);
-
-       case VIDIOC_S_CTRL:
-               return cx18_s_ctrl(cx, arg);
-
-       case VIDIOC_G_CTRL:
-               return cx18_g_ctrl(cx, arg);
-
-       case VIDIOC_S_EXT_CTRLS:
-       {
-               struct v4l2_ext_controls *c = arg;
-
-               if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
-                       int i;
-                       int err = 0;
-
-                       for (i = 0; i < c->count; i++) {
-                               ctrl.id = c->controls[i].id;
-                               ctrl.value = c->controls[i].value;
-                               err = cx18_s_ctrl(cx, &ctrl);
-                               c->controls[i].value = ctrl.value;
-                               if (err) {
-                                       c->error_idx = i;
-                                       break;
-                               }
+       if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+               int i;
+               int err = 0;
+
+               for (i = 0; i < c->count; i++) {
+                       ctrl.id = c->controls[i].id;
+                       ctrl.value = c->controls[i].value;
+                       err = cx18_g_ctrl(cx, &ctrl);
+                       c->controls[i].value = ctrl.value;
+                       if (err) {
+                               c->error_idx = i;
+                               break;
                        }
-                       return err;
                }
-               CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
-               if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
-                       struct cx2341x_mpeg_params p = cx->params;
-                       int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd);
+               return err;
+       }
+       if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+               return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS);
+       return -EINVAL;
+}
 
-                       if (err)
-                               return err;
+int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+       struct cx18_open_id *id = fh;
+       struct cx18 *cx = id->cx;
+       int ret;
+       struct v4l2_control ctrl;
 
-                       if (p.video_encoding != cx->params.video_encoding) {
-                               int is_mpeg1 = p.video_encoding ==
-                                               V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
-                               struct v4l2_format fmt;
+       ret = v4l2_prio_check(&cx->prio, &id->prio);
+       if (ret)
+               return ret;
 
-                               /* fix videodecoder resolution */
-                               fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-                               fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1);
-                               fmt.fmt.pix.height = cx->params.height;
-                               cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
+       if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+               int i;
+               int err = 0;
+
+               for (i = 0; i < c->count; i++) {
+                       ctrl.id = c->controls[i].id;
+                       ctrl.value = c->controls[i].value;
+                       err = cx18_s_ctrl(cx, &ctrl);
+                       c->controls[i].value = ctrl.value;
+                       if (err) {
+                               c->error_idx = i;
+                               break;
                        }
-                       err = cx2341x_update(cx, cx18_api_func, &cx->params, &p);
-                       if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
-                               err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
-                       cx->params = p;
-                       cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
-                       cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
-                       return err;
                }
-               return -EINVAL;
+               return err;
        }
+       if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+               struct cx2341x_mpeg_params p = cx->params;
+               int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
+                                               c, VIDIOC_S_EXT_CTRLS);
 
-       case VIDIOC_G_EXT_CTRLS:
-       {
-               struct v4l2_ext_controls *c = arg;
-
-               if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
-                       int i;
-                       int err = 0;
-
-                       for (i = 0; i < c->count; i++) {
-                               ctrl.id = c->controls[i].id;
-                               ctrl.value = c->controls[i].value;
-                               err = cx18_g_ctrl(cx, &ctrl);
-                               c->controls[i].value = ctrl.value;
-                               if (err) {
-                                       c->error_idx = i;
-                                       break;
-                               }
-                       }
+               if (err)
                        return err;
+
+               if (p.video_encoding != cx->params.video_encoding) {
+                       int is_mpeg1 = p.video_encoding ==
+                                               V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+                       struct v4l2_format fmt;
+
+                       /* fix videodecoder resolution */
+                       fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                       fmt.fmt.pix.width = cx->params.width
+                                               / (is_mpeg1 ? 2 : 1);
+                       fmt.fmt.pix.height = cx->params.height;
+                       cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
                }
-               CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
-               if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
-                       return cx2341x_ext_ctrls(&cx->params, 0, arg, cmd);
-               return -EINVAL;
+               err = cx2341x_update(cx, cx18_api_func, &cx->params, &p);
+               if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
+                       err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
+               cx->params = p;
+               cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
+               cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
+               return err;
        }
+       return -EINVAL;
+}
 
-       case VIDIOC_TRY_EXT_CTRLS:
-       {
-               struct v4l2_ext_controls *c = arg;
+int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+       struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
 
-               CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
-               if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
-                       return cx2341x_ext_ctrls(&cx->params,
-                                       atomic_read(&cx->ana_capturing), arg, cmd);
-               return -EINVAL;
-       }
+       if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+               int i;
+               int err = 0;
 
-       default:
-               return -EINVAL;
+               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;
        }
-       return 0;
+       if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+               return cx2341x_ext_ctrls(&cx->params,
+                                               atomic_read(&cx->ana_capturing),
+                                               c, VIDIOC_TRY_EXT_CTRLS);
+       return -EINVAL;
 }