aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/cx88/cx88-blackbird.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/cx88/cx88-blackbird.c')
-rw-r--r--drivers/media/pci/cx88/cx88-blackbird.c565
1 files changed, 253 insertions, 312 deletions
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index 150bb76e7839..4160ca4e5413 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -45,10 +45,6 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.us>, Gerd Knorr <kraxel@bytesex.org> [SuSE
45MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
46MODULE_VERSION(CX88_VERSION); 46MODULE_VERSION(CX88_VERSION);
47 47
48static unsigned int mpegbufs = 32;
49module_param(mpegbufs,int,0644);
50MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
51
52static unsigned int debug; 48static unsigned int debug;
53module_param(debug,int,0644); 49module_param(debug,int,0644);
54MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); 50MODULE_PARM_DESC(debug,"enable debug messages [blackbird]");
@@ -326,13 +322,13 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat
326 memory_read(dev->core, dev->mailbox - 4, &value); 322 memory_read(dev->core, dev->mailbox - 4, &value);
327 if (value != 0x12345678) { 323 if (value != 0x12345678) {
328 dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n"); 324 dprintk(0, "Firmware and/or mailbox pointer not initialized or corrupted\n");
329 return -1; 325 return -EIO;
330 } 326 }
331 327
332 memory_read(dev->core, dev->mailbox, &flag); 328 memory_read(dev->core, dev->mailbox, &flag);
333 if (flag) { 329 if (flag) {
334 dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag); 330 dprintk(0, "ERROR: Mailbox appears to be in use (%x)\n", flag);
335 return -1; 331 return -EIO;
336 } 332 }
337 333
338 flag |= 1; /* tell 'em we're working on it */ 334 flag |= 1; /* tell 'em we're working on it */
@@ -352,14 +348,14 @@ static int blackbird_mbox_func(void *priv, u32 command, int in, int out, u32 dat
352 memory_write(dev->core, dev->mailbox, flag); 348 memory_write(dev->core, dev->mailbox, flag);
353 349
354 /* wait for firmware to handle the API command */ 350 /* wait for firmware to handle the API command */
355 timeout = jiffies + msecs_to_jiffies(10); 351 timeout = jiffies + msecs_to_jiffies(1000);
356 for (;;) { 352 for (;;) {
357 memory_read(dev->core, dev->mailbox, &flag); 353 memory_read(dev->core, dev->mailbox, &flag);
358 if (0 != (flag & 4)) 354 if (0 != (flag & 4))
359 break; 355 break;
360 if (time_after(jiffies,timeout)) { 356 if (time_after(jiffies,timeout)) {
361 dprintk(0, "ERROR: API Mailbox timeout\n"); 357 dprintk(0, "ERROR: API Mailbox timeout %x\n", command);
362 return -1; 358 return -EIO;
363 } 359 }
364 udelay(10); 360 udelay(10);
365 } 361 }
@@ -420,7 +416,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev)
420 } 416 }
421 } 417 }
422 dprintk(0, "Mailbox signature values not found!\n"); 418 dprintk(0, "Mailbox signature values not found!\n");
423 return -1; 419 return -EIO;
424} 420}
425 421
426static int blackbird_load_firmware(struct cx8802_dev *dev) 422static int blackbird_load_firmware(struct cx8802_dev *dev)
@@ -432,7 +428,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
432 int i, retval = 0; 428 int i, retval = 0;
433 u32 value = 0; 429 u32 value = 0;
434 u32 checksum = 0; 430 u32 checksum = 0;
435 u32 *dataptr; 431 __le32 *dataptr;
436 432
437 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); 433 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
438 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 434 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
@@ -449,29 +445,28 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
449 445
450 446
451 if (retval != 0) { 447 if (retval != 0) {
452 dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n", 448 pr_err("Hotplug firmware request failed (%s).\n",
453 CX2341X_FIRM_ENC_FILENAME); 449 CX2341X_FIRM_ENC_FILENAME);
454 dprintk(0, "Please fix your hotplug setup, the board will " 450 pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n");
455 "not work without firmware loaded!\n"); 451 return -EIO;
456 return -1;
457 } 452 }
458 453
459 if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { 454 if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
460 dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", 455 pr_err("Firmware size mismatch (have %zd, expected %d)\n",
461 firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); 456 firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE);
462 release_firmware(firmware); 457 release_firmware(firmware);
463 return -1; 458 return -EINVAL;
464 } 459 }
465 460
466 if (0 != memcmp(firmware->data, magic, 8)) { 461 if (0 != memcmp(firmware->data, magic, 8)) {
467 dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n"); 462 pr_err("Firmware magic mismatch, wrong file?\n");
468 release_firmware(firmware); 463 release_firmware(firmware);
469 return -1; 464 return -EINVAL;
470 } 465 }
471 466
472 /* transfer to the chip */ 467 /* transfer to the chip */
473 dprintk(1,"Loading firmware ...\n"); 468 dprintk(1,"Loading firmware ...\n");
474 dataptr = (u32*)firmware->data; 469 dataptr = (__le32 *)firmware->data;
475 for (i = 0; i < (firmware->size >> 2); i++) { 470 for (i = 0; i < (firmware->size >> 2); i++) {
476 value = le32_to_cpu(*dataptr); 471 value = le32_to_cpu(*dataptr);
477 checksum += ~value; 472 checksum += ~value;
@@ -484,12 +479,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
484 memory_read(dev->core, i, &value); 479 memory_read(dev->core, i, &value);
485 checksum -= ~value; 480 checksum -= ~value;
486 } 481 }
482 release_firmware(firmware);
487 if (checksum) { 483 if (checksum) {
488 dprintk(0, "ERROR: Firmware load failed (checksum mismatch).\n"); 484 pr_err("Firmware load might have failed (checksum mismatch).\n");
489 release_firmware(firmware); 485 return -EIO;
490 return -1;
491 } 486 }
492 release_firmware(firmware);
493 dprintk(0, "Firmware upload successful.\n"); 487 dprintk(0, "Firmware upload successful.\n");
494 488
495 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 489 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
@@ -521,12 +515,14 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
521 515
522static void blackbird_codec_settings(struct cx8802_dev *dev) 516static void blackbird_codec_settings(struct cx8802_dev *dev)
523{ 517{
518 struct cx88_core *core = dev->core;
519
524 /* assign frame size */ 520 /* assign frame size */
525 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, 521 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
526 dev->height, dev->width); 522 core->height, core->width);
527 523
528 dev->cxhdl.width = dev->width; 524 dev->cxhdl.width = core->width;
529 dev->cxhdl.height = dev->height; 525 dev->cxhdl.height = core->height;
530 cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50); 526 cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50);
531 cx2341x_handler_setup(&dev->cxhdl); 527 cx2341x_handler_setup(&dev->cxhdl);
532} 528}
@@ -540,9 +536,6 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
540 dprintk(1,"Initialize codec\n"); 536 dprintk(1,"Initialize codec\n");
541 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ 537 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
542 if (retval < 0) { 538 if (retval < 0) {
543
544 dev->mpeg_active = 0;
545
546 /* ping was not successful, reset and upload firmware */ 539 /* ping was not successful, reset and upload firmware */
547 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ 540 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
548 cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */ 541 cx_write(MO_SRST_IO, 1); /* SYS_RSTO=1 */
@@ -589,9 +582,8 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
589 return 0; 582 return 0;
590} 583}
591 584
592static int blackbird_start_codec(struct file *file, void *priv) 585static int blackbird_start_codec(struct cx8802_dev *dev)
593{ 586{
594 struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
595 struct cx88_core *core = dev->core; 587 struct cx88_core *core = dev->core;
596 /* start capturing to the host interface */ 588 /* start capturing to the host interface */
597 u32 reg; 589 u32 reg;
@@ -627,7 +619,6 @@ static int blackbird_start_codec(struct file *file, void *priv)
627 BLACKBIRD_RAW_BITS_NONE 619 BLACKBIRD_RAW_BITS_NONE
628 ); 620 );
629 621
630 dev->mpeg_active = 1;
631 return 0; 622 return 0;
632} 623}
633 624
@@ -641,51 +632,139 @@ static int blackbird_stop_codec(struct cx8802_dev *dev)
641 632
642 cx2341x_handler_set_busy(&dev->cxhdl, 0); 633 cx2341x_handler_set_busy(&dev->cxhdl, 0);
643 634
644 dev->mpeg_active = 0;
645 return 0; 635 return 0;
646} 636}
647 637
648/* ------------------------------------------------------------------ */ 638/* ------------------------------------------------------------------ */
649 639
650static int bb_buf_setup(struct videobuf_queue *q, 640static int queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
651 unsigned int *count, unsigned int *size) 641 unsigned int *num_buffers, unsigned int *num_planes,
642 unsigned int sizes[], void *alloc_ctxs[])
652{ 643{
653 struct cx8802_fh *fh = q->priv_data; 644 struct cx8802_dev *dev = q->drv_priv;
654
655 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
656 fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
657 645
658 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 646 *num_planes = 1;
659 *count = fh->dev->ts_packet_count; 647 dev->ts_packet_size = 188 * 4;
648 dev->ts_packet_count = 32;
649 sizes[0] = dev->ts_packet_size * dev->ts_packet_count;
660 return 0; 650 return 0;
661} 651}
662 652
663static int 653static int buffer_prepare(struct vb2_buffer *vb)
664bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
665 enum v4l2_field field)
666{ 654{
667 struct cx8802_fh *fh = q->priv_data; 655 struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
668 return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field); 656 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
657
658 return cx8802_buf_prepare(vb->vb2_queue, dev, buf);
669} 659}
670 660
671static void 661static void buffer_finish(struct vb2_buffer *vb)
672bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
673{ 662{
674 struct cx8802_fh *fh = q->priv_data; 663 struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
675 cx8802_buf_queue(fh->dev, (struct cx88_buffer*)vb); 664 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
665 struct sg_table *sgt = vb2_dma_sg_plane_desc(vb, 0);
666 struct cx88_riscmem *risc = &buf->risc;
667
668 if (risc->cpu)
669 pci_free_consistent(dev->pci, risc->size, risc->cpu, risc->dma);
670 memset(risc, 0, sizeof(*risc));
671
672 dma_unmap_sg(&dev->pci->dev, sgt->sgl, sgt->nents, DMA_FROM_DEVICE);
676} 673}
677 674
678static void 675static void buffer_queue(struct vb2_buffer *vb)
679bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
680{ 676{
681 cx88_free_buffer(q, (struct cx88_buffer*)vb); 677 struct cx8802_dev *dev = vb->vb2_queue->drv_priv;
678 struct cx88_buffer *buf = container_of(vb, struct cx88_buffer, vb);
679
680 cx8802_buf_queue(dev, buf);
681}
682
683static int start_streaming(struct vb2_queue *q, unsigned int count)
684{
685 struct cx8802_dev *dev = q->drv_priv;
686 struct cx88_dmaqueue *dmaq = &dev->mpegq;
687 struct cx8802_driver *drv;
688 struct cx88_buffer *buf;
689 unsigned long flags;
690 int err;
691
692 /* Make sure we can acquire the hardware */
693 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
694 if (!drv) {
695 dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
696 err = -ENODEV;
697 goto fail;
698 }
699
700 err = drv->request_acquire(drv);
701 if (err != 0) {
702 dprintk(1, "%s: Unable to acquire hardware, %d\n", __func__, err);
703 goto fail;
704 }
705
706 if (blackbird_initialize_codec(dev) < 0) {
707 drv->request_release(drv);
708 err = -EINVAL;
709 goto fail;
710 }
711
712 err = blackbird_start_codec(dev);
713 if (err == 0) {
714 buf = list_entry(dmaq->active.next, struct cx88_buffer, list);
715 cx8802_start_dma(dev, dmaq, buf);
716 return 0;
717 }
718
719fail:
720 spin_lock_irqsave(&dev->slock, flags);
721 while (!list_empty(&dmaq->active)) {
722 struct cx88_buffer *buf = list_entry(dmaq->active.next,
723 struct cx88_buffer, list);
724
725 list_del(&buf->list);
726 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
727 }
728 spin_unlock_irqrestore(&dev->slock, flags);
729 return err;
682} 730}
683 731
684static struct videobuf_queue_ops blackbird_qops = { 732static void stop_streaming(struct vb2_queue *q)
685 .buf_setup = bb_buf_setup, 733{
686 .buf_prepare = bb_buf_prepare, 734 struct cx8802_dev *dev = q->drv_priv;
687 .buf_queue = bb_buf_queue, 735 struct cx88_dmaqueue *dmaq = &dev->mpegq;
688 .buf_release = bb_buf_release, 736 struct cx8802_driver *drv = NULL;
737 unsigned long flags;
738
739 cx8802_cancel_buffers(dev);
740 blackbird_stop_codec(dev);
741
742 /* Make sure we release the hardware */
743 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
744 WARN_ON(!drv);
745 if (drv)
746 drv->request_release(drv);
747
748 spin_lock_irqsave(&dev->slock, flags);
749 while (!list_empty(&dmaq->active)) {
750 struct cx88_buffer *buf = list_entry(dmaq->active.next,
751 struct cx88_buffer, list);
752
753 list_del(&buf->list);
754 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
755 }
756 spin_unlock_irqrestore(&dev->slock, flags);
757}
758
759static struct vb2_ops blackbird_qops = {
760 .queue_setup = queue_setup,
761 .buf_prepare = buffer_prepare,
762 .buf_finish = buffer_finish,
763 .buf_queue = buffer_queue,
764 .wait_prepare = vb2_ops_wait_prepare,
765 .wait_finish = vb2_ops_wait_finish,
766 .start_streaming = start_streaming,
767 .stop_streaming = stop_streaming,
689}; 768};
690 769
691/* ------------------------------------------------------------------ */ 770/* ------------------------------------------------------------------ */
@@ -693,8 +772,8 @@ static struct videobuf_queue_ops blackbird_qops = {
693static int vidioc_querycap(struct file *file, void *priv, 772static int vidioc_querycap(struct file *file, void *priv,
694 struct v4l2_capability *cap) 773 struct v4l2_capability *cap)
695{ 774{
696 struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; 775 struct cx8802_dev *dev = video_drvdata(file);
697 struct cx88_core *core = dev->core; 776 struct cx88_core *core = dev->core;
698 777
699 strcpy(cap->driver, "cx88_blackbird"); 778 strcpy(cap->driver, "cx88_blackbird");
700 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); 779 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
@@ -714,131 +793,111 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
714 return 0; 793 return 0;
715} 794}
716 795
717static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, 796static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
718 struct v4l2_format *f) 797 struct v4l2_format *f)
719{ 798{
720 struct cx8802_fh *fh = priv; 799 struct cx8802_dev *dev = video_drvdata(file);
721 struct cx8802_dev *dev = fh->dev; 800 struct cx88_core *core = dev->core;
722 801
723 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 802 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
724 f->fmt.pix.bytesperline = 0; 803 f->fmt.pix.bytesperline = 0;
725 f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */ 804 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count;
726 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 805 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
727 f->fmt.pix.width = dev->width; 806 f->fmt.pix.width = core->width;
728 f->fmt.pix.height = dev->height; 807 f->fmt.pix.height = core->height;
729 f->fmt.pix.field = fh->mpegq.field; 808 f->fmt.pix.field = core->field;
730 dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
731 dev->width, dev->height, fh->mpegq.field );
732 return 0; 809 return 0;
733} 810}
734 811
735static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, 812static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
736 struct v4l2_format *f) 813 struct v4l2_format *f)
737{ 814{
738 struct cx8802_fh *fh = priv; 815 struct cx8802_dev *dev = video_drvdata(file);
739 struct cx8802_dev *dev = fh->dev; 816 struct cx88_core *core = dev->core;
817 unsigned maxw, maxh;
818 enum v4l2_field field;
740 819
741 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 820 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
742 f->fmt.pix.bytesperline = 0; 821 f->fmt.pix.bytesperline = 0;
743 f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */ 822 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count;
744 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 823 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
745 dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", 824
746 dev->width, dev->height, fh->mpegq.field ); 825 maxw = norm_maxw(core->tvnorm);
826 maxh = norm_maxh(core->tvnorm);
827
828 field = f->fmt.pix.field;
829
830 switch (field) {
831 case V4L2_FIELD_TOP:
832 case V4L2_FIELD_BOTTOM:
833 case V4L2_FIELD_INTERLACED:
834 case V4L2_FIELD_SEQ_BT:
835 case V4L2_FIELD_SEQ_TB:
836 break;
837 default:
838 field = (f->fmt.pix.height > maxh / 2)
839 ? V4L2_FIELD_INTERLACED
840 : V4L2_FIELD_BOTTOM;
841 break;
842 }
843 if (V4L2_FIELD_HAS_T_OR_B(field))
844 maxh /= 2;
845
846 v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2,
847 &f->fmt.pix.height, 32, maxh, 0, 0);
848 f->fmt.pix.field = field;
747 return 0; 849 return 0;
748} 850}
749 851
750static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, 852static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
751 struct v4l2_format *f) 853 struct v4l2_format *f)
752{ 854{
753 struct cx8802_fh *fh = priv; 855 struct cx8802_dev *dev = video_drvdata(file);
754 struct cx8802_dev *dev = fh->dev;
755 struct cx88_core *core = dev->core; 856 struct cx88_core *core = dev->core;
756 857
757 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 858 if (vb2_is_busy(&dev->vb2_mpegq))
758 f->fmt.pix.bytesperline = 0; 859 return -EBUSY;
759 f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */ 860 if (core->v4ldev && (vb2_is_busy(&core->v4ldev->vb2_vidq) ||
760 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 861 vb2_is_busy(&core->v4ldev->vb2_vbiq)))
761 dev->width = f->fmt.pix.width; 862 return -EBUSY;
762 dev->height = f->fmt.pix.height; 863 vidioc_try_fmt_vid_cap(file, priv, f);
763 fh->mpegq.field = f->fmt.pix.field; 864 core->width = f->fmt.pix.width;
865 core->height = f->fmt.pix.height;
866 core->field = f->fmt.pix.field;
764 cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); 867 cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
765 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, 868 blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
766 f->fmt.pix.height, f->fmt.pix.width); 869 f->fmt.pix.height, f->fmt.pix.width);
767 dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
768 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
769 return 0; 870 return 0;
770} 871}
771 872
772static int vidioc_reqbufs (struct file *file, void *priv, struct v4l2_requestbuffers *p)
773{
774 struct cx8802_fh *fh = priv;
775 return (videobuf_reqbufs(&fh->mpegq, p));
776}
777
778static int vidioc_querybuf (struct file *file, void *priv, struct v4l2_buffer *p)
779{
780 struct cx8802_fh *fh = priv;
781 return (videobuf_querybuf(&fh->mpegq, p));
782}
783
784static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *p)
785{
786 struct cx8802_fh *fh = priv;
787 return (videobuf_qbuf(&fh->mpegq, p));
788}
789
790static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
791{
792 struct cx8802_fh *fh = priv;
793 return (videobuf_dqbuf(&fh->mpegq, p,
794 file->f_flags & O_NONBLOCK));
795}
796
797static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
798{
799 struct cx8802_fh *fh = priv;
800 struct cx8802_dev *dev = fh->dev;
801
802 if (!dev->mpeg_active)
803 blackbird_start_codec(file, fh);
804 return videobuf_streamon(&fh->mpegq);
805}
806
807static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
808{
809 struct cx8802_fh *fh = priv;
810 struct cx8802_dev *dev = fh->dev;
811
812 if (dev->mpeg_active)
813 blackbird_stop_codec(dev);
814 return videobuf_streamoff(&fh->mpegq);
815}
816
817static int vidioc_s_frequency (struct file *file, void *priv, 873static int vidioc_s_frequency (struct file *file, void *priv,
818 const struct v4l2_frequency *f) 874 const struct v4l2_frequency *f)
819{ 875{
820 struct cx8802_fh *fh = priv; 876 struct cx8802_dev *dev = video_drvdata(file);
821 struct cx8802_dev *dev = fh->dev; 877 struct cx88_core *core = dev->core;
822 struct cx88_core *core = dev->core; 878 bool streaming;
823 879
824 if (unlikely(UNSET == core->board.tuner_type)) 880 if (unlikely(UNSET == core->board.tuner_type))
825 return -EINVAL; 881 return -EINVAL;
826 if (unlikely(f->tuner != 0)) 882 if (unlikely(f->tuner != 0))
827 return -EINVAL; 883 return -EINVAL;
828 if (dev->mpeg_active) 884 streaming = vb2_start_streaming_called(&dev->vb2_mpegq);
885 if (streaming)
829 blackbird_stop_codec(dev); 886 blackbird_stop_codec(dev);
830 887
831 cx88_set_freq (core,f); 888 cx88_set_freq (core,f);
832 blackbird_initialize_codec(dev); 889 blackbird_initialize_codec(dev);
833 cx88_set_scale(dev->core, dev->width, dev->height, 890 cx88_set_scale(core, core->width, core->height,
834 fh->mpegq.field); 891 core->field);
892 if (streaming)
893 blackbird_start_codec(dev);
835 return 0; 894 return 0;
836} 895}
837 896
838static int vidioc_log_status (struct file *file, void *priv) 897static int vidioc_log_status (struct file *file, void *priv)
839{ 898{
840 struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev; 899 struct cx8802_dev *dev = video_drvdata(file);
841 struct cx88_core *core = dev->core; 900 struct cx88_core *core = dev->core;
842 char name[32 + 2]; 901 char name[32 + 2];
843 902
844 snprintf(name, sizeof(name), "%s/2", core->name); 903 snprintf(name, sizeof(name), "%s/2", core->name);
@@ -850,15 +909,16 @@ static int vidioc_log_status (struct file *file, void *priv)
850static int vidioc_enum_input (struct file *file, void *priv, 909static int vidioc_enum_input (struct file *file, void *priv,
851 struct v4l2_input *i) 910 struct v4l2_input *i)
852{ 911{
853 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; 912 struct cx8802_dev *dev = video_drvdata(file);
913 struct cx88_core *core = dev->core;
854 return cx88_enum_input (core,i); 914 return cx88_enum_input (core,i);
855} 915}
856 916
857static int vidioc_g_frequency (struct file *file, void *priv, 917static int vidioc_g_frequency (struct file *file, void *priv,
858 struct v4l2_frequency *f) 918 struct v4l2_frequency *f)
859{ 919{
860 struct cx8802_fh *fh = priv; 920 struct cx8802_dev *dev = video_drvdata(file);
861 struct cx88_core *core = fh->dev->core; 921 struct cx88_core *core = dev->core;
862 922
863 if (unlikely(UNSET == core->board.tuner_type)) 923 if (unlikely(UNSET == core->board.tuner_type))
864 return -EINVAL; 924 return -EINVAL;
@@ -873,7 +933,8 @@ static int vidioc_g_frequency (struct file *file, void *priv,
873 933
874static int vidioc_g_input (struct file *file, void *priv, unsigned int *i) 934static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
875{ 935{
876 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; 936 struct cx8802_dev *dev = video_drvdata(file);
937 struct cx88_core *core = dev->core;
877 938
878 *i = core->input; 939 *i = core->input;
879 return 0; 940 return 0;
@@ -881,24 +942,24 @@ static int vidioc_g_input (struct file *file, void *priv, unsigned int *i)
881 942
882static int vidioc_s_input (struct file *file, void *priv, unsigned int i) 943static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
883{ 944{
884 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; 945 struct cx8802_dev *dev = video_drvdata(file);
946 struct cx88_core *core = dev->core;
885 947
886 if (i >= 4) 948 if (i >= 4)
887 return -EINVAL; 949 return -EINVAL;
888 if (0 == INPUT(i).type) 950 if (0 == INPUT(i).type)
889 return -EINVAL; 951 return -EINVAL;
890 952
891 mutex_lock(&core->lock);
892 cx88_newstation(core); 953 cx88_newstation(core);
893 cx88_video_mux(core,i); 954 cx88_video_mux(core,i);
894 mutex_unlock(&core->lock);
895 return 0; 955 return 0;
896} 956}
897 957
898static int vidioc_g_tuner (struct file *file, void *priv, 958static int vidioc_g_tuner (struct file *file, void *priv,
899 struct v4l2_tuner *t) 959 struct v4l2_tuner *t)
900{ 960{
901 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; 961 struct cx8802_dev *dev = video_drvdata(file);
962 struct cx88_core *core = dev->core;
902 u32 reg; 963 u32 reg;
903 964
904 if (unlikely(UNSET == core->board.tuner_type)) 965 if (unlikely(UNSET == core->board.tuner_type))
@@ -920,7 +981,8 @@ static int vidioc_g_tuner (struct file *file, void *priv,
920static int vidioc_s_tuner (struct file *file, void *priv, 981static int vidioc_s_tuner (struct file *file, void *priv,
921 const struct v4l2_tuner *t) 982 const struct v4l2_tuner *t)
922{ 983{
923 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; 984 struct cx8802_dev *dev = video_drvdata(file);
985 struct cx88_core *core = dev->core;
924 986
925 if (UNSET == core->board.tuner_type) 987 if (UNSET == core->board.tuner_type)
926 return -EINVAL; 988 return -EINVAL;
@@ -933,7 +995,8 @@ static int vidioc_s_tuner (struct file *file, void *priv,
933 995
934static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm) 996static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
935{ 997{
936 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core; 998 struct cx8802_dev *dev = video_drvdata(file);
999 struct cx88_core *core = dev->core;
937 1000
938 *tvnorm = core->tvnorm; 1001 *tvnorm = core->tvnorm;
939 return 0; 1002 return 0;
@@ -941,155 +1004,20 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
941 1004
942static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id) 1005static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id id)
943{ 1006{
944 struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
945
946 mutex_lock(&core->lock);
947 cx88_set_tvnorm(core, id);
948 mutex_unlock(&core->lock);
949 return 0;
950}
951
952/* FIXME: cx88_ioctl_hook not implemented */
953
954static int mpeg_open(struct file *file)
955{
956 struct video_device *vdev = video_devdata(file);
957 struct cx8802_dev *dev = video_drvdata(file); 1007 struct cx8802_dev *dev = video_drvdata(file);
958 struct cx8802_fh *fh; 1008 struct cx88_core *core = dev->core;
959 struct cx8802_driver *drv = NULL;
960 int err;
961
962 dprintk( 1, "%s\n", __func__);
963
964 mutex_lock(&dev->core->lock);
965
966 /* Make sure we can acquire the hardware */
967 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
968 if (!drv) {
969 dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
970 mutex_unlock(&dev->core->lock);
971 return -ENODEV;
972 }
973
974 err = drv->request_acquire(drv);
975 if (err != 0) {
976 dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
977 mutex_unlock(&dev->core->lock);
978 return err;
979 }
980
981 if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
982 drv->request_release(drv);
983 mutex_unlock(&dev->core->lock);
984 return -EINVAL;
985 }
986 dprintk(1, "open dev=%s\n", video_device_node_name(vdev));
987
988 /* allocate + initialize per filehandle data */
989 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
990 if (NULL == fh) {
991 drv->request_release(drv);
992 mutex_unlock(&dev->core->lock);
993 return -ENOMEM;
994 }
995 v4l2_fh_init(&fh->fh, vdev);
996 file->private_data = fh;
997 fh->dev = dev;
998
999 videobuf_queue_sg_init(&fh->mpegq, &blackbird_qops,
1000 &dev->pci->dev, &dev->slock,
1001 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1002 V4L2_FIELD_INTERLACED,
1003 sizeof(struct cx88_buffer),
1004 fh, NULL);
1005
1006 /* FIXME: locking against other video device */
1007 cx88_set_scale(dev->core, dev->width, dev->height,
1008 fh->mpegq.field);
1009
1010 dev->core->mpeg_users++;
1011 mutex_unlock(&dev->core->lock);
1012 v4l2_fh_add(&fh->fh);
1013 return 0;
1014}
1015
1016static int mpeg_release(struct file *file)
1017{
1018 struct cx8802_fh *fh = file->private_data;
1019 struct cx8802_dev *dev = fh->dev;
1020 struct cx8802_driver *drv = NULL;
1021
1022 mutex_lock(&dev->core->lock);
1023
1024 if (dev->mpeg_active && dev->core->mpeg_users == 1)
1025 blackbird_stop_codec(dev);
1026
1027 cx8802_cancel_buffers(fh->dev);
1028 /* stop mpeg capture */
1029 videobuf_stop(&fh->mpegq);
1030
1031 videobuf_mmap_free(&fh->mpegq);
1032
1033 v4l2_fh_del(&fh->fh);
1034 v4l2_fh_exit(&fh->fh);
1035 file->private_data = NULL;
1036 kfree(fh);
1037
1038 /* Make sure we release the hardware */
1039 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1040 WARN_ON(!drv);
1041 if (drv)
1042 drv->request_release(drv);
1043
1044 dev->core->mpeg_users--;
1045
1046 mutex_unlock(&dev->core->lock);
1047
1048 return 0;
1049}
1050
1051static ssize_t
1052mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1053{
1054 struct cx8802_fh *fh = file->private_data;
1055 struct cx8802_dev *dev = fh->dev;
1056
1057 if (!dev->mpeg_active)
1058 blackbird_start_codec(file, fh);
1059
1060 return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
1061 file->f_flags & O_NONBLOCK);
1062}
1063
1064static unsigned int
1065mpeg_poll(struct file *file, struct poll_table_struct *wait)
1066{
1067 unsigned long req_events = poll_requested_events(wait);
1068 struct cx8802_fh *fh = file->private_data;
1069 struct cx8802_dev *dev = fh->dev;
1070
1071 if (!dev->mpeg_active && (req_events & (POLLIN | POLLRDNORM)))
1072 blackbird_start_codec(file, fh);
1073
1074 return v4l2_ctrl_poll(file, wait) | videobuf_poll_stream(file, &fh->mpegq, wait);
1075}
1076
1077static int
1078mpeg_mmap(struct file *file, struct vm_area_struct * vma)
1079{
1080 struct cx8802_fh *fh = file->private_data;
1081 1009
1082 return videobuf_mmap_mapper(&fh->mpegq, vma); 1010 return cx88_set_tvnorm(core, id);
1083} 1011}
1084 1012
1085static const struct v4l2_file_operations mpeg_fops = 1013static const struct v4l2_file_operations mpeg_fops =
1086{ 1014{
1087 .owner = THIS_MODULE, 1015 .owner = THIS_MODULE,
1088 .open = mpeg_open, 1016 .open = v4l2_fh_open,
1089 .release = mpeg_release, 1017 .release = vb2_fop_release,
1090 .read = mpeg_read, 1018 .read = vb2_fop_read,
1091 .poll = mpeg_poll, 1019 .poll = vb2_fop_poll,
1092 .mmap = mpeg_mmap, 1020 .mmap = vb2_fop_mmap,
1093 .unlocked_ioctl = video_ioctl2, 1021 .unlocked_ioctl = video_ioctl2,
1094}; 1022};
1095 1023
@@ -1099,12 +1027,12 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
1099 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 1027 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1100 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 1028 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1101 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 1029 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1102 .vidioc_reqbufs = vidioc_reqbufs, 1030 .vidioc_reqbufs = vb2_ioctl_reqbufs,
1103 .vidioc_querybuf = vidioc_querybuf, 1031 .vidioc_querybuf = vb2_ioctl_querybuf,
1104 .vidioc_qbuf = vidioc_qbuf, 1032 .vidioc_qbuf = vb2_ioctl_qbuf,
1105 .vidioc_dqbuf = vidioc_dqbuf, 1033 .vidioc_dqbuf = vb2_ioctl_dqbuf,
1106 .vidioc_streamon = vidioc_streamon, 1034 .vidioc_streamon = vb2_ioctl_streamon,
1107 .vidioc_streamoff = vidioc_streamoff, 1035 .vidioc_streamoff = vb2_ioctl_streamoff,
1108 .vidioc_s_frequency = vidioc_s_frequency, 1036 .vidioc_s_frequency = vidioc_s_frequency,
1109 .vidioc_log_status = vidioc_log_status, 1037 .vidioc_log_status = vidioc_log_status,
1110 .vidioc_enum_input = vidioc_enum_input, 1038 .vidioc_enum_input = vidioc_enum_input,
@@ -1189,11 +1117,12 @@ static int blackbird_register_video(struct cx8802_dev *dev)
1189{ 1117{
1190 int err; 1118 int err;
1191 1119
1192 dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci, 1120 dev->mpeg_dev = cx88_vdev_init(dev->core, dev->pci,
1193 &cx8802_mpeg_template,"mpeg"); 1121 &cx8802_mpeg_template, "mpeg");
1194 dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl; 1122 dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl;
1195 video_set_drvdata(dev->mpeg_dev, dev); 1123 video_set_drvdata(dev->mpeg_dev, dev);
1196 err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1); 1124 dev->mpeg_dev->queue = &dev->vb2_mpegq;
1125 err = video_register_device(dev->mpeg_dev, VFL_TYPE_GRABBER, -1);
1197 if (err < 0) { 1126 if (err < 0) {
1198 printk(KERN_INFO "%s/2: can't register mpeg device\n", 1127 printk(KERN_INFO "%s/2: can't register mpeg device\n",
1199 dev->core->name); 1128 dev->core->name);
@@ -1210,6 +1139,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1210{ 1139{
1211 struct cx88_core *core = drv->core; 1140 struct cx88_core *core = drv->core;
1212 struct cx8802_dev *dev = core->dvbdev; 1141 struct cx8802_dev *dev = core->dvbdev;
1142 struct vb2_queue *q;
1213 int err; 1143 int err;
1214 1144
1215 dprintk( 1, "%s\n", __func__); 1145 dprintk( 1, "%s\n", __func__);
@@ -1223,15 +1153,9 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1223 if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD)) 1153 if (!(core->board.mpeg & CX88_MPEG_BLACKBIRD))
1224 goto fail_core; 1154 goto fail_core;
1225 1155
1226 dev->width = 720;
1227 if (core->tvnorm & V4L2_STD_525_60) {
1228 dev->height = 480;
1229 } else {
1230 dev->height = 576;
1231 }
1232 dev->cxhdl.port = CX2341X_PORT_STREAMING; 1156 dev->cxhdl.port = CX2341X_PORT_STREAMING;
1233 dev->cxhdl.width = dev->width; 1157 dev->cxhdl.width = core->width;
1234 dev->cxhdl.height = dev->height; 1158 dev->cxhdl.height = core->height;
1235 dev->cxhdl.func = blackbird_mbox_func; 1159 dev->cxhdl.func = blackbird_mbox_func;
1236 dev->cxhdl.priv = dev; 1160 dev->cxhdl.priv = dev;
1237 err = cx2341x_handler_init(&dev->cxhdl, 36); 1161 err = cx2341x_handler_init(&dev->cxhdl, 36);
@@ -1250,13 +1174,30 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1250// init_controls(core); 1174// init_controls(core);
1251 cx88_set_tvnorm(core,core->tvnorm); 1175 cx88_set_tvnorm(core,core->tvnorm);
1252 cx88_video_mux(core,0); 1176 cx88_video_mux(core,0);
1253 cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576); 1177 cx2341x_handler_set_50hz(&dev->cxhdl, core->height == 576);
1254 cx2341x_handler_setup(&dev->cxhdl); 1178 cx2341x_handler_setup(&dev->cxhdl);
1179
1180 q = &dev->vb2_mpegq;
1181 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1182 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
1183 q->gfp_flags = GFP_DMA32;
1184 q->min_buffers_needed = 2;
1185 q->drv_priv = dev;
1186 q->buf_struct_size = sizeof(struct cx88_buffer);
1187 q->ops = &blackbird_qops;
1188 q->mem_ops = &vb2_dma_sg_memops;
1189 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1190 q->lock = &core->lock;
1191
1192 err = vb2_queue_init(q);
1193 if (err < 0)
1194 goto fail_core;
1195
1255 blackbird_register_video(dev); 1196 blackbird_register_video(dev);
1256 1197
1257 return 0; 1198 return 0;
1258 1199
1259 fail_core: 1200fail_core:
1260 return err; 1201 return err;
1261} 1202}
1262 1203