diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-mailbox.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-mailbox.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 9605d54bd083..c07191e09fcb 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = { | |||
81 | API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), | 81 | API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), |
82 | API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), | 82 | API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), |
83 | API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), | 83 | API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), |
84 | API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM, 0), | ||
84 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), | 85 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), |
85 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), | 86 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), |
86 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), | 87 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), |
@@ -158,6 +159,60 @@ static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) | |||
158 | } | 159 | } |
159 | } | 160 | } |
160 | 161 | ||
162 | static void cx18_mdl_send_to_videobuf(struct cx18_stream *s, | ||
163 | struct cx18_mdl *mdl) | ||
164 | { | ||
165 | struct cx18_videobuf_buffer *vb_buf; | ||
166 | struct cx18_buffer *buf; | ||
167 | u8 *p; | ||
168 | u32 offset = 0; | ||
169 | int dispatch = 0; | ||
170 | |||
171 | if (mdl->bytesused == 0) | ||
172 | return; | ||
173 | |||
174 | /* Acquire a videobuf buffer, clone to and and release it */ | ||
175 | spin_lock(&s->vb_lock); | ||
176 | if (list_empty(&s->vb_capture)) | ||
177 | goto out; | ||
178 | |||
179 | vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer, | ||
180 | vb.queue); | ||
181 | |||
182 | p = videobuf_to_vmalloc(&vb_buf->vb); | ||
183 | if (!p) | ||
184 | goto out; | ||
185 | |||
186 | offset = vb_buf->bytes_used; | ||
187 | list_for_each_entry(buf, &mdl->buf_list, list) { | ||
188 | if (buf->bytesused == 0) | ||
189 | break; | ||
190 | |||
191 | if ((offset + buf->bytesused) <= vb_buf->vb.bsize) { | ||
192 | memcpy(p + offset, buf->buf, buf->bytesused); | ||
193 | offset += buf->bytesused; | ||
194 | vb_buf->bytes_used += buf->bytesused; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | /* If we've filled the buffer as per the callers res then dispatch it */ | ||
199 | if (vb_buf->bytes_used >= (vb_buf->vb.width * vb_buf->vb.height * 2)) { | ||
200 | dispatch = 1; | ||
201 | vb_buf->bytes_used = 0; | ||
202 | } | ||
203 | |||
204 | if (dispatch) { | ||
205 | vb_buf->vb.ts = ktime_to_timeval(ktime_get()); | ||
206 | list_del(&vb_buf->vb.queue); | ||
207 | vb_buf->vb.state = VIDEOBUF_DONE; | ||
208 | wake_up(&vb_buf->vb.done); | ||
209 | } | ||
210 | |||
211 | mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies); | ||
212 | |||
213 | out: | ||
214 | spin_unlock(&s->vb_lock); | ||
215 | } | ||
161 | 216 | ||
162 | static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, | 217 | static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s, |
163 | struct cx18_mdl *mdl) | 218 | struct cx18_mdl *mdl) |
@@ -263,6 +318,9 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_in_work_order *order) | |||
263 | } else { | 318 | } else { |
264 | cx18_enqueue(s, mdl, &s->q_full); | 319 | cx18_enqueue(s, mdl, &s->q_full); |
265 | } | 320 | } |
321 | } else if (s->type == CX18_ENC_STREAM_TYPE_YUV) { | ||
322 | cx18_mdl_send_to_videobuf(s, mdl); | ||
323 | cx18_enqueue(s, mdl, &s->q_free); | ||
266 | } else { | 324 | } else { |
267 | cx18_enqueue(s, mdl, &s->q_full); | 325 | cx18_enqueue(s, mdl, &s->q_full); |
268 | if (s->type == CX18_ENC_STREAM_TYPE_IDX) | 326 | if (s->type == CX18_ENC_STREAM_TYPE_IDX) |