diff options
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-vbi.c')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-vbi.c | 123 |
1 files changed, 45 insertions, 78 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-vbi.c b/drivers/media/usb/em28xx/em28xx-vbi.c index 2b4c9cba2d67..39f39c527c13 100644 --- a/drivers/media/usb/em28xx/em28xx-vbi.c +++ b/drivers/media/usb/em28xx/em28xx-vbi.c | |||
@@ -41,105 +41,72 @@ MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); | |||
41 | 41 | ||
42 | /* ------------------------------------------------------------------ */ | 42 | /* ------------------------------------------------------------------ */ |
43 | 43 | ||
44 | static void | 44 | static int vbi_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, |
45 | free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | 45 | unsigned int *nbuffers, unsigned int *nplanes, |
46 | unsigned int sizes[], void *alloc_ctxs[]) | ||
46 | { | 47 | { |
47 | struct em28xx_fh *fh = vq->priv_data; | 48 | struct em28xx *dev = vb2_get_drv_priv(vq); |
48 | struct em28xx *dev = fh->dev; | 49 | unsigned long size; |
49 | unsigned long flags = 0; | ||
50 | if (in_interrupt()) | ||
51 | BUG(); | ||
52 | |||
53 | /* We used to wait for the buffer to finish here, but this didn't work | ||
54 | because, as we were keeping the state as VIDEOBUF_QUEUED, | ||
55 | videobuf_queue_cancel marked it as finished for us. | ||
56 | (Also, it could wedge forever if the hardware was misconfigured.) | ||
57 | |||
58 | This should be safe; by the time we get here, the buffer isn't | ||
59 | queued anymore. If we ever start marking the buffers as | ||
60 | VIDEOBUF_ACTIVE, it won't be, though. | ||
61 | */ | ||
62 | spin_lock_irqsave(&dev->slock, flags); | ||
63 | if (dev->isoc_ctl.vbi_buf == buf) | ||
64 | dev->isoc_ctl.vbi_buf = NULL; | ||
65 | spin_unlock_irqrestore(&dev->slock, flags); | ||
66 | 50 | ||
67 | videobuf_vmalloc_free(&buf->vb); | 51 | if (fmt) |
68 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | 52 | size = fmt->fmt.pix.sizeimage; |
69 | } | 53 | else |
54 | size = dev->vbi_width * dev->vbi_height * 2; | ||
70 | 55 | ||
71 | static int | 56 | if (0 == *nbuffers) |
72 | vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | 57 | *nbuffers = 32; |
73 | { | 58 | if (*nbuffers < 2) |
74 | struct em28xx_fh *fh = q->priv_data; | 59 | *nbuffers = 2; |
75 | struct em28xx *dev = fh->dev; | 60 | if (*nbuffers > 32) |
61 | *nbuffers = 32; | ||
76 | 62 | ||
77 | *size = dev->vbi_width * dev->vbi_height * 2; | 63 | *nplanes = 1; |
64 | sizes[0] = size; | ||
78 | 65 | ||
79 | if (0 == *count) | ||
80 | *count = vbibufs; | ||
81 | if (*count < 2) | ||
82 | *count = 2; | ||
83 | if (*count > 32) | ||
84 | *count = 32; | ||
85 | return 0; | 66 | return 0; |
86 | } | 67 | } |
87 | 68 | ||
88 | static int | 69 | static int vbi_buffer_prepare(struct vb2_buffer *vb) |
89 | vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
90 | enum v4l2_field field) | ||
91 | { | 70 | { |
92 | struct em28xx_fh *fh = q->priv_data; | 71 | struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue); |
93 | struct em28xx *dev = fh->dev; | ||
94 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | 72 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); |
95 | int rc = 0; | 73 | unsigned long size; |
96 | 74 | ||
97 | buf->vb.size = dev->vbi_width * dev->vbi_height * 2; | 75 | size = dev->vbi_width * dev->vbi_height * 2; |
98 | 76 | ||
99 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 77 | if (vb2_plane_size(vb, 0) < size) { |
78 | printk(KERN_INFO "%s data will not fit into plane (%lu < %lu)\n", | ||
79 | __func__, vb2_plane_size(vb, 0), size); | ||
100 | return -EINVAL; | 80 | return -EINVAL; |
101 | |||
102 | buf->vb.width = dev->vbi_width; | ||
103 | buf->vb.height = dev->vbi_height; | ||
104 | buf->vb.field = field; | ||
105 | |||
106 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
107 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
108 | if (rc < 0) | ||
109 | goto fail; | ||
110 | } | 81 | } |
82 | vb2_set_plane_payload(&buf->vb, 0, size); | ||
111 | 83 | ||
112 | buf->vb.state = VIDEOBUF_PREPARED; | ||
113 | return 0; | 84 | return 0; |
114 | |||
115 | fail: | ||
116 | free_buffer(q, buf); | ||
117 | return rc; | ||
118 | } | 85 | } |
119 | 86 | ||
120 | static void | 87 | static void |
121 | vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | 88 | vbi_buffer_queue(struct vb2_buffer *vb) |
122 | { | ||
123 | struct em28xx_buffer *buf = container_of(vb, | ||
124 | struct em28xx_buffer, | ||
125 | vb); | ||
126 | struct em28xx_fh *fh = vq->priv_data; | ||
127 | struct em28xx *dev = fh->dev; | ||
128 | struct em28xx_dmaqueue *vbiq = &dev->vbiq; | ||
129 | |||
130 | buf->vb.state = VIDEOBUF_QUEUED; | ||
131 | list_add_tail(&buf->vb.queue, &vbiq->active); | ||
132 | } | ||
133 | |||
134 | static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
135 | { | 89 | { |
90 | struct em28xx *dev = vb2_get_drv_priv(vb->vb2_queue); | ||
136 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | 91 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); |
137 | free_buffer(q, buf); | 92 | struct em28xx_dmaqueue *vbiq = &dev->vbiq; |
93 | unsigned long flags = 0; | ||
94 | |||
95 | buf->mem = vb2_plane_vaddr(vb, 0); | ||
96 | buf->length = vb2_plane_size(vb, 0); | ||
97 | |||
98 | spin_lock_irqsave(&dev->slock, flags); | ||
99 | list_add_tail(&buf->list, &vbiq->active); | ||
100 | spin_unlock_irqrestore(&dev->slock, flags); | ||
138 | } | 101 | } |
139 | 102 | ||
140 | struct videobuf_queue_ops em28xx_vbi_qops = { | 103 | |
141 | .buf_setup = vbi_setup, | 104 | struct vb2_ops em28xx_vbi_qops = { |
142 | .buf_prepare = vbi_prepare, | 105 | .queue_setup = vbi_queue_setup, |
143 | .buf_queue = vbi_queue, | 106 | .buf_prepare = vbi_buffer_prepare, |
144 | .buf_release = vbi_release, | 107 | .buf_queue = vbi_buffer_queue, |
108 | .start_streaming = em28xx_start_analog_streaming, | ||
109 | .stop_streaming = em28xx_stop_vbi_streaming, | ||
110 | .wait_prepare = vb2_ops_wait_prepare, | ||
111 | .wait_finish = vb2_ops_wait_finish, | ||
145 | }; | 112 | }; |