GNU Linux-libre 4.9.317-gnu1
[releases.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(16, MAX_WIDTH, 16, 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                 .is_yuv   = true,
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                 .is_yuv   = true,
61                 .planes   = 1,
62                 .buffers = 1,
63         },
64         {
65                 .fourcc   = V4L2_PIX_FMT_YVYU,
66                 .vdownsampling = { 1 },
67                 .bit_depth = { 16 },
68                 .is_yuv   = true,
69                 .planes   = 1,
70                 .buffers = 1,
71         },
72         {
73                 .fourcc   = V4L2_PIX_FMT_VYUY,
74                 .vdownsampling = { 1 },
75                 .bit_depth = { 16 },
76                 .is_yuv   = true,
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                 .is_yuv   = true,
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                 .is_yuv   = true,
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                 .is_yuv   = true,
101                 .planes   = 3,
102                 .buffers = 1,
103         },
104         {
105                 .fourcc   = V4L2_PIX_FMT_NV12,
106                 .vdownsampling = { 1, 2 },
107                 .bit_depth = { 8, 8 },
108                 .is_yuv   = true,
109                 .planes   = 2,
110                 .buffers = 1,
111         },
112         {
113                 .fourcc   = V4L2_PIX_FMT_NV21,
114                 .vdownsampling = { 1, 2 },
115                 .bit_depth = { 8, 8 },
116                 .is_yuv   = true,
117                 .planes   = 2,
118                 .buffers = 1,
119         },
120         {
121                 .fourcc   = V4L2_PIX_FMT_NV16,
122                 .vdownsampling = { 1, 1 },
123                 .bit_depth = { 8, 8 },
124                 .is_yuv   = true,
125                 .planes   = 2,
126                 .buffers = 1,
127         },
128         {
129                 .fourcc   = V4L2_PIX_FMT_NV61,
130                 .vdownsampling = { 1, 1 },
131                 .bit_depth = { 8, 8 },
132                 .is_yuv   = true,
133                 .planes   = 2,
134                 .buffers = 1,
135         },
136         {
137                 .fourcc   = V4L2_PIX_FMT_NV24,
138                 .vdownsampling = { 1, 1 },
139                 .bit_depth = { 8, 16 },
140                 .is_yuv   = true,
141                 .planes   = 2,
142                 .buffers = 1,
143         },
144         {
145                 .fourcc   = V4L2_PIX_FMT_NV42,
146                 .vdownsampling = { 1, 1 },
147                 .bit_depth = { 8, 16 },
148                 .is_yuv   = true,
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                 .is_yuv   = true,
188                 .planes   = 1,
189                 .buffers = 1,
190         },
191         {
192                 .fourcc   = V4L2_PIX_FMT_Y16,
193                 .vdownsampling = { 1 },
194                 .bit_depth = { 16 },
195                 .is_yuv   = true,
196                 .planes   = 1,
197                 .buffers = 1,
198         },
199         {
200                 .fourcc   = V4L2_PIX_FMT_Y16_BE,
201                 .vdownsampling = { 1 },
202                 .bit_depth = { 16 },
203                 .is_yuv   = true,
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         /* Multiplanar formats */
450
451         {
452                 .fourcc   = V4L2_PIX_FMT_NV16M,
453                 .vdownsampling = { 1, 1 },
454                 .bit_depth = { 8, 8 },
455                 .is_yuv   = true,
456                 .planes   = 2,
457                 .buffers = 2,
458                 .data_offset = { PLANE0_DATA_OFFSET, 0 },
459         },
460         {
461                 .fourcc   = V4L2_PIX_FMT_NV61M,
462                 .vdownsampling = { 1, 1 },
463                 .bit_depth = { 8, 8 },
464                 .is_yuv   = true,
465                 .planes   = 2,
466                 .buffers = 2,
467                 .data_offset = { 0, PLANE0_DATA_OFFSET },
468         },
469         {
470                 .fourcc   = V4L2_PIX_FMT_YUV420M,
471                 .vdownsampling = { 1, 2, 2 },
472                 .bit_depth = { 8, 4, 4 },
473                 .is_yuv   = true,
474                 .planes   = 3,
475                 .buffers = 3,
476         },
477         {
478                 .fourcc   = V4L2_PIX_FMT_YVU420M,
479                 .vdownsampling = { 1, 2, 2 },
480                 .bit_depth = { 8, 4, 4 },
481                 .is_yuv   = true,
482                 .planes   = 3,
483                 .buffers = 3,
484         },
485         {
486                 .fourcc   = V4L2_PIX_FMT_NV12M,
487                 .vdownsampling = { 1, 2 },
488                 .bit_depth = { 8, 8 },
489                 .is_yuv   = true,
490                 .planes   = 2,
491                 .buffers = 2,
492         },
493         {
494                 .fourcc   = V4L2_PIX_FMT_NV21M,
495                 .vdownsampling = { 1, 2 },
496                 .bit_depth = { 8, 8 },
497                 .is_yuv   = true,
498                 .planes   = 2,
499                 .buffers = 2,
500         },
501         {
502                 .fourcc   = V4L2_PIX_FMT_YUV422M,
503                 .vdownsampling = { 1, 1, 1 },
504                 .bit_depth = { 8, 4, 4 },
505                 .is_yuv   = true,
506                 .planes   = 3,
507                 .buffers = 3,
508         },
509         {
510                 .fourcc   = V4L2_PIX_FMT_YVU422M,
511                 .vdownsampling = { 1, 1, 1 },
512                 .bit_depth = { 8, 4, 4 },
513                 .is_yuv   = true,
514                 .planes   = 3,
515                 .buffers = 3,
516         },
517         {
518                 .fourcc   = V4L2_PIX_FMT_YUV444M,
519                 .vdownsampling = { 1, 1, 1 },
520                 .bit_depth = { 8, 8, 8 },
521                 .is_yuv   = true,
522                 .planes   = 3,
523                 .buffers = 3,
524         },
525         {
526                 .fourcc   = V4L2_PIX_FMT_YVU444M,
527                 .vdownsampling = { 1, 1, 1 },
528                 .bit_depth = { 8, 8, 8 },
529                 .is_yuv   = true,
530                 .planes   = 3,
531                 .buffers = 3,
532         },
533 };
534
535 /* There are this many multiplanar formats in the list */
536 #define VIVID_MPLANAR_FORMATS 10
537
538 const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
539 {
540         const struct vivid_fmt *fmt;
541         unsigned k;
542
543         for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
544                 fmt = &vivid_formats[k];
545                 if (fmt->fourcc == pixelformat)
546                         if (fmt->buffers == 1 || dev->multiplanar)
547                                 return fmt;
548         }
549
550         return NULL;
551 }
552
553 bool vivid_vid_can_loop(struct vivid_dev *dev)
554 {
555         if (dev->src_rect.width != dev->sink_rect.width ||
556             dev->src_rect.height != dev->sink_rect.height)
557                 return false;
558         if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc)
559                 return false;
560         if (dev->field_cap != dev->field_out)
561                 return false;
562         /*
563          * While this can be supported, it is just too much work
564          * to actually implement.
565          */
566         if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
567             dev->field_cap == V4L2_FIELD_SEQ_BT)
568                 return false;
569         if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
570                 if (!(dev->std_cap & V4L2_STD_525_60) !=
571                     !(dev->std_out & V4L2_STD_525_60))
572                         return false;
573                 return true;
574         }
575         if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev))
576                 return true;
577         return false;
578 }
579
580 void vivid_send_source_change(struct vivid_dev *dev, unsigned type)
581 {
582         struct v4l2_event ev = {
583                 .type = V4L2_EVENT_SOURCE_CHANGE,
584                 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
585         };
586         unsigned i;
587
588         for (i = 0; i < dev->num_inputs; i++) {
589                 ev.id = i;
590                 if (dev->input_type[i] == type) {
591                         if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
592                                 v4l2_event_queue(&dev->vid_cap_dev, &ev);
593                         if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
594                                 v4l2_event_queue(&dev->vbi_cap_dev, &ev);
595                 }
596         }
597 }
598
599 /*
600  * Conversion function that converts a single-planar format to a
601  * single-plane multiplanar format.
602  */
603 void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
604 {
605         struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
606         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
607         const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
608         bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
609
610         memset(mp->reserved, 0, sizeof(mp->reserved));
611         mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
612                            V4L2_CAP_VIDEO_CAPTURE_MPLANE;
613         mp->width = pix->width;
614         mp->height = pix->height;
615         mp->pixelformat = pix->pixelformat;
616         mp->field = pix->field;
617         mp->colorspace = pix->colorspace;
618         mp->xfer_func = pix->xfer_func;
619         mp->ycbcr_enc = pix->ycbcr_enc;
620         mp->quantization = pix->quantization;
621         mp->num_planes = 1;
622         mp->flags = pix->flags;
623         ppix->sizeimage = pix->sizeimage;
624         ppix->bytesperline = pix->bytesperline;
625         memset(ppix->reserved, 0, sizeof(ppix->reserved));
626 }
627
628 int fmt_sp2mp_func(struct file *file, void *priv,
629                 struct v4l2_format *f, fmtfunc func)
630 {
631         struct v4l2_format fmt;
632         struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
633         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
634         struct v4l2_pix_format *pix = &f->fmt.pix;
635         int ret;
636
637         /* Converts to a mplane format */
638         fmt_sp2mp(f, &fmt);
639         /* Passes it to the generic mplane format function */
640         ret = func(file, priv, &fmt);
641         /* Copies back the mplane data to the single plane format */
642         pix->width = mp->width;
643         pix->height = mp->height;
644         pix->pixelformat = mp->pixelformat;
645         pix->field = mp->field;
646         pix->colorspace = mp->colorspace;
647         pix->xfer_func = mp->xfer_func;
648         pix->ycbcr_enc = mp->ycbcr_enc;
649         pix->quantization = mp->quantization;
650         pix->sizeimage = ppix->sizeimage;
651         pix->bytesperline = ppix->bytesperline;
652         pix->flags = mp->flags;
653         return ret;
654 }
655
656 int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
657 {
658         unsigned w = r->width;
659         unsigned h = r->height;
660
661         /* sanitize w and h in case someone passes ~0 as the value */
662         w &= 0xffff;
663         h &= 0xffff;
664         if (!(flags & V4L2_SEL_FLAG_LE)) {
665                 w++;
666                 h++;
667                 if (w < 2)
668                         w = 2;
669                 if (h < 2)
670                         h = 2;
671         }
672         if (!(flags & V4L2_SEL_FLAG_GE)) {
673                 if (w > MAX_WIDTH)
674                         w = MAX_WIDTH;
675                 if (h > MAX_HEIGHT)
676                         h = MAX_HEIGHT;
677         }
678         w = w & ~1;
679         h = h & ~1;
680         if (w < 2 || h < 2)
681                 return -ERANGE;
682         if (w > MAX_WIDTH || h > MAX_HEIGHT)
683                 return -ERANGE;
684         if (r->top < 0)
685                 r->top = 0;
686         if (r->left < 0)
687                 r->left = 0;
688         /* sanitize left and top in case someone passes ~0 as the value */
689         r->left &= 0xfffe;
690         r->top &= 0xfffe;
691         if (r->left + w > MAX_WIDTH)
692                 r->left = MAX_WIDTH - w;
693         if (r->top + h > MAX_HEIGHT)
694                 r->top = MAX_HEIGHT - h;
695         if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
696                         (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
697             (r->width != w || r->height != h))
698                 return -ERANGE;
699         r->width = w;
700         r->height = h;
701         return 0;
702 }
703
704 int vivid_enum_fmt_vid(struct file *file, void  *priv,
705                                         struct v4l2_fmtdesc *f)
706 {
707         struct vivid_dev *dev = video_drvdata(file);
708         const struct vivid_fmt *fmt;
709
710         if (f->index >= ARRAY_SIZE(vivid_formats) -
711             (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
712                 return -EINVAL;
713
714         fmt = &vivid_formats[f->index];
715
716         f->pixelformat = fmt->fourcc;
717         return 0;
718 }
719
720 int vidioc_enum_fmt_vid_mplane(struct file *file, void  *priv,
721                                         struct v4l2_fmtdesc *f)
722 {
723         struct vivid_dev *dev = video_drvdata(file);
724
725         if (!dev->multiplanar)
726                 return -ENOTTY;
727         return vivid_enum_fmt_vid(file, priv, f);
728 }
729
730 int vidioc_enum_fmt_vid(struct file *file, void  *priv,
731                                         struct v4l2_fmtdesc *f)
732 {
733         struct vivid_dev *dev = video_drvdata(file);
734
735         if (dev->multiplanar)
736                 return -ENOTTY;
737         return vivid_enum_fmt_vid(file, priv, f);
738 }
739
740 int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
741 {
742         struct vivid_dev *dev = video_drvdata(file);
743         struct video_device *vdev = video_devdata(file);
744
745         if (vdev->vfl_dir == VFL_DIR_RX) {
746                 if (!vivid_is_sdtv_cap(dev))
747                         return -ENODATA;
748                 *id = dev->std_cap;
749         } else {
750                 if (!vivid_is_svid_out(dev))
751                         return -ENODATA;
752                 *id = dev->std_out;
753         }
754         return 0;
755 }
756
757 int vidioc_g_dv_timings(struct file *file, void *_fh,
758                                     struct v4l2_dv_timings *timings)
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_hdmi_cap(dev))
765                         return -ENODATA;
766                 *timings = dev->dv_timings_cap;
767         } else {
768                 if (!vivid_is_hdmi_out(dev))
769                         return -ENODATA;
770                 *timings = dev->dv_timings_out;
771         }
772         return 0;
773 }
774
775 int vidioc_enum_dv_timings(struct file *file, void *_fh,
776                                     struct v4l2_enum_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         } else {
785                 if (!vivid_is_hdmi_out(dev))
786                         return -ENODATA;
787         }
788         return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
789                         NULL, NULL);
790 }
791
792 int vidioc_dv_timings_cap(struct file *file, void *_fh,
793                                     struct v4l2_dv_timings_cap *cap)
794 {
795         struct vivid_dev *dev = video_drvdata(file);
796         struct video_device *vdev = video_devdata(file);
797
798         if (vdev->vfl_dir == VFL_DIR_RX) {
799                 if (!vivid_is_hdmi_cap(dev))
800                         return -ENODATA;
801         } else {
802                 if (!vivid_is_hdmi_out(dev))
803                         return -ENODATA;
804         }
805         *cap = vivid_dv_timings_cap;
806         return 0;
807 }
808
809 int vidioc_g_edid(struct file *file, void *_fh,
810                          struct v4l2_edid *edid)
811 {
812         struct vivid_dev *dev = video_drvdata(file);
813         struct video_device *vdev = video_devdata(file);
814         struct cec_adapter *adap;
815
816         memset(edid->reserved, 0, sizeof(edid->reserved));
817         if (vdev->vfl_dir == VFL_DIR_RX) {
818                 if (edid->pad >= dev->num_inputs)
819                         return -EINVAL;
820                 if (dev->input_type[edid->pad] != HDMI)
821                         return -EINVAL;
822                 adap = dev->cec_rx_adap;
823         } else {
824                 unsigned int bus_idx;
825
826                 if (edid->pad >= dev->num_outputs)
827                         return -EINVAL;
828                 if (dev->output_type[edid->pad] != HDMI)
829                         return -EINVAL;
830                 bus_idx = dev->cec_output2bus_map[edid->pad];
831                 adap = dev->cec_tx_adap[bus_idx];
832         }
833         if (edid->start_block == 0 && edid->blocks == 0) {
834                 edid->blocks = dev->edid_blocks;
835                 return 0;
836         }
837         if (dev->edid_blocks == 0)
838                 return -ENODATA;
839         if (edid->start_block >= dev->edid_blocks)
840                 return -EINVAL;
841         if (edid->start_block + edid->blocks > dev->edid_blocks)
842                 edid->blocks = dev->edid_blocks - edid->start_block;
843         memcpy(edid->edid, dev->edid, edid->blocks * 128);
844         if (adap)
845                 cec_set_edid_phys_addr(edid->edid, edid->blocks * 128, adap->phys_addr);
846         return 0;
847 }