Linux-libre 4.14.12-gnu
[librecmc/linux-libre.git] / drivers / media / platform / rcar-vin / rcar-v4l2.c
1 /*
2  * Driver for Renesas R-Car VIN
3  *
4  * Copyright (C) 2016 Renesas Electronics Corp.
5  * Copyright (C) 2011-2013 Renesas Solutions Corp.
6  * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com>
7  * Copyright (C) 2008 Magnus Damm
8  *
9  * Based on the soc-camera rcar_vin driver
10  *
11  * This program is free software; you can redistribute  it and/or modify it
12  * under  the terms of  the GNU General  Public License as published by the
13  * Free Software Foundation;  either version 2 of the  License, or (at your
14  * option) any later version.
15  */
16
17 #include <linux/pm_runtime.h>
18
19 #include <media/v4l2-event.h>
20 #include <media/v4l2-ioctl.h>
21 #include <media/v4l2-rect.h>
22
23 #include "rcar-vin.h"
24
25 #define RVIN_DEFAULT_FORMAT     V4L2_PIX_FMT_YUYV
26 #define RVIN_MAX_WIDTH          2048
27 #define RVIN_MAX_HEIGHT         2048
28
29 /* -----------------------------------------------------------------------------
30  * Format Conversions
31  */
32
33 static const struct rvin_video_format rvin_formats[] = {
34         {
35                 .fourcc                 = V4L2_PIX_FMT_NV16,
36                 .bpp                    = 1,
37         },
38         {
39                 .fourcc                 = V4L2_PIX_FMT_YUYV,
40                 .bpp                    = 2,
41         },
42         {
43                 .fourcc                 = V4L2_PIX_FMT_UYVY,
44                 .bpp                    = 2,
45         },
46         {
47                 .fourcc                 = V4L2_PIX_FMT_RGB565,
48                 .bpp                    = 2,
49         },
50         {
51                 .fourcc                 = V4L2_PIX_FMT_XRGB555,
52                 .bpp                    = 2,
53         },
54         {
55                 .fourcc                 = V4L2_PIX_FMT_XBGR32,
56                 .bpp                    = 4,
57         },
58 };
59
60 const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat)
61 {
62         int i;
63
64         for (i = 0; i < ARRAY_SIZE(rvin_formats); i++)
65                 if (rvin_formats[i].fourcc == pixelformat)
66                         return rvin_formats + i;
67
68         return NULL;
69 }
70
71 static u32 rvin_format_bytesperline(struct v4l2_pix_format *pix)
72 {
73         const struct rvin_video_format *fmt;
74
75         fmt = rvin_format_from_pixel(pix->pixelformat);
76
77         if (WARN_ON(!fmt))
78                 return -EINVAL;
79
80         return pix->width * fmt->bpp;
81 }
82
83 static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix)
84 {
85         if (pix->pixelformat == V4L2_PIX_FMT_NV16)
86                 return pix->bytesperline * pix->height * 2;
87
88         return pix->bytesperline * pix->height;
89 }
90
91 /* -----------------------------------------------------------------------------
92  * V4L2
93  */
94
95 static void rvin_reset_crop_compose(struct rvin_dev *vin)
96 {
97         vin->crop.top = vin->crop.left = 0;
98         vin->crop.width = vin->source.width;
99         vin->crop.height = vin->source.height;
100
101         vin->compose.top = vin->compose.left = 0;
102         vin->compose.width = vin->format.width;
103         vin->compose.height = vin->format.height;
104 }
105
106 static int rvin_reset_format(struct rvin_dev *vin)
107 {
108         struct v4l2_subdev_format fmt = {
109                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
110         };
111         struct v4l2_mbus_framefmt *mf = &fmt.format;
112         int ret;
113
114         fmt.pad = vin->digital.source_pad;
115
116         ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
117         if (ret)
118                 return ret;
119
120         vin->format.width       = mf->width;
121         vin->format.height      = mf->height;
122         vin->format.colorspace  = mf->colorspace;
123         vin->format.field       = mf->field;
124
125         /*
126          * If the subdevice uses ALTERNATE field mode and G_STD is
127          * implemented use the VIN HW to combine the two fields to
128          * one INTERLACED frame. The ALTERNATE field mode can still
129          * be requested in S_FMT and be respected, this is just the
130          * default which is applied at probing or when S_STD is called.
131          */
132         if (vin->format.field == V4L2_FIELD_ALTERNATE &&
133             v4l2_subdev_has_op(vin_to_source(vin), video, g_std))
134                 vin->format.field = V4L2_FIELD_INTERLACED;
135
136         switch (vin->format.field) {
137         case V4L2_FIELD_TOP:
138         case V4L2_FIELD_BOTTOM:
139         case V4L2_FIELD_ALTERNATE:
140                 vin->format.height /= 2;
141                 break;
142         case V4L2_FIELD_NONE:
143         case V4L2_FIELD_INTERLACED_TB:
144         case V4L2_FIELD_INTERLACED_BT:
145         case V4L2_FIELD_INTERLACED:
146                 break;
147         default:
148                 vin->format.field = V4L2_FIELD_NONE;
149                 break;
150         }
151
152         rvin_reset_crop_compose(vin);
153
154         vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
155         vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
156
157         return 0;
158 }
159
160 static int __rvin_try_format_source(struct rvin_dev *vin,
161                                     u32 which,
162                                     struct v4l2_pix_format *pix,
163                                     struct rvin_source_fmt *source)
164 {
165         struct v4l2_subdev *sd;
166         struct v4l2_subdev_pad_config *pad_cfg;
167         struct v4l2_subdev_format format = {
168                 .which = which,
169         };
170         enum v4l2_field field;
171         int ret;
172
173         sd = vin_to_source(vin);
174
175         v4l2_fill_mbus_format(&format.format, pix, vin->digital.code);
176
177         pad_cfg = v4l2_subdev_alloc_pad_config(sd);
178         if (pad_cfg == NULL)
179                 return -ENOMEM;
180
181         format.pad = vin->digital.source_pad;
182
183         field = pix->field;
184
185         ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, &format);
186         if (ret < 0 && ret != -ENOIOCTLCMD)
187                 goto done;
188
189         v4l2_fill_pix_format(pix, &format.format);
190
191         pix->field = field;
192
193         source->width = pix->width;
194         source->height = pix->height;
195
196         vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
197                 source->height);
198
199 done:
200         v4l2_subdev_free_pad_config(pad_cfg);
201         return ret;
202 }
203
204 static int __rvin_try_format(struct rvin_dev *vin,
205                              u32 which,
206                              struct v4l2_pix_format *pix,
207                              struct rvin_source_fmt *source)
208 {
209         u32 rwidth, rheight, walign;
210         int ret;
211
212         /* Requested */
213         rwidth = pix->width;
214         rheight = pix->height;
215
216         /* Keep current field if no specific one is asked for */
217         if (pix->field == V4L2_FIELD_ANY)
218                 pix->field = vin->format.field;
219
220         /* If requested format is not supported fallback to the default */
221         if (!rvin_format_from_pixel(pix->pixelformat)) {
222                 vin_dbg(vin, "Format 0x%x not found, using default 0x%x\n",
223                         pix->pixelformat, RVIN_DEFAULT_FORMAT);
224                 pix->pixelformat = RVIN_DEFAULT_FORMAT;
225         }
226
227         /* Always recalculate */
228         pix->bytesperline = 0;
229         pix->sizeimage = 0;
230
231         /* Limit to source capabilities */
232         ret = __rvin_try_format_source(vin, which, pix, source);
233         if (ret)
234                 return ret;
235
236         switch (pix->field) {
237         case V4L2_FIELD_TOP:
238         case V4L2_FIELD_BOTTOM:
239         case V4L2_FIELD_ALTERNATE:
240                 pix->height /= 2;
241                 source->height /= 2;
242                 break;
243         case V4L2_FIELD_NONE:
244         case V4L2_FIELD_INTERLACED_TB:
245         case V4L2_FIELD_INTERLACED_BT:
246         case V4L2_FIELD_INTERLACED:
247                 break;
248         default:
249                 pix->field = V4L2_FIELD_NONE;
250                 break;
251         }
252
253         /* If source can't match format try if VIN can scale */
254         if (source->width != rwidth || source->height != rheight)
255                 rvin_scale_try(vin, pix, rwidth, rheight);
256
257         /* HW limit width to a multiple of 32 (2^5) for NV16 else 2 (2^1) */
258         walign = vin->format.pixelformat == V4L2_PIX_FMT_NV16 ? 5 : 1;
259
260         /* Limit to VIN capabilities */
261         v4l_bound_align_image(&pix->width, 2, RVIN_MAX_WIDTH, walign,
262                               &pix->height, 4, RVIN_MAX_HEIGHT, 2, 0);
263
264         pix->bytesperline = max_t(u32, pix->bytesperline,
265                                   rvin_format_bytesperline(pix));
266         pix->sizeimage = max_t(u32, pix->sizeimage,
267                                rvin_format_sizeimage(pix));
268
269         if (vin->chip == RCAR_M1 && pix->pixelformat == V4L2_PIX_FMT_XBGR32) {
270                 vin_err(vin, "pixel format XBGR32 not supported on M1\n");
271                 return -EINVAL;
272         }
273
274         vin_dbg(vin, "Requested %ux%u Got %ux%u bpl: %d size: %d\n",
275                 rwidth, rheight, pix->width, pix->height,
276                 pix->bytesperline, pix->sizeimage);
277
278         return 0;
279 }
280
281 static int rvin_querycap(struct file *file, void *priv,
282                          struct v4l2_capability *cap)
283 {
284         struct rvin_dev *vin = video_drvdata(file);
285
286         strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
287         strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card));
288         snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
289                  dev_name(vin->dev));
290         return 0;
291 }
292
293 static int rvin_try_fmt_vid_cap(struct file *file, void *priv,
294                                 struct v4l2_format *f)
295 {
296         struct rvin_dev *vin = video_drvdata(file);
297         struct rvin_source_fmt source;
298
299         return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix,
300                                  &source);
301 }
302
303 static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
304                               struct v4l2_format *f)
305 {
306         struct rvin_dev *vin = video_drvdata(file);
307         struct rvin_source_fmt source;
308         int ret;
309
310         if (vb2_is_busy(&vin->queue))
311                 return -EBUSY;
312
313         ret = __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix,
314                                 &source);
315         if (ret)
316                 return ret;
317
318         vin->source.width = source.width;
319         vin->source.height = source.height;
320
321         vin->format = f->fmt.pix;
322
323         rvin_reset_crop_compose(vin);
324
325         return 0;
326 }
327
328 static int rvin_g_fmt_vid_cap(struct file *file, void *priv,
329                               struct v4l2_format *f)
330 {
331         struct rvin_dev *vin = video_drvdata(file);
332
333         f->fmt.pix = vin->format;
334
335         return 0;
336 }
337
338 static int rvin_enum_fmt_vid_cap(struct file *file, void *priv,
339                                  struct v4l2_fmtdesc *f)
340 {
341         if (f->index >= ARRAY_SIZE(rvin_formats))
342                 return -EINVAL;
343
344         f->pixelformat = rvin_formats[f->index].fourcc;
345
346         return 0;
347 }
348
349 static int rvin_g_selection(struct file *file, void *fh,
350                             struct v4l2_selection *s)
351 {
352         struct rvin_dev *vin = video_drvdata(file);
353
354         if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
355                 return -EINVAL;
356
357         switch (s->target) {
358         case V4L2_SEL_TGT_CROP_BOUNDS:
359         case V4L2_SEL_TGT_CROP_DEFAULT:
360                 s->r.left = s->r.top = 0;
361                 s->r.width = vin->source.width;
362                 s->r.height = vin->source.height;
363                 break;
364         case V4L2_SEL_TGT_CROP:
365                 s->r = vin->crop;
366                 break;
367         case V4L2_SEL_TGT_COMPOSE_BOUNDS:
368         case V4L2_SEL_TGT_COMPOSE_DEFAULT:
369                 s->r.left = s->r.top = 0;
370                 s->r.width = vin->format.width;
371                 s->r.height = vin->format.height;
372                 break;
373         case V4L2_SEL_TGT_COMPOSE:
374                 s->r = vin->compose;
375                 break;
376         default:
377                 return -EINVAL;
378         }
379
380         return 0;
381 }
382
383 static int rvin_s_selection(struct file *file, void *fh,
384                             struct v4l2_selection *s)
385 {
386         struct rvin_dev *vin = video_drvdata(file);
387         const struct rvin_video_format *fmt;
388         struct v4l2_rect r = s->r;
389         struct v4l2_rect max_rect;
390         struct v4l2_rect min_rect = {
391                 .width = 6,
392                 .height = 2,
393         };
394
395         if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
396                 return -EINVAL;
397
398         v4l2_rect_set_min_size(&r, &min_rect);
399
400         switch (s->target) {
401         case V4L2_SEL_TGT_CROP:
402                 /* Can't crop outside of source input */
403                 max_rect.top = max_rect.left = 0;
404                 max_rect.width = vin->source.width;
405                 max_rect.height = vin->source.height;
406                 v4l2_rect_map_inside(&r, &max_rect);
407
408                 v4l_bound_align_image(&r.width, 2, vin->source.width, 1,
409                                       &r.height, 4, vin->source.height, 2, 0);
410
411                 r.top  = clamp_t(s32, r.top, 0, vin->source.height - r.height);
412                 r.left = clamp_t(s32, r.left, 0, vin->source.width - r.width);
413
414                 vin->crop = s->r = r;
415
416                 vin_dbg(vin, "Cropped %dx%d@%d:%d of %dx%d\n",
417                         r.width, r.height, r.left, r.top,
418                         vin->source.width, vin->source.height);
419                 break;
420         case V4L2_SEL_TGT_COMPOSE:
421                 /* Make sure compose rect fits inside output format */
422                 max_rect.top = max_rect.left = 0;
423                 max_rect.width = vin->format.width;
424                 max_rect.height = vin->format.height;
425                 v4l2_rect_map_inside(&r, &max_rect);
426
427                 /*
428                  * Composing is done by adding a offset to the buffer address,
429                  * the HW wants this address to be aligned to HW_BUFFER_MASK.
430                  * Make sure the top and left values meets this requirement.
431                  */
432                 while ((r.top * vin->format.bytesperline) & HW_BUFFER_MASK)
433                         r.top--;
434
435                 fmt = rvin_format_from_pixel(vin->format.pixelformat);
436                 while ((r.left * fmt->bpp) & HW_BUFFER_MASK)
437                         r.left--;
438
439                 vin->compose = s->r = r;
440
441                 vin_dbg(vin, "Compose %dx%d@%d:%d in %dx%d\n",
442                         r.width, r.height, r.left, r.top,
443                         vin->format.width, vin->format.height);
444                 break;
445         default:
446                 return -EINVAL;
447         }
448
449         /* HW supports modifying configuration while running */
450         rvin_crop_scale_comp(vin);
451
452         return 0;
453 }
454
455 static int rvin_cropcap(struct file *file, void *priv,
456                         struct v4l2_cropcap *crop)
457 {
458         struct rvin_dev *vin = video_drvdata(file);
459         struct v4l2_subdev *sd = vin_to_source(vin);
460
461         if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
462                 return -EINVAL;
463
464         return v4l2_subdev_call(sd, video, g_pixelaspect, &crop->pixelaspect);
465 }
466
467 static int rvin_enum_input(struct file *file, void *priv,
468                            struct v4l2_input *i)
469 {
470         struct rvin_dev *vin = video_drvdata(file);
471         struct v4l2_subdev *sd = vin_to_source(vin);
472         int ret;
473
474         if (i->index != 0)
475                 return -EINVAL;
476
477         ret = v4l2_subdev_call(sd, video, g_input_status, &i->status);
478         if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
479                 return ret;
480
481         i->type = V4L2_INPUT_TYPE_CAMERA;
482
483         if (v4l2_subdev_has_op(sd, pad, dv_timings_cap)) {
484                 i->capabilities = V4L2_IN_CAP_DV_TIMINGS;
485                 i->std = 0;
486         } else {
487                 i->capabilities = V4L2_IN_CAP_STD;
488                 i->std = vin->vdev.tvnorms;
489         }
490
491         strlcpy(i->name, "Camera", sizeof(i->name));
492
493         return 0;
494 }
495
496 static int rvin_g_input(struct file *file, void *priv, unsigned int *i)
497 {
498         *i = 0;
499         return 0;
500 }
501
502 static int rvin_s_input(struct file *file, void *priv, unsigned int i)
503 {
504         if (i > 0)
505                 return -EINVAL;
506         return 0;
507 }
508
509 static int rvin_querystd(struct file *file, void *priv, v4l2_std_id *a)
510 {
511         struct rvin_dev *vin = video_drvdata(file);
512         struct v4l2_subdev *sd = vin_to_source(vin);
513
514         return v4l2_subdev_call(sd, video, querystd, a);
515 }
516
517 static int rvin_s_std(struct file *file, void *priv, v4l2_std_id a)
518 {
519         struct rvin_dev *vin = video_drvdata(file);
520         int ret;
521
522         ret = v4l2_subdev_call(vin_to_source(vin), video, s_std, a);
523         if (ret < 0)
524                 return ret;
525
526         /* Changing the standard will change the width/height */
527         return rvin_reset_format(vin);
528 }
529
530 static int rvin_g_std(struct file *file, void *priv, v4l2_std_id *a)
531 {
532         struct rvin_dev *vin = video_drvdata(file);
533         struct v4l2_subdev *sd = vin_to_source(vin);
534
535         return v4l2_subdev_call(sd, video, g_std, a);
536 }
537
538 static int rvin_subscribe_event(struct v4l2_fh *fh,
539                                 const struct v4l2_event_subscription *sub)
540 {
541         switch (sub->type) {
542         case V4L2_EVENT_SOURCE_CHANGE:
543                 return v4l2_event_subscribe(fh, sub, 4, NULL);
544         }
545         return v4l2_ctrl_subscribe_event(fh, sub);
546 }
547
548 static int rvin_enum_dv_timings(struct file *file, void *priv_fh,
549                                 struct v4l2_enum_dv_timings *timings)
550 {
551         struct rvin_dev *vin = video_drvdata(file);
552         struct v4l2_subdev *sd = vin_to_source(vin);
553         int ret;
554
555         if (timings->pad)
556                 return -EINVAL;
557
558         timings->pad = vin->digital.sink_pad;
559
560         ret = v4l2_subdev_call(sd, pad, enum_dv_timings, timings);
561
562         timings->pad = 0;
563
564         return ret;
565 }
566
567 static int rvin_s_dv_timings(struct file *file, void *priv_fh,
568                              struct v4l2_dv_timings *timings)
569 {
570         struct rvin_dev *vin = video_drvdata(file);
571         struct v4l2_subdev *sd = vin_to_source(vin);
572         int ret;
573
574         ret = v4l2_subdev_call(sd, video, s_dv_timings, timings);
575         if (ret)
576                 return ret;
577
578         /* Changing the timings will change the width/height */
579         return rvin_reset_format(vin);
580 }
581
582 static int rvin_g_dv_timings(struct file *file, void *priv_fh,
583                              struct v4l2_dv_timings *timings)
584 {
585         struct rvin_dev *vin = video_drvdata(file);
586         struct v4l2_subdev *sd = vin_to_source(vin);
587
588         return v4l2_subdev_call(sd, video, g_dv_timings, timings);
589 }
590
591 static int rvin_query_dv_timings(struct file *file, void *priv_fh,
592                                  struct v4l2_dv_timings *timings)
593 {
594         struct rvin_dev *vin = video_drvdata(file);
595         struct v4l2_subdev *sd = vin_to_source(vin);
596
597         return v4l2_subdev_call(sd, video, query_dv_timings, timings);
598 }
599
600 static int rvin_dv_timings_cap(struct file *file, void *priv_fh,
601                                struct v4l2_dv_timings_cap *cap)
602 {
603         struct rvin_dev *vin = video_drvdata(file);
604         struct v4l2_subdev *sd = vin_to_source(vin);
605         int ret;
606
607         if (cap->pad)
608                 return -EINVAL;
609
610         cap->pad = vin->digital.sink_pad;
611
612         ret = v4l2_subdev_call(sd, pad, dv_timings_cap, cap);
613
614         cap->pad = 0;
615
616         return ret;
617 }
618
619 static int rvin_g_edid(struct file *file, void *fh, struct v4l2_edid *edid)
620 {
621         struct rvin_dev *vin = video_drvdata(file);
622         struct v4l2_subdev *sd = vin_to_source(vin);
623         int ret;
624
625         if (edid->pad)
626                 return -EINVAL;
627
628         edid->pad = vin->digital.sink_pad;
629
630         ret = v4l2_subdev_call(sd, pad, get_edid, edid);
631
632         edid->pad = 0;
633
634         return ret;
635 }
636
637 static int rvin_s_edid(struct file *file, void *fh, struct v4l2_edid *edid)
638 {
639         struct rvin_dev *vin = video_drvdata(file);
640         struct v4l2_subdev *sd = vin_to_source(vin);
641         int ret;
642
643         if (edid->pad)
644                 return -EINVAL;
645
646         edid->pad = vin->digital.sink_pad;
647
648         ret = v4l2_subdev_call(sd, pad, set_edid, edid);
649
650         edid->pad = 0;
651
652         return ret;
653 }
654
655 static const struct v4l2_ioctl_ops rvin_ioctl_ops = {
656         .vidioc_querycap                = rvin_querycap,
657         .vidioc_try_fmt_vid_cap         = rvin_try_fmt_vid_cap,
658         .vidioc_g_fmt_vid_cap           = rvin_g_fmt_vid_cap,
659         .vidioc_s_fmt_vid_cap           = rvin_s_fmt_vid_cap,
660         .vidioc_enum_fmt_vid_cap        = rvin_enum_fmt_vid_cap,
661
662         .vidioc_g_selection             = rvin_g_selection,
663         .vidioc_s_selection             = rvin_s_selection,
664
665         .vidioc_cropcap                 = rvin_cropcap,
666
667         .vidioc_enum_input              = rvin_enum_input,
668         .vidioc_g_input                 = rvin_g_input,
669         .vidioc_s_input                 = rvin_s_input,
670
671         .vidioc_dv_timings_cap          = rvin_dv_timings_cap,
672         .vidioc_enum_dv_timings         = rvin_enum_dv_timings,
673         .vidioc_g_dv_timings            = rvin_g_dv_timings,
674         .vidioc_s_dv_timings            = rvin_s_dv_timings,
675         .vidioc_query_dv_timings        = rvin_query_dv_timings,
676
677         .vidioc_g_edid                  = rvin_g_edid,
678         .vidioc_s_edid                  = rvin_s_edid,
679
680         .vidioc_querystd                = rvin_querystd,
681         .vidioc_g_std                   = rvin_g_std,
682         .vidioc_s_std                   = rvin_s_std,
683
684         .vidioc_reqbufs                 = vb2_ioctl_reqbufs,
685         .vidioc_create_bufs             = vb2_ioctl_create_bufs,
686         .vidioc_querybuf                = vb2_ioctl_querybuf,
687         .vidioc_qbuf                    = vb2_ioctl_qbuf,
688         .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
689         .vidioc_expbuf                  = vb2_ioctl_expbuf,
690         .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
691         .vidioc_streamon                = vb2_ioctl_streamon,
692         .vidioc_streamoff               = vb2_ioctl_streamoff,
693
694         .vidioc_log_status              = v4l2_ctrl_log_status,
695         .vidioc_subscribe_event         = rvin_subscribe_event,
696         .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
697 };
698
699 /* -----------------------------------------------------------------------------
700  * File Operations
701  */
702
703 static int rvin_power_on(struct rvin_dev *vin)
704 {
705         int ret;
706         struct v4l2_subdev *sd = vin_to_source(vin);
707
708         pm_runtime_get_sync(vin->v4l2_dev.dev);
709
710         ret = v4l2_subdev_call(sd, core, s_power, 1);
711         if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
712                 return ret;
713         return 0;
714 }
715
716 static int rvin_power_off(struct rvin_dev *vin)
717 {
718         int ret;
719         struct v4l2_subdev *sd = vin_to_source(vin);
720
721         ret = v4l2_subdev_call(sd, core, s_power, 0);
722
723         pm_runtime_put(vin->v4l2_dev.dev);
724
725         if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
726                 return ret;
727
728         return 0;
729 }
730
731 static int rvin_initialize_device(struct file *file)
732 {
733         struct rvin_dev *vin = video_drvdata(file);
734         int ret;
735
736         struct v4l2_format f = {
737                 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
738                 .fmt.pix = {
739                         .width          = vin->format.width,
740                         .height         = vin->format.height,
741                         .field          = vin->format.field,
742                         .colorspace     = vin->format.colorspace,
743                         .pixelformat    = vin->format.pixelformat,
744                 },
745         };
746
747         ret = rvin_power_on(vin);
748         if (ret < 0)
749                 return ret;
750
751         pm_runtime_enable(&vin->vdev.dev);
752         ret = pm_runtime_resume(&vin->vdev.dev);
753         if (ret < 0 && ret != -ENOSYS)
754                 goto eresume;
755
756         /*
757          * Try to configure with default parameters. Notice: this is the
758          * very first open, so, we cannot race against other calls,
759          * apart from someone else calling open() simultaneously, but
760          * .host_lock is protecting us against it.
761          */
762         ret = rvin_s_fmt_vid_cap(file, NULL, &f);
763         if (ret < 0)
764                 goto esfmt;
765
766         v4l2_ctrl_handler_setup(&vin->ctrl_handler);
767
768         return 0;
769 esfmt:
770         pm_runtime_disable(&vin->vdev.dev);
771 eresume:
772         rvin_power_off(vin);
773
774         return ret;
775 }
776
777 static int rvin_open(struct file *file)
778 {
779         struct rvin_dev *vin = video_drvdata(file);
780         int ret;
781
782         mutex_lock(&vin->lock);
783
784         file->private_data = vin;
785
786         ret = v4l2_fh_open(file);
787         if (ret)
788                 goto unlock;
789
790         if (!v4l2_fh_is_singular_file(file))
791                 goto unlock;
792
793         if (rvin_initialize_device(file)) {
794                 v4l2_fh_release(file);
795                 ret = -ENODEV;
796         }
797
798 unlock:
799         mutex_unlock(&vin->lock);
800         return ret;
801 }
802
803 static int rvin_release(struct file *file)
804 {
805         struct rvin_dev *vin = video_drvdata(file);
806         bool fh_singular;
807         int ret;
808
809         mutex_lock(&vin->lock);
810
811         /* Save the singular status before we call the clean-up helper */
812         fh_singular = v4l2_fh_is_singular_file(file);
813
814         /* the release helper will cleanup any on-going streaming */
815         ret = _vb2_fop_release(file, NULL);
816
817         /*
818          * If this was the last open file.
819          * Then de-initialize hw module.
820          */
821         if (fh_singular) {
822                 pm_runtime_suspend(&vin->vdev.dev);
823                 pm_runtime_disable(&vin->vdev.dev);
824                 rvin_power_off(vin);
825         }
826
827         mutex_unlock(&vin->lock);
828
829         return ret;
830 }
831
832 static const struct v4l2_file_operations rvin_fops = {
833         .owner          = THIS_MODULE,
834         .unlocked_ioctl = video_ioctl2,
835         .open           = rvin_open,
836         .release        = rvin_release,
837         .poll           = vb2_fop_poll,
838         .mmap           = vb2_fop_mmap,
839         .read           = vb2_fop_read,
840 };
841
842 void rvin_v4l2_remove(struct rvin_dev *vin)
843 {
844         v4l2_info(&vin->v4l2_dev, "Removing %s\n",
845                   video_device_node_name(&vin->vdev));
846
847         /* Checks internaly if handlers have been init or not */
848         v4l2_ctrl_handler_free(&vin->ctrl_handler);
849
850         /* Checks internaly if vdev have been init or not */
851         video_unregister_device(&vin->vdev);
852 }
853
854 static void rvin_notify(struct v4l2_subdev *sd,
855                         unsigned int notification, void *arg)
856 {
857         struct rvin_dev *vin =
858                 container_of(sd->v4l2_dev, struct rvin_dev, v4l2_dev);
859
860         switch (notification) {
861         case V4L2_DEVICE_NOTIFY_EVENT:
862                 v4l2_event_queue(&vin->vdev, arg);
863                 break;
864         default:
865                 break;
866         }
867 }
868
869 int rvin_v4l2_probe(struct rvin_dev *vin)
870 {
871         struct video_device *vdev = &vin->vdev;
872         struct v4l2_subdev *sd = vin_to_source(vin);
873         int ret;
874
875         v4l2_set_subdev_hostdata(sd, vin);
876
877         vin->v4l2_dev.notify = rvin_notify;
878
879         ret = v4l2_subdev_call(sd, video, g_tvnorms, &vin->vdev.tvnorms);
880         if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
881                 return ret;
882
883         if (vin->vdev.tvnorms == 0) {
884                 /* Disable the STD API if there are no tvnorms defined */
885                 v4l2_disable_ioctl(&vin->vdev, VIDIOC_G_STD);
886                 v4l2_disable_ioctl(&vin->vdev, VIDIOC_S_STD);
887                 v4l2_disable_ioctl(&vin->vdev, VIDIOC_QUERYSTD);
888                 v4l2_disable_ioctl(&vin->vdev, VIDIOC_ENUMSTD);
889         }
890
891         /* Add the controls */
892         /*
893          * Currently the subdev with the largest number of controls (13) is
894          * ov6550. So let's pick 16 as a hint for the control handler. Note
895          * that this is a hint only: too large and you waste some memory, too
896          * small and there is a (very) small performance hit when looking up
897          * controls in the internal hash.
898          */
899         ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16);
900         if (ret < 0)
901                 return ret;
902
903         ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, sd->ctrl_handler, NULL);
904         if (ret < 0)
905                 return ret;
906
907         /* video node */
908         vdev->fops = &rvin_fops;
909         vdev->v4l2_dev = &vin->v4l2_dev;
910         vdev->queue = &vin->queue;
911         strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
912         vdev->release = video_device_release_empty;
913         vdev->ioctl_ops = &rvin_ioctl_ops;
914         vdev->lock = &vin->lock;
915         vdev->ctrl_handler = &vin->ctrl_handler;
916         vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
917                 V4L2_CAP_READWRITE;
918
919         vin->format.pixelformat = RVIN_DEFAULT_FORMAT;
920         rvin_reset_format(vin);
921
922         ret = video_register_device(&vin->vdev, VFL_TYPE_GRABBER, -1);
923         if (ret) {
924                 vin_err(vin, "Failed to register video device\n");
925                 return ret;
926         }
927
928         video_set_drvdata(&vin->vdev, vin);
929
930         v4l2_info(&vin->v4l2_dev, "Device registered as %s\n",
931                   video_device_node_name(&vin->vdev));
932
933         return ret;
934 }