diff options
Diffstat (limited to 'drivers/media/pci/cx18/cx18-ioctl.c')
| -rw-r--r-- | drivers/media/pci/cx18/cx18-ioctl.c | 475 |
1 files changed, 205 insertions, 270 deletions
diff --git a/drivers/media/pci/cx18/cx18-ioctl.c b/drivers/media/pci/cx18/cx18-ioctl.c index c8ba7841c720..0d676a57e24e 100644 --- a/drivers/media/pci/cx18/cx18-ioctl.c +++ b/drivers/media/pci/cx18/cx18-ioctl.c @@ -4,7 +4,7 @@ * * Derived from ivtv-ioctl.c * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> + * Copyright (C) 2007 Hans Verkuil <hverkuil@kernel.org> * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> */ @@ -27,6 +27,133 @@ #include <media/tveeprom.h> #include <media/v4l2-event.h> +static const struct v4l2_fmtdesc cx18_formats_yuv[] = { + { + .index = 0, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .pixelformat = V4L2_PIX_FMT_NV12_16L16, + }, + { + .index = 1, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .pixelformat = V4L2_PIX_FMT_UYVY, + }, +}; + +static const struct v4l2_fmtdesc cx18_formats_mpeg[] = { + { + .index = 0, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, + .flags = V4L2_FMT_FLAG_COMPRESSED, + .pixelformat = V4L2_PIX_FMT_MPEG, + }, +}; + +static int cx18_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18_open_id *id = file2id(file); + struct cx18 *cx = id->cx; + struct cx18_stream *s = &cx->streams[id->type]; + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; + + pixfmt->width = cx->cxhdl.width; + pixfmt->height = cx->cxhdl.height; + pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + pixfmt->field = V4L2_FIELD_INTERLACED; + if (id->type == CX18_ENC_STREAM_TYPE_YUV) { + pixfmt->pixelformat = s->pixelformat; + pixfmt->sizeimage = s->vb_bytes_per_frame; + pixfmt->bytesperline = s->vb_bytes_per_line; + } else { + pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; + pixfmt->sizeimage = 128 * 1024; + pixfmt->bytesperline = 0; + } + return 0; +} + +static int cx18_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18_open_id *id = file2id(file); + struct cx18 *cx = id->cx; + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; + int w = pixfmt->width; + int h = pixfmt->height; + + w = min(w, 720); + w = max(w, 720 / 16); + + h = min(h, cx->is_50hz ? 576 : 480); + h = max(h, (cx->is_50hz ? 576 : 480) / 8); + + if (id->type == CX18_ENC_STREAM_TYPE_YUV) { + if (pixfmt->pixelformat != V4L2_PIX_FMT_NV12_16L16 && + pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) + pixfmt->pixelformat = V4L2_PIX_FMT_UYVY; + /* YUV height must be a multiple of 32 */ + h = round_up(h, 32); + /* + * HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) + * UYUV YUV size is (Y=(h*720) + UV=(h*(720))) + */ + if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12_16L16) { + pixfmt->sizeimage = h * 720 * 3 / 2; + pixfmt->bytesperline = 720; /* First plane */ + } else { + pixfmt->sizeimage = h * 720 * 2; + pixfmt->bytesperline = 1440; /* Packed */ + } + } else { + pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; + pixfmt->sizeimage = 128 * 1024; + pixfmt->bytesperline = 0; + } + + pixfmt->width = w; + pixfmt->height = h; + pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + pixfmt->field = V4L2_FIELD_INTERLACED; + return 0; +} + +static int cx18_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18_open_id *id = file2id(file); + struct cx18 *cx = id->cx; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct cx18_stream *s = &cx->streams[id->type]; + int ret; + int w, h; + + ret = cx18_try_fmt_vid_cap(file, fh, fmt); + if (ret) + return ret; + w = fmt->fmt.pix.width; + h = fmt->fmt.pix.height; + + if (cx->cxhdl.width == w && cx->cxhdl.height == h && + s->pixelformat == fmt->fmt.pix.pixelformat) + return 0; + + if (atomic_read(&cx->ana_capturing) > 0) + return -EBUSY; + + s->pixelformat = fmt->fmt.pix.pixelformat; + s->vb_bytes_per_frame = fmt->fmt.pix.sizeimage; + s->vb_bytes_per_line = fmt->fmt.pix.bytesperline; + + format.format.width = cx->cxhdl.width = w; + format.format.height = cx->cxhdl.height = h; + format.format.code = MEDIA_BUS_FMT_FIXED; + v4l2_subdev_call(cx->sd_av, pad, set_fmt, NULL, &format); + return cx18_g_fmt_vid_cap(file, fh, fmt); +} + u16 cx18_service2vbi(int type) { switch (type) { @@ -131,34 +258,10 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) return set; } -static int cx18_g_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; - - pixfmt->width = cx->cxhdl.width; - pixfmt->height = cx->cxhdl.height; - pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - pixfmt->field = V4L2_FIELD_INTERLACED; - if (id->type == CX18_ENC_STREAM_TYPE_YUV) { - pixfmt->pixelformat = s->pixelformat; - pixfmt->sizeimage = s->vb_bytes_per_frame; - pixfmt->bytesperline = s->vb_bytes_per_line; - } else { - pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; - pixfmt->sizeimage = 128 * 1024; - pixfmt->bytesperline = 0; - } - return 0; -} - static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; vbifmt->sampling_rate = 27000000; @@ -177,7 +280,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; /* sane, V4L2 spec compliant, defaults */ @@ -199,30 +302,6 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, return 0; } -static int cx18_try_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; - int w = fmt->fmt.pix.width; - int h = fmt->fmt.pix.height; - int min_h = 2; - - w = min(w, 720); - w = max(w, 2); - if (id->type == CX18_ENC_STREAM_TYPE_YUV) { - /* YUV height must be a multiple of 32 */ - h &= ~0x1f; - min_h = 32; - } - h = min(h, cx->is_50hz ? 576 : 480); - h = max(h, min_h); - - fmt->fmt.pix.width = w; - fmt->fmt.pix.height = h; - return 0; -} - static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { @@ -232,7 +311,7 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; @@ -248,53 +327,10 @@ static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, return 0; } -static int cx18_s_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; - struct v4l2_subdev_format format = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; - struct cx18_stream *s = &cx->streams[id->type]; - int ret; - int w, h; - - ret = cx18_try_fmt_vid_cap(file, fh, fmt); - if (ret) - return ret; - w = fmt->fmt.pix.width; - h = fmt->fmt.pix.height; - - if (cx->cxhdl.width == w && cx->cxhdl.height == h && - s->pixelformat == fmt->fmt.pix.pixelformat) - return 0; - - if (atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - - s->pixelformat = fmt->fmt.pix.pixelformat; - /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) - UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */ - if (s->pixelformat == V4L2_PIX_FMT_NV12_16L16) { - s->vb_bytes_per_frame = h * 720 * 3 / 2; - s->vb_bytes_per_line = 720; /* First plane */ - } else { - s->vb_bytes_per_frame = h * 720 * 2; - s->vb_bytes_per_line = 1440; /* Packed */ - } - - format.format.width = cx->cxhdl.width = w; - format.format.height = cx->cxhdl.height = h; - format.format.code = MEDIA_BUS_FMT_FIXED; - v4l2_subdev_call(cx->sd_av, pad, set_fmt, NULL, &format); - return cx18_g_fmt_vid_cap(file, fh, fmt); -} - static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18_open_id *id = fh2id(fh); + struct cx18_open_id *id = file2id(file); struct cx18 *cx = id->cx; int ret; @@ -324,7 +360,7 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18_open_id *id = fh2id(fh); + struct cx18_open_id *id = file2id(file); struct cx18 *cx = id->cx; int ret; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; @@ -356,7 +392,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, static int cx18_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (reg->reg & 0x3) return -EINVAL; @@ -370,7 +406,7 @@ static int cx18_g_register(struct file *file, void *fh, static int cx18_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (reg->reg & 0x3) return -EINVAL; @@ -384,7 +420,7 @@ static int cx18_s_register(struct file *file, void *fh, static int cx18_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) { - struct cx18_open_id *id = fh2id(fh); + struct cx18_open_id *id = file2id(file); struct cx18 *cx = id->cx; strscpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); @@ -395,14 +431,14 @@ static int cx18_querycap(struct file *file, void *fh, static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; return cx18_get_audio_input(cx, vin->index, vin); } static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; vin->index = cx->audio_input; return cx18_get_audio_input(cx, vin->index, vin); @@ -410,7 +446,7 @@ static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) static int cx18_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (vout->index >= cx->nof_audio_inputs) return -EINVAL; @@ -421,7 +457,7 @@ static int cx18_s_audio(struct file *file, void *fh, const struct v4l2_audio *vo static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; /* set it to defaults from our table */ return cx18_get_input(cx, vin->index, vin); @@ -430,7 +466,7 @@ static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) static int cx18_g_pixelaspect(struct file *file, void *fh, int type, struct v4l2_fract *f) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -443,7 +479,7 @@ static int cx18_g_pixelaspect(struct file *file, void *fh, static int cx18_g_selection(struct file *file, void *fh, struct v4l2_selection *sel) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -463,46 +499,30 @@ static int cx18_g_selection(struct file *file, void *fh, static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) { - static const struct v4l2_fmtdesc formats[] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "HM12 (YUV 4:1:1)", - .pixelformat = V4L2_PIX_FMT_NV12_16L16, - }, - { - .index = 1, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .description = "MPEG", - .pixelformat = V4L2_PIX_FMT_MPEG, - }, - { - .index = 2, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "UYVY 4:2:2", - .pixelformat = V4L2_PIX_FMT_UYVY, - }, - }; + struct cx18_open_id *id = file2id(file); - if (fmt->index > ARRAY_SIZE(formats) - 1) + if (id->type == CX18_ENC_STREAM_TYPE_YUV) { + if (fmt->index >= ARRAY_SIZE(cx18_formats_yuv)) + return -EINVAL; + *fmt = cx18_formats_yuv[fmt->index]; + return 0; + } + if (fmt->index) return -EINVAL; - *fmt = formats[fmt->index]; + *fmt = cx18_formats_mpeg[0]; return 0; } static int cx18_g_input(struct file *file, void *fh, unsigned int *i) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; *i = cx->active_input; return 0; } -int cx18_s_input(struct file *file, void *fh, unsigned int inp) +int cx18_do_s_input(struct cx18 *cx, unsigned int inp) { - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; v4l2_std_id std = V4L2_STD_ALL; const struct cx18_card_video_input *card_input = cx->card->video_inputs + inp; @@ -536,10 +556,15 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) return 0; } +static int cx18_s_input(struct file *file, void *fh, unsigned int inp) +{ + return cx18_do_s_input(file2id(file)->cx, inp); +} + static int cx18_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (vf->tuner != 0) return -EINVAL; @@ -548,11 +573,8 @@ static int cx18_g_frequency(struct file *file, void *fh, return 0; } -int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf) +int cx18_do_s_frequency(struct cx18 *cx, const struct v4l2_frequency *vf) { - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; - if (vf->tuner != 0) return -EINVAL; @@ -563,19 +585,22 @@ int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *v return 0; } +static int cx18_s_frequency(struct file *file, void *fh, + const struct v4l2_frequency *vf) +{ + return cx18_do_s_frequency(file2id(file)->cx, vf); +} + static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; *std = cx->std; return 0; } -int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) +int cx18_do_s_std(struct cx18 *cx, v4l2_std_id std) { - struct cx18_open_id *id = fh2id(fh); - struct cx18 *cx = id->cx; - if ((std & V4L2_STD_ALL) == 0) return -EINVAL; @@ -596,6 +621,19 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz); cx->cxhdl.width = 720; cx->cxhdl.height = cx->is_50hz ? 576 : 480; + /* + * HM12 YUV size is (Y=(h*720) + UV=(h*(720/2))) + * UYUV YUV size is (Y=(h*720) + UV=(h*(720))) + */ + if (cx->streams[CX18_ENC_STREAM_TYPE_YUV].pixelformat == V4L2_PIX_FMT_NV12_16L16) { + cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_frame = + cx->cxhdl.height * 720 * 3 / 2; + cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_line = 720; + } else { + cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_frame = + cx->cxhdl.height * 720 * 2; + cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_line = 1440; + } cx->vbi.count = cx->is_50hz ? 18 : 12; cx->vbi.start[0] = cx->is_50hz ? 6 : 10; cx->vbi.start[1] = cx->is_50hz ? 318 : 273; @@ -607,9 +645,14 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) return 0; } +static int cx18_s_std(struct file *file, void *fh, v4l2_std_id std) +{ + return cx18_do_s_std(file2id(file)->cx, std); +} + static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt) { - struct cx18_open_id *id = fh2id(fh); + struct cx18_open_id *id = file2id(file); struct cx18 *cx = id->cx; if (vt->index != 0) @@ -621,7 +664,7 @@ static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; if (vt->index != 0) return -EINVAL; @@ -638,7 +681,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; int f, l; @@ -729,7 +772,7 @@ static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl, mdl->curr_buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, list); - if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) { + if (list_entry_is_head(mdl->curr_buf, &mdl->buf_list, list)) { /* * For some reason we've exhausted the buffers, but the MDL * object still said some data was unread. @@ -759,7 +802,7 @@ static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl, static int cx18_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX]; s32 tmp; struct cx18_mdl *mdl; @@ -803,121 +846,10 @@ static int cx18_g_enc_index(struct file *file, void *fh, return 0; } -static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id) -{ - struct videobuf_queue *q = NULL; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - switch (s->vb_type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - q = &s->vbuf_q; - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - break; - default: - break; - } - return q; -} - -static int cx18_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - /* Start the hardware only if we're the video device */ - if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - if (id->type != CX18_ENC_STREAM_TYPE_YUV) - return -EINVAL; - - /* Establish a buffer timeout */ - mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies); - - return videobuf_streamon(cx18_vb_queue(id)); -} - -static int cx18_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - /* Start the hardware only if we're the video device */ - if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - if (id->type != CX18_ENC_STREAM_TYPE_YUV) - return -EINVAL; - - return videobuf_streamoff(cx18_vb_queue(id)); -} - -static int cx18_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *rb) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - return videobuf_reqbufs(cx18_vb_queue(id), rb); -} - -static int cx18_querybuf(struct file *file, void *priv, - struct v4l2_buffer *b) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - return videobuf_querybuf(cx18_vb_queue(id), b); -} - -static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - return videobuf_qbuf(cx18_vb_queue(id), b); -} - -static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx18_open_id *id = file->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - - return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK); -} - static int cx18_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) { - struct cx18_open_id *id = fh2id(fh); + struct cx18_open_id *id = file2id(file); struct cx18 *cx = id->cx; u32 h; @@ -930,7 +862,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, case V4L2_ENC_CMD_STOP: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; - cx18_stop_capture(id, + cx18_stop_capture(&cx->streams[id->type], enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); break; @@ -976,7 +908,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, static int cx18_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; switch (enc->cmd) { case V4L2_ENC_CMD_START: @@ -1008,7 +940,7 @@ static int cx18_try_encoder_cmd(struct file *file, void *fh, static int cx18_log_status(struct file *file, void *fh) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; struct v4l2_input vidin; struct v4l2_audio audin; int i; @@ -1052,7 +984,7 @@ static int cx18_log_status(struct file *file, void *fh) static long cx18_default(struct file *file, void *fh, bool valid_prio, unsigned int cmd, void *arg) { - struct cx18 *cx = fh2id(fh)->cx; + struct cx18 *cx = file2id(file)->cx; switch (cmd) { case VIDIOC_INT_RESET: { @@ -1106,12 +1038,15 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = { .vidioc_s_register = cx18_s_register, #endif .vidioc_default = cx18_default, - .vidioc_streamon = cx18_streamon, - .vidioc_streamoff = cx18_streamoff, - .vidioc_reqbufs = cx18_reqbufs, - .vidioc_querybuf = cx18_querybuf, - .vidioc_qbuf = cx18_qbuf, - .vidioc_dqbuf = cx18_dqbuf, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; |
