summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-controls.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-controls.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c225
1 files changed, 112 insertions, 113 deletions
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index c7e449f6397..48e103be718 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -47,12 +47,12 @@ static const u32 *ctrl_classes[] = {
NULL
};
-static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
+
+int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
const char *name;
- IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
-
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
@@ -87,21 +87,35 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
return 0;
}
-static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu)
+int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_queryctrl qctrl;
qctrl.id = qmenu->id;
- ivtv_queryctrl(itv, &qctrl);
- return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
+ ivtv_queryctrl(file, fh, &qctrl);
+ return v4l2_ctrl_query_menu(qmenu, &qctrl,
+ cx2341x_ctrl_get_menu(&itv->params, qmenu->id));
}
-static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
+static int ivtv_try_ctrl(struct file *file, void *fh,
+ struct v4l2_ext_control *vctrl)
{
- s32 v = vctrl->value;
-
- IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
+ struct v4l2_queryctrl qctrl;
+ const char **menu_items = NULL;
+ int err;
+
+ qctrl.id = vctrl->id;
+ err = ivtv_queryctrl(file, fh, &qctrl);
+ if (err)
+ return err;
+ if (qctrl.type == V4L2_CTRL_TYPE_MENU)
+ menu_items = v4l2_ctrl_get_menu(qctrl.id);
+ return v4l2_ctrl_check(vctrl, &qctrl, menu_items);
+}
+static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
+{
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
@@ -119,7 +133,7 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
default:
- IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+ IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
@@ -127,8 +141,6 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
{
- IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
-
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
@@ -145,7 +157,7 @@ static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_LOUDNESS:
return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
default:
- IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id);
+ IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
@@ -191,119 +203,106 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
return 0;
}
-int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg)
+int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_control ctrl;
- switch (cmd) {
- case VIDIOC_QUERYMENU:
- IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
- return ivtv_querymenu(itv, arg);
-
- case VIDIOC_QUERYCTRL:
- return ivtv_queryctrl(itv, arg);
-
- case VIDIOC_S_CTRL:
- return ivtv_s_ctrl(itv, arg);
-
- case VIDIOC_G_CTRL:
- return ivtv_g_ctrl(itv, arg);
-
- case VIDIOC_S_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
-
- if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
- int i;
- int err = 0;
-
- for (i = 0; i < c->count; i++) {
- ctrl.id = c->controls[i].id;
- ctrl.value = c->controls[i].value;
- err = ivtv_s_ctrl(itv, &ctrl);
- c->controls[i].value = ctrl.value;
- if (err) {
- c->error_idx = i;
- break;
- }
+ 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_S_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
- static u32 freqs[3] = { 44100, 48000, 32000 };
- struct cx2341x_mpeg_params p = itv->params;
- int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd);
- unsigned idx;
-
- if (err)
- return err;
-
- if (p.video_encoding != itv->params.video_encoding) {
- int is_mpeg1 = p.video_encoding ==
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
- struct v4l2_format fmt;
-
- /* fix videodecoder resolution */
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
- fmt.fmt.pix.height = itv->params.height;
- itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
- }
- err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
- if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) {
- err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
+ return err;
+ }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+ return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS);
+ return -EINVAL;
+}
+
+int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
+ struct v4l2_control ctrl;
+
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
+
+ for (i = 0; i < c->count; i++) {
+ ctrl.id = c->controls[i].id;
+ ctrl.value = c->controls[i].value;
+ err = ivtv_s_ctrl(itv, &ctrl);
+ c->controls[i].value = ctrl.value;
+ if (err) {
+ c->error_idx = i;
+ break;
}
- itv->params = p;
- itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
- idx = p.audio_properties & 0x03;
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (idx < sizeof(freqs))
- ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
- return err;
}
- return -EINVAL;
+ return err;
}
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ static u32 freqs[3] = { 44100, 48000, 32000 };
+ struct cx2341x_mpeg_params p = itv->params;
+ int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS);
+ unsigned idx;
- 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;
- }
- }
+ if (err)
return err;
+
+ if (p.video_encoding != itv->params.video_encoding) {
+ int is_mpeg1 = p.video_encoding ==
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+ struct v4l2_format fmt;
+
+ /* fix videodecoder resolution */
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
+ fmt.fmt.pix.height = itv->params.height;
+ itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
}
- 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;
+ err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
+ if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
+ err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
+ itv->params = p;
+ itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
+ idx = p.audio_properties & 0x03;
+ /* The audio clock of the digitizer must match the codec sample
+ rate otherwise you get some very strange effects. */
+ if (idx < sizeof(freqs))
+ ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
+ return err;
}
+ return -EINVAL;
+}
- case VIDIOC_TRY_EXT_CTRLS:
- {
- struct v4l2_ext_controls *c = arg;
+int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
+{
+ struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
- IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
- if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
- return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd);
- return -EINVAL;
- }
+ if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ int i;
+ int err = 0;
- default:
- return -EINVAL;
+ for (i = 0; i < c->count; i++) {
+ err = ivtv_try_ctrl(file, fh, &c->controls[i]);
+ if (err) {
+ c->error_idx = i;
+ break;
+ }
+ }
+ return err;
}
- return 0;
+ if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
+ return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS);
+ return -EINVAL;
}