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:
committed by
Mauro Carvalho Chehab
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,
|
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,
|
|||||||
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[] = {
|
|||||||
};
|
};
|
||||||
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,
|
|||||||
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);
|
|||||||
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:
|
||||||
|
Reference in New Issue
Block a user