diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2013-03-15 11:04:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-25 07:46:03 -0400 |
commit | 382c31a94330a96e5800358140840998671722bf (patch) | |
tree | 0734e8c4c8df472172cc1cd23adc9d9e0c3e10ac | |
parent | a7eb931d635cce7b831f745c903204fb79a4aba0 (diff) |
[media] solo6x10: convert encoder nodes to vb2
As a consequence the ioctl op has been replaced by unlocked_ioctl.
Since we are now using the core lock the locking scheme has been
simplified as well.
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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/solo6x10.h | 13 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/v4l2-enc.c | 505 |
3 files changed, 140 insertions, 379 deletions
diff --git a/drivers/staging/media/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig index 63352de5eabf..f93b4cab9cc7 100644 --- a/drivers/staging/media/solo6x10/Kconfig +++ b/drivers/staging/media/solo6x10/Kconfig | |||
@@ -2,6 +2,7 @@ config SOLO6X10 | |||
2 | tristate "Softlogic 6x10 MPEG codec cards" | 2 | tristate "Softlogic 6x10 MPEG codec cards" |
3 | depends on PCI && VIDEO_DEV && SND && I2C | 3 | depends on PCI && VIDEO_DEV && SND && I2C |
4 | select VIDEOBUF_DMA_SG | 4 | select VIDEOBUF_DMA_SG |
5 | select VIDEOBUF2_DMA_SG | ||
5 | select SND_PCM | 6 | select SND_PCM |
6 | ---help--- | 7 | ---help--- |
7 | This driver supports the Softlogic based MPEG-4 and h.264 codec | 8 | This driver supports the Softlogic based MPEG-4 and h.264 codec |
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h index 413ee10e691e..d18093fac2b2 100644 --- a/drivers/staging/media/solo6x10/solo6x10.h +++ b/drivers/staging/media/solo6x10/solo6x10.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <media/v4l2-device.h> | 40 | #include <media/v4l2-device.h> |
41 | #include <media/v4l2-ctrls.h> | 41 | #include <media/v4l2-ctrls.h> |
42 | #include <media/videobuf-core.h> | 42 | #include <media/videobuf-core.h> |
43 | #include <media/videobuf2-core.h> | ||
43 | 44 | ||
44 | #include "registers.h" | 45 | #include "registers.h" |
45 | 46 | ||
@@ -135,6 +136,11 @@ struct solo_p2m_dev { | |||
135 | 136 | ||
136 | #define OSD_TEXT_MAX 44 | 137 | #define OSD_TEXT_MAX 44 |
137 | 138 | ||
139 | struct solo_vb2_buf { | ||
140 | struct vb2_buffer vb; | ||
141 | struct list_head list; | ||
142 | }; | ||
143 | |||
138 | enum solo_enc_types { | 144 | enum solo_enc_types { |
139 | SOLO_ENC_TYPE_STD, | 145 | SOLO_ENC_TYPE_STD, |
140 | SOLO_ENC_TYPE_EXT, | 146 | SOLO_ENC_TYPE_EXT, |
@@ -146,10 +152,8 @@ struct solo_enc_dev { | |||
146 | struct v4l2_ctrl_handler hdl; | 152 | struct v4l2_ctrl_handler hdl; |
147 | struct video_device *vfd; | 153 | struct video_device *vfd; |
148 | /* General accounting */ | 154 | /* General accounting */ |
149 | struct mutex enable_lock; | 155 | struct mutex lock; |
150 | spinlock_t motion_lock; | 156 | spinlock_t motion_lock; |
151 | atomic_t readers; | ||
152 | atomic_t mpeg_readers; | ||
153 | u8 ch; | 157 | u8 ch; |
154 | u8 mode, gop, qp, interlaced, interval; | 158 | u8 mode, gop, qp, interlaced, interval; |
155 | u8 bw_weight; | 159 | u8 bw_weight; |
@@ -169,9 +173,8 @@ struct solo_enc_dev { | |||
169 | int jpeg_len; | 173 | int jpeg_len; |
170 | 174 | ||
171 | u32 fmt; | 175 | u32 fmt; |
172 | u8 enc_on; | ||
173 | enum solo_enc_types type; | 176 | enum solo_enc_types type; |
174 | struct videobuf_queue vidq; | 177 | struct vb2_queue vidq; |
175 | struct list_head vidq_active; | 178 | struct list_head vidq_active; |
176 | int desc_count; | 179 | int desc_count; |
177 | int desc_nelts; | 180 | int desc_nelts; |
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c index 546a18b31328..d7d96ce1006d 100644 --- a/drivers/staging/media/solo6x10/v4l2-enc.c +++ b/drivers/staging/media/solo6x10/v4l2-enc.c | |||
@@ -30,7 +30,7 @@ | |||
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/v4l2-event.h> |
33 | #include <media/videobuf-dma-sg.h> | 33 | #include <media/videobuf2-dma-sg.h> |
34 | 34 | ||
35 | #include "solo6x10.h" | 35 | #include "solo6x10.h" |
36 | #include "tw28.h" | 36 | #include "tw28.h" |
@@ -181,7 +181,6 @@ static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) | |||
181 | spin_unlock_irqrestore(&solo_enc->motion_lock, flags); | 181 | spin_unlock_irqrestore(&solo_enc->motion_lock, flags); |
182 | } | 182 | } |
183 | 183 | ||
184 | /* MUST be called with solo_enc->enable_lock held */ | ||
185 | static void solo_update_mode(struct solo_enc_dev *solo_enc) | 184 | static void solo_update_mode(struct solo_enc_dev *solo_enc) |
186 | { | 185 | { |
187 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 186 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
@@ -264,43 +263,22 @@ static void solo_update_mode(struct solo_enc_dev *solo_enc) | |||
264 | jpeg_dqt[solo_g_jpeg_qp(solo_dev, solo_enc->ch)], DQT_LEN); | 263 | jpeg_dqt[solo_g_jpeg_qp(solo_dev, solo_enc->ch)], DQT_LEN); |
265 | } | 264 | } |
266 | 265 | ||
267 | /* MUST be called with solo_enc->enable_lock held */ | 266 | static int solo_enc_on(struct solo_enc_dev *solo_enc) |
268 | static int __solo_enc_on(struct solo_enc_dev *solo_enc) | ||
269 | { | 267 | { |
270 | u8 ch = solo_enc->ch; | 268 | u8 ch = solo_enc->ch; |
271 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 269 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
272 | u8 interval; | 270 | u8 interval; |
273 | 271 | ||
274 | BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); | ||
275 | |||
276 | if (solo_enc->enc_on) | ||
277 | return 0; | ||
278 | |||
279 | solo_update_mode(solo_enc); | 272 | solo_update_mode(solo_enc); |
280 | 273 | ||
281 | /* Make sure to bw check on first reader */ | 274 | /* Make sure to do a bandwidth check */ |
282 | if (!atomic_read(&solo_enc->readers)) { | 275 | if (solo_enc->bw_weight > solo_dev->enc_bw_remain) |
283 | if (solo_enc->bw_weight > solo_dev->enc_bw_remain) | 276 | return -EBUSY; |
284 | return -EBUSY; | 277 | solo_dev->enc_bw_remain -= solo_enc->bw_weight; |
285 | else | ||
286 | solo_dev->enc_bw_remain -= solo_enc->bw_weight; | ||
287 | } | ||
288 | |||
289 | solo_enc->enc_on = 1; | ||
290 | 278 | ||
291 | if (solo_enc->type == SOLO_ENC_TYPE_EXT) | 279 | if (solo_enc->type == SOLO_ENC_TYPE_EXT) |
292 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); | 280 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); |
293 | 281 | ||
294 | /* Reset the encoder if we are the first mpeg reader, else only reset | ||
295 | * on the first mjpeg reader. */ | ||
296 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) { | ||
297 | atomic_inc(&solo_enc->readers); | ||
298 | if (atomic_inc_return(&solo_enc->mpeg_readers) > 1) | ||
299 | return 0; | ||
300 | } else if (atomic_inc_return(&solo_enc->readers) > 1) { | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | /* Disable all encoding for this channel */ | 282 | /* Disable all encoding for this channel */ |
305 | solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0); | 283 | solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), 0); |
306 | 284 | ||
@@ -329,47 +307,16 @@ static int __solo_enc_on(struct solo_enc_dev *solo_enc) | |||
329 | return 0; | 307 | return 0; |
330 | } | 308 | } |
331 | 309 | ||
332 | static int solo_enc_on(struct solo_enc_dev *solo_enc) | 310 | static void solo_enc_off(struct solo_enc_dev *solo_enc) |
333 | { | ||
334 | int ret; | ||
335 | |||
336 | mutex_lock(&solo_enc->enable_lock); | ||
337 | ret = __solo_enc_on(solo_enc); | ||
338 | mutex_unlock(&solo_enc->enable_lock); | ||
339 | |||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | static void __solo_enc_off(struct solo_enc_dev *solo_enc) | ||
344 | { | 311 | { |
345 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 312 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
346 | 313 | ||
347 | BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); | ||
348 | |||
349 | if (!solo_enc->enc_on) | ||
350 | return; | ||
351 | |||
352 | solo_enc->enc_on = 0; | ||
353 | |||
354 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) | ||
355 | atomic_dec(&solo_enc->mpeg_readers); | ||
356 | |||
357 | if (atomic_dec_return(&solo_enc->readers) > 0) | ||
358 | return; | ||
359 | |||
360 | solo_dev->enc_bw_remain += solo_enc->bw_weight; | 314 | solo_dev->enc_bw_remain += solo_enc->bw_weight; |
361 | 315 | ||
362 | solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0); | 316 | solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0); |
363 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); | 317 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); |
364 | } | 318 | } |
365 | 319 | ||
366 | static void solo_enc_off(struct solo_enc_dev *solo_enc) | ||
367 | { | ||
368 | mutex_lock(&solo_enc->enable_lock); | ||
369 | __solo_enc_off(solo_enc); | ||
370 | mutex_unlock(&solo_enc->enable_lock); | ||
371 | } | ||
372 | |||
373 | static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma, | 320 | static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma, |
374 | unsigned int off, unsigned int size) | 321 | unsigned int off, unsigned int size) |
375 | { | 322 | { |
@@ -403,7 +350,7 @@ static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma, | |||
403 | /* Build a descriptor queue out of an SG list and send it to the P2M for | 350 | /* Build a descriptor queue out of an SG list and send it to the P2M for |
404 | * processing. */ | 351 | * processing. */ |
405 | static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, | 352 | static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, |
406 | struct videobuf_dmabuf *vbuf, int off, int size, | 353 | struct vb2_dma_sg_desc *vbuf, int off, int size, |
407 | unsigned int base, unsigned int base_size) | 354 | unsigned int base, unsigned int base_size) |
408 | { | 355 | { |
409 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 356 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
@@ -416,7 +363,7 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, | |||
416 | 363 | ||
417 | solo_enc->desc_count = 1; | 364 | solo_enc->desc_count = 1; |
418 | 365 | ||
419 | for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { | 366 | for_each_sg(vbuf->sglist, sg, vbuf->num_pages, i) { |
420 | struct solo_p2m_desc *desc; | 367 | struct solo_p2m_desc *desc; |
421 | dma_addr_t dma; | 368 | dma_addr_t dma; |
422 | int len; | 369 | int len; |
@@ -487,61 +434,62 @@ static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, | |||
487 | solo_enc->desc_count - 1); | 434 | solo_enc->desc_count - 1); |
488 | } | 435 | } |
489 | 436 | ||
490 | static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb, | 437 | static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, |
491 | struct videobuf_dmabuf *vbuf, struct vop_header *vh) | 438 | struct vb2_buffer *vb, struct vop_header *vh) |
492 | { | 439 | { |
493 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 440 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
494 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; | 441 | struct vb2_dma_sg_desc *vbuf = vb2_dma_sg_plane_desc(vb, 0); |
495 | int frame_size; | 442 | int frame_size; |
443 | int ret; | ||
496 | 444 | ||
497 | svb->flags |= V4L2_BUF_FLAG_KEYFRAME; | 445 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
498 | 446 | ||
499 | if (vb->bsize < (vh->jpeg_size + solo_enc->jpeg_len)) | 447 | if (vb2_plane_size(vb, 0) < vh->jpeg_size + solo_enc->jpeg_len) |
500 | return -EIO; | 448 | return -EIO; |
501 | 449 | ||
502 | vb->width = solo_enc->width; | 450 | sg_copy_from_buffer(vbuf->sglist, vbuf->num_pages, |
503 | vb->height = solo_enc->height; | 451 | solo_enc->jpeg_header, |
504 | vb->size = vh->jpeg_size + solo_enc->jpeg_len; | 452 | solo_enc->jpeg_len); |
505 | |||
506 | sg_copy_from_buffer(vbuf->sglist, vbuf->sglen, | ||
507 | solo_enc->jpeg_header, | ||
508 | solo_enc->jpeg_len); | ||
509 | 453 | ||
510 | frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) | 454 | frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) |
511 | & ~(DMA_ALIGN - 1); | 455 | & ~(DMA_ALIGN - 1); |
512 | 456 | vb2_set_plane_payload(vb, 0, vh->jpeg_size + solo_enc->jpeg_len); | |
513 | return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off, | 457 | |
514 | frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), | 458 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, |
515 | SOLO_JPEG_EXT_SIZE(solo_dev)); | 459 | DMA_FROM_DEVICE); |
460 | ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off, | ||
461 | frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), | ||
462 | SOLO_JPEG_EXT_SIZE(solo_dev)); | ||
463 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, | ||
464 | DMA_FROM_DEVICE); | ||
465 | return ret; | ||
516 | } | 466 | } |
517 | 467 | ||
518 | static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb, | 468 | static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, |
519 | struct videobuf_dmabuf *vbuf, struct vop_header *vh) | 469 | struct vb2_buffer *vb, struct vop_header *vh) |
520 | { | 470 | { |
521 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 471 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
522 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; | 472 | struct vb2_dma_sg_desc *vbuf = vb2_dma_sg_plane_desc(vb, 0); |
523 | int frame_off, frame_size; | 473 | int frame_off, frame_size; |
524 | int skip = 0; | 474 | int skip = 0; |
475 | int ret; | ||
525 | 476 | ||
526 | if (vb->bsize < vh->mpeg_size) | 477 | if (vb2_plane_size(vb, 0) < vh->mpeg_size) |
527 | return -EIO; | 478 | return -EIO; |
528 | 479 | ||
529 | vb->width = vh->hsize << 4; | ||
530 | vb->height = vh->vsize << 4; | ||
531 | vb->size = vh->mpeg_size; | ||
532 | |||
533 | /* If this is a key frame, add extra header */ | 480 | /* If this is a key frame, add extra header */ |
534 | if (!vh->vop_type) { | 481 | if (!vh->vop_type) { |
535 | sg_copy_from_buffer(vbuf->sglist, vbuf->sglen, | 482 | sg_copy_from_buffer(vbuf->sglist, vbuf->num_pages, |
536 | solo_enc->vop, | 483 | solo_enc->vop, |
537 | solo_enc->vop_len); | 484 | solo_enc->vop_len); |
538 | 485 | ||
539 | skip = solo_enc->vop_len; | 486 | skip = solo_enc->vop_len; |
540 | vb->size += solo_enc->vop_len; | ||
541 | 487 | ||
542 | svb->flags |= V4L2_BUF_FLAG_KEYFRAME; | 488 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
489 | vb2_set_plane_payload(vb, 0, vh->mpeg_size + solo_enc->vop_len); | ||
543 | } else { | 490 | } else { |
544 | svb->flags |= V4L2_BUF_FLAG_PFRAME; | 491 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_PFRAME; |
492 | vb2_set_plane_payload(vb, 0, vh->mpeg_size); | ||
545 | } | 493 | } |
546 | 494 | ||
547 | /* Now get the actual mpeg payload */ | 495 | /* Now get the actual mpeg payload */ |
@@ -550,93 +498,67 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer | |||
550 | frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) | 498 | frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) |
551 | & ~(DMA_ALIGN - 1); | 499 | & ~(DMA_ALIGN - 1); |
552 | 500 | ||
553 | return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, | 501 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, |
554 | SOLO_MP4E_EXT_ADDR(solo_dev), | 502 | DMA_FROM_DEVICE); |
555 | SOLO_MP4E_EXT_SIZE(solo_dev)); | 503 | ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, |
504 | SOLO_MP4E_EXT_ADDR(solo_dev), | ||
505 | SOLO_MP4E_EXT_SIZE(solo_dev)); | ||
506 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sglist, vbuf->num_pages, | ||
507 | DMA_FROM_DEVICE); | ||
508 | return ret; | ||
556 | } | 509 | } |
557 | 510 | ||
558 | static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, | 511 | static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, |
559 | struct videobuf_buffer *vb, | 512 | struct vb2_buffer *vb, struct solo_enc_buf *enc_buf) |
560 | struct solo_enc_buf *enc_buf) | ||
561 | { | 513 | { |
562 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; | ||
563 | struct videobuf_dmabuf *vbuf = NULL; | ||
564 | struct vop_header *vh = enc_buf->vh; | 514 | struct vop_header *vh = enc_buf->vh; |
565 | int ret; | 515 | int ret; |
566 | 516 | ||
567 | vbuf = videobuf_to_dma(vb); | ||
568 | if (WARN_ON_ONCE(!vbuf)) { | ||
569 | ret = -EIO; | ||
570 | goto vbuf_error; | ||
571 | } | ||
572 | |||
573 | /* Setup some common flags for both types */ | ||
574 | svb->flags = V4L2_BUF_FLAG_TIMECODE; | ||
575 | vb->ts.tv_sec = vh->sec; | ||
576 | vb->ts.tv_usec = vh->usec; | ||
577 | |||
578 | /* Check for motion flags */ | 517 | /* Check for motion flags */ |
579 | if (solo_is_motion_on(solo_enc)) { | 518 | if (solo_is_motion_on(solo_enc)) { |
580 | svb->flags |= V4L2_BUF_FLAG_MOTION_ON; | 519 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_MOTION_ON; |
581 | if (enc_buf->motion) | 520 | if (enc_buf->motion) |
582 | svb->flags |= V4L2_BUF_FLAG_MOTION_DETECTED; | 521 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_MOTION_DETECTED; |
583 | } | 522 | } |
584 | 523 | ||
585 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) | 524 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) |
586 | ret = solo_fill_mpeg(solo_enc, vb, vbuf, vh); | 525 | ret = solo_fill_mpeg(solo_enc, vb, vh); |
587 | else | 526 | else |
588 | ret = solo_fill_jpeg(solo_enc, vb, vbuf, vh); | 527 | ret = solo_fill_jpeg(solo_enc, vb, vh); |
589 | |||
590 | vbuf_error: | ||
591 | /* On error, we push this buffer back into the queue. The | ||
592 | * videobuf-core doesn't handle error packets very well. Plus | ||
593 | * we recover nicely internally anyway. */ | ||
594 | if (ret) { | ||
595 | unsigned long flags; | ||
596 | |||
597 | spin_lock_irqsave(&solo_enc->av_lock, flags); | ||
598 | list_add(&vb->queue, &solo_enc->vidq_active); | ||
599 | vb->state = VIDEOBUF_QUEUED; | ||
600 | spin_unlock_irqrestore(&solo_enc->av_lock, flags); | ||
601 | } else { | ||
602 | vb->state = VIDEOBUF_DONE; | ||
603 | vb->field_count++; | ||
604 | vb->width = solo_enc->width; | ||
605 | vb->height = solo_enc->height; | ||
606 | 528 | ||
607 | wake_up(&vb->done); | 529 | if (!ret) { |
530 | vb->v4l2_buf.sequence++; | ||
531 | vb->v4l2_buf.timestamp.tv_sec = vh->sec; | ||
532 | vb->v4l2_buf.timestamp.tv_usec = vh->usec; | ||
608 | } | 533 | } |
609 | 534 | ||
535 | vb2_buffer_done(vb, ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE); | ||
536 | |||
610 | return ret; | 537 | return ret; |
611 | } | 538 | } |
612 | 539 | ||
613 | static void solo_enc_handle_one(struct solo_enc_dev *solo_enc, | 540 | static void solo_enc_handle_one(struct solo_enc_dev *solo_enc, |
614 | struct solo_enc_buf *enc_buf) | 541 | struct solo_enc_buf *enc_buf) |
615 | { | 542 | { |
616 | struct videobuf_buffer *vb; | 543 | struct solo_vb2_buf *vb; |
617 | unsigned long flags; | 544 | unsigned long flags; |
618 | 545 | ||
619 | mutex_lock(&solo_enc->enable_lock); | 546 | mutex_lock(&solo_enc->lock); |
620 | |||
621 | if (solo_enc->type != enc_buf->type) | 547 | if (solo_enc->type != enc_buf->type) |
622 | goto unlock; | 548 | goto unlock; |
623 | 549 | ||
624 | if (list_empty(&solo_enc->vidq_active)) | ||
625 | goto unlock; | ||
626 | |||
627 | spin_lock_irqsave(&solo_enc->av_lock, flags); | 550 | spin_lock_irqsave(&solo_enc->av_lock, flags); |
628 | 551 | if (list_empty(&solo_enc->vidq_active)) { | |
629 | vb = list_first_entry(&solo_enc->vidq_active, | 552 | spin_unlock_irqrestore(&solo_enc->av_lock, flags); |
630 | struct videobuf_buffer, queue); | 553 | goto unlock; |
631 | 554 | } | |
632 | list_del(&vb->queue); | 555 | vb = list_first_entry(&solo_enc->vidq_active, struct solo_vb2_buf, list); |
633 | vb->state = VIDEOBUF_ACTIVE; | 556 | list_del(&vb->list); |
634 | |||
635 | spin_unlock_irqrestore(&solo_enc->av_lock, flags); | 557 | spin_unlock_irqrestore(&solo_enc->av_lock, flags); |
636 | 558 | ||
637 | solo_enc_fillbuf(solo_enc, vb, enc_buf); | 559 | solo_enc_fillbuf(solo_enc, &vb->vb, enc_buf); |
638 | unlock: | 560 | unlock: |
639 | mutex_unlock(&solo_enc->enable_lock); | 561 | mutex_unlock(&solo_enc->lock); |
640 | } | 562 | } |
641 | 563 | ||
642 | void solo_enc_v4l2_isr(struct solo_dev *solo_dev) | 564 | void solo_enc_v4l2_isr(struct solo_dev *solo_dev) |
@@ -723,85 +645,29 @@ static int solo_ring_thread(void *data) | |||
723 | return 0; | 645 | return 0; |
724 | } | 646 | } |
725 | 647 | ||
726 | static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count, | 648 | static int solo_enc_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt, |
727 | unsigned int *size) | 649 | unsigned int *num_buffers, unsigned int *num_planes, |
728 | { | 650 | unsigned int sizes[], void *alloc_ctxs[]) |
729 | *size = FRAME_BUF_SIZE; | ||
730 | |||
731 | if (*count < MIN_VID_BUFFERS) | ||
732 | *count = MIN_VID_BUFFERS; | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | static int solo_enc_buf_prepare(struct videobuf_queue *vq, | ||
738 | struct videobuf_buffer *vb, | ||
739 | enum v4l2_field field) | ||
740 | { | 651 | { |
741 | vb->size = FRAME_BUF_SIZE; | 652 | sizes[0] = FRAME_BUF_SIZE; |
742 | if (vb->baddr != 0 && vb->bsize < vb->size) | 653 | *num_planes = 1; |
743 | return -EINVAL; | ||
744 | |||
745 | /* This property only change when queue is idle */ | ||
746 | vb->field = field; | ||
747 | 654 | ||
748 | if (vb->state == VIDEOBUF_NEEDS_INIT) { | 655 | if (*num_buffers < MIN_VID_BUFFERS) |
749 | int rc = videobuf_iolock(vq, vb, NULL); | 656 | *num_buffers = MIN_VID_BUFFERS; |
750 | if (rc < 0) { | ||
751 | struct videobuf_dmabuf *dma = videobuf_to_dma(vb); | ||
752 | videobuf_dma_unmap(vq->dev, dma); | ||
753 | videobuf_dma_free(dma); | ||
754 | |||
755 | return rc; | ||
756 | } | ||
757 | } | ||
758 | vb->state = VIDEOBUF_PREPARED; | ||
759 | 657 | ||
760 | return 0; | 658 | return 0; |
761 | } | 659 | } |
762 | 660 | ||
763 | static void solo_enc_buf_queue(struct videobuf_queue *vq, | 661 | static void solo_enc_buf_queue(struct vb2_buffer *vb) |
764 | struct videobuf_buffer *vb) | ||
765 | { | 662 | { |
766 | struct solo_enc_dev *solo_enc = vq->priv_data; | 663 | struct vb2_queue *vq = vb->vb2_queue; |
767 | 664 | struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vq); | |
768 | vb->state = VIDEOBUF_QUEUED; | 665 | struct solo_vb2_buf *solo_vb = |
769 | list_add_tail(&vb->queue, &solo_enc->vidq_active); | 666 | container_of(vb, struct solo_vb2_buf, vb); |
770 | } | ||
771 | |||
772 | static void solo_enc_buf_release(struct videobuf_queue *vq, | ||
773 | struct videobuf_buffer *vb) | ||
774 | { | ||
775 | struct videobuf_dmabuf *dma = videobuf_to_dma(vb); | ||
776 | videobuf_dma_unmap(vq->dev, dma); | ||
777 | videobuf_dma_free(dma); | ||
778 | vb->state = VIDEOBUF_NEEDS_INIT; | ||
779 | } | ||
780 | |||
781 | static const struct videobuf_queue_ops solo_enc_video_qops = { | ||
782 | .buf_setup = solo_enc_buf_setup, | ||
783 | .buf_prepare = solo_enc_buf_prepare, | ||
784 | .buf_queue = solo_enc_buf_queue, | ||
785 | .buf_release = solo_enc_buf_release, | ||
786 | }; | ||
787 | 667 | ||
788 | static unsigned int solo_enc_poll(struct file *file, | 668 | spin_lock(&solo_enc->av_lock); |
789 | struct poll_table_struct *wait) | 669 | list_add_tail(&solo_vb->list, &solo_enc->vidq_active); |
790 | { | 670 | spin_unlock(&solo_enc->av_lock); |
791 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
792 | unsigned long req_events = poll_requested_events(wait); | ||
793 | unsigned res = v4l2_ctrl_poll(file, wait); | ||
794 | |||
795 | if (!(req_events & (POLLIN | POLLRDNORM))) | ||
796 | return res; | ||
797 | return videobuf_poll_stream(file, &solo_enc->vidq, wait); | ||
798 | } | ||
799 | |||
800 | static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma) | ||
801 | { | ||
802 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
803 | |||
804 | return videobuf_mmap_mapper(&solo_enc->vidq, vma); | ||
805 | } | 671 | } |
806 | 672 | ||
807 | static int solo_ring_start(struct solo_dev *solo_dev) | 673 | static int solo_ring_start(struct solo_dev *solo_dev) |
@@ -835,50 +701,36 @@ static void solo_ring_stop(struct solo_dev *solo_dev) | |||
835 | solo_irq_off(solo_dev, SOLO_IRQ_ENCODER); | 701 | solo_irq_off(solo_dev, SOLO_IRQ_ENCODER); |
836 | } | 702 | } |
837 | 703 | ||
838 | static int solo_enc_open(struct file *file) | 704 | static int solo_enc_start_streaming(struct vb2_queue *q, unsigned int count) |
839 | { | 705 | { |
840 | struct solo_enc_dev *solo_enc = video_drvdata(file); | 706 | struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); |
841 | struct solo_dev *solo_dev = solo_enc->solo_dev; | ||
842 | int ret = v4l2_fh_open(file); | ||
843 | |||
844 | if (ret) | ||
845 | return ret; | ||
846 | ret = solo_ring_start(solo_dev); | ||
847 | if (ret) { | ||
848 | v4l2_fh_release(file); | ||
849 | return ret; | ||
850 | } | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static ssize_t solo_enc_read(struct file *file, char __user *data, | ||
855 | size_t count, loff_t *ppos) | ||
856 | { | ||
857 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
858 | int ret; | 707 | int ret; |
859 | 708 | ||
860 | /* Make sure the encoder is on */ | ||
861 | ret = solo_enc_on(solo_enc); | 709 | ret = solo_enc_on(solo_enc); |
862 | if (ret) | 710 | if (ret) |
863 | return ret; | 711 | return ret; |
864 | 712 | return solo_ring_start(solo_enc->solo_dev); | |
865 | return videobuf_read_stream(&solo_enc->vidq, data, count, ppos, 0, | ||
866 | file->f_flags & O_NONBLOCK); | ||
867 | } | 713 | } |
868 | 714 | ||
869 | static int solo_enc_release(struct file *file) | 715 | static int solo_enc_stop_streaming(struct vb2_queue *q) |
870 | { | 716 | { |
871 | struct solo_enc_dev *solo_enc = video_drvdata(file); | 717 | struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q); |
872 | struct solo_dev *solo_dev = solo_enc->solo_dev; | ||
873 | 718 | ||
874 | solo_enc_off(solo_enc); | 719 | solo_enc_off(solo_enc); |
875 | videobuf_stop(&solo_enc->vidq); | 720 | INIT_LIST_HEAD(&solo_enc->vidq_active); |
876 | videobuf_mmap_free(&solo_enc->vidq); | 721 | solo_ring_stop(solo_enc->solo_dev); |
877 | solo_ring_stop(solo_dev); | 722 | return 0; |
878 | |||
879 | return v4l2_fh_release(file); | ||
880 | } | 723 | } |
881 | 724 | ||
725 | static struct vb2_ops solo_enc_video_qops = { | ||
726 | .queue_setup = solo_enc_queue_setup, | ||
727 | .buf_queue = solo_enc_buf_queue, | ||
728 | .start_streaming = solo_enc_start_streaming, | ||
729 | .stop_streaming = solo_enc_stop_streaming, | ||
730 | .wait_prepare = vb2_ops_wait_prepare, | ||
731 | .wait_finish = vb2_ops_wait_finish, | ||
732 | }; | ||
733 | |||
882 | static int solo_enc_querycap(struct file *file, void *priv, | 734 | static int solo_enc_querycap(struct file *file, void *priv, |
883 | struct v4l2_capability *cap) | 735 | struct v4l2_capability *cap) |
884 | { | 736 | { |
@@ -1007,23 +859,13 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, | |||
1007 | struct v4l2_pix_format *pix = &f->fmt.pix; | 859 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1008 | int ret; | 860 | int ret; |
1009 | 861 | ||
1010 | mutex_lock(&solo_enc->enable_lock); | 862 | if (vb2_is_busy(&solo_enc->vidq)) |
863 | return -EBUSY; | ||
1011 | 864 | ||
1012 | ret = solo_enc_try_fmt_cap(file, priv, f); | 865 | ret = solo_enc_try_fmt_cap(file, priv, f); |
1013 | if (ret) | 866 | if (ret) |
1014 | return ret; | 867 | return ret; |
1015 | 868 | ||
1016 | /* We cannot change width/height in mid read */ | ||
1017 | if (!ret && atomic_read(&solo_enc->readers) > 0) { | ||
1018 | if (pix->width != solo_enc->width || | ||
1019 | pix->height != solo_enc->height) | ||
1020 | ret = -EBUSY; | ||
1021 | } | ||
1022 | if (ret) { | ||
1023 | mutex_unlock(&solo_enc->enable_lock); | ||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | if (pix->width == solo_dev->video_hsize) | 869 | if (pix->width == solo_dev->video_hsize) |
1028 | solo_enc->mode = SOLO_ENC_MODE_D1; | 870 | solo_enc->mode = SOLO_ENC_MODE_D1; |
1029 | else | 871 | else |
@@ -1034,9 +876,6 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, | |||
1034 | 876 | ||
1035 | if (pix->priv) | 877 | if (pix->priv) |
1036 | solo_enc->type = SOLO_ENC_TYPE_EXT; | 878 | solo_enc->type = SOLO_ENC_TYPE_EXT; |
1037 | |||
1038 | mutex_unlock(&solo_enc->enable_lock); | ||
1039 | |||
1040 | return 0; | 879 | return 0; |
1041 | } | 880 | } |
1042 | 881 | ||
@@ -1058,80 +897,6 @@ static int solo_enc_get_fmt_cap(struct file *file, void *priv, | |||
1058 | return 0; | 897 | return 0; |
1059 | } | 898 | } |
1060 | 899 | ||
1061 | static int solo_enc_reqbufs(struct file *file, void *priv, | ||
1062 | struct v4l2_requestbuffers *req) | ||
1063 | { | ||
1064 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
1065 | |||
1066 | return videobuf_reqbufs(&solo_enc->vidq, req); | ||
1067 | } | ||
1068 | |||
1069 | static int solo_enc_querybuf(struct file *file, void *priv, | ||
1070 | struct v4l2_buffer *buf) | ||
1071 | { | ||
1072 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
1073 | |||
1074 | return videobuf_querybuf(&solo_enc->vidq, buf); | ||
1075 | } | ||
1076 | |||
1077 | static int solo_enc_qbuf(struct file *file, void *priv, | ||
1078 | struct v4l2_buffer *buf) | ||
1079 | { | ||
1080 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
1081 | |||
1082 | return videobuf_qbuf(&solo_enc->vidq, buf); | ||
1083 | } | ||
1084 | |||
1085 | static int solo_enc_dqbuf(struct file *file, void *priv, | ||
1086 | struct v4l2_buffer *buf) | ||
1087 | { | ||
1088 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
1089 | struct solo_videobuf *svb; | ||
1090 | int ret; | ||
1091 | |||
1092 | /* Make sure the encoder is on */ | ||
1093 | ret = solo_enc_on(solo_enc); | ||
1094 | if (ret) | ||
1095 | return ret; | ||
1096 | |||
1097 | ret = videobuf_dqbuf(&solo_enc->vidq, buf, file->f_flags & O_NONBLOCK); | ||
1098 | if (ret) | ||
1099 | return ret; | ||
1100 | |||
1101 | /* Copy over the flags */ | ||
1102 | svb = (struct solo_videobuf *)solo_enc->vidq.bufs[buf->index]; | ||
1103 | buf->flags |= svb->flags; | ||
1104 | |||
1105 | return 0; | ||
1106 | } | ||
1107 | |||
1108 | static int solo_enc_streamon(struct file *file, void *priv, | ||
1109 | enum v4l2_buf_type i) | ||
1110 | { | ||
1111 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
1112 | |||
1113 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1114 | return -EINVAL; | ||
1115 | |||
1116 | return videobuf_streamon(&solo_enc->vidq); | ||
1117 | } | ||
1118 | |||
1119 | static int solo_enc_streamoff(struct file *file, void *priv, | ||
1120 | enum v4l2_buf_type i) | ||
1121 | { | ||
1122 | struct solo_enc_dev *solo_enc = video_drvdata(file); | ||
1123 | int ret; | ||
1124 | |||
1125 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1126 | return -EINVAL; | ||
1127 | |||
1128 | ret = videobuf_streamoff(&solo_enc->vidq); | ||
1129 | if (!ret) | ||
1130 | solo_enc_off(solo_enc); | ||
1131 | |||
1132 | return ret; | ||
1133 | } | ||
1134 | |||
1135 | static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id i) | 900 | static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id i) |
1136 | { | 901 | { |
1137 | return 0; | 902 | return 0; |
@@ -1220,12 +985,8 @@ static int solo_s_parm(struct file *file, void *priv, | |||
1220 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 985 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1221 | struct v4l2_captureparm *cp = &sp->parm.capture; | 986 | struct v4l2_captureparm *cp = &sp->parm.capture; |
1222 | 987 | ||
1223 | mutex_lock(&solo_enc->enable_lock); | 988 | if (vb2_is_streaming(&solo_enc->vidq)) |
1224 | |||
1225 | if (atomic_read(&solo_enc->mpeg_readers) > 0) { | ||
1226 | mutex_unlock(&solo_enc->enable_lock); | ||
1227 | return -EBUSY; | 989 | return -EBUSY; |
1228 | } | ||
1229 | 990 | ||
1230 | if ((cp->timeperframe.numerator == 0) || | 991 | if ((cp->timeperframe.numerator == 0) || |
1231 | (cp->timeperframe.denominator == 0)) { | 992 | (cp->timeperframe.denominator == 0)) { |
@@ -1246,9 +1007,6 @@ static int solo_s_parm(struct file *file, void *priv, | |||
1246 | cp->readbuffers = 2; | 1007 | cp->readbuffers = 2; |
1247 | 1008 | ||
1248 | solo_update_mode(solo_enc); | 1009 | solo_update_mode(solo_enc); |
1249 | |||
1250 | mutex_unlock(&solo_enc->enable_lock); | ||
1251 | |||
1252 | return 0; | 1010 | return 0; |
1253 | } | 1011 | } |
1254 | 1012 | ||
@@ -1297,10 +1055,8 @@ static int solo_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1297 | solo_motion_toggle(solo_enc, ctrl->val); | 1055 | solo_motion_toggle(solo_enc, ctrl->val); |
1298 | return 0; | 1056 | return 0; |
1299 | case V4L2_CID_OSD_TEXT: | 1057 | case V4L2_CID_OSD_TEXT: |
1300 | mutex_lock(&solo_enc->enable_lock); | ||
1301 | strcpy(solo_enc->osd_text, ctrl->string); | 1058 | strcpy(solo_enc->osd_text, ctrl->string); |
1302 | err = solo_osd_print(solo_enc); | 1059 | err = solo_osd_print(solo_enc); |
1303 | mutex_unlock(&solo_enc->enable_lock); | ||
1304 | return err; | 1060 | return err; |
1305 | default: | 1061 | default: |
1306 | return -EINVAL; | 1062 | return -EINVAL; |
@@ -1311,12 +1067,12 @@ static int solo_s_ctrl(struct v4l2_ctrl *ctrl) | |||
1311 | 1067 | ||
1312 | static const struct v4l2_file_operations solo_enc_fops = { | 1068 | static const struct v4l2_file_operations solo_enc_fops = { |
1313 | .owner = THIS_MODULE, | 1069 | .owner = THIS_MODULE, |
1314 | .open = solo_enc_open, | 1070 | .open = v4l2_fh_open, |
1315 | .release = solo_enc_release, | 1071 | .release = vb2_fop_release, |
1316 | .read = solo_enc_read, | 1072 | .read = vb2_fop_read, |
1317 | .poll = solo_enc_poll, | 1073 | .poll = vb2_fop_poll, |
1318 | .mmap = solo_enc_mmap, | 1074 | .mmap = vb2_fop_mmap, |
1319 | .ioctl = video_ioctl2, | 1075 | .unlocked_ioctl = video_ioctl2, |
1320 | }; | 1076 | }; |
1321 | 1077 | ||
1322 | static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { | 1078 | static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { |
@@ -1332,12 +1088,12 @@ static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = { | |||
1332 | .vidioc_s_fmt_vid_cap = solo_enc_set_fmt_cap, | 1088 | .vidioc_s_fmt_vid_cap = solo_enc_set_fmt_cap, |
1333 | .vidioc_g_fmt_vid_cap = solo_enc_get_fmt_cap, | 1089 | .vidioc_g_fmt_vid_cap = solo_enc_get_fmt_cap, |
1334 | /* Streaming I/O */ | 1090 | /* Streaming I/O */ |
1335 | .vidioc_reqbufs = solo_enc_reqbufs, | 1091 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
1336 | .vidioc_querybuf = solo_enc_querybuf, | 1092 | .vidioc_querybuf = vb2_ioctl_querybuf, |
1337 | .vidioc_qbuf = solo_enc_qbuf, | 1093 | .vidioc_qbuf = vb2_ioctl_qbuf, |
1338 | .vidioc_dqbuf = solo_enc_dqbuf, | 1094 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
1339 | .vidioc_streamon = solo_enc_streamon, | 1095 | .vidioc_streamon = vb2_ioctl_streamon, |
1340 | .vidioc_streamoff = solo_enc_streamoff, | 1096 | .vidioc_streamoff = vb2_ioctl_streamoff, |
1341 | /* Frame size and interval */ | 1097 | /* Frame size and interval */ |
1342 | .vidioc_enum_framesizes = solo_enum_framesizes, | 1098 | .vidioc_enum_framesizes = solo_enum_framesizes, |
1343 | .vidioc_enum_frameintervals = solo_enum_frameintervals, | 1099 | .vidioc_enum_frameintervals = solo_enum_frameintervals, |
@@ -1434,29 +1190,36 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, | |||
1434 | 1190 | ||
1435 | solo_enc->solo_dev = solo_dev; | 1191 | solo_enc->solo_dev = solo_dev; |
1436 | solo_enc->ch = ch; | 1192 | solo_enc->ch = ch; |
1193 | mutex_init(&solo_enc->lock); | ||
1437 | spin_lock_init(&solo_enc->av_lock); | 1194 | spin_lock_init(&solo_enc->av_lock); |
1438 | INIT_LIST_HEAD(&solo_enc->vidq_active); | 1195 | INIT_LIST_HEAD(&solo_enc->vidq_active); |
1439 | solo_enc->fmt = V4L2_PIX_FMT_MPEG; | 1196 | solo_enc->fmt = V4L2_PIX_FMT_MPEG; |
1440 | solo_enc->type = SOLO_ENC_TYPE_STD; | 1197 | solo_enc->type = SOLO_ENC_TYPE_STD; |
1441 | 1198 | ||
1442 | atomic_set(&solo_enc->readers, 0); | ||
1443 | |||
1444 | solo_enc->qp = SOLO_DEFAULT_QP; | 1199 | solo_enc->qp = SOLO_DEFAULT_QP; |
1445 | solo_enc->gop = solo_dev->fps; | 1200 | solo_enc->gop = solo_dev->fps; |
1446 | solo_enc->interval = 1; | 1201 | solo_enc->interval = 1; |
1447 | solo_enc->mode = SOLO_ENC_MODE_CIF; | 1202 | solo_enc->mode = SOLO_ENC_MODE_CIF; |
1448 | solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; | 1203 | solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; |
1449 | 1204 | ||
1205 | solo_enc->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1206 | solo_enc->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; | ||
1207 | solo_enc->vidq.ops = &solo_enc_video_qops; | ||
1208 | solo_enc->vidq.mem_ops = &vb2_dma_sg_memops; | ||
1209 | solo_enc->vidq.drv_priv = solo_enc; | ||
1210 | solo_enc->vidq.gfp_flags = __GFP_DMA32; | ||
1211 | solo_enc->vidq.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | ||
1212 | solo_enc->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); | ||
1213 | solo_enc->vidq.lock = &solo_enc->lock; | ||
1214 | ret = vb2_queue_init(&solo_enc->vidq); | ||
1215 | if (ret) | ||
1216 | goto hdl_free; | ||
1450 | spin_lock(&solo_enc->av_lock); | 1217 | spin_lock(&solo_enc->av_lock); |
1451 | solo_update_mode(solo_enc); | 1218 | solo_update_mode(solo_enc); |
1452 | spin_unlock(&solo_enc->av_lock); | 1219 | spin_unlock(&solo_enc->av_lock); |
1453 | 1220 | ||
1454 | mutex_init(&solo_enc->enable_lock); | ||
1455 | spin_lock_init(&solo_enc->motion_lock); | 1221 | spin_lock_init(&solo_enc->motion_lock); |
1456 | 1222 | ||
1457 | atomic_set(&solo_enc->readers, 0); | ||
1458 | atomic_set(&solo_enc->mpeg_readers, 0); | ||
1459 | |||
1460 | /* Initialize this per encoder */ | 1223 | /* Initialize this per encoder */ |
1461 | solo_enc->jpeg_len = sizeof(jpeg_header); | 1224 | solo_enc->jpeg_len = sizeof(jpeg_header); |
1462 | memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len); | 1225 | memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len); |
@@ -1469,14 +1232,6 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, | |||
1469 | if (solo_enc->desc_items == NULL) | 1232 | if (solo_enc->desc_items == NULL) |
1470 | goto hdl_free; | 1233 | goto hdl_free; |
1471 | 1234 | ||
1472 | videobuf_queue_sg_init(&solo_enc->vidq, &solo_enc_video_qops, | ||
1473 | &solo_dev->pdev->dev, | ||
1474 | &solo_enc->av_lock, | ||
1475 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
1476 | V4L2_FIELD_INTERLACED, | ||
1477 | sizeof(struct solo_videobuf), | ||
1478 | solo_enc, NULL); | ||
1479 | |||
1480 | solo_enc->vfd = video_device_alloc(); | 1235 | solo_enc->vfd = video_device_alloc(); |
1481 | if (!solo_enc->vfd) | 1236 | if (!solo_enc->vfd) |
1482 | goto pci_free; | 1237 | goto pci_free; |
@@ -1484,6 +1239,8 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, | |||
1484 | *solo_enc->vfd = solo_enc_template; | 1239 | *solo_enc->vfd = solo_enc_template; |
1485 | solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; | 1240 | solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; |
1486 | solo_enc->vfd->ctrl_handler = hdl; | 1241 | solo_enc->vfd->ctrl_handler = hdl; |
1242 | solo_enc->vfd->queue = &solo_enc->vidq; | ||
1243 | solo_enc->vfd->lock = &solo_enc->lock; | ||
1487 | set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags); | 1244 | set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags); |
1488 | video_set_drvdata(solo_enc->vfd, solo_enc); | 1245 | video_set_drvdata(solo_enc->vfd, solo_enc); |
1489 | ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); | 1246 | ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); |