GNU Linux-libre 4.19.264-gnu1
[releases.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_GREY,
173                 .vdownsampling = { 1 },
174                 .bit_depth = { 8 },
175                 .color_enc = TGP_COLOR_ENC_LUMA,
176                 .planes   = 1,
177                 .buffers = 1,
178         },
179         {
180                 .fourcc   = V4L2_PIX_FMT_Y10,
181                 .vdownsampling = { 1 },
182                 .bit_depth = { 16 },
183                 .color_enc = TGP_COLOR_ENC_LUMA,
184                 .planes   = 1,
185                 .buffers = 1,
186         },
187         {
188                 .fourcc   = V4L2_PIX_FMT_Y12,
189                 .vdownsampling = { 1 },
190                 .bit_depth = { 16 },
191                 .color_enc = TGP_COLOR_ENC_LUMA,
192                 .planes   = 1,
193                 .buffers = 1,
194         },
195         {
196                 .fourcc   = V4L2_PIX_FMT_Y16,
197                 .vdownsampling = { 1 },
198                 .bit_depth = { 16 },
199                 .color_enc = TGP_COLOR_ENC_LUMA,
200                 .planes   = 1,
201                 .buffers = 1,
202         },
203         {
204                 .fourcc   = V4L2_PIX_FMT_Y16_BE,
205                 .vdownsampling = { 1 },
206                 .bit_depth = { 16 },
207                 .color_enc = TGP_COLOR_ENC_LUMA,
208                 .planes   = 1,
209                 .buffers = 1,
210         },
211         {
212                 .fourcc   = V4L2_PIX_FMT_RGB332, /* rrrgggbb */
213                 .vdownsampling = { 1 },
214                 .bit_depth = { 8 },
215                 .planes   = 1,
216                 .buffers = 1,
217         },
218         {
219                 .fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
220                 .vdownsampling = { 1 },
221                 .bit_depth = { 16 },
222                 .planes   = 1,
223                 .buffers = 1,
224                 .can_do_overlay = true,
225         },
226         {
227                 .fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
228                 .vdownsampling = { 1 },
229                 .bit_depth = { 16 },
230                 .planes   = 1,
231                 .buffers = 1,
232                 .can_do_overlay = true,
233         },
234         {
235                 .fourcc   = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */
236                 .vdownsampling = { 1 },
237                 .bit_depth = { 16 },
238                 .planes   = 1,
239                 .buffers = 1,
240         },
241         {
242                 .fourcc   = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */
243                 .vdownsampling = { 1 },
244                 .bit_depth = { 16 },
245                 .planes   = 1,
246                 .buffers = 1,
247         },
248         {
249                 .fourcc   = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */
250                 .vdownsampling = { 1 },
251                 .bit_depth = { 16 },
252                 .planes   = 1,
253                 .buffers = 1,
254                 .alpha_mask = 0x00f0,
255         },
256         {
257                 .fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */
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_XRGB555, /* gggbbbbb xrrrrrgg */
266                 .vdownsampling = { 1 },
267                 .bit_depth = { 16 },
268                 .planes   = 1,
269                 .buffers = 1,
270                 .can_do_overlay = true,
271         },
272         {
273                 .fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
274                 .vdownsampling = { 1 },
275                 .bit_depth = { 16 },
276                 .planes   = 1,
277                 .buffers = 1,
278                 .can_do_overlay = true,
279                 .alpha_mask = 0x8000,
280         },
281         {
282                 .fourcc   = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
283                 .vdownsampling = { 1 },
284                 .bit_depth = { 16 },
285                 .planes   = 1,
286                 .buffers = 1,
287         },
288         {
289                 .fourcc   = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */
290                 .vdownsampling = { 1 },
291                 .bit_depth = { 16 },
292                 .planes   = 1,
293                 .buffers = 1,
294         },
295         {
296                 .fourcc   = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */
297                 .vdownsampling = { 1 },
298                 .bit_depth = { 16 },
299                 .planes   = 1,
300                 .buffers = 1,
301                 .alpha_mask = 0x0080,
302         },
303         {
304                 .fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
305                 .vdownsampling = { 1 },
306                 .bit_depth = { 24 },
307                 .planes   = 1,
308                 .buffers = 1,
309         },
310         {
311                 .fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
312                 .vdownsampling = { 1 },
313                 .bit_depth = { 24 },
314                 .planes   = 1,
315                 .buffers = 1,
316         },
317         {
318                 .fourcc   = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */
319                 .vdownsampling = { 1 },
320                 .bit_depth = { 32 },
321                 .planes   = 1,
322                 .buffers = 1,
323         },
324         {
325                 .fourcc   = V4L2_PIX_FMT_RGB32, /* xrgb */
326                 .vdownsampling = { 1 },
327                 .bit_depth = { 32 },
328                 .planes   = 1,
329                 .buffers = 1,
330         },
331         {
332                 .fourcc   = V4L2_PIX_FMT_BGR32, /* bgrx */
333                 .vdownsampling = { 1 },
334                 .bit_depth = { 32 },
335                 .planes   = 1,
336                 .buffers = 1,
337         },
338         {
339                 .fourcc   = V4L2_PIX_FMT_XRGB32, /* xrgb */
340                 .vdownsampling = { 1 },
341                 .bit_depth = { 32 },
342                 .planes   = 1,
343                 .buffers = 1,
344         },
345         {
346                 .fourcc   = V4L2_PIX_FMT_XBGR32, /* bgrx */
347                 .vdownsampling = { 1 },
348                 .bit_depth = { 32 },
349                 .planes   = 1,
350                 .buffers = 1,
351         },
352         {
353                 .fourcc   = V4L2_PIX_FMT_ARGB32, /* argb */
354                 .vdownsampling = { 1 },
355                 .bit_depth = { 32 },
356                 .planes   = 1,
357                 .buffers = 1,
358                 .alpha_mask = 0x000000ff,
359         },
360         {
361                 .fourcc   = V4L2_PIX_FMT_ABGR32, /* bgra */
362                 .vdownsampling = { 1 },
363                 .bit_depth = { 32 },
364                 .planes   = 1,
365                 .buffers = 1,
366                 .alpha_mask = 0xff000000,
367         },
368         {
369                 .fourcc   = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
370                 .vdownsampling = { 1 },
371                 .bit_depth = { 8 },
372                 .planes   = 1,
373                 .buffers = 1,
374         },
375         {
376                 .fourcc   = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
377                 .vdownsampling = { 1 },
378                 .bit_depth = { 8 },
379                 .planes   = 1,
380                 .buffers = 1,
381         },
382         {
383                 .fourcc   = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
384                 .vdownsampling = { 1 },
385                 .bit_depth = { 8 },
386                 .planes   = 1,
387                 .buffers = 1,
388         },
389         {
390                 .fourcc   = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
391                 .vdownsampling = { 1 },
392                 .bit_depth = { 8 },
393                 .planes   = 1,
394                 .buffers = 1,
395         },
396         {
397                 .fourcc   = V4L2_PIX_FMT_SBGGR10, /* Bayer BG/GR */
398                 .vdownsampling = { 1 },
399                 .bit_depth = { 16 },
400                 .planes   = 1,
401                 .buffers = 1,
402         },
403         {
404                 .fourcc   = V4L2_PIX_FMT_SGBRG10, /* Bayer GB/RG */
405                 .vdownsampling = { 1 },
406                 .bit_depth = { 16 },
407                 .planes   = 1,
408                 .buffers = 1,
409         },
410         {
411                 .fourcc   = V4L2_PIX_FMT_SGRBG10, /* Bayer GR/BG */
412                 .vdownsampling = { 1 },
413                 .bit_depth = { 16 },
414                 .planes   = 1,
415                 .buffers = 1,
416         },
417         {
418                 .fourcc   = V4L2_PIX_FMT_SRGGB10, /* Bayer RG/GB */
419                 .vdownsampling = { 1 },
420                 .bit_depth = { 16 },
421                 .planes   = 1,
422                 .buffers = 1,
423         },
424         {
425                 .fourcc   = V4L2_PIX_FMT_SBGGR12, /* Bayer BG/GR */
426                 .vdownsampling = { 1 },
427                 .bit_depth = { 16 },
428                 .planes   = 1,
429                 .buffers = 1,
430         },
431         {
432                 .fourcc   = V4L2_PIX_FMT_SGBRG12, /* Bayer GB/RG */
433                 .vdownsampling = { 1 },
434                 .bit_depth = { 16 },
435                 .planes   = 1,
436                 .buffers = 1,
437         },
438         {
439                 .fourcc   = V4L2_PIX_FMT_SGRBG12, /* Bayer GR/BG */
440                 .vdownsampling = { 1 },
441                 .bit_depth = { 16 },
442                 .planes   = 1,
443                 .buffers = 1,
444         },
445         {
446                 .fourcc   = V4L2_PIX_FMT_SRGGB12, /* Bayer RG/GB */
447                 .vdownsampling = { 1 },
448                 .bit_depth = { 16 },
449                 .planes   = 1,
450                 .buffers = 1,
451         },
452         {
453                 .fourcc   = V4L2_PIX_FMT_HSV24, /* HSV 24bits */
454                 .color_enc = TGP_COLOR_ENC_HSV,
455                 .vdownsampling = { 1 },
456                 .bit_depth = { 24 },
457                 .planes   = 1,
458                 .buffers = 1,
459         },
460         {
461                 .fourcc   = V4L2_PIX_FMT_HSV32, /* HSV 32bits */
462                 .color_enc = TGP_COLOR_ENC_HSV,
463                 .vdownsampling = { 1 },
464                 .bit_depth = { 32 },
465                 .planes   = 1,
466                 .buffers = 1,
467         },
468
469         /* Multiplanar formats */
470
471         {
472                 .fourcc   = V4L2_PIX_FMT_NV16M,
473                 .vdownsampling = { 1, 1 },
474                 .bit_depth = { 8, 8 },
475                 .color_enc = TGP_COLOR_ENC_YCBCR,
476                 .planes   = 2,
477                 .buffers = 2,
478                 .data_offset = { PLANE0_DATA_OFFSET, 0 },
479         },
480         {
481                 .fourcc   = V4L2_PIX_FMT_NV61M,
482                 .vdownsampling = { 1, 1 },
483                 .bit_depth = { 8, 8 },
484                 .color_enc = TGP_COLOR_ENC_YCBCR,
485                 .planes   = 2,
486                 .buffers = 2,
487                 .data_offset = { 0, PLANE0_DATA_OFFSET },
488         },
489         {
490                 .fourcc   = V4L2_PIX_FMT_YUV420M,
491                 .vdownsampling = { 1, 2, 2 },
492                 .bit_depth = { 8, 4, 4 },
493                 .color_enc = TGP_COLOR_ENC_YCBCR,
494                 .planes   = 3,
495                 .buffers = 3,
496         },
497         {
498                 .fourcc   = V4L2_PIX_FMT_YVU420M,
499                 .vdownsampling = { 1, 2, 2 },
500                 .bit_depth = { 8, 4, 4 },
501                 .color_enc = TGP_COLOR_ENC_YCBCR,
502                 .planes   = 3,
503                 .buffers = 3,
504         },
505         {
506                 .fourcc   = V4L2_PIX_FMT_NV12M,
507                 .vdownsampling = { 1, 2 },
508                 .bit_depth = { 8, 8 },
509                 .color_enc = TGP_COLOR_ENC_YCBCR,
510                 .planes   = 2,
511                 .buffers = 2,
512         },
513         {
514                 .fourcc   = V4L2_PIX_FMT_NV21M,
515                 .vdownsampling = { 1, 2 },
516                 .bit_depth = { 8, 8 },
517                 .color_enc = TGP_COLOR_ENC_YCBCR,
518                 .planes   = 2,
519                 .buffers = 2,
520         },
521         {
522                 .fourcc   = V4L2_PIX_FMT_YUV422M,
523                 .vdownsampling = { 1, 1, 1 },
524                 .bit_depth = { 8, 4, 4 },
525                 .color_enc = TGP_COLOR_ENC_YCBCR,
526                 .planes   = 3,
527                 .buffers = 3,
528         },
529         {
530                 .fourcc   = V4L2_PIX_FMT_YVU422M,
531                 .vdownsampling = { 1, 1, 1 },
532                 .bit_depth = { 8, 4, 4 },
533                 .color_enc = TGP_COLOR_ENC_YCBCR,
534                 .planes   = 3,
535                 .buffers = 3,
536         },
537         {
538                 .fourcc   = V4L2_PIX_FMT_YUV444M,
539                 .vdownsampling = { 1, 1, 1 },
540                 .bit_depth = { 8, 8, 8 },
541                 .color_enc = TGP_COLOR_ENC_YCBCR,
542                 .planes   = 3,
543                 .buffers = 3,
544         },
545         {
546                 .fourcc   = V4L2_PIX_FMT_YVU444M,
547                 .vdownsampling = { 1, 1, 1 },
548                 .bit_depth = { 8, 8, 8 },
549                 .color_enc = TGP_COLOR_ENC_YCBCR,
550                 .planes   = 3,
551                 .buffers = 3,
552         },
553 };
554
555 /* There are this many multiplanar formats in the list */
556 #define VIVID_MPLANAR_FORMATS 10
557
558 const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
559 {
560         const struct vivid_fmt *fmt;
561         unsigned k;
562
563         for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
564                 fmt = &vivid_formats[k];
565                 if (fmt->fourcc == pixelformat)
566                         if (fmt->buffers == 1 || dev->multiplanar)
567                                 return fmt;
568         }
569
570         return NULL;
571 }
572
573 bool vivid_vid_can_loop(struct vivid_dev *dev)
574 {
575         if (dev->src_rect.width != dev->sink_rect.width ||
576             dev->src_rect.height != dev->sink_rect.height)
577                 return false;
578         if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc)
579                 return false;
580         if (dev->field_cap != dev->field_out)
581                 return false;
582         /*
583          * While this can be supported, it is just too much work
584          * to actually implement.
585          */
586         if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
587             dev->field_cap == V4L2_FIELD_SEQ_BT)
588                 return false;
589         if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
590                 if (!(dev->std_cap & V4L2_STD_525_60) !=
591                     !(dev->std_out & V4L2_STD_525_60))
592                         return false;
593                 return true;
594         }
595         if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev))
596                 return true;
597         return false;
598 }
599
600 void vivid_send_source_change(struct vivid_dev *dev, unsigned type)
601 {
602         struct v4l2_event ev = {
603                 .type = V4L2_EVENT_SOURCE_CHANGE,
604                 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
605         };
606         unsigned i;
607
608         for (i = 0; i < dev->num_inputs; i++) {
609                 ev.id = i;
610                 if (dev->input_type[i] == type) {
611                         if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
612                                 v4l2_event_queue(&dev->vid_cap_dev, &ev);
613                         if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
614                                 v4l2_event_queue(&dev->vbi_cap_dev, &ev);
615                 }
616         }
617 }
618
619 /*
620  * Conversion function that converts a single-planar format to a
621  * single-plane multiplanar format.
622  */
623 void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
624 {
625         struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
626         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
627         const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
628         bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
629
630         memset(mp->reserved, 0, sizeof(mp->reserved));
631         mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
632                            V4L2_CAP_VIDEO_CAPTURE_MPLANE;
633         mp->width = pix->width;
634         mp->height = pix->height;
635         mp->pixelformat = pix->pixelformat;
636         mp->field = pix->field;
637         mp->colorspace = pix->colorspace;
638         mp->xfer_func = pix->xfer_func;
639         /* Also copies hsv_enc */
640         mp->ycbcr_enc = pix->ycbcr_enc;
641         mp->quantization = pix->quantization;
642         mp->num_planes = 1;
643         mp->flags = pix->flags;
644         ppix->sizeimage = pix->sizeimage;
645         ppix->bytesperline = pix->bytesperline;
646         memset(ppix->reserved, 0, sizeof(ppix->reserved));
647 }
648
649 int fmt_sp2mp_func(struct file *file, void *priv,
650                 struct v4l2_format *f, fmtfunc func)
651 {
652         struct v4l2_format fmt;
653         struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
654         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
655         struct v4l2_pix_format *pix = &f->fmt.pix;
656         int ret;
657
658         /* Converts to a mplane format */
659         fmt_sp2mp(f, &fmt);
660         /* Passes it to the generic mplane format function */
661         ret = func(file, priv, &fmt);
662         /* Copies back the mplane data to the single plane format */
663         pix->width = mp->width;
664         pix->height = mp->height;
665         pix->pixelformat = mp->pixelformat;
666         pix->field = mp->field;
667         pix->colorspace = mp->colorspace;
668         pix->xfer_func = mp->xfer_func;
669         /* Also copies hsv_enc */
670         pix->ycbcr_enc = mp->ycbcr_enc;
671         pix->quantization = mp->quantization;
672         pix->sizeimage = ppix->sizeimage;
673         pix->bytesperline = ppix->bytesperline;
674         pix->flags = mp->flags;
675         return ret;
676 }
677
678 int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
679 {
680         unsigned w = r->width;
681         unsigned h = r->height;
682
683         /* sanitize w and h in case someone passes ~0 as the value */
684         w &= 0xffff;
685         h &= 0xffff;
686         if (!(flags & V4L2_SEL_FLAG_LE)) {
687                 w++;
688                 h++;
689                 if (w < 2)
690                         w = 2;
691                 if (h < 2)
692                         h = 2;
693         }
694         if (!(flags & V4L2_SEL_FLAG_GE)) {
695                 if (w > MAX_WIDTH)
696                         w = MAX_WIDTH;
697                 if (h > MAX_HEIGHT)
698                         h = MAX_HEIGHT;
699         }
700         w = w & ~1;
701         h = h & ~1;
702         if (w < 2 || h < 2)
703                 return -ERANGE;
704         if (w > MAX_WIDTH || h > MAX_HEIGHT)
705                 return -ERANGE;
706         if (r->top < 0)
707                 r->top = 0;
708         if (r->left < 0)
709                 r->left = 0;
710         /* sanitize left and top in case someone passes ~0 as the value */
711         r->left &= 0xfffe;
712         r->top &= 0xfffe;
713         if (r->left + w > MAX_WIDTH)
714                 r->left = MAX_WIDTH - w;
715         if (r->top + h > MAX_HEIGHT)
716                 r->top = MAX_HEIGHT - h;
717         if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
718                         (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
719             (r->width != w || r->height != h))
720                 return -ERANGE;
721         r->width = w;
722         r->height = h;
723         return 0;
724 }
725
726 int vivid_enum_fmt_vid(struct file *file, void  *priv,
727                                         struct v4l2_fmtdesc *f)
728 {
729         struct vivid_dev *dev = video_drvdata(file);
730         const struct vivid_fmt *fmt;
731
732         if (f->index >= ARRAY_SIZE(vivid_formats) -
733             (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
734                 return -EINVAL;
735
736         fmt = &vivid_formats[f->index];
737
738         f->pixelformat = fmt->fourcc;
739         return 0;
740 }
741
742 int vidioc_enum_fmt_vid_mplane(struct file *file, void  *priv,
743                                         struct v4l2_fmtdesc *f)
744 {
745         struct vivid_dev *dev = video_drvdata(file);
746
747         if (!dev->multiplanar)
748                 return -ENOTTY;
749         return vivid_enum_fmt_vid(file, priv, f);
750 }
751
752 int vidioc_enum_fmt_vid(struct file *file, void  *priv,
753                                         struct v4l2_fmtdesc *f)
754 {
755         struct vivid_dev *dev = video_drvdata(file);
756
757         if (dev->multiplanar)
758                 return -ENOTTY;
759         return vivid_enum_fmt_vid(file, priv, f);
760 }
761
762 int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
763 {
764         struct vivid_dev *dev = video_drvdata(file);
765         struct video_device *vdev = video_devdata(file);
766
767         if (vdev->vfl_dir == VFL_DIR_RX) {
768                 if (!vivid_is_sdtv_cap(dev))
769                         return -ENODATA;
770                 *id = dev->std_cap;
771         } else {
772                 if (!vivid_is_svid_out(dev))
773                         return -ENODATA;
774                 *id = dev->std_out;
775         }
776         return 0;
777 }
778
779 int vidioc_g_dv_timings(struct file *file, void *_fh,
780                                     struct v4l2_dv_timings *timings)
781 {
782         struct vivid_dev *dev = video_drvdata(file);
783         struct video_device *vdev = video_devdata(file);
784
785         if (vdev->vfl_dir == VFL_DIR_RX) {
786                 if (!vivid_is_hdmi_cap(dev))
787                         return -ENODATA;
788                 *timings = dev->dv_timings_cap;
789         } else {
790                 if (!vivid_is_hdmi_out(dev))
791                         return -ENODATA;
792                 *timings = dev->dv_timings_out;
793         }
794         return 0;
795 }
796
797 int vidioc_enum_dv_timings(struct file *file, void *_fh,
798                                     struct v4l2_enum_dv_timings *timings)
799 {
800         struct vivid_dev *dev = video_drvdata(file);
801         struct video_device *vdev = video_devdata(file);
802
803         if (vdev->vfl_dir == VFL_DIR_RX) {
804                 if (!vivid_is_hdmi_cap(dev))
805                         return -ENODATA;
806         } else {
807                 if (!vivid_is_hdmi_out(dev))
808                         return -ENODATA;
809         }
810         return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
811                         NULL, NULL);
812 }
813
814 int vidioc_dv_timings_cap(struct file *file, void *_fh,
815                                     struct v4l2_dv_timings_cap *cap)
816 {
817         struct vivid_dev *dev = video_drvdata(file);
818         struct video_device *vdev = video_devdata(file);
819
820         if (vdev->vfl_dir == VFL_DIR_RX) {
821                 if (!vivid_is_hdmi_cap(dev))
822                         return -ENODATA;
823         } else {
824                 if (!vivid_is_hdmi_out(dev))
825                         return -ENODATA;
826         }
827         *cap = vivid_dv_timings_cap;
828         return 0;
829 }
830
831 int vidioc_g_edid(struct file *file, void *_fh,
832                          struct v4l2_edid *edid)
833 {
834         struct vivid_dev *dev = video_drvdata(file);
835         struct video_device *vdev = video_devdata(file);
836         struct cec_adapter *adap;
837
838         memset(edid->reserved, 0, sizeof(edid->reserved));
839         if (vdev->vfl_dir == VFL_DIR_RX) {
840                 if (edid->pad >= dev->num_inputs)
841                         return -EINVAL;
842                 if (dev->input_type[edid->pad] != HDMI)
843                         return -EINVAL;
844                 adap = dev->cec_rx_adap;
845         } else {
846                 unsigned int bus_idx;
847
848                 if (edid->pad >= dev->num_outputs)
849                         return -EINVAL;
850                 if (dev->output_type[edid->pad] != HDMI)
851                         return -EINVAL;
852                 bus_idx = dev->cec_output2bus_map[edid->pad];
853                 adap = dev->cec_tx_adap[bus_idx];
854         }
855         if (edid->start_block == 0 && edid->blocks == 0) {
856                 edid->blocks = dev->edid_blocks;
857                 return 0;
858         }
859         if (dev->edid_blocks == 0)
860                 return -ENODATA;
861         if (edid->start_block >= dev->edid_blocks)
862                 return -EINVAL;
863         if (edid->blocks > dev->edid_blocks - edid->start_block)
864                 edid->blocks = dev->edid_blocks - edid->start_block;
865         if (adap)
866                 v4l2_set_edid_phys_addr(dev->edid, dev->edid_blocks * 128, adap->phys_addr);
867         memcpy(edid->edid, dev->edid + edid->start_block * 128, edid->blocks * 128);
868         return 0;
869 }