diff options
author | Michael Krufky <mkrufky@linuxtv.org> | 2006-06-26 22:42:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-30 14:59:27 -0400 |
commit | 38a2713ada91d5e7e4c0a1a0b12e45e2ec7079c3 (patch) | |
tree | e3d0a2fd5b3b95f75b3e09de9dc54d2edb5e1533 /drivers | |
parent | 598736c55622f7ea65b98f93c825ff95c433877c (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 43 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 59 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 2 |
3 files changed, 91 insertions, 13 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 4ff81582ec56..349632b48e93 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -686,6 +686,39 @@ static struct videobuf_queue_ops blackbird_qops = { | |||
686 | 686 | ||
687 | /* ------------------------------------------------------------------ */ | 687 | /* ------------------------------------------------------------------ */ |
688 | 688 | ||
689 | static const u32 *ctrl_classes[] = { | ||
690 | cx88_user_ctrls, | ||
691 | cx2341x_mpeg_ctrls, | ||
692 | NULL | ||
693 | }; | ||
694 | |||
695 | static int blackbird_queryctrl(struct cx8802_dev *dev, struct v4l2_queryctrl *qctrl) | ||
696 | { | ||
697 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | ||
698 | if (qctrl->id == 0) | ||
699 | return -EINVAL; | ||
700 | |||
701 | /* Standard V4L2 controls */ | ||
702 | if (cx8800_ctrl_query(qctrl) == 0) | ||
703 | return 0; | ||
704 | |||
705 | /* MPEG V4L2 controls */ | ||
706 | if (cx2341x_ctrl_query(&dev->params, qctrl)) | ||
707 | qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static int blackbird_querymenu(struct cx8802_dev *dev, struct v4l2_querymenu *qmenu) | ||
712 | { | ||
713 | struct v4l2_queryctrl qctrl; | ||
714 | |||
715 | qctrl.id = qmenu->id; | ||
716 | blackbird_queryctrl(dev, &qctrl); | ||
717 | return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); | ||
718 | } | ||
719 | |||
720 | /* ------------------------------------------------------------------ */ | ||
721 | |||
689 | static int mpeg_do_ioctl(struct inode *inode, struct file *file, | 722 | static int mpeg_do_ioctl(struct inode *inode, struct file *file, |
690 | unsigned int cmd, void *arg) | 723 | unsigned int cmd, void *arg) |
691 | { | 724 | { |
@@ -866,6 +899,16 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
866 | core->name); | 899 | core->name); |
867 | return 0; | 900 | return 0; |
868 | } | 901 | } |
902 | case VIDIOC_QUERYMENU: | ||
903 | return blackbird_querymenu(dev, arg); | ||
904 | case VIDIOC_QUERYCTRL: | ||
905 | { | ||
906 | struct v4l2_queryctrl *c = arg; | ||
907 | |||
908 | if (blackbird_queryctrl(dev, c) == 0) | ||
909 | return 0; | ||
910 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); | ||
911 | } | ||
869 | 912 | ||
870 | default: | 913 | default: |
871 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); | 914 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 8d5cf474b68e..fe147e3aaa70 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -327,6 +327,51 @@ static struct cx88_ctrl cx8800_ctls[] = { | |||
327 | }; | 327 | }; |
328 | static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); | 328 | static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls); |
329 | 329 | ||
330 | const u32 cx88_user_ctrls[] = { | ||
331 | V4L2_CID_USER_CLASS, | ||
332 | V4L2_CID_BRIGHTNESS, | ||
333 | V4L2_CID_CONTRAST, | ||
334 | V4L2_CID_SATURATION, | ||
335 | V4L2_CID_HUE, | ||
336 | V4L2_CID_AUDIO_VOLUME, | ||
337 | V4L2_CID_AUDIO_BALANCE, | ||
338 | V4L2_CID_AUDIO_MUTE, | ||
339 | 0 | ||
340 | }; | ||
341 | EXPORT_SYMBOL(cx88_user_ctrls); | ||
342 | |||
343 | static const u32 *ctrl_classes[] = { | ||
344 | cx88_user_ctrls, | ||
345 | NULL | ||
346 | }; | ||
347 | |||
348 | int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl) | ||
349 | { | ||
350 | int i; | ||
351 | |||
352 | if (qctrl->id < V4L2_CID_BASE || | ||
353 | qctrl->id >= V4L2_CID_LASTP1) | ||
354 | return -EINVAL; | ||
355 | for (i = 0; i < CX8800_CTLS; i++) | ||
356 | if (cx8800_ctls[i].v.id == qctrl->id) | ||
357 | break; | ||
358 | if (i == CX8800_CTLS) { | ||
359 | *qctrl = no_ctl; | ||
360 | return 0; | ||
361 | } | ||
362 | *qctrl = cx8800_ctls[i].v; | ||
363 | return 0; | ||
364 | } | ||
365 | EXPORT_SYMBOL(cx8800_ctrl_query); | ||
366 | |||
367 | static int cx88_queryctrl(struct v4l2_queryctrl *qctrl) | ||
368 | { | ||
369 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | ||
370 | if (qctrl->id == 0) | ||
371 | return -EINVAL; | ||
372 | return cx8800_ctrl_query(qctrl); | ||
373 | } | ||
374 | |||
330 | /* ------------------------------------------------------------------- */ | 375 | /* ------------------------------------------------------------------- */ |
331 | /* resource management */ | 376 | /* resource management */ |
332 | 377 | ||
@@ -1362,20 +1407,8 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
1362 | case VIDIOC_QUERYCTRL: | 1407 | case VIDIOC_QUERYCTRL: |
1363 | { | 1408 | { |
1364 | struct v4l2_queryctrl *c = arg; | 1409 | struct v4l2_queryctrl *c = arg; |
1365 | int i; | ||
1366 | 1410 | ||
1367 | if (c->id < V4L2_CID_BASE || | 1411 | return cx88_queryctrl(c); |
1368 | c->id >= V4L2_CID_LASTP1) | ||
1369 | return -EINVAL; | ||
1370 | for (i = 0; i < CX8800_CTLS; i++) | ||
1371 | if (cx8800_ctls[i].v.id == c->id) | ||
1372 | break; | ||
1373 | if (i == CX8800_CTLS) { | ||
1374 | *c = no_ctl; | ||
1375 | return 0; | ||
1376 | } | ||
1377 | *c = cx8800_ctls[i].v; | ||
1378 | return 0; | ||
1379 | } | 1412 | } |
1380 | case VIDIOC_G_CTRL: | 1413 | case VIDIOC_G_CTRL: |
1381 | return get_control(core,arg); | 1414 | return get_control(core,arg); |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 9a9a0fc7a41a..336e823c7588 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -590,6 +590,8 @@ int cx8802_resume_common(struct pci_dev *pci_dev); | |||
590 | extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | 590 | extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, |
591 | struct cx88_core *core, unsigned int cmd, | 591 | struct cx88_core *core, unsigned int cmd, |
592 | void *arg, v4l2_kioctl driver_ioctl); | 592 | void *arg, v4l2_kioctl driver_ioctl); |
593 | extern const u32 cx88_user_ctrls[]; | ||
594 | extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl); | ||
593 | 595 | ||
594 | /* | 596 | /* |
595 | * Local variables: | 597 | * Local variables: |