Linux 6.9-rc1
[linux-2.6-microblaze.git] / drivers / media / test-drivers / vim2m.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * A virtual v4l2-mem2mem example device.
4  *
5  * This is a virtual device driver for testing mem-to-mem videobuf framework.
6  * It simulates a device that uses memory buffers for both source and
7  * destination, processes the data and issues an "irq" (simulated by a delayed
8  * workqueue).
9  * The device is capable of multi-instance, multi-buffer-per-transaction
10  * operation (via the mem2mem framework).
11  *
12  * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
13  * Pawel Osciak, <pawel@osciak.com>
14  * Marek Szyprowski, <m.szyprowski@samsung.com>
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by the
18  * Free Software Foundation; either version 2 of the
19  * License, or (at your option) any later version
20  */
21 #include <linux/module.h>
22 #include <linux/delay.h>
23 #include <linux/fs.h>
24 #include <linux/sched.h>
25 #include <linux/slab.h>
26
27 #include <linux/platform_device.h>
28 #include <media/v4l2-mem2mem.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-ioctl.h>
31 #include <media/v4l2-ctrls.h>
32 #include <media/v4l2-event.h>
33 #include <media/videobuf2-vmalloc.h>
34
35 MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
36 MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
37 MODULE_LICENSE("GPL");
38 MODULE_VERSION("0.2");
39 MODULE_ALIAS("mem2mem_testdev");
40
41 static unsigned int debug;
42 module_param(debug, uint, 0644);
43 MODULE_PARM_DESC(debug, "debug level");
44
45 /* Default transaction time in msec */
46 static unsigned int default_transtime = 40; /* Max 25 fps */
47 module_param(default_transtime, uint, 0644);
48 MODULE_PARM_DESC(default_transtime, "default transaction time in ms");
49
50 #define MIN_W 32
51 #define MIN_H 32
52 #define MAX_W 640
53 #define MAX_H 480
54
55 /* Pixel alignment for non-bayer formats */
56 #define WIDTH_ALIGN 2
57 #define HEIGHT_ALIGN 1
58
59 /* Pixel alignment for bayer formats */
60 #define BAYER_WIDTH_ALIGN  2
61 #define BAYER_HEIGHT_ALIGN 2
62
63 /* Flags that indicate a format can be used for capture/output */
64 #define MEM2MEM_CAPTURE BIT(0)
65 #define MEM2MEM_OUTPUT  BIT(1)
66
67 #define MEM2MEM_NAME            "vim2m"
68
69 /* Per queue */
70 #define MEM2MEM_DEF_NUM_BUFS    VIDEO_MAX_FRAME
71 /* In bytes, per queue */
72 #define MEM2MEM_VID_MEM_LIMIT   (16 * 1024 * 1024)
73
74 /* Flags that indicate processing mode */
75 #define MEM2MEM_HFLIP   BIT(0)
76 #define MEM2MEM_VFLIP   BIT(1)
77
78 #define dprintk(dev, lvl, fmt, arg...) \
79         v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
80
81 static void vim2m_dev_release(struct device *dev)
82 {}
83
84 static struct platform_device vim2m_pdev = {
85         .name           = MEM2MEM_NAME,
86         .dev.release    = vim2m_dev_release,
87 };
88
89 struct vim2m_fmt {
90         u32     fourcc;
91         int     depth;
92         /* Types the format can be used for */
93         u32     types;
94 };
95
96 static struct vim2m_fmt formats[] = {
97         {
98                 .fourcc = V4L2_PIX_FMT_RGB565,  /* rrrrrggg gggbbbbb */
99                 .depth  = 16,
100                 .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
101         }, {
102                 .fourcc = V4L2_PIX_FMT_RGB565X, /* gggbbbbb rrrrrggg */
103                 .depth  = 16,
104                 .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
105         }, {
106                 .fourcc = V4L2_PIX_FMT_RGB24,
107                 .depth  = 24,
108                 .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
109         }, {
110                 .fourcc = V4L2_PIX_FMT_BGR24,
111                 .depth  = 24,
112                 .types  = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT,
113         }, {
114                 .fourcc = V4L2_PIX_FMT_YUYV,
115                 .depth  = 16,
116                 .types  = MEM2MEM_CAPTURE,
117         }, {
118                 .fourcc = V4L2_PIX_FMT_SBGGR8,
119                 .depth  = 8,
120                 .types  = MEM2MEM_CAPTURE,
121         }, {
122                 .fourcc = V4L2_PIX_FMT_SGBRG8,
123                 .depth  = 8,
124                 .types  = MEM2MEM_CAPTURE,
125         }, {
126                 .fourcc = V4L2_PIX_FMT_SGRBG8,
127                 .depth  = 8,
128                 .types  = MEM2MEM_CAPTURE,
129         }, {
130                 .fourcc = V4L2_PIX_FMT_SRGGB8,
131                 .depth  = 8,
132                 .types  = MEM2MEM_CAPTURE,
133         },
134 };
135
136 #define NUM_FORMATS ARRAY_SIZE(formats)
137
138 /* Per-queue, driver-specific private data */
139 struct vim2m_q_data {
140         unsigned int            width;
141         unsigned int            height;
142         unsigned int            sizeimage;
143         unsigned int            sequence;
144         struct vim2m_fmt        *fmt;
145 };
146
147 enum {
148         V4L2_M2M_SRC = 0,
149         V4L2_M2M_DST = 1,
150 };
151
152 #define V4L2_CID_TRANS_TIME_MSEC        (V4L2_CID_USER_BASE + 0x1000)
153 #define V4L2_CID_TRANS_NUM_BUFS         (V4L2_CID_USER_BASE + 0x1001)
154
155 static struct vim2m_fmt *find_format(u32 fourcc)
156 {
157         struct vim2m_fmt *fmt;
158         unsigned int k;
159
160         for (k = 0; k < NUM_FORMATS; k++) {
161                 fmt = &formats[k];
162                 if (fmt->fourcc == fourcc)
163                         break;
164         }
165
166         if (k == NUM_FORMATS)
167                 return NULL;
168
169         return &formats[k];
170 }
171
172 static void get_alignment(u32 fourcc,
173                           unsigned int *walign, unsigned int *halign)
174 {
175         switch (fourcc) {
176         case V4L2_PIX_FMT_SBGGR8:
177         case V4L2_PIX_FMT_SGBRG8:
178         case V4L2_PIX_FMT_SGRBG8:
179         case V4L2_PIX_FMT_SRGGB8:
180                 *walign = BAYER_WIDTH_ALIGN;
181                 *halign = BAYER_HEIGHT_ALIGN;
182                 return;
183         default:
184                 *walign = WIDTH_ALIGN;
185                 *halign = HEIGHT_ALIGN;
186                 return;
187         }
188 }
189
190 struct vim2m_dev {
191         struct v4l2_device      v4l2_dev;
192         struct video_device     vfd;
193 #ifdef CONFIG_MEDIA_CONTROLLER
194         struct media_device     mdev;
195 #endif
196
197         atomic_t                num_inst;
198         struct mutex            dev_mutex;
199
200         struct v4l2_m2m_dev     *m2m_dev;
201 };
202
203 struct vim2m_ctx {
204         struct v4l2_fh          fh;
205         struct vim2m_dev        *dev;
206
207         struct v4l2_ctrl_handler hdl;
208
209         /* Processed buffers in this transaction */
210         u8                      num_processed;
211
212         /* Transaction length (i.e. how many buffers per transaction) */
213         u32                     translen;
214         /* Transaction time (i.e. simulated processing time) in milliseconds */
215         u32                     transtime;
216
217         struct mutex            vb_mutex;
218         struct delayed_work     work_run;
219
220         /* Abort requested by m2m */
221         int                     aborting;
222
223         /* Processing mode */
224         int                     mode;
225
226         enum v4l2_colorspace    colorspace;
227         enum v4l2_ycbcr_encoding ycbcr_enc;
228         enum v4l2_xfer_func     xfer_func;
229         enum v4l2_quantization  quant;
230
231         /* Source and destination queue data */
232         struct vim2m_q_data   q_data[2];
233 };
234
235 static inline struct vim2m_ctx *file2ctx(struct file *file)
236 {
237         return container_of(file->private_data, struct vim2m_ctx, fh);
238 }
239
240 static struct vim2m_q_data *get_q_data(struct vim2m_ctx *ctx,
241                                        enum v4l2_buf_type type)
242 {
243         switch (type) {
244         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
245                 return &ctx->q_data[V4L2_M2M_SRC];
246         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
247                 return &ctx->q_data[V4L2_M2M_DST];
248         default:
249                 return NULL;
250         }
251 }
252
253 static const char *type_name(enum v4l2_buf_type type)
254 {
255         switch (type) {
256         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
257                 return "Output";
258         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
259                 return "Capture";
260         default:
261                 return "Invalid";
262         }
263 }
264
265 #define CLIP(__color) \
266         (u8)(((__color) > 0xff) ? 0xff : (((__color) < 0) ? 0 : (__color)))
267
268 static void copy_line(struct vim2m_q_data *q_data_out,
269                       u8 *src, u8 *dst, bool reverse)
270 {
271         int x, depth = q_data_out->fmt->depth >> 3;
272
273         if (!reverse) {
274                 memcpy(dst, src, q_data_out->width * depth);
275         } else {
276                 for (x = 0; x < q_data_out->width >> 1; x++) {
277                         memcpy(dst, src, depth);
278                         memcpy(dst + depth, src - depth, depth);
279                         src -= depth << 1;
280                         dst += depth << 1;
281                 }
282                 return;
283         }
284 }
285
286 static void copy_two_pixels(struct vim2m_q_data *q_data_in,
287                             struct vim2m_q_data *q_data_out,
288                             u8 *src[2], u8 **dst, int ypos, bool reverse)
289 {
290         struct vim2m_fmt *out = q_data_out->fmt;
291         struct vim2m_fmt *in = q_data_in->fmt;
292         u8 _r[2], _g[2], _b[2], *r, *g, *b;
293         int i;
294
295         /* Step 1: read two consecutive pixels from src pointer */
296
297         r = _r;
298         g = _g;
299         b = _b;
300
301         switch (in->fourcc) {
302         case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
303                 for (i = 0; i < 2; i++) {
304                         u16 pix = le16_to_cpu(*(__le16 *)(src[i]));
305
306                         *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07;
307                         *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
308                         *b++ = (u8)((pix & 0x1f) << 3) | 0x07;
309                 }
310                 break;
311         case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
312                 for (i = 0; i < 2; i++) {
313                         u16 pix = be16_to_cpu(*(__be16 *)(src[i]));
314
315                         *r++ = (u8)(((pix & 0xf800) >> 11) << 3) | 0x07;
316                         *g++ = (u8)((((pix & 0x07e0) >> 5)) << 2) | 0x03;
317                         *b++ = (u8)((pix & 0x1f) << 3) | 0x07;
318                 }
319                 break;
320         default:
321         case V4L2_PIX_FMT_RGB24:
322                 for (i = 0; i < 2; i++) {
323                         *r++ = src[i][0];
324                         *g++ = src[i][1];
325                         *b++ = src[i][2];
326                 }
327                 break;
328         case V4L2_PIX_FMT_BGR24:
329                 for (i = 0; i < 2; i++) {
330                         *b++ = src[i][0];
331                         *g++ = src[i][1];
332                         *r++ = src[i][2];
333                 }
334                 break;
335         }
336
337         /* Step 2: store two consecutive points, reversing them if needed */
338
339         r = _r;
340         g = _g;
341         b = _b;
342
343         switch (out->fourcc) {
344         case V4L2_PIX_FMT_RGB565: /* rrrrrggg gggbbbbb */
345                 for (i = 0; i < 2; i++) {
346                         u16 pix;
347                         __le16 *dst_pix = (__le16 *)*dst;
348
349                         pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) |
350                               (*b >> 3);
351
352                         *dst_pix = cpu_to_le16(pix);
353
354                         *dst += 2;
355                 }
356                 return;
357         case V4L2_PIX_FMT_RGB565X: /* gggbbbbb rrrrrggg */
358                 for (i = 0; i < 2; i++) {
359                         u16 pix;
360                         __be16 *dst_pix = (__be16 *)*dst;
361
362                         pix = ((*r << 8) & 0xf800) | ((*g << 3) & 0x07e0) |
363                               (*b >> 3);
364
365                         *dst_pix = cpu_to_be16(pix);
366
367                         *dst += 2;
368                 }
369                 return;
370         case V4L2_PIX_FMT_RGB24:
371                 for (i = 0; i < 2; i++) {
372                         *(*dst)++ = *r++;
373                         *(*dst)++ = *g++;
374                         *(*dst)++ = *b++;
375                 }
376                 return;
377         case V4L2_PIX_FMT_BGR24:
378                 for (i = 0; i < 2; i++) {
379                         *(*dst)++ = *b++;
380                         *(*dst)++ = *g++;
381                         *(*dst)++ = *r++;
382                 }
383                 return;
384         case V4L2_PIX_FMT_YUYV:
385         default:
386         {
387                 u8 y, y1, u, v;
388
389                 y = ((8453  * (*r) + 16594 * (*g) +  3223 * (*b)
390                      + 524288) >> 15);
391                 u = ((-4878 * (*r) - 9578  * (*g) + 14456 * (*b)
392                      + 4210688) >> 15);
393                 v = ((14456 * (*r++) - 12105 * (*g++) - 2351 * (*b++)
394                      + 4210688) >> 15);
395                 y1 = ((8453 * (*r) + 16594 * (*g) +  3223 * (*b)
396                      + 524288) >> 15);
397
398                 *(*dst)++ = y;
399                 *(*dst)++ = u;
400
401                 *(*dst)++ = y1;
402                 *(*dst)++ = v;
403                 return;
404         }
405         case V4L2_PIX_FMT_SBGGR8:
406                 if (!(ypos & 1)) {
407                         *(*dst)++ = *b;
408                         *(*dst)++ = *++g;
409                 } else {
410                         *(*dst)++ = *g;
411                         *(*dst)++ = *++r;
412                 }
413                 return;
414         case V4L2_PIX_FMT_SGBRG8:
415                 if (!(ypos & 1)) {
416                         *(*dst)++ = *g;
417                         *(*dst)++ = *++b;
418                 } else {
419                         *(*dst)++ = *r;
420                         *(*dst)++ = *++g;
421                 }
422                 return;
423         case V4L2_PIX_FMT_SGRBG8:
424                 if (!(ypos & 1)) {
425                         *(*dst)++ = *g;
426                         *(*dst)++ = *++r;
427                 } else {
428                         *(*dst)++ = *b;
429                         *(*dst)++ = *++g;
430                 }
431                 return;
432         case V4L2_PIX_FMT_SRGGB8:
433                 if (!(ypos & 1)) {
434                         *(*dst)++ = *r;
435                         *(*dst)++ = *++g;
436                 } else {
437                         *(*dst)++ = *g;
438                         *(*dst)++ = *++b;
439                 }
440                 return;
441         }
442 }
443
444 static int device_process(struct vim2m_ctx *ctx,
445                           struct vb2_v4l2_buffer *in_vb,
446                           struct vb2_v4l2_buffer *out_vb)
447 {
448         struct vim2m_dev *dev = ctx->dev;
449         struct vim2m_q_data *q_data_in, *q_data_out;
450         u8 *p_in, *p_line, *p_in_x[2], *p, *p_out;
451         unsigned int width, height, bytesperline, bytes_per_pixel;
452         unsigned int x, y, y_in, y_out, x_int, x_fract, x_err, x_offset;
453         int start, end, step;
454
455         q_data_in = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
456         if (!q_data_in)
457                 return 0;
458         bytesperline = (q_data_in->width * q_data_in->fmt->depth) >> 3;
459         bytes_per_pixel = q_data_in->fmt->depth >> 3;
460
461         q_data_out = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
462         if (!q_data_out)
463                 return 0;
464
465         /* As we're doing scaling, use the output dimensions here */
466         height = q_data_out->height;
467         width = q_data_out->width;
468
469         p_in = vb2_plane_vaddr(&in_vb->vb2_buf, 0);
470         p_out = vb2_plane_vaddr(&out_vb->vb2_buf, 0);
471         if (!p_in || !p_out) {
472                 v4l2_err(&dev->v4l2_dev,
473                          "Acquiring kernel pointers to buffers failed\n");
474                 return -EFAULT;
475         }
476
477         out_vb->sequence = q_data_out->sequence++;
478         in_vb->sequence = q_data_in->sequence++;
479         v4l2_m2m_buf_copy_metadata(in_vb, out_vb, true);
480
481         if (ctx->mode & MEM2MEM_VFLIP) {
482                 start = height - 1;
483                 end = -1;
484                 step = -1;
485         } else {
486                 start = 0;
487                 end = height;
488                 step = 1;
489         }
490         y_out = 0;
491
492         /*
493          * When format and resolution are identical,
494          * we can use a faster copy logic
495          */
496         if (q_data_in->fmt->fourcc == q_data_out->fmt->fourcc &&
497             q_data_in->width == q_data_out->width &&
498             q_data_in->height == q_data_out->height) {
499                 for (y = start; y != end; y += step, y_out++) {
500                         p = p_in + (y * bytesperline);
501                         if (ctx->mode & MEM2MEM_HFLIP)
502                                 p += bytesperline - (q_data_in->fmt->depth >> 3);
503
504                         copy_line(q_data_out, p, p_out,
505                                   ctx->mode & MEM2MEM_HFLIP);
506
507                         p_out += bytesperline;
508                 }
509                 return 0;
510         }
511
512         /* Slower algorithm with format conversion, hflip, vflip and scaler */
513
514         /* To speed scaler up, use Bresenham for X dimension */
515         x_int = q_data_in->width / q_data_out->width;
516         x_fract = q_data_in->width % q_data_out->width;
517
518         for (y = start; y != end; y += step, y_out++) {
519                 y_in = (y * q_data_in->height) / q_data_out->height;
520                 x_offset = 0;
521                 x_err = 0;
522
523                 p_line = p_in + (y_in * bytesperline);
524                 if (ctx->mode & MEM2MEM_HFLIP)
525                         p_line += bytesperline - (q_data_in->fmt->depth >> 3);
526                 p_in_x[0] = p_line;
527
528                 for (x = 0; x < width >> 1; x++) {
529                         x_offset += x_int;
530                         x_err += x_fract;
531                         if (x_err > width) {
532                                 x_offset++;
533                                 x_err -= width;
534                         }
535
536                         if (ctx->mode & MEM2MEM_HFLIP)
537                                 p_in_x[1] = p_line - x_offset * bytes_per_pixel;
538                         else
539                                 p_in_x[1] = p_line + x_offset * bytes_per_pixel;
540
541                         copy_two_pixels(q_data_in, q_data_out,
542                                         p_in_x, &p_out, y_out,
543                                         ctx->mode & MEM2MEM_HFLIP);
544
545                         /* Calculate the next p_in_x0 */
546                         x_offset += x_int;
547                         x_err += x_fract;
548                         if (x_err > width) {
549                                 x_offset++;
550                                 x_err -= width;
551                         }
552
553                         if (ctx->mode & MEM2MEM_HFLIP)
554                                 p_in_x[0] = p_line - x_offset * bytes_per_pixel;
555                         else
556                                 p_in_x[0] = p_line + x_offset * bytes_per_pixel;
557                 }
558         }
559
560         return 0;
561 }
562
563 /*
564  * mem2mem callbacks
565  */
566
567 /*
568  * job_ready() - check whether an instance is ready to be scheduled to run
569  */
570 static int job_ready(void *priv)
571 {
572         struct vim2m_ctx *ctx = priv;
573
574         if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen
575             || v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) < ctx->translen) {
576                 dprintk(ctx->dev, 1, "Not enough buffers available\n");
577                 return 0;
578         }
579
580         return 1;
581 }
582
583 static void job_abort(void *priv)
584 {
585         struct vim2m_ctx *ctx = priv;
586
587         /* Will cancel the transaction in the next interrupt handler */
588         ctx->aborting = 1;
589 }
590
591 /* device_run() - prepares and starts the device
592  *
593  * This simulates all the immediate preparations required before starting
594  * a device. This will be called by the framework when it decides to schedule
595  * a particular instance.
596  */
597 static void device_run(void *priv)
598 {
599         struct vim2m_ctx *ctx = priv;
600         struct vb2_v4l2_buffer *src_buf, *dst_buf;
601
602         src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
603         dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
604
605         /* Apply request controls if any */
606         v4l2_ctrl_request_setup(src_buf->vb2_buf.req_obj.req,
607                                 &ctx->hdl);
608
609         device_process(ctx, src_buf, dst_buf);
610
611         /* Complete request controls if any */
612         v4l2_ctrl_request_complete(src_buf->vb2_buf.req_obj.req,
613                                    &ctx->hdl);
614
615         /* Run delayed work, which simulates a hardware irq  */
616         schedule_delayed_work(&ctx->work_run, msecs_to_jiffies(ctx->transtime));
617 }
618
619 static void device_work(struct work_struct *w)
620 {
621         struct vim2m_ctx *curr_ctx;
622         struct vim2m_dev *vim2m_dev;
623         struct vb2_v4l2_buffer *src_vb, *dst_vb;
624
625         curr_ctx = container_of(w, struct vim2m_ctx, work_run.work);
626
627         vim2m_dev = curr_ctx->dev;
628
629         src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
630         dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
631
632         curr_ctx->num_processed++;
633
634         v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
635         v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
636
637         if (curr_ctx->num_processed == curr_ctx->translen
638             || curr_ctx->aborting) {
639                 dprintk(curr_ctx->dev, 2, "Finishing capture buffer fill\n");
640                 curr_ctx->num_processed = 0;
641                 v4l2_m2m_job_finish(vim2m_dev->m2m_dev, curr_ctx->fh.m2m_ctx);
642         } else {
643                 device_run(curr_ctx);
644         }
645 }
646
647 /*
648  * video ioctls
649  */
650 static int vidioc_querycap(struct file *file, void *priv,
651                            struct v4l2_capability *cap)
652 {
653         strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver));
654         strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card));
655         snprintf(cap->bus_info, sizeof(cap->bus_info),
656                  "platform:%s", MEM2MEM_NAME);
657         return 0;
658 }
659
660 static int enum_fmt(struct v4l2_fmtdesc *f, u32 type)
661 {
662         int i, num;
663         struct vim2m_fmt *fmt;
664
665         num = 0;
666
667         for (i = 0; i < NUM_FORMATS; ++i) {
668                 if (formats[i].types & type) {
669                         /* index-th format of type type found ? */
670                         if (num == f->index)
671                                 break;
672                         /*
673                          * Correct type but haven't reached our index yet,
674                          * just increment per-type index
675                          */
676                         ++num;
677                 }
678         }
679
680         if (i < NUM_FORMATS) {
681                 /* Format found */
682                 fmt = &formats[i];
683                 f->pixelformat = fmt->fourcc;
684                 return 0;
685         }
686
687         /* Format not found */
688         return -EINVAL;
689 }
690
691 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
692                                    struct v4l2_fmtdesc *f)
693 {
694         return enum_fmt(f, MEM2MEM_CAPTURE);
695 }
696
697 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
698                                    struct v4l2_fmtdesc *f)
699 {
700         return enum_fmt(f, MEM2MEM_OUTPUT);
701 }
702
703 static int vidioc_enum_framesizes(struct file *file, void *priv,
704                                   struct v4l2_frmsizeenum *fsize)
705 {
706         if (fsize->index != 0)
707                 return -EINVAL;
708
709         if (!find_format(fsize->pixel_format))
710                 return -EINVAL;
711
712         fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
713         fsize->stepwise.min_width = MIN_W;
714         fsize->stepwise.min_height = MIN_H;
715         fsize->stepwise.max_width = MAX_W;
716         fsize->stepwise.max_height = MAX_H;
717
718         get_alignment(fsize->pixel_format,
719                       &fsize->stepwise.step_width,
720                       &fsize->stepwise.step_height);
721         return 0;
722 }
723
724 static int vidioc_g_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
725 {
726         struct vb2_queue *vq;
727         struct vim2m_q_data *q_data;
728
729         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
730         if (!vq)
731                 return -EINVAL;
732
733         q_data = get_q_data(ctx, f->type);
734         if (!q_data)
735                 return -EINVAL;
736
737         f->fmt.pix.width        = q_data->width;
738         f->fmt.pix.height       = q_data->height;
739         f->fmt.pix.field        = V4L2_FIELD_NONE;
740         f->fmt.pix.pixelformat  = q_data->fmt->fourcc;
741         f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
742         f->fmt.pix.sizeimage    = q_data->sizeimage;
743         f->fmt.pix.colorspace   = ctx->colorspace;
744         f->fmt.pix.xfer_func    = ctx->xfer_func;
745         f->fmt.pix.ycbcr_enc    = ctx->ycbcr_enc;
746         f->fmt.pix.quantization = ctx->quant;
747
748         return 0;
749 }
750
751 static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
752                                 struct v4l2_format *f)
753 {
754         return vidioc_g_fmt(file2ctx(file), f);
755 }
756
757 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
758                                 struct v4l2_format *f)
759 {
760         return vidioc_g_fmt(file2ctx(file), f);
761 }
762
763 static int vidioc_try_fmt(struct v4l2_format *f, struct vim2m_fmt *fmt)
764 {
765         int walign, halign;
766         /*
767          * V4L2 specification specifies the driver corrects the
768          * format struct if any of the dimensions is unsupported
769          */
770         if (f->fmt.pix.height < MIN_H)
771                 f->fmt.pix.height = MIN_H;
772         else if (f->fmt.pix.height > MAX_H)
773                 f->fmt.pix.height = MAX_H;
774
775         if (f->fmt.pix.width < MIN_W)
776                 f->fmt.pix.width = MIN_W;
777         else if (f->fmt.pix.width > MAX_W)
778                 f->fmt.pix.width = MAX_W;
779
780         get_alignment(f->fmt.pix.pixelformat, &walign, &halign);
781         f->fmt.pix.width &= ~(walign - 1);
782         f->fmt.pix.height &= ~(halign - 1);
783         f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
784         f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
785         f->fmt.pix.field = V4L2_FIELD_NONE;
786
787         return 0;
788 }
789
790 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
791                                   struct v4l2_format *f)
792 {
793         struct vim2m_fmt *fmt;
794         struct vim2m_ctx *ctx = file2ctx(file);
795
796         fmt = find_format(f->fmt.pix.pixelformat);
797         if (!fmt) {
798                 f->fmt.pix.pixelformat = formats[0].fourcc;
799                 fmt = find_format(f->fmt.pix.pixelformat);
800         }
801         if (!(fmt->types & MEM2MEM_CAPTURE)) {
802                 v4l2_err(&ctx->dev->v4l2_dev,
803                          "Fourcc format (0x%08x) invalid.\n",
804                          f->fmt.pix.pixelformat);
805                 return -EINVAL;
806         }
807         f->fmt.pix.colorspace = ctx->colorspace;
808         f->fmt.pix.xfer_func = ctx->xfer_func;
809         f->fmt.pix.ycbcr_enc = ctx->ycbcr_enc;
810         f->fmt.pix.quantization = ctx->quant;
811
812         return vidioc_try_fmt(f, fmt);
813 }
814
815 static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
816                                   struct v4l2_format *f)
817 {
818         struct vim2m_fmt *fmt;
819         struct vim2m_ctx *ctx = file2ctx(file);
820
821         fmt = find_format(f->fmt.pix.pixelformat);
822         if (!fmt) {
823                 f->fmt.pix.pixelformat = formats[0].fourcc;
824                 fmt = find_format(f->fmt.pix.pixelformat);
825         }
826         if (!(fmt->types & MEM2MEM_OUTPUT)) {
827                 v4l2_err(&ctx->dev->v4l2_dev,
828                          "Fourcc format (0x%08x) invalid.\n",
829                          f->fmt.pix.pixelformat);
830                 return -EINVAL;
831         }
832         if (!f->fmt.pix.colorspace)
833                 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
834
835         return vidioc_try_fmt(f, fmt);
836 }
837
838 static int vidioc_s_fmt(struct vim2m_ctx *ctx, struct v4l2_format *f)
839 {
840         struct vim2m_q_data *q_data;
841         struct vb2_queue *vq;
842
843         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
844         if (!vq)
845                 return -EINVAL;
846
847         q_data = get_q_data(ctx, f->type);
848         if (!q_data)
849                 return -EINVAL;
850
851         if (vb2_is_busy(vq)) {
852                 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
853                 return -EBUSY;
854         }
855
856         q_data->fmt             = find_format(f->fmt.pix.pixelformat);
857         q_data->width           = f->fmt.pix.width;
858         q_data->height          = f->fmt.pix.height;
859         q_data->sizeimage       = q_data->width * q_data->height
860                                 * q_data->fmt->depth >> 3;
861
862         dprintk(ctx->dev, 1,
863                 "Format for type %s: %dx%d (%d bpp), fmt: %c%c%c%c\n",
864                 type_name(f->type), q_data->width, q_data->height,
865                 q_data->fmt->depth,
866                 (q_data->fmt->fourcc & 0xff),
867                 (q_data->fmt->fourcc >>  8) & 0xff,
868                 (q_data->fmt->fourcc >> 16) & 0xff,
869                 (q_data->fmt->fourcc >> 24) & 0xff);
870
871         return 0;
872 }
873
874 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
875                                 struct v4l2_format *f)
876 {
877         int ret;
878
879         ret = vidioc_try_fmt_vid_cap(file, priv, f);
880         if (ret)
881                 return ret;
882
883         return vidioc_s_fmt(file2ctx(file), f);
884 }
885
886 static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
887                                 struct v4l2_format *f)
888 {
889         struct vim2m_ctx *ctx = file2ctx(file);
890         int ret;
891
892         ret = vidioc_try_fmt_vid_out(file, priv, f);
893         if (ret)
894                 return ret;
895
896         ret = vidioc_s_fmt(file2ctx(file), f);
897         if (!ret) {
898                 ctx->colorspace = f->fmt.pix.colorspace;
899                 ctx->xfer_func = f->fmt.pix.xfer_func;
900                 ctx->ycbcr_enc = f->fmt.pix.ycbcr_enc;
901                 ctx->quant = f->fmt.pix.quantization;
902         }
903         return ret;
904 }
905
906 static int vim2m_s_ctrl(struct v4l2_ctrl *ctrl)
907 {
908         struct vim2m_ctx *ctx =
909                 container_of(ctrl->handler, struct vim2m_ctx, hdl);
910
911         switch (ctrl->id) {
912         case V4L2_CID_HFLIP:
913                 if (ctrl->val)
914                         ctx->mode |= MEM2MEM_HFLIP;
915                 else
916                         ctx->mode &= ~MEM2MEM_HFLIP;
917                 break;
918
919         case V4L2_CID_VFLIP:
920                 if (ctrl->val)
921                         ctx->mode |= MEM2MEM_VFLIP;
922                 else
923                         ctx->mode &= ~MEM2MEM_VFLIP;
924                 break;
925
926         case V4L2_CID_TRANS_TIME_MSEC:
927                 ctx->transtime = ctrl->val;
928                 if (ctx->transtime < 1)
929                         ctx->transtime = 1;
930                 break;
931
932         case V4L2_CID_TRANS_NUM_BUFS:
933                 ctx->translen = ctrl->val;
934                 break;
935
936         default:
937                 v4l2_err(&ctx->dev->v4l2_dev, "Invalid control\n");
938                 return -EINVAL;
939         }
940
941         return 0;
942 }
943
944 static const struct v4l2_ctrl_ops vim2m_ctrl_ops = {
945         .s_ctrl = vim2m_s_ctrl,
946 };
947
948 static const struct v4l2_ioctl_ops vim2m_ioctl_ops = {
949         .vidioc_querycap        = vidioc_querycap,
950
951         .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
952         .vidioc_enum_framesizes = vidioc_enum_framesizes,
953         .vidioc_g_fmt_vid_cap   = vidioc_g_fmt_vid_cap,
954         .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
955         .vidioc_s_fmt_vid_cap   = vidioc_s_fmt_vid_cap,
956
957         .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
958         .vidioc_g_fmt_vid_out   = vidioc_g_fmt_vid_out,
959         .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
960         .vidioc_s_fmt_vid_out   = vidioc_s_fmt_vid_out,
961
962         .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
963         .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
964         .vidioc_qbuf            = v4l2_m2m_ioctl_qbuf,
965         .vidioc_dqbuf           = v4l2_m2m_ioctl_dqbuf,
966         .vidioc_prepare_buf     = v4l2_m2m_ioctl_prepare_buf,
967         .vidioc_create_bufs     = v4l2_m2m_ioctl_create_bufs,
968         .vidioc_expbuf          = v4l2_m2m_ioctl_expbuf,
969
970         .vidioc_streamon        = v4l2_m2m_ioctl_streamon,
971         .vidioc_streamoff       = v4l2_m2m_ioctl_streamoff,
972
973         .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
974         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
975 };
976
977 /*
978  * Queue operations
979  */
980
981 static int vim2m_queue_setup(struct vb2_queue *vq,
982                              unsigned int *nbuffers,
983                              unsigned int *nplanes,
984                              unsigned int sizes[],
985                              struct device *alloc_devs[])
986 {
987         struct vim2m_ctx *ctx = vb2_get_drv_priv(vq);
988         struct vim2m_q_data *q_data;
989         unsigned int size, count = *nbuffers;
990
991         q_data = get_q_data(ctx, vq->type);
992         if (!q_data)
993                 return -EINVAL;
994
995         size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
996
997         while (size * count > MEM2MEM_VID_MEM_LIMIT)
998                 (count)--;
999         *nbuffers = count;
1000
1001         if (*nplanes)
1002                 return sizes[0] < size ? -EINVAL : 0;
1003
1004         *nplanes = 1;
1005         sizes[0] = size;
1006
1007         dprintk(ctx->dev, 1, "%s: get %d buffer(s) of size %d each.\n",
1008                 type_name(vq->type), count, size);
1009
1010         return 0;
1011 }
1012
1013 static int vim2m_buf_out_validate(struct vb2_buffer *vb)
1014 {
1015         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1016         struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1017
1018         if (vbuf->field == V4L2_FIELD_ANY)
1019                 vbuf->field = V4L2_FIELD_NONE;
1020         if (vbuf->field != V4L2_FIELD_NONE) {
1021                 dprintk(ctx->dev, 1, "%s field isn't supported\n", __func__);
1022                 return -EINVAL;
1023         }
1024
1025         return 0;
1026 }
1027
1028 static int vim2m_buf_prepare(struct vb2_buffer *vb)
1029 {
1030         struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1031         struct vim2m_q_data *q_data;
1032
1033         dprintk(ctx->dev, 2, "type: %s\n", type_name(vb->vb2_queue->type));
1034
1035         q_data = get_q_data(ctx, vb->vb2_queue->type);
1036         if (!q_data)
1037                 return -EINVAL;
1038         if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
1039                 dprintk(ctx->dev, 1,
1040                         "%s data will not fit into plane (%lu < %lu)\n",
1041                         __func__, vb2_plane_size(vb, 0),
1042                         (long)q_data->sizeimage);
1043                 return -EINVAL;
1044         }
1045
1046         vb2_set_plane_payload(vb, 0, q_data->sizeimage);
1047
1048         return 0;
1049 }
1050
1051 static void vim2m_buf_queue(struct vb2_buffer *vb)
1052 {
1053         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1054         struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1055
1056         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1057 }
1058
1059 static int vim2m_start_streaming(struct vb2_queue *q, unsigned int count)
1060 {
1061         struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
1062         struct vim2m_q_data *q_data = get_q_data(ctx, q->type);
1063
1064         if (!q_data)
1065                 return -EINVAL;
1066
1067         if (V4L2_TYPE_IS_OUTPUT(q->type))
1068                 ctx->aborting = 0;
1069
1070         q_data->sequence = 0;
1071         return 0;
1072 }
1073
1074 static void vim2m_stop_streaming(struct vb2_queue *q)
1075 {
1076         struct vim2m_ctx *ctx = vb2_get_drv_priv(q);
1077         struct vb2_v4l2_buffer *vbuf;
1078
1079         cancel_delayed_work_sync(&ctx->work_run);
1080
1081         for (;;) {
1082                 if (V4L2_TYPE_IS_OUTPUT(q->type))
1083                         vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1084                 else
1085                         vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1086                 if (!vbuf)
1087                         return;
1088                 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
1089                                            &ctx->hdl);
1090                 v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
1091         }
1092 }
1093
1094 static void vim2m_buf_request_complete(struct vb2_buffer *vb)
1095 {
1096         struct vim2m_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1097
1098         v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
1099 }
1100
1101 static const struct vb2_ops vim2m_qops = {
1102         .queue_setup     = vim2m_queue_setup,
1103         .buf_out_validate        = vim2m_buf_out_validate,
1104         .buf_prepare     = vim2m_buf_prepare,
1105         .buf_queue       = vim2m_buf_queue,
1106         .start_streaming = vim2m_start_streaming,
1107         .stop_streaming  = vim2m_stop_streaming,
1108         .wait_prepare    = vb2_ops_wait_prepare,
1109         .wait_finish     = vb2_ops_wait_finish,
1110         .buf_request_complete = vim2m_buf_request_complete,
1111 };
1112
1113 static int queue_init(void *priv, struct vb2_queue *src_vq,
1114                       struct vb2_queue *dst_vq)
1115 {
1116         struct vim2m_ctx *ctx = priv;
1117         int ret;
1118
1119         src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1120         src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1121         src_vq->drv_priv = ctx;
1122         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1123         src_vq->ops = &vim2m_qops;
1124         src_vq->mem_ops = &vb2_vmalloc_memops;
1125         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1126         src_vq->lock = &ctx->vb_mutex;
1127         src_vq->supports_requests = true;
1128
1129         ret = vb2_queue_init(src_vq);
1130         if (ret)
1131                 return ret;
1132
1133         dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1134         dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1135         dst_vq->drv_priv = ctx;
1136         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1137         dst_vq->ops = &vim2m_qops;
1138         dst_vq->mem_ops = &vb2_vmalloc_memops;
1139         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1140         dst_vq->lock = &ctx->vb_mutex;
1141
1142         return vb2_queue_init(dst_vq);
1143 }
1144
1145 static struct v4l2_ctrl_config vim2m_ctrl_trans_time_msec = {
1146         .ops = &vim2m_ctrl_ops,
1147         .id = V4L2_CID_TRANS_TIME_MSEC,
1148         .name = "Transaction Time (msec)",
1149         .type = V4L2_CTRL_TYPE_INTEGER,
1150         .min = 1,
1151         .max = 10001,
1152         .step = 1,
1153 };
1154
1155 static const struct v4l2_ctrl_config vim2m_ctrl_trans_num_bufs = {
1156         .ops = &vim2m_ctrl_ops,
1157         .id = V4L2_CID_TRANS_NUM_BUFS,
1158         .name = "Buffers Per Transaction",
1159         .type = V4L2_CTRL_TYPE_INTEGER,
1160         .def = 1,
1161         .min = 1,
1162         .max = MEM2MEM_DEF_NUM_BUFS,
1163         .step = 1,
1164 };
1165
1166 /*
1167  * File operations
1168  */
1169 static int vim2m_open(struct file *file)
1170 {
1171         struct vim2m_dev *dev = video_drvdata(file);
1172         struct vim2m_ctx *ctx = NULL;
1173         struct v4l2_ctrl_handler *hdl;
1174         int rc = 0;
1175
1176         if (mutex_lock_interruptible(&dev->dev_mutex))
1177                 return -ERESTARTSYS;
1178         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1179         if (!ctx) {
1180                 rc = -ENOMEM;
1181                 goto open_unlock;
1182         }
1183
1184         v4l2_fh_init(&ctx->fh, video_devdata(file));
1185         file->private_data = &ctx->fh;
1186         ctx->dev = dev;
1187         hdl = &ctx->hdl;
1188         v4l2_ctrl_handler_init(hdl, 4);
1189         v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1190         v4l2_ctrl_new_std(hdl, &vim2m_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1191
1192         vim2m_ctrl_trans_time_msec.def = default_transtime;
1193         v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_time_msec, NULL);
1194         v4l2_ctrl_new_custom(hdl, &vim2m_ctrl_trans_num_bufs, NULL);
1195         if (hdl->error) {
1196                 rc = hdl->error;
1197                 v4l2_ctrl_handler_free(hdl);
1198                 kfree(ctx);
1199                 goto open_unlock;
1200         }
1201         ctx->fh.ctrl_handler = hdl;
1202         v4l2_ctrl_handler_setup(hdl);
1203
1204         ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
1205         ctx->q_data[V4L2_M2M_SRC].width = 640;
1206         ctx->q_data[V4L2_M2M_SRC].height = 480;
1207         ctx->q_data[V4L2_M2M_SRC].sizeimage =
1208                 ctx->q_data[V4L2_M2M_SRC].width *
1209                 ctx->q_data[V4L2_M2M_SRC].height *
1210                 (ctx->q_data[V4L2_M2M_SRC].fmt->depth >> 3);
1211         ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
1212         ctx->colorspace = V4L2_COLORSPACE_REC709;
1213
1214         ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
1215
1216         mutex_init(&ctx->vb_mutex);
1217         INIT_DELAYED_WORK(&ctx->work_run, device_work);
1218
1219         if (IS_ERR(ctx->fh.m2m_ctx)) {
1220                 rc = PTR_ERR(ctx->fh.m2m_ctx);
1221
1222                 v4l2_ctrl_handler_free(hdl);
1223                 v4l2_fh_exit(&ctx->fh);
1224                 kfree(ctx);
1225                 goto open_unlock;
1226         }
1227
1228         v4l2_fh_add(&ctx->fh);
1229         atomic_inc(&dev->num_inst);
1230
1231         dprintk(dev, 1, "Created instance: %p, m2m_ctx: %p\n",
1232                 ctx, ctx->fh.m2m_ctx);
1233
1234 open_unlock:
1235         mutex_unlock(&dev->dev_mutex);
1236         return rc;
1237 }
1238
1239 static int vim2m_release(struct file *file)
1240 {
1241         struct vim2m_dev *dev = video_drvdata(file);
1242         struct vim2m_ctx *ctx = file2ctx(file);
1243
1244         dprintk(dev, 1, "Releasing instance %p\n", ctx);
1245
1246         v4l2_fh_del(&ctx->fh);
1247         v4l2_fh_exit(&ctx->fh);
1248         v4l2_ctrl_handler_free(&ctx->hdl);
1249         mutex_lock(&dev->dev_mutex);
1250         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1251         mutex_unlock(&dev->dev_mutex);
1252         kfree(ctx);
1253
1254         atomic_dec(&dev->num_inst);
1255
1256         return 0;
1257 }
1258
1259 static void vim2m_device_release(struct video_device *vdev)
1260 {
1261         struct vim2m_dev *dev = container_of(vdev, struct vim2m_dev, vfd);
1262
1263         v4l2_device_unregister(&dev->v4l2_dev);
1264         v4l2_m2m_release(dev->m2m_dev);
1265 #ifdef CONFIG_MEDIA_CONTROLLER
1266         media_device_cleanup(&dev->mdev);
1267 #endif
1268         kfree(dev);
1269 }
1270
1271 static const struct v4l2_file_operations vim2m_fops = {
1272         .owner          = THIS_MODULE,
1273         .open           = vim2m_open,
1274         .release        = vim2m_release,
1275         .poll           = v4l2_m2m_fop_poll,
1276         .unlocked_ioctl = video_ioctl2,
1277         .mmap           = v4l2_m2m_fop_mmap,
1278 };
1279
1280 static const struct video_device vim2m_videodev = {
1281         .name           = MEM2MEM_NAME,
1282         .vfl_dir        = VFL_DIR_M2M,
1283         .fops           = &vim2m_fops,
1284         .ioctl_ops      = &vim2m_ioctl_ops,
1285         .minor          = -1,
1286         .release        = vim2m_device_release,
1287         .device_caps    = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING,
1288 };
1289
1290 static const struct v4l2_m2m_ops m2m_ops = {
1291         .device_run     = device_run,
1292         .job_ready      = job_ready,
1293         .job_abort      = job_abort,
1294 };
1295
1296 static const struct media_device_ops m2m_media_ops = {
1297         .req_validate = vb2_request_validate,
1298         .req_queue = v4l2_m2m_request_queue,
1299 };
1300
1301 static int vim2m_probe(struct platform_device *pdev)
1302 {
1303         struct vim2m_dev *dev;
1304         struct video_device *vfd;
1305         int ret;
1306
1307         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1308         if (!dev)
1309                 return -ENOMEM;
1310
1311         ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
1312         if (ret)
1313                 goto error_free;
1314
1315         atomic_set(&dev->num_inst, 0);
1316         mutex_init(&dev->dev_mutex);
1317
1318         dev->vfd = vim2m_videodev;
1319         vfd = &dev->vfd;
1320         vfd->lock = &dev->dev_mutex;
1321         vfd->v4l2_dev = &dev->v4l2_dev;
1322
1323         video_set_drvdata(vfd, dev);
1324         v4l2_info(&dev->v4l2_dev,
1325                   "Device registered as /dev/video%d\n", vfd->num);
1326
1327         platform_set_drvdata(pdev, dev);
1328
1329         dev->m2m_dev = v4l2_m2m_init(&m2m_ops);
1330         if (IS_ERR(dev->m2m_dev)) {
1331                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
1332                 ret = PTR_ERR(dev->m2m_dev);
1333                 dev->m2m_dev = NULL;
1334                 goto error_dev;
1335         }
1336
1337 #ifdef CONFIG_MEDIA_CONTROLLER
1338         dev->mdev.dev = &pdev->dev;
1339         strscpy(dev->mdev.model, "vim2m", sizeof(dev->mdev.model));
1340         strscpy(dev->mdev.bus_info, "platform:vim2m",
1341                 sizeof(dev->mdev.bus_info));
1342         media_device_init(&dev->mdev);
1343         dev->mdev.ops = &m2m_media_ops;
1344         dev->v4l2_dev.mdev = &dev->mdev;
1345 #endif
1346
1347         ret = video_register_device(vfd, VFL_TYPE_VIDEO, 0);
1348         if (ret) {
1349                 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1350                 goto error_m2m;
1351         }
1352
1353 #ifdef CONFIG_MEDIA_CONTROLLER
1354         ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd,
1355                                                  MEDIA_ENT_F_PROC_VIDEO_SCALER);
1356         if (ret) {
1357                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n");
1358                 goto error_v4l2;
1359         }
1360
1361         ret = media_device_register(&dev->mdev);
1362         if (ret) {
1363                 v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
1364                 goto error_m2m_mc;
1365         }
1366 #endif
1367         return 0;
1368
1369 #ifdef CONFIG_MEDIA_CONTROLLER
1370 error_m2m_mc:
1371         v4l2_m2m_unregister_media_controller(dev->m2m_dev);
1372 #endif
1373 error_v4l2:
1374         video_unregister_device(&dev->vfd);
1375         /* vim2m_device_release called by video_unregister_device to release various objects */
1376         return ret;
1377 error_m2m:
1378         v4l2_m2m_release(dev->m2m_dev);
1379 error_dev:
1380         v4l2_device_unregister(&dev->v4l2_dev);
1381 error_free:
1382         kfree(dev);
1383
1384         return ret;
1385 }
1386
1387 static int vim2m_remove(struct platform_device *pdev)
1388 {
1389         struct vim2m_dev *dev = platform_get_drvdata(pdev);
1390
1391         v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME);
1392
1393 #ifdef CONFIG_MEDIA_CONTROLLER
1394         media_device_unregister(&dev->mdev);
1395         v4l2_m2m_unregister_media_controller(dev->m2m_dev);
1396 #endif
1397         video_unregister_device(&dev->vfd);
1398
1399         return 0;
1400 }
1401
1402 static struct platform_driver vim2m_pdrv = {
1403         .probe          = vim2m_probe,
1404         .remove         = vim2m_remove,
1405         .driver         = {
1406                 .name   = MEM2MEM_NAME,
1407         },
1408 };
1409
1410 static void __exit vim2m_exit(void)
1411 {
1412         platform_driver_unregister(&vim2m_pdrv);
1413         platform_device_unregister(&vim2m_pdev);
1414 }
1415
1416 static int __init vim2m_init(void)
1417 {
1418         int ret;
1419
1420         ret = platform_device_register(&vim2m_pdev);
1421         if (ret)
1422                 return ret;
1423
1424         ret = platform_driver_register(&vim2m_pdrv);
1425         if (ret)
1426                 platform_device_unregister(&vim2m_pdev);
1427
1428         return ret;
1429 }
1430
1431 module_init(vim2m_init);
1432 module_exit(vim2m_exit);