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 = { ...@@ -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, static int mpeg_do_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *arg) unsigned int cmd, void *arg)
{ {
...@@ -866,6 +899,16 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, ...@@ -866,6 +899,16 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
core->name); core->name);
return 0; 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: default:
return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl);
......
...@@ -327,6 +327,51 @@ static struct cx88_ctrl cx8800_ctls[] = { ...@@ -327,6 +327,51 @@ static struct cx88_ctrl cx8800_ctls[] = {
}; };
static const int CX8800_CTLS = ARRAY_SIZE(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 */ /* resource management */
...@@ -1362,20 +1407,8 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, ...@@ -1362,20 +1407,8 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
case VIDIOC_QUERYCTRL: case VIDIOC_QUERYCTRL:
{ {
struct v4l2_queryctrl *c = arg; struct v4l2_queryctrl *c = arg;
int i;
if (c->id < V4L2_CID_BASE || return cx88_queryctrl(c);
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;
} }
case VIDIOC_G_CTRL: case VIDIOC_G_CTRL:
return get_control(core,arg); return get_control(core,arg);
......
...@@ -590,6 +590,8 @@ int cx8802_resume_common(struct pci_dev *pci_dev); ...@@ -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, extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
struct cx88_core *core, unsigned int cmd, struct cx88_core *core, unsigned int cmd,
void *arg, v4l2_kioctl driver_ioctl); void *arg, v4l2_kioctl driver_ioctl);
extern const u32 cx88_user_ctrls[];
extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl);
/* /*
* Local variables: * 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