Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / media / platform / vivid / vivid-vid-common.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * vivid-vid-common.c - common video support functions.
4  *
5  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6  */
7
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>
16
17 #include "vivid-core.h"
18 #include "vivid-vid-common.h"
19
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 */
23         .reserved = { 0 },
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)
28 };
29
30 /* ------------------------------------------------------------------
31         Basic structures
32    ------------------------------------------------------------------*/
33
34 struct vivid_fmt vivid_formats[] = {
35         {
36                 .fourcc   = V4L2_PIX_FMT_YUYV,
37                 .vdownsampling = { 1 },
38                 .bit_depth = { 16 },
39                 .color_enc = TGP_COLOR_ENC_YCBCR,
40                 .planes   = 1,
41                 .buffers = 1,
42                 .data_offset = { PLANE0_DATA_OFFSET },
43         },
44         {
45                 .fourcc   = V4L2_PIX_FMT_UYVY,
46                 .vdownsampling = { 1 },
47                 .bit_depth = { 16 },
48                 .color_enc = TGP_COLOR_ENC_YCBCR,
49                 .planes   = 1,
50                 .buffers = 1,
51         },
52         {
53                 .fourcc   = V4L2_PIX_FMT_YVYU,
54                 .vdownsampling = { 1 },
55                 .bit_depth = { 16 },
56                 .color_enc = TGP_COLOR_ENC_YCBCR,
57                 .planes   = 1,
58                 .buffers = 1,
59         },
60         {
61                 .fourcc   = V4L2_PIX_FMT_VYUY,
62                 .vdownsampling = { 1 },
63                 .bit_depth = { 16 },
64                 .color_enc = TGP_COLOR_ENC_YCBCR,
65                 .planes   = 1,
66                 .buffers = 1,
67         },
68         {
69                 .fourcc   = V4L2_PIX_FMT_YUV422P,
70                 .vdownsampling = { 1, 1, 1 },
71                 .bit_depth = { 8, 4, 4 },
72                 .color_enc = TGP_COLOR_ENC_YCBCR,
73                 .planes   = 3,
74                 .buffers = 1,
75         },
76         {
77                 .fourcc   = V4L2_PIX_FMT_YUV420,
78                 .vdownsampling = { 1, 2, 2 },
79                 .bit_depth = { 8, 4, 4 },
80                 .color_enc = TGP_COLOR_ENC_YCBCR,
81                 .planes   = 3,
82                 .buffers = 1,
83         },
84         {
85                 .fourcc   = V4L2_PIX_FMT_YVU420,
86                 .vdownsampling = { 1, 2, 2 },
87                 .bit_depth = { 8, 4, 4 },
88                 .color_enc = TGP_COLOR_ENC_YCBCR,
89                 .planes   = 3,
90                 .buffers = 1,
91         },
92         {
93                 .fourcc   = V4L2_PIX_FMT_NV12,
94                 .vdownsampling = { 1, 2 },
95                 .bit_depth = { 8, 8 },
96                 .color_enc = TGP_COLOR_ENC_YCBCR,
97                 .planes   = 2,
98                 .buffers = 1,
99         },
100         {
101                 .fourcc   = V4L2_PIX_FMT_NV21,
102                 .vdownsampling = { 1, 2 },
103                 .bit_depth = { 8, 8 },
104                 .color_enc = TGP_COLOR_ENC_YCBCR,
105                 .planes   = 2,
106                 .buffers = 1,
107         },
108         {
109                 .fourcc   = V4L2_PIX_FMT_NV16,
110                 .vdownsampling = { 1, 1 },
111                 .bit_depth = { 8, 8 },
112                 .color_enc = TGP_COLOR_ENC_YCBCR,
113                 .planes   = 2,
114                 .buffers = 1,
115         },
116         {
117                 .fourcc   = V4L2_PIX_FMT_NV61,
118                 .vdownsampling = { 1, 1 },
119                 .bit_depth = { 8, 8 },
120                 .color_enc = TGP_COLOR_ENC_YCBCR,
121                 .planes   = 2,
122                 .buffers = 1,
123         },
124         {
125                 .fourcc   = V4L2_PIX_FMT_NV24,
126                 .vdownsampling = { 1, 1 },
127                 .bit_depth = { 8, 16 },
128                 .color_enc = TGP_COLOR_ENC_YCBCR,
129                 .planes   = 2,
130                 .buffers = 1,
131         },
132         {
133                 .fourcc   = V4L2_PIX_FMT_NV42,
134                 .vdownsampling = { 1, 1 },
135                 .bit_depth = { 8, 16 },
136                 .color_enc = TGP_COLOR_ENC_YCBCR,
137                 .planes   = 2,
138                 .buffers = 1,
139         },
140         {
141                 .fourcc   = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */
142                 .vdownsampling = { 1 },
143                 .bit_depth = { 16 },
144                 .planes   = 1,
145                 .buffers = 1,
146                 .alpha_mask = 0x8000,
147         },
148         {
149                 .fourcc   = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */
150                 .vdownsampling = { 1 },
151                 .bit_depth = { 16 },
152                 .planes   = 1,
153                 .buffers = 1,
154         },
155         {
156                 .fourcc   = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */
157                 .vdownsampling = { 1 },
158                 .bit_depth = { 16 },
159                 .planes   = 1,
160                 .buffers = 1,
161                 .alpha_mask = 0xf000,
162         },
163         {
164                 .fourcc   = V4L2_PIX_FMT_YUV32, /* ayuv */
165                 .vdownsampling = { 1 },
166                 .bit_depth = { 32 },
167                 .planes   = 1,
168                 .buffers = 1,
169                 .alpha_mask = 0x000000ff,
170         },
171         {
172                 .fourcc   = V4L2_PIX_FMT_AYUV32,
173                 .vdownsampling = { 1 },
174                 .bit_depth = { 32 },
175                 .planes   = 1,
176                 .buffers = 1,
177                 .alpha_mask = 0x000000ff,
178         },
179         {
180                 .fourcc   = V4L2_PIX_FMT_XYUV32,
181                 .vdownsampling = { 1 },
182                 .bit_depth = { 32 },
183                 .planes   = 1,
184                 .buffers = 1,
185         },
186         {
187                 .fourcc   = V4L2_PIX_FMT_VUYA32,
188                 .vdownsampling = { 1 },
189                 .bit_depth = { 32 },
190                 .planes   = 1,
191                 .buffers = 1,
192                 .alpha_mask = 0xff000000,
193         },
194         {
195                 .fourcc   = V4L2_PIX_FMT_VUYX32,
196                 .vdownsampling = { 1 },
197                 .bit_depth = { 32 },
198                 .planes   = 1,
199                 .buffers = 1,
200         },
201         {
202                 .fourcc   = V4L2_PIX_FMT_GREY,
203                 .vdownsampling = { 1 },
204                 .bit_depth = { 8 },
205                 .color_enc = TGP_COLOR_ENC_LUMA,
206                 .planes   = 1,
207                 .buffers = 1,
208         },
209         {
210                 .fourcc   = V4L2_PIX_FMT_Y10,
211                 .vdownsampling = { 1 },
212                 .bit_depth = { 16 },
213                 .color_enc = TGP_COLOR_ENC_LUMA,
214                 .planes   = 1,
215                 .buffers = 1,
216         },
217         {
218                 .fourcc   = V4L2_PIX_FMT_Y12,
219                 .vdownsampling = { 1 },
220                 .bit_depth = { 16 },
221                 .color_enc = TGP_COLOR_ENC_LUMA,
222                 .planes   = 1,
223                 .buffers = 1,
224         },
225         {
226                 .fourcc   = V4L2_PIX_FMT_Y16,
227                 .vdownsampling = { 1 },
228                 .bit_depth = { 16 },
229                 .color_enc = TGP_COLOR_ENC_LUMA,
230                 .planes   = 1,
231                 .buffers = 1,
232         },
233         {
234                 .fourcc   = V4L2_PIX_FMT_Y16_BE,
235                 .vdownsampling = { 1 },
236                 .bit_depth = { 16 },
237                 .color_enc = TGP_COLOR_ENC_LUMA,
238                 .planes   = 1,
239                 .buffers = 1,
240         },
241         {
242                 .fourcc   = V4L2_PIX_FMT_RGB332, /* rrrgggbb */
243                 .vdownsampling = { 1 },
244                 .bit_depth = { 8 },
245                 .planes   = 1,
246                 .buffers = 1,
247         },
248         {
249                 .fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
250                 .vdownsampling = { 1 },
251                 .bit_depth = { 16 },
252                 .planes   = 1,
253                 .buffers = 1,
254                 .can_do_overlay = true,
255         },
256         {
257                 .fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
258                 .vdownsampling = { 1 },
259                 .bit_depth = { 16 },
260                 .planes   = 1,
261                 .buffers = 1,
262                 .can_do_overlay = true,
263         },
264         {
265                 .fourcc   = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */
266                 .vdownsampling = { 1 },
267                 .bit_depth = { 16 },
268                 .planes   = 1,
269                 .buffers = 1,
270         },
271         {
272                 .fourcc   = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */
273                 .vdownsampling = { 1 },
274                 .bit_depth = { 16 },
275                 .planes   = 1,
276                 .buffers = 1,
277         },
278         {
279                 .fourcc   = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */
280                 .vdownsampling = { 1 },
281                 .bit_depth = { 16 },
282                 .planes   = 1,
283                 .buffers = 1,
284                 .alpha_mask = 0x00f0,
285         },
286         {
287                 .fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */
288                 .vdownsampling = { 1 },
289                 .bit_depth = { 16 },
290                 .planes   = 1,
291                 .buffers = 1,
292                 .can_do_overlay = true,
293         },
294         {
295                 .fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */
296                 .vdownsampling = { 1 },
297                 .bit_depth = { 16 },
298                 .planes   = 1,
299                 .buffers = 1,
300                 .can_do_overlay = true,
301         },
302         {
303                 .fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
304                 .vdownsampling = { 1 },
305                 .bit_depth = { 16 },
306                 .planes   = 1,
307                 .buffers = 1,
308                 .can_do_overlay = true,
309                 .alpha_mask = 0x8000,
310         },
311         {
312                 .fourcc   = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
313                 .vdownsampling = { 1 },
314                 .bit_depth = { 16 },
315                 .planes   = 1,
316                 .buffers = 1,
317         },
318         {
319                 .fourcc   = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */
320                 .vdownsampling = { 1 },
321                 .bit_depth = { 16 },
322                 .planes   = 1,
323                 .buffers = 1,
324         },
325         {
326                 .fourcc   = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */
327                 .vdownsampling = { 1 },
328                 .bit_depth = { 16 },
329                 .planes   = 1,
330                 .buffers = 1,
331                 .alpha_mask = 0x0080,
332         },
333         {
334                 .fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
335                 .vdownsampling = { 1 },
336                 .bit_depth = { 24 },
337                 .planes   = 1,
338                 .buffers = 1,
339         },
340         {
341                 .fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
342                 .vdownsampling = { 1 },
343                 .bit_depth = { 24 },
344                 .planes   = 1,
345                 .buffers = 1,
346         },
347         {
348                 .fourcc   = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */
349                 .vdownsampling = { 1 },
350                 .bit_depth = { 32 },
351                 .planes   = 1,
352                 .buffers = 1,
353         },
354         {
355                 .fourcc   = V4L2_PIX_FMT_RGB32, /* xrgb */
356                 .vdownsampling = { 1 },
357                 .bit_depth = { 32 },
358                 .planes   = 1,
359                 .buffers = 1,
360         },
361         {
362                 .fourcc   = V4L2_PIX_FMT_BGR32, /* bgrx */
363                 .vdownsampling = { 1 },
364                 .bit_depth = { 32 },
365                 .planes   = 1,
366                 .buffers = 1,
367         },
368         {
369                 .fourcc   = V4L2_PIX_FMT_XRGB32, /* xrgb */
370                 .vdownsampling = { 1 },
371                 .bit_depth = { 32 },
372                 .planes   = 1,
373                 .buffers = 1,
374         },
375         {
376                 .fourcc   = V4L2_PIX_FMT_XBGR32, /* bgrx */
377                 .vdownsampling = { 1 },
378                 .bit_depth = { 32 },
379                 .planes   = 1,
380                 .buffers = 1,
381         },
382         {
383                 .fourcc   = V4L2_PIX_FMT_ARGB32, /* argb */
384                 .vdownsampling = { 1 },
385                 .bit_depth = { 32 },
386                 .planes   = 1,
387                 .buffers = 1,
388                 .alpha_mask = 0x000000ff,
389         },
390         {
391                 .fourcc   = V4L2_PIX_FMT_ABGR32, /* bgra */
392                 .vdownsampling = { 1 },
393                 .bit_depth = { 32 },
394                 .planes   = 1,
395                 .buffers = 1,
396                 .alpha_mask = 0xff000000,
397         },
398         {
399                 .fourcc   = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
400                 .vdownsampling = { 1 },
401                 .bit_depth = { 8 },
402                 .planes   = 1,
403                 .buffers = 1,
404         },
405         {
406                 .fourcc   = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
407                 .vdownsampling = { 1 },
408                 .bit_depth = { 8 },
409                 .planes   = 1,
410                 .buffers = 1,
411         },
412         {
413                 .fourcc   = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
414                 .vdownsampling = { 1 },
415                 .bit_depth = { 8 },
416                 .planes   = 1,
417                 .buffers = 1,
418         },
419         {
420                 .fourcc   = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
421                 .vdownsampling = { 1 },
422                 .bit_depth = { 8 },
423                 .planes   = 1,
424                 .buffers = 1,
425         },
426         {
427                 .fourcc   = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */
428                 .vdownsampling = { 1 },
429                 .bit_depth = { 16 },
430                 .planes   = 1,
431                 .buffers = 1,
432         },
433         {
434                 .fourcc   = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */
435                 .vdownsampling = { 1 },
436                 .bit_depth = { 16 },
437                 .planes   = 1,
438                 .buffers = 1,
439         },
440         {
441                 .fourcc   = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */
442                 .vdownsampling = { 1 },
443                 .bit_depth = { 16 },
444                 .planes   = 1,
445                 .buffers = 1,
446         },
447         {
448                 .fourcc   = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */
449                 .vdownsampling = { 1 },
450                 .bit_depth = { 16 },
451                 .planes   = 1,
452                 .buffers = 1,
453         },
454         {
455                 .fourcc   = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */
456                 .vdownsampling = { 1 },
457                 .bit_depth = { 16 },
458                 .planes   = 1,
459                 .buffers = 1,
460         },
461         {
462                 .fourcc   = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */
463                 .vdownsampling = { 1 },
464                 .bit_depth = { 16 },
465                 .planes   = 1,
466                 .buffers = 1,
467         },
468         {
469                 .fourcc   = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */
470                 .vdownsampling = { 1 },
471                 .bit_depth = { 16 },
472                 .planes   = 1,
473                 .buffers = 1,
474         },
475         {
476                 .fourcc   = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */
477                 .vdownsampling = { 1 },
478                 .bit_depth = { 16 },
479                 .planes   = 1,
480                 .buffers = 1,
481         },
482         {
483                 .fourcc   = V4L2_PIX_FMT_SBGGR16, /* Bayer BG/GR */
484                 .vdownsampling = { 1 },
485                 .bit_depth = { 16 },
486                 .planes   = 1,
487                 .buffers = 1,
488         },
489         {
490                 .fourcc   = V4L2_PIX_FMT_SGBRG16, /* Bayer GB/RG */
491                 .vdownsampling = { 1 },
492                 .bit_depth = { 16 },
493                 .planes   = 1,
494                 .buffers = 1,
495         },
496         {
497                 .fourcc   = V4L2_PIX_FMT_SGRBG16, /* Bayer GR/BG */
498                 .vdownsampling = { 1 },
499                 .bit_depth = { 16 },
500                 .planes   = 1,
501                 .buffers = 1,
502         },
503         {
504                 .fourcc   = V4L2_PIX_FMT_SRGGB16, /* Bayer RG/GB */
505                 .vdownsampling = { 1 },
506                 .bit_depth = { 16 },
507                 .planes   = 1,
508                 .buffers = 1,
509         },
510         {
511                 .fourcc   = V4L2_PIX_FMT_HSV24, /* HSV 24bits */
512                 .color_enc = TGP_COLOR_ENC_HSV,
513                 .vdownsampling = { 1 },
514                 .bit_depth = { 24 },
515                 .planes   = 1,
516                 .buffers = 1,
517         },
518         {
519                 .fourcc   = V4L2_PIX_FMT_HSV32, /* HSV 32bits */
520                 .color_enc = TGP_COLOR_ENC_HSV,
521                 .vdownsampling = { 1 },
522                 .bit_depth = { 32 },
523                 .planes   = 1,
524                 .buffers = 1,
525         },
526
527         /* Multiplanar formats */
528
529         {
530                 .fourcc   = V4L2_PIX_FMT_NV16M,
531                 .vdownsampling = { 1, 1 },
532                 .bit_depth = { 8, 8 },
533                 .color_enc = TGP_COLOR_ENC_YCBCR,
534                 .planes   = 2,
535                 .buffers = 2,
536                 .data_offset = { PLANE0_DATA_OFFSET, 0 },
537         },
538         {
539                 .fourcc   = V4L2_PIX_FMT_NV61M,
540                 .vdownsampling = { 1, 1 },
541                 .bit_depth = { 8, 8 },
542                 .color_enc = TGP_COLOR_ENC_YCBCR,
543                 .planes   = 2,
544                 .buffers = 2,
545                 .data_offset = { 0, PLANE0_DATA_OFFSET },
546         },
547         {
548                 .fourcc   = V4L2_PIX_FMT_YUV420M,
549                 .vdownsampling = { 1, 2, 2 },
550                 .bit_depth = { 8, 4, 4 },
551                 .color_enc = TGP_COLOR_ENC_YCBCR,
552                 .planes   = 3,
553                 .buffers = 3,
554         },
555         {
556                 .fourcc   = V4L2_PIX_FMT_YVU420M,
557                 .vdownsampling = { 1, 2, 2 },
558                 .bit_depth = { 8, 4, 4 },
559                 .color_enc = TGP_COLOR_ENC_YCBCR,
560                 .planes   = 3,
561                 .buffers = 3,
562         },
563         {
564                 .fourcc   = V4L2_PIX_FMT_NV12M,
565                 .vdownsampling = { 1, 2 },
566                 .bit_depth = { 8, 8 },
567                 .color_enc = TGP_COLOR_ENC_YCBCR,
568                 .planes   = 2,
569                 .buffers = 2,
570         },
571         {
572                 .fourcc   = V4L2_PIX_FMT_NV21M,
573                 .vdownsampling = { 1, 2 },
574                 .bit_depth = { 8, 8 },
575                 .color_enc = TGP_COLOR_ENC_YCBCR,
576                 .planes   = 2,
577                 .buffers = 2,
578         },
579         {
580                 .fourcc   = V4L2_PIX_FMT_YUV422M,
581                 .vdownsampling = { 1, 1, 1 },
582                 .bit_depth = { 8, 4, 4 },
583                 .color_enc = TGP_COLOR_ENC_YCBCR,
584                 .planes   = 3,
585                 .buffers = 3,
586         },
587         {
588                 .fourcc   = V4L2_PIX_FMT_YVU422M,
589                 .vdownsampling = { 1, 1, 1 },
590                 .bit_depth = { 8, 4, 4 },
591                 .color_enc = TGP_COLOR_ENC_YCBCR,
592                 .planes   = 3,
593                 .buffers = 3,
594         },
595         {
596                 .fourcc   = V4L2_PIX_FMT_YUV444M,
597                 .vdownsampling = { 1, 1, 1 },
598                 .bit_depth = { 8, 8, 8 },
599                 .color_enc = TGP_COLOR_ENC_YCBCR,
600                 .planes   = 3,
601                 .buffers = 3,
602         },
603         {
604                 .fourcc   = V4L2_PIX_FMT_YVU444M,
605                 .vdownsampling = { 1, 1, 1 },
606                 .bit_depth = { 8, 8, 8 },
607                 .color_enc = TGP_COLOR_ENC_YCBCR,
608                 .planes   = 3,
609                 .buffers = 3,
610         },
611 };
612
613 /* There are this many multiplanar formats in the list */
614 #define VIVID_MPLANAR_FORMATS 10
615
616 const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
617 {
618         const struct vivid_fmt *fmt;
619         unsigned k;
620
621         for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
622                 fmt = &vivid_formats[k];
623                 if (fmt->fourcc == pixelformat)
624                         if (fmt->buffers == 1 || dev->multiplanar)
625                                 return fmt;
626         }
627
628         return NULL;
629 }
630
631 bool vivid_vid_can_loop(struct vivid_dev *dev)
632 {
633         if (dev->src_rect.width != dev->sink_rect.width ||
634             dev->src_rect.height != dev->sink_rect.height)
635                 return false;
636         if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc)
637                 return false;
638         if (dev->field_cap != dev->field_out)
639                 return false;
640         /*
641          * While this can be supported, it is just too much work
642          * to actually implement.
643          */
644         if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
645             dev->field_cap == V4L2_FIELD_SEQ_BT)
646                 return false;
647         if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
648                 if (!(dev->std_cap[dev->input] & V4L2_STD_525_60) !=
649                     !(dev->std_out & V4L2_STD_525_60))
650                         return false;
651                 return true;
652         }
653         if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev))
654                 return true;
655         return false;
656 }
657
658 void vivid_send_source_change(struct vivid_dev *dev, unsigned type)
659 {
660         struct v4l2_event ev = {
661                 .type = V4L2_EVENT_SOURCE_CHANGE,
662                 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
663         };
664         unsigned i;
665
666         for (i = 0; i < dev->num_inputs; i++) {
667                 ev.id = i;
668                 if (dev->input_type[i] == type) {
669                         if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
670                                 v4l2_event_queue(&dev->vid_cap_dev, &ev);
671                         if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
672                                 v4l2_event_queue(&dev->vbi_cap_dev, &ev);
673                 }
674         }
675 }
676
677 /*
678  * Conversion function that converts a single-planar format to a
679  * single-plane multiplanar format.
680  */
681 void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
682 {
683         struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
684         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
685         const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
686         bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
687
688         memset(mp->reserved, 0, sizeof(mp->reserved));
689         mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
690                            V4L2_CAP_VIDEO_CAPTURE_MPLANE;
691         mp->width = pix->width;
692         mp->height = pix->height;
693         mp->pixelformat = pix->pixelformat;
694         mp->field = pix->field;
695         mp->colorspace = pix->colorspace;
696         mp->xfer_func = pix->xfer_func;
697         /* Also copies hsv_enc */
698         mp->ycbcr_enc = pix->ycbcr_enc;
699         mp->quantization = pix->quantization;
700         mp->num_planes = 1;
701         mp->flags = pix->flags;
702         ppix->sizeimage = pix->sizeimage;
703         ppix->bytesperline = pix->bytesperline;
704         memset(ppix->reserved, 0, sizeof(ppix->reserved));
705 }
706
707 int fmt_sp2mp_func(struct file *file, void *priv,
708                 struct v4l2_format *f, fmtfunc func)
709 {
710         struct v4l2_format fmt;
711         struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
712         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
713         struct v4l2_pix_format *pix = &f->fmt.pix;
714         int ret;
715
716         /* Converts to a mplane format */
717         fmt_sp2mp(f, &fmt);
718         /* Passes it to the generic mplane format function */
719         ret = func(file, priv, &fmt);
720         /* Copies back the mplane data to the single plane format */
721         pix->width = mp->width;
722         pix->height = mp->height;
723         pix->pixelformat = mp->pixelformat;
724         pix->field = mp->field;
725         pix->colorspace = mp->colorspace;
726         pix->xfer_func = mp->xfer_func;
727         /* Also copies hsv_enc */
728         pix->ycbcr_enc = mp->ycbcr_enc;
729         pix->quantization = mp->quantization;
730         pix->sizeimage = ppix->sizeimage;
731         pix->bytesperline = ppix->bytesperline;
732         pix->flags = mp->flags;
733         return ret;
734 }
735
736 int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
737 {
738         unsigned w = r->width;
739         unsigned h = r->height;
740
741         /* sanitize w and h in case someone passes ~0 as the value */
742         w &= 0xffff;
743         h &= 0xffff;
744         if (!(flags & V4L2_SEL_FLAG_LE)) {
745                 w++;
746                 h++;
747                 if (w < 2)
748                         w = 2;
749                 if (h < 2)
750                         h = 2;
751         }
752         if (!(flags & V4L2_SEL_FLAG_GE)) {
753                 if (w > MAX_WIDTH)
754                         w = MAX_WIDTH;
755                 if (h > MAX_HEIGHT)
756                         h = MAX_HEIGHT;
757         }
758         w = w & ~1;
759         h = h & ~1;
760         if (w < 2 || h < 2)
761                 return -ERANGE;
762         if (w > MAX_WIDTH || h > MAX_HEIGHT)
763                 return -ERANGE;
764         if (r->top < 0)
765                 r->top = 0;
766         if (r->left < 0)
767                 r->left = 0;
768         /* sanitize left and top in case someone passes ~0 as the value */
769         r->left &= 0xfffe;
770         r->top &= 0xfffe;
771         if (r->left + w > MAX_WIDTH)
772                 r->left = MAX_WIDTH - w;
773         if (r->top + h > MAX_HEIGHT)
774                 r->top = MAX_HEIGHT - h;
775         if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
776                         (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
777             (r->width != w || r->height != h))
778                 return -ERANGE;
779         r->width = w;
780         r->height = h;
781         return 0;
782 }
783
784 int vivid_enum_fmt_vid(struct file *file, void  *priv,
785                                         struct v4l2_fmtdesc *f)
786 {
787         struct vivid_dev *dev = video_drvdata(file);
788         const struct vivid_fmt *fmt;
789
790         if (f->index >= ARRAY_SIZE(vivid_formats) -
791             (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
792                 return -EINVAL;
793
794         fmt = &vivid_formats[f->index];
795
796         f->pixelformat = fmt->fourcc;
797         return 0;
798 }
799
800 int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
801 {
802         struct vivid_dev *dev = video_drvdata(file);
803         struct video_device *vdev = video_devdata(file);
804
805         if (vdev->vfl_dir == VFL_DIR_RX) {
806                 if (!vivid_is_sdtv_cap(dev))
807                         return -ENODATA;
808                 *id = dev->std_cap[dev->input];
809         } else {
810                 if (!vivid_is_svid_out(dev))
811                         return -ENODATA;
812                 *id = dev->std_out;
813         }
814         return 0;
815 }
816
817 int vidioc_g_dv_timings(struct file *file, void *_fh,
818                                     struct v4l2_dv_timings *timings)
819 {
820         struct vivid_dev *dev = video_drvdata(file);
821         struct video_device *vdev = video_devdata(file);
822
823         if (vdev->vfl_dir == VFL_DIR_RX) {
824                 if (!vivid_is_hdmi_cap(dev))
825                         return -ENODATA;
826                 *timings = dev->dv_timings_cap[dev->input];
827         } else {
828                 if (!vivid_is_hdmi_out(dev))
829                         return -ENODATA;
830                 *timings = dev->dv_timings_out;
831         }
832         return 0;
833 }
834
835 int vidioc_enum_dv_timings(struct file *file, void *_fh,
836                                     struct v4l2_enum_dv_timings *timings)
837 {
838         struct vivid_dev *dev = video_drvdata(file);
839         struct video_device *vdev = video_devdata(file);
840
841         if (vdev->vfl_dir == VFL_DIR_RX) {
842                 if (!vivid_is_hdmi_cap(dev))
843                         return -ENODATA;
844         } else {
845                 if (!vivid_is_hdmi_out(dev))
846                         return -ENODATA;
847         }
848         return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
849                         NULL, NULL);
850 }
851
852 int vidioc_dv_timings_cap(struct file *file, void *_fh,
853                                     struct v4l2_dv_timings_cap *cap)
854 {
855         struct vivid_dev *dev = video_drvdata(file);
856         struct video_device *vdev = video_devdata(file);
857
858         if (vdev->vfl_dir == VFL_DIR_RX) {
859                 if (!vivid_is_hdmi_cap(dev))
860                         return -ENODATA;
861         } else {
862                 if (!vivid_is_hdmi_out(dev))
863                         return -ENODATA;
864         }
865         *cap = vivid_dv_timings_cap;
866         return 0;
867 }
868
869 int vidioc_g_edid(struct file *file, void *_fh,
870                          struct v4l2_edid *edid)
871 {
872         struct vivid_dev *dev = video_drvdata(file);
873         struct video_device *vdev = video_devdata(file);
874         struct cec_adapter *adap;
875
876         memset(edid->reserved, 0, sizeof(edid->reserved));
877         if (vdev->vfl_dir == VFL_DIR_RX) {
878                 if (edid->pad >= dev->num_inputs)
879                         return -EINVAL;
880                 if (dev->input_type[edid->pad] != HDMI)
881                         return -EINVAL;
882                 adap = dev->cec_rx_adap;
883         } else {
884                 unsigned int bus_idx;
885
886                 if (edid->pad >= dev->num_outputs)
887                         return -EINVAL;
888                 if (dev->output_type[edid->pad] != HDMI)
889                         return -EINVAL;
890                 if (!dev->display_present[edid->pad])
891                         return -ENODATA;
892                 bus_idx = dev->cec_output2bus_map[edid->pad];
893                 adap = dev->cec_tx_adap[bus_idx];
894         }
895         if (edid->start_block == 0 && edid->blocks == 0) {
896                 edid->blocks = dev->edid_blocks;
897                 return 0;
898         }
899         if (dev->edid_blocks == 0)
900                 return -ENODATA;
901         if (edid->start_block >= dev->edid_blocks)
902                 return -EINVAL;
903         if (edid->blocks > dev->edid_blocks - edid->start_block)
904                 edid->blocks = dev->edid_blocks - edid->start_block;
905         if (adap)
906                 v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
907         memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
908         return 0;
909 }