Commit 3f038d80 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB (8079): ivtv: Convert to video_ioctl2.

Based on an initial conversion patch from Douglas Landgraf.
Signed-off-by: default avatarDouglas Schilling Landgraf <dougsland@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 539a7555
...@@ -47,8 +47,10 @@ static const u32 *ctrl_classes[] = { ...@@ -47,8 +47,10 @@ static const u32 *ctrl_classes[] = {
NULL 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; const char *name;
IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
...@@ -87,17 +89,20 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl) ...@@ -87,17 +89,20 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
return 0; 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; struct v4l2_queryctrl qctrl;
IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
qctrl.id = qmenu->id; 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)); 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; s32 v = vctrl->value;
IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); 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) ...@@ -125,8 +130,10 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
return 0; 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); IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
switch (vctrl->id) { switch (vctrl->id) {
...@@ -191,27 +198,37 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm ...@@ -191,27 +198,37 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
return 0; 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; struct v4l2_control ctrl;
switch (cmd) { if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
case VIDIOC_QUERYMENU: int i;
IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); int err = 0;
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: for (i = 0; i < c->count; i++) {
return ivtv_g_ctrl(itv, arg); 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;
}
}
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_S_EXT_CTRLS: int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
{ {
struct v4l2_ext_controls *c = arg; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_control ctrl;
if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
int i; int i;
...@@ -220,7 +237,7 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) ...@@ -220,7 +237,7 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
for (i = 0; i < c->count; i++) { for (i = 0; i < c->count; i++) {
ctrl.id = c->controls[i].id; ctrl.id = c->controls[i].id;
ctrl.value = c->controls[i].value; ctrl.value = c->controls[i].value;
err = ivtv_s_ctrl(itv, &ctrl); err = ivtv_s_ctrl(file, fh, &ctrl);
c->controls[i].value = ctrl.value; c->controls[i].value = ctrl.value;
if (err) { if (err) {
c->error_idx = i; c->error_idx = i;
...@@ -233,7 +250,7 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) ...@@ -233,7 +250,7 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
static u32 freqs[3] = { 44100, 48000, 32000 }; static u32 freqs[3] = { 44100, 48000, 32000 };
struct cx2341x_mpeg_params p = itv->params; struct cx2341x_mpeg_params p = itv->params;
int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd); int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS);
unsigned idx; unsigned idx;
if (err) if (err)
...@@ -251,9 +268,8 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) ...@@ -251,9 +268,8 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt); itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
} }
err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) { if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt); err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
}
itv->params = p; itv->params = p;
itv->dualwatch_stereo_mode = p.audio_properties & 0x0300; itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
idx = p.audio_properties & 0x03; idx = p.audio_properties & 0x03;
...@@ -264,46 +280,14 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) ...@@ -264,46 +280,14 @@ int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
return err; return err;
} }
return -EINVAL; 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;
}
}
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;
}
case VIDIOC_TRY_EXT_CTRLS: int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
{ {
struct v4l2_ext_controls *c = arg; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd); return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS);
return -EINVAL; return -EINVAL;
}
default:
return -EINVAL;
}
return 0;
} }
...@@ -21,6 +21,12 @@ ...@@ -21,6 +21,12 @@
#ifndef IVTV_CONTROLS_H #ifndef IVTV_CONTROLS_H
#define 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 #endif
...@@ -1262,9 +1262,13 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ...@@ -1262,9 +1262,13 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
int ivtv_init_on_first_open(struct ivtv *itv) int ivtv_init_on_first_open(struct ivtv *itv)
{ {
struct v4l2_frequency vf; struct v4l2_frequency vf;
/* Needed to call ioctls later */
struct ivtv_open_id fh;
int fw_retry_count = 3; int fw_retry_count = 3;
int video_input; int video_input;
fh.itv = itv;
if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
return -ENXIO; return -ENXIO;
...@@ -1312,18 +1316,18 @@ int ivtv_init_on_first_open(struct ivtv *itv) ...@@ -1312,18 +1316,18 @@ int ivtv_init_on_first_open(struct ivtv *itv)
video_input = itv->active_input; video_input = itv->active_input;
itv->active_input++; /* Force update of 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 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
in one place. */ in one place. */
itv->std++; /* Force full standard initialization */ itv->std++; /* Force full standard initialization */
itv->std_out = itv->std; 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) { if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
ivtv_init_mpeg_decoder(itv); 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? */ /* On a cx23416 this seems to be able to enable DMA to the chip? */
if (!itv->has_cx23415) if (!itv->has_cx23415)
......
...@@ -373,17 +373,94 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) ...@@ -373,17 +373,94 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
return 0; 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) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
case V4L2_BUF_TYPE_VIDEO_OUTPUT: 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;
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;
}
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;
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_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
{
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;
}
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;
vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
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;
}
itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
vbifmt->service_set = ivtv_get_service_set(vbifmt);
return 0;
}
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;
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL; return -EINVAL;
fmt->fmt.pix.width = itv->main_rect.width; fmt->fmt.pix.width = itv->main_rect.width;
fmt->fmt.pix.height = itv->main_rect.height; fmt->fmt.pix.height = itv->main_rect.height;
fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
case IVTV_YUV_MODE_INTERLACED: case IVTV_YUV_MODE_INTERLACED:
fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
...@@ -403,7 +480,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm ...@@ -403,7 +480,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
/* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
fmt->fmt.pix.sizeimage = fmt->fmt.pix.sizeimage =
1080 * ((fmt->fmt.pix.height + 31) & ~31); 1080 * ((fmt->fmt.pix.height + 31) & ~31);
} else if (streamtype == IVTV_ENC_STREAM_TYPE_YUV) { } else if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
/* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
fmt->fmt.pix.sizeimage = fmt->fmt.pix.sizeimage =
...@@ -413,112 +490,81 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm ...@@ -413,112 +490,81 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
fmt->fmt.pix.sizeimage = 128 * 1024; fmt->fmt.pix.sizeimage = 128 * 1024;
} }
break; return 0;
}
case V4L2_BUF_TYPE_VIDEO_CAPTURE: static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
fmt->fmt.pix.width = itv->params.width; {
fmt->fmt.pix.height = itv->params.height; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
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)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL; return -EINVAL;
fmt->fmt.win.chromakey = itv->osd_chroma_key; fmt->fmt.win.chromakey = itv->osd_chroma_key;
fmt->fmt.win.global_alpha = itv->osd_global_alpha; fmt->fmt.win.global_alpha = itv->osd_global_alpha;
break; return 0;
}
case V4L2_BUF_TYPE_VBI_CAPTURE: static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
fmt->fmt.vbi.sampling_rate = 27000000; {
fmt->fmt.vbi.offset = 248; return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
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: static int ivtv_try_fmt_vid_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 w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) w = min(w, 720);
return -EINVAL; w = max(w, 1);
vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; h = min(h, itv->is_50hz ? 576 : 480);
memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); h = max(h, 2);
memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); ivtv_g_fmt_vid_cap(file, fh, fmt);
if (itv->is_60hz) { fmt->fmt.pix.width = w;
vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; fmt->fmt.pix.height = h;
vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; return 0;
} else { }
vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
} {
vbifmt->service_set = ivtv_get_service_set(vbifmt); return ivtv_g_fmt_vbi_cap(file, fh, fmt);
break; }
}
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 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 v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
struct ivtv_open_id *id = fh;
struct ivtv *itv = id->itv;
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; vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) { if (vbifmt->service_set)
vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
V4L2_SLICED_VBI_525;
ivtv_expand_service_set(vbifmt, itv->is_50hz); ivtv_expand_service_set(vbifmt, itv->is_50hz);
break; check_service_set(vbifmt, itv->is_50hz);
}
itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
vbifmt->service_set = ivtv_get_service_set(vbifmt); vbifmt->service_set = ivtv_get_service_set(vbifmt);
break;
}
case V4L2_BUF_TYPE_VBI_OUTPUT:
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
default:
return -EINVAL;
}
return 0; return 0;
} }
static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
struct v4l2_format *fmt, int set_fmt)
{ {
struct yuv_playback_info *yi = &itv->yuv_info; struct ivtv_open_id *id = fh;
struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; s32 w, h;
u16 set;
if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
struct v4l2_rect r;
int field; int field;
int ret;
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) w = fmt->fmt.pix.width;
return -EINVAL; h = fmt->fmt.pix.height;
field = fmt->fmt.pix.field; field = fmt->fmt.pix.field;
r.top = 0; ret = ivtv_g_fmt_vid_out(file, fh, fmt);
r.left = 0; fmt->fmt.pix.width = w;
r.width = fmt->fmt.pix.width; fmt->fmt.pix.height = h;
r.height = fmt->fmt.pix.height; if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) {
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; fmt->fmt.pix.field = field;
if (fmt->fmt.pix.width < 2) if (fmt->fmt.pix.width < 2)
fmt->fmt.pix.width = 2; fmt->fmt.pix.width = 2;
...@@ -529,70 +575,38 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, ...@@ -529,70 +575,38 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
if (fmt->fmt.pix.height > 576) if (fmt->fmt.pix.height > 576)
fmt->fmt.pix.height = 576; fmt->fmt.pix.height = 576;
} }
if (set_fmt && streamtype == IVTV_DEC_STREAM_TYPE_YUV) { return ret;
/* Return now if we already have some frame data */ }
if (yi->stream_size)
return -EBUSY;
yi->v4l2_src_w = r.width;
yi->v4l2_src_h = r.height;
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;
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 */ static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
yi->yuv_forced_update = 1; {
return 0; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
}
return 0;
}
if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) {
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL; 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; return 0;
} }
/* set window size */ static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { {
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; struct cx2341x_mpeg_params *p = &itv->params;
int w = fmt->fmt.pix.width; int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height; int h = fmt->fmt.pix.height;
int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
if (w > 720) w = 720; if (ret)
else if (w < 1) w = 1; return ret;
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)) if (p->width == w && p->height == h)
return 0; return 0;
if (atomic_read(&itv->capturing) > 0) if (atomic_read(&itv->capturing) > 0)
return -EBUSY; return -EBUSY;
...@@ -605,151 +619,157 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, ...@@ -605,151 +619,157 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
fmt->fmt.pix.width /= 2; fmt->fmt.pix.width /= 2;
itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
return ivtv_get_fmt(itv, streamtype, 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;
/* 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->vbi.sliced_in->service_set = 0;
itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
} return ivtv_g_fmt_vbi_cap(file, fh, fmt);
return ivtv_get_fmt(itv, streamtype, fmt); }
}
/* 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);
/* any else but sliced VBI capture is an error */
if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
return -EINVAL;
if (streamtype == IVTV_DEC_STREAM_TYPE_VBI)
return ivtv_get_fmt(itv, streamtype, fmt);
/* set sliced VBI capture format */ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; {
memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); 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 (vbifmt->service_set) if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
ivtv_expand_service_set(vbifmt, itv->is_50hz); return ret;
set = check_service_set(vbifmt, itv->is_50hz);
vbifmt->service_set = ivtv_get_service_set(vbifmt);
if (!set_fmt) if (check_service_set(vbifmt, itv->is_50hz) == 0)
return 0;
if (set == 0)
return -EINVAL; return -EINVAL;
if (atomic_read(&itv->capturing) > 0) { if (atomic_read(&itv->capturing) > 0)
return -EBUSY; return -EBUSY;
}
itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
return 0; 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 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: { if (ret)
struct v4l2_chip_ident *chip = arg; return ret;
chip->ident = V4L2_IDENT_NONE; if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
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; 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;
}
case VIDIOC_INT_S_AUDIO_ROUTING: { /* Return now if we already have some frame data */
struct v4l2_routing *route = arg; if (yi->stream_size)
return -EBUSY;
ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); yi->v4l2_src_w = fmt->fmt.pix.width;
yi->v4l2_src_h = fmt->fmt.pix.height;
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:
yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
break; break;
} }
yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
case VIDIOC_INT_RESET: { if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
u32 val = *(u32 *)arg; itv->dma_data_req_size =
1080 * ((yi->v4l2_src_h + 31) & ~31);
if ((val == 0 && itv->options.newi2c) || (val & 0x01)) { /* Force update of yuv registers */
ivtv_reset_ir_gpio(itv); yi->yuv_forced_update = 1;
} return 0;
if (val & 0x02) { }
itv->video_dec_func(itv, cmd, NULL);
}
break;
}
default: static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
return -EINVAL; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
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 0; return ret;
} }
int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip)
{ {
struct ivtv_open_id *id = NULL; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
u32 data[CX2341X_MBOX_MAX_DATA];
int streamtype = 0;
if (filp) { chip->ident = V4L2_IDENT_NONE;
id = (struct ivtv_open_id *)filp->private_data; chip->revision = 0;
streamtype = id->type; 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;
}
switch (cmd) { static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg)
case VIDIOC_G_PRIORITY: {
{ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
enum v4l2_priority *p = arg;
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;
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);
}
static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
{
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
*p = v4l2_prio_max(&itv->prio); *p = v4l2_prio_max(&itv->prio);
break;
}
case VIDIOC_S_PRIORITY: return 0;
{ }
enum v4l2_priority *prio = arg;
return v4l2_prio_change(&itv->prio, &id->prio, *prio); 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;
return v4l2_prio_change(&itv->prio, &id->prio, prio);
}
case VIDIOC_QUERYCAP:{ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
struct v4l2_capability *vcap = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
memset(vcap, 0, sizeof(*vcap)); memset(vcap, 0, sizeof(*vcap));
strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
...@@ -757,87 +777,86 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -757,87 +777,86 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->version = IVTV_DRIVER_VERSION; /* version */
vcap->capabilities = itv->v4l2_cap; /* capabilities */ vcap->capabilities = itv->v4l2_cap; /* capabilities */
/* reserved.. must set to 0! */ /* reserved.. must set to 0! */
vcap->reserved[0] = vcap->reserved[1] = vcap->reserved[0] = vcap->reserved[1] =
vcap->reserved[2] = vcap->reserved[3] = 0; vcap->reserved[2] = vcap->reserved[3] = 0;
break; return 0;
} }
case VIDIOC_ENUMAUDIO:{ static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
struct v4l2_audio *vin = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
return ivtv_get_audio_input(itv, vin->index, vin); return ivtv_get_audio_input(itv, vin->index, vin);
} }
case VIDIOC_G_AUDIO:{ static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
struct v4l2_audio *vin = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
vin->index = itv->audio_input; vin->index = itv->audio_input;
return ivtv_get_audio_input(itv, vin->index, vin); return ivtv_get_audio_input(itv, vin->index, vin);
} }
case VIDIOC_S_AUDIO:{ static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
struct v4l2_audio *vout = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
if (vout->index >= itv->nof_audio_inputs) if (vout->index >= itv->nof_audio_inputs)
return -EINVAL; return -EINVAL;
itv->audio_input = vout->index; itv->audio_input = vout->index;
ivtv_audio_set_io(itv); ivtv_audio_set_io(itv);
break;
}
case VIDIOC_ENUMAUDOUT:{ return 0;
struct v4l2_audioout *vin = arg; }
static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
{
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
/* set it to defaults from our table */ /* set it to defaults from our table */
return ivtv_get_audio_output(itv, vin->index, vin); return ivtv_get_audio_output(itv, vin->index, vin);
} }
case VIDIOC_G_AUDOUT:{ static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
struct v4l2_audioout *vin = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
vin->index = 0; vin->index = 0;
return ivtv_get_audio_output(itv, vin->index, vin); return ivtv_get_audio_output(itv, vin->index, vin);
} }
case VIDIOC_S_AUDOUT:{ static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
struct v4l2_audioout *vout = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
return ivtv_get_audio_output(itv, vout->index, vout); return ivtv_get_audio_output(itv, vout->index, vout);
} }
case VIDIOC_ENUMINPUT:{ static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
struct v4l2_input *vin = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
/* set it to defaults from our table */ /* set it to defaults from our table */
return ivtv_get_input(itv, vin->index, vin); return ivtv_get_input(itv, vin->index, vin);
} }
case VIDIOC_ENUMOUTPUT:{ static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
struct v4l2_output *vout = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
return ivtv_get_output(itv, vout->index, vout); return ivtv_get_output(itv, vout->index, vout);
} }
case VIDIOC_TRY_FMT:
case VIDIOC_S_FMT: {
struct v4l2_format *fmt = arg;
return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
}
case VIDIOC_G_FMT: {
struct v4l2_format *fmt = arg;
int type = fmt->type;
memset(fmt, 0, sizeof(*fmt)); static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
fmt->type = type; {
return ivtv_get_fmt(itv, id->type, fmt); struct ivtv_open_id *id = fh;
} struct ivtv *itv = id->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
int streamtype;
case VIDIOC_CROPCAP: { streamtype = id->type;
struct v4l2_cropcap *cropcap = arg;
if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL; return -EINVAL;
...@@ -865,10 +884,22 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -865,10 +884,22 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
} }
cropcap->defrect = cropcap->bounds; cropcap->defrect = cropcap->bounds;
return 0; 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;
streamtype = id->type;
case VIDIOC_S_CROP: { if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
struct v4l2_crop *crop = arg; 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 && if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
...@@ -885,10 +916,16 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -885,10 +916,16 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return -EINVAL; return -EINVAL;
} }
return -EINVAL; return -EINVAL;
} }
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;
case VIDIOC_G_CROP: { streamtype = id->type;
struct v4l2_crop *crop = arg;
if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
...@@ -899,9 +936,34 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -899,9 +936,34 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return 0; return 0;
} }
return -EINVAL; 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;
*fmt = formats[fmt->index];
fmt->type = type;
return 0;
}
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;
case VIDIOC_ENUM_FMT: {
static struct v4l2_fmtdesc formats[] = { static struct v4l2_fmtdesc formats[] = {
{ 0, 0, 0, { 0, 0, 0,
"HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
...@@ -912,44 +974,45 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -912,44 +974,45 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
} }
}; };
struct v4l2_fmtdesc *fmt = arg;
enum v4l2_buf_type type = fmt->type; enum v4l2_buf_type type = fmt->type;
switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL; return -EINVAL;
break;
default:
return -EINVAL;
}
if (fmt->index > 1) if (fmt->index > 1)
return -EINVAL; return -EINVAL;
*fmt = formats[fmt->index]; *fmt = formats[fmt->index];
fmt->type = type; fmt->type = type;
return 0; return 0;
} }
case VIDIOC_G_INPUT:{ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
*(int *)arg = itv->active_input; {
break; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
}
case VIDIOC_S_INPUT:{ *i = itv->active_input;
int inp = *(int *)arg;
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) if (inp < 0 || inp >= itv->nof_inputs)
return -EINVAL; return -EINVAL;
if (inp == itv->active_input) { if (inp == itv->active_input) {
IVTV_DEBUG_INFO("Input unchanged\n"); IVTV_DEBUG_INFO("Input unchanged\n");
break; return 0;
} }
if (atomic_read(&itv->capturing) > 0) { if (atomic_read(&itv->capturing) > 0) {
return -EBUSY; return -EBUSY;
} }
IVTV_DEBUG_INFO("Changing input from %d to %d\n", IVTV_DEBUG_INFO("Changing input from %d to %d\n",
itv->active_input, inp); itv->active_input, inp);
...@@ -964,18 +1027,25 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -964,18 +1027,25 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
ivtv_video_set_io(itv); ivtv_video_set_io(itv);
ivtv_audio_set_io(itv); ivtv_audio_set_io(itv);
ivtv_unmute(itv); ivtv_unmute(itv);
break;
}
case VIDIOC_G_OUTPUT:{ return 0;
}
static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
{
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return -EINVAL; return -EINVAL;
*(int *)arg = itv->active_output;
break;
}
case VIDIOC_S_OUTPUT:{ *i = itv->active_output;
int outp = *(int *)arg;
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; struct v4l2_routing route;
if (outp >= itv->card->nof_outputs) if (outp >= itv->card->nof_outputs)
...@@ -983,7 +1053,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -983,7 +1053,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (outp == itv->active_output) { if (outp == itv->active_output) {
IVTV_DEBUG_INFO("Output unchanged\n"); IVTV_DEBUG_INFO("Output unchanged\n");
break; return 0;
} }
IVTV_DEBUG_INFO("Changing output from %d to %d\n", IVTV_DEBUG_INFO("Changing output from %d to %d\n",
itv->active_output, outp); itv->active_output, outp);
...@@ -992,59 +1062,53 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -992,59 +1062,53 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
route.input = SAA7127_INPUT_TYPE_NORMAL; route.input = SAA7127_INPUT_TYPE_NORMAL;
route.output = itv->card->video_outputs[outp].video_output; route.output = itv->card->video_outputs[outp].video_output;
ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
break;
}
case VIDIOC_G_FREQUENCY:{
struct v4l2_frequency *vf = arg;
if (vf->tuner != 0) return 0;
return -EINVAL; }
ivtv_call_i2c_clients(itv, cmd, arg);
break;
}
case VIDIOC_S_FREQUENCY:{ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
struct v4l2_frequency vf = *(struct v4l2_frequency *)arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
if (vf.tuner != 0) if (vf->tuner != 0)
return -EINVAL; return -EINVAL;
ivtv_mute(itv); ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf);
IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency); return 0;
ivtv_call_i2c_clients(itv, cmd, &vf); }
ivtv_unmute(itv);
break;
}
case VIDIOC_ENUMSTD:{ int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
struct v4l2_standard *vs = arg; {
int idx = vs->index; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
if (idx < 0 || idx >= ARRAY_SIZE(enum_stds)) if (vf->tuner != 0)
return -EINVAL; return -EINVAL;
*vs = (enum_stds[idx].std & V4L2_STD_525_60) ? ivtv_mute(itv);
ivtv_std_60hz : ivtv_std_50hz; IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
vs->index = idx; ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf);
vs->id = enum_stds[idx].std; ivtv_unmute(itv);
strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name)); return 0;
break; }
}
case VIDIOC_G_STD:{ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
*(v4l2_std_id *) arg = itv->std; {
break; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
}
*std = itv->std;
return 0;
}
case VIDIOC_S_STD: { int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
v4l2_std_id std = *(v4l2_std_id *) arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct yuv_playback_info *yi = &itv->yuv_info;
if ((std & V4L2_STD_ALL) == 0) if ((*std & V4L2_STD_ALL) == 0)
return -EINVAL; return -EINVAL;
if (std == itv->std) if (*std == itv->std)
break; return 0;
if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
atomic_read(&itv->capturing) > 0 || atomic_read(&itv->capturing) > 0 ||
...@@ -1055,17 +1119,18 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1055,17 +1119,18 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return -EBUSY; return -EBUSY;
} }
itv->std = std; itv->std = *std;
itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0; itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
itv->params.width = 720; itv->params.width = 720;
itv->params.height = itv->is_50hz ? 576 : 480; itv->params.height = itv->is_50hz ? 576 : 480;
itv->vbi.count = itv->is_50hz ? 18 : 12; itv->vbi.count = itv->is_50hz ? 18 : 12;
itv->vbi.start[0] = itv->is_50hz ? 6 : 10; itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
itv->vbi.start[1] = itv->is_50hz ? 318 : 273; itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
if (itv->hw_flags & IVTV_HW_CX25840) {
if (itv->hw_flags & IVTV_HW_CX25840)
itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
}
IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
/* Tuner */ /* Tuner */
...@@ -1073,7 +1138,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1073,7 +1138,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
/* set display standard */ /* set display standard */
itv->std_out = std; itv->std_out = *std;
itv->is_out_60hz = itv->is_60hz; itv->is_out_60hz = itv->is_60hz;
itv->is_out_50hz = itv->is_50hz; itv->is_out_50hz = itv->is_50hz;
ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
...@@ -1089,21 +1154,25 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1089,21 +1154,25 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
yi->osd_full_h = itv->is_out_50hz ? 576 : 480; yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
} }
} }
break; return 0;
} }
case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */ static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
struct v4l2_tuner *vt = arg; {
struct ivtv_open_id *id = fh;
struct ivtv *itv = id->itv;
if (vt->index != 0) if (vt->index != 0)
return -EINVAL; return -EINVAL;
ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
break;
}
case VIDIOC_G_TUNER: { return 0;
struct v4l2_tuner *vt = arg; }
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) if (vt->index != 0)
return -EINVAL; return -EINVAL;
...@@ -1118,11 +1187,13 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1118,11 +1187,13 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
vt->type = V4L2_TUNER_ANALOG_TV; vt->type = V4L2_TUNER_ANALOG_TV;
} }
break;
}
case VIDIOC_G_SLICED_VBI_CAP: { return 0;
struct v4l2_sliced_vbi_cap *cap = arg; }
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 set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
int f, l; int f, l;
enum v4l2_buf_type type = cap->type; enum v4l2_buf_type type = cap->type;
...@@ -1132,11 +1203,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1132,11 +1203,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
for (f = 0; f < 2; f++) { for (f = 0; f < 2; f++) {
for (l = 0; l < 24; l++) { for (l = 0; l < 24; l++) {
if (valid_service_line(f, l, itv->is_50hz)) { if (valid_service_line(f, l, itv->is_50hz))
cap->service_lines[f][l] = set; cap->service_lines[f][l] = set;
} }
} }
}
return 0; return 0;
} }
if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
...@@ -1152,10 +1222,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1152,10 +1222,11 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
return 0; return 0;
} }
return -EINVAL; return -EINVAL;
} }
case VIDIOC_G_ENC_INDEX: { static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
struct v4l2_enc_idx *idx = arg; {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_enc_idx_entry *e = idx->entry; struct v4l2_enc_idx_entry *e = idx->entry;
int entries; int entries;
int i; int i;
...@@ -1173,40 +1244,37 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1173,40 +1244,37 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
} }
} }
itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
break; return 0;
} }
case VIDIOC_ENCODER_CMD: static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
case VIDIOC_TRY_ENCODER_CMD: { {
struct v4l2_encoder_cmd *enc = arg; struct ivtv_open_id *id = fh;
int try = cmd == VIDIOC_TRY_ENCODER_CMD; struct ivtv *itv = id->itv;
memset(&enc->raw, 0, sizeof(enc->raw)); memset(&enc->raw, 0, sizeof(enc->raw));
switch (enc->cmd) { switch (enc->cmd) {
case V4L2_ENC_CMD_START: case V4L2_ENC_CMD_START:
IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
enc->flags = 0; enc->flags = 0;
if (try)
return 0;
return ivtv_start_capture(id); return ivtv_start_capture(id);
case V4L2_ENC_CMD_STOP: case V4L2_ENC_CMD_STOP:
IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; 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); ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
return 0; return 0;
case V4L2_ENC_CMD_PAUSE: case V4L2_ENC_CMD_PAUSE:
IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
enc->flags = 0; enc->flags = 0;
if (try)
return 0;
if (!atomic_read(&itv->capturing)) if (!atomic_read(&itv->capturing))
return -EPERM; return -EPERM;
if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
return 0; return 0;
ivtv_mute(itv); ivtv_mute(itv);
ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
break; break;
...@@ -1214,12 +1282,13 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1214,12 +1282,13 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
case V4L2_ENC_CMD_RESUME: case V4L2_ENC_CMD_RESUME:
IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
enc->flags = 0; enc->flags = 0;
if (try)
return 0;
if (!atomic_read(&itv->capturing)) if (!atomic_read(&itv->capturing))
return -EPERM; return -EPERM;
if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
return 0; return 0;
ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
ivtv_unmute(itv); ivtv_unmute(itv);
break; break;
...@@ -1227,11 +1296,48 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1227,11 +1296,48 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
return -EINVAL; return -EINVAL;
} }
break;
return 0;
}
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;
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;
return 0;
case V4L2_ENC_CMD_STOP:
IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
return 0;
case V4L2_ENC_CMD_PAUSE:
IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
enc->flags = 0;
return 0;
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;
} }
}
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;
case VIDIOC_G_FBUF: {
struct v4l2_framebuffer *fb = arg;
int pixfmt; int pixfmt;
static u32 pixel_format[16] = { static u32 pixel_format[16] = {
V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
...@@ -1253,30 +1359,40 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1253,30 +1359,40 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
}; };
memset(fb, 0, sizeof(*fb)); memset(fb, 0, sizeof(*fb));
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
return -EINVAL; return -EINVAL;
fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
V4L2_FBUF_CAP_GLOBAL_ALPHA; V4L2_FBUF_CAP_GLOBAL_ALPHA;
ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
data[0] |= (read_reg(0x2a00) >> 7) & 0x40; data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
pixfmt = (data[0] >> 3) & 0xf; pixfmt = (data[0] >> 3) & 0xf;
fb->fmt.pixelformat = pixel_format[pixfmt]; fb->fmt.pixelformat = pixel_format[pixfmt];
fb->fmt.width = itv->osd_rect.width; fb->fmt.width = itv->osd_rect.width;
fb->fmt.height = itv->osd_rect.height; fb->fmt.height = itv->osd_rect.height;
fb->base = (void *)itv->osd_video_pbase; fb->base = (void *)itv->osd_video_pbase;
if (itv->osd_chroma_key_state) if (itv->osd_chroma_key_state)
fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
if (itv->osd_global_alpha_state) if (itv->osd_global_alpha_state)
fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
pixfmt &= 7; pixfmt &= 7;
/* no local alpha for RGB565 or unknown formats */ /* no local alpha for RGB565 or unknown formats */
if (pixfmt == 1 || pixfmt > 4) if (pixfmt == 1 || pixfmt > 4)
break; return 0;
/* 16-bit formats have inverted local alpha */ /* 16-bit formats have inverted local alpha */
if (pixfmt == 2 || pixfmt == 3) if (pixfmt == 2 || pixfmt == 3)
fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
else else
fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
if (itv->osd_local_alpha_state) { if (itv->osd_local_alpha_state) {
/* 16-bit formats have inverted local alpha */ /* 16-bit formats have inverted local alpha */
if (pixfmt == 2 || pixfmt == 3) if (pixfmt == 2 || pixfmt == 3)
...@@ -1286,34 +1402,47 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1286,34 +1402,47 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
} }
if (yi->track_osd) if (yi->track_osd)
fb->flags |= V4L2_FBUF_FLAG_OVERLAY; fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
break;
}
case VIDIOC_S_FBUF: { return 0;
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)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
return -EINVAL; return -EINVAL;
itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
itv->osd_local_alpha_state = itv->osd_local_alpha_state =
(fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; (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; itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
ivtv_set_osd_alpha(itv); ivtv_set_osd_alpha(itv);
yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
break;
}
case VIDIOC_OVERLAY: { return 0;
int *on = arg; }
static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
{
struct ivtv_open_id *id = fh;
struct ivtv *itv = id->itv;
if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
return -EINVAL; return -EINVAL;
ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
break;
}
case VIDIOC_LOG_STATUS: ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
{
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; int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
struct v4l2_input vidin; struct v4l2_input vidin;
struct v4l2_audio audin; struct v4l2_audio audin;
...@@ -1404,14 +1533,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void ...@@ -1404,14 +1533,10 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
(s->buffers - s->q_free.buffers) * 100 / s->buffers, (s->buffers - s->q_free.buffers) * 100 / s->buffers,
(s->buffers * s->buf_size) / 1024, 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("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("================== END STATUS CARD #%d ==================\n", itv->num);
break;
}
default:
return -EINVAL;
}
return 0; return 0;
} }
...@@ -1607,121 +1732,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) ...@@ -1607,121 +1732,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
return 0; return 0;
} }
static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
unsigned int cmd, void *arg)
{ {
struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct ivtv *itv = id->itv;
int ret;
/* check priority */
switch (cmd) { switch (cmd) {
case VIDIOC_S_CTRL: case VIDIOC_INT_S_AUDIO_ROUTING: {
case VIDIOC_S_STD: struct v4l2_routing *route = arg;
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;
}
switch (cmd) { ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
case VIDIOC_DBG_G_REGISTER: break;
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_G_PRIORITY: case VIDIOC_INT_RESET: {
case VIDIOC_S_PRIORITY: u32 val = *(u32 *)arg;
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);
case VIDIOC_QUERYMENU: if ((val == 0 && itv->options.newi2c) || (val & 0x01))
case VIDIOC_QUERYCTRL: ivtv_reset_ir_gpio(itv);
case VIDIOC_S_CTRL: if (val & 0x02)
case VIDIOC_G_CTRL: itv->video_dec_func(itv, cmd, NULL);
case VIDIOC_S_EXT_CTRLS: break;
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 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);
case 0x00005401: /* Handle isatty() calls */
return -EINVAL;
default: default:
return v4l_compat_translate_ioctl(inode, filp, cmd, arg, return -EINVAL;
ivtv_v4l2_do_ioctl);
} }
return 0; return 0;
} }
...@@ -1729,7 +1763,10 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, ...@@ -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, static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg) 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) { switch (cmd) {
case VIDEO_SELECT_SOURCE: case VIDEO_SELECT_SOURCE:
IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
...@@ -1758,10 +1795,49 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f ...@@ -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); ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
return 0; 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: default:
break; 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, 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, ...@@ -1776,3 +1852,70 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
mutex_unlock(&itv->serialize_lock); mutex_unlock(&itv->serialize_lock);
return res; 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;
}
...@@ -24,10 +24,13 @@ ...@@ -24,10 +24,13 @@
u16 ivtv_service2vbi(int type); u16 ivtv_service2vbi(int type);
void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); 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); 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); void ivtv_set_osd_alpha(struct ivtv *itv);
int ivtv_set_speed(struct ivtv *itv, int speed); 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 #endif
...@@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) ...@@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
s->v4l2dev->dev = &itv->dev->dev; s->v4l2dev->dev = &itv->dev->dev;
s->v4l2dev->fops = ivtv_stream_info[type].fops; s->v4l2dev->fops = ivtv_stream_info[type].fops;
s->v4l2dev->release = video_device_release; s->v4l2dev->release = video_device_release;
s->v4l2dev->tvnorms = V4L2_STD_ALL;
ivtv_set_funcs(s->v4l2dev);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment