.. | .. |
---|
85 | 85 | #define VNMC_INF_YUV8_BT601 (1 << 16) |
---|
86 | 86 | #define VNMC_INF_YUV10_BT656 (2 << 16) |
---|
87 | 87 | #define VNMC_INF_YUV10_BT601 (3 << 16) |
---|
| 88 | +#define VNMC_INF_RAW8 (4 << 16) |
---|
88 | 89 | #define VNMC_INF_YUV16 (5 << 16) |
---|
89 | 90 | #define VNMC_INF_RGB888 (6 << 16) |
---|
90 | 91 | #define VNMC_VUP (1 << 10) |
---|
.. | .. |
---|
111 | 112 | #define VNIE_EFE (1 << 1) |
---|
112 | 113 | |
---|
113 | 114 | /* Video n Data Mode Register bits */ |
---|
| 115 | +#define VNDMR_A8BIT(n) (((n) & 0xff) << 24) |
---|
| 116 | +#define VNDMR_A8BIT_MASK (0xff << 24) |
---|
114 | 117 | #define VNDMR_EXRGB (1 << 8) |
---|
115 | 118 | #define VNDMR_BPSM (1 << 4) |
---|
| 119 | +#define VNDMR_ABIT (1 << 2) |
---|
116 | 120 | #define VNDMR_DTMD_YCSEP (1 << 1) |
---|
117 | | -#define VNDMR_DTMD_ARGB1555 (1 << 0) |
---|
| 121 | +#define VNDMR_DTMD_ARGB (1 << 0) |
---|
| 122 | +#define VNDMR_DTMD_YCSEP_420 (3 << 0) |
---|
118 | 123 | |
---|
119 | 124 | /* Video n Data Mode Register 2 bits */ |
---|
120 | 125 | #define VNDMR2_VPS (1 << 30) |
---|
121 | 126 | #define VNDMR2_HPS (1 << 29) |
---|
122 | 127 | #define VNDMR2_CES (1 << 28) |
---|
| 128 | +#define VNDMR2_YDS (1 << 22) |
---|
123 | 129 | #define VNDMR2_FTEV (1 << 17) |
---|
124 | 130 | #define VNDMR2_VLV(n) ((n & 0xf) << 12) |
---|
125 | 131 | |
---|
.. | .. |
---|
486 | 492 | } |
---|
487 | 493 | |
---|
488 | 494 | /* Use previous value if its XS value is closer */ |
---|
489 | | - if (p_prev_set && p_set && |
---|
| 495 | + if (p_prev_set && |
---|
490 | 496 | xs - p_prev_set->xs_value < p_set->xs_value - xs) |
---|
491 | 497 | p_set = p_prev_set; |
---|
492 | 498 | |
---|
.. | .. |
---|
526 | 532 | |
---|
527 | 533 | static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) |
---|
528 | 534 | { |
---|
| 535 | + unsigned int crop_height; |
---|
529 | 536 | u32 xs, ys; |
---|
530 | 537 | |
---|
531 | 538 | /* Set scaling coefficient */ |
---|
| 539 | + crop_height = vin->crop.height; |
---|
| 540 | + if (V4L2_FIELD_HAS_BOTH(vin->format.field)) |
---|
| 541 | + crop_height *= 2; |
---|
| 542 | + |
---|
532 | 543 | ys = 0; |
---|
533 | | - if (vin->crop.height != vin->compose.height) |
---|
534 | | - ys = (4096 * vin->crop.height) / vin->compose.height; |
---|
| 544 | + if (crop_height != vin->compose.height) |
---|
| 545 | + ys = (4096 * crop_height) / vin->compose.height; |
---|
535 | 546 | rvin_write(vin, ys, VNYS_REG); |
---|
536 | 547 | |
---|
537 | 548 | xs = 0; |
---|
.. | .. |
---|
554 | 565 | rvin_write(vin, 0, VNSPPOC_REG); |
---|
555 | 566 | rvin_write(vin, 0, VNSLPOC_REG); |
---|
556 | 567 | rvin_write(vin, vin->format.width - 1, VNEPPOC_REG); |
---|
557 | | - switch (vin->format.field) { |
---|
558 | | - case V4L2_FIELD_INTERLACED: |
---|
559 | | - case V4L2_FIELD_INTERLACED_TB: |
---|
560 | | - case V4L2_FIELD_INTERLACED_BT: |
---|
| 568 | + |
---|
| 569 | + if (V4L2_FIELD_HAS_BOTH(vin->format.field)) |
---|
561 | 570 | rvin_write(vin, vin->format.height / 2 - 1, VNELPOC_REG); |
---|
562 | | - break; |
---|
563 | | - default: |
---|
| 571 | + else |
---|
564 | 572 | rvin_write(vin, vin->format.height - 1, VNELPOC_REG); |
---|
565 | | - break; |
---|
566 | | - } |
---|
567 | 573 | |
---|
568 | 574 | vin_dbg(vin, |
---|
569 | 575 | "Pre-Clip: %ux%u@%u:%u YS: %d XS: %d Post-Clip: %ux%u@%u:%u\n", |
---|
.. | .. |
---|
574 | 580 | |
---|
575 | 581 | void rvin_crop_scale_comp(struct rvin_dev *vin) |
---|
576 | 582 | { |
---|
| 583 | + const struct rvin_video_format *fmt; |
---|
| 584 | + u32 stride; |
---|
| 585 | + |
---|
577 | 586 | /* Set Start/End Pixel/Line Pre-Clip */ |
---|
578 | 587 | rvin_write(vin, vin->crop.left, VNSPPRC_REG); |
---|
579 | 588 | rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG); |
---|
580 | | - |
---|
581 | | - switch (vin->format.field) { |
---|
582 | | - case V4L2_FIELD_INTERLACED: |
---|
583 | | - case V4L2_FIELD_INTERLACED_TB: |
---|
584 | | - case V4L2_FIELD_INTERLACED_BT: |
---|
585 | | - rvin_write(vin, vin->crop.top / 2, VNSLPRC_REG); |
---|
586 | | - rvin_write(vin, (vin->crop.top + vin->crop.height) / 2 - 1, |
---|
587 | | - VNELPRC_REG); |
---|
588 | | - break; |
---|
589 | | - default: |
---|
590 | | - rvin_write(vin, vin->crop.top, VNSLPRC_REG); |
---|
591 | | - rvin_write(vin, vin->crop.top + vin->crop.height - 1, |
---|
592 | | - VNELPRC_REG); |
---|
593 | | - break; |
---|
594 | | - } |
---|
| 589 | + rvin_write(vin, vin->crop.top, VNSLPRC_REG); |
---|
| 590 | + rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG); |
---|
595 | 591 | |
---|
596 | 592 | /* TODO: Add support for the UDS scaler. */ |
---|
597 | 593 | if (vin->info->model != RCAR_GEN3) |
---|
598 | 594 | rvin_crop_scale_comp_gen2(vin); |
---|
599 | 595 | |
---|
600 | | - if (vin->format.pixelformat == V4L2_PIX_FMT_NV16) |
---|
601 | | - rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG); |
---|
602 | | - else |
---|
603 | | - rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG); |
---|
| 596 | + fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); |
---|
| 597 | + stride = vin->format.bytesperline / fmt->bpp; |
---|
| 598 | + |
---|
| 599 | + /* For RAW8 format bpp is 1, but the hardware process RAW8 |
---|
| 600 | + * format in 2 pixel unit hence configure VNIS_REG as stride / 2. |
---|
| 601 | + */ |
---|
| 602 | + switch (vin->format.pixelformat) { |
---|
| 603 | + case V4L2_PIX_FMT_SBGGR8: |
---|
| 604 | + case V4L2_PIX_FMT_SGBRG8: |
---|
| 605 | + case V4L2_PIX_FMT_SGRBG8: |
---|
| 606 | + case V4L2_PIX_FMT_SRGGB8: |
---|
| 607 | + stride /= 2; |
---|
| 608 | + break; |
---|
| 609 | + default: |
---|
| 610 | + break; |
---|
| 611 | + } |
---|
| 612 | + |
---|
| 613 | + rvin_write(vin, stride, VNIS_REG); |
---|
604 | 614 | } |
---|
605 | 615 | |
---|
606 | 616 | /* ----------------------------------------------------------------------------- |
---|
.. | .. |
---|
632 | 642 | case V4L2_FIELD_INTERLACED_BT: |
---|
633 | 643 | vnmc = VNMC_IM_FULL | VNMC_FOC; |
---|
634 | 644 | break; |
---|
| 645 | + case V4L2_FIELD_SEQ_TB: |
---|
| 646 | + case V4L2_FIELD_SEQ_BT: |
---|
635 | 647 | case V4L2_FIELD_NONE: |
---|
636 | 648 | vnmc = VNMC_IM_ODD_EVEN; |
---|
637 | 649 | progressive = true; |
---|
| 650 | + break; |
---|
| 651 | + case V4L2_FIELD_ALTERNATE: |
---|
| 652 | + vnmc = VNMC_IM_ODD_EVEN; |
---|
638 | 653 | break; |
---|
639 | 654 | default: |
---|
640 | 655 | vnmc = VNMC_IM_ODD; |
---|
.. | .. |
---|
677 | 692 | |
---|
678 | 693 | input_is_yuv = true; |
---|
679 | 694 | break; |
---|
| 695 | + case MEDIA_BUS_FMT_SBGGR8_1X8: |
---|
| 696 | + case MEDIA_BUS_FMT_SGBRG8_1X8: |
---|
| 697 | + case MEDIA_BUS_FMT_SGRBG8_1X8: |
---|
| 698 | + case MEDIA_BUS_FMT_SRGGB8_1X8: |
---|
| 699 | + vnmc |= VNMC_INF_RAW8; |
---|
| 700 | + break; |
---|
680 | 701 | default: |
---|
681 | 702 | break; |
---|
682 | 703 | } |
---|
683 | 704 | |
---|
684 | | - /* Enable VSYNC Field Toogle mode after one VSYNC input */ |
---|
| 705 | + /* Enable VSYNC Field Toggle mode after one VSYNC input */ |
---|
685 | 706 | if (vin->info->model == RCAR_GEN3) |
---|
686 | 707 | dmr2 = VNDMR2_FTEV; |
---|
687 | 708 | else |
---|
.. | .. |
---|
689 | 710 | |
---|
690 | 711 | if (!vin->is_csi) { |
---|
691 | 712 | /* Hsync Signal Polarity Select */ |
---|
692 | | - if (!(vin->parallel->mbus_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) |
---|
| 713 | + if (!(vin->parallel->bus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) |
---|
693 | 714 | dmr2 |= VNDMR2_HPS; |
---|
694 | 715 | |
---|
695 | 716 | /* Vsync Signal Polarity Select */ |
---|
696 | | - if (!(vin->parallel->mbus_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) |
---|
| 717 | + if (!(vin->parallel->bus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) |
---|
697 | 718 | dmr2 |= VNDMR2_VPS; |
---|
698 | 719 | |
---|
699 | 720 | /* Data Enable Polarity Select */ |
---|
700 | | - if (vin->parallel->mbus_flags & V4L2_MBUS_DATA_ENABLE_LOW) |
---|
| 721 | + if (vin->parallel->bus.flags & V4L2_MBUS_DATA_ENABLE_LOW) |
---|
701 | 722 | dmr2 |= VNDMR2_CES; |
---|
| 723 | + |
---|
| 724 | + switch (vin->mbus_code) { |
---|
| 725 | + case MEDIA_BUS_FMT_UYVY8_2X8: |
---|
| 726 | + if (vin->parallel->bus.bus_width == 8 && |
---|
| 727 | + vin->parallel->bus.data_shift == 8) |
---|
| 728 | + dmr2 |= VNDMR2_YDS; |
---|
| 729 | + break; |
---|
| 730 | + default: |
---|
| 731 | + break; |
---|
| 732 | + } |
---|
702 | 733 | } |
---|
703 | 734 | |
---|
704 | 735 | /* |
---|
705 | 736 | * Output format |
---|
706 | 737 | */ |
---|
707 | 738 | switch (vin->format.pixelformat) { |
---|
| 739 | + case V4L2_PIX_FMT_NV12: |
---|
708 | 740 | case V4L2_PIX_FMT_NV16: |
---|
709 | 741 | rvin_write(vin, |
---|
710 | | - ALIGN(vin->format.width * vin->format.height, 0x80), |
---|
711 | | - VNUVAOF_REG); |
---|
712 | | - dmr = VNDMR_DTMD_YCSEP; |
---|
| 742 | + ALIGN(vin->format.bytesperline * vin->format.height, |
---|
| 743 | + 0x80), VNUVAOF_REG); |
---|
| 744 | + dmr = vin->format.pixelformat == V4L2_PIX_FMT_NV12 ? |
---|
| 745 | + VNDMR_DTMD_YCSEP_420 : VNDMR_DTMD_YCSEP; |
---|
713 | 746 | output_is_yuv = true; |
---|
714 | 747 | break; |
---|
715 | 748 | case V4L2_PIX_FMT_YUYV: |
---|
.. | .. |
---|
721 | 754 | output_is_yuv = true; |
---|
722 | 755 | break; |
---|
723 | 756 | case V4L2_PIX_FMT_XRGB555: |
---|
724 | | - dmr = VNDMR_DTMD_ARGB1555; |
---|
| 757 | + dmr = VNDMR_DTMD_ARGB; |
---|
725 | 758 | break; |
---|
726 | 759 | case V4L2_PIX_FMT_RGB565: |
---|
727 | 760 | dmr = 0; |
---|
.. | .. |
---|
729 | 762 | case V4L2_PIX_FMT_XBGR32: |
---|
730 | 763 | /* Note: not supported on M1 */ |
---|
731 | 764 | dmr = VNDMR_EXRGB; |
---|
| 765 | + break; |
---|
| 766 | + case V4L2_PIX_FMT_ARGB555: |
---|
| 767 | + dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB; |
---|
| 768 | + break; |
---|
| 769 | + case V4L2_PIX_FMT_ABGR32: |
---|
| 770 | + dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB; |
---|
| 771 | + break; |
---|
| 772 | + case V4L2_PIX_FMT_SBGGR8: |
---|
| 773 | + case V4L2_PIX_FMT_SGBRG8: |
---|
| 774 | + case V4L2_PIX_FMT_SGRBG8: |
---|
| 775 | + case V4L2_PIX_FMT_SRGGB8: |
---|
| 776 | + dmr = 0; |
---|
732 | 777 | break; |
---|
733 | 778 | default: |
---|
734 | 779 | vin_err(vin, "Invalid pixelformat (0x%x)\n", |
---|
.. | .. |
---|
788 | 833 | return rvin_read(vin, VNMS_REG) & VNMS_CA; |
---|
789 | 834 | } |
---|
790 | 835 | |
---|
| 836 | +static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) |
---|
| 837 | +{ |
---|
| 838 | + if (vin->format.field == V4L2_FIELD_ALTERNATE) { |
---|
| 839 | + /* If FS is set it is an Even field. */ |
---|
| 840 | + if (vnms & VNMS_FS) |
---|
| 841 | + return V4L2_FIELD_BOTTOM; |
---|
| 842 | + return V4L2_FIELD_TOP; |
---|
| 843 | + } |
---|
| 844 | + |
---|
| 845 | + return vin->format.field; |
---|
| 846 | +} |
---|
| 847 | + |
---|
791 | 848 | static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) |
---|
792 | 849 | { |
---|
793 | 850 | const struct rvin_video_format *fmt; |
---|
794 | 851 | int offsetx, offsety; |
---|
795 | 852 | dma_addr_t offset; |
---|
796 | 853 | |
---|
797 | | - fmt = rvin_format_from_pixel(vin->format.pixelformat); |
---|
| 854 | + fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); |
---|
798 | 855 | |
---|
799 | 856 | /* |
---|
800 | 857 | * There is no HW support for composition do the beast we can |
---|
.. | .. |
---|
825 | 882 | struct rvin_buffer *buf; |
---|
826 | 883 | struct vb2_v4l2_buffer *vbuf; |
---|
827 | 884 | dma_addr_t phys_addr; |
---|
| 885 | + int prev; |
---|
828 | 886 | |
---|
829 | 887 | /* A already populated slot shall never be overwritten. */ |
---|
830 | | - if (WARN_ON(vin->queue_buf[slot] != NULL)) |
---|
| 888 | + if (WARN_ON(vin->buf_hw[slot].buffer)) |
---|
831 | 889 | return; |
---|
832 | 890 | |
---|
833 | | - vin_dbg(vin, "Filling HW slot: %d\n", slot); |
---|
| 891 | + prev = (slot == 0 ? HW_BUFFER_NUM : slot) - 1; |
---|
834 | 892 | |
---|
835 | | - if (list_empty(&vin->buf_list)) { |
---|
836 | | - vin->queue_buf[slot] = NULL; |
---|
| 893 | + if (vin->buf_hw[prev].type == HALF_TOP) { |
---|
| 894 | + vbuf = vin->buf_hw[prev].buffer; |
---|
| 895 | + vin->buf_hw[slot].buffer = vbuf; |
---|
| 896 | + vin->buf_hw[slot].type = HALF_BOTTOM; |
---|
| 897 | + switch (vin->format.pixelformat) { |
---|
| 898 | + case V4L2_PIX_FMT_NV12: |
---|
| 899 | + case V4L2_PIX_FMT_NV16: |
---|
| 900 | + phys_addr = vin->buf_hw[prev].phys + |
---|
| 901 | + vin->format.sizeimage / 4; |
---|
| 902 | + break; |
---|
| 903 | + default: |
---|
| 904 | + phys_addr = vin->buf_hw[prev].phys + |
---|
| 905 | + vin->format.sizeimage / 2; |
---|
| 906 | + break; |
---|
| 907 | + } |
---|
| 908 | + } else if (list_empty(&vin->buf_list)) { |
---|
| 909 | + vin->buf_hw[slot].buffer = NULL; |
---|
| 910 | + vin->buf_hw[slot].type = FULL; |
---|
837 | 911 | phys_addr = vin->scratch_phys; |
---|
838 | 912 | } else { |
---|
839 | 913 | /* Keep track of buffer we give to HW */ |
---|
840 | 914 | buf = list_entry(vin->buf_list.next, struct rvin_buffer, list); |
---|
841 | 915 | vbuf = &buf->vb; |
---|
842 | 916 | list_del_init(to_buf_list(vbuf)); |
---|
843 | | - vin->queue_buf[slot] = vbuf; |
---|
| 917 | + vin->buf_hw[slot].buffer = vbuf; |
---|
| 918 | + |
---|
| 919 | + vin->buf_hw[slot].type = |
---|
| 920 | + V4L2_FIELD_IS_SEQUENTIAL(vin->format.field) ? |
---|
| 921 | + HALF_TOP : FULL; |
---|
844 | 922 | |
---|
845 | 923 | /* Setup DMA */ |
---|
846 | 924 | phys_addr = vb2_dma_contig_plane_dma_addr(&vbuf->vb2_buf, 0); |
---|
847 | 925 | } |
---|
848 | 926 | |
---|
| 927 | + vin_dbg(vin, "Filling HW slot: %d type: %d buffer: %p\n", |
---|
| 928 | + slot, vin->buf_hw[slot].type, vin->buf_hw[slot].buffer); |
---|
| 929 | + |
---|
| 930 | + vin->buf_hw[slot].phys = phys_addr; |
---|
849 | 931 | rvin_set_slot_addr(vin, slot, phys_addr); |
---|
850 | 932 | } |
---|
851 | 933 | |
---|
852 | 934 | static int rvin_capture_start(struct rvin_dev *vin) |
---|
853 | 935 | { |
---|
854 | 936 | int slot, ret; |
---|
| 937 | + |
---|
| 938 | + for (slot = 0; slot < HW_BUFFER_NUM; slot++) { |
---|
| 939 | + vin->buf_hw[slot].buffer = NULL; |
---|
| 940 | + vin->buf_hw[slot].type = FULL; |
---|
| 941 | + } |
---|
855 | 942 | |
---|
856 | 943 | for (slot = 0; slot < HW_BUFFER_NUM; slot++) |
---|
857 | 944 | rvin_fill_hw_slot(vin, slot); |
---|
.. | .. |
---|
936 | 1023 | } |
---|
937 | 1024 | |
---|
938 | 1025 | /* Capture frame */ |
---|
939 | | - if (vin->queue_buf[slot]) { |
---|
940 | | - vin->queue_buf[slot]->field = vin->format.field; |
---|
941 | | - vin->queue_buf[slot]->sequence = vin->sequence; |
---|
942 | | - vin->queue_buf[slot]->vb2_buf.timestamp = ktime_get_ns(); |
---|
943 | | - vb2_buffer_done(&vin->queue_buf[slot]->vb2_buf, |
---|
| 1026 | + if (vin->buf_hw[slot].buffer) { |
---|
| 1027 | + /* |
---|
| 1028 | + * Nothing to do but refill the hardware slot if |
---|
| 1029 | + * capture only filled first half of vb2 buffer. |
---|
| 1030 | + */ |
---|
| 1031 | + if (vin->buf_hw[slot].type == HALF_TOP) { |
---|
| 1032 | + vin->buf_hw[slot].buffer = NULL; |
---|
| 1033 | + rvin_fill_hw_slot(vin, slot); |
---|
| 1034 | + goto done; |
---|
| 1035 | + } |
---|
| 1036 | + |
---|
| 1037 | + vin->buf_hw[slot].buffer->field = |
---|
| 1038 | + rvin_get_active_field(vin, vnms); |
---|
| 1039 | + vin->buf_hw[slot].buffer->sequence = vin->sequence; |
---|
| 1040 | + vin->buf_hw[slot].buffer->vb2_buf.timestamp = ktime_get_ns(); |
---|
| 1041 | + vb2_buffer_done(&vin->buf_hw[slot].buffer->vb2_buf, |
---|
944 | 1042 | VB2_BUF_STATE_DONE); |
---|
945 | | - vin->queue_buf[slot] = NULL; |
---|
| 1043 | + vin->buf_hw[slot].buffer = NULL; |
---|
946 | 1044 | } else { |
---|
947 | 1045 | /* Scratch buffer was used, dropping frame. */ |
---|
948 | 1046 | vin_dbg(vin, "Dropping frame %u\n", vin->sequence); |
---|
.. | .. |
---|
963 | 1061 | enum vb2_buffer_state state) |
---|
964 | 1062 | { |
---|
965 | 1063 | struct rvin_buffer *buf, *node; |
---|
966 | | - int i; |
---|
| 1064 | + struct vb2_v4l2_buffer *freed[HW_BUFFER_NUM]; |
---|
| 1065 | + unsigned int i, n; |
---|
967 | 1066 | |
---|
968 | 1067 | for (i = 0; i < HW_BUFFER_NUM; i++) { |
---|
969 | | - if (vin->queue_buf[i]) { |
---|
970 | | - vb2_buffer_done(&vin->queue_buf[i]->vb2_buf, |
---|
971 | | - state); |
---|
972 | | - vin->queue_buf[i] = NULL; |
---|
| 1068 | + freed[i] = vin->buf_hw[i].buffer; |
---|
| 1069 | + vin->buf_hw[i].buffer = NULL; |
---|
| 1070 | + |
---|
| 1071 | + for (n = 0; n < i; n++) { |
---|
| 1072 | + if (freed[i] == freed[n]) { |
---|
| 1073 | + freed[i] = NULL; |
---|
| 1074 | + break; |
---|
| 1075 | + } |
---|
973 | 1076 | } |
---|
| 1077 | + |
---|
| 1078 | + if (freed[i]) |
---|
| 1079 | + vb2_buffer_done(&freed[i]->vb2_buf, state); |
---|
974 | 1080 | } |
---|
975 | 1081 | |
---|
976 | 1082 | list_for_each_entry_safe(buf, node, &vin->buf_list, list) { |
---|
.. | .. |
---|
1042 | 1148 | case MEDIA_BUS_FMT_UYVY8_2X8: |
---|
1043 | 1149 | case MEDIA_BUS_FMT_UYVY10_2X10: |
---|
1044 | 1150 | case MEDIA_BUS_FMT_RGB888_1X24: |
---|
1045 | | - vin->mbus_code = fmt.format.code; |
---|
| 1151 | + break; |
---|
| 1152 | + case MEDIA_BUS_FMT_SBGGR8_1X8: |
---|
| 1153 | + if (vin->format.pixelformat != V4L2_PIX_FMT_SBGGR8) |
---|
| 1154 | + return -EPIPE; |
---|
| 1155 | + break; |
---|
| 1156 | + case MEDIA_BUS_FMT_SGBRG8_1X8: |
---|
| 1157 | + if (vin->format.pixelformat != V4L2_PIX_FMT_SGBRG8) |
---|
| 1158 | + return -EPIPE; |
---|
| 1159 | + break; |
---|
| 1160 | + case MEDIA_BUS_FMT_SGRBG8_1X8: |
---|
| 1161 | + if (vin->format.pixelformat != V4L2_PIX_FMT_SGRBG8) |
---|
| 1162 | + return -EPIPE; |
---|
| 1163 | + break; |
---|
| 1164 | + case MEDIA_BUS_FMT_SRGGB8_1X8: |
---|
| 1165 | + if (vin->format.pixelformat != V4L2_PIX_FMT_SRGGB8) |
---|
| 1166 | + return -EPIPE; |
---|
1046 | 1167 | break; |
---|
1047 | 1168 | default: |
---|
1048 | 1169 | return -EPIPE; |
---|
1049 | 1170 | } |
---|
| 1171 | + vin->mbus_code = fmt.format.code; |
---|
1050 | 1172 | |
---|
1051 | 1173 | switch (fmt.format.field) { |
---|
1052 | 1174 | case V4L2_FIELD_TOP: |
---|
.. | .. |
---|
1064 | 1186 | case V4L2_FIELD_TOP: |
---|
1065 | 1187 | case V4L2_FIELD_BOTTOM: |
---|
1066 | 1188 | case V4L2_FIELD_NONE: |
---|
| 1189 | + case V4L2_FIELD_ALTERNATE: |
---|
1067 | 1190 | break; |
---|
1068 | 1191 | case V4L2_FIELD_INTERLACED_TB: |
---|
1069 | 1192 | case V4L2_FIELD_INTERLACED_BT: |
---|
.. | .. |
---|
1273 | 1396 | vin->state = STOPPED; |
---|
1274 | 1397 | |
---|
1275 | 1398 | for (i = 0; i < HW_BUFFER_NUM; i++) |
---|
1276 | | - vin->queue_buf[i] = NULL; |
---|
| 1399 | + vin->buf_hw[i].buffer = NULL; |
---|
1277 | 1400 | |
---|
1278 | 1401 | /* buffer queue */ |
---|
1279 | 1402 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
---|
.. | .. |
---|
1343 | 1466 | |
---|
1344 | 1467 | pm_runtime_put(vin->dev); |
---|
1345 | 1468 | |
---|
1346 | | - return ret; |
---|
| 1469 | + return 0; |
---|
| 1470 | +} |
---|
| 1471 | + |
---|
| 1472 | +void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha) |
---|
| 1473 | +{ |
---|
| 1474 | + unsigned long flags; |
---|
| 1475 | + u32 dmr; |
---|
| 1476 | + |
---|
| 1477 | + spin_lock_irqsave(&vin->qlock, flags); |
---|
| 1478 | + |
---|
| 1479 | + vin->alpha = alpha; |
---|
| 1480 | + |
---|
| 1481 | + if (vin->state == STOPPED) |
---|
| 1482 | + goto out; |
---|
| 1483 | + |
---|
| 1484 | + switch (vin->format.pixelformat) { |
---|
| 1485 | + case V4L2_PIX_FMT_ARGB555: |
---|
| 1486 | + dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT; |
---|
| 1487 | + if (vin->alpha) |
---|
| 1488 | + dmr |= VNDMR_ABIT; |
---|
| 1489 | + break; |
---|
| 1490 | + case V4L2_PIX_FMT_ABGR32: |
---|
| 1491 | + dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK; |
---|
| 1492 | + dmr |= VNDMR_A8BIT(vin->alpha); |
---|
| 1493 | + break; |
---|
| 1494 | + default: |
---|
| 1495 | + goto out; |
---|
| 1496 | + } |
---|
| 1497 | + |
---|
| 1498 | + rvin_write(vin, dmr, VNDMR_REG); |
---|
| 1499 | +out: |
---|
| 1500 | + spin_unlock_irqrestore(&vin->qlock, flags); |
---|
1347 | 1501 | } |
---|