Fix race condition between vxlan_sock_add and vxlan_sock_release
[cascardo/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, 25000000, 600000000,
37                 V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT,
38                 V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED)
39 };
40
41 /* ------------------------------------------------------------------
42         Basic structures
43    ------------------------------------------------------------------*/
44
45 struct vivid_fmt vivid_formats[] = {
46         {
47                 .name     = "4:2:2, packed, YUYV",
48                 .fourcc   = V4L2_PIX_FMT_YUYV,
49                 .depth    = 16,
50                 .is_yuv   = true,
51                 .planes   = 1,
52                 .data_offset = { PLANE0_DATA_OFFSET, 0 },
53         },
54         {
55                 .name     = "4:2:2, packed, UYVY",
56                 .fourcc   = V4L2_PIX_FMT_UYVY,
57                 .depth    = 16,
58                 .is_yuv   = true,
59                 .planes   = 1,
60         },
61         {
62                 .name     = "4:2:2, packed, YVYU",
63                 .fourcc   = V4L2_PIX_FMT_YVYU,
64                 .depth    = 16,
65                 .is_yuv   = true,
66                 .planes   = 1,
67         },
68         {
69                 .name     = "4:2:2, packed, VYUY",
70                 .fourcc   = V4L2_PIX_FMT_VYUY,
71                 .depth    = 16,
72                 .is_yuv   = true,
73                 .planes   = 1,
74         },
75         {
76                 .name     = "RGB565 (LE)",
77                 .fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
78                 .depth    = 16,
79                 .planes   = 1,
80                 .can_do_overlay = true,
81         },
82         {
83                 .name     = "RGB565 (BE)",
84                 .fourcc   = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
85                 .depth    = 16,
86                 .planes   = 1,
87                 .can_do_overlay = true,
88         },
89         {
90                 .name     = "RGB555 (LE)",
91                 .fourcc   = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
92                 .depth    = 16,
93                 .planes   = 1,
94                 .can_do_overlay = true,
95         },
96         {
97                 .name     = "XRGB555 (LE)",
98                 .fourcc   = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */
99                 .depth    = 16,
100                 .planes   = 1,
101                 .can_do_overlay = true,
102         },
103         {
104                 .name     = "ARGB555 (LE)",
105                 .fourcc   = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
106                 .depth    = 16,
107                 .planes   = 1,
108                 .can_do_overlay = true,
109                 .alpha_mask = 0x8000,
110         },
111         {
112                 .name     = "RGB555 (BE)",
113                 .fourcc   = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
114                 .depth    = 16,
115                 .planes   = 1,
116                 .can_do_overlay = true,
117         },
118         {
119                 .name     = "RGB24 (LE)",
120                 .fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
121                 .depth    = 24,
122                 .planes   = 1,
123         },
124         {
125                 .name     = "RGB24 (BE)",
126                 .fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
127                 .depth    = 24,
128                 .planes   = 1,
129         },
130         {
131                 .name     = "RGB32 (LE)",
132                 .fourcc   = V4L2_PIX_FMT_RGB32, /* argb */
133                 .depth    = 32,
134                 .planes   = 1,
135         },
136         {
137                 .name     = "RGB32 (BE)",
138                 .fourcc   = V4L2_PIX_FMT_BGR32, /* bgra */
139                 .depth    = 32,
140                 .planes   = 1,
141         },
142         {
143                 .name     = "XRGB32 (LE)",
144                 .fourcc   = V4L2_PIX_FMT_XRGB32, /* argb */
145                 .depth    = 32,
146                 .planes   = 1,
147         },
148         {
149                 .name     = "XRGB32 (BE)",
150                 .fourcc   = V4L2_PIX_FMT_XBGR32, /* bgra */
151                 .depth    = 32,
152                 .planes   = 1,
153         },
154         {
155                 .name     = "ARGB32 (LE)",
156                 .fourcc   = V4L2_PIX_FMT_ARGB32, /* argb */
157                 .depth    = 32,
158                 .planes   = 1,
159                 .alpha_mask = 0x000000ff,
160         },
161         {
162                 .name     = "ARGB32 (BE)",
163                 .fourcc   = V4L2_PIX_FMT_ABGR32, /* bgra */
164                 .depth    = 32,
165                 .planes   = 1,
166                 .alpha_mask = 0xff000000,
167         },
168         {
169                 .name     = "4:2:2, planar, YUV",
170                 .fourcc   = V4L2_PIX_FMT_NV16M,
171                 .depth    = 8,
172                 .is_yuv   = true,
173                 .planes   = 2,
174                 .data_offset = { PLANE0_DATA_OFFSET, 0 },
175         },
176         {
177                 .name     = "4:2:2, planar, YVU",
178                 .fourcc   = V4L2_PIX_FMT_NV61M,
179                 .depth    = 8,
180                 .is_yuv   = true,
181                 .planes   = 2,
182                 .data_offset = { 0, PLANE0_DATA_OFFSET },
183         },
184 };
185
186 /* There are 2 multiplanar formats in the list */
187 #define VIVID_MPLANAR_FORMATS 2
188
189 const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
190 {
191         const struct vivid_fmt *fmt;
192         unsigned k;
193
194         for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
195                 fmt = &vivid_formats[k];
196                 if (fmt->fourcc == pixelformat)
197                         if (fmt->planes == 1 || dev->multiplanar)
198                                 return fmt;
199         }
200
201         return NULL;
202 }
203
204 bool vivid_vid_can_loop(struct vivid_dev *dev)
205 {
206         if (dev->src_rect.width != dev->sink_rect.width ||
207             dev->src_rect.height != dev->sink_rect.height)
208                 return false;
209         if (dev->fmt_cap->fourcc != dev->fmt_out->fourcc)
210                 return false;
211         if (dev->field_cap != dev->field_out)
212                 return false;
213         if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
214                 if (!(dev->std_cap & V4L2_STD_525_60) !=
215                     !(dev->std_out & V4L2_STD_525_60))
216                         return false;
217                 return true;
218         }
219         if (vivid_is_hdmi_cap(dev) && vivid_is_hdmi_out(dev))
220                 return true;
221         return false;
222 }
223
224 void vivid_send_source_change(struct vivid_dev *dev, unsigned type)
225 {
226         struct v4l2_event ev = {
227                 .type = V4L2_EVENT_SOURCE_CHANGE,
228                 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
229         };
230         unsigned i;
231
232         for (i = 0; i < dev->num_inputs; i++) {
233                 ev.id = i;
234                 if (dev->input_type[i] == type) {
235                         if (video_is_registered(&dev->vid_cap_dev) && dev->has_vid_cap)
236                                 v4l2_event_queue(&dev->vid_cap_dev, &ev);
237                         if (video_is_registered(&dev->vbi_cap_dev) && dev->has_vbi_cap)
238                                 v4l2_event_queue(&dev->vbi_cap_dev, &ev);
239                 }
240         }
241 }
242
243 /*
244  * Conversion function that converts a single-planar format to a
245  * single-plane multiplanar format.
246  */
247 void fmt_sp2mp(const struct v4l2_format *sp_fmt, struct v4l2_format *mp_fmt)
248 {
249         struct v4l2_pix_format_mplane *mp = &mp_fmt->fmt.pix_mp;
250         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
251         const struct v4l2_pix_format *pix = &sp_fmt->fmt.pix;
252         bool is_out = sp_fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT;
253
254         memset(mp->reserved, 0, sizeof(mp->reserved));
255         mp_fmt->type = is_out ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
256                            V4L2_CAP_VIDEO_CAPTURE_MPLANE;
257         mp->width = pix->width;
258         mp->height = pix->height;
259         mp->pixelformat = pix->pixelformat;
260         mp->field = pix->field;
261         mp->colorspace = pix->colorspace;
262         mp->num_planes = 1;
263         mp->flags = pix->flags;
264         ppix->sizeimage = pix->sizeimage;
265         ppix->bytesperline = pix->bytesperline;
266         memset(ppix->reserved, 0, sizeof(ppix->reserved));
267 }
268
269 int fmt_sp2mp_func(struct file *file, void *priv,
270                 struct v4l2_format *f, fmtfunc func)
271 {
272         struct v4l2_format fmt;
273         struct v4l2_pix_format_mplane *mp = &fmt.fmt.pix_mp;
274         struct v4l2_plane_pix_format *ppix = &mp->plane_fmt[0];
275         struct v4l2_pix_format *pix = &f->fmt.pix;
276         int ret;
277
278         /* Converts to a mplane format */
279         fmt_sp2mp(f, &fmt);
280         /* Passes it to the generic mplane format function */
281         ret = func(file, priv, &fmt);
282         /* Copies back the mplane data to the single plane format */
283         pix->width = mp->width;
284         pix->height = mp->height;
285         pix->pixelformat = mp->pixelformat;
286         pix->field = mp->field;
287         pix->colorspace = mp->colorspace;
288         pix->sizeimage = ppix->sizeimage;
289         pix->bytesperline = ppix->bytesperline;
290         pix->flags = mp->flags;
291         return ret;
292 }
293
294 /* v4l2_rect helper function: copy the width/height values */
295 void rect_set_size_to(struct v4l2_rect *r, const struct v4l2_rect *size)
296 {
297         r->width = size->width;
298         r->height = size->height;
299 }
300
301 /* v4l2_rect helper function: width and height of r should be >= min_size */
302 void rect_set_min_size(struct v4l2_rect *r, const struct v4l2_rect *min_size)
303 {
304         if (r->width < min_size->width)
305                 r->width = min_size->width;
306         if (r->height < min_size->height)
307                 r->height = min_size->height;
308 }
309
310 /* v4l2_rect helper function: width and height of r should be <= max_size */
311 void rect_set_max_size(struct v4l2_rect *r, const struct v4l2_rect *max_size)
312 {
313         if (r->width > max_size->width)
314                 r->width = max_size->width;
315         if (r->height > max_size->height)
316                 r->height = max_size->height;
317 }
318
319 /* v4l2_rect helper function: r should be inside boundary */
320 void rect_map_inside(struct v4l2_rect *r, const struct v4l2_rect *boundary)
321 {
322         rect_set_max_size(r, boundary);
323         if (r->left < boundary->left)
324                 r->left = boundary->left;
325         if (r->top < boundary->top)
326                 r->top = boundary->top;
327         if (r->left + r->width > boundary->width)
328                 r->left = boundary->width - r->width;
329         if (r->top + r->height > boundary->height)
330                 r->top = boundary->height - r->height;
331 }
332
333 /* v4l2_rect helper function: return true if r1 has the same size as r2 */
334 bool rect_same_size(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
335 {
336         return r1->width == r2->width && r1->height == r2->height;
337 }
338
339 /* v4l2_rect helper function: calculate the intersection of two rects */
340 struct v4l2_rect rect_intersect(const struct v4l2_rect *a, const struct v4l2_rect *b)
341 {
342         struct v4l2_rect r;
343         int right, bottom;
344
345         r.top = max(a->top, b->top);
346         r.left = max(a->left, b->left);
347         bottom = min(a->top + a->height, b->top + b->height);
348         right = min(a->left + a->width, b->left + b->width);
349         r.height = max(0, bottom - r.top);
350         r.width = max(0, right - r.left);
351         return r;
352 }
353
354 /*
355  * v4l2_rect helper function: scale rect r by to->width / from->width and
356  * to->height / from->height.
357  */
358 void rect_scale(struct v4l2_rect *r, const struct v4l2_rect *from,
359                                      const struct v4l2_rect *to)
360 {
361         if (from->width == 0 || from->height == 0) {
362                 r->left = r->top = r->width = r->height = 0;
363                 return;
364         }
365         r->left = (((r->left - from->left) * to->width) / from->width) & ~1;
366         r->width = ((r->width * to->width) / from->width) & ~1;
367         r->top = ((r->top - from->top) * to->height) / from->height;
368         r->height = (r->height * to->height) / from->height;
369 }
370
371 bool rect_overlap(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
372 {
373         /*
374          * IF the left side of r1 is to the right of the right side of r2 OR
375          *    the left side of r2 is to the right of the right side of r1 THEN
376          * they do not overlap.
377          */
378         if (r1->left >= r2->left + r2->width ||
379             r2->left >= r1->left + r1->width)
380                 return false;
381         /*
382          * IF the top side of r1 is below the bottom of r2 OR
383          *    the top side of r2 is below the bottom of r1 THEN
384          * they do not overlap.
385          */
386         if (r1->top >= r2->top + r2->height ||
387             r2->top >= r1->top + r1->height)
388                 return false;
389         return true;
390 }
391 int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
392 {
393         unsigned w = r->width;
394         unsigned h = r->height;
395
396         if (!(flags & V4L2_SEL_FLAG_LE)) {
397                 w++;
398                 h++;
399                 if (w < 2)
400                         w = 2;
401                 if (h < 2)
402                         h = 2;
403         }
404         if (!(flags & V4L2_SEL_FLAG_GE)) {
405                 if (w > MAX_WIDTH)
406                         w = MAX_WIDTH;
407                 if (h > MAX_HEIGHT)
408                         h = MAX_HEIGHT;
409         }
410         w = w & ~1;
411         h = h & ~1;
412         if (w < 2 || h < 2)
413                 return -ERANGE;
414         if (w > MAX_WIDTH || h > MAX_HEIGHT)
415                 return -ERANGE;
416         if (r->top < 0)
417                 r->top = 0;
418         if (r->left < 0)
419                 r->left = 0;
420         r->left &= ~1;
421         r->top &= ~1;
422         if (r->left + w > MAX_WIDTH)
423                 r->left = MAX_WIDTH - w;
424         if (r->top + h > MAX_HEIGHT)
425                 r->top = MAX_HEIGHT - h;
426         if ((flags & (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE)) ==
427                         (V4L2_SEL_FLAG_GE | V4L2_SEL_FLAG_LE) &&
428             (r->width != w || r->height != h))
429                 return -ERANGE;
430         r->width = w;
431         r->height = h;
432         return 0;
433 }
434
435 int vivid_enum_fmt_vid(struct file *file, void  *priv,
436                                         struct v4l2_fmtdesc *f)
437 {
438         struct vivid_dev *dev = video_drvdata(file);
439         const struct vivid_fmt *fmt;
440
441         if (f->index >= ARRAY_SIZE(vivid_formats) -
442             (dev->multiplanar ? 0 : VIVID_MPLANAR_FORMATS))
443                 return -EINVAL;
444
445         fmt = &vivid_formats[f->index];
446
447         strlcpy(f->description, fmt->name, sizeof(f->description));
448         f->pixelformat = fmt->fourcc;
449         return 0;
450 }
451
452 int vidioc_enum_fmt_vid_mplane(struct file *file, void  *priv,
453                                         struct v4l2_fmtdesc *f)
454 {
455         struct vivid_dev *dev = video_drvdata(file);
456
457         if (!dev->multiplanar)
458                 return -ENOTTY;
459         return vivid_enum_fmt_vid(file, priv, f);
460 }
461
462 int vidioc_enum_fmt_vid(struct file *file, void  *priv,
463                                         struct v4l2_fmtdesc *f)
464 {
465         struct vivid_dev *dev = video_drvdata(file);
466
467         if (dev->multiplanar)
468                 return -ENOTTY;
469         return vivid_enum_fmt_vid(file, priv, f);
470 }
471
472 int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id)
473 {
474         struct vivid_dev *dev = video_drvdata(file);
475         struct video_device *vdev = video_devdata(file);
476
477         if (vdev->vfl_dir == VFL_DIR_RX) {
478                 if (!vivid_is_sdtv_cap(dev))
479                         return -ENODATA;
480                 *id = dev->std_cap;
481         } else {
482                 if (!vivid_is_svid_out(dev))
483                         return -ENODATA;
484                 *id = dev->std_out;
485         }
486         return 0;
487 }
488
489 int vidioc_g_dv_timings(struct file *file, void *_fh,
490                                     struct v4l2_dv_timings *timings)
491 {
492         struct vivid_dev *dev = video_drvdata(file);
493         struct video_device *vdev = video_devdata(file);
494
495         if (vdev->vfl_dir == VFL_DIR_RX) {
496                 if (!vivid_is_hdmi_cap(dev))
497                         return -ENODATA;
498                 *timings = dev->dv_timings_cap;
499         } else {
500                 if (!vivid_is_hdmi_out(dev))
501                         return -ENODATA;
502                 *timings = dev->dv_timings_out;
503         }
504         return 0;
505 }
506
507 int vidioc_enum_dv_timings(struct file *file, void *_fh,
508                                     struct v4l2_enum_dv_timings *timings)
509 {
510         struct vivid_dev *dev = video_drvdata(file);
511         struct video_device *vdev = video_devdata(file);
512
513         if (vdev->vfl_dir == VFL_DIR_RX) {
514                 if (!vivid_is_hdmi_cap(dev))
515                         return -ENODATA;
516         } else {
517                 if (!vivid_is_hdmi_out(dev))
518                         return -ENODATA;
519         }
520         return v4l2_enum_dv_timings_cap(timings, &vivid_dv_timings_cap,
521                         NULL, NULL);
522 }
523
524 int vidioc_dv_timings_cap(struct file *file, void *_fh,
525                                     struct v4l2_dv_timings_cap *cap)
526 {
527         struct vivid_dev *dev = video_drvdata(file);
528         struct video_device *vdev = video_devdata(file);
529
530         if (vdev->vfl_dir == VFL_DIR_RX) {
531                 if (!vivid_is_hdmi_cap(dev))
532                         return -ENODATA;
533         } else {
534                 if (!vivid_is_hdmi_out(dev))
535                         return -ENODATA;
536         }
537         *cap = vivid_dv_timings_cap;
538         return 0;
539 }
540
541 int vidioc_g_edid(struct file *file, void *_fh,
542                          struct v4l2_edid *edid)
543 {
544         struct vivid_dev *dev = video_drvdata(file);
545         struct video_device *vdev = video_devdata(file);
546
547         memset(edid->reserved, 0, sizeof(edid->reserved));
548         if (vdev->vfl_dir == VFL_DIR_RX) {
549                 if (edid->pad >= dev->num_inputs)
550                         return -EINVAL;
551                 if (dev->input_type[edid->pad] != HDMI)
552                         return -EINVAL;
553         } else {
554                 if (edid->pad >= dev->num_outputs)
555                         return -EINVAL;
556                 if (dev->output_type[edid->pad] != HDMI)
557                         return -EINVAL;
558         }
559         if (edid->start_block == 0 && edid->blocks == 0) {
560                 edid->blocks = dev->edid_blocks;
561                 return 0;
562         }
563         if (dev->edid_blocks == 0)
564                 return -ENODATA;
565         if (edid->start_block >= dev->edid_blocks)
566                 return -EINVAL;
567         if (edid->start_block + edid->blocks > dev->edid_blocks)
568                 edid->blocks = dev->edid_blocks - edid->start_block;
569         memcpy(edid->edid, dev->edid, edid->blocks * 128);
570         return 0;
571 }