diff options
-rw-r--r-- | drivers/staging/media/solo6x10/solo6x10.h | 17 | ||||
-rw-r--r-- | drivers/staging/media/solo6x10/v4l2-enc.c | 379 |
2 files changed, 175 insertions, 221 deletions
diff --git a/drivers/staging/media/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h index 830359f3bb16..413ee10e691e 100644 --- a/drivers/staging/media/solo6x10/solo6x10.h +++ b/drivers/staging/media/solo6x10/solo6x10.h | |||
@@ -135,6 +135,11 @@ struct solo_p2m_dev { | |||
135 | 135 | ||
136 | #define OSD_TEXT_MAX 44 | 136 | #define OSD_TEXT_MAX 44 |
137 | 137 | ||
138 | enum solo_enc_types { | ||
139 | SOLO_ENC_TYPE_STD, | ||
140 | SOLO_ENC_TYPE_EXT, | ||
141 | }; | ||
142 | |||
138 | struct solo_enc_dev { | 143 | struct solo_enc_dev { |
139 | struct solo_dev *solo_dev; | 144 | struct solo_dev *solo_dev; |
140 | /* V4L2 Items */ | 145 | /* V4L2 Items */ |
@@ -163,8 +168,16 @@ struct solo_enc_dev { | |||
163 | unsigned char jpeg_header[1024]; | 168 | unsigned char jpeg_header[1024]; |
164 | int jpeg_len; | 169 | int jpeg_len; |
165 | 170 | ||
166 | /* File handles that are listening for buffers */ | 171 | u32 fmt; |
167 | struct list_head listeners; | 172 | u8 enc_on; |
173 | enum solo_enc_types type; | ||
174 | struct videobuf_queue vidq; | ||
175 | struct list_head vidq_active; | ||
176 | int desc_count; | ||
177 | int desc_nelts; | ||
178 | struct solo_p2m_desc *desc_items; | ||
179 | dma_addr_t desc_dma; | ||
180 | spinlock_t av_lock; | ||
168 | }; | 181 | }; |
169 | 182 | ||
170 | /* The SOLO6x10 PCI Device */ | 183 | /* The SOLO6x10 PCI Device */ |
diff --git a/drivers/staging/media/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c index 7cf3e7b8725f..546a18b31328 100644 --- a/drivers/staging/media/solo6x10/v4l2-enc.c +++ b/drivers/staging/media/solo6x10/v4l2-enc.c | |||
@@ -41,27 +41,6 @@ | |||
41 | #define MP4_QS 16 | 41 | #define MP4_QS 16 |
42 | #define DMA_ALIGN 4096 | 42 | #define DMA_ALIGN 4096 |
43 | 43 | ||
44 | enum solo_enc_types { | ||
45 | SOLO_ENC_TYPE_STD, | ||
46 | SOLO_ENC_TYPE_EXT, | ||
47 | }; | ||
48 | |||
49 | struct solo_enc_fh { | ||
50 | struct v4l2_fh fh; | ||
51 | struct solo_enc_dev *enc; | ||
52 | u32 fmt; | ||
53 | u8 enc_on; | ||
54 | enum solo_enc_types type; | ||
55 | struct videobuf_queue vidq; | ||
56 | struct list_head vidq_active; | ||
57 | int desc_count; | ||
58 | int desc_nelts; | ||
59 | struct solo_p2m_desc *desc_items; | ||
60 | dma_addr_t desc_dma; | ||
61 | spinlock_t av_lock; | ||
62 | struct list_head list; | ||
63 | }; | ||
64 | |||
65 | struct solo_videobuf { | 44 | struct solo_videobuf { |
66 | struct videobuf_buffer vb; | 45 | struct videobuf_buffer vb; |
67 | unsigned int flags; | 46 | unsigned int flags; |
@@ -286,16 +265,15 @@ static void solo_update_mode(struct solo_enc_dev *solo_enc) | |||
286 | } | 265 | } |
287 | 266 | ||
288 | /* MUST be called with solo_enc->enable_lock held */ | 267 | /* MUST be called with solo_enc->enable_lock held */ |
289 | static int __solo_enc_on(struct solo_enc_fh *fh) | 268 | static int __solo_enc_on(struct solo_enc_dev *solo_enc) |
290 | { | 269 | { |
291 | struct solo_enc_dev *solo_enc = fh->enc; | ||
292 | u8 ch = solo_enc->ch; | 270 | u8 ch = solo_enc->ch; |
293 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 271 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
294 | u8 interval; | 272 | u8 interval; |
295 | 273 | ||
296 | BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); | 274 | BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); |
297 | 275 | ||
298 | if (fh->enc_on) | 276 | if (solo_enc->enc_on) |
299 | return 0; | 277 | return 0; |
300 | 278 | ||
301 | solo_update_mode(solo_enc); | 279 | solo_update_mode(solo_enc); |
@@ -308,15 +286,14 @@ static int __solo_enc_on(struct solo_enc_fh *fh) | |||
308 | solo_dev->enc_bw_remain -= solo_enc->bw_weight; | 286 | solo_dev->enc_bw_remain -= solo_enc->bw_weight; |
309 | } | 287 | } |
310 | 288 | ||
311 | fh->enc_on = 1; | 289 | solo_enc->enc_on = 1; |
312 | list_add(&fh->list, &solo_enc->listeners); | ||
313 | 290 | ||
314 | if (fh->type == SOLO_ENC_TYPE_EXT) | 291 | if (solo_enc->type == SOLO_ENC_TYPE_EXT) |
315 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); | 292 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(ch), 1); |
316 | 293 | ||
317 | /* Reset the encoder if we are the first mpeg reader, else only reset | 294 | /* Reset the encoder if we are the first mpeg reader, else only reset |
318 | * on the first mjpeg reader. */ | 295 | * on the first mjpeg reader. */ |
319 | if (fh->fmt == V4L2_PIX_FMT_MPEG) { | 296 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) { |
320 | atomic_inc(&solo_enc->readers); | 297 | atomic_inc(&solo_enc->readers); |
321 | if (atomic_inc_return(&solo_enc->mpeg_readers) > 1) | 298 | if (atomic_inc_return(&solo_enc->mpeg_readers) > 1) |
322 | return 0; | 299 | return 0; |
@@ -352,32 +329,29 @@ static int __solo_enc_on(struct solo_enc_fh *fh) | |||
352 | return 0; | 329 | return 0; |
353 | } | 330 | } |
354 | 331 | ||
355 | static int solo_enc_on(struct solo_enc_fh *fh) | 332 | static int solo_enc_on(struct solo_enc_dev *solo_enc) |
356 | { | 333 | { |
357 | struct solo_enc_dev *solo_enc = fh->enc; | ||
358 | int ret; | 334 | int ret; |
359 | 335 | ||
360 | mutex_lock(&solo_enc->enable_lock); | 336 | mutex_lock(&solo_enc->enable_lock); |
361 | ret = __solo_enc_on(fh); | 337 | ret = __solo_enc_on(solo_enc); |
362 | mutex_unlock(&solo_enc->enable_lock); | 338 | mutex_unlock(&solo_enc->enable_lock); |
363 | 339 | ||
364 | return ret; | 340 | return ret; |
365 | } | 341 | } |
366 | 342 | ||
367 | static void __solo_enc_off(struct solo_enc_fh *fh) | 343 | static void __solo_enc_off(struct solo_enc_dev *solo_enc) |
368 | { | 344 | { |
369 | struct solo_enc_dev *solo_enc = fh->enc; | ||
370 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 345 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
371 | 346 | ||
372 | BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); | 347 | BUG_ON(!mutex_is_locked(&solo_enc->enable_lock)); |
373 | 348 | ||
374 | if (!fh->enc_on) | 349 | if (!solo_enc->enc_on) |
375 | return; | 350 | return; |
376 | 351 | ||
377 | list_del(&fh->list); | 352 | solo_enc->enc_on = 0; |
378 | fh->enc_on = 0; | ||
379 | 353 | ||
380 | if (fh->fmt == V4L2_PIX_FMT_MPEG) | 354 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) |
381 | atomic_dec(&solo_enc->mpeg_readers); | 355 | atomic_dec(&solo_enc->mpeg_readers); |
382 | 356 | ||
383 | if (atomic_dec_return(&solo_enc->readers) > 0) | 357 | if (atomic_dec_return(&solo_enc->readers) > 0) |
@@ -389,12 +363,10 @@ static void __solo_enc_off(struct solo_enc_fh *fh) | |||
389 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); | 363 | solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); |
390 | } | 364 | } |
391 | 365 | ||
392 | static void solo_enc_off(struct solo_enc_fh *fh) | 366 | static void solo_enc_off(struct solo_enc_dev *solo_enc) |
393 | { | 367 | { |
394 | struct solo_enc_dev *solo_enc = fh->enc; | ||
395 | |||
396 | mutex_lock(&solo_enc->enable_lock); | 368 | mutex_lock(&solo_enc->enable_lock); |
397 | __solo_enc_off(fh); | 369 | __solo_enc_off(solo_enc); |
398 | mutex_unlock(&solo_enc->enable_lock); | 370 | mutex_unlock(&solo_enc->enable_lock); |
399 | } | 371 | } |
400 | 372 | ||
@@ -430,11 +402,11 @@ static int enc_get_mpeg_dma(struct solo_dev *solo_dev, dma_addr_t dma, | |||
430 | 402 | ||
431 | /* Build a descriptor queue out of an SG list and send it to the P2M for | 403 | /* Build a descriptor queue out of an SG list and send it to the P2M for |
432 | * processing. */ | 404 | * processing. */ |
433 | static int solo_send_desc(struct solo_enc_fh *fh, int skip, | 405 | static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip, |
434 | struct videobuf_dmabuf *vbuf, int off, int size, | 406 | struct videobuf_dmabuf *vbuf, int off, int size, |
435 | unsigned int base, unsigned int base_size) | 407 | unsigned int base, unsigned int base_size) |
436 | { | 408 | { |
437 | struct solo_dev *solo_dev = fh->enc->solo_dev; | 409 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
438 | struct scatterlist *sg; | 410 | struct scatterlist *sg; |
439 | int i; | 411 | int i; |
440 | int ret; | 412 | int ret; |
@@ -442,7 +414,7 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip, | |||
442 | if (WARN_ON_ONCE(size > FRAME_BUF_SIZE)) | 414 | if (WARN_ON_ONCE(size > FRAME_BUF_SIZE)) |
443 | return -EINVAL; | 415 | return -EINVAL; |
444 | 416 | ||
445 | fh->desc_count = 1; | 417 | solo_enc->desc_count = 1; |
446 | 418 | ||
447 | for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { | 419 | for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { |
448 | struct solo_p2m_desc *desc; | 420 | struct solo_p2m_desc *desc; |
@@ -450,7 +422,7 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip, | |||
450 | int len; | 422 | int len; |
451 | int left = base_size - off; | 423 | int left = base_size - off; |
452 | 424 | ||
453 | desc = &fh->desc_items[fh->desc_count++]; | 425 | desc = &solo_enc->desc_items[solo_enc->desc_count++]; |
454 | dma = sg_dma_address(sg); | 426 | dma = sg_dma_address(sg); |
455 | len = sg_dma_len(sg); | 427 | len = sg_dma_len(sg); |
456 | 428 | ||
@@ -486,7 +458,7 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip, | |||
486 | if (ret) | 458 | if (ret) |
487 | return ret; | 459 | return ret; |
488 | 460 | ||
489 | fh->desc_count--; | 461 | solo_enc->desc_count--; |
490 | } | 462 | } |
491 | 463 | ||
492 | size -= len; | 464 | size -= len; |
@@ -498,27 +470,26 @@ static int solo_send_desc(struct solo_enc_fh *fh, int skip, | |||
498 | off -= base_size; | 470 | off -= base_size; |
499 | 471 | ||
500 | /* Because we may use two descriptors per loop */ | 472 | /* Because we may use two descriptors per loop */ |
501 | if (fh->desc_count >= (fh->desc_nelts - 1)) { | 473 | if (solo_enc->desc_count >= (solo_enc->desc_nelts - 1)) { |
502 | ret = solo_p2m_dma_desc(solo_dev, fh->desc_items, | 474 | ret = solo_p2m_dma_desc(solo_dev, solo_enc->desc_items, |
503 | fh->desc_dma, | 475 | solo_enc->desc_dma, |
504 | fh->desc_count - 1); | 476 | solo_enc->desc_count - 1); |
505 | if (ret) | 477 | if (ret) |
506 | return ret; | 478 | return ret; |
507 | fh->desc_count = 1; | 479 | solo_enc->desc_count = 1; |
508 | } | 480 | } |
509 | } | 481 | } |
510 | 482 | ||
511 | if (fh->desc_count <= 1) | 483 | if (solo_enc->desc_count <= 1) |
512 | return 0; | 484 | return 0; |
513 | 485 | ||
514 | return solo_p2m_dma_desc(solo_dev, fh->desc_items, fh->desc_dma, | 486 | return solo_p2m_dma_desc(solo_dev, solo_enc->desc_items, solo_enc->desc_dma, |
515 | fh->desc_count - 1); | 487 | solo_enc->desc_count - 1); |
516 | } | 488 | } |
517 | 489 | ||
518 | static int solo_fill_jpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb, | 490 | static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb, |
519 | struct videobuf_dmabuf *vbuf, struct vop_header *vh) | 491 | struct videobuf_dmabuf *vbuf, struct vop_header *vh) |
520 | { | 492 | { |
521 | struct solo_enc_dev *solo_enc = fh->enc; | ||
522 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 493 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
523 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; | 494 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; |
524 | int frame_size; | 495 | int frame_size; |
@@ -539,15 +510,14 @@ static int solo_fill_jpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb, | |||
539 | frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) | 510 | frame_size = (vh->jpeg_size + solo_enc->jpeg_len + (DMA_ALIGN - 1)) |
540 | & ~(DMA_ALIGN - 1); | 511 | & ~(DMA_ALIGN - 1); |
541 | 512 | ||
542 | return solo_send_desc(fh, solo_enc->jpeg_len, vbuf, vh->jpeg_off, | 513 | return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, vh->jpeg_off, |
543 | frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), | 514 | frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), |
544 | SOLO_JPEG_EXT_SIZE(solo_dev)); | 515 | SOLO_JPEG_EXT_SIZE(solo_dev)); |
545 | } | 516 | } |
546 | 517 | ||
547 | static int solo_fill_mpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb, | 518 | static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, struct videobuf_buffer *vb, |
548 | struct videobuf_dmabuf *vbuf, struct vop_header *vh) | 519 | struct videobuf_dmabuf *vbuf, struct vop_header *vh) |
549 | { | 520 | { |
550 | struct solo_enc_dev *solo_enc = fh->enc; | ||
551 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 521 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
552 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; | 522 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; |
553 | int frame_off, frame_size; | 523 | int frame_off, frame_size; |
@@ -580,16 +550,15 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct videobuf_buffer *vb, | |||
580 | frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) | 550 | frame_size = (vh->mpeg_size + skip + (DMA_ALIGN - 1)) |
581 | & ~(DMA_ALIGN - 1); | 551 | & ~(DMA_ALIGN - 1); |
582 | 552 | ||
583 | return solo_send_desc(fh, skip, vbuf, frame_off, frame_size, | 553 | return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, |
584 | SOLO_MP4E_EXT_ADDR(solo_dev), | 554 | SOLO_MP4E_EXT_ADDR(solo_dev), |
585 | SOLO_MP4E_EXT_SIZE(solo_dev)); | 555 | SOLO_MP4E_EXT_SIZE(solo_dev)); |
586 | } | 556 | } |
587 | 557 | ||
588 | static int solo_enc_fillbuf(struct solo_enc_fh *fh, | 558 | static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, |
589 | struct videobuf_buffer *vb, | 559 | struct videobuf_buffer *vb, |
590 | struct solo_enc_buf *enc_buf) | 560 | struct solo_enc_buf *enc_buf) |
591 | { | 561 | { |
592 | struct solo_enc_dev *solo_enc = fh->enc; | ||
593 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; | 562 | struct solo_videobuf *svb = (struct solo_videobuf *)vb; |
594 | struct videobuf_dmabuf *vbuf = NULL; | 563 | struct videobuf_dmabuf *vbuf = NULL; |
595 | struct vop_header *vh = enc_buf->vh; | 564 | struct vop_header *vh = enc_buf->vh; |
@@ -613,10 +582,10 @@ static int solo_enc_fillbuf(struct solo_enc_fh *fh, | |||
613 | svb->flags |= V4L2_BUF_FLAG_MOTION_DETECTED; | 582 | svb->flags |= V4L2_BUF_FLAG_MOTION_DETECTED; |
614 | } | 583 | } |
615 | 584 | ||
616 | if (fh->fmt == V4L2_PIX_FMT_MPEG) | 585 | if (solo_enc->fmt == V4L2_PIX_FMT_MPEG) |
617 | ret = solo_fill_mpeg(fh, vb, vbuf, vh); | 586 | ret = solo_fill_mpeg(solo_enc, vb, vbuf, vh); |
618 | else | 587 | else |
619 | ret = solo_fill_jpeg(fh, vb, vbuf, vh); | 588 | ret = solo_fill_jpeg(solo_enc, vb, vbuf, vh); |
620 | 589 | ||
621 | vbuf_error: | 590 | vbuf_error: |
622 | /* On error, we push this buffer back into the queue. The | 591 | /* On error, we push this buffer back into the queue. The |
@@ -625,10 +594,10 @@ vbuf_error: | |||
625 | if (ret) { | 594 | if (ret) { |
626 | unsigned long flags; | 595 | unsigned long flags; |
627 | 596 | ||
628 | spin_lock_irqsave(&fh->av_lock, flags); | 597 | spin_lock_irqsave(&solo_enc->av_lock, flags); |
629 | list_add(&vb->queue, &fh->vidq_active); | 598 | list_add(&vb->queue, &solo_enc->vidq_active); |
630 | vb->state = VIDEOBUF_QUEUED; | 599 | vb->state = VIDEOBUF_QUEUED; |
631 | spin_unlock_irqrestore(&fh->av_lock, flags); | 600 | spin_unlock_irqrestore(&solo_enc->av_lock, flags); |
632 | } else { | 601 | } else { |
633 | vb->state = VIDEOBUF_DONE; | 602 | vb->state = VIDEOBUF_DONE; |
634 | vb->field_count++; | 603 | vb->field_count++; |
@@ -644,34 +613,29 @@ vbuf_error: | |||
644 | static void solo_enc_handle_one(struct solo_enc_dev *solo_enc, | 613 | static void solo_enc_handle_one(struct solo_enc_dev *solo_enc, |
645 | struct solo_enc_buf *enc_buf) | 614 | struct solo_enc_buf *enc_buf) |
646 | { | 615 | { |
647 | struct solo_enc_fh *fh; | 616 | struct videobuf_buffer *vb; |
617 | unsigned long flags; | ||
648 | 618 | ||
649 | mutex_lock(&solo_enc->enable_lock); | 619 | mutex_lock(&solo_enc->enable_lock); |
650 | 620 | ||
651 | list_for_each_entry(fh, &solo_enc->listeners, list) { | 621 | if (solo_enc->type != enc_buf->type) |
652 | struct videobuf_buffer *vb; | 622 | goto unlock; |
653 | unsigned long flags; | ||
654 | |||
655 | if (fh->type != enc_buf->type) | ||
656 | continue; | ||
657 | |||
658 | |||
659 | if (list_empty(&fh->vidq_active)) | ||
660 | continue; | ||
661 | 623 | ||
662 | spin_lock_irqsave(&fh->av_lock, flags); | 624 | if (list_empty(&solo_enc->vidq_active)) |
625 | goto unlock; | ||
663 | 626 | ||
664 | vb = list_first_entry(&fh->vidq_active, | 627 | spin_lock_irqsave(&solo_enc->av_lock, flags); |
665 | struct videobuf_buffer, queue); | ||
666 | 628 | ||
667 | list_del(&vb->queue); | 629 | vb = list_first_entry(&solo_enc->vidq_active, |
668 | vb->state = VIDEOBUF_ACTIVE; | 630 | struct videobuf_buffer, queue); |
669 | 631 | ||
670 | spin_unlock_irqrestore(&fh->av_lock, flags); | 632 | list_del(&vb->queue); |
633 | vb->state = VIDEOBUF_ACTIVE; | ||
671 | 634 | ||
672 | solo_enc_fillbuf(fh, vb, enc_buf); | 635 | spin_unlock_irqrestore(&solo_enc->av_lock, flags); |
673 | } | ||
674 | 636 | ||
637 | solo_enc_fillbuf(solo_enc, vb, enc_buf); | ||
638 | unlock: | ||
675 | mutex_unlock(&solo_enc->enable_lock); | 639 | mutex_unlock(&solo_enc->enable_lock); |
676 | } | 640 | } |
677 | 641 | ||
@@ -799,10 +763,10 @@ static int solo_enc_buf_prepare(struct videobuf_queue *vq, | |||
799 | static void solo_enc_buf_queue(struct videobuf_queue *vq, | 763 | static void solo_enc_buf_queue(struct videobuf_queue *vq, |
800 | struct videobuf_buffer *vb) | 764 | struct videobuf_buffer *vb) |
801 | { | 765 | { |
802 | struct solo_enc_fh *fh = vq->priv_data; | 766 | struct solo_enc_dev *solo_enc = vq->priv_data; |
803 | 767 | ||
804 | vb->state = VIDEOBUF_QUEUED; | 768 | vb->state = VIDEOBUF_QUEUED; |
805 | list_add_tail(&vb->queue, &fh->vidq_active); | 769 | list_add_tail(&vb->queue, &solo_enc->vidq_active); |
806 | } | 770 | } |
807 | 771 | ||
808 | static void solo_enc_buf_release(struct videobuf_queue *vq, | 772 | static void solo_enc_buf_release(struct videobuf_queue *vq, |
@@ -824,20 +788,20 @@ static const struct videobuf_queue_ops solo_enc_video_qops = { | |||
824 | static unsigned int solo_enc_poll(struct file *file, | 788 | static unsigned int solo_enc_poll(struct file *file, |
825 | struct poll_table_struct *wait) | 789 | struct poll_table_struct *wait) |
826 | { | 790 | { |
827 | struct solo_enc_fh *fh = file->private_data; | 791 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
828 | unsigned long req_events = poll_requested_events(wait); | 792 | unsigned long req_events = poll_requested_events(wait); |
829 | unsigned res = v4l2_ctrl_poll(file, wait); | 793 | unsigned res = v4l2_ctrl_poll(file, wait); |
830 | 794 | ||
831 | if (!(req_events & (POLLIN | POLLRDNORM))) | 795 | if (!(req_events & (POLLIN | POLLRDNORM))) |
832 | return res; | 796 | return res; |
833 | return videobuf_poll_stream(file, &fh->vidq, wait); | 797 | return videobuf_poll_stream(file, &solo_enc->vidq, wait); |
834 | } | 798 | } |
835 | 799 | ||
836 | static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma) | 800 | static int solo_enc_mmap(struct file *file, struct vm_area_struct *vma) |
837 | { | 801 | { |
838 | struct solo_enc_fh *fh = file->private_data; | 802 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
839 | 803 | ||
840 | return videobuf_mmap_mapper(&fh->vidq, vma); | 804 | return videobuf_mmap_mapper(&solo_enc->vidq, vma); |
841 | } | 805 | } |
842 | 806 | ||
843 | static int solo_ring_start(struct solo_dev *solo_dev) | 807 | static int solo_ring_start(struct solo_dev *solo_dev) |
@@ -875,91 +839,50 @@ static int solo_enc_open(struct file *file) | |||
875 | { | 839 | { |
876 | struct solo_enc_dev *solo_enc = video_drvdata(file); | 840 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
877 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 841 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
878 | struct solo_enc_fh *fh; | 842 | int ret = v4l2_fh_open(file); |
879 | int ret; | ||
880 | 843 | ||
881 | ret = solo_ring_start(solo_dev); | ||
882 | if (ret) | 844 | if (ret) |
883 | return ret; | 845 | return ret; |
884 | 846 | ret = solo_ring_start(solo_dev); | |
885 | fh = kzalloc(sizeof(*fh), GFP_KERNEL); | 847 | if (ret) { |
886 | if (fh == NULL) { | 848 | v4l2_fh_release(file); |
887 | solo_ring_stop(solo_dev); | 849 | return ret; |
888 | return -ENOMEM; | ||
889 | } | ||
890 | |||
891 | fh->desc_nelts = 32; | ||
892 | fh->desc_items = pci_alloc_consistent(solo_dev->pdev, | ||
893 | sizeof(struct solo_p2m_desc) * | ||
894 | fh->desc_nelts, &fh->desc_dma); | ||
895 | if (fh->desc_items == NULL) { | ||
896 | kfree(fh); | ||
897 | solo_ring_stop(solo_dev); | ||
898 | return -ENOMEM; | ||
899 | } | 850 | } |
900 | |||
901 | v4l2_fh_init(&fh->fh, video_devdata(file)); | ||
902 | fh->enc = solo_enc; | ||
903 | spin_lock_init(&fh->av_lock); | ||
904 | file->private_data = fh; | ||
905 | INIT_LIST_HEAD(&fh->vidq_active); | ||
906 | fh->fmt = V4L2_PIX_FMT_MPEG; | ||
907 | fh->type = SOLO_ENC_TYPE_STD; | ||
908 | |||
909 | videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops, | ||
910 | &solo_dev->pdev->dev, | ||
911 | &fh->av_lock, | ||
912 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | ||
913 | V4L2_FIELD_INTERLACED, | ||
914 | sizeof(struct solo_videobuf), | ||
915 | fh, NULL); | ||
916 | v4l2_fh_add(&fh->fh); | ||
917 | return 0; | 851 | return 0; |
918 | } | 852 | } |
919 | 853 | ||
920 | static ssize_t solo_enc_read(struct file *file, char __user *data, | 854 | static ssize_t solo_enc_read(struct file *file, char __user *data, |
921 | size_t count, loff_t *ppos) | 855 | size_t count, loff_t *ppos) |
922 | { | 856 | { |
923 | struct solo_enc_fh *fh = file->private_data; | 857 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
924 | int ret; | 858 | int ret; |
925 | 859 | ||
926 | /* Make sure the encoder is on */ | 860 | /* Make sure the encoder is on */ |
927 | ret = solo_enc_on(fh); | 861 | ret = solo_enc_on(solo_enc); |
928 | if (ret) | 862 | if (ret) |
929 | return ret; | 863 | return ret; |
930 | 864 | ||
931 | return videobuf_read_stream(&fh->vidq, data, count, ppos, 0, | 865 | return videobuf_read_stream(&solo_enc->vidq, data, count, ppos, 0, |
932 | file->f_flags & O_NONBLOCK); | 866 | file->f_flags & O_NONBLOCK); |
933 | } | 867 | } |
934 | 868 | ||
935 | static int solo_enc_release(struct file *file) | 869 | static int solo_enc_release(struct file *file) |
936 | { | 870 | { |
937 | struct solo_enc_fh *fh = file->private_data; | 871 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
938 | struct solo_dev *solo_dev = fh->enc->solo_dev; | 872 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
939 | |||
940 | solo_enc_off(fh); | ||
941 | v4l2_fh_del(&fh->fh); | ||
942 | v4l2_fh_exit(&fh->fh); | ||
943 | |||
944 | videobuf_stop(&fh->vidq); | ||
945 | videobuf_mmap_free(&fh->vidq); | ||
946 | |||
947 | pci_free_consistent(fh->enc->solo_dev->pdev, | ||
948 | sizeof(struct solo_p2m_desc) * | ||
949 | fh->desc_nelts, fh->desc_items, fh->desc_dma); | ||
950 | |||
951 | kfree(fh); | ||
952 | 873 | ||
874 | solo_enc_off(solo_enc); | ||
875 | videobuf_stop(&solo_enc->vidq); | ||
876 | videobuf_mmap_free(&solo_enc->vidq); | ||
953 | solo_ring_stop(solo_dev); | 877 | solo_ring_stop(solo_dev); |
954 | 878 | ||
955 | return 0; | 879 | return v4l2_fh_release(file); |
956 | } | 880 | } |
957 | 881 | ||
958 | static int solo_enc_querycap(struct file *file, void *priv, | 882 | static int solo_enc_querycap(struct file *file, void *priv, |
959 | struct v4l2_capability *cap) | 883 | struct v4l2_capability *cap) |
960 | { | 884 | { |
961 | struct solo_enc_fh *fh = priv; | 885 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
962 | struct solo_enc_dev *solo_enc = fh->enc; | ||
963 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 886 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
964 | 887 | ||
965 | strcpy(cap->driver, SOLO6X10_NAME); | 888 | strcpy(cap->driver, SOLO6X10_NAME); |
@@ -976,8 +899,7 @@ static int solo_enc_querycap(struct file *file, void *priv, | |||
976 | static int solo_enc_enum_input(struct file *file, void *priv, | 899 | static int solo_enc_enum_input(struct file *file, void *priv, |
977 | struct v4l2_input *input) | 900 | struct v4l2_input *input) |
978 | { | 901 | { |
979 | struct solo_enc_fh *fh = priv; | 902 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
980 | struct solo_enc_dev *solo_enc = fh->enc; | ||
981 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 903 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
982 | 904 | ||
983 | if (input->index) | 905 | if (input->index) |
@@ -1039,8 +961,7 @@ static int solo_enc_enum_fmt_cap(struct file *file, void *priv, | |||
1039 | static int solo_enc_try_fmt_cap(struct file *file, void *priv, | 961 | static int solo_enc_try_fmt_cap(struct file *file, void *priv, |
1040 | struct v4l2_format *f) | 962 | struct v4l2_format *f) |
1041 | { | 963 | { |
1042 | struct solo_enc_fh *fh = priv; | 964 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1043 | struct solo_enc_dev *solo_enc = fh->enc; | ||
1044 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 965 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1045 | struct v4l2_pix_format *pix = &f->fmt.pix; | 966 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1046 | 967 | ||
@@ -1081,8 +1002,7 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv, | |||
1081 | static int solo_enc_set_fmt_cap(struct file *file, void *priv, | 1002 | static int solo_enc_set_fmt_cap(struct file *file, void *priv, |
1082 | struct v4l2_format *f) | 1003 | struct v4l2_format *f) |
1083 | { | 1004 | { |
1084 | struct solo_enc_fh *fh = priv; | 1005 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1085 | struct solo_enc_dev *solo_enc = fh->enc; | ||
1086 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 1006 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1087 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1007 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1088 | int ret; | 1008 | int ret; |
@@ -1110,10 +1030,10 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, | |||
1110 | solo_enc->mode = SOLO_ENC_MODE_CIF; | 1030 | solo_enc->mode = SOLO_ENC_MODE_CIF; |
1111 | 1031 | ||
1112 | /* This does not change the encoder at all */ | 1032 | /* This does not change the encoder at all */ |
1113 | fh->fmt = pix->pixelformat; | 1033 | solo_enc->fmt = pix->pixelformat; |
1114 | 1034 | ||
1115 | if (pix->priv) | 1035 | if (pix->priv) |
1116 | fh->type = SOLO_ENC_TYPE_EXT; | 1036 | solo_enc->type = SOLO_ENC_TYPE_EXT; |
1117 | 1037 | ||
1118 | mutex_unlock(&solo_enc->enable_lock); | 1038 | mutex_unlock(&solo_enc->enable_lock); |
1119 | 1039 | ||
@@ -1123,13 +1043,12 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, | |||
1123 | static int solo_enc_get_fmt_cap(struct file *file, void *priv, | 1043 | static int solo_enc_get_fmt_cap(struct file *file, void *priv, |
1124 | struct v4l2_format *f) | 1044 | struct v4l2_format *f) |
1125 | { | 1045 | { |
1126 | struct solo_enc_fh *fh = priv; | 1046 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1127 | struct solo_enc_dev *solo_enc = fh->enc; | ||
1128 | struct v4l2_pix_format *pix = &f->fmt.pix; | 1047 | struct v4l2_pix_format *pix = &f->fmt.pix; |
1129 | 1048 | ||
1130 | pix->width = solo_enc->width; | 1049 | pix->width = solo_enc->width; |
1131 | pix->height = solo_enc->height; | 1050 | pix->height = solo_enc->height; |
1132 | pix->pixelformat = fh->fmt; | 1051 | pix->pixelformat = solo_enc->fmt; |
1133 | pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED : | 1052 | pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED : |
1134 | V4L2_FIELD_NONE; | 1053 | V4L2_FIELD_NONE; |
1135 | pix->sizeimage = FRAME_BUF_SIZE; | 1054 | pix->sizeimage = FRAME_BUF_SIZE; |
@@ -1142,45 +1061,45 @@ static int solo_enc_get_fmt_cap(struct file *file, void *priv, | |||
1142 | static int solo_enc_reqbufs(struct file *file, void *priv, | 1061 | static int solo_enc_reqbufs(struct file *file, void *priv, |
1143 | struct v4l2_requestbuffers *req) | 1062 | struct v4l2_requestbuffers *req) |
1144 | { | 1063 | { |
1145 | struct solo_enc_fh *fh = priv; | 1064 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1146 | 1065 | ||
1147 | return videobuf_reqbufs(&fh->vidq, req); | 1066 | return videobuf_reqbufs(&solo_enc->vidq, req); |
1148 | } | 1067 | } |
1149 | 1068 | ||
1150 | static int solo_enc_querybuf(struct file *file, void *priv, | 1069 | static int solo_enc_querybuf(struct file *file, void *priv, |
1151 | struct v4l2_buffer *buf) | 1070 | struct v4l2_buffer *buf) |
1152 | { | 1071 | { |
1153 | struct solo_enc_fh *fh = priv; | 1072 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1154 | 1073 | ||
1155 | return videobuf_querybuf(&fh->vidq, buf); | 1074 | return videobuf_querybuf(&solo_enc->vidq, buf); |
1156 | } | 1075 | } |
1157 | 1076 | ||
1158 | static int solo_enc_qbuf(struct file *file, void *priv, | 1077 | static int solo_enc_qbuf(struct file *file, void *priv, |
1159 | struct v4l2_buffer *buf) | 1078 | struct v4l2_buffer *buf) |
1160 | { | 1079 | { |
1161 | struct solo_enc_fh *fh = priv; | 1080 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1162 | 1081 | ||
1163 | return videobuf_qbuf(&fh->vidq, buf); | 1082 | return videobuf_qbuf(&solo_enc->vidq, buf); |
1164 | } | 1083 | } |
1165 | 1084 | ||
1166 | static int solo_enc_dqbuf(struct file *file, void *priv, | 1085 | static int solo_enc_dqbuf(struct file *file, void *priv, |
1167 | struct v4l2_buffer *buf) | 1086 | struct v4l2_buffer *buf) |
1168 | { | 1087 | { |
1169 | struct solo_enc_fh *fh = priv; | 1088 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1170 | struct solo_videobuf *svb; | 1089 | struct solo_videobuf *svb; |
1171 | int ret; | 1090 | int ret; |
1172 | 1091 | ||
1173 | /* Make sure the encoder is on */ | 1092 | /* Make sure the encoder is on */ |
1174 | ret = solo_enc_on(fh); | 1093 | ret = solo_enc_on(solo_enc); |
1175 | if (ret) | 1094 | if (ret) |
1176 | return ret; | 1095 | return ret; |
1177 | 1096 | ||
1178 | ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); | 1097 | ret = videobuf_dqbuf(&solo_enc->vidq, buf, file->f_flags & O_NONBLOCK); |
1179 | if (ret) | 1098 | if (ret) |
1180 | return ret; | 1099 | return ret; |
1181 | 1100 | ||
1182 | /* Copy over the flags */ | 1101 | /* Copy over the flags */ |
1183 | svb = (struct solo_videobuf *)fh->vidq.bufs[buf->index]; | 1102 | svb = (struct solo_videobuf *)solo_enc->vidq.bufs[buf->index]; |
1184 | buf->flags |= svb->flags; | 1103 | buf->flags |= svb->flags; |
1185 | 1104 | ||
1186 | return 0; | 1105 | return 0; |
@@ -1189,26 +1108,26 @@ static int solo_enc_dqbuf(struct file *file, void *priv, | |||
1189 | static int solo_enc_streamon(struct file *file, void *priv, | 1108 | static int solo_enc_streamon(struct file *file, void *priv, |
1190 | enum v4l2_buf_type i) | 1109 | enum v4l2_buf_type i) |
1191 | { | 1110 | { |
1192 | struct solo_enc_fh *fh = priv; | 1111 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1193 | 1112 | ||
1194 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1113 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1195 | return -EINVAL; | 1114 | return -EINVAL; |
1196 | 1115 | ||
1197 | return videobuf_streamon(&fh->vidq); | 1116 | return videobuf_streamon(&solo_enc->vidq); |
1198 | } | 1117 | } |
1199 | 1118 | ||
1200 | static int solo_enc_streamoff(struct file *file, void *priv, | 1119 | static int solo_enc_streamoff(struct file *file, void *priv, |
1201 | enum v4l2_buf_type i) | 1120 | enum v4l2_buf_type i) |
1202 | { | 1121 | { |
1203 | struct solo_enc_fh *fh = priv; | 1122 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1204 | int ret; | 1123 | int ret; |
1205 | 1124 | ||
1206 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1125 | if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1207 | return -EINVAL; | 1126 | return -EINVAL; |
1208 | 1127 | ||
1209 | ret = videobuf_streamoff(&fh->vidq); | 1128 | ret = videobuf_streamoff(&solo_enc->vidq); |
1210 | if (!ret) | 1129 | if (!ret) |
1211 | solo_enc_off(fh); | 1130 | solo_enc_off(solo_enc); |
1212 | 1131 | ||
1213 | return ret; | 1132 | return ret; |
1214 | } | 1133 | } |
@@ -1221,8 +1140,8 @@ static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id i) | |||
1221 | static int solo_enum_framesizes(struct file *file, void *priv, | 1140 | static int solo_enum_framesizes(struct file *file, void *priv, |
1222 | struct v4l2_frmsizeenum *fsize) | 1141 | struct v4l2_frmsizeenum *fsize) |
1223 | { | 1142 | { |
1224 | struct solo_enc_fh *fh = priv; | 1143 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1225 | struct solo_dev *solo_dev = fh->enc->solo_dev; | 1144 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1226 | 1145 | ||
1227 | if (fsize->pixel_format != V4L2_PIX_FMT_MPEG && | 1146 | if (fsize->pixel_format != V4L2_PIX_FMT_MPEG && |
1228 | fsize->pixel_format != V4L2_PIX_FMT_MJPEG) | 1147 | fsize->pixel_format != V4L2_PIX_FMT_MJPEG) |
@@ -1249,8 +1168,8 @@ static int solo_enum_framesizes(struct file *file, void *priv, | |||
1249 | static int solo_enum_frameintervals(struct file *file, void *priv, | 1168 | static int solo_enum_frameintervals(struct file *file, void *priv, |
1250 | struct v4l2_frmivalenum *fintv) | 1169 | struct v4l2_frmivalenum *fintv) |
1251 | { | 1170 | { |
1252 | struct solo_enc_fh *fh = priv; | 1171 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1253 | struct solo_dev *solo_dev = fh->enc->solo_dev; | 1172 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1254 | 1173 | ||
1255 | if (fintv->pixel_format != V4L2_PIX_FMT_MPEG && | 1174 | if (fintv->pixel_format != V4L2_PIX_FMT_MPEG && |
1256 | fintv->pixel_format != V4L2_PIX_FMT_MJPEG) | 1175 | fintv->pixel_format != V4L2_PIX_FMT_MJPEG) |
@@ -1280,8 +1199,7 @@ static int solo_enum_frameintervals(struct file *file, void *priv, | |||
1280 | static int solo_g_parm(struct file *file, void *priv, | 1199 | static int solo_g_parm(struct file *file, void *priv, |
1281 | struct v4l2_streamparm *sp) | 1200 | struct v4l2_streamparm *sp) |
1282 | { | 1201 | { |
1283 | struct solo_enc_fh *fh = priv; | 1202 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1284 | struct solo_enc_dev *solo_enc = fh->enc; | ||
1285 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 1203 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1286 | struct v4l2_captureparm *cp = &sp->parm.capture; | 1204 | struct v4l2_captureparm *cp = &sp->parm.capture; |
1287 | 1205 | ||
@@ -1298,8 +1216,7 @@ static int solo_g_parm(struct file *file, void *priv, | |||
1298 | static int solo_s_parm(struct file *file, void *priv, | 1216 | static int solo_s_parm(struct file *file, void *priv, |
1299 | struct v4l2_streamparm *sp) | 1217 | struct v4l2_streamparm *sp) |
1300 | { | 1218 | { |
1301 | struct solo_enc_fh *fh = priv; | 1219 | struct solo_enc_dev *solo_enc = video_drvdata(file); |
1302 | struct solo_enc_dev *solo_enc = fh->enc; | ||
1303 | struct solo_dev *solo_dev = solo_enc->solo_dev; | 1220 | struct solo_dev *solo_dev = solo_enc->solo_dev; |
1304 | struct v4l2_captureparm *cp = &sp->parm.capture; | 1221 | struct v4l2_captureparm *cp = &sp->parm.capture; |
1305 | 1222 | ||
@@ -1512,45 +1429,17 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, | |||
1512 | v4l2_ctrl_new_custom(hdl, &solo_osd_text_ctrl, NULL); | 1429 | v4l2_ctrl_new_custom(hdl, &solo_osd_text_ctrl, NULL); |
1513 | if (hdl->error) { | 1430 | if (hdl->error) { |
1514 | ret = hdl->error; | 1431 | ret = hdl->error; |
1515 | v4l2_ctrl_handler_free(hdl); | 1432 | goto hdl_free; |
1516 | kfree(solo_enc); | ||
1517 | return ERR_PTR(ret); | ||
1518 | } | ||
1519 | |||
1520 | solo_enc->vfd = video_device_alloc(); | ||
1521 | if (!solo_enc->vfd) { | ||
1522 | v4l2_ctrl_handler_free(hdl); | ||
1523 | kfree(solo_enc); | ||
1524 | return ERR_PTR(-ENOMEM); | ||
1525 | } | 1433 | } |
1526 | 1434 | ||
1527 | solo_enc->solo_dev = solo_dev; | 1435 | solo_enc->solo_dev = solo_dev; |
1528 | solo_enc->ch = ch; | 1436 | solo_enc->ch = ch; |
1529 | 1437 | spin_lock_init(&solo_enc->av_lock); | |
1530 | *solo_enc->vfd = solo_enc_template; | 1438 | INIT_LIST_HEAD(&solo_enc->vidq_active); |
1531 | solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; | 1439 | solo_enc->fmt = V4L2_PIX_FMT_MPEG; |
1532 | solo_enc->vfd->ctrl_handler = hdl; | 1440 | solo_enc->type = SOLO_ENC_TYPE_STD; |
1533 | set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags); | ||
1534 | ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); | ||
1535 | if (ret < 0) { | ||
1536 | video_device_release(solo_enc->vfd); | ||
1537 | v4l2_ctrl_handler_free(hdl); | ||
1538 | kfree(solo_enc); | ||
1539 | return ERR_PTR(ret); | ||
1540 | } | ||
1541 | |||
1542 | video_set_drvdata(solo_enc->vfd, solo_enc); | ||
1543 | |||
1544 | snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name), | ||
1545 | "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num, | ||
1546 | solo_enc->vfd->num); | ||
1547 | |||
1548 | INIT_LIST_HEAD(&solo_enc->listeners); | ||
1549 | mutex_init(&solo_enc->enable_lock); | ||
1550 | spin_lock_init(&solo_enc->motion_lock); | ||
1551 | 1441 | ||
1552 | atomic_set(&solo_enc->readers, 0); | 1442 | atomic_set(&solo_enc->readers, 0); |
1553 | atomic_set(&solo_enc->mpeg_readers, 0); | ||
1554 | 1443 | ||
1555 | solo_enc->qp = SOLO_DEFAULT_QP; | 1444 | solo_enc->qp = SOLO_DEFAULT_QP; |
1556 | solo_enc->gop = solo_dev->fps; | 1445 | solo_enc->gop = solo_dev->fps; |
@@ -1558,15 +1447,65 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, | |||
1558 | solo_enc->mode = SOLO_ENC_MODE_CIF; | 1447 | solo_enc->mode = SOLO_ENC_MODE_CIF; |
1559 | solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; | 1448 | solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; |
1560 | 1449 | ||
1561 | mutex_lock(&solo_enc->enable_lock); | 1450 | spin_lock(&solo_enc->av_lock); |
1562 | solo_update_mode(solo_enc); | 1451 | solo_update_mode(solo_enc); |
1563 | mutex_unlock(&solo_enc->enable_lock); | 1452 | spin_unlock(&solo_enc->av_lock); |
1453 | |||
1454 | mutex_init(&solo_enc->enable_lock); | ||
1455 | spin_lock_init(&solo_enc->motion_lock); | ||
1456 | |||
1457 | atomic_set(&solo_enc->readers, 0); | ||
1458 | atomic_set(&solo_enc->mpeg_readers, 0); | ||
1564 | 1459 | ||
1565 | /* Initialize this per encoder */ | 1460 | /* Initialize this per encoder */ |
1566 | solo_enc->jpeg_len = sizeof(jpeg_header); | 1461 | solo_enc->jpeg_len = sizeof(jpeg_header); |
1567 | memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len); | 1462 | memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len); |
1568 | 1463 | ||
1464 | solo_enc->desc_nelts = 32; | ||
1465 | solo_enc->desc_items = pci_alloc_consistent(solo_dev->pdev, | ||
1466 | sizeof(struct solo_p2m_desc) * | ||
1467 | solo_enc->desc_nelts, &solo_enc->desc_dma); | ||
1468 | ret = -ENOMEM; | ||
1469 | if (solo_enc->desc_items == NULL) | ||
1470 | goto hdl_free; | ||
1471 | |||
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(); | ||
1481 | if (!solo_enc->vfd) | ||
1482 | goto pci_free; | ||
1483 | |||
1484 | *solo_enc->vfd = solo_enc_template; | ||
1485 | solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; | ||
1486 | solo_enc->vfd->ctrl_handler = hdl; | ||
1487 | set_bit(V4L2_FL_USE_FH_PRIO, &solo_enc->vfd->flags); | ||
1488 | video_set_drvdata(solo_enc->vfd, solo_enc); | ||
1489 | ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); | ||
1490 | if (ret < 0) | ||
1491 | goto vdev_release; | ||
1492 | |||
1493 | snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name), | ||
1494 | "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num, | ||
1495 | solo_enc->vfd->num); | ||
1496 | |||
1569 | return solo_enc; | 1497 | return solo_enc; |
1498 | |||
1499 | vdev_release: | ||
1500 | video_device_release(solo_enc->vfd); | ||
1501 | pci_free: | ||
1502 | pci_free_consistent(solo_enc->solo_dev->pdev, | ||
1503 | sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts, | ||
1504 | solo_enc->desc_items, solo_enc->desc_dma); | ||
1505 | hdl_free: | ||
1506 | v4l2_ctrl_handler_free(hdl); | ||
1507 | kfree(solo_enc); | ||
1508 | return ERR_PTR(ret); | ||
1570 | } | 1509 | } |
1571 | 1510 | ||
1572 | static void solo_enc_free(struct solo_enc_dev *solo_enc) | 1511 | static void solo_enc_free(struct solo_enc_dev *solo_enc) |
@@ -1605,6 +1544,7 @@ int solo_enc_v4l2_init(struct solo_dev *solo_dev, unsigned nr) | |||
1605 | solo_enc_free(solo_dev->v4l2_enc[i]); | 1544 | solo_enc_free(solo_dev->v4l2_enc[i]); |
1606 | pci_free_consistent(solo_dev->pdev, solo_dev->vh_size, | 1545 | pci_free_consistent(solo_dev->pdev, solo_dev->vh_size, |
1607 | solo_dev->vh_buf, solo_dev->vh_dma); | 1546 | solo_dev->vh_buf, solo_dev->vh_dma); |
1547 | solo_dev->vh_buf = NULL; | ||
1608 | return ret; | 1548 | return ret; |
1609 | } | 1549 | } |
1610 | 1550 | ||
@@ -1627,6 +1567,7 @@ void solo_enc_v4l2_exit(struct solo_dev *solo_dev) | |||
1627 | for (i = 0; i < solo_dev->nr_chans; i++) | 1567 | for (i = 0; i < solo_dev->nr_chans; i++) |
1628 | solo_enc_free(solo_dev->v4l2_enc[i]); | 1568 | solo_enc_free(solo_dev->v4l2_enc[i]); |
1629 | 1569 | ||
1630 | pci_free_consistent(solo_dev->pdev, solo_dev->vh_size, | 1570 | if (solo_dev->vh_buf) |
1571 | pci_free_consistent(solo_dev->pdev, solo_dev->vh_size, | ||
1631 | solo_dev->vh_buf, solo_dev->vh_dma); | 1572 | solo_dev->vh_buf, solo_dev->vh_dma); |
1632 | } | 1573 | } |