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