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: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
598736c556
commit
38a2713ada
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue