diff options
| author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-01 11:04:52 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 14:00:03 -0400 |
| commit | 537fa492e084af58d16899f8d0f3f3516a4fbe7c (patch) | |
| tree | 73486cf2548394a597c230818c7cb40a2eba7b2c | |
| parent | 9bb601935b8495cd4ef8aea389df77233d6be5dd (diff) | |
[media] saa7146: support control events and priority handling
Use v4l2_fh which gives you control events and priority handling for free.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/common/saa7146_fops.c | 18 | ||||
| -rw-r--r-- | drivers/media/common/saa7146_video.c | 4 | ||||
| -rw-r--r-- | include/media/saa7146_vv.h | 3 |
3 files changed, 19 insertions, 6 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 66f6e79dd97b..dfb396568ab6 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
| @@ -198,7 +198,6 @@ static int fops_open(struct file *file) | |||
| 198 | struct saa7146_dev *dev = video_drvdata(file); | 198 | struct saa7146_dev *dev = video_drvdata(file); |
| 199 | struct saa7146_fh *fh = NULL; | 199 | struct saa7146_fh *fh = NULL; |
| 200 | int result = 0; | 200 | int result = 0; |
| 201 | |||
| 202 | enum v4l2_buf_type type; | 201 | enum v4l2_buf_type type; |
| 203 | 202 | ||
| 204 | DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); | 203 | DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); |
| @@ -227,7 +226,9 @@ static int fops_open(struct file *file) | |||
| 227 | goto out; | 226 | goto out; |
| 228 | } | 227 | } |
| 229 | 228 | ||
| 230 | file->private_data = fh; | 229 | v4l2_fh_init(&fh->fh, vdev); |
| 230 | |||
| 231 | file->private_data = &fh->fh; | ||
| 231 | fh->dev = dev; | 232 | fh->dev = dev; |
| 232 | 233 | ||
| 233 | if (vdev->vfl_type == VFL_TYPE_VBI) { | 234 | if (vdev->vfl_type == VFL_TYPE_VBI) { |
| @@ -251,6 +252,7 @@ static int fops_open(struct file *file) | |||
| 251 | } | 252 | } |
| 252 | 253 | ||
| 253 | result = 0; | 254 | result = 0; |
| 255 | v4l2_fh_add(&fh->fh); | ||
| 254 | out: | 256 | out: |
| 255 | if (fh && result != 0) { | 257 | if (fh && result != 0) { |
| 256 | kfree(fh); | 258 | kfree(fh); |
| @@ -280,6 +282,8 @@ static int fops_release(struct file *file) | |||
| 280 | saa7146_video_uops.release(dev,file); | 282 | saa7146_video_uops.release(dev,file); |
| 281 | } | 283 | } |
| 282 | 284 | ||
| 285 | v4l2_fh_del(&fh->fh); | ||
| 286 | v4l2_fh_exit(&fh->fh); | ||
| 283 | module_put(dev->ext->module); | 287 | module_put(dev->ext->module); |
| 284 | file->private_data = NULL; | 288 | file->private_data = NULL; |
| 285 | kfree(fh); | 289 | kfree(fh); |
| @@ -322,12 +326,13 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) | |||
| 322 | struct saa7146_fh *fh = file->private_data; | 326 | struct saa7146_fh *fh = file->private_data; |
| 323 | struct videobuf_buffer *buf = NULL; | 327 | struct videobuf_buffer *buf = NULL; |
| 324 | struct videobuf_queue *q; | 328 | struct videobuf_queue *q; |
| 329 | unsigned int res = v4l2_ctrl_poll(file, wait); | ||
| 325 | 330 | ||
| 326 | DEB_EE("file:%p, poll:%p\n", file, wait); | 331 | DEB_EE("file:%p, poll:%p\n", file, wait); |
| 327 | 332 | ||
| 328 | if (vdev->vfl_type == VFL_TYPE_VBI) { | 333 | if (vdev->vfl_type == VFL_TYPE_VBI) { |
| 329 | if( 0 == fh->vbi_q.streaming ) | 334 | if( 0 == fh->vbi_q.streaming ) |
| 330 | return videobuf_poll_stream(file, &fh->vbi_q, wait); | 335 | return res | videobuf_poll_stream(file, &fh->vbi_q, wait); |
| 331 | q = &fh->vbi_q; | 336 | q = &fh->vbi_q; |
| 332 | } else { | 337 | } else { |
| 333 | DEB_D("using video queue\n"); | 338 | DEB_D("using video queue\n"); |
| @@ -339,17 +344,17 @@ static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait) | |||
| 339 | 344 | ||
| 340 | if (!buf) { | 345 | if (!buf) { |
| 341 | DEB_D("buf == NULL!\n"); | 346 | DEB_D("buf == NULL!\n"); |
| 342 | return POLLERR; | 347 | return res | POLLERR; |
| 343 | } | 348 | } |
| 344 | 349 | ||
| 345 | poll_wait(file, &buf->done, wait); | 350 | poll_wait(file, &buf->done, wait); |
| 346 | if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { | 351 | if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) { |
| 347 | DEB_D("poll succeeded!\n"); | 352 | DEB_D("poll succeeded!\n"); |
| 348 | return POLLIN|POLLRDNORM; | 353 | return res | POLLIN | POLLRDNORM; |
| 349 | } | 354 | } |
| 350 | 355 | ||
| 351 | DEB_D("nothing to poll for, buf->state:%d\n", buf->state); | 356 | DEB_D("nothing to poll for, buf->state:%d\n", buf->state); |
| 352 | return 0; | 357 | return res; |
| 353 | } | 358 | } |
| 354 | 359 | ||
| 355 | static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | 360 | static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos) |
| @@ -583,6 +588,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
| 583 | vfd->lock = &dev->v4l2_lock; | 588 | vfd->lock = &dev->v4l2_lock; |
| 584 | vfd->v4l2_dev = &dev->v4l2_dev; | 589 | vfd->v4l2_dev = &dev->v4l2_dev; |
| 585 | vfd->tvnorms = 0; | 590 | vfd->tvnorms = 0; |
| 591 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | ||
| 586 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) | 592 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) |
| 587 | vfd->tvnorms |= dev->ext_vv_data->stds[i].id; | 593 | vfd->tvnorms |= dev->ext_vv_data->stds[i].id; |
| 588 | strlcpy(vfd->name, name, sizeof(vfd->name)); | 594 | strlcpy(vfd->name, name, sizeof(vfd->name)); |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 850799051bef..4ca9a2561513 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | #include <media/saa7146_vv.h> | 3 | #include <media/saa7146_vv.h> |
| 4 | #include <media/v4l2-chip-ident.h> | 4 | #include <media/v4l2-chip-ident.h> |
| 5 | #include <media/v4l2-event.h> | ||
| 6 | #include <media/v4l2-ctrls.h> | ||
| 5 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 6 | 8 | ||
| 7 | static int max_memory = 32; | 9 | static int max_memory = 32; |
| @@ -1021,6 +1023,8 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { | |||
| 1021 | .vidioc_streamon = vidioc_streamon, | 1023 | .vidioc_streamon = vidioc_streamon, |
| 1022 | .vidioc_streamoff = vidioc_streamoff, | 1024 | .vidioc_streamoff = vidioc_streamoff, |
| 1023 | .vidioc_g_parm = vidioc_g_parm, | 1025 | .vidioc_g_parm = vidioc_g_parm, |
| 1026 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
| 1027 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
| 1024 | }; | 1028 | }; |
| 1025 | 1029 | ||
| 1026 | /*********************************************************************************/ | 1030 | /*********************************************************************************/ |
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index 2cc32c514173..2bbdf3046be6 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #include <media/v4l2-common.h> | 4 | #include <media/v4l2-common.h> |
| 5 | #include <media/v4l2-ioctl.h> | 5 | #include <media/v4l2-ioctl.h> |
| 6 | #include <media/v4l2-fh.h> | ||
| 6 | #include <media/saa7146.h> | 7 | #include <media/saa7146.h> |
| 7 | #include <media/videobuf-dma-sg.h> | 8 | #include <media/videobuf-dma-sg.h> |
| 8 | 9 | ||
| @@ -84,6 +85,8 @@ struct saa7146_overlay { | |||
| 84 | 85 | ||
| 85 | /* per open data */ | 86 | /* per open data */ |
| 86 | struct saa7146_fh { | 87 | struct saa7146_fh { |
| 88 | /* Must be the first field! */ | ||
| 89 | struct v4l2_fh fh; | ||
| 87 | struct saa7146_dev *dev; | 90 | struct saa7146_dev *dev; |
| 88 | 91 | ||
| 89 | /* video capture */ | 92 | /* video capture */ |
