V4L/DVB (8079): ivtv: Convert to video_ioctl2.
authorHans Verkuil <hverkuil@xs4all.nl>
Thu, 29 May 2008 19:43:54 +0000 (16:43 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Sun, 20 Jul 2008 10:10:31 +0000 (07:10 -0300)
Based on an initial conversion patch from Douglas Landgraf.

Signed-off-by: Douglas Schilling Landgraf <dougsland@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/ivtv/ivtv-controls.c
drivers/media/video/ivtv/ivtv-controls.h
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-ioctl.c
drivers/media/video/ivtv/ivtv-ioctl.h
drivers/media/video/ivtv/ivtv-streams.c

index c7e449f..06723ba 100644 (file)
@@ -47,8 +47,10 @@ static const u32 *ctrl_classes[] = {
        NULL
 };
 
-static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
+
+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);
@@ -87,17 +89,20 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
        return 0;
 }
 
-static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu)
+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(itv, &qctrl);
+       ivtv_queryctrl(file, fh, &qctrl);
        return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
 }
 
-static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
+int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl)
 {
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
        s32 v = vctrl->value;
 
        IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
@@ -125,8 +130,10 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
        return 0;
 }
 
-static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
+int ivtv_g_ctrl(struct file *file, void *fh, 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) {
@@ -191,119 +198,96 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
        return 0;
 }
 
-int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
+int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
 {
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
        struct v4l2_control ctrl;
 
-       switch (cmd) {
-       case VIDIOC_QUERYMENU:
-               IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
-               return ivtv_querymenu(itv, arg);
-
-       case VIDIOC_QUERYCTRL:
-               return ivtv_queryctrl(itv, arg);
-
-       case VIDIOC_S_CTRL:
-               return ivtv_s_ctrl(itv, arg);
-
-       case VIDIOC_G_CTRL:
-               return ivtv_g_ctrl(itv, 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 = ivtv_s_ctrl(itv, &ctrl);
-                               c->controls[i].value = ctrl.value;
-                               if (err) {
-                                       c->error_idx = i;
-                                       break;
-                               }
-                       }
-                       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;
-                       int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd);
-                       unsigned idx;
-
-                       if (err)
-                               return err;
-
-                       if (p.video_encoding != itv->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 = itv->params.width / (is_mpeg1 ? 2 : 1);
-                               fmt.fmt.pix.height = itv->params.height;
-                               itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
-                       }
-                       err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
-                       if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) {
-                               err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_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 = ivtv_g_ctrl(file, fh, &ctrl);
+                       c->controls[i].value = ctrl.value;
+                       if (err) {
+                               c->error_idx = i;
+                               break;
                        }
-                       itv->params = p;
-                       itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
-                       idx = p.audio_properties & 0x03;
-                       /* The audio clock of the digitizer must match the codec sample
-                          rate otherwise you get some very strange effects. */
-                       if (idx < sizeof(freqs))
-                           ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
-                       return err;
                }
-               return -EINVAL;
+               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;
+}
 
-       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 = ivtv_g_ctrl(itv, &ctrl);
-                               c->controls[i].value = ctrl.value;
-                               if (err) {
-                                       c->error_idx = i;
-                                       break;
-                               }
+int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       struct v4l2_control ctrl;
+
+       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 = ivtv_s_ctrl(file, fh, &ctrl);
+                       c->controls[i].value = ctrl.value;
+                       if (err) {
+                               c->error_idx = i;
+                               break;
                        }
-                       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, arg, cmd);
-               return -EINVAL;
+               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;
+               int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS);
+               unsigned idx;
+
+               if (err)
+                       return err;
 
-       case VIDIOC_TRY_EXT_CTRLS:
-       {
-               struct v4l2_ext_controls *c = arg;
+               if (p.video_encoding != itv->params.video_encoding) {
+                       int is_mpeg1 = p.video_encoding ==
+                               V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+                       struct v4l2_format fmt;
 
-               IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
-               if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
-                       return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd);
-               return -EINVAL;
+                       /* fix videodecoder resolution */
+                       fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+                       fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
+                       fmt.fmt.pix.height = itv->params.height;
+                       itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
+               }
+               err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
+               if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
+                       err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
+               itv->params = p;
+               itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
+               idx = p.audio_properties & 0x03;
+               /* The audio clock of the digitizer must match the codec sample
+                  rate otherwise you get some very strange effects. */
+               if (idx < sizeof(freqs))
+                       ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
+               return err;
        }
+       return -EINVAL;
+}
 
-       default:
-               return -EINVAL;
-       }
-       return 0;
+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_MPEG)
+               return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS);
+       return -EINVAL;
 }
index bb8a6a5..304204b 100644 (file)
 #ifndef IVTV_CONTROLS_H
 #define IVTV_CONTROLS_H
 
-int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg);
+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);
+int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
 
 #endif
index 323dd68..9e6a649 100644 (file)
@@ -1262,9 +1262,13 @@ err:
 int ivtv_init_on_first_open(struct ivtv *itv)
 {
        struct v4l2_frequency vf;
+       /* Needed to call ioctls later */
+       struct ivtv_open_id fh;
        int fw_retry_count = 3;
        int video_input;
 
+       fh.itv = itv;
+
        if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
                return -ENXIO;
 
@@ -1312,18 +1316,18 @@ int ivtv_init_on_first_open(struct ivtv *itv)
 
        video_input = itv->active_input;
        itv->active_input++;    /* Force update of input */
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input);
+       ivtv_s_input(NULL, &fh, video_input);
 
        /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
           in one place. */
        itv->std++;             /* Force full standard initialization */
        itv->std_out = itv->std;
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf);
+       ivtv_s_frequency(NULL, &fh, &vf);
 
        if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
                ivtv_init_mpeg_decoder(itv);
        }
-       ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std);
+       ivtv_s_std(NULL, &fh, &itv->tuner_std);
 
        /* On a cx23416 this seems to be able to enable DMA to the chip? */
        if (!itv->has_cx23415)
index 26cc0f6..49b297e 100644 (file)
@@ -373,267 +373,172 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
        return 0;
 }
 
-static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt)
+static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
 {
-       switch (fmt->type) {
-       case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-                       return -EINVAL;
-               fmt->fmt.pix.width = itv->main_rect.width;
-               fmt->fmt.pix.height = itv->main_rect.height;
-               fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
-               if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
-                       switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
-                       case IVTV_YUV_MODE_INTERLACED:
-                               fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
-                                       V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
-                               break;
-                       case IVTV_YUV_MODE_PROGRESSIVE:
-                               fmt->fmt.pix.field = V4L2_FIELD_NONE;
-                               break;
-                       default:
-                               fmt->fmt.pix.field = V4L2_FIELD_ANY;
-                               break;
-                       }
-                       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
-                       fmt->fmt.pix.bytesperline = 720;
-                       fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w;
-                       fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h;
-                       /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
-                       fmt->fmt.pix.sizeimage =
-                               1080 * ((fmt->fmt.pix.height + 31) & ~31);
-               } else if (streamtype == IVTV_ENC_STREAM_TYPE_YUV) {
-                       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
-                       /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
-                       fmt->fmt.pix.sizeimage =
-                               fmt->fmt.pix.height * fmt->fmt.pix.width +
-                               fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
-               } else {
-                       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
-                       fmt->fmt.pix.sizeimage = 128 * 1024;
-               }
-               break;
-
-       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-               fmt->fmt.pix.width = itv->params.width;
-               fmt->fmt.pix.height = itv->params.height;
-               fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-               fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
-               if (streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
-                               streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
-                       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
-                       /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
-                       fmt->fmt.pix.sizeimage =
-                               fmt->fmt.pix.height * fmt->fmt.pix.width +
-                               fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
-               } else {
-                       fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
-                       fmt->fmt.pix.sizeimage = 128 * 1024;
-               }
-               break;
-
-       case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-                       return -EINVAL;
-               fmt->fmt.win.chromakey = itv->osd_chroma_key;
-               fmt->fmt.win.global_alpha = itv->osd_global_alpha;
-               break;
-
-       case V4L2_BUF_TYPE_VBI_CAPTURE:
-               fmt->fmt.vbi.sampling_rate = 27000000;
-               fmt->fmt.vbi.offset = 248;
-               fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
-               fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
-               fmt->fmt.vbi.start[0] = itv->vbi.start[0];
-               fmt->fmt.vbi.start[1] = itv->vbi.start[1];
-               fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
-               break;
-
-       case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
-       {
-               struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 
-               if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
-                       return -EINVAL;
-               vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
-               memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
-               memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
-               if (itv->is_60hz) {
-                       vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
-                       vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
-               } else {
-                       vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
-                       vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
-               }
-               vbifmt->service_set = ivtv_get_service_set(vbifmt);
-               break;
+       if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
+               return -EINVAL;
+       vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+       if (itv->is_60hz) {
+               vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+               vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+       } else {
+               vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
+               vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
        }
+       vbifmt->service_set = ivtv_get_service_set(vbifmt);
+       return 0;
+}
 
-       case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
-       {
-               struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-
-               vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
-               memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
-               memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
-
-               if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
-                       vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
-                                                V4L2_SLICED_VBI_525;
-                       ivtv_expand_service_set(vbifmt, itv->is_50hz);
-                       break;
-               }
+static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-               itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
-               vbifmt->service_set = ivtv_get_service_set(vbifmt);
-               break;
-       }
-       case V4L2_BUF_TYPE_VBI_OUTPUT:
-       case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-       default:
-               return -EINVAL;
+       fmt->fmt.pix.width = itv->params.width;
+       fmt->fmt.pix.height = itv->params.height;
+       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       if (id->type == IVTV_ENC_STREAM_TYPE_YUV ||
+                       id->type == IVTV_DEC_STREAM_TYPE_YUV) {
+               fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
+               /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
+               fmt->fmt.pix.sizeimage =
+                       fmt->fmt.pix.height * fmt->fmt.pix.width +
+                       fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
+       } else {
+               fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+               fmt->fmt.pix.sizeimage = 128 * 1024;
        }
        return 0;
 }
 
-static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
-               struct v4l2_format *fmt, int set_fmt)
+static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
 {
-       struct yuv_playback_info *yi = &itv->yuv_info;
-       struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
-       u16 set;
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       fmt->fmt.vbi.sampling_rate = 27000000;
+       fmt->fmt.vbi.offset = 248;
+       fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
+       fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+       fmt->fmt.vbi.start[0] = itv->vbi.start[0];
+       fmt->fmt.vbi.start[1] = itv->vbi.start[1];
+       fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
+       return 0;
+}
 
-       if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
-               struct v4l2_rect r;
-               int field;
+static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-                       return -EINVAL;
-               field = fmt->fmt.pix.field;
-               r.top = 0;
-               r.left = 0;
-               r.width = fmt->fmt.pix.width;
-               r.height = fmt->fmt.pix.height;
-               ivtv_get_fmt(itv, streamtype, fmt);
-               fmt->fmt.pix.width = r.width;
-               fmt->fmt.pix.height = r.height;
-               if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
-                       fmt->fmt.pix.field = field;
-                       if (fmt->fmt.pix.width < 2)
-                               fmt->fmt.pix.width = 2;
-                       if (fmt->fmt.pix.width > 720)
-                               fmt->fmt.pix.width = 720;
-                       if (fmt->fmt.pix.height < 2)
-                               fmt->fmt.pix.height = 2;
-                       if (fmt->fmt.pix.height > 576)
-                               fmt->fmt.pix.height = 576;
-               }
-               if (set_fmt && streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
-                       /* Return now if we already have some frame data */
-                       if (yi->stream_size)
-                               return -EBUSY;
+       vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
 
-                       yi->v4l2_src_w = r.width;
-                       yi->v4l2_src_h = r.height;
+       if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
+               vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
+                       V4L2_SLICED_VBI_525;
+               ivtv_expand_service_set(vbifmt, itv->is_50hz);
+               return 0;
+       }
 
-                       switch (field) {
-                       case V4L2_FIELD_NONE:
-                               yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
-                               break;
-                       case V4L2_FIELD_ANY:
-                               yi->lace_mode = IVTV_YUV_MODE_AUTO;
-                               break;
-                       case V4L2_FIELD_INTERLACED_BT:
-                               yi->lace_mode =
-                                    IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
-                               break;
-                       case V4L2_FIELD_INTERLACED_TB:
-                       default:
-                               yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
-                               break;
-                       }
-                       yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
+       itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
+       vbifmt->service_set = ivtv_get_service_set(vbifmt);
+       return 0;
+}
 
-                       if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
-                               itv->dma_data_req_size =
-                                          1080 * ((yi->v4l2_src_h + 31) & ~31);
+static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-                       /* Force update of yuv registers */
-                       yi->yuv_forced_update = 1;
-                       return 0;
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return -EINVAL;
+       fmt->fmt.pix.width = itv->main_rect.width;
+       fmt->fmt.pix.height = itv->main_rect.height;
+       fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
+               switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
+               case IVTV_YUV_MODE_INTERLACED:
+                       fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
+                               V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
+                       break;
+               case IVTV_YUV_MODE_PROGRESSIVE:
+                       fmt->fmt.pix.field = V4L2_FIELD_NONE;
+                       break;
+               default:
+                       fmt->fmt.pix.field = V4L2_FIELD_ANY;
+                       break;
                }
-               return 0;
+               fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
+               fmt->fmt.pix.bytesperline = 720;
+               fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w;
+               fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h;
+               /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
+               fmt->fmt.pix.sizeimage =
+                       1080 * ((fmt->fmt.pix.height + 31) & ~31);
+       } else if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
+               fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
+               /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
+               fmt->fmt.pix.sizeimage =
+                       fmt->fmt.pix.height * fmt->fmt.pix.width +
+                       fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
+       } else {
+               fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+               fmt->fmt.pix.sizeimage = 128 * 1024;
        }
+       return 0;
+}
 
-       if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) {
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-                       return -EINVAL;
-               if (set_fmt) {
-                       itv->osd_chroma_key = fmt->fmt.win.chromakey;
-                       itv->osd_global_alpha = fmt->fmt.win.global_alpha;
-                       ivtv_set_osd_alpha(itv);
-               }
-               return 0;
-       }
+static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       /* set window size */
-       if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-               struct cx2341x_mpeg_params *p = &itv->params;
-               int w = fmt->fmt.pix.width;
-               int h = fmt->fmt.pix.height;
-
-               if (w > 720) w = 720;
-               else if (w < 1) w = 1;
-               if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480);
-               else if (h < 2) h = 2;
-               ivtv_get_fmt(itv, streamtype, fmt);
-               fmt->fmt.pix.width = w;
-               fmt->fmt.pix.height = h;
-
-               if (!set_fmt || (p->width == w && p->height == h))
-                       return 0;
-               if (atomic_read(&itv->capturing) > 0)
-                       return -EBUSY;
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return -EINVAL;
+       fmt->fmt.win.chromakey = itv->osd_chroma_key;
+       fmt->fmt.win.global_alpha = itv->osd_global_alpha;
+       return 0;
+}
 
-               p->width = w;
-               p->height = h;
-               if (w != 720 || h != (itv->is_50hz ? 576 : 480))
-                       p->video_temporal_filter = 0;
-               else
-                       p->video_temporal_filter = 8;
-               if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
-                       fmt->fmt.pix.width /= 2;
-               itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
-               return ivtv_get_fmt(itv, streamtype, fmt);
-       }
+static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
+}
 
-       /* set raw VBI format */
-       if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
-               if (set_fmt && atomic_read(&itv->capturing) > 0) {
-                       return -EBUSY;
-               }
-               if (set_fmt) {
-                       itv->vbi.sliced_in->service_set = 0;
-                       itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
-               }
-               return ivtv_get_fmt(itv, streamtype, fmt);
-       }
+static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       int w = fmt->fmt.pix.width;
+       int h = fmt->fmt.pix.height;
+
+       w = min(w, 720);
+       w = max(w, 1);
+       h = min(h, itv->is_50hz ? 576 : 480);
+       h = max(h, 2);
+       ivtv_g_fmt_vid_cap(file, fh, fmt);
+       fmt->fmt.pix.width = w;
+       fmt->fmt.pix.height = h;
+       return 0;
+}
 
-       /* set sliced VBI output
-          In principle the user could request that only certain
-          VBI types are output and that the others are ignored.
-          I.e., suppress CC in the even fields or only output
-          WSS and no VPS. Currently though there is no choice. */
-       if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
-               return ivtv_get_fmt(itv, streamtype, fmt);
+static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       return ivtv_g_fmt_vbi_cap(file, fh, fmt);
+}
 
-       /* any else but sliced VBI capture is an error */
-       if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
-               return -EINVAL;
+static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-       if (streamtype == IVTV_DEC_STREAM_TYPE_VBI)
-               return ivtv_get_fmt(itv, streamtype, fmt);
+       if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
+               return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
 
        /* set sliced VBI capture format */
        vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
@@ -641,777 +546,997 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
 
        if (vbifmt->service_set)
                ivtv_expand_service_set(vbifmt, itv->is_50hz);
-       set = check_service_set(vbifmt, itv->is_50hz);
+       check_service_set(vbifmt, itv->is_50hz);
        vbifmt->service_set = ivtv_get_service_set(vbifmt);
+       return 0;
+}
+
+static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv_open_id *id = fh;
+       s32 w, h;
+       int field;
+       int ret;
+
+       w = fmt->fmt.pix.width;
+       h = fmt->fmt.pix.height;
+       field = fmt->fmt.pix.field;
+       ret = ivtv_g_fmt_vid_out(file, fh, fmt);
+       fmt->fmt.pix.width = w;
+       fmt->fmt.pix.height = h;
+       if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) {
+               fmt->fmt.pix.field = field;
+               if (fmt->fmt.pix.width < 2)
+                       fmt->fmt.pix.width = 2;
+               if (fmt->fmt.pix.width > 720)
+                       fmt->fmt.pix.width = 720;
+               if (fmt->fmt.pix.height < 2)
+                       fmt->fmt.pix.height = 2;
+               if (fmt->fmt.pix.height > 576)
+                       fmt->fmt.pix.height = 576;
+       }
+       return ret;
+}
+
+static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       if (!set_fmt)
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return -EINVAL;
+       return 0;
+}
+
+static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
+}
+
+static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       struct cx2341x_mpeg_params *p = &itv->params;
+       int w = fmt->fmt.pix.width;
+       int h = fmt->fmt.pix.height;
+       int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
+
+       if (ret)
+               return ret;
+
+       if (p->width == w && p->height == h)
                return 0;
-       if (set == 0)
+
+       if (atomic_read(&itv->capturing) > 0)
+               return -EBUSY;
+
+       p->width = w;
+       p->height = h;
+       if (w != 720 || h != (itv->is_50hz ? 576 : 480))
+               p->video_temporal_filter = 0;
+       else
+               p->video_temporal_filter = 8;
+       if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+               fmt->fmt.pix.width /= 2;
+       itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
+       return ivtv_g_fmt_vid_cap(file, fh, fmt);
+}
+
+static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       itv->vbi.sliced_in->service_set = 0;
+       itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
+       return ivtv_g_fmt_vbi_cap(file, fh, fmt);
+}
+
+static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
+{
+       struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+       if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
+               return ret;
+
+       if (check_service_set(vbifmt, itv->is_50hz) == 0)
                return -EINVAL;
-       if (atomic_read(&itv->capturing) > 0) {
+       if (atomic_read(&itv->capturing) > 0)
                return -EBUSY;
-       }
        itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
        memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
        return 0;
 }
 
-static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
+static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
 {
-       struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
+       struct ivtv_open_id *id = fh;
        struct ivtv *itv = id->itv;
-       struct v4l2_register *reg = arg;
+       struct yuv_playback_info *yi = &itv->yuv_info;
+       int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
 
-       switch (cmd) {
-       /* ioctls to allow direct access to the encoder registers for testing */
-       case VIDIOC_DBG_G_REGISTER:
-               if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
-                       return ivtv_itvc(itv, cmd, arg);
-               if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
-                       return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
-               return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
-
-       case VIDIOC_DBG_S_REGISTER:
-               if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
-                       return ivtv_itvc(itv, cmd, arg);
-               if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
-                       return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
-               return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
-
-       case VIDIOC_G_CHIP_IDENT: {
-               struct v4l2_chip_ident *chip = arg;
-
-               chip->ident = V4L2_IDENT_NONE;
-               chip->revision = 0;
-               if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
-                       if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
-                               chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
-                       return 0;
-               }
-               if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
-                       return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
-               if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
-                       return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
-               return -EINVAL;
-       }
+       if (ret)
+               return ret;
 
-       case VIDIOC_INT_S_AUDIO_ROUTING: {
-               struct v4l2_routing *route = arg;
+       if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
+               return 0;
 
-               ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
-               break;
-       }
+       /* Return now if we already have some frame data */
+       if (yi->stream_size)
+               return -EBUSY;
 
-       case VIDIOC_INT_RESET: {
-               u32 val = *(u32 *)arg;
+       yi->v4l2_src_w = fmt->fmt.pix.width;
+       yi->v4l2_src_h = fmt->fmt.pix.height;
 
-               if ((val == 0 && itv->options.newi2c) || (val & 0x01)) {
-                       ivtv_reset_ir_gpio(itv);
-               }
-               if (val & 0x02) {
-                       itv->video_dec_func(itv, cmd, NULL);
-               }
+       switch (fmt->fmt.pix.field) {
+       case V4L2_FIELD_NONE:
+               yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
                break;
-       }
-
+       case V4L2_FIELD_ANY:
+               yi->lace_mode = IVTV_YUV_MODE_AUTO;
+               break;
+       case V4L2_FIELD_INTERLACED_BT:
+               yi->lace_mode =
+                       IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
+               break;
+       case V4L2_FIELD_INTERLACED_TB:
        default:
-               return -EINVAL;
+               yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
+               break;
        }
+       yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
+
+       if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
+               itv->dma_data_req_size =
+                       1080 * ((yi->v4l2_src_h + 31) & ~31);
+
+       /* Force update of yuv registers */
+       yi->yuv_forced_update = 1;
        return 0;
 }
 
-int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
+static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
 {
-       struct ivtv_open_id *id = NULL;
-       struct yuv_playback_info *yi = &itv->yuv_info;
-       u32 data[CX2341X_MBOX_MAX_DATA];
-       int streamtype = 0;
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
 
-       if (filp) {
-               id = (struct ivtv_open_id *)filp->private_data;
-               streamtype = id->type;
+       if (ret == 0) {
+               itv->osd_chroma_key = fmt->fmt.win.chromakey;
+               itv->osd_global_alpha = fmt->fmt.win.global_alpha;
+               ivtv_set_osd_alpha(itv);
        }
+       return ret;
+}
 
-       switch (cmd) {
-       case VIDIOC_G_PRIORITY:
-       {
-               enum v4l2_priority *p = arg;
+static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-               *p = v4l2_prio_max(&itv->prio);
-               break;
+       chip->ident = V4L2_IDENT_NONE;
+       chip->revision = 0;
+       if (chip->match_type == V4L2_CHIP_MATCH_HOST) {
+               if (v4l2_chip_match_host(chip->match_type, chip->match_chip))
+                       chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
+               return 0;
        }
+       if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+               return ivtv_i2c_id(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip);
+       if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
+               return ivtv_call_i2c_client(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip);
+       return -EINVAL;
+}
 
-       case VIDIOC_S_PRIORITY:
-       {
-               enum v4l2_priority *prio = arg;
+static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-               return v4l2_prio_change(&itv->prio, &id->prio, *prio);
-       }
+       if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
+               return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
+       if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+               return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg);
+       return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg);
+}
+
+static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_QUERYCAP:{
-               struct v4l2_capability *vcap = arg;
+       if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
+               return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
+       if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
+               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);
+}
 
-               memset(vcap, 0, sizeof(*vcap));
-               strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
-               strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
-               strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
-               vcap->version = IVTV_DRIVER_VERSION;        /* version */
-               vcap->capabilities = itv->v4l2_cap;         /* capabilities */
+static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-               /* reserved.. must set to 0! */
-               vcap->reserved[0] = vcap->reserved[1] =
-                       vcap->reserved[2] = vcap->reserved[3] = 0;
-               break;
-       }
+       *p = v4l2_prio_max(&itv->prio);
 
-       case VIDIOC_ENUMAUDIO:{
-               struct v4l2_audio *vin = arg;
+       return 0;
+}
 
-               return ivtv_get_audio_input(itv, vin->index, vin);
-       }
+static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-       case VIDIOC_G_AUDIO:{
-               struct v4l2_audio *vin = arg;
+       return v4l2_prio_change(&itv->prio, &id->prio, prio);
+}
 
-               vin->index = itv->audio_input;
-               return ivtv_get_audio_input(itv, vin->index, vin);
-       }
+static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       memset(vcap, 0, sizeof(*vcap));
+       strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
+       strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
+       strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
+       vcap->version = IVTV_DRIVER_VERSION;        /* version */
+       vcap->capabilities = itv->v4l2_cap;         /* capabilities */
+       /* reserved.. must set to 0! */
+       vcap->reserved[0] = vcap->reserved[1] =
+               vcap->reserved[2] = vcap->reserved[3] = 0;
+       return 0;
+}
 
-       case VIDIOC_S_AUDIO:{
-               struct v4l2_audio *vout = arg;
+static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-               if (vout->index >= itv->nof_audio_inputs)
-                       return -EINVAL;
-               itv->audio_input = vout->index;
-               ivtv_audio_set_io(itv);
-               break;
-       }
+       return ivtv_get_audio_input(itv, vin->index, vin);
+}
+
+static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_ENUMAUDOUT:{
-               struct v4l2_audioout *vin = arg;
+       vin->index = itv->audio_input;
+       return ivtv_get_audio_input(itv, vin->index, vin);
+}
 
-               /* set it to defaults from our table */
-               return ivtv_get_audio_output(itv, vin->index, vin);
-       }
+static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_G_AUDOUT:{
-               struct v4l2_audioout *vin = arg;
+       if (vout->index >= itv->nof_audio_inputs)
+               return -EINVAL;
 
-               vin->index = 0;
-               return ivtv_get_audio_output(itv, vin->index, vin);
-       }
+       itv->audio_input = vout->index;
+       ivtv_audio_set_io(itv);
 
-       case VIDIOC_S_AUDOUT:{
-               struct v4l2_audioout *vout = arg;
+       return 0;
+}
 
-               return ivtv_get_audio_output(itv, vout->index, vout);
-       }
+static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_ENUMINPUT:{
-               struct v4l2_input *vin = arg;
+       /* set it to defaults from our table */
+       return ivtv_get_audio_output(itv, vin->index, vin);
+}
 
-               /* set it to defaults from our table */
-               return ivtv_get_input(itv, vin->index, vin);
-       }
+static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_ENUMOUTPUT:{
-               struct v4l2_output *vout = arg;
+       vin->index = 0;
+       return ivtv_get_audio_output(itv, vin->index, vin);
+}
 
-               return ivtv_get_output(itv, vout->index, vout);
-       }
+static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_TRY_FMT:
-       case VIDIOC_S_FMT: {
-               struct v4l2_format *fmt = arg;
+       return ivtv_get_audio_output(itv, vout->index, vout);
+}
 
-               return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
-       }
+static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_G_FMT: {
-               struct v4l2_format *fmt = arg;
-               int type = fmt->type;
+       /* set it to defaults from our table */
+       return ivtv_get_input(itv, vin->index, vin);
+}
 
-               memset(fmt, 0, sizeof(*fmt));
-               fmt->type = type;
-               return ivtv_get_fmt(itv, id->type, fmt);
-       }
+static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-       case VIDIOC_CROPCAP: {
-               struct v4l2_cropcap *cropcap = arg;
+       return ivtv_get_output(itv, vout->index, vout);
+}
 
-               if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
-                       return -EINVAL;
-               cropcap->bounds.top = cropcap->bounds.left = 0;
-               cropcap->bounds.width = 720;
-               if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-                       cropcap->bounds.height = itv->is_50hz ? 576 : 480;
-                       cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
-                       cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
-               } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
-                       if (yi->track_osd) {
-                               cropcap->bounds.width = yi->osd_full_w;
-                               cropcap->bounds.height = yi->osd_full_h;
-                       } else {
-                               cropcap->bounds.width = 720;
-                               cropcap->bounds.height =
-                                               itv->is_out_50hz ? 576 : 480;
-                       }
-                       cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
-                       cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       struct yuv_playback_info *yi = &itv->yuv_info;
+       int streamtype;
+
+       streamtype = id->type;
+
+       if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+               return -EINVAL;
+       cropcap->bounds.top = cropcap->bounds.left = 0;
+       cropcap->bounds.width = 720;
+       if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+               cropcap->bounds.height = itv->is_50hz ? 576 : 480;
+               cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
+               cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
+       } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
+               if (yi->track_osd) {
+                       cropcap->bounds.width = yi->osd_full_w;
+                       cropcap->bounds.height = yi->osd_full_h;
                } else {
-                       cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
-                       cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
-                       cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+                       cropcap->bounds.width = 720;
+                       cropcap->bounds.height =
+                                       itv->is_out_50hz ? 576 : 480;
                }
-               cropcap->defrect = cropcap->bounds;
-               return 0;
+               cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+               cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
+       } else {
+               cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
+               cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
+               cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
        }
+       cropcap->defrect = cropcap->bounds;
+       return 0;
+}
+
+static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       struct yuv_playback_info *yi = &itv->yuv_info;
+       int streamtype;
 
-       case VIDIOC_S_CROP: {
-               struct v4l2_crop *crop = arg;
+       streamtype = id->type;
 
-               if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-                   (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
-                       if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
-                               yi->main_rect = crop->c;
+       if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
+               printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
+               /* Should be replaced */
+               /* v4l_printk_ioctl(VIDIOC_S_CROP); */
+       }
+
+       if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+           (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+               if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
+                       yi->main_rect = crop->c;
+                       return 0;
+               } else {
+                       if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+                               crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
+                               itv->main_rect = crop->c;
                                return 0;
-                       } else {
-                               if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
-                                       crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
-                                       itv->main_rect = crop->c;
-                                       return 0;
-                               }
                        }
-                       return -EINVAL;
                }
                return -EINVAL;
        }
+       return -EINVAL;
+}
 
-       case VIDIOC_G_CROP: {
-               struct v4l2_crop *crop = arg;
+static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       struct yuv_playback_info *yi = &itv->yuv_info;
+       int streamtype;
 
-               if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
-                   (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
-                       if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
-                               crop->c = yi->main_rect;
-                       else
-                               crop->c = itv->main_rect;
-                       return 0;
+       streamtype = id->type;
+
+       if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+           (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
+               if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
+                       crop->c = yi->main_rect;
+               else
+                       crop->c = itv->main_rect;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
+{
+       static struct v4l2_fmtdesc formats[] = {
+               { 0, 0, 0,
+                 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
+                 { 0, 0, 0, 0 }
+               },
+               { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
+                 "MPEG", V4L2_PIX_FMT_MPEG,
+                 { 0, 0, 0, 0 }
                }
+       };
+       enum v4l2_buf_type type = fmt->type;
+
+       if (fmt->index > 1)
                return -EINVAL;
-       }
 
-       case VIDIOC_ENUM_FMT: {
-               static struct v4l2_fmtdesc formats[] = {
-                       { 0, 0, 0,
-                         "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
-                         { 0, 0, 0, 0 }
-                       },
-                       { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
-                         "MPEG", V4L2_PIX_FMT_MPEG,
-                         { 0, 0, 0, 0 }
-                       }
-               };
-               struct v4l2_fmtdesc *fmt = arg;
-               enum v4l2_buf_type type = fmt->type;
+       *fmt = formats[fmt->index];
+       fmt->type = type;
+       return 0;
+}
 
-               switch (type) {
-               case V4L2_BUF_TYPE_VIDEO_CAPTURE:
-                       break;
-               case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-                       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-                               return -EINVAL;
-                       break;
-               default:
-                       return -EINVAL;
+static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       static struct v4l2_fmtdesc formats[] = {
+               { 0, 0, 0,
+                 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
+                 { 0, 0, 0, 0 }
+               },
+               { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
+                 "MPEG", V4L2_PIX_FMT_MPEG,
+                 { 0, 0, 0, 0 }
                }
-               if (fmt->index > 1)
-                       return -EINVAL;
-               *fmt = formats[fmt->index];
-               fmt->type = type;
+       };
+       enum v4l2_buf_type type = fmt->type;
+
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return -EINVAL;
+
+       if (fmt->index > 1)
+               return -EINVAL;
+
+       *fmt = formats[fmt->index];
+       fmt->type = type;
+
+       return 0;
+}
+
+static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       *i = itv->active_input;
+
+       return 0;
+}
+
+int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       if (inp < 0 || inp >= itv->nof_inputs)
+               return -EINVAL;
+
+       if (inp == itv->active_input) {
+               IVTV_DEBUG_INFO("Input unchanged\n");
                return 0;
        }
 
-       case VIDIOC_G_INPUT:{
-               *(int *)arg = itv->active_input;
-               break;
+       if (atomic_read(&itv->capturing) > 0) {
+               return -EBUSY;
        }
 
-       case VIDIOC_S_INPUT:{
-               int inp = *(int *)arg;
+       IVTV_DEBUG_INFO("Changing input from %d to %d\n",
+                       itv->active_input, inp);
 
-               if (inp < 0 || inp >= itv->nof_inputs)
-                       return -EINVAL;
+       itv->active_input = inp;
+       /* Set the audio input to whatever is appropriate for the
+          input type. */
+       itv->audio_input = itv->card->video_inputs[inp].audio_index;
 
-               if (inp == itv->active_input) {
-                       IVTV_DEBUG_INFO("Input unchanged\n");
-                       break;
-               }
-               if (atomic_read(&itv->capturing) > 0) {
-                       return -EBUSY;
-               }
-               IVTV_DEBUG_INFO("Changing input from %d to %d\n",
-                               itv->active_input, inp);
+       /* prevent others from messing with the streams until
+          we're finished changing inputs. */
+       ivtv_mute(itv);
+       ivtv_video_set_io(itv);
+       ivtv_audio_set_io(itv);
+       ivtv_unmute(itv);
+
+       return 0;
+}
 
-               itv->active_input = inp;
-               /* Set the audio input to whatever is appropriate for the
-                  input type. */
-               itv->audio_input = itv->card->video_inputs[inp].audio_index;
+static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-               /* prevent others from messing with the streams until
-                  we're finished changing inputs. */
-               ivtv_mute(itv);
-               ivtv_video_set_io(itv);
-               ivtv_audio_set_io(itv);
-               ivtv_unmute(itv);
-               break;
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
+               return -EINVAL;
+
+       *i = itv->active_output;
+
+       return 0;
+}
+
+static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       struct v4l2_routing route;
+
+       if (outp >= itv->card->nof_outputs)
+               return -EINVAL;
+
+       if (outp == itv->active_output) {
+               IVTV_DEBUG_INFO("Output unchanged\n");
+               return 0;
        }
+       IVTV_DEBUG_INFO("Changing output from %d to %d\n",
+                  itv->active_output, outp);
 
-       case VIDIOC_G_OUTPUT:{
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
-                       return -EINVAL;
-               *(int *)arg = itv->active_output;
-               break;
+       itv->active_output = outp;
+       route.input = SAA7127_INPUT_TYPE_NORMAL;
+       route.output = itv->card->video_outputs[outp].video_output;
+       ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+
+       return 0;
+}
+
+static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       if (vf->tuner != 0)
+               return -EINVAL;
+
+       ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf);
+       return 0;
+}
+
+int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       if (vf->tuner != 0)
+               return -EINVAL;
+
+       ivtv_mute(itv);
+       IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
+       ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf);
+       ivtv_unmute(itv);
+       return 0;
+}
+
+static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       *std = itv->std;
+       return 0;
+}
+
+int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       struct yuv_playback_info *yi = &itv->yuv_info;
+
+       if ((*std & V4L2_STD_ALL) == 0)
+               return -EINVAL;
+
+       if (*std == itv->std)
+               return 0;
+
+       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
+           atomic_read(&itv->capturing) > 0 ||
+           atomic_read(&itv->decoding) > 0) {
+               /* Switching standard would turn off the radio or mess
+                  with already running streams, prevent that by
+                  returning EBUSY. */
+               return -EBUSY;
+       }
+
+       itv->std = *std;
+       itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
+       itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
+       itv->params.width = 720;
+       itv->params.height = itv->is_50hz ? 576 : 480;
+       itv->vbi.count = itv->is_50hz ? 18 : 12;
+       itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
+       itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
+
+       if (itv->hw_flags & IVTV_HW_CX25840)
+               itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
+
+       IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
+
+       /* Tuner */
+       ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
+
+       if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+               /* set display standard */
+               itv->std_out = *std;
+               itv->is_out_60hz = itv->is_60hz;
+               itv->is_out_50hz = itv->is_50hz;
+               ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
+               ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
+               itv->main_rect.left = itv->main_rect.top = 0;
+               itv->main_rect.width = 720;
+               itv->main_rect.height = itv->params.height;
+               ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+                       720, itv->main_rect.height, 0, 0);
+               yi->main_rect = itv->main_rect;
+               if (!itv->osd_info) {
+                       yi->osd_full_w = 720;
+                       yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
+               }
+       }
+       return 0;
+}
+
+static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+
+       if (vt->index != 0)
+               return -EINVAL;
+
+       ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
+
+       return 0;
+}
+
+static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+
+       if (vt->index != 0)
+               return -EINVAL;
+
+       memset(vt, 0, sizeof(*vt));
+       ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
+
+       if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+               strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
+               vt->type = V4L2_TUNER_RADIO;
+       } else {
+               strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
+               vt->type = V4L2_TUNER_ANALOG_TV;
        }
 
-       case VIDIOC_S_OUTPUT:{
-               int outp = *(int *)arg;
-               struct v4l2_routing route;
+       return 0;
+}
 
-               if (outp >= itv->card->nof_outputs)
+static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+       int f, l;
+       enum v4l2_buf_type type = cap->type;
+
+       memset(cap, 0, sizeof(*cap));
+       cap->type = type;
+       if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+               for (f = 0; f < 2; f++) {
+                       for (l = 0; l < 24; l++) {
+                               if (valid_service_line(f, l, itv->is_50hz))
+                                       cap->service_lines[f][l] = set;
+                       }
+               }
+               return 0;
+       }
+       if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
+               if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
                        return -EINVAL;
-
-               if (outp == itv->active_output) {
-                       IVTV_DEBUG_INFO("Output unchanged\n");
-                       break;
+               if (itv->is_60hz) {
+                       cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+                       cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+               } else {
+                       cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
+                       cap->service_lines[0][16] = V4L2_SLICED_VPS;
                }
-               IVTV_DEBUG_INFO("Changing output from %d to %d\n",
-                          itv->active_output, outp);
-
-               itv->active_output = outp;
-               route.input = SAA7127_INPUT_TYPE_NORMAL;
-               route.output = itv->card->video_outputs[outp].video_output;
-               ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
-               break;
+               return 0;
        }
+       return -EINVAL;
+}
 
-       case VIDIOC_G_FREQUENCY:{
-               struct v4l2_frequency *vf = arg;
+static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       struct v4l2_enc_idx_entry *e = idx->entry;
+       int entries;
+       int i;
 
-               if (vf->tuner != 0)
-                       return -EINVAL;
-               ivtv_call_i2c_clients(itv, cmd, arg);
-               break;
+       entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
+                               IVTV_MAX_PGM_INDEX;
+       if (entries > V4L2_ENC_IDX_ENTRIES)
+               entries = V4L2_ENC_IDX_ENTRIES;
+       idx->entries = 0;
+       for (i = 0; i < entries; i++) {
+               *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
+               if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
+                       idx->entries++;
+                       e++;
+               }
        }
+       itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
+       return 0;
+}
 
-       case VIDIOC_S_FREQUENCY:{
-               struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
+static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-               if (vf.tuner != 0)
-                       return -EINVAL;
+       memset(&enc->raw, 0, sizeof(enc->raw));
 
-               ivtv_mute(itv);
-               IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
-               ivtv_call_i2c_clients(itv, cmd, &vf);
-               ivtv_unmute(itv);
-               break;
-       }
+       switch (enc->cmd) {
+       case V4L2_ENC_CMD_START:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
+               enc->flags = 0;
+               return ivtv_start_capture(id);
 
-       case VIDIOC_ENUMSTD:{
-               struct v4l2_standard *vs = arg;
-               int idx = vs->index;
+       case V4L2_ENC_CMD_STOP:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
+               enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
+               ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
+               return 0;
 
-               if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
-                       return -EINVAL;
+       case V4L2_ENC_CMD_PAUSE:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
+               enc->flags = 0;
 
-               *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
-                               ivtv_std_60hz : ivtv_std_50hz;
-               vs->index = idx;
-               vs->id = enum_stds[idx].std;
-               strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name));
-               break;
-       }
+               if (!atomic_read(&itv->capturing))
+                       return -EPERM;
+               if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
+                       return 0;
 
-       case VIDIOC_G_STD:{
-               *(v4l2_std_id *) arg = itv->std;
+               ivtv_mute(itv);
+               ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
                break;
-       }
-
-       case VIDIOC_S_STD: {
-               v4l2_std_id std = *(v4l2_std_id *) arg;
 
-               if ((std & V4L2_STD_ALL) == 0)
-                       return -EINVAL;
+       case V4L2_ENC_CMD_RESUME:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
+               enc->flags = 0;
 
-               if (std == itv->std)
-                       break;
+               if (!atomic_read(&itv->capturing))
+                       return -EPERM;
 
-               if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
-                   atomic_read(&itv->capturing) > 0 ||
-                   atomic_read(&itv->decoding) > 0) {
-                       /* Switching standard would turn off the radio or mess
-                          with already running streams, prevent that by
-                          returning EBUSY. */
-                       return -EBUSY;
-               }
+               if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
+                       return 0;
 
-               itv->std = std;
-               itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
-               itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
-               itv->params.width = 720;
-               itv->params.height = itv->is_50hz ? 576 : 480;
-               itv->vbi.count = itv->is_50hz ? 18 : 12;
-               itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
-               itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
-               if (itv->hw_flags & IVTV_HW_CX25840) {
-                       itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
-               }
-               IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
-
-               /* Tuner */
-               ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
-
-               if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
-                       /* set display standard */
-                       itv->std_out = std;
-                       itv->is_out_60hz = itv->is_60hz;
-                       itv->is_out_50hz = itv->is_50hz;
-                       ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
-                       ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
-                       itv->main_rect.left = itv->main_rect.top = 0;
-                       itv->main_rect.width = 720;
-                       itv->main_rect.height = itv->params.height;
-                       ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
-                               720, itv->main_rect.height, 0, 0);
-                       yi->main_rect = itv->main_rect;
-                       if (!itv->osd_info) {
-                               yi->osd_full_w = 720;
-                               yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
-                       }
-               }
+               ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
+               ivtv_unmute(itv);
                break;
+       default:
+               IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
+               return -EINVAL;
        }
 
-       case VIDIOC_S_TUNER: {  /* Setting tuner can only set audio mode */
-               struct v4l2_tuner *vt = arg;
+       return 0;
+}
 
-               if (vt->index != 0)
-                       return -EINVAL;
+static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
-               ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
-               break;
-       }
+       memset(&enc->raw, 0, sizeof(enc->raw));
 
-       case VIDIOC_G_TUNER: {
-               struct v4l2_tuner *vt = arg;
+       switch (enc->cmd) {
+       case V4L2_ENC_CMD_START:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
+               enc->flags = 0;
+               return 0;
 
-               if (vt->index != 0)
-                       return -EINVAL;
+       case V4L2_ENC_CMD_STOP:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
+               enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
+               return 0;
 
-               memset(vt, 0, sizeof(*vt));
-               ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
+       case V4L2_ENC_CMD_PAUSE:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
+               enc->flags = 0;
+               return 0;
 
-               if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
-                       strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
-                       vt->type = V4L2_TUNER_RADIO;
-               } else {
-                       strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
-                       vt->type = V4L2_TUNER_ANALOG_TV;
-               }
-               break;
+       case V4L2_ENC_CMD_RESUME:
+               IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
+               enc->flags = 0;
+               return 0;
+       default:
+               IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
+               return -EINVAL;
        }
+}
 
-       case VIDIOC_G_SLICED_VBI_CAP: {
-               struct v4l2_sliced_vbi_cap *cap = arg;
-               int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
-               int f, l;
-               enum v4l2_buf_type type = cap->type;
-
-               memset(cap, 0, sizeof(*cap));
-               cap->type = type;
-               if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
-                       for (f = 0; f < 2; f++) {
-                               for (l = 0; l < 24; l++) {
-                                       if (valid_service_line(f, l, itv->is_50hz)) {
-                                               cap->service_lines[f][l] = set;
-                                       }
-                               }
-                       }
-                       return 0;
-               }
-               if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
-                       if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
-                               return -EINVAL;
-                       if (itv->is_60hz) {
-                               cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
-                               cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
-                       } else {
-                               cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
-                               cap->service_lines[0][16] = V4L2_SLICED_VPS;
-                       }
-                       return 0;
-               }
+static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       u32 data[CX2341X_MBOX_MAX_DATA];
+       struct yuv_playback_info *yi = &itv->yuv_info;
+
+       int pixfmt;
+       static u32 pixel_format[16] = {
+               V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
+               V4L2_PIX_FMT_RGB565,
+               V4L2_PIX_FMT_RGB555,
+               V4L2_PIX_FMT_RGB444,
+               V4L2_PIX_FMT_RGB32,
+               0,
+               0,
+               0,
+               V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
+               V4L2_PIX_FMT_YUV565,
+               V4L2_PIX_FMT_YUV555,
+               V4L2_PIX_FMT_YUV444,
+               V4L2_PIX_FMT_YUV32,
+               0,
+               0,
+               0,
+       };
+
+       memset(fb, 0, sizeof(*fb));
+
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -EINVAL;
-       }
 
-       case VIDIOC_G_ENC_INDEX: {
-               struct v4l2_enc_idx *idx = arg;
-               struct v4l2_enc_idx_entry *e = idx->entry;
-               int entries;
-               int i;
-
-               entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
-                                       IVTV_MAX_PGM_INDEX;
-               if (entries > V4L2_ENC_IDX_ENTRIES)
-                       entries = V4L2_ENC_IDX_ENTRIES;
-               idx->entries = 0;
-               for (i = 0; i < entries; i++) {
-                       *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
-                       if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
-                               idx->entries++;
-                               e++;
-                       }
-               }
-               itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
-               break;
-       }
+       fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
+               V4L2_FBUF_CAP_GLOBAL_ALPHA;
 
-       case VIDIOC_ENCODER_CMD:
-       case VIDIOC_TRY_ENCODER_CMD: {
-               struct v4l2_encoder_cmd *enc = arg;
-               int try = cmd == VIDIOC_TRY_ENCODER_CMD;
-
-               memset(&enc->raw, 0, sizeof(enc->raw));
-               switch (enc->cmd) {
-               case V4L2_ENC_CMD_START:
-                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
-                       enc->flags = 0;
-                       if (try)
-                               return 0;
-                       return ivtv_start_capture(id);
+       ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+       data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
+       pixfmt = (data[0] >> 3) & 0xf;
 
-               case V4L2_ENC_CMD_STOP:
-                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
-                       enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
-                       if (try)
-                               return 0;
-                       ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
-                       return 0;
+       fb->fmt.pixelformat = pixel_format[pixfmt];
+       fb->fmt.width = itv->osd_rect.width;
+       fb->fmt.height = itv->osd_rect.height;
+       fb->base = (void *)itv->osd_video_pbase;
 
-               case V4L2_ENC_CMD_PAUSE:
-                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
-                       enc->flags = 0;
-                       if (try)
-                               return 0;
-                       if (!atomic_read(&itv->capturing))
-                               return -EPERM;
-                       if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
-                               return 0;
-                       ivtv_mute(itv);
-                       ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
-                       break;
+       if (itv->osd_chroma_key_state)
+               fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
 
-               case V4L2_ENC_CMD_RESUME:
-                       IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
-                       enc->flags = 0;
-                       if (try)
-                               return 0;
-                       if (!atomic_read(&itv->capturing))
-                               return -EPERM;
-                       if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
-                               return 0;
-                       ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
-                       ivtv_unmute(itv);
-                       break;
-               default:
-                       IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
-                       return -EINVAL;
-               }
-               break;
-       }
+       if (itv->osd_global_alpha_state)
+               fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
 
-       case VIDIOC_G_FBUF: {
-               struct v4l2_framebuffer *fb = arg;
-               int pixfmt;
-               static u32 pixel_format[16] = {
-                       V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
-                       V4L2_PIX_FMT_RGB565,
-                       V4L2_PIX_FMT_RGB555,
-                       V4L2_PIX_FMT_RGB444,
-                       V4L2_PIX_FMT_RGB32,
-                       0,
-                       0,
-                       0,
-                       V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
-                       V4L2_PIX_FMT_YUV565,
-                       V4L2_PIX_FMT_YUV555,
-                       V4L2_PIX_FMT_YUV444,
-                       V4L2_PIX_FMT_YUV32,
-                       0,
-                       0,
-                       0,
-               };
+       pixfmt &= 7;
 
-               memset(fb, 0, sizeof(*fb));
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
-                       return -EINVAL;
-               fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
-                       V4L2_FBUF_CAP_GLOBAL_ALPHA;
-               ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
-               data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
-               pixfmt = (data[0] >> 3) & 0xf;
-               fb->fmt.pixelformat = pixel_format[pixfmt];
-               fb->fmt.width = itv->osd_rect.width;
-               fb->fmt.height = itv->osd_rect.height;
-               fb->base = (void *)itv->osd_video_pbase;
-               if (itv->osd_chroma_key_state)
-                       fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
-               if (itv->osd_global_alpha_state)
-                       fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
-               pixfmt &= 7;
-               /* no local alpha for RGB565 or unknown formats */
-               if (pixfmt == 1 || pixfmt > 4)
-                       break;
+       /* no local alpha for RGB565 or unknown formats */
+       if (pixfmt == 1 || pixfmt > 4)
+               return 0;
+
+       /* 16-bit formats have inverted local alpha */
+       if (pixfmt == 2 || pixfmt == 3)
+               fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
+       else
+               fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
+
+       if (itv->osd_local_alpha_state) {
                /* 16-bit formats have inverted local alpha */
                if (pixfmt == 2 || pixfmt == 3)
-                       fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
+                       fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
                else
-                       fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
-               if (itv->osd_local_alpha_state) {
-                       /* 16-bit formats have inverted local alpha */
-                       if (pixfmt == 2 || pixfmt == 3)
-                               fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
-                       else
-                               fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
-               }
-               if (yi->track_osd)
-                       fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
-               break;
+                       fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
        }
+       if (yi->track_osd)
+               fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
+
+       return 0;
+}
 
-       case VIDIOC_S_FBUF: {
-               struct v4l2_framebuffer *fb = arg;
+static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
+       struct yuv_playback_info *yi = &itv->yuv_info;
 
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
-                       return -EINVAL;
-               itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
-               itv->osd_local_alpha_state =
-                       (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
-               itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
-               ivtv_set_osd_alpha(itv);
-               yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
-               break;
-       }
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+               return -EINVAL;
 
-       case VIDIOC_OVERLAY: {
-               int *on = arg;
+       itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
+       itv->osd_local_alpha_state =
+               (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
+       itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
+       ivtv_set_osd_alpha(itv);
+       yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
 
-               if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
-                       return -EINVAL;
-               ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
-               break;
-       }
+       return 0;
+}
+
+static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
+{
+       struct ivtv_open_id *id = fh;
+       struct ivtv *itv = id->itv;
 
-       case VIDIOC_LOG_STATUS:
-       {
-               int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
-               struct v4l2_input vidin;
-               struct v4l2_audio audin;
-               int i;
+       if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
+               return -EINVAL;
 
-               IVTV_INFO("=================  START STATUS CARD #%d  =================\n", itv->num);
-               IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
-               if (itv->hw_flags & IVTV_HW_TVEEPROM) {
-                       struct tveeprom tv;
+       ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
 
-                       ivtv_read_eeprom(itv, &tv);
-               }
-               ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
-               ivtv_get_input(itv, itv->active_input, &vidin);
-               ivtv_get_audio_input(itv, itv->audio_input, &audin);
-               IVTV_INFO("Video Input:  %s\n", vidin.name);
-               IVTV_INFO("Audio Input:  %s%s\n", audin.name,
-                       (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
-               if (has_output) {
-                       struct v4l2_output vidout;
-                       struct v4l2_audioout audout;
-                       int mode = itv->output_mode;
-                       static const char * const output_modes[5] = {
-                               "None",
-                               "MPEG Streaming",
-                               "YUV Streaming",
-                               "YUV Frames",
-                               "Passthrough",
-                       };
-                       static const char * const audio_modes[5] = {
-                               "Stereo",
-                               "Left",
-                               "Right",
-                               "Mono",
-                               "Swapped"
-                       };
-                       static const char * const alpha_mode[4] = {
-                               "None",
-                               "Global",
-                               "Local",
-                               "Global and Local"
-                       };
-                       static const char * const pixel_format[16] = {
-                               "ARGB Indexed",
-                               "RGB 5:6:5",
-                               "ARGB 1:5:5:5",
-                               "ARGB 1:4:4:4",
-                               "ARGB 8:8:8:8",
-                               "5",
-                               "6",
-                               "7",
-                               "AYUV Indexed",
-                               "YUV 5:6:5",
-                               "AYUV 1:5:5:5",
-                               "AYUV 1:4:4:4",
-                               "AYUV 8:8:8:8",
-                               "13",
-                               "14",
-                               "15",
-                       };
-
-                       ivtv_get_output(itv, itv->active_output, &vidout);
-                       ivtv_get_audio_output(itv, 0, &audout);
-                       IVTV_INFO("Video Output: %s\n", vidout.name);
-                       IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
-                               audio_modes[itv->audio_stereo_mode],
-                               audio_modes[itv->audio_bilingual_mode]);
-                       if (mode < 0 || mode > OUT_PASSTHROUGH)
-                               mode = OUT_NONE;
-                       IVTV_INFO("Output Mode:  %s\n", output_modes[mode]);
-                       ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
-                       data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
-                       IVTV_INFO("Overlay:      %s, Alpha: %s, Pixel Format: %s\n",
-                               data[0] & 1 ? "On" : "Off",
-                               alpha_mode[(data[0] >> 1) & 0x3],
-                               pixel_format[(data[0] >> 3) & 0xf]);
-               }
-               IVTV_INFO("Tuner:  %s\n",
-                       test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
-               cx2341x_log_status(&itv->params, itv->name);
-               IVTV_INFO("Status flags:    0x%08lx\n", itv->i_flags);
-               for (i = 0; i < IVTV_MAX_STREAMS; i++) {
-                       struct ivtv_stream *s = &itv->streams[i];
-
-                       if (s->v4l2dev == NULL || s->buffers == 0)
-                               continue;
-                       IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
-                                       (s->buffers - s->q_free.buffers) * 100 / s->buffers,
-                                       (s->buffers * s->buf_size) / 1024, s->buffers);
-               }
-               IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
-               IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);
-               break;
+       return 0;
+}
+
+static int ivtv_log_status(struct file *file, void *fh)
+{
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+       u32 data[CX2341X_MBOX_MAX_DATA];
+
+       int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
+       struct v4l2_input vidin;
+       struct v4l2_audio audin;
+       int i;
+
+       IVTV_INFO("=================  START STATUS CARD #%d  =================\n", itv->num);
+       IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
+       if (itv->hw_flags & IVTV_HW_TVEEPROM) {
+               struct tveeprom tv;
+
+               ivtv_read_eeprom(itv, &tv);
+       }
+       ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
+       ivtv_get_input(itv, itv->active_input, &vidin);
+       ivtv_get_audio_input(itv, itv->audio_input, &audin);
+       IVTV_INFO("Video Input:  %s\n", vidin.name);
+       IVTV_INFO("Audio Input:  %s%s\n", audin.name,
+               (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
+       if (has_output) {
+               struct v4l2_output vidout;
+               struct v4l2_audioout audout;
+               int mode = itv->output_mode;
+               static const char * const output_modes[5] = {
+                       "None",
+                       "MPEG Streaming",
+                       "YUV Streaming",
+                       "YUV Frames",
+                       "Passthrough",
+               };
+               static const char * const audio_modes[5] = {
+                       "Stereo",
+                       "Left",
+                       "Right",
+                       "Mono",
+                       "Swapped"
+               };
+               static const char * const alpha_mode[4] = {
+                       "None",
+                       "Global",
+                       "Local",
+                       "Global and Local"
+               };
+               static const char * const pixel_format[16] = {
+                       "ARGB Indexed",
+                       "RGB 5:6:5",
+                       "ARGB 1:5:5:5",
+                       "ARGB 1:4:4:4",
+                       "ARGB 8:8:8:8",
+                       "5",
+                       "6",
+                       "7",
+                       "AYUV Indexed",
+                       "YUV 5:6:5",
+                       "AYUV 1:5:5:5",
+                       "AYUV 1:4:4:4",
+                       "AYUV 8:8:8:8",
+                       "13",
+                       "14",
+                       "15",
+               };
+
+               ivtv_get_output(itv, itv->active_output, &vidout);
+               ivtv_get_audio_output(itv, 0, &audout);
+               IVTV_INFO("Video Output: %s\n", vidout.name);
+               IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
+                       audio_modes[itv->audio_stereo_mode],
+                       audio_modes[itv->audio_bilingual_mode]);
+               if (mode < 0 || mode > OUT_PASSTHROUGH)
+                       mode = OUT_NONE;
+               IVTV_INFO("Output Mode:  %s\n", output_modes[mode]);
+               ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
+               data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
+               IVTV_INFO("Overlay:      %s, Alpha: %s, Pixel Format: %s\n",
+                       data[0] & 1 ? "On" : "Off",
+                       alpha_mode[(data[0] >> 1) & 0x3],
+                       pixel_format[(data[0] >> 3) & 0xf]);
        }
+       IVTV_INFO("Tuner:  %s\n",
+               test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
+       cx2341x_log_status(&itv->params, itv->name);
+       IVTV_INFO("Status flags:    0x%08lx\n", itv->i_flags);
+       for (i = 0; i < IVTV_MAX_STREAMS; i++) {
+               struct ivtv_stream *s = &itv->streams[i];
 
-       default:
-               return -EINVAL;
+               if (s->v4l2dev == NULL || s->buffers == 0)
+                       continue;
+               IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
+                               (s->buffers - s->q_free.buffers) * 100 / s->buffers,
+                               (s->buffers * s->buf_size) / 1024, s->buffers);
        }
+
+       IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
+       IVTV_INFO("==================  END STATUS CARD #%d  ==================\n", itv->num);
+
        return 0;
 }
 
@@ -1607,121 +1732,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        return 0;
 }
 
-static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
-                             unsigned int cmd, void *arg)
+static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
 {
-       struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
-       struct ivtv *itv = id->itv;
-       int ret;
-
-       /* check priority */
-       switch (cmd) {
-       case VIDIOC_S_CTRL:
-       case VIDIOC_S_STD:
-       case VIDIOC_S_INPUT:
-       case VIDIOC_S_OUTPUT:
-       case VIDIOC_S_TUNER:
-       case VIDIOC_S_FREQUENCY:
-       case VIDIOC_S_FMT:
-       case VIDIOC_S_CROP:
-       case VIDIOC_S_AUDIO:
-       case VIDIOC_S_AUDOUT:
-       case VIDIOC_S_EXT_CTRLS:
-       case VIDIOC_S_FBUF:
-       case VIDIOC_OVERLAY:
-               ret = v4l2_prio_check(&itv->prio, &id->prio);
-               if (ret)
-                       return ret;
-       }
+       struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
        switch (cmd) {
-       case VIDIOC_DBG_G_REGISTER:
-       case VIDIOC_DBG_S_REGISTER:
-       case VIDIOC_G_CHIP_IDENT:
-       case VIDIOC_INT_S_AUDIO_ROUTING:
-       case VIDIOC_INT_RESET:
-               if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
-                       printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
-                       v4l_printk_ioctl(cmd);
-                       printk("\n");
-               }
-               return ivtv_debug_ioctls(filp, cmd, arg);
+       case VIDIOC_INT_S_AUDIO_ROUTING: {
+               struct v4l2_routing *route = arg;
 
-       case VIDIOC_G_PRIORITY:
-       case VIDIOC_S_PRIORITY:
-       case VIDIOC_QUERYCAP:
-       case VIDIOC_ENUMINPUT:
-       case VIDIOC_G_INPUT:
-       case VIDIOC_S_INPUT:
-       case VIDIOC_ENUMOUTPUT:
-       case VIDIOC_G_OUTPUT:
-       case VIDIOC_S_OUTPUT:
-       case VIDIOC_G_FMT:
-       case VIDIOC_S_FMT:
-       case VIDIOC_TRY_FMT:
-       case VIDIOC_ENUM_FMT:
-       case VIDIOC_CROPCAP:
-       case VIDIOC_G_CROP:
-       case VIDIOC_S_CROP:
-       case VIDIOC_G_FREQUENCY:
-       case VIDIOC_S_FREQUENCY:
-       case VIDIOC_ENUMSTD:
-       case VIDIOC_G_STD:
-       case VIDIOC_S_STD:
-       case VIDIOC_S_TUNER:
-       case VIDIOC_G_TUNER:
-       case VIDIOC_ENUMAUDIO:
-       case VIDIOC_S_AUDIO:
-       case VIDIOC_G_AUDIO:
-       case VIDIOC_ENUMAUDOUT:
-       case VIDIOC_S_AUDOUT:
-       case VIDIOC_G_AUDOUT:
-       case VIDIOC_G_SLICED_VBI_CAP:
-       case VIDIOC_LOG_STATUS:
-       case VIDIOC_G_ENC_INDEX:
-       case VIDIOC_ENCODER_CMD:
-       case VIDIOC_TRY_ENCODER_CMD:
-       case VIDIOC_G_FBUF:
-       case VIDIOC_S_FBUF:
-       case VIDIOC_OVERLAY:
-               if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
-                       printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
-                       v4l_printk_ioctl(cmd);
-                       printk("\n");
-               }
-               return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
+               ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
+               break;
+       }
 
-       case VIDIOC_QUERYMENU:
-       case VIDIOC_QUERYCTRL:
-       case VIDIOC_S_CTRL:
-       case VIDIOC_G_CTRL:
-       case VIDIOC_S_EXT_CTRLS:
-       case VIDIOC_G_EXT_CTRLS:
-       case VIDIOC_TRY_EXT_CTRLS:
-               if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
-                       printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
-                       v4l_printk_ioctl(cmd);
-                       printk("\n");
-               }
-               return ivtv_control_ioctls(itv, cmd, arg);
+       case VIDIOC_INT_RESET: {
+               u32 val = *(u32 *)arg;
 
-       case IVTV_IOC_DMA_FRAME:
-       case VIDEO_GET_PTS:
-       case VIDEO_GET_FRAME_COUNT:
-       case VIDEO_GET_EVENT:
-       case VIDEO_PLAY:
-       case VIDEO_STOP:
-       case VIDEO_FREEZE:
-       case VIDEO_CONTINUE:
-       case VIDEO_COMMAND:
-       case VIDEO_TRY_COMMAND:
-               return ivtv_decoder_ioctls(filp, cmd, arg);
+               if ((val == 0 && itv->options.newi2c) || (val & 0x01))
+                       ivtv_reset_ir_gpio(itv);
+               if (val & 0x02)
+                       itv->video_dec_func(itv, cmd, NULL);
+               break;
+       }
 
-       case 0x00005401:        /* Handle isatty() calls */
-               return -EINVAL;
        default:
-               return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
-                                                  ivtv_v4l2_do_ioctl);
+               return -EINVAL;
        }
        return 0;
 }
@@ -1729,7 +1763,10 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
 static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
                unsigned int cmd, unsigned long arg)
 {
-       /* Filter dvb ioctls that cannot be handled by video_usercopy */
+       struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
+       int ret;
+
+       /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */
        switch (cmd) {
        case VIDEO_SELECT_SOURCE:
                IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
@@ -1758,10 +1795,49 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f
                ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
                return 0;
 
+       case IVTV_IOC_DMA_FRAME:
+       case VIDEO_GET_PTS:
+       case VIDEO_GET_FRAME_COUNT:
+       case VIDEO_GET_EVENT:
+       case VIDEO_PLAY:
+       case VIDEO_STOP:
+       case VIDEO_FREEZE:
+       case VIDEO_CONTINUE:
+       case VIDEO_COMMAND:
+       case VIDEO_TRY_COMMAND:
+               return ivtv_decoder_ioctls(filp, cmd, (void *)arg);
+
        default:
                break;
        }
-       return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
+
+       /* check priority */
+       switch (cmd) {
+       case VIDIOC_S_CTRL:
+       case VIDIOC_S_STD:
+       case VIDIOC_S_INPUT:
+       case VIDIOC_S_OUTPUT:
+       case VIDIOC_S_TUNER:
+       case VIDIOC_S_FREQUENCY:
+       case VIDIOC_S_FMT:
+       case VIDIOC_S_CROP:
+       case VIDIOC_S_AUDIO:
+       case VIDIOC_S_AUDOUT:
+       case VIDIOC_S_EXT_CTRLS:
+       case VIDIOC_S_FBUF:
+       case VIDIOC_OVERLAY:
+               ret = v4l2_prio_check(&itv->prio, &id->prio);
+               if (ret)
+                       return ret;
+       }
+
+       if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
+               printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
+               v4l_printk_ioctl(cmd);
+               printk("\n");
+       }
+
+       return video_ioctl2(inode, filp, cmd, arg);
 }
 
 int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -1776,3 +1852,70 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
        mutex_unlock(&itv->serialize_lock);
        return res;
 }
+
+void ivtv_set_funcs(struct video_device *vdev)
+{
+       vdev->vidioc_querycap               = ivtv_querycap;
+       vdev->vidioc_g_priority             = ivtv_g_priority;
+       vdev->vidioc_s_priority             = ivtv_s_priority;
+       vdev->vidioc_s_audio                = ivtv_s_audio;
+       vdev->vidioc_g_audio                = ivtv_g_audio;
+       vdev->vidioc_enumaudio              = ivtv_enumaudio;
+       vdev->vidioc_s_audout               = ivtv_s_audout;
+       vdev->vidioc_g_audout               = ivtv_g_audout;
+       vdev->vidioc_enum_input             = ivtv_enum_input;
+       vdev->vidioc_enum_output            = ivtv_enum_output;
+       vdev->vidioc_enumaudout             = ivtv_enumaudout;
+       vdev->vidioc_cropcap                = ivtv_cropcap;
+       vdev->vidioc_s_crop                 = ivtv_s_crop;
+       vdev->vidioc_g_crop                 = ivtv_g_crop;
+       vdev->vidioc_g_input                = ivtv_g_input;
+       vdev->vidioc_s_input                = ivtv_s_input;
+       vdev->vidioc_g_output               = ivtv_g_output;
+       vdev->vidioc_s_output               = ivtv_s_output;
+       vdev->vidioc_g_frequency            = ivtv_g_frequency;
+       vdev->vidioc_s_frequency            = ivtv_s_frequency;
+       vdev->vidioc_s_tuner                = ivtv_s_tuner;
+       vdev->vidioc_g_tuner                = ivtv_g_tuner;
+       vdev->vidioc_g_enc_index            = ivtv_g_enc_index;
+       vdev->vidioc_g_fbuf                 = ivtv_g_fbuf;
+       vdev->vidioc_s_fbuf                 = ivtv_s_fbuf;
+       vdev->vidioc_g_std                  = ivtv_g_std;
+       vdev->vidioc_s_std                  = ivtv_s_std;
+       vdev->vidioc_overlay                = ivtv_overlay;
+       vdev->vidioc_log_status             = ivtv_log_status;
+       vdev->vidioc_enum_fmt_vid_cap       = ivtv_enum_fmt_vid_cap;
+       vdev->vidioc_encoder_cmd            = ivtv_encoder_cmd;
+       vdev->vidioc_try_encoder_cmd        = ivtv_try_encoder_cmd;
+       vdev->vidioc_enum_fmt_vid_out       = ivtv_enum_fmt_vid_out;
+       vdev->vidioc_g_fmt_vid_cap          = ivtv_g_fmt_vid_cap;
+       vdev->vidioc_g_fmt_vbi_cap          = ivtv_g_fmt_vbi_cap;
+       vdev->vidioc_g_fmt_sliced_vbi_cap   = ivtv_g_fmt_sliced_vbi_cap;
+       vdev->vidioc_g_fmt_vid_out          = ivtv_g_fmt_vid_out;
+       vdev->vidioc_g_fmt_vid_out_overlay  = ivtv_g_fmt_vid_out_overlay;
+       vdev->vidioc_g_fmt_sliced_vbi_out   = ivtv_g_fmt_sliced_vbi_out;
+       vdev->vidioc_s_fmt_vid_cap          = ivtv_s_fmt_vid_cap;
+       vdev->vidioc_s_fmt_vbi_cap          = ivtv_s_fmt_vbi_cap;
+       vdev->vidioc_s_fmt_sliced_vbi_cap   = ivtv_s_fmt_sliced_vbi_cap;
+       vdev->vidioc_s_fmt_vid_out          = ivtv_s_fmt_vid_out;
+       vdev->vidioc_s_fmt_vid_out_overlay  = ivtv_s_fmt_vid_out_overlay;
+       vdev->vidioc_s_fmt_sliced_vbi_out   = ivtv_s_fmt_sliced_vbi_out;
+       vdev->vidioc_try_fmt_vid_cap        = ivtv_try_fmt_vid_cap;
+       vdev->vidioc_try_fmt_vbi_cap        = ivtv_try_fmt_vbi_cap;
+       vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap;
+       vdev->vidioc_try_fmt_vid_out        = ivtv_try_fmt_vid_out;
+       vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay;
+       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;
+       vdev->vidioc_g_register             = ivtv_g_register;
+       vdev->vidioc_s_register             = ivtv_s_register;
+       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;
+}
index 4e67f0e..7018858 100644 (file)
 u16 ivtv_service2vbi(int type);
 void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
 u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg);
-int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
 void ivtv_set_osd_alpha(struct ivtv *itv);
 int ivtv_set_speed(struct ivtv *itv, int speed);
+void ivtv_set_funcs(struct video_device *vdev);
+int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std);
+int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
+int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
+int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+                   unsigned long arg);
 
 #endif
index c854285..f8883b4 100644 (file)
@@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
        s->v4l2dev->dev = &itv->dev->dev;
        s->v4l2dev->fops = ivtv_stream_info[type].fops;
        s->v4l2dev->release = video_device_release;
-
+       s->v4l2dev->tvnorms = V4L2_STD_ALL;
+       ivtv_set_funcs(s->v4l2dev);
        return 0;
 }