diff options
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r-- | drivers/media/video/vivi.c | 579 |
1 files changed, 331 insertions, 248 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index c49c39386bd0..2238a613d664 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -7,6 +7,9 @@ | |||
7 | * John Sokol <sokol--a.t--videotechnology.com> | 7 | * John Sokol <sokol--a.t--videotechnology.com> |
8 | * http://v4l.videotechnology.com/ | 8 | * http://v4l.videotechnology.com/ |
9 | * | 9 | * |
10 | * Conversion to videobuf2 by Pawel Osciak & Marek Szyprowski | ||
11 | * Copyright (c) 2010 Samsung Electronics | ||
12 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | 13 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the BSD Licence, GNU General Public License | 14 | * it under the terms of the BSD Licence, GNU General Public License |
12 | * as published by the Free Software Foundation; either version 2 of the | 15 | * as published by the Free Software Foundation; either version 2 of the |
@@ -23,12 +26,12 @@ | |||
23 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
24 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
25 | #include <linux/kthread.h> | 28 | #include <linux/kthread.h> |
26 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) | ||
27 | #include <linux/freezer.h> | 29 | #include <linux/freezer.h> |
28 | #endif | 30 | #include <media/videobuf2-vmalloc.h> |
29 | #include <media/videobuf-vmalloc.h> | ||
30 | #include <media/v4l2-device.h> | 31 | #include <media/v4l2-device.h> |
31 | #include <media/v4l2-ioctl.h> | 32 | #include <media/v4l2-ioctl.h> |
33 | #include <media/v4l2-ctrls.h> | ||
34 | #include <media/v4l2-fh.h> | ||
32 | #include <media/v4l2-common.h> | 35 | #include <media/v4l2-common.h> |
33 | 36 | ||
34 | #define VIVI_MODULE_NAME "vivi" | 37 | #define VIVI_MODULE_NAME "vivi" |
@@ -42,7 +45,7 @@ | |||
42 | #define MAX_HEIGHT 1200 | 45 | #define MAX_HEIGHT 1200 |
43 | 46 | ||
44 | #define VIVI_MAJOR_VERSION 0 | 47 | #define VIVI_MAJOR_VERSION 0 |
45 | #define VIVI_MINOR_VERSION 7 | 48 | #define VIVI_MINOR_VERSION 8 |
46 | #define VIVI_RELEASE 0 | 49 | #define VIVI_RELEASE 0 |
47 | #define VIVI_VERSION \ | 50 | #define VIVI_VERSION \ |
48 | KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) | 51 | KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) |
@@ -133,16 +136,11 @@ static struct vivi_fmt *get_format(struct v4l2_format *f) | |||
133 | return &formats[k]; | 136 | return &formats[k]; |
134 | } | 137 | } |
135 | 138 | ||
136 | struct sg_to_addr { | ||
137 | int pos; | ||
138 | struct scatterlist *sg; | ||
139 | }; | ||
140 | |||
141 | /* buffer for one video frame */ | 139 | /* buffer for one video frame */ |
142 | struct vivi_buffer { | 140 | struct vivi_buffer { |
143 | /* common v4l buffer stuff -- must be first */ | 141 | /* common v4l buffer stuff -- must be first */ |
144 | struct videobuf_buffer vb; | 142 | struct vb2_buffer vb; |
145 | 143 | struct list_head list; | |
146 | struct vivi_fmt *fmt; | 144 | struct vivi_fmt *fmt; |
147 | }; | 145 | }; |
148 | 146 | ||
@@ -162,13 +160,20 @@ static LIST_HEAD(vivi_devlist); | |||
162 | struct vivi_dev { | 160 | struct vivi_dev { |
163 | struct list_head vivi_devlist; | 161 | struct list_head vivi_devlist; |
164 | struct v4l2_device v4l2_dev; | 162 | struct v4l2_device v4l2_dev; |
163 | struct v4l2_ctrl_handler ctrl_handler; | ||
165 | 164 | ||
166 | /* controls */ | 165 | /* controls */ |
167 | int brightness; | 166 | struct v4l2_ctrl *brightness; |
168 | int contrast; | 167 | struct v4l2_ctrl *contrast; |
169 | int saturation; | 168 | struct v4l2_ctrl *saturation; |
170 | int hue; | 169 | struct v4l2_ctrl *hue; |
171 | int volume; | 170 | struct v4l2_ctrl *volume; |
171 | struct v4l2_ctrl *button; | ||
172 | struct v4l2_ctrl *boolean; | ||
173 | struct v4l2_ctrl *int32; | ||
174 | struct v4l2_ctrl *int64; | ||
175 | struct v4l2_ctrl *menu; | ||
176 | struct v4l2_ctrl *string; | ||
172 | 177 | ||
173 | spinlock_t slock; | 178 | spinlock_t slock; |
174 | struct mutex mutex; | 179 | struct mutex mutex; |
@@ -181,6 +186,7 @@ struct vivi_dev { | |||
181 | /* Several counters */ | 186 | /* Several counters */ |
182 | unsigned ms; | 187 | unsigned ms; |
183 | unsigned long jiffies; | 188 | unsigned long jiffies; |
189 | unsigned button_pressed; | ||
184 | 190 | ||
185 | int mv_count; /* Controls bars movement */ | 191 | int mv_count; /* Controls bars movement */ |
186 | 192 | ||
@@ -190,9 +196,10 @@ struct vivi_dev { | |||
190 | /* video capture */ | 196 | /* video capture */ |
191 | struct vivi_fmt *fmt; | 197 | struct vivi_fmt *fmt; |
192 | unsigned int width, height; | 198 | unsigned int width, height; |
193 | struct videobuf_queue vb_vidq; | 199 | struct vb2_queue vb_vidq; |
200 | enum v4l2_field field; | ||
201 | unsigned int field_count; | ||
194 | 202 | ||
195 | unsigned long generating; | ||
196 | u8 bars[9][3]; | 203 | u8 bars[9][3]; |
197 | u8 line[MAX_WIDTH * 4]; | 204 | u8 line[MAX_WIDTH * 4]; |
198 | }; | 205 | }; |
@@ -443,10 +450,10 @@ static void gen_text(struct vivi_dev *dev, char *basep, | |||
443 | 450 | ||
444 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | 451 | static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) |
445 | { | 452 | { |
446 | int hmax = buf->vb.height; | 453 | int wmax = dev->width; |
447 | int wmax = buf->vb.width; | 454 | int hmax = dev->height; |
448 | struct timeval ts; | 455 | struct timeval ts; |
449 | void *vbuf = videobuf_to_vmalloc(&buf->vb); | 456 | void *vbuf = vb2_plane_vaddr(&buf->vb, 0); |
450 | unsigned ms; | 457 | unsigned ms; |
451 | char str[100]; | 458 | char str[100]; |
452 | int h, line = 1; | 459 | int h, line = 1; |
@@ -472,22 +479,38 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) | |||
472 | dev->width, dev->height, dev->input); | 479 | dev->width, dev->height, dev->input); |
473 | gen_text(dev, vbuf, line++ * 16, 16, str); | 480 | gen_text(dev, vbuf, line++ * 16, 16, str); |
474 | 481 | ||
482 | mutex_lock(&dev->ctrl_handler.lock); | ||
475 | snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", | 483 | snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", |
476 | dev->brightness, | 484 | dev->brightness->cur.val, |
477 | dev->contrast, | 485 | dev->contrast->cur.val, |
478 | dev->saturation, | 486 | dev->saturation->cur.val, |
479 | dev->hue); | 487 | dev->hue->cur.val); |
480 | gen_text(dev, vbuf, line++ * 16, 16, str); | 488 | gen_text(dev, vbuf, line++ * 16, 16, str); |
481 | snprintf(str, sizeof(str), " volume %3d ", dev->volume); | 489 | snprintf(str, sizeof(str), " volume %3d ", dev->volume->cur.val); |
482 | gen_text(dev, vbuf, line++ * 16, 16, str); | 490 | gen_text(dev, vbuf, line++ * 16, 16, str); |
491 | snprintf(str, sizeof(str), " int32 %d, int64 %lld ", | ||
492 | dev->int32->cur.val, | ||
493 | dev->int64->cur.val64); | ||
494 | gen_text(dev, vbuf, line++ * 16, 16, str); | ||
495 | snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ", | ||
496 | dev->boolean->cur.val, | ||
497 | dev->menu->qmenu[dev->menu->cur.val], | ||
498 | dev->string->cur.string); | ||
499 | mutex_unlock(&dev->ctrl_handler.lock); | ||
500 | gen_text(dev, vbuf, line++ * 16, 16, str); | ||
501 | if (dev->button_pressed) { | ||
502 | dev->button_pressed--; | ||
503 | snprintf(str, sizeof(str), " button pressed!"); | ||
504 | gen_text(dev, vbuf, line++ * 16, 16, str); | ||
505 | } | ||
483 | 506 | ||
484 | dev->mv_count += 2; | 507 | dev->mv_count += 2; |
485 | 508 | ||
486 | /* Advice that buffer was filled */ | 509 | buf->vb.v4l2_buf.field = dev->field; |
487 | buf->vb.field_count++; | 510 | dev->field_count++; |
511 | buf->vb.v4l2_buf.sequence = dev->field_count >> 1; | ||
488 | do_gettimeofday(&ts); | 512 | do_gettimeofday(&ts); |
489 | buf->vb.ts = ts; | 513 | buf->vb.v4l2_buf.timestamp = ts; |
490 | buf->vb.state = VIDEOBUF_DONE; | ||
491 | } | 514 | } |
492 | 515 | ||
493 | static void vivi_thread_tick(struct vivi_dev *dev) | 516 | static void vivi_thread_tick(struct vivi_dev *dev) |
@@ -504,23 +527,17 @@ static void vivi_thread_tick(struct vivi_dev *dev) | |||
504 | goto unlock; | 527 | goto unlock; |
505 | } | 528 | } |
506 | 529 | ||
507 | buf = list_entry(dma_q->active.next, | 530 | buf = list_entry(dma_q->active.next, struct vivi_buffer, list); |
508 | struct vivi_buffer, vb.queue); | 531 | list_del(&buf->list); |
509 | 532 | ||
510 | /* Nobody is waiting on this buffer, return */ | 533 | do_gettimeofday(&buf->vb.v4l2_buf.timestamp); |
511 | if (!waitqueue_active(&buf->vb.done)) | ||
512 | goto unlock; | ||
513 | |||
514 | list_del(&buf->vb.queue); | ||
515 | |||
516 | do_gettimeofday(&buf->vb.ts); | ||
517 | 534 | ||
518 | /* Fill buffer */ | 535 | /* Fill buffer */ |
519 | vivi_fillbuff(dev, buf); | 536 | vivi_fillbuff(dev, buf); |
520 | dprintk(dev, 1, "filled buffer %p\n", buf); | 537 | dprintk(dev, 1, "filled buffer %p\n", buf); |
521 | 538 | ||
522 | wake_up(&buf->vb.done); | 539 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE); |
523 | dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); | 540 | dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index); |
524 | unlock: | 541 | unlock: |
525 | spin_unlock_irqrestore(&dev->slock, flags); | 542 | spin_unlock_irqrestore(&dev->slock, flags); |
526 | } | 543 | } |
@@ -571,17 +588,12 @@ static int vivi_thread(void *data) | |||
571 | return 0; | 588 | return 0; |
572 | } | 589 | } |
573 | 590 | ||
574 | static void vivi_start_generating(struct file *file) | 591 | static int vivi_start_generating(struct vivi_dev *dev) |
575 | { | 592 | { |
576 | struct vivi_dev *dev = video_drvdata(file); | ||
577 | struct vivi_dmaqueue *dma_q = &dev->vidq; | 593 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
578 | 594 | ||
579 | dprintk(dev, 1, "%s\n", __func__); | 595 | dprintk(dev, 1, "%s\n", __func__); |
580 | 596 | ||
581 | if (test_and_set_bit(0, &dev->generating)) | ||
582 | return; | ||
583 | file->private_data = dev; | ||
584 | |||
585 | /* Resets frame counters */ | 597 | /* Resets frame counters */ |
586 | dev->ms = 0; | 598 | dev->ms = 0; |
587 | dev->mv_count = 0; | 599 | dev->mv_count = 0; |
@@ -593,146 +605,200 @@ static void vivi_start_generating(struct file *file) | |||
593 | 605 | ||
594 | if (IS_ERR(dma_q->kthread)) { | 606 | if (IS_ERR(dma_q->kthread)) { |
595 | v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); | 607 | v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); |
596 | clear_bit(0, &dev->generating); | 608 | return PTR_ERR(dma_q->kthread); |
597 | return; | ||
598 | } | 609 | } |
599 | /* Wakes thread */ | 610 | /* Wakes thread */ |
600 | wake_up_interruptible(&dma_q->wq); | 611 | wake_up_interruptible(&dma_q->wq); |
601 | 612 | ||
602 | dprintk(dev, 1, "returning from %s\n", __func__); | 613 | dprintk(dev, 1, "returning from %s\n", __func__); |
614 | return 0; | ||
603 | } | 615 | } |
604 | 616 | ||
605 | static void vivi_stop_generating(struct file *file) | 617 | static void vivi_stop_generating(struct vivi_dev *dev) |
606 | { | 618 | { |
607 | struct vivi_dev *dev = video_drvdata(file); | ||
608 | struct vivi_dmaqueue *dma_q = &dev->vidq; | 619 | struct vivi_dmaqueue *dma_q = &dev->vidq; |
609 | 620 | ||
610 | dprintk(dev, 1, "%s\n", __func__); | 621 | dprintk(dev, 1, "%s\n", __func__); |
611 | 622 | ||
612 | if (!file->private_data) | ||
613 | return; | ||
614 | if (!test_and_clear_bit(0, &dev->generating)) | ||
615 | return; | ||
616 | |||
617 | /* shutdown control thread */ | 623 | /* shutdown control thread */ |
618 | if (dma_q->kthread) { | 624 | if (dma_q->kthread) { |
619 | kthread_stop(dma_q->kthread); | 625 | kthread_stop(dma_q->kthread); |
620 | dma_q->kthread = NULL; | 626 | dma_q->kthread = NULL; |
621 | } | 627 | } |
622 | videobuf_stop(&dev->vb_vidq); | ||
623 | videobuf_mmap_free(&dev->vb_vidq); | ||
624 | } | ||
625 | 628 | ||
626 | static int vivi_is_generating(struct vivi_dev *dev) | 629 | /* |
627 | { | 630 | * Typical driver might need to wait here until dma engine stops. |
628 | return test_bit(0, &dev->generating); | 631 | * In this case we can abort imiedetly, so it's just a noop. |
632 | */ | ||
633 | |||
634 | /* Release all active buffers */ | ||
635 | while (!list_empty(&dma_q->active)) { | ||
636 | struct vivi_buffer *buf; | ||
637 | buf = list_entry(dma_q->active.next, struct vivi_buffer, list); | ||
638 | list_del(&buf->list); | ||
639 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | ||
640 | dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index); | ||
641 | } | ||
629 | } | 642 | } |
630 | |||
631 | /* ------------------------------------------------------------------ | 643 | /* ------------------------------------------------------------------ |
632 | Videobuf operations | 644 | Videobuf operations |
633 | ------------------------------------------------------------------*/ | 645 | ------------------------------------------------------------------*/ |
634 | static int | 646 | static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, |
635 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | 647 | unsigned int *nplanes, unsigned long sizes[], |
648 | void *alloc_ctxs[]) | ||
636 | { | 649 | { |
637 | struct vivi_dev *dev = vq->priv_data; | 650 | struct vivi_dev *dev = vb2_get_drv_priv(vq); |
651 | unsigned long size; | ||
652 | |||
653 | size = dev->width * dev->height * 2; | ||
654 | |||
655 | if (0 == *nbuffers) | ||
656 | *nbuffers = 32; | ||
638 | 657 | ||
639 | *size = dev->width * dev->height * 2; | 658 | while (size * *nbuffers > vid_limit * 1024 * 1024) |
659 | (*nbuffers)--; | ||
640 | 660 | ||
641 | if (0 == *count) | 661 | *nplanes = 1; |
642 | *count = 32; | ||
643 | 662 | ||
644 | while (*size * *count > vid_limit * 1024 * 1024) | 663 | sizes[0] = size; |
645 | (*count)--; | ||
646 | 664 | ||
647 | dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, | 665 | /* |
648 | *count, *size); | 666 | * videobuf2-vmalloc allocator is context-less so no need to set |
667 | * alloc_ctxs array. | ||
668 | */ | ||
669 | |||
670 | dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__, | ||
671 | *nbuffers, size); | ||
649 | 672 | ||
650 | return 0; | 673 | return 0; |
651 | } | 674 | } |
652 | 675 | ||
653 | static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) | 676 | static int buffer_init(struct vb2_buffer *vb) |
654 | { | 677 | { |
655 | struct vivi_dev *dev = vq->priv_data; | 678 | struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
679 | |||
680 | BUG_ON(NULL == dev->fmt); | ||
656 | 681 | ||
657 | dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); | 682 | /* |
683 | * This callback is called once per buffer, after its allocation. | ||
684 | * | ||
685 | * Vivi does not allow changing format during streaming, but it is | ||
686 | * possible to do so when streaming is paused (i.e. in streamoff state). | ||
687 | * Buffers however are not freed when going into streamoff and so | ||
688 | * buffer size verification has to be done in buffer_prepare, on each | ||
689 | * qbuf. | ||
690 | * It would be best to move verification code here to buf_init and | ||
691 | * s_fmt though. | ||
692 | */ | ||
658 | 693 | ||
659 | videobuf_vmalloc_free(&buf->vb); | 694 | return 0; |
660 | dprintk(dev, 1, "free_buffer: freed\n"); | ||
661 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
662 | } | 695 | } |
663 | 696 | ||
664 | static int | 697 | static int buffer_prepare(struct vb2_buffer *vb) |
665 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | ||
666 | enum v4l2_field field) | ||
667 | { | 698 | { |
668 | struct vivi_dev *dev = vq->priv_data; | 699 | struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
669 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 700 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
670 | int rc; | 701 | unsigned long size; |
671 | 702 | ||
672 | dprintk(dev, 1, "%s, field=%d\n", __func__, field); | 703 | dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field); |
673 | 704 | ||
674 | BUG_ON(NULL == dev->fmt); | 705 | BUG_ON(NULL == dev->fmt); |
675 | 706 | ||
707 | /* | ||
708 | * Theses properties only change when queue is idle, see s_fmt. | ||
709 | * The below checks should not be performed here, on each | ||
710 | * buffer_prepare (i.e. on each qbuf). Most of the code in this function | ||
711 | * should thus be moved to buffer_init and s_fmt. | ||
712 | */ | ||
676 | if (dev->width < 48 || dev->width > MAX_WIDTH || | 713 | if (dev->width < 48 || dev->width > MAX_WIDTH || |
677 | dev->height < 32 || dev->height > MAX_HEIGHT) | 714 | dev->height < 32 || dev->height > MAX_HEIGHT) |
678 | return -EINVAL; | 715 | return -EINVAL; |
679 | 716 | ||
680 | buf->vb.size = dev->width * dev->height * 2; | 717 | size = dev->width * dev->height * 2; |
681 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 718 | if (vb2_plane_size(vb, 0) < size) { |
719 | dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n", | ||
720 | __func__, vb2_plane_size(vb, 0), size); | ||
682 | return -EINVAL; | 721 | return -EINVAL; |
722 | } | ||
683 | 723 | ||
684 | /* These properties only change when queue is idle, see s_fmt */ | 724 | vb2_set_plane_payload(&buf->vb, 0, size); |
685 | buf->fmt = dev->fmt; | 725 | |
686 | buf->vb.width = dev->width; | 726 | buf->fmt = dev->fmt; |
687 | buf->vb.height = dev->height; | ||
688 | buf->vb.field = field; | ||
689 | 727 | ||
690 | precalculate_bars(dev); | 728 | precalculate_bars(dev); |
691 | precalculate_line(dev); | 729 | precalculate_line(dev); |
692 | 730 | ||
693 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | 731 | return 0; |
694 | rc = videobuf_iolock(vq, &buf->vb, NULL); | 732 | } |
695 | if (rc < 0) | ||
696 | goto fail; | ||
697 | } | ||
698 | 733 | ||
699 | buf->vb.state = VIDEOBUF_PREPARED; | 734 | static int buffer_finish(struct vb2_buffer *vb) |
735 | { | ||
736 | struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); | ||
737 | dprintk(dev, 1, "%s\n", __func__); | ||
700 | return 0; | 738 | return 0; |
739 | } | ||
740 | |||
741 | static void buffer_cleanup(struct vb2_buffer *vb) | ||
742 | { | ||
743 | struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); | ||
744 | dprintk(dev, 1, "%s\n", __func__); | ||
701 | 745 | ||
702 | fail: | ||
703 | free_buffer(vq, buf); | ||
704 | return rc; | ||
705 | } | 746 | } |
706 | 747 | ||
707 | static void | 748 | static void buffer_queue(struct vb2_buffer *vb) |
708 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
709 | { | 749 | { |
710 | struct vivi_dev *dev = vq->priv_data; | 750 | struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue); |
711 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 751 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); |
712 | struct vivi_dmaqueue *vidq = &dev->vidq; | 752 | struct vivi_dmaqueue *vidq = &dev->vidq; |
753 | unsigned long flags = 0; | ||
713 | 754 | ||
714 | dprintk(dev, 1, "%s\n", __func__); | 755 | dprintk(dev, 1, "%s\n", __func__); |
715 | 756 | ||
716 | buf->vb.state = VIDEOBUF_QUEUED; | 757 | spin_lock_irqsave(&dev->slock, flags); |
717 | list_add_tail(&buf->vb.queue, &vidq->active); | 758 | list_add_tail(&buf->list, &vidq->active); |
759 | spin_unlock_irqrestore(&dev->slock, flags); | ||
718 | } | 760 | } |
719 | 761 | ||
720 | static void buffer_release(struct videobuf_queue *vq, | 762 | static int start_streaming(struct vb2_queue *vq) |
721 | struct videobuf_buffer *vb) | ||
722 | { | 763 | { |
723 | struct vivi_dev *dev = vq->priv_data; | 764 | struct vivi_dev *dev = vb2_get_drv_priv(vq); |
724 | struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); | 765 | dprintk(dev, 1, "%s\n", __func__); |
766 | return vivi_start_generating(dev); | ||
767 | } | ||
725 | 768 | ||
769 | /* abort streaming and wait for last buffer */ | ||
770 | static int stop_streaming(struct vb2_queue *vq) | ||
771 | { | ||
772 | struct vivi_dev *dev = vb2_get_drv_priv(vq); | ||
726 | dprintk(dev, 1, "%s\n", __func__); | 773 | dprintk(dev, 1, "%s\n", __func__); |
774 | vivi_stop_generating(dev); | ||
775 | return 0; | ||
776 | } | ||
727 | 777 | ||
728 | free_buffer(vq, buf); | 778 | static void vivi_lock(struct vb2_queue *vq) |
779 | { | ||
780 | struct vivi_dev *dev = vb2_get_drv_priv(vq); | ||
781 | mutex_lock(&dev->mutex); | ||
729 | } | 782 | } |
730 | 783 | ||
731 | static struct videobuf_queue_ops vivi_video_qops = { | 784 | static void vivi_unlock(struct vb2_queue *vq) |
732 | .buf_setup = buffer_setup, | 785 | { |
733 | .buf_prepare = buffer_prepare, | 786 | struct vivi_dev *dev = vb2_get_drv_priv(vq); |
734 | .buf_queue = buffer_queue, | 787 | mutex_unlock(&dev->mutex); |
735 | .buf_release = buffer_release, | 788 | } |
789 | |||
790 | |||
791 | static struct vb2_ops vivi_video_qops = { | ||
792 | .queue_setup = queue_setup, | ||
793 | .buf_init = buffer_init, | ||
794 | .buf_prepare = buffer_prepare, | ||
795 | .buf_finish = buffer_finish, | ||
796 | .buf_cleanup = buffer_cleanup, | ||
797 | .buf_queue = buffer_queue, | ||
798 | .start_streaming = start_streaming, | ||
799 | .stop_streaming = stop_streaming, | ||
800 | .wait_prepare = vivi_unlock, | ||
801 | .wait_finish = vivi_lock, | ||
736 | }; | 802 | }; |
737 | 803 | ||
738 | /* ------------------------------------------------------------------ | 804 | /* ------------------------------------------------------------------ |
@@ -774,7 +840,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
774 | 840 | ||
775 | f->fmt.pix.width = dev->width; | 841 | f->fmt.pix.width = dev->width; |
776 | f->fmt.pix.height = dev->height; | 842 | f->fmt.pix.height = dev->height; |
777 | f->fmt.pix.field = dev->vb_vidq.field; | 843 | f->fmt.pix.field = dev->field; |
778 | f->fmt.pix.pixelformat = dev->fmt->fourcc; | 844 | f->fmt.pix.pixelformat = dev->fmt->fourcc; |
779 | f->fmt.pix.bytesperline = | 845 | f->fmt.pix.bytesperline = |
780 | (f->fmt.pix.width * dev->fmt->depth) >> 3; | 846 | (f->fmt.pix.width * dev->fmt->depth) >> 3; |
@@ -820,82 +886,60 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
820 | struct v4l2_format *f) | 886 | struct v4l2_format *f) |
821 | { | 887 | { |
822 | struct vivi_dev *dev = video_drvdata(file); | 888 | struct vivi_dev *dev = video_drvdata(file); |
889 | struct vb2_queue *q = &dev->vb_vidq; | ||
823 | 890 | ||
824 | int ret = vidioc_try_fmt_vid_cap(file, priv, f); | 891 | int ret = vidioc_try_fmt_vid_cap(file, priv, f); |
825 | if (ret < 0) | 892 | if (ret < 0) |
826 | return ret; | 893 | return ret; |
827 | 894 | ||
828 | if (vivi_is_generating(dev)) { | 895 | if (vb2_is_streaming(q)) { |
829 | dprintk(dev, 1, "%s device busy\n", __func__); | 896 | dprintk(dev, 1, "%s device busy\n", __func__); |
830 | ret = -EBUSY; | 897 | return -EBUSY; |
831 | goto out; | ||
832 | } | 898 | } |
833 | 899 | ||
834 | dev->fmt = get_format(f); | 900 | dev->fmt = get_format(f); |
835 | dev->width = f->fmt.pix.width; | 901 | dev->width = f->fmt.pix.width; |
836 | dev->height = f->fmt.pix.height; | 902 | dev->height = f->fmt.pix.height; |
837 | dev->vb_vidq.field = f->fmt.pix.field; | 903 | dev->field = f->fmt.pix.field; |
838 | ret = 0; | 904 | |
839 | out: | 905 | return 0; |
840 | return ret; | ||
841 | } | 906 | } |
842 | 907 | ||
843 | static int vidioc_reqbufs(struct file *file, void *priv, | 908 | static int vidioc_reqbufs(struct file *file, void *priv, |
844 | struct v4l2_requestbuffers *p) | 909 | struct v4l2_requestbuffers *p) |
845 | { | 910 | { |
846 | struct vivi_dev *dev = video_drvdata(file); | 911 | struct vivi_dev *dev = video_drvdata(file); |
847 | 912 | return vb2_reqbufs(&dev->vb_vidq, p); | |
848 | return videobuf_reqbufs(&dev->vb_vidq, p); | ||
849 | } | 913 | } |
850 | 914 | ||
851 | static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) | 915 | static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) |
852 | { | 916 | { |
853 | struct vivi_dev *dev = video_drvdata(file); | 917 | struct vivi_dev *dev = video_drvdata(file); |
854 | 918 | return vb2_querybuf(&dev->vb_vidq, p); | |
855 | return videobuf_querybuf(&dev->vb_vidq, p); | ||
856 | } | 919 | } |
857 | 920 | ||
858 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) | 921 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) |
859 | { | 922 | { |
860 | struct vivi_dev *dev = video_drvdata(file); | 923 | struct vivi_dev *dev = video_drvdata(file); |
861 | 924 | return vb2_qbuf(&dev->vb_vidq, p); | |
862 | return videobuf_qbuf(&dev->vb_vidq, p); | ||
863 | } | 925 | } |
864 | 926 | ||
865 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) | 927 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) |
866 | { | 928 | { |
867 | struct vivi_dev *dev = video_drvdata(file); | 929 | struct vivi_dev *dev = video_drvdata(file); |
868 | 930 | return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK); | |
869 | return videobuf_dqbuf(&dev->vb_vidq, p, | ||
870 | file->f_flags & O_NONBLOCK); | ||
871 | } | 931 | } |
872 | 932 | ||
873 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | 933 | static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) |
874 | { | 934 | { |
875 | struct vivi_dev *dev = video_drvdata(file); | 935 | struct vivi_dev *dev = video_drvdata(file); |
876 | int ret; | 936 | return vb2_streamon(&dev->vb_vidq, i); |
877 | |||
878 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
879 | return -EINVAL; | ||
880 | ret = videobuf_streamon(&dev->vb_vidq); | ||
881 | if (ret) | ||
882 | return ret; | ||
883 | |||
884 | vivi_start_generating(file); | ||
885 | return 0; | ||
886 | } | 937 | } |
887 | 938 | ||
888 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | 939 | static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) |
889 | { | 940 | { |
890 | struct vivi_dev *dev = video_drvdata(file); | 941 | struct vivi_dev *dev = video_drvdata(file); |
891 | int ret; | 942 | return vb2_streamoff(&dev->vb_vidq, i); |
892 | |||
893 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
894 | return -EINVAL; | ||
895 | ret = videobuf_streamoff(&dev->vb_vidq); | ||
896 | if (!ret) | ||
897 | vivi_stop_generating(file); | ||
898 | return ret; | ||
899 | } | 943 | } |
900 | 944 | ||
901 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) | 945 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) |
@@ -938,80 +982,14 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | |||
938 | } | 982 | } |
939 | 983 | ||
940 | /* --- controls ---------------------------------------------- */ | 984 | /* --- controls ---------------------------------------------- */ |
941 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
942 | struct v4l2_queryctrl *qc) | ||
943 | { | ||
944 | switch (qc->id) { | ||
945 | case V4L2_CID_AUDIO_VOLUME: | ||
946 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 200); | ||
947 | case V4L2_CID_BRIGHTNESS: | ||
948 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127); | ||
949 | case V4L2_CID_CONTRAST: | ||
950 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 16); | ||
951 | case V4L2_CID_SATURATION: | ||
952 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127); | ||
953 | case V4L2_CID_HUE: | ||
954 | return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0); | ||
955 | } | ||
956 | return -EINVAL; | ||
957 | } | ||
958 | 985 | ||
959 | static int vidioc_g_ctrl(struct file *file, void *priv, | 986 | static int vivi_s_ctrl(struct v4l2_ctrl *ctrl) |
960 | struct v4l2_control *ctrl) | ||
961 | { | 987 | { |
962 | struct vivi_dev *dev = video_drvdata(file); | 988 | struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler); |
963 | 989 | ||
964 | switch (ctrl->id) { | 990 | if (ctrl == dev->button) |
965 | case V4L2_CID_AUDIO_VOLUME: | 991 | dev->button_pressed = 30; |
966 | ctrl->value = dev->volume; | 992 | return 0; |
967 | return 0; | ||
968 | case V4L2_CID_BRIGHTNESS: | ||
969 | ctrl->value = dev->brightness; | ||
970 | return 0; | ||
971 | case V4L2_CID_CONTRAST: | ||
972 | ctrl->value = dev->contrast; | ||
973 | return 0; | ||
974 | case V4L2_CID_SATURATION: | ||
975 | ctrl->value = dev->saturation; | ||
976 | return 0; | ||
977 | case V4L2_CID_HUE: | ||
978 | ctrl->value = dev->hue; | ||
979 | return 0; | ||
980 | } | ||
981 | return -EINVAL; | ||
982 | } | ||
983 | |||
984 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
985 | struct v4l2_control *ctrl) | ||
986 | { | ||
987 | struct vivi_dev *dev = video_drvdata(file); | ||
988 | struct v4l2_queryctrl qc; | ||
989 | int err; | ||
990 | |||
991 | qc.id = ctrl->id; | ||
992 | err = vidioc_queryctrl(file, priv, &qc); | ||
993 | if (err < 0) | ||
994 | return err; | ||
995 | if (ctrl->value < qc.minimum || ctrl->value > qc.maximum) | ||
996 | return -ERANGE; | ||
997 | switch (ctrl->id) { | ||
998 | case V4L2_CID_AUDIO_VOLUME: | ||
999 | dev->volume = ctrl->value; | ||
1000 | return 0; | ||
1001 | case V4L2_CID_BRIGHTNESS: | ||
1002 | dev->brightness = ctrl->value; | ||
1003 | return 0; | ||
1004 | case V4L2_CID_CONTRAST: | ||
1005 | dev->contrast = ctrl->value; | ||
1006 | return 0; | ||
1007 | case V4L2_CID_SATURATION: | ||
1008 | dev->saturation = ctrl->value; | ||
1009 | return 0; | ||
1010 | case V4L2_CID_HUE: | ||
1011 | dev->hue = ctrl->value; | ||
1012 | return 0; | ||
1013 | } | ||
1014 | return -EINVAL; | ||
1015 | } | 993 | } |
1016 | 994 | ||
1017 | /* ------------------------------------------------------------------ | 995 | /* ------------------------------------------------------------------ |
@@ -1023,21 +1001,19 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) | |||
1023 | { | 1001 | { |
1024 | struct vivi_dev *dev = video_drvdata(file); | 1002 | struct vivi_dev *dev = video_drvdata(file); |
1025 | 1003 | ||
1026 | vivi_start_generating(file); | 1004 | dprintk(dev, 1, "read called\n"); |
1027 | return videobuf_read_stream(&dev->vb_vidq, data, count, ppos, 0, | 1005 | return vb2_read(&dev->vb_vidq, data, count, ppos, |
1028 | file->f_flags & O_NONBLOCK); | 1006 | file->f_flags & O_NONBLOCK); |
1029 | } | 1007 | } |
1030 | 1008 | ||
1031 | static unsigned int | 1009 | static unsigned int |
1032 | vivi_poll(struct file *file, struct poll_table_struct *wait) | 1010 | vivi_poll(struct file *file, struct poll_table_struct *wait) |
1033 | { | 1011 | { |
1034 | struct vivi_dev *dev = video_drvdata(file); | 1012 | struct vivi_dev *dev = video_drvdata(file); |
1035 | struct videobuf_queue *q = &dev->vb_vidq; | 1013 | struct vb2_queue *q = &dev->vb_vidq; |
1036 | 1014 | ||
1037 | dprintk(dev, 1, "%s\n", __func__); | 1015 | dprintk(dev, 1, "%s\n", __func__); |
1038 | 1016 | return vb2_poll(q, file, wait); | |
1039 | vivi_start_generating(file); | ||
1040 | return videobuf_poll_stream(file, q, wait); | ||
1041 | } | 1017 | } |
1042 | 1018 | ||
1043 | static int vivi_close(struct file *file) | 1019 | static int vivi_close(struct file *file) |
@@ -1045,11 +1021,12 @@ static int vivi_close(struct file *file) | |||
1045 | struct video_device *vdev = video_devdata(file); | 1021 | struct video_device *vdev = video_devdata(file); |
1046 | struct vivi_dev *dev = video_drvdata(file); | 1022 | struct vivi_dev *dev = video_drvdata(file); |
1047 | 1023 | ||
1048 | vivi_stop_generating(file); | 1024 | dprintk(dev, 1, "close called (dev=%s), file %p\n", |
1025 | video_device_node_name(vdev), file); | ||
1049 | 1026 | ||
1050 | dprintk(dev, 1, "close called (dev=%s)\n", | 1027 | if (v4l2_fh_is_singular_file(file)) |
1051 | video_device_node_name(vdev)); | 1028 | vb2_queue_release(&dev->vb_vidq); |
1052 | return 0; | 1029 | return v4l2_fh_release(file); |
1053 | } | 1030 | } |
1054 | 1031 | ||
1055 | static int vivi_mmap(struct file *file, struct vm_area_struct *vma) | 1032 | static int vivi_mmap(struct file *file, struct vm_area_struct *vma) |
@@ -1059,8 +1036,7 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma) | |||
1059 | 1036 | ||
1060 | dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); | 1037 | dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); |
1061 | 1038 | ||
1062 | ret = videobuf_mmap_mapper(&dev->vb_vidq, vma); | 1039 | ret = vb2_mmap(&dev->vb_vidq, vma); |
1063 | |||
1064 | dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", | 1040 | dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", |
1065 | (unsigned long)vma->vm_start, | 1041 | (unsigned long)vma->vm_start, |
1066 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, | 1042 | (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, |
@@ -1068,8 +1044,82 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma) | |||
1068 | return ret; | 1044 | return ret; |
1069 | } | 1045 | } |
1070 | 1046 | ||
1047 | static const struct v4l2_ctrl_ops vivi_ctrl_ops = { | ||
1048 | .s_ctrl = vivi_s_ctrl, | ||
1049 | }; | ||
1050 | |||
1051 | #define VIVI_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000) | ||
1052 | |||
1053 | static const struct v4l2_ctrl_config vivi_ctrl_button = { | ||
1054 | .ops = &vivi_ctrl_ops, | ||
1055 | .id = VIVI_CID_CUSTOM_BASE + 0, | ||
1056 | .name = "Button", | ||
1057 | .type = V4L2_CTRL_TYPE_BUTTON, | ||
1058 | }; | ||
1059 | |||
1060 | static const struct v4l2_ctrl_config vivi_ctrl_boolean = { | ||
1061 | .ops = &vivi_ctrl_ops, | ||
1062 | .id = VIVI_CID_CUSTOM_BASE + 1, | ||
1063 | .name = "Boolean", | ||
1064 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1065 | .min = 0, | ||
1066 | .max = 1, | ||
1067 | .step = 1, | ||
1068 | .def = 1, | ||
1069 | }; | ||
1070 | |||
1071 | static const struct v4l2_ctrl_config vivi_ctrl_int32 = { | ||
1072 | .ops = &vivi_ctrl_ops, | ||
1073 | .id = VIVI_CID_CUSTOM_BASE + 2, | ||
1074 | .name = "Integer 32 Bits", | ||
1075 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1076 | .min = 0x80000000, | ||
1077 | .max = 0x7fffffff, | ||
1078 | .step = 1, | ||
1079 | }; | ||
1080 | |||
1081 | static const struct v4l2_ctrl_config vivi_ctrl_int64 = { | ||
1082 | .ops = &vivi_ctrl_ops, | ||
1083 | .id = VIVI_CID_CUSTOM_BASE + 3, | ||
1084 | .name = "Integer 64 Bits", | ||
1085 | .type = V4L2_CTRL_TYPE_INTEGER64, | ||
1086 | }; | ||
1087 | |||
1088 | static const char * const vivi_ctrl_menu_strings[] = { | ||
1089 | "Menu Item 0 (Skipped)", | ||
1090 | "Menu Item 1", | ||
1091 | "Menu Item 2 (Skipped)", | ||
1092 | "Menu Item 3", | ||
1093 | "Menu Item 4", | ||
1094 | "Menu Item 5 (Skipped)", | ||
1095 | NULL, | ||
1096 | }; | ||
1097 | |||
1098 | static const struct v4l2_ctrl_config vivi_ctrl_menu = { | ||
1099 | .ops = &vivi_ctrl_ops, | ||
1100 | .id = VIVI_CID_CUSTOM_BASE + 4, | ||
1101 | .name = "Menu", | ||
1102 | .type = V4L2_CTRL_TYPE_MENU, | ||
1103 | .min = 1, | ||
1104 | .max = 4, | ||
1105 | .def = 3, | ||
1106 | .menu_skip_mask = 0x04, | ||
1107 | .qmenu = vivi_ctrl_menu_strings, | ||
1108 | }; | ||
1109 | |||
1110 | static const struct v4l2_ctrl_config vivi_ctrl_string = { | ||
1111 | .ops = &vivi_ctrl_ops, | ||
1112 | .id = VIVI_CID_CUSTOM_BASE + 5, | ||
1113 | .name = "String", | ||
1114 | .type = V4L2_CTRL_TYPE_STRING, | ||
1115 | .min = 2, | ||
1116 | .max = 4, | ||
1117 | .step = 1, | ||
1118 | }; | ||
1119 | |||
1071 | static const struct v4l2_file_operations vivi_fops = { | 1120 | static const struct v4l2_file_operations vivi_fops = { |
1072 | .owner = THIS_MODULE, | 1121 | .owner = THIS_MODULE, |
1122 | .open = v4l2_fh_open, | ||
1073 | .release = vivi_close, | 1123 | .release = vivi_close, |
1074 | .read = vivi_read, | 1124 | .read = vivi_read, |
1075 | .poll = vivi_poll, | 1125 | .poll = vivi_poll, |
@@ -1093,9 +1143,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = { | |||
1093 | .vidioc_s_input = vidioc_s_input, | 1143 | .vidioc_s_input = vidioc_s_input, |
1094 | .vidioc_streamon = vidioc_streamon, | 1144 | .vidioc_streamon = vidioc_streamon, |
1095 | .vidioc_streamoff = vidioc_streamoff, | 1145 | .vidioc_streamoff = vidioc_streamoff, |
1096 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1097 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1098 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1099 | }; | 1146 | }; |
1100 | 1147 | ||
1101 | static struct video_device vivi_template = { | 1148 | static struct video_device vivi_template = { |
@@ -1126,6 +1173,7 @@ static int vivi_release(void) | |||
1126 | video_device_node_name(dev->vfd)); | 1173 | video_device_node_name(dev->vfd)); |
1127 | video_unregister_device(dev->vfd); | 1174 | video_unregister_device(dev->vfd); |
1128 | v4l2_device_unregister(&dev->v4l2_dev); | 1175 | v4l2_device_unregister(&dev->v4l2_dev); |
1176 | v4l2_ctrl_handler_free(&dev->ctrl_handler); | ||
1129 | kfree(dev); | 1177 | kfree(dev); |
1130 | } | 1178 | } |
1131 | 1179 | ||
@@ -1136,6 +1184,8 @@ static int __init vivi_create_instance(int inst) | |||
1136 | { | 1184 | { |
1137 | struct vivi_dev *dev; | 1185 | struct vivi_dev *dev; |
1138 | struct video_device *vfd; | 1186 | struct video_device *vfd; |
1187 | struct v4l2_ctrl_handler *hdl; | ||
1188 | struct vb2_queue *q; | ||
1139 | int ret; | 1189 | int ret; |
1140 | 1190 | ||
1141 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1191 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
@@ -1151,20 +1201,46 @@ static int __init vivi_create_instance(int inst) | |||
1151 | dev->fmt = &formats[0]; | 1201 | dev->fmt = &formats[0]; |
1152 | dev->width = 640; | 1202 | dev->width = 640; |
1153 | dev->height = 480; | 1203 | dev->height = 480; |
1154 | dev->volume = 200; | 1204 | hdl = &dev->ctrl_handler; |
1155 | dev->brightness = 127; | 1205 | v4l2_ctrl_handler_init(hdl, 11); |
1156 | dev->contrast = 16; | 1206 | dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, |
1157 | dev->saturation = 127; | 1207 | V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200); |
1158 | dev->hue = 0; | 1208 | dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, |
1209 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 127); | ||
1210 | dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, | ||
1211 | V4L2_CID_CONTRAST, 0, 255, 1, 16); | ||
1212 | dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, | ||
1213 | V4L2_CID_SATURATION, 0, 255, 1, 127); | ||
1214 | dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops, | ||
1215 | V4L2_CID_HUE, -128, 127, 1, 0); | ||
1216 | dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL); | ||
1217 | dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL); | ||
1218 | dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL); | ||
1219 | dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL); | ||
1220 | dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL); | ||
1221 | dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL); | ||
1222 | if (hdl->error) { | ||
1223 | ret = hdl->error; | ||
1224 | goto unreg_dev; | ||
1225 | } | ||
1226 | dev->v4l2_dev.ctrl_handler = hdl; | ||
1159 | 1227 | ||
1160 | /* initialize locks */ | 1228 | /* initialize locks */ |
1161 | spin_lock_init(&dev->slock); | 1229 | spin_lock_init(&dev->slock); |
1162 | mutex_init(&dev->mutex); | ||
1163 | 1230 | ||
1164 | videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops, | 1231 | /* initialize queue */ |
1165 | NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, | 1232 | q = &dev->vb_vidq; |
1166 | V4L2_FIELD_INTERLACED, | 1233 | memset(q, 0, sizeof(dev->vb_vidq)); |
1167 | sizeof(struct vivi_buffer), dev, &dev->mutex); | 1234 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
1235 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; | ||
1236 | q->drv_priv = dev; | ||
1237 | q->buf_struct_size = sizeof(struct vivi_buffer); | ||
1238 | q->ops = &vivi_video_qops; | ||
1239 | q->mem_ops = &vb2_vmalloc_memops; | ||
1240 | |||
1241 | vb2_queue_init(q); | ||
1242 | |||
1243 | mutex_init(&dev->mutex); | ||
1168 | 1244 | ||
1169 | /* init video dma queues */ | 1245 | /* init video dma queues */ |
1170 | INIT_LIST_HEAD(&dev->vidq.active); | 1246 | INIT_LIST_HEAD(&dev->vidq.active); |
@@ -1178,6 +1254,12 @@ static int __init vivi_create_instance(int inst) | |||
1178 | *vfd = vivi_template; | 1254 | *vfd = vivi_template; |
1179 | vfd->debug = debug; | 1255 | vfd->debug = debug; |
1180 | vfd->v4l2_dev = &dev->v4l2_dev; | 1256 | vfd->v4l2_dev = &dev->v4l2_dev; |
1257 | set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | ||
1258 | |||
1259 | /* | ||
1260 | * Provide a mutex to v4l2 core. It will be used to protect | ||
1261 | * all fops and v4l2 ioctls. | ||
1262 | */ | ||
1181 | vfd->lock = &dev->mutex; | 1263 | vfd->lock = &dev->mutex; |
1182 | 1264 | ||
1183 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | 1265 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); |
@@ -1200,6 +1282,7 @@ static int __init vivi_create_instance(int inst) | |||
1200 | rel_vdev: | 1282 | rel_vdev: |
1201 | video_device_release(vfd); | 1283 | video_device_release(vfd); |
1202 | unreg_dev: | 1284 | unreg_dev: |
1285 | v4l2_ctrl_handler_free(hdl); | ||
1203 | v4l2_device_unregister(&dev->v4l2_dev); | 1286 | v4l2_device_unregister(&dev->v4l2_dev); |
1204 | free_dev: | 1287 | free_dev: |
1205 | kfree(dev); | 1288 | kfree(dev); |