2 * vivid-vid-common.c - common video support functions.
4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6 * This program is free software; you may redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 #include <linux/errno.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/videodev2.h>
24 #include <linux/v4l2-dv-timings.h>
25 #include <media/v4l2-common.h>
26 #include <media/v4l2-event.h>
27 #include <media/v4l2-dv-timings.h>
29 #include "vivid-core.h"
30 #include "vivid-vid-common.h"
32 const struct v4l2_dv_timings_cap vivid_dv_timings_cap
= {
33 .type
= V4L2_DV_BT_656_1120
,
34 /* keep this initialization for compatibility with GCC < 4.4.6 */
36 V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH
, 0, MAX_HEIGHT
, 25000000, 600000000,
37 V4L2_DV_BT_STD_CEA861
| V4L2_DV_BT_STD_DMT
,
38 V4L2_DV_BT_CAP_PROGRESSIVE
| V4L2_DV_BT_CAP_INTERLACED
)
41 /* ------------------------------------------------------------------
43 ------------------------------------------------------------------*/
45 struct vivid_fmt vivid_formats
[] = {
47 .name
= "4:2:2, packed, YUYV",
48 .fourcc
= V4L2_PIX_FMT_YUYV
,
49 .vdownsampling
= { 1 },
54 .data_offset
= { PLANE0_DATA_OFFSET
},
57 .name
= "4:2:2, packed, UYVY",
58 .fourcc
= V4L2_PIX_FMT_UYVY
,
59 .vdownsampling
= { 1 },
66 .name
= "4:2:2, packed, YVYU",
67 .fourcc
= V4L2_PIX_FMT_YVYU
,
68 .vdownsampling
= { 1 },
75 .name
= "4:2:2, packed, VYUY",
76 .fourcc
= V4L2_PIX_FMT_VYUY
,
77 .vdownsampling
= { 1 },
84 .name
= "YUV 4:2:2 triplanar",
85 .fourcc
= V4L2_PIX_FMT_YUV422P
,
86 .vdownsampling
= { 1, 1, 1 },
87 .bit_depth
= { 8, 4, 4 },
93 .name
= "YUV 4:2:0 triplanar",
94 .fourcc
= V4L2_PIX_FMT_YUV420
,
95 .vdownsampling
= { 1, 2, 2 },
96 .bit_depth
= { 8, 4, 4 },
102 .name
= "YVU 4:2:0 triplanar",
103 .fourcc
= V4L2_PIX_FMT_YVU420
,
104 .vdownsampling
= { 1, 2, 2 },
105 .bit_depth
= { 8, 4, 4 },
111 .name
= "YUV 4:2:0 biplanar",
112 .fourcc
= V4L2_PIX_FMT_NV12
,
113 .vdownsampling
= { 1, 2 },
114 .bit_depth
= { 8, 8 },
120 .name
= "YVU 4:2:0 biplanar",
121 .fourcc
= V4L2_PIX_FMT_NV21
,
122 .vdownsampling
= { 1, 2 },
123 .bit_depth
= { 8, 8 },
129 .name
= "YUV 4:2:2 biplanar",
130 .fourcc
= V4L2_PIX_FMT_NV16
,
131 .vdownsampling
= { 1, 1 },
132 .bit_depth
= { 8, 8 },
138 .name
= "YVU 4:2:2 biplanar",
139 .fourcc
= V4L2_PIX_FMT_NV61
,
140 .vdownsampling
= { 1, 1 },
141 .bit_depth
= { 8, 8 },
147 .name
= "YUV 4:4:4 biplanar",
148 .fourcc
= V4L2_PIX_FMT_NV24
,
149 .vdownsampling
= { 1, 1 },
150 .bit_depth
= { 8, 16 },
156 .name
= "YVU 4:4:4 biplanar",
157 .fourcc
= V4L2_PIX_FMT_NV42
,
158 .vdownsampling
= { 1, 1 },
159 .bit_depth
= { 8, 16 },
165 .name
= "YUV555 (LE)",
166 .fourcc
= V4L2_PIX_FMT_YUV555
, /* uuuvvvvv ayyyyyuu */
167 .vdownsampling
= { 1 },
171 .alpha_mask
= 0x8000,
174 .name
= "YUV565 (LE)",
175 .fourcc
= V4L2_PIX_FMT_YUV565
, /* uuuvvvvv yyyyyuuu */
176 .vdownsampling
= { 1 },
183 .fourcc
= V4L2_PIX_FMT_YUV444
, /* uuuuvvvv aaaayyyy */
184 .vdownsampling
= { 1 },
188 .alpha_mask
= 0xf000,
191 .name
= "YUV32 (LE)",
192 .fourcc
= V4L2_PIX_FMT_YUV32
, /* ayuv */
193 .vdownsampling
= { 1 },
197 .alpha_mask
= 0x000000ff,
200 .name
= "Monochrome",
201 .fourcc
= V4L2_PIX_FMT_GREY
,
202 .vdownsampling
= { 1 },
210 .fourcc
= V4L2_PIX_FMT_RGB332
, /* rrrgggbb */
211 .vdownsampling
= { 1 },
217 .name
= "RGB565 (LE)",
218 .fourcc
= V4L2_PIX_FMT_RGB565
, /* gggbbbbb rrrrrggg */
219 .vdownsampling
= { 1 },
223 .can_do_overlay
= true,
226 .name
= "RGB565 (BE)",
227 .fourcc
= V4L2_PIX_FMT_RGB565X
, /* rrrrrggg gggbbbbb */
228 .vdownsampling
= { 1 },
232 .can_do_overlay
= true,
236 .fourcc
= V4L2_PIX_FMT_RGB444
, /* xxxxrrrr ggggbbbb */
237 .vdownsampling
= { 1 },
244 .fourcc
= V4L2_PIX_FMT_XRGB444
, /* xxxxrrrr ggggbbbb */
245 .vdownsampling
= { 1 },
252 .fourcc
= V4L2_PIX_FMT_ARGB444
, /* aaaarrrr ggggbbbb */
253 .vdownsampling
= { 1 },
257 .alpha_mask
= 0x00f0,
260 .name
= "RGB555 (LE)",
261 .fourcc
= V4L2_PIX_FMT_RGB555
, /* gggbbbbb xrrrrrgg */
262 .vdownsampling
= { 1 },
266 .can_do_overlay
= true,
269 .name
= "XRGB555 (LE)",
270 .fourcc
= V4L2_PIX_FMT_XRGB555
, /* gggbbbbb xrrrrrgg */
271 .vdownsampling
= { 1 },
275 .can_do_overlay
= true,
278 .name
= "ARGB555 (LE)",
279 .fourcc
= V4L2_PIX_FMT_ARGB555
, /* gggbbbbb arrrrrgg */
280 .vdownsampling
= { 1 },
284 .can_do_overlay
= true,
285 .alpha_mask
= 0x8000,
288 .name
= "RGB555 (BE)",
289 .fourcc
= V4L2_PIX_FMT_RGB555X
, /* xrrrrrgg gggbbbbb */
290 .vdownsampling
= { 1 },
296 .name
= "XRGB555 (BE)",
297 .fourcc
= V4L2_PIX_FMT_XRGB555X
, /* xrrrrrgg gggbbbbb */
298 .vdownsampling
= { 1 },
304 .name
= "ARGB555 (BE)",
305 .fourcc
= V4L2_PIX_FMT_ARGB555X
, /* arrrrrgg gggbbbbb */
306 .vdownsampling
= { 1 },
310 .alpha_mask
= 0x0080,
313 .name
= "RGB24 (LE)",
314 .fourcc
= V4L2_PIX_FMT_RGB24
, /* rgb */
315 .vdownsampling
= { 1 },
321 .name
= "RGB24 (BE)",
322 .fourcc
= V4L2_PIX_FMT_BGR24
, /* bgr */
323 .vdownsampling
= { 1 },
330 .fourcc
= V4L2_PIX_FMT_BGR666
, /* bbbbbbgg ggggrrrr rrxxxxxx */
331 .vdownsampling
= { 1 },
337 .name
= "RGB32 (LE)",
338 .fourcc
= V4L2_PIX_FMT_RGB32
, /* xrgb */
339 .vdownsampling
= { 1 },
345 .name
= "RGB32 (BE)",
346 .fourcc
= V4L2_PIX_FMT_BGR32
, /* bgrx */
347 .vdownsampling
= { 1 },
353 .name
= "XRGB32 (LE)",
354 .fourcc
= V4L2_PIX_FMT_XRGB32
, /* xrgb */
355 .vdownsampling
= { 1 },
361 .name
= "XRGB32 (BE)",
362 .fourcc
= V4L2_PIX_FMT_XBGR32
, /* bgrx */
363 .vdownsampling
= { 1 },
369 .name
= "ARGB32 (LE)",
370 .fourcc
= V4L2_PIX_FMT_ARGB32
, /* argb */
371 .vdownsampling
= { 1 },
375 .alpha_mask
= 0x000000ff,
378 .name
= "ARGB32 (BE)",
379 .fourcc
= V4L2_PIX_FMT_ABGR32
, /* bgra */
380 .vdownsampling
= { 1 },
384 .alpha_mask
= 0xff000000,
387 .name
= "4:2:2, biplanar, YUV",
388 .fourcc
= V4L2_PIX_FMT_NV16M
,
389 .vdownsampling
= { 1, 1 },
390 .bit_depth
= { 8, 8 },
394 .data_offset
= { PLANE0_DATA_OFFSET
, 0 },
397 .name
= "4:2:2, biplanar, YVU",
398 .fourcc
= V4L2_PIX_FMT_NV61M
,
399 .vdownsampling
= { 1, 1 },
400 .bit_depth
= { 8, 8 },
404 .data_offset
= { 0, PLANE0_DATA_OFFSET
},
407 .name
= "4:2:0, triplanar, YUV",
408 .fourcc
= V4L2_PIX_FMT_YUV420M
,
409 .vdownsampling
= { 1, 2, 2 },
410 .bit_depth
= { 8, 4, 4 },
416 .name
= "4:2:0, triplanar, YVU",
417 .fourcc
= V4L2_PIX_FMT_YVU420M
,
418 .vdownsampling
= { 1, 2, 2 },
419 .bit_depth
= { 8, 4, 4 },
425 .name
= "4:2:0, biplanar, YUV",
426 .fourcc
= V4L2_PIX_FMT_NV12M
,
427 .vdownsampling
= { 1, 2 },
428 .bit_depth
= { 8, 8 },
434 .name
= "4:2:0, biplanar, YVU",
435 .fourcc
= V4L2_PIX_FMT_NV21M
,
436 .vdownsampling
= { 1, 2 },
437 .bit_depth
= { 8, 8 },
444 /* There are 6 multiplanar formats in the list */
445 #define VIVID_MPLANAR_FORMATS 6
447 const struct vivid_fmt
*vivid_get_format(struct vivid_dev
*dev
, u32 pixelformat
)
449 const struct vivid_fmt
*fmt
;
452 for (k
= 0; k
< ARRAY_SIZE(vivid_formats
); k
++) {
453 fmt
= &vivid_formats
[k
];
454 if (fmt
->fourcc
== pixelformat
)
455 if (fmt
->buffers
== 1 || dev
->multiplanar
)
462 bool vivid_vid_can_loop(struct vivid_dev
*dev
)
464 if (dev
->src_rect
.width
!= dev
->sink_rect
.width
||
465 dev
->src_rect
.height
!= dev
->sink_rect
.height
)
467 if (dev
->fmt_cap
->fourcc
!= dev
->fmt_out
->fourcc
)
469 if (dev
->field_cap
!= dev
->field_out
)
472 * While this can be supported, it is just too much work
473 * to actually implement.
475 if (dev
->field_cap
== V4L2_FIELD_SEQ_TB
||
476 dev
->field_cap
== V4L2_FIELD_SEQ_BT
)
478 if (vivid_is_svid_cap(dev
) && vivid_is_svid_out(dev
)) {
479 if (!(dev
->std_cap
& V4L2_STD_525_60
) !=
480 !(dev
->std_out
& V4L2_STD_525_60
))
484 if (vivid_is_hdmi_cap(dev
) && vivid_is_hdmi_out(dev
))
489 void vivid_send_source_change(struct vivid_dev
*dev
, unsigned type
)
491 struct v4l2_event ev
= {
492 .type
= V4L2_EVENT_SOURCE_CHANGE
,
493 .u
.src_change
.changes
= V4L2_EVENT_SRC_CH_RESOLUTION
,
497 for (i
= 0; i
< dev
->num_inputs
; i
++) {
499 if (dev
->input_type
[i
] == type
) {
500 if (video_is_registered(&dev
->vid_cap_dev
) && dev
->has_vid_cap
)
501 v4l2_event_queue(&dev
->vid_cap_dev
, &ev
);
502 if (video_is_registered(&dev
->vbi_cap_dev
) && dev
->has_vbi_cap
)
503 v4l2_event_queue(&dev
->vbi_cap_dev
, &ev
);
509 * Conversion function that converts a single-planar format to a
510 * single-plane multiplanar format.
512 void fmt_sp2mp(const struct v4l2_format
*sp_fmt
, struct v4l2_format
*mp_fmt
)
514 struct v4l2_pix_format_mplane
*mp
= &mp_fmt
->fmt
.pix_mp
;
515 struct v4l2_plane_pix_format
*ppix
= &mp
->plane_fmt
[0];
516 const struct v4l2_pix_format
*pix
= &sp_fmt
->fmt
.pix
;
517 bool is_out
= sp_fmt
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
;
519 memset(mp
->reserved
, 0, sizeof(mp
->reserved
));
520 mp_fmt
->type
= is_out
? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
521 V4L2_CAP_VIDEO_CAPTURE_MPLANE
;
522 mp
->width
= pix
->width
;
523 mp
->height
= pix
->height
;
524 mp
->pixelformat
= pix
->pixelformat
;
525 mp
->field
= pix
->field
;
526 mp
->colorspace
= pix
->colorspace
;
527 mp
->ycbcr_enc
= pix
->ycbcr_enc
;
528 mp
->quantization
= pix
->quantization
;
530 mp
->flags
= pix
->flags
;
531 ppix
->sizeimage
= pix
->sizeimage
;
532 ppix
->bytesperline
= pix
->bytesperline
;
533 memset(ppix
->reserved
, 0, sizeof(ppix
->reserved
));
536 int fmt_sp2mp_func(struct file
*file
, void *priv
,
537 struct v4l2_format
*f
, fmtfunc func
)
539 struct v4l2_format fmt
;
540 struct v4l2_pix_format_mplane
*mp
= &fmt
.fmt
.pix_mp
;
541 struct v4l2_plane_pix_format
*ppix
= &mp
->plane_fmt
[0];
542 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
545 /* Converts to a mplane format */
547 /* Passes it to the generic mplane format function */
548 ret
= func(file
, priv
, &fmt
);
549 /* Copies back the mplane data to the single plane format */
550 pix
->width
= mp
->width
;
551 pix
->height
= mp
->height
;
552 pix
->pixelformat
= mp
->pixelformat
;
553 pix
->field
= mp
->field
;
554 pix
->colorspace
= mp
->colorspace
;
555 pix
->ycbcr_enc
= mp
->ycbcr_enc
;
556 pix
->quantization
= mp
->quantization
;
557 pix
->sizeimage
= ppix
->sizeimage
;
558 pix
->bytesperline
= ppix
->bytesperline
;
559 pix
->flags
= mp
->flags
;
563 /* v4l2_rect helper function: copy the width/height values */
564 void rect_set_size_to(struct v4l2_rect
*r
, const struct v4l2_rect
*size
)
566 r
->width
= size
->width
;
567 r
->height
= size
->height
;
570 /* v4l2_rect helper function: width and height of r should be >= min_size */
571 void rect_set_min_size(struct v4l2_rect
*r
, const struct v4l2_rect
*min_size
)
573 if (r
->width
< min_size
->width
)
574 r
->width
= min_size
->width
;
575 if (r
->height
< min_size
->height
)
576 r
->height
= min_size
->height
;
579 /* v4l2_rect helper function: width and height of r should be <= max_size */
580 void rect_set_max_size(struct v4l2_rect
*r
, const struct v4l2_rect
*max_size
)
582 if (r
->width
> max_size
->width
)
583 r
->width
= max_size
->width
;
584 if (r
->height
> max_size
->height
)
585 r
->height
= max_size
->height
;
588 /* v4l2_rect helper function: r should be inside boundary */
589 void rect_map_inside(struct v4l2_rect
*r
, const struct v4l2_rect
*boundary
)
591 rect_set_max_size(r
, boundary
);
592 if (r
->left
< boundary
->left
)
593 r
->left
= boundary
->left
;
594 if (r
->top
< boundary
->top
)
595 r
->top
= boundary
->top
;
596 if (r
->left
+ r
->width
> boundary
->width
)
597 r
->left
= boundary
->width
- r
->width
;
598 if (r
->top
+ r
->height
> boundary
->height
)
599 r
->top
= boundary
->height
- r
->height
;
602 /* v4l2_rect helper function: return true if r1 has the same size as r2 */
603 bool rect_same_size(const struct v4l2_rect
*r1
, const struct v4l2_rect
*r2
)
605 return r1
->width
== r2
->width
&& r1
->height
== r2
->height
;
608 /* v4l2_rect helper function: calculate the intersection of two rects */
609 struct v4l2_rect
rect_intersect(const struct v4l2_rect
*a
, const struct v4l2_rect
*b
)
614 r
.top
= max(a
->top
, b
->top
);
615 r
.left
= max(a
->left
, b
->left
);
616 bottom
= min(a
->top
+ a
->height
, b
->top
+ b
->height
);
617 right
= min(a
->left
+ a
->width
, b
->left
+ b
->width
);
618 r
.height
= max(0, bottom
- r
.top
);
619 r
.width
= max(0, right
- r
.left
);
624 * v4l2_rect helper function: scale rect r by to->width / from->width and
625 * to->height / from->height.
627 void rect_scale(struct v4l2_rect
*r
, const struct v4l2_rect
*from
,
628 const struct v4l2_rect
*to
)
630 if (from
->width
== 0 || from
->height
== 0) {
631 r
->left
= r
->top
= r
->width
= r
->height
= 0;
634 r
->left
= (((r
->left
- from
->left
) * to
->width
) / from
->width
) & ~1;
635 r
->width
= ((r
->width
* to
->width
) / from
->width
) & ~1;
636 r
->top
= ((r
->top
- from
->top
) * to
->height
) / from
->height
;
637 r
->height
= (r
->height
* to
->height
) / from
->height
;
640 bool rect_overlap(const struct v4l2_rect
*r1
, const struct v4l2_rect
*r2
)
643 * IF the left side of r1 is to the right of the right side of r2 OR
644 * the left side of r2 is to the right of the right side of r1 THEN
645 * they do not overlap.
647 if (r1
->left
>= r2
->left
+ r2
->width
||
648 r2
->left
>= r1
->left
+ r1
->width
)
651 * IF the top side of r1 is below the bottom of r2 OR
652 * the top side of r2 is below the bottom of r1 THEN
653 * they do not overlap.
655 if (r1
->top
>= r2
->top
+ r2
->height
||
656 r2
->top
>= r1
->top
+ r1
->height
)
660 int vivid_vid_adjust_sel(unsigned flags
, struct v4l2_rect
*r
)
662 unsigned w
= r
->width
;
663 unsigned h
= r
->height
;
665 if (!(flags
& V4L2_SEL_FLAG_LE
)) {
673 if (!(flags
& V4L2_SEL_FLAG_GE
)) {
683 if (w
> MAX_WIDTH
|| h
> MAX_HEIGHT
)
691 if (r
->left
+ w
> MAX_WIDTH
)
692 r
->left
= MAX_WIDTH
- w
;
693 if (r
->top
+ h
> MAX_HEIGHT
)
694 r
->top
= MAX_HEIGHT
- h
;
695 if ((flags
& (V4L2_SEL_FLAG_GE
| V4L2_SEL_FLAG_LE
)) ==
696 (V4L2_SEL_FLAG_GE
| V4L2_SEL_FLAG_LE
) &&
697 (r
->width
!= w
|| r
->height
!= h
))
704 int vivid_enum_fmt_vid(struct file
*file
, void *priv
,
705 struct v4l2_fmtdesc
*f
)
707 struct vivid_dev
*dev
= video_drvdata(file
);
708 const struct vivid_fmt
*fmt
;
710 if (f
->index
>= ARRAY_SIZE(vivid_formats
) -
711 (dev
->multiplanar
? 0 : VIVID_MPLANAR_FORMATS
))
714 fmt
= &vivid_formats
[f
->index
];
716 strlcpy(f
->description
, fmt
->name
, sizeof(f
->description
));
717 f
->pixelformat
= fmt
->fourcc
;
721 int vidioc_enum_fmt_vid_mplane(struct file
*file
, void *priv
,
722 struct v4l2_fmtdesc
*f
)
724 struct vivid_dev
*dev
= video_drvdata(file
);
726 if (!dev
->multiplanar
)
728 return vivid_enum_fmt_vid(file
, priv
, f
);
731 int vidioc_enum_fmt_vid(struct file
*file
, void *priv
,
732 struct v4l2_fmtdesc
*f
)
734 struct vivid_dev
*dev
= video_drvdata(file
);
736 if (dev
->multiplanar
)
738 return vivid_enum_fmt_vid(file
, priv
, f
);
741 int vidioc_g_std(struct file
*file
, void *priv
, v4l2_std_id
*id
)
743 struct vivid_dev
*dev
= video_drvdata(file
);
744 struct video_device
*vdev
= video_devdata(file
);
746 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
747 if (!vivid_is_sdtv_cap(dev
))
751 if (!vivid_is_svid_out(dev
))
758 int vidioc_g_dv_timings(struct file
*file
, void *_fh
,
759 struct v4l2_dv_timings
*timings
)
761 struct vivid_dev
*dev
= video_drvdata(file
);
762 struct video_device
*vdev
= video_devdata(file
);
764 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
765 if (!vivid_is_hdmi_cap(dev
))
767 *timings
= dev
->dv_timings_cap
;
769 if (!vivid_is_hdmi_out(dev
))
771 *timings
= dev
->dv_timings_out
;
776 int vidioc_enum_dv_timings(struct file
*file
, void *_fh
,
777 struct v4l2_enum_dv_timings
*timings
)
779 struct vivid_dev
*dev
= video_drvdata(file
);
780 struct video_device
*vdev
= video_devdata(file
);
782 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
783 if (!vivid_is_hdmi_cap(dev
))
786 if (!vivid_is_hdmi_out(dev
))
789 return v4l2_enum_dv_timings_cap(timings
, &vivid_dv_timings_cap
,
793 int vidioc_dv_timings_cap(struct file
*file
, void *_fh
,
794 struct v4l2_dv_timings_cap
*cap
)
796 struct vivid_dev
*dev
= video_drvdata(file
);
797 struct video_device
*vdev
= video_devdata(file
);
799 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
800 if (!vivid_is_hdmi_cap(dev
))
803 if (!vivid_is_hdmi_out(dev
))
806 *cap
= vivid_dv_timings_cap
;
810 int vidioc_g_edid(struct file
*file
, void *_fh
,
811 struct v4l2_edid
*edid
)
813 struct vivid_dev
*dev
= video_drvdata(file
);
814 struct video_device
*vdev
= video_devdata(file
);
816 memset(edid
->reserved
, 0, sizeof(edid
->reserved
));
817 if (vdev
->vfl_dir
== VFL_DIR_RX
) {
818 if (edid
->pad
>= dev
->num_inputs
)
820 if (dev
->input_type
[edid
->pad
] != HDMI
)
823 if (edid
->pad
>= dev
->num_outputs
)
825 if (dev
->output_type
[edid
->pad
] != HDMI
)
828 if (edid
->start_block
== 0 && edid
->blocks
== 0) {
829 edid
->blocks
= dev
->edid_blocks
;
832 if (dev
->edid_blocks
== 0)
834 if (edid
->start_block
>= dev
->edid_blocks
)
836 if (edid
->start_block
+ edid
->blocks
> dev
->edid_blocks
)
837 edid
->blocks
= dev
->edid_blocks
- edid
->start_block
;
838 memcpy(edid
->edid
, dev
->edid
, edid
->blocks
* 128);