Commit 38a2713a authored by Michael Krufky's avatar Michael Krufky Committed by Mauro Carvalho Chehab

V4L/DVB (4264): Cx88-blackbird: implement VIDIOC_QUERYCTRL and VIDIOC_QUERYMENU

This patch implements the newer v4l2 control features to make the
standard user controls and mpeg encoder controls of cx88-blackbird
video encoder boards available to userspace.
Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 598736c5
......@@ -686,6 +686,39 @@ static struct videobuf_queue_ops blackbird_qops = {
/* ------------------------------------------------------------------ */
static const u32 *ctrl_classes[] = {
cx88_user_ctrls,
cx2341x_mpeg_ctrls,
NULL
};
static int blackbird_queryctrl(struct cx8802_dev *dev, struct v4l2_queryctrl *qctrl)
{
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
/* Standard V4L2 controls */
if (cx8800_ctrl_query(qctrl) == 0)
return 0;
/* MPEG V4L2 controls */
if (cx2341x_ctrl_query(&dev->params, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
}
static int blackbird_querymenu(struct cx8802_dev *dev, struct v4l2_querymenu *qmenu)
{
struct v4l2_queryctrl qctrl;
qctrl.id = qmenu->id;
blackbird_queryctrl(dev, &qctrl);
return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
}
/* ------------------------------------------------------------------ */
static int mpeg_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg)
{
......@@ -866,6 +899,16 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
core->name);
return 0;
}
case VIDIOC_QUERYMENU:
return blackbird_querymenu(dev, arg);
case VIDIOC_QUERYCTRL:
{
struct v4l2_queryctrl *c = arg;
if (blackbird_queryctrl(dev, c) == 0)
return 0;
return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl);
}
default:
return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl);
......
......@@ -327,6 +327,51 @@ static struct cx88_ctrl cx8800_ctls[] = {
};
static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
const u32 cx88_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
V4L2_CID_CONTRAST,
V4L2_CID_SATURATION,
V4L2_CID_HUE,
V4L2_CID_AUDIO_VOLUME,
V4L2_CID_AUDIO_BALANCE,
V4L2_CID_AUDIO_MUTE,
0
};
EXPORT_SYMBOL(cx88_user_ctrls);
static const u32 *ctrl_classes[] = {
cx88_user_ctrls,
NULL
};
int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl)
{
int i;
if (qctrl->id < V4L2_CID_BASE ||
qctrl->id >= V4L2_CID_LASTP1)
return -EINVAL;
for (i = 0; i < CX8800_CTLS; i++)
if (cx8800_ctls[i].v.id == qctrl->id)
break;
if (i == CX8800_CTLS) {
*qctrl = no_ctl;
return 0;
}
*qctrl = cx8800_ctls[i].v;
return 0;
}
EXPORT_SYMBOL(cx8800_ctrl_query);
static int cx88_queryctrl(struct v4l2_queryctrl *qctrl)
{
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
return cx8800_ctrl_query(qctrl);
}
/* ------------------------------------------------------------------- */
/* resource management */
......@@ -1362,20 +1407,8 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
case VIDIOC_QUERYCTRL:
{
struct v4l2_queryctrl *c = arg;
int i;
if (c->id < V4L2_CID_BASE ||
c->id >= V4L2_CID_LASTP1)
return -EINVAL;
for (i = 0; i < CX8800_CTLS; i++)
if (cx8800_ctls[i].v.id == c->id)
break;
if (i == CX8800_CTLS) {
*c = no_ctl;
return 0;
}
*c = cx8800_ctls[i].v;
return 0;
return cx88_queryctrl(c);
}
case VIDIOC_G_CTRL:
return get_control(core,arg);
......
......@@ -590,6 +590,8 @@ int cx8802_resume_common(struct pci_dev *pci_dev);
extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
struct cx88_core *core, unsigned int cmd,
void *arg, v4l2_kioctl driver_ioctl);
extern const u32 cx88_user_ctrls[];
extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl);
/*
* Local variables:
......
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