1 // SPDX-License-Identifier: GPL-2.0-only
3 * vivid-vid-common.c - common video support functions.
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/videodev2.h>
12 #include <linux/v4l2-dv-timings.h>
13 #include <media/v4l2-common.h>
14 #include <media/v4l2-event.h>
15 #include <media/v4l2-dv-timings.h>
17 #include "vivid-core.h"
18 #include "vivid-vid-common.h"
20 const struct v4l2_dv_timings_cap vivid_dv_timings_cap
= {
21 .type
= V4L2_DV_BT_656_1120
,
22 /* keep this initialization for compatibility with GCC < 4.4.6 */
24 V4L2_INIT_BT_TIMINGS(16, MAX_WIDTH
, 16, MAX_HEIGHT
, 14000000, 775000000,
25 V4L2_DV_BT_STD_CEA861
| V4L2_DV_BT_STD_DMT
|
26 V4L2_DV_BT_STD_CVT
| V4L2_DV_BT_STD_GTF
,
27 V4L2_DV_BT_CAP_PROGRESSIVE
| V4L2_DV_BT_CAP_INTERLACED
)
30 /* ------------------------------------------------------------------
32 ------------------------------------------------------------------*/
34 struct vivid_fmt vivid_formats
[] = {
36 .fourcc
= V4L2_PIX_FMT_YUYV
,
37 .vdownsampling
= { 1 },
39 .color_enc
= TGP_COLOR_ENC_YCBCR
,
42 .data_offset
= { PLANE0_DATA_OFFSET
},
45 .fourcc
= V4L2_PIX_FMT_UYVY
,
46 .vdownsampling
= { 1 },
48 .color_enc
= TGP_COLOR_ENC_YCBCR
,
53 .fourcc
= V4L2_PIX_FMT_YVYU
,
54 .vdownsampling
= { 1 },
56 .color_enc
= TGP_COLOR_ENC_YCBCR
,
61 .fourcc
= V4L2_PIX_FMT_VYUY
,
62 .vdownsampling
= { 1 },
64 .color_enc
= TGP_COLOR_ENC_YCBCR
,
69 .fourcc
= V4L2_PIX_FMT_YUV422P
,
70 .vdownsampling
= { 1, 1, 1 },
71 .bit_depth
= { 8, 4, 4 },
72 .color_enc
= TGP_COLOR_ENC_YCBCR
,
77 .fourcc
= V4L2_PIX_FMT_YUV420
,
78 .vdownsampling
= { 1, 2, 2 },
79 .bit_depth
= { 8, 4, 4 },
80 .color_enc
= TGP_COLOR_ENC_YCBCR
,
85 .fourcc
= V4L2_PIX_FMT_YVU420
,
86 .vdownsampling
= { 1, 2, 2 },
87 .bit_depth
= { 8, 4, 4 },
88 .color_enc
= TGP_COLOR_ENC_YCBCR
,
93 .fourcc
= V4L2_PIX_FMT_NV12
,
94 .vdownsampling
= { 1, 2 },
95 .bit_depth
= { 8, 8 },
96 .color_enc
= TGP_COLOR_ENC_YCBCR
,
101 .fourcc
= V4L2_PIX_FMT_NV21
,
102 .vdownsampling
= { 1, 2 },
103 .bit_depth
= { 8, 8 },
104 .color_enc
= TGP_COLOR_ENC_YCBCR
,
109 .fourcc
= V4L2_PIX_FMT_NV16
,
110 .vdownsampling
= { 1, 1 },
111 .bit_depth
= { 8, 8 },
112 .color_enc
= TGP_COLOR_ENC_YCBCR
,
117 .fourcc
= V4L2_PIX_FMT_NV61
,
118 .vdownsampling
= { 1, 1 },
119 .bit_depth
= { 8, 8 },
120 .color_enc
= TGP_COLOR_ENC_YCBCR
,
125 .fourcc
= V4L2_PIX_FMT_NV24
,
126 .vdownsampling
= { 1, 1 },
127 .bit_depth
= { 8, 16 },
128 .color_enc
= TGP_COLOR_ENC_YCBCR
,
133 .fourcc
= V4L2_PIX_FMT_NV42
,
134 .vdownsampling
= { 1, 1 },
135 .bit_depth
= { 8, 16 },
136 .color_enc
= TGP_COLOR_ENC_YCBCR
,
141 .fourcc
= V4L2_PIX_FMT_YUV555
, /* uuuvvvvv ayyyyyuu */
142 .vdownsampling
= { 1 },
146 .alpha_mask
= 0x8000,
149 .fourcc
= V4L2_PIX_FMT_YUV565
, /* uuuvvvvv yyyyyuuu */
150 .vdownsampling
= { 1 },
156 .fourcc
= V4L2_PIX_FMT_YUV444
, /* uuuuvvvv aaaayyyy */
157 .vdownsampling
= { 1 },
161 .alpha_mask
= 0xf000,
164 .fourcc
= V4L2_PIX_FMT_YUV32
, /* ayuv */
165 .vdownsampling
= { 1 },
169 .alpha_mask
= 0x000000ff,
172 .fourcc
= V4L2_PIX_FMT_AYUV32
,
173 .vdownsampling
= { 1 },
177 .alpha_mask
= 0x000000ff,
180 .fourcc
= V4L2_PIX_FMT_XYUV32
,
181 .vdownsampling
= { 1 },
187 .fourcc
= V4L2_PIX_FMT_VUYA32
,
188 .vdownsampling
= { 1 },
192 .alpha_mask
= 0xff000000,
195 .fourcc
= V4L2_PIX_FMT_VUYX32
,
196 .vdownsampling
= { 1 },
202 .fourcc
= V4L2_PIX_FMT_GREY
,
203 .vdownsampling
= { 1 },
205 .color_enc
= TGP_COLOR_ENC_LUMA
,
210 .fourcc
= V4L2_PIX_FMT_Y10
,
211 .vdownsampling
= { 1 },
213 .color_enc
= TGP_COLOR_ENC_LUMA
,
218 .fourcc
= V4L2_PIX_FMT_Y12
,
219 .vdownsampling
= { 1 },
221 .color_enc
= TGP_COLOR_ENC_LUMA
,
226 .fourcc
= V4L2_PIX_FMT_Y16
,
227 .vdownsampling
= { 1 },
229 .color_enc
= TGP_COLOR_ENC_LUMA
,
234 .fourcc
= V4L2_PIX_FMT_Y16_BE
,
235 .vdownsampling
= { 1 },
237 .color_enc
= TGP_COLOR_ENC_LUMA
,
242 .fourcc
= V4L2_PIX_FMT_RGB332
, /* rrrgggbb */
243 .vdownsampling
= { 1 },
249 .fourcc
= V4L2_PIX_FMT_RGB565
, /* gggbbbbb rrrrrggg */
250 .vdownsampling
= { 1 },
254 .can_do_overlay
= true,
257 .fourcc
= V4L2_PIX_FMT_RGB565X
, /* rrrrrggg gggbbbbb */
258 .vdownsampling
= { 1 },
262 .can_do_overlay
= true,
265 .fourcc
= V4L2_PIX_FMT_RGB444
, /* ggggbbbb xxxxrrrr */
266 .vdownsampling
= { 1 },
272 .fourcc
= V4L2_PIX_FMT_XRGB444
, /* ggggbbbb xxxxrrrr */
273 .vdownsampling
= { 1 },
279 .fourcc
= V4L2_PIX_FMT_ARGB444
, /* ggggbbbb aaaarrrr */
280 .vdownsampling
= { 1 },
284 .alpha_mask
= 0x00f0,
287 .fourcc
= V4L2_PIX_FMT_RGBX444
, /* bbbbxxxx rrrrgggg */
288 .vdownsampling
= { 1 },
294 .fourcc
= V4L2_PIX_FMT_RGBA444
, /* bbbbaaaa rrrrgggg */
295 .vdownsampling
= { 1 },
299 .alpha_mask
= 0x00f0,
302 .fourcc
= V4L2_PIX_FMT_XBGR444
, /* ggggrrrr xxxxbbbb */
303 .vdownsampling
= { 1 },
309 .fourcc
= V4L2_PIX_FMT_ABGR444
, /* ggggrrrr aaaabbbb */
310 .vdownsampling
= { 1 },
314 .alpha_mask
= 0x00f0,
317 .fourcc
= V4L2_PIX_FMT_BGRX444
, /* rrrrxxxx bbbbgggg */
318 .vdownsampling
= { 1 },
324 .fourcc
= V4L2_PIX_FMT_BGRA444
, /* rrrraaaa bbbbgggg */
325 .vdownsampling
= { 1 },
329 .alpha_mask
= 0x00f0,
332 .fourcc
= V4L2_PIX_FMT_RGB555
, /* gggbbbbb xrrrrrgg */
333 .vdownsampling
= { 1 },
337 .can_do_overlay
= true,
340 .fourcc
= V4L2_PIX_FMT_XRGB555
, /* gggbbbbb xrrrrrgg */
341 .vdownsampling
= { 1 },
345 .can_do_overlay
= true,
348 .fourcc
= V4L2_PIX_FMT_ARGB555
, /* gggbbbbb arrrrrgg */
349 .vdownsampling
= { 1 },
353 .can_do_overlay
= true,
354 .alpha_mask
= 0x8000,
357 .fourcc
= V4L2_PIX_FMT_RGBX555
, /* ggbbbbbx rrrrrggg */
358 .vdownsampling
= { 1 },
362 .can_do_overlay
= true,
365 .fourcc
= V4L2_PIX_FMT_RGBA555
, /* ggbbbbba rrrrrggg */
366 .vdownsampling
= { 1 },
370 .can_do_overlay
= true,
371 .alpha_mask
= 0x8000,
374 .fourcc
= V4L2_PIX_FMT_XBGR555
, /* gggrrrrr xbbbbbgg */
375 .vdownsampling
= { 1 },
379 .can_do_overlay
= true,
382 .fourcc
= V4L2_PIX_FMT_ABGR555
, /* gggrrrrr abbbbbgg */
383 .vdownsampling
= { 1 },
387 .can_do_overlay
= true,
388 .alpha_mask
= 0x8000,
391 .fourcc
= V4L2_PIX_FMT_BGRX555
, /* ggrrrrrx bbbbbggg */
392 .vdownsampling
= { 1 },
396 .can_do_overlay
= true,
399 .fourcc
= V4L2_PIX_FMT_BGRA555
, /* ggrrrrra bbbbbggg */
400 .vdownsampling
= { 1 },
404 .can_do_overlay
= true,
405 .alpha_mask
= 0x8000,
408 .fourcc
= V4L2_PIX_FMT_RGB555X
, /* xrrrrrgg gggbbbbb */
409 .vdownsampling
= { 1 },
415 .fourcc
= V4L2_PIX_FMT_XRGB555X
, /* xrrrrrgg gggbbbbb */
416 .vdownsampling
= { 1 },
422 .fourcc
= V4L2_PIX_FMT_ARGB555X
, /* arrrrrgg gggbbbbb */
423 .vdownsampling
= { 1 },
427 .alpha_mask
= 0x0080,
430 .fourcc
= V4L2_PIX_FMT_RGB24
, /* rgb */
431 .vdownsampling
= { 1 },
437 .fourcc
= V4L2_PIX_FMT_BGR24
, /* bgr */
438 .vdownsampling
= { 1 },
444 .fourcc
= V4L2_PIX_FMT_BGR666
, /* bbbbbbgg ggggrrrr rrxxxxxx */
445 .vdownsampling
= { 1 },
451 .fourcc
= V4L2_PIX_FMT_RGB32
, /* xrgb */
452 .vdownsampling
= { 1 },
458 .fourcc
= V4L2_PIX_FMT_BGR32
, /* bgrx */
459 .vdownsampling
= { 1 },
465 .fourcc
= V4L2_PIX_FMT_XRGB32
, /* xrgb */
466 .vdownsampling
= { 1 },
472 .fourcc
= V4L2_PIX_FMT_XBGR32
, /* bgrx */
473 .vdownsampling
= { 1 },
479 .fourcc
= V4L2_PIX_FMT_ARGB32
, /* argb */
480 .vdownsampling
= { 1 },
484 .alpha_mask
= 0x000000ff,
487 .fourcc
= V4L2_PIX_FMT_ABGR32
, /* bgra */
488 .vdownsampling
= { 1 },
492 .alpha_mask
= 0xff000000,
495 .fourcc
= V4L2_PIX_FMT_RGBX32
, /* rgbx */
496 .vdownsampling
= { 1 },
502 .fourcc
= V4L2_PIX_FMT_BGRX32
, /* xbgr */
503 .vdownsampling
= { 1 },
509 .fourcc
= V4L2_PIX_FMT_RGBA32
, /* rgba */
510 .vdownsampling
= { 1 },
514 .alpha_mask
= 0x000000ff,
517 .fourcc
= V4L2_PIX_FMT_BGRA32
, /* abgr */
518 .vdownsampling
= { 1 },
522 .alpha_mask
= 0xff000000,
525 .fourcc
= V4L2_PIX_FMT_SBGGR8
, /* Bayer BG/GR */
526 .vdownsampling
= { 1 },
532 .fourcc
= V4L2_PIX_FMT_SGBRG8
, /* Bayer GB/RG */
533 .vdownsampling
= { 1 },
539 .fourcc
= V4L2_PIX_FMT_SGRBG8
, /* Bayer GR/BG */
540 .vdownsampling
= { 1 },
546 .fourcc
= V4L2_PIX_FMT_SRGGB8
, /* Bayer RG/GB */
547 .vdownsampling
= { 1 },
553 .fourcc
= V4L2_PIX_FMT_SBGGR10
, /* Bayer BG/GR */
554 .vdownsampling
= { 1 },
560 .fourcc
= V4L2_PIX_FMT_SGBRG10
, /* Bayer GB/RG */
561 .vdownsampling
= { 1 },
567 .fourcc
= V4L2_PIX_FMT_SGRBG10
, /* Bayer GR/BG */
568 .vdownsampling
= { 1 },
574 .fourcc
= V4L2_PIX_FMT_SRGGB10
, /* Bayer RG/GB */
575 .vdownsampling
= { 1 },
581 .fourcc
= V4L2_PIX_FMT_SBGGR12
, /* Bayer BG/GR */
582 .vdownsampling
= { 1 },
588 .fourcc
= V4L2_PIX_FMT_SGBRG12
, /* Bayer GB/RG */
589 .vdownsampling
= { 1 },
595 .fourcc
= V4L2_PIX_FMT_SGRBG12
, /* Bayer GR/BG */
596 .vdownsampling
= { 1 },
602 .fourcc
= V4L2_PIX_FMT_SRGGB12
, /* Bayer RG/GB */
603 .vdownsampling
= { 1 },
609 .fourcc
= V4L2_PIX_FMT_SBGGR16
, /* Bayer BG/GR */
610 .vdownsampling
= { 1 },
616 .fourcc
= V4L2_PIX_FMT_SGBRG16
, /* Bayer GB/RG */
617 .vdownsampling
= { 1 },
623 .fourcc
= V4L2_PIX_FMT_SGRBG16
, /* Bayer GR/BG */
624 .vdownsampling
= { 1 },
630 .fourcc
= V4L2_PIX_FMT_SRGGB16
, /* Bayer RG/GB */
631 .vdownsampling
= { 1 },
637 .fourcc
= V4L2_PIX_FMT_HSV24
, /* HSV 24bits */
638 .color_enc
= TGP_COLOR_ENC_HSV
,
639 .vdownsampling
= { 1 },
645 .fourcc
= V4L2_PIX_FMT_HSV32
, /* HSV 32bits */
646 .color_enc
= TGP_COLOR_ENC_HSV
,
647 .vdownsampling
= { 1 },
653 /* Multiplanar formats */
656 .fourcc
= V4L2_PIX_FMT_NV16M
,
657 .vdownsampling
= { 1, 1 },
658 .bit_depth
= { 8, 8 },
659 .color_enc
= TGP_COLOR_ENC_YCBCR
,
662 .data_offset
= { PLANE0_DATA_OFFSET
, 0 },
665 .fourcc
= V4L2_PIX_FMT_NV61M
,
666 .vdownsampling
= { 1, 1 },
667 .bit_depth
= { 8, 8 },
668 .color_enc
= TGP_COLOR_ENC_YCBCR
,
671 .data_offset
= { 0, PLANE0_DATA_OFFSET
},
674 .fourcc
= V4L2_PIX_FMT_YUV420M
,
675 .vdownsampling
= { 1, 2, 2 },
676 .bit_depth
= { 8, 4, 4 },
677 .color_enc
= TGP_COLOR_ENC_YCBCR
,
682 .fourcc
= V4L2_PIX_FMT_YVU420M
,
683 .vdownsampling
= { 1, 2, 2 },
684 .bit_depth
= { 8, 4, 4 },
685 .color_enc
= TGP_COLOR_ENC_YCBCR
,
690 .fourcc
= V4L2_PIX_FMT_NV12M
,
691 .vdownsampling
= { 1, 2 },
692 .bit_depth
= { 8, 8 },
693 .color_enc
= TGP_COLOR_ENC_YCBCR
,
698 .fourcc
= V4L2_PIX_FMT_NV21M
,
699 .vdownsampling
= { 1, 2 },
700 .bit_depth
= { 8, 8 },
701 .color_enc
= TGP_COLOR_ENC_YCBCR
,
706 .fourcc
= V4L2_PIX_FMT_YUV422M
,
707 .vdownsampling
= { 1, 1, 1 },
708 .bit_depth
= { 8, 4, 4 },
709 .color_enc
= TGP_COLOR_ENC_YCBCR
,
714 .fourcc
= V4L2_PIX_FMT_YVU422M
,
715 .vdownsampling
= { 1, 1, 1 },
716 .bit_depth
= { 8, 4, 4 },
717 .color_enc
= TGP_COLOR_ENC_YCBCR
,
722 .fourcc
= V4L2_PIX_FMT_YUV444M
,
723 .vdownsampling
= { 1, 1, 1 },
724 .bit_depth
= { 8, 8, 8 },
725 .color_enc
= TGP_COLOR_ENC_YCBCR
,
730 .fourcc
= V4L2_PIX_FMT_YVU444M
,
731 .vdownsampling
= { 1, 1, 1 },
732 .bit_depth
= { 8, 8, 8 },
733 .color_enc
= TGP_COLOR_ENC_YCBCR
,
739 /* There are this many multiplanar formats in the list */
740 #define VIVID_MPLANAR_FORMATS 10
742 const struct vivid_fmt
*vivid_get_format(struct vivid_dev
*dev
, u32 pixelformat
)
744 const struct vivid_fmt
*fmt
;
747 for (k
= 0; k
< ARRAY_SIZE(vivid_formats
); k
++) {
748 fmt
= &vivid_formats
[k
];
749 if (fmt
->fourcc
== pixelformat
)
750 if (fmt
->buffers
== 1 || dev
->multiplanar
)
757 bool vivid_vid_can_loop(struct vivid_dev
*dev
)
759 if (dev
->src_rect
.width
!= dev
->sink_rect
.width
||
760 dev
->src_rect
.height
!= dev
->sink_rect
.height
)
762 if (dev
->fmt_cap
->fourcc
!= dev
->fmt_out
->fourcc
)
764 if (dev
->field_cap
!= dev
->field_out
)
767 * While this can be supported, it is just too much work
768 * to actually implement.
770 if (dev
->field_cap
== V4L2_FIELD_SEQ_TB
||
771 dev
->field_cap
== V4L2_FIELD_SEQ_BT
)
773 if (vivid_is_svid_cap(dev
) && vivid_is_svid_out(dev
)) {
774 if (!(dev
->std_cap
[dev
->input
] & V4L2_STD_525_60
) !=
775 !(dev
->std_out
& V4L2_STD_525_60
))
779 if (vivid_is_hdmi_cap(dev
) && vivid_is_hdmi_out(dev
))
784 void vivid_send_source_change(struct vivid_dev
*dev
, unsigned type
)
786 struct v4l2_event ev
= {
787 .type
= V4L2_EVENT_SOURCE_CHANGE
,
788 .u
.src_change
.changes
= V4L2_EVENT_SRC_CH_RESOLUTION
,
792 for (i
= 0; i
< dev
->num_inputs
; i
++) {
794 if (dev
->input_type
[i
] == type
) {
795 if (video_is_registered(&dev
->vid_cap_dev
) && dev
->has_vid_cap
)
796 v4l2_event_queue(&dev
->vid_cap_dev
, &ev
);
797 if (video_is_registered(&dev
->vbi_cap_dev
) && dev
->has_vbi_cap
)
798 v4l2_event_queue(&dev
->vbi_cap_dev
, &ev
);
804 * Conversion function that converts a single-planar format to a
805 * single-plane multiplanar format.
807 void fmt_sp2mp(const struct v4l2_format
*sp_fmt
, struct v4l2_format
*mp_fmt
)
809 struct v4l2_pix_format_mplane
*mp
= &mp_fmt
->fmt
.pix_mp
;
810 struct v4l2_plane_pix_format
*ppix
= &mp
->plane_fmt
[0];
811 const struct v4l2_pix_format
*pix
= &sp_fmt
->fmt
.pix
;
812 bool is_out
= sp_fmt
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
;
814 memset(mp
->reserved
, 0, sizeof(mp
->reserved
));
815 mp_fmt
->type
= is_out
? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
816 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
817 mp
->width
= pix
->width
;
818 mp
->height
= pix
->height
;
819 mp
->pixelformat
= pix
->pixelformat
;
820 mp
->field
= pix
->field
;
821 mp
->colorspace
= pix
->colorspace
;
822 mp
->xfer_func
= pix
->xfer_func
;
823 /* Also copies hsv_enc */
824 mp
->ycbcr_enc
= pix
->ycbcr_enc
;
825 mp
->quantization
= pix
->quantization
;
827 mp
->flags
= pix
->flags
;
828 ppix
->sizeimage
= pix
->sizeimage
;
829 ppix
->bytesperline
= pix
->bytesperline
;
830 memset(ppix
->reserved
, 0, sizeof(ppix
->reserved
));
833 int fmt_sp2mp_func(struct file
*file
, void *priv
,
834 struct v4l2_format
*f
, fmtfunc func
)
836 struct v4l2_format fmt
;
837 struct v4l2_pix_format_mplane
*mp
= &fmt
.fmt
.pix_mp
;
838 struct v4l2_plane_pix_format
*ppix
= &mp
->plane_fmt
[0];
839 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
842 /* Converts to a mplane format */
844 /* Passes it to the generic mplane format function */
845 ret
= func(file
, priv
, &fmt
);
846 /* Copies back the mplane data to the single plane format */
847 pix
->width
= mp
->width
;
848 pix
->height
= mp
->height
;
849 pix
->pixelformat
= mp
->pixelformat
;
850 pix
->field
= mp
->field
;
851 pix
->colorspace
= mp
->colorspace
;
852 pix
->xfer_func
= mp
->xfer_func
;
853 /* Also copies hsv_enc */
854 pix
->ycbcr_enc
= mp
->ycbcr_enc
;
855 pix
->quantization
= mp
->quantization
;
856 pix
->sizeimage
= ppix
->sizeimage
;
857 pix
->bytesperline
= ppix
->bytesperline
;
858 pix
->flags
= mp
->flags
;
862 int vivid_vid_adjust_sel(unsigned flags
, struct v4l2_rect
*r
)
864 unsigned w
= r
->width
;
865 unsigned h
= r
->height
;
867 /* sanitize w and h in case someone passes ~0 as the value */
870 if (!(flags
& V4L2_SEL_FLAG_LE
)) {
878 if (!(flags
& V4L2_SEL_FLAG_GE
)) {
888 if (w
> MAX_WIDTH
|| h
> MAX_HEIGHT
)
894 /* sanitize left and top in case someone passes ~0 as the value */
897 if (r
->left
+ w
> MAX_WIDTH
)
898 r
->left
= MAX_WIDTH
- w
;
899 if (r
->top
+ h
> MAX_HEIGHT
)
900 r
->top
= MAX_HEIGHT
- h
;
901 if ((flags
& (V4L2_SEL_FLAG_GE
| V4L2_SEL_FLAG_LE
)) ==
902 (V4L2_SEL_FLAG_GE
| V4L2_SEL_FLAG_LE
) &&
903 (r
->width
!= w
|| r
->height
!= h
))
910 int vivid_enum_fmt_vid(struct file
*file
, void *priv
,
911 struct v4l2_fmtdesc
*f
)
913 struct vivid_dev
*dev
= video_drvdata(file
);
914 const struct vivid_fmt
*fmt
;
916 if (f
->index
>= ARRAY_SIZE(vivid_formats
) -
917 (dev
->multiplanar
? 0 : VIVID_MPLANAR_FORMATS
))
920 fmt
= &vivid_formats
[f
->index
];
922 f
->pixelformat
= fmt
->fourcc
;
924 if (f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
&&
925 f
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
)
928 * For capture devices, we support the CSC API.
929 * We allow userspace to:
930 * 1. set the colorspace
931 * 2. set the xfer_func
932 * 3. set the ycbcr_enc on YUV formats
933 * 4. set the hsv_enc on HSV formats
934 * 5. set the quantization on YUV and RGB formats
936 f
->flags
|= V4L2_FMT_FLAG_CSC_COLORSPACE
;
937 f
->flags
|= V4L2_FMT_FLAG_CSC_XFER_FUNC
;
939 if (fmt
->color_enc
== TGP_COLOR_ENC_YCBCR
) {
940 f
->flags
|= V4L2_FMT_FLAG_CSC_YCBCR_ENC
;
941 f
->flags
|= V4L2_FMT_FLAG_CSC_QUANTIZATION
;
942 } else if (fmt
->color_enc
== TGP_COLOR_ENC_HSV
) {
943 f
->flags
|= V4L2_FMT_FLAG_CSC_HSV_ENC
;
944 } else if (fmt
->color_enc
== TGP_COLOR_ENC_RGB
) {
945 f
->flags
|= V4L2_FMT_FLAG_CSC_QUANTIZATION
;
951 int vidioc_g_std(struct file
*file
, void *priv
, v4l2_std_id
*id
)
953 struct vivid_dev
*dev
= video_drvdata(file
);
954 struct video_device
*vdev
= video_devdata(file
);
956 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
957 if (!vivid_is_sdtv_cap(dev
))
959 *id
= dev
->std_cap
[dev
->input
];
961 if (!vivid_is_svid_out(dev
))
968 int vidioc_g_dv_timings(struct file
*file
, void *_fh
,
969 struct v4l2_dv_timings
*timings
)
971 struct vivid_dev
*dev
= video_drvdata(file
);
972 struct video_device
*vdev
= video_devdata(file
);
974 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
975 if (!vivid_is_hdmi_cap(dev
))
977 *timings
= dev
->dv_timings_cap
[dev
->input
];
979 if (!vivid_is_hdmi_out(dev
))
981 *timings
= dev
->dv_timings_out
;
986 int vidioc_enum_dv_timings(struct file
*file
, void *_fh
,
987 struct v4l2_enum_dv_timings
*timings
)
989 struct vivid_dev
*dev
= video_drvdata(file
);
990 struct video_device
*vdev
= video_devdata(file
);
992 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
993 if (!vivid_is_hdmi_cap(dev
))
996 if (!vivid_is_hdmi_out(dev
))
999 return v4l2_enum_dv_timings_cap(timings
, &vivid_dv_timings_cap
,
1003 int vidioc_dv_timings_cap(struct file
*file
, void *_fh
,
1004 struct v4l2_dv_timings_cap
*cap
)
1006 struct vivid_dev
*dev
= video_drvdata(file
);
1007 struct video_device
*vdev
= video_devdata(file
);
1009 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
1010 if (!vivid_is_hdmi_cap(dev
))
1013 if (!vivid_is_hdmi_out(dev
))
1016 *cap
= vivid_dv_timings_cap
;
1020 int vidioc_g_edid(struct file
*file
, void *_fh
,
1021 struct v4l2_edid
*edid
)
1023 struct vivid_dev
*dev
= video_drvdata(file
);
1024 struct video_device
*vdev
= video_devdata(file
);
1025 struct cec_adapter
*adap
;
1027 memset(edid
->reserved
, 0, sizeof(edid
->reserved
));
1028 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
1029 if (edid
->pad
>= dev
->num_inputs
)
1031 if (dev
->input_type
[edid
->pad
] != HDMI
)
1033 adap
= dev
->cec_rx_adap
;
1035 unsigned int bus_idx
;
1037 if (edid
->pad
>= dev
->num_outputs
)
1039 if (dev
->output_type
[edid
->pad
] != HDMI
)
1041 if (!dev
->display_present
[edid
->pad
])
1043 bus_idx
= dev
->cec_output2bus_map
[edid
->pad
];
1044 adap
= dev
->cec_tx_adap
[bus_idx
];
1046 if (edid
->start_block
== 0 && edid
->blocks
== 0) {
1047 edid
->blocks
= dev
->edid_blocks
;
1050 if (dev
->edid_blocks
== 0)
1052 if (edid
->start_block
>= dev
->edid_blocks
)
1054 if (edid
->blocks
> dev
->edid_blocks
- edid
->start_block
)
1055 edid
->blocks
= dev
->edid_blocks
- edid
->start_block
;
1057 v4l2_set_edid_phys_addr(dev
->edid
, dev
->edid_blocks
* 128, adap
->phys_addr
);
1058 memcpy(edid
->edid
, dev
->edid
+ edid
->start_block
* 128, edid
->blocks
* 128);