diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-03-12 17:47:03 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-25 07:44:08 -0400 |
commit | 941604977c00ebeb6324348ece84d2140b190754 (patch) | |
tree | 31e3dcbb79a41c5df27580b03b2f83423c3fb055 | |
parent | 016afda4fb298aa2e5515048fcba0271ad6f7320 (diff) |
[media] solo6x10: add support for prio and control event handling
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/staging/media/solo6x10/v4l2-enc.c | 19 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/v4l2.c | 17 |
2 files changed, 33 insertions, 3 deletions
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c index 5b2fdfbaef65..7cf3e7b8725f 100644 --- a/drivers/staging/media/solo6x10/v4l2-enc.c +++ b/drivers/staging/media/solo6x10/v4l2-enc.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <media/v4l2-ioctl.h> | 30 | #include <media/v4l2-ioctl.h> |
31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
32 | #include <media/v4l2-event.h> | ||
32 | #include <media/videobuf-dma-sg.h> | 33 | #include <media/videobuf-dma-sg.h> |
33 | 34 | ||
34 | #include "solo6x10.h" | 35 | #include "solo6x10.h" |
@@ -46,7 +47,8 @@ enum solo_enc_types { | |||
46 | }; | 47 | }; |
47 | 48 | ||
48 | struct solo_enc_fh { | 49 | struct solo_enc_fh { |
49 | struct solo_enc_dev *enc; | 50 | struct v4l2_fh fh; |
51 | struct solo_enc_dev *enc; | ||
50 | u32 fmt; | 52 | u32 fmt; |
51 | u8 enc_on; | 53 | u8 enc_on; |
52 | enum solo_enc_types type; | 54 | enum solo_enc_types type; |
@@ -823,7 +825,11 @@ static unsigned int solo_enc_poll(struct file *file, | |||
823 | struct poll_table_struct *wait) | 825 | struct poll_table_struct *wait) |
824 | { | 826 | { |
825 | struct solo_enc_fh *fh = file->private_data; | 827 | struct solo_enc_fh *fh = file->private_data; |
828 | unsigned long req_events = poll_requested_events(wait); | ||
829 | unsigned res = v4l2_ctrl_poll(file, wait); | ||
826 | 830 | ||
831 | if (!(req_events & (POLLIN | POLLRDNORM))) | ||
832 | return res; | ||
827 | return videobuf_poll_stream(file, &fh->vidq, wait); | 833 | return videobuf_poll_stream(file, &fh->vidq, wait); |
828 | } | 834 | } |
829 | 835 | ||
@@ -892,6 +898,7 @@ static int solo_enc_open(struct file *file) | |||
892 | return -ENOMEM; | 898 | return -ENOMEM; |
893 | } | 899 | } |
894 | 900 | ||
901 | v4l2_fh_init(&fh->fh, video_devdata(file)); | ||
895 | fh->enc = solo_enc; | 902 | fh->enc = solo_enc; |
896 | spin_lock_init(&fh->av_lock); | 903 | spin_lock_init(&fh->av_lock); |
897 | file->private_data = fh; | 904 | file->private_data = fh; |
@@ -906,7 +913,7 @@ static int solo_enc_open(struct file *file) | |||
906 | V4L2_FIELD_INTERLACED, | 913 | V4L2_FIELD_INTERLACED, |
907 | sizeof(struct solo_videobuf), | 914 | sizeof(struct solo_videobuf), |
908 | fh, NULL); | 915 | fh, NULL); |
909 | 916 | v4l2_fh_add(&fh->fh); | |
910 | return 0; | 917 | return 0; |
911 | } | 918 | } |
912 | 919 | ||
@@ -931,6 +938,8 @@ static int solo_enc_release(struct file *file) | |||
931 | struct solo_dev *solo_dev = fh->enc->solo_dev; | 938 | struct solo_dev *solo_dev = fh->enc->solo_dev; |
932 | 939 | ||
933 | solo_enc_off(fh); | 940 | solo_enc_off(fh); |
941 | v4l2_fh_del(&fh->fh); | ||
942 | v4l2_fh_exit(&fh->fh); | ||
934 | 943 | ||
935 | videobuf_stop(&fh->vidq); | 944 | videobuf_stop(&fh->vidq); |
936 | videobuf_mmap_free(&fh->vidq); | 945 | videobuf_mmap_free(&fh->vidq); |
@@ -1063,6 +1072,7 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv, | |||
1063 | /* Just set these */ | 1072 | /* Just set these */ |
1064 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; | 1073 | pix->colorspace = V4L2_COLORSPACE_SMPTE170M; |
1065 | pix->sizeimage = FRAME_BUF_SIZE; | 1074 | pix->sizeimage = FRAME_BUF_SIZE; |
1075 | pix->bytesperline = 0; | ||
1066 | pix->priv = 0; | 1076 | pix->priv = 0; |
1067 | 1077 | ||
1068 | return 0; | 1078 | return 0; |
@@ -1417,6 +1427,10 @@ static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { | |||
1417 | /* Video capture parameters */ | 1427 | /* Video capture parameters */ |
1418 | .vidioc_s_parm = solo_s_parm, | 1428 | .vidioc_s_parm = solo_s_parm, |
1419 | .vidioc_g_parm = solo_g_parm, | 1429 | .vidioc_g_parm = solo_g_parm, |
1430 | /* Logging and events */ | ||
1431 | .vidioc_log_status = v4l2_ctrl_log_status, | ||
1432 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
1433 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1420 | }; | 1434 | }; |
1421 | 1435 | ||
1422 | static const struct video_device solo_enc_template = { | 1436 | static const struct video_device solo_enc_template = { |
@@ -1516,6 +1530,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, | |||
1516 | *solo_enc->vfd = solo_enc_template; | 1530 | *solo_enc->vfd = solo_enc_template; |
1517 | solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; | 1531 | solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; |
1518 | solo_enc->vfd->ctrl_handler = hdl; | 1532 | solo_enc->vfd->ctrl_handler = hdl; |
1533 | set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags); | ||
1519 | ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); | 1534 | ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); |
1520 | if (ret < 0) { | 1535 | if (ret < 0) { |
1521 | video_device_release(solo_enc->vfd); | 1536 | video_device_release(solo_enc->vfd); |
diff --git a/drivers/staging/media/solo6x10/v4l2.c b/drivers/staging/media/solo6x10/v4l2.c index 668dc48458a9..a6889490561b 100644 --- a/drivers/staging/media/solo6x10/v4l2.c +++ b/drivers/staging/media/solo6x10/v4l2.c | |||
@@ -29,6 +29,7 @@ | |||
29 | 29 | ||
30 | #include <media/v4l2-ioctl.h> | 30 | #include <media/v4l2-ioctl.h> |
31 | #include <media/v4l2-common.h> | 31 | #include <media/v4l2-common.h> |
32 | #include <media/v4l2-event.h> | ||
32 | #include <media/videobuf-dma-contig.h> | 33 | #include <media/videobuf-dma-contig.h> |
33 | 34 | ||
34 | #include "solo6x10.h" | 35 | #include "solo6x10.h" |
@@ -45,6 +46,7 @@ | |||
45 | 46 | ||
46 | /* Simple file handle */ | 47 | /* Simple file handle */ |
47 | struct solo_filehandle { | 48 | struct solo_filehandle { |
49 | struct v4l2_fh fh; | ||
48 | struct solo_dev *solo_dev; | 50 | struct solo_dev *solo_dev; |
49 | struct videobuf_queue vidq; | 51 | struct videobuf_queue vidq; |
50 | struct task_struct *kthread; | 52 | struct task_struct *kthread; |
@@ -402,8 +404,12 @@ static unsigned int solo_v4l2_poll(struct file *file, | |||
402 | struct poll_table_struct *wait) | 404 | struct poll_table_struct *wait) |
403 | { | 405 | { |
404 | struct solo_filehandle *fh = file->private_data; | 406 | struct solo_filehandle *fh = file->private_data; |
407 | unsigned long req_events = poll_requested_events(wait); | ||
408 | unsigned res = v4l2_ctrl_poll(file, wait); | ||
405 | 409 | ||
406 | return videobuf_poll_stream(file, &fh->vidq, wait); | 410 | if (!(req_events & (POLLIN | POLLRDNORM))) |
411 | return res; | ||
412 | return res | videobuf_poll_stream(file, &fh->vidq, wait); | ||
407 | } | 413 | } |
408 | 414 | ||
409 | static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 415 | static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
@@ -423,6 +429,7 @@ static int solo_v4l2_open(struct file *file) | |||
423 | if (fh == NULL) | 429 | if (fh == NULL) |
424 | return -ENOMEM; | 430 | return -ENOMEM; |
425 | 431 | ||
432 | v4l2_fh_init(&fh->fh, video_devdata(file)); | ||
426 | spin_lock_init(&fh->slock); | 433 | spin_lock_init(&fh->slock); |
427 | INIT_LIST_HEAD(&fh->vidq_active); | 434 | INIT_LIST_HEAD(&fh->vidq_active); |
428 | fh->solo_dev = solo_dev; | 435 | fh->solo_dev = solo_dev; |
@@ -440,6 +447,7 @@ static int solo_v4l2_open(struct file *file) | |||
440 | V4L2_FIELD_INTERLACED, | 447 | V4L2_FIELD_INTERLACED, |
441 | sizeof(struct videobuf_buffer), | 448 | sizeof(struct videobuf_buffer), |
442 | fh, NULL); | 449 | fh, NULL); |
450 | v4l2_fh_add(&fh->fh); | ||
443 | return 0; | 451 | return 0; |
444 | } | 452 | } |
445 | 453 | ||
@@ -461,6 +469,8 @@ static int solo_v4l2_release(struct file *file) | |||
461 | videobuf_stop(&fh->vidq); | 469 | videobuf_stop(&fh->vidq); |
462 | videobuf_mmap_free(&fh->vidq); | 470 | videobuf_mmap_free(&fh->vidq); |
463 | 471 | ||
472 | v4l2_fh_del(&fh->fh); | ||
473 | v4l2_fh_exit(&fh->fh); | ||
464 | kfree(fh); | 474 | kfree(fh); |
465 | 475 | ||
466 | return 0; | 476 | return 0; |
@@ -737,6 +747,10 @@ static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { | |||
737 | .vidioc_dqbuf = solo_dqbuf, | 747 | .vidioc_dqbuf = solo_dqbuf, |
738 | .vidioc_streamon = solo_streamon, | 748 | .vidioc_streamon = solo_streamon, |
739 | .vidioc_streamoff = solo_streamoff, | 749 | .vidioc_streamoff = solo_streamoff, |
750 | /* Logging and events */ | ||
751 | .vidioc_log_status = v4l2_ctrl_log_status, | ||
752 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
753 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
740 | }; | 754 | }; |
741 | 755 | ||
742 | static struct video_device solo_v4l2_template = { | 756 | static struct video_device solo_v4l2_template = { |
@@ -782,6 +796,7 @@ int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) | |||
782 | if (solo_dev->disp_hdl.error) | 796 | if (solo_dev->disp_hdl.error) |
783 | return solo_dev->disp_hdl.error; | 797 | return solo_dev->disp_hdl.error; |
784 | solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; | 798 | solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; |
799 | set_bit(V4L2_FL_USE_FH_PRIO, &solo_dev->vfd->flags); | ||
785 | 800 | ||
786 | ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); | 801 | ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); |
787 | if (ret < 0) { | 802 | if (ret < 0) { |