V4L/DVB (10138): v4l2-ioctl: change to long return type to match unlocked_ioctl.
[safe/jmp/linux-2.6] / drivers / media / video / ivtv / ivtv-ioctl.c
index b1cda6c..1f6ca93 100644 (file)
@@ -101,18 +101,15 @@ void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
        }
 }
 
-static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 {
        int f, l;
-       u16 set = 0;
 
        for (f = 0; f < 2; f++) {
                for (l = 0; l < 24; l++) {
                        fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
-                       set |= fmt->service_lines[f][l];
                }
        }
-       return set != 0;
 }
 
 u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt)
@@ -314,34 +311,6 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
        return 0;
 }
 
-static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
-{
-       struct v4l2_register *regs = arg;
-       unsigned long flags;
-       volatile u8 __iomem *reg_start;
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-       if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
-               reg_start = itv->reg_mem - IVTV_REG_OFFSET;
-       else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
-                       regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
-               reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
-       else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
-               reg_start = itv->enc_mem;
-       else
-               return -EINVAL;
-
-       spin_lock_irqsave(&ivtv_cards_lock, flags);
-       if (cmd == VIDIOC_DBG_G_REGISTER) {
-               regs->val = readl(regs->reg + reg_start);
-       } else {
-               writel(regs->val, regs->reg + reg_start);
-       }
-       spin_unlock_irqrestore(&ivtv_cards_lock, flags);
-       return 0;
-}
-
 static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
 {
        struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
@@ -424,7 +393,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
                return 0;
        }
 
-       itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
+       v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
        vbifmt->service_set = ivtv_get_service_set(vbifmt);
        return 0;
 }
@@ -502,7 +471,7 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
        int h = fmt->fmt.pix.height;
 
        w = min(w, 720);
-       w = max(w, 1);
+       w = max(w, 2);
        h = min(h, itv->is_50hz ? 576 : 480);
        h = max(h, 2);
        ivtv_g_fmt_vid_cap(file, fh, fmt);
@@ -540,27 +509,34 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
 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);
+       s32 w = fmt->fmt.pix.width;
+       s32 h = fmt->fmt.pix.height;
+       int field = fmt->fmt.pix.field;
+       int ret = ivtv_g_fmt_vid_out(file, fh, fmt);
+
+       w = min(w, 720);
+       w = max(w, 2);
+       /* Why can the height be 576 even when the output is NTSC?
+
+          Internally the buffers of the PVR350 are always set to 720x576. The
+          decoded video frame will always be placed in the top left corner of
+          this buffer. For any video which is not 720x576, the buffer will
+          then be cropped to remove the unused right and lower areas, with
+          the remaining image being scaled by the hardware to fit the display
+          area. The video can be scaled both up and down, so a 720x480 video
+          can be displayed full-screen on PAL and a 720x576 video can be
+          displayed without cropping on NTSC.
+
+          Note that the scaling only occurs on the video stream, the osd
+          resolution is locked to the broadcast standard and not scaled.
+
+          Thanks to Ian Armstrong for this explanation. */
+       h = min(h, 576);
+       h = max(h, 2);
+       if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
+               fmt->fmt.pix.field = field;
        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;
 }
 
@@ -588,9 +564,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
        struct ivtv_open_id *id = fh;
        struct ivtv *itv = id->itv;
        struct cx2341x_mpeg_params *p = &itv->params;
+       int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
        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;
@@ -605,7 +581,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
        p->height = h;
        if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
                fmt->fmt.pix.width /= 2;
-       itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
+       v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
        return ivtv_g_fmt_vid_cap(file, fh, fmt);
 }
 
@@ -613,8 +589,11 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
 {
        struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
+       if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
+               return -EBUSY;
        itv->vbi.sliced_in->service_set = 0;
-       itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
+       itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
+       v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
        return ivtv_g_fmt_vbi_cap(file, fh, fmt);
 }
 
@@ -628,11 +607,11 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
        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)
+       check_service_set(vbifmt, itv->is_50hz);
+       if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
                return -EBUSY;
-       itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
+       itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+       v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt);
        memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
        return 0;
 }
@@ -679,8 +658,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
                itv->dma_data_req_size =
                        1080 * ((yi->v4l2_src_h + 31) & ~31);
 
-       /* Force update of yuv registers */
-       yi->yuv_forced_update = 1;
        return 0;
 }
 
@@ -708,11 +685,36 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident
                        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;
+       if (chip->match_type != V4L2_CHIP_MATCH_I2C_DRIVER &&
+           chip->match_type != V4L2_CHIP_MATCH_I2C_ADDR)
+               return -EINVAL;
+       /* TODO: is this correct? */
+       return ivtv_call_all_err(itv, core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
+{
+       struct v4l2_register *regs = arg;
+       volatile u8 __iomem *reg_start;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+       if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
+               reg_start = itv->reg_mem - IVTV_REG_OFFSET;
+       else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
+                       regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
+               reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
+       else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
+               reg_start = itv->enc_mem;
+       else
+               return -EINVAL;
+
+       if (cmd == VIDIOC_DBG_G_REGISTER)
+               regs->val = readl(regs->reg + reg_start);
+       else
+               writel(regs->val, regs->reg + reg_start);
+       return 0;
 }
 
 static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg)
@@ -721,9 +723,10 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *re
 
        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);
+       /* TODO: subdev errors should not be ignored, this should become a
+          subdev helper function. */
+       ivtv_call_all(itv, core, g_register, reg);
+       return 0;
 }
 
 static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg)
@@ -732,10 +735,12 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *re
 
        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);
+       /* TODO: subdev errors should not be ignored, this should become a
+          subdev helper function. */
+       ivtv_call_all(itv, core, s_register, reg);
+       return 0;
 }
+#endif
 
 static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
 {
@@ -760,7 +765,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
 
        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));
+       snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev));
        vcap->version = IVTV_DRIVER_VERSION;        /* version */
        vcap->capabilities = itv->v4l2_cap;         /* capabilities */
        return 0;
@@ -878,12 +883,6 @@ static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 
        streamtype = id->type;
 
-       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) {
@@ -1044,7 +1043,7 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int 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);
+       ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing, &route);
 
        return 0;
 }
@@ -1056,7 +1055,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
        if (vf->tuner != 0)
                return -EINVAL;
 
-       ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf);
+       ivtv_call_all(itv, tuner, g_frequency, vf);
        return 0;
 }
 
@@ -1069,7 +1068,7 @@ int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
 
        ivtv_mute(itv);
        IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
-       ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf);
+       ivtv_call_all(itv, tuner, s_frequency, vf);
        ivtv_unmute(itv);
        return 0;
 }
@@ -1117,14 +1116,14 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
        IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
 
        /* Tuner */
-       ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
+       ivtv_call_all(itv, tuner, 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_call_all(itv, video, 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;
@@ -1148,7 +1147,7 @@ static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        if (vt->index != 0)
                return -EINVAL;
 
-       ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
+       ivtv_call_all(itv, tuner, s_tuner, vt);
 
        return 0;
 }
@@ -1160,7 +1159,7 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
        if (vt->index != 0)
                return -EINVAL;
 
-       ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
+       ivtv_call_all(itv, tuner, g_tuner, vt);
 
        if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
                strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
@@ -1336,6 +1335,8 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
 
        if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -EINVAL;
+       if (!itv->osd_video_pbase)
+               return -EINVAL;
 
        fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
                V4L2_FBUF_CAP_GLOBAL_ALPHA;
@@ -1349,11 +1350,15 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
        fb->fmt.height = itv->osd_rect.height;
        fb->fmt.field = V4L2_FIELD_INTERLACED;
        fb->fmt.bytesperline = fb->fmt.width;
+       fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
+       fb->fmt.field = V4L2_FIELD_INTERLACED;
+       fb->fmt.priv = 0;
        if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8)
                fb->fmt.bytesperline *= 2;
        if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 ||
            fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32)
                fb->fmt.bytesperline *= 2;
+       fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height;
        fb->base = (void *)itv->osd_video_pbase;
        fb->flags = 0;
 
@@ -1363,6 +1368,9 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
        if (itv->osd_global_alpha_state)
                fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
 
+       if (yi->track_osd)
+               fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
+
        pixfmt &= 7;
 
        /* no local alpha for RGB565 or unknown formats */
@@ -1382,8 +1390,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
                else
                        fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
        }
-       if (yi->track_osd)
-               fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
 
        return 0;
 }
@@ -1396,6 +1402,8 @@ static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
 
        if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
                return -EINVAL;
+       if (!itv->osd_video_pbase)
+               return -EINVAL;
 
        itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
        itv->osd_local_alpha_state =
@@ -1429,14 +1437,15 @@ static int ivtv_log_status(struct file *file, void *fh)
        struct v4l2_audio audin;
        int i;
 
-       IVTV_INFO("=================  START STATUS CARD #%d  =================\n", itv->num);
+       IVTV_INFO("=================  START STATUS CARD #%d  =================\n",
+                      itv->instance);
        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_call_all(itv, core, log_status);
        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);
@@ -1503,7 +1512,7 @@ static int ivtv_log_status(struct file *file, void *fh)
        }
        IVTV_INFO("Tuner:  %s\n",
                test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
-       cx2341x_log_status(&itv->params, itv->name);
+       cx2341x_log_status(&itv->params, itv->device.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];
@@ -1515,8 +1524,11 @@ static int ivtv_log_status(struct file *file, void *fh)
                                (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);
+       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->instance);
 
        return 0;
 }
@@ -1539,7 +1551,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
                        return 0;
-               if (ivtv_claim_stream(id, id->type)) {
+               if (ivtv_start_decoding(id, id->type)) {
                        return -EBUSY;
                }
                if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
@@ -1713,7 +1725,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
        return 0;
 }
 
-static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
+static long ivtv_default(struct file *file, void *fh, int cmd, void *arg)
 {
        struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
 
@@ -1721,7 +1733,7 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
        case VIDIOC_INT_S_AUDIO_ROUTING: {
                struct v4l2_routing *route = arg;
 
-               ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
+               ivtv_call_hw(itv, itv->card->hw_audio, audio, s_routing, route);
                break;
        }
 
@@ -1731,7 +1743,7 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
                if ((val == 0 && itv->options.newi2c) || (val & 0x01))
                        ivtv_reset_ir_gpio(itv);
                if (val & 0x02)
-                       itv->video_dec_func(itv, cmd, NULL);
+                       v4l2_subdev_call(itv->sd_video, core, reset, 0);
                break;
        }
 
@@ -1741,11 +1753,12 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
        return 0;
 }
 
-static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
+static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
                unsigned int cmd, unsigned long arg)
 {
+       struct video_device *vfd = video_devdata(filp);
        struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
-       int ret;
+       long ret;
 
        /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */
        switch (cmd) {
@@ -1812,91 +1825,92 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f
                        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);
+       if (ivtv_debug & IVTV_DBGFLG_IOCTL)
+               vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
+       ret = video_ioctl2(filp, cmd, arg);
+       vfd->debug = 0;
+       return ret;
 }
 
-int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
-                   unsigned long arg)
+long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
        struct ivtv *itv = id->itv;
-       int res;
+       long res;
 
        mutex_lock(&itv->serialize_lock);
-       res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
+       res = ivtv_serialized_ioctl(itv, filp, cmd, arg);
        mutex_unlock(&itv->serialize_lock);
        return res;
 }
 
+static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
+       .vidioc_querycap                    = ivtv_querycap,
+       .vidioc_g_priority                  = ivtv_g_priority,
+       .vidioc_s_priority                  = ivtv_s_priority,
+       .vidioc_s_audio                     = ivtv_s_audio,
+       .vidioc_g_audio                     = ivtv_g_audio,
+       .vidioc_enumaudio                   = ivtv_enumaudio,
+       .vidioc_s_audout                    = ivtv_s_audout,
+       .vidioc_g_audout                    = ivtv_g_audout,
+       .vidioc_enum_input                  = ivtv_enum_input,
+       .vidioc_enum_output                 = ivtv_enum_output,
+       .vidioc_enumaudout                  = ivtv_enumaudout,
+       .vidioc_cropcap                     = ivtv_cropcap,
+       .vidioc_s_crop                      = ivtv_s_crop,
+       .vidioc_g_crop                      = ivtv_g_crop,
+       .vidioc_g_input                     = ivtv_g_input,
+       .vidioc_s_input                     = ivtv_s_input,
+       .vidioc_g_output                    = ivtv_g_output,
+       .vidioc_s_output                    = ivtv_s_output,
+       .vidioc_g_frequency                 = ivtv_g_frequency,
+       .vidioc_s_frequency                 = ivtv_s_frequency,
+       .vidioc_s_tuner                     = ivtv_s_tuner,
+       .vidioc_g_tuner                     = ivtv_g_tuner,
+       .vidioc_g_enc_index                 = ivtv_g_enc_index,
+       .vidioc_g_fbuf                      = ivtv_g_fbuf,
+       .vidioc_s_fbuf                      = ivtv_s_fbuf,
+       .vidioc_g_std                       = ivtv_g_std,
+       .vidioc_s_std                       = ivtv_s_std,
+       .vidioc_overlay                     = ivtv_overlay,
+       .vidioc_log_status                  = ivtv_log_status,
+       .vidioc_enum_fmt_vid_cap            = ivtv_enum_fmt_vid_cap,
+       .vidioc_encoder_cmd                 = ivtv_encoder_cmd,
+       .vidioc_try_encoder_cmd             = ivtv_try_encoder_cmd,
+       .vidioc_enum_fmt_vid_out            = ivtv_enum_fmt_vid_out,
+       .vidioc_g_fmt_vid_cap               = ivtv_g_fmt_vid_cap,
+       .vidioc_g_fmt_vbi_cap               = ivtv_g_fmt_vbi_cap,
+       .vidioc_g_fmt_sliced_vbi_cap        = ivtv_g_fmt_sliced_vbi_cap,
+       .vidioc_g_fmt_vid_out               = ivtv_g_fmt_vid_out,
+       .vidioc_g_fmt_vid_out_overlay       = ivtv_g_fmt_vid_out_overlay,
+       .vidioc_g_fmt_sliced_vbi_out        = ivtv_g_fmt_sliced_vbi_out,
+       .vidioc_s_fmt_vid_cap               = ivtv_s_fmt_vid_cap,
+       .vidioc_s_fmt_vbi_cap               = ivtv_s_fmt_vbi_cap,
+       .vidioc_s_fmt_sliced_vbi_cap        = ivtv_s_fmt_sliced_vbi_cap,
+       .vidioc_s_fmt_vid_out               = ivtv_s_fmt_vid_out,
+       .vidioc_s_fmt_vid_out_overlay       = ivtv_s_fmt_vid_out_overlay,
+       .vidioc_s_fmt_sliced_vbi_out        = ivtv_s_fmt_sliced_vbi_out,
+       .vidioc_try_fmt_vid_cap             = ivtv_try_fmt_vid_cap,
+       .vidioc_try_fmt_vbi_cap             = ivtv_try_fmt_vbi_cap,
+       .vidioc_try_fmt_sliced_vbi_cap      = ivtv_try_fmt_sliced_vbi_cap,
+       .vidioc_try_fmt_vid_out             = ivtv_try_fmt_vid_out,
+       .vidioc_try_fmt_vid_out_overlay     = ivtv_try_fmt_vid_out_overlay,
+       .vidioc_try_fmt_sliced_vbi_out      = ivtv_try_fmt_sliced_vbi_out,
+       .vidioc_g_sliced_vbi_cap            = ivtv_g_sliced_vbi_cap,
+       .vidioc_g_chip_ident                = ivtv_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+       .vidioc_g_register                  = ivtv_g_register,
+       .vidioc_s_register                  = ivtv_s_register,
+#endif
+       .vidioc_default                     = ivtv_default,
+       .vidioc_queryctrl                   = ivtv_queryctrl,
+       .vidioc_querymenu                   = ivtv_querymenu,
+       .vidioc_g_ext_ctrls                 = ivtv_g_ext_ctrls,
+       .vidioc_s_ext_ctrls                 = ivtv_s_ext_ctrls,
+       .vidioc_try_ext_ctrls               = ivtv_try_ext_ctrls,
+};
+
 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;
+       vdev->ioctl_ops = &ivtv_ioctl_ops;
 }