Commit 1a708ea0 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] saa7164: convert to the control framework

Convert this driver to the control framework. Note that the VBI device
nodes have no controls as there is nothing to control.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 28c50292
This diff is collapsed.
......@@ -31,10 +31,6 @@ static struct saa7164_tvnorm saa7164_tvnorms[] = {
}
};
static const u32 saa7164_v4l2_ctrls[] = {
0
};
/* Take the encoder configuration from the port struct and
* flush it to the hardware.
*/
......@@ -368,286 +364,6 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return 0;
}
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctl)
{
struct saa7164_vbi_fh *fh = file->private_data;
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
ctl->id, ctl->value);
switch (ctl->id) {
case V4L2_CID_BRIGHTNESS:
ctl->value = port->ctl_brightness;
break;
case V4L2_CID_CONTRAST:
ctl->value = port->ctl_contrast;
break;
case V4L2_CID_SATURATION:
ctl->value = port->ctl_saturation;
break;
case V4L2_CID_HUE:
ctl->value = port->ctl_hue;
break;
case V4L2_CID_SHARPNESS:
ctl->value = port->ctl_sharpness;
break;
case V4L2_CID_AUDIO_VOLUME:
ctl->value = port->ctl_volume;
break;
default:
return -EINVAL;
}
return 0;
}
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctl)
{
struct saa7164_vbi_fh *fh = file->private_data;
struct saa7164_port *port = fh->port;
struct saa7164_dev *dev = port->dev;
int ret = 0;
dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
ctl->id, ctl->value);
switch (ctl->id) {
case V4L2_CID_BRIGHTNESS:
if ((ctl->value >= 0) && (ctl->value <= 255)) {
port->ctl_brightness = ctl->value;
saa7164_api_set_usercontrol(port,
PU_BRIGHTNESS_CONTROL);
} else
ret = -EINVAL;
break;
case V4L2_CID_CONTRAST:
if ((ctl->value >= 0) && (ctl->value <= 255)) {
port->ctl_contrast = ctl->value;
saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
} else
ret = -EINVAL;
break;
case V4L2_CID_SATURATION:
if ((ctl->value >= 0) && (ctl->value <= 255)) {
port->ctl_saturation = ctl->value;
saa7164_api_set_usercontrol(port,
PU_SATURATION_CONTROL);
} else
ret = -EINVAL;
break;
case V4L2_CID_HUE:
if ((ctl->value >= 0) && (ctl->value <= 255)) {
port->ctl_hue = ctl->value;
saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
} else
ret = -EINVAL;
break;
case V4L2_CID_SHARPNESS:
if ((ctl->value >= 0) && (ctl->value <= 255)) {
port->ctl_sharpness = ctl->value;
saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
} else
ret = -EINVAL;
break;
case V4L2_CID_AUDIO_VOLUME:
if ((ctl->value >= -83) && (ctl->value <= 24)) {
port->ctl_volume = ctl->value;
saa7164_api_set_audio_volume(port, port->ctl_volume);
} else
ret = -EINVAL;
break;
default:
ret = -EINVAL;
}
return ret;
}
static int saa7164_get_ctrl(struct saa7164_port *port,
struct v4l2_ext_control *ctrl)
{
struct saa7164_vbi_params *params = &port->vbi_params;
switch (ctrl->id) {
case V4L2_CID_MPEG_STREAM_TYPE:
ctrl->value = params->stream_type;
break;
case V4L2_CID_MPEG_AUDIO_MUTE:
ctrl->value = params->ctl_mute;
break;
case V4L2_CID_MPEG_VIDEO_ASPECT:
ctrl->value = params->ctl_aspect;
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
ctrl->value = params->refdist;
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
ctrl->value = params->gop_size;
break;
default:
return -EINVAL;
}
return 0;
}
static int vidioc_g_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
struct saa7164_vbi_fh *fh = file->private_data;
struct saa7164_port *port = fh->port;
int i, err = 0;
if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
err = saa7164_get_ctrl(port, ctrl);
if (err) {
ctrls->error_idx = i;
break;
}
}
return err;
}
return -EINVAL;
}
static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
{
int ret = -EINVAL;
switch (ctrl->id) {
case V4L2_CID_MPEG_STREAM_TYPE:
if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
(ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
ret = 0;
break;
case V4L2_CID_MPEG_AUDIO_MUTE:
if ((ctrl->value >= 0) &&
(ctrl->value <= 1))
ret = 0;
break;
case V4L2_CID_MPEG_VIDEO_ASPECT:
if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
(ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
ret = 0;
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
if ((ctrl->value >= 0) &&
(ctrl->value <= 255))
ret = 0;
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
if ((ctrl->value >= 1) &&
(ctrl->value <= 3))
ret = 0;
break;
default:
ret = -EINVAL;
}
return ret;
}
static int vidioc_try_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
int i, err = 0;
if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
err = saa7164_try_ctrl(ctrl, 0);
if (err) {
ctrls->error_idx = i;
break;
}
}
return err;
}
return -EINVAL;
}
static int saa7164_set_ctrl(struct saa7164_port *port,
struct v4l2_ext_control *ctrl)
{
struct saa7164_vbi_params *params = &port->vbi_params;
int ret = 0;
switch (ctrl->id) {
case V4L2_CID_MPEG_STREAM_TYPE:
params->stream_type = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_MUTE:
params->ctl_mute = ctrl->value;
ret = saa7164_api_audio_mute(port, params->ctl_mute);
if (ret != SAA_OK) {
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
ret);
ret = -EIO;
}
break;
case V4L2_CID_MPEG_VIDEO_ASPECT:
params->ctl_aspect = ctrl->value;
ret = saa7164_api_set_aspect_ratio(port);
if (ret != SAA_OK) {
printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
ret);
ret = -EIO;
}
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
params->refdist = ctrl->value;
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
params->gop_size = ctrl->value;
break;
default:
return -EINVAL;
}
/* TODO: Update the hardware */
return ret;
}
static int vidioc_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *ctrls)
{
struct saa7164_vbi_fh *fh = file->private_data;
struct saa7164_port *port = fh->port;
int i, err = 0;
if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
for (i = 0; i < ctrls->count; i++) {
struct v4l2_ext_control *ctrl = ctrls->controls + i;
err = saa7164_try_ctrl(ctrl, 0);
if (err) {
ctrls->error_idx = i;
break;
}
err = saa7164_set_ctrl(port, ctrl);
if (err) {
ctrls->error_idx = i;
break;
}
}
return err;
}
return -EINVAL;
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
......@@ -741,75 +457,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
static int fill_queryctrl(struct saa7164_vbi_params *params,
struct v4l2_queryctrl *c)
{
switch (c->id) {
case V4L2_CID_BRIGHTNESS:
return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
case V4L2_CID_CONTRAST:
return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
case V4L2_CID_SATURATION:
return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
case V4L2_CID_HUE:
return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
case V4L2_CID_SHARPNESS:
return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
case V4L2_CID_MPEG_AUDIO_MUTE:
return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
case V4L2_CID_AUDIO_VOLUME:
return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
case V4L2_CID_MPEG_STREAM_TYPE:
return v4l2_ctrl_query_fill(c,
V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
case V4L2_CID_MPEG_VIDEO_ASPECT:
return v4l2_ctrl_query_fill(c,
V4L2_MPEG_VIDEO_ASPECT_1x1,
V4L2_MPEG_VIDEO_ASPECT_221x100,
1, V4L2_MPEG_VIDEO_ASPECT_4x3);
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
return v4l2_ctrl_query_fill(c,
1, 3, 1, 1);
default:
return -EINVAL;
}
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
struct saa7164_vbi_fh *fh = priv;
struct saa7164_port *port = fh->port;
int i, next;
u32 id = c->id;
memset(c, 0, sizeof(*c));
next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
if (next) {
if (c->id < saa7164_v4l2_ctrls[i])
c->id = saa7164_v4l2_ctrls[i];
else
continue;
}
if (c->id == saa7164_v4l2_ctrls[i])
return fill_queryctrl(&port->vbi_params, c);
if (c->id < saa7164_v4l2_ctrls[i])
break;
}
return -EINVAL;
}
static int saa7164_vbi_stop_port(struct saa7164_port *port)
{
struct saa7164_dev *dev = port->dev;
......@@ -1255,17 +902,11 @@ static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
.vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
.vidioc_queryctrl = vidioc_queryctrl,
.vidioc_g_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_try_fmt_vbi_cap = saa7164_vbi_fmt,
.vidioc_s_fmt_vbi_cap = saa7164_vbi_fmt,
......
......@@ -64,6 +64,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include "saa7164-reg.h"
#include "saa7164-types.h"
......@@ -381,6 +382,7 @@ struct saa7164_port {
/* Encoder */
/* Defaults established in saa7164-encoder.c */
struct saa7164_tvnorm encodernorm;
struct v4l2_ctrl_handler ctrl_handler;
v4l2_std_id std;
u32 height;
u32 width;
......
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