Browse Source

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>
Michael Krufky 19 years ago
parent
commit
38a2713ada

+ 43 - 0
drivers/media/video/cx88/cx88-blackbird.c

@@ -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);

+ 46 - 13
drivers/media/video/cx88/cx88-video.c

@@ -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);

+ 2 - 0
drivers/media/video/cx88/cx88.h

@@ -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: