]> Git Repo - J-linux.git/blob - drivers/media/platform/imagination/e5010-jpeg-enc.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / media / platform / imagination / e5010-jpeg-enc.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Imagination E5010 JPEG Encoder driver.
4  *
5  * TODO: Add MMU and memory tiling support
6  *
7  * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
8  *
9  * Author: David Huang <[email protected]>
10  * Author: Devarsh Thakkar <[email protected]>
11  */
12
13 #include <linux/clk.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/err.h>
16 #include <linux/interrupt.h>
17 #include <linux/ioctl.h>
18 #include <linux/module.h>
19 #include <linux/of_device.h>
20 #include <linux/pm_runtime.h>
21 #include <media/jpeg.h>
22 #include <media/v4l2-common.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-ioctl.h>
27 #include <media/v4l2-jpeg.h>
28 #include <media/v4l2-rect.h>
29 #include <media/v4l2-mem2mem.h>
30 #include <media/videobuf2-dma-contig.h>
31 #include <media/videobuf2-v4l2.h>
32 #include "e5010-jpeg-enc.h"
33 #include "e5010-jpeg-enc-hw.h"
34
35 /* forward declarations */
36 static const struct of_device_id e5010_of_match[];
37
38 static const struct v4l2_file_operations e5010_fops;
39
40 static const struct v4l2_ioctl_ops e5010_ioctl_ops;
41
42 static const struct vb2_ops e5010_video_ops;
43
44 static const struct v4l2_m2m_ops e5010_m2m_ops;
45
46 static struct e5010_fmt e5010_formats[] = {
47         {
48                 .fourcc = V4L2_PIX_FMT_NV12,
49                 .num_planes = 1,
50                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
51                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
52                 .chroma_order = CHROMA_ORDER_CB_CR,
53                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
54                              MIN_DIMENSION, MAX_DIMENSION, 8 },
55         },
56         {
57                 .fourcc = V4L2_PIX_FMT_NV12M,
58                 .num_planes = 2,
59                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
60                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
61                 .chroma_order = CHROMA_ORDER_CB_CR,
62                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
63                              MIN_DIMENSION, MAX_DIMENSION, 8 },
64         },
65         {
66                 .fourcc = V4L2_PIX_FMT_NV21,
67                 .num_planes = 1,
68                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
69                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
70                 .chroma_order = CHROMA_ORDER_CR_CB,
71                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
72                              MIN_DIMENSION, MAX_DIMENSION, 8 },
73         },
74         {
75                 .fourcc = V4L2_PIX_FMT_NV21M,
76                 .num_planes = 2,
77                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
78                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
79                 .chroma_order = CHROMA_ORDER_CR_CB,
80                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
81                              MIN_DIMENSION, MAX_DIMENSION, 8 },
82         },
83         {
84                 .fourcc = V4L2_PIX_FMT_NV16,
85                 .num_planes = 1,
86                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
87                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
88                 .chroma_order = CHROMA_ORDER_CB_CR,
89                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
90                              MIN_DIMENSION, MAX_DIMENSION, 8 },
91         },
92         {
93                 .fourcc = V4L2_PIX_FMT_NV16M,
94                 .num_planes = 2,
95                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
96                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
97                 .chroma_order = CHROMA_ORDER_CB_CR,
98                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
99                              MIN_DIMENSION, MAX_DIMENSION, 8 },
100
101         },
102         {
103                 .fourcc = V4L2_PIX_FMT_NV61,
104                 .num_planes = 1,
105                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
106                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
107                 .chroma_order = CHROMA_ORDER_CR_CB,
108                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
109                              MIN_DIMENSION, MAX_DIMENSION, 8 },
110         },
111         {
112                 .fourcc = V4L2_PIX_FMT_NV61M,
113                 .num_planes = 2,
114                 .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
115                 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
116                 .chroma_order = CHROMA_ORDER_CR_CB,
117                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 64,
118                              MIN_DIMENSION, MAX_DIMENSION, 8 },
119         },
120         {
121                 .fourcc = V4L2_PIX_FMT_JPEG,
122                 .num_planes = 1,
123                 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
124                 .subsampling = 0,
125                 .chroma_order = 0,
126                 .frmsize = { MIN_DIMENSION, MAX_DIMENSION, 16,
127                              MIN_DIMENSION, MAX_DIMENSION, 8 },
128         },
129 };
130
131 static unsigned int debug;
132 module_param(debug, uint, 0644);
133 MODULE_PARM_DESC(debug, "debug level");
134
135 #define dprintk(dev, lvl, fmt, arg...) \
136         v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
137
138 static const struct v4l2_event e5010_eos_event = {
139         .type = V4L2_EVENT_EOS
140 };
141
142 static const char *type_name(enum v4l2_buf_type type)
143 {
144         switch (type) {
145         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
146                 return "Output";
147         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
148                 return "Capture";
149         default:
150                 return "Invalid";
151         }
152 }
153
154 static struct e5010_q_data *get_queue(struct e5010_context *ctx, enum v4l2_buf_type type)
155 {
156         return (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? &ctx->out_queue : &ctx->cap_queue;
157 }
158
159 static void calculate_qp_tables(struct e5010_context *ctx)
160 {
161         long long luminosity, contrast;
162         int quality, i;
163
164         quality = 50 - ctx->quality;
165
166         luminosity = LUMINOSITY * quality / 50;
167         contrast = CONTRAST * quality / 50;
168
169         if (quality > 0) {
170                 luminosity *= INCREASE;
171                 contrast *= INCREASE;
172         }
173
174         for (i = 0; i < V4L2_JPEG_PIXELS_IN_BLOCK; i++) {
175                 long long delta = v4l2_jpeg_ref_table_chroma_qt[i] * contrast + luminosity;
176                 int val = (int)(v4l2_jpeg_ref_table_chroma_qt[i] + delta);
177
178                 clamp(val, 1, 255);
179                 ctx->chroma_qp[i] = quality == -50 ? 1 : val;
180
181                 delta = v4l2_jpeg_ref_table_luma_qt[i] * contrast + luminosity;
182                 val = (int)(v4l2_jpeg_ref_table_luma_qt[i] + delta);
183                 clamp(val, 1, 255);
184                 ctx->luma_qp[i] = quality == -50 ? 1 : val;
185         }
186
187         ctx->update_qp = true;
188 }
189
190 static int update_qp_tables(struct e5010_context *ctx)
191 {
192         struct e5010_dev *e5010 = ctx->e5010;
193         int i, ret = 0;
194         u32 lvalue, cvalue;
195
196         lvalue = 0;
197         cvalue = 0;
198
199         for (i = 0; i < QP_TABLE_SIZE; i++) {
200                 lvalue |= ctx->luma_qp[i] << (8 * (i % 4));
201                 cvalue |= ctx->chroma_qp[i] << (8 * (i % 4));
202                 if (i % 4 == 3) {
203                         ret |= e5010_hw_set_qpvalue(e5010->core_base,
204                                                         JASPER_LUMA_QUANTIZATION_TABLE0_OFFSET
205                                                         + QP_TABLE_FIELD_OFFSET * ((i - 3) / 4),
206                                                         lvalue);
207                         ret |= e5010_hw_set_qpvalue(e5010->core_base,
208                                                         JASPER_CHROMA_QUANTIZATION_TABLE0_OFFSET
209                                                         + QP_TABLE_FIELD_OFFSET * ((i - 3) / 4),
210                                                         cvalue);
211                         lvalue = 0;
212                         cvalue = 0;
213                 }
214         }
215
216         return ret;
217 }
218
219 static int e5010_set_input_subsampling(void __iomem *core_base, int subsampling)
220 {
221         switch (subsampling) {
222         case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
223                 return e5010_hw_set_input_subsampling(core_base, SUBSAMPLING_420);
224         case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
225                 return e5010_hw_set_input_subsampling(core_base, SUBSAMPLING_422);
226         default:
227                 return -EINVAL;
228         };
229 }
230
231 static int e5010_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
232 {
233         strscpy(cap->driver, E5010_MODULE_NAME, sizeof(cap->driver));
234         strscpy(cap->card, E5010_MODULE_NAME, sizeof(cap->card));
235
236         return 0;
237 }
238
239 static struct e5010_fmt *find_format(struct v4l2_format *f)
240 {
241         int i;
242
243         for (i = 0; i < ARRAY_SIZE(e5010_formats); ++i) {
244                 if (e5010_formats[i].fourcc == f->fmt.pix_mp.pixelformat &&
245                     e5010_formats[i].type == f->type)
246                         return &e5010_formats[i];
247         }
248
249         return NULL;
250 }
251
252 static int e5010_enum_fmt(struct file *file, void *priv, struct v4l2_fmtdesc *f)
253 {
254         int i, index = 0;
255         struct e5010_fmt *fmt = NULL;
256         struct e5010_context *ctx = file->private_data;
257
258         if (!V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
259                 v4l2_err(&ctx->e5010->v4l2_dev, "ENUMFMT with Invalid type: %d\n", f->type);
260                 return -EINVAL;
261         }
262
263         for (i = 0; i < ARRAY_SIZE(e5010_formats); ++i) {
264                 if (e5010_formats[i].type == f->type) {
265                         if (index == f->index) {
266                                 fmt = &e5010_formats[i];
267                                 break;
268                         }
269                         index++;
270                 }
271         }
272
273         if (!fmt)
274                 return -EINVAL;
275
276         f->pixelformat = fmt->fourcc;
277         return 0;
278 }
279
280 static int e5010_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
281 {
282         struct e5010_context *ctx = file->private_data;
283         struct e5010_q_data *queue;
284         int i;
285         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
286         struct v4l2_plane_pix_format *plane_fmt = pix_mp->plane_fmt;
287
288         queue = get_queue(ctx, f->type);
289
290         pix_mp->flags = 0;
291         pix_mp->field = V4L2_FIELD_NONE;
292         pix_mp->pixelformat = queue->fmt->fourcc;
293         pix_mp->width = queue->width_adjusted;
294         pix_mp->height = queue->height_adjusted;
295         pix_mp->num_planes = queue->fmt->num_planes;
296
297         if (V4L2_TYPE_IS_OUTPUT(f->type)) {
298                 if (!pix_mp->colorspace)
299                         pix_mp->colorspace = V4L2_COLORSPACE_SRGB;
300
301                 for (i = 0; i < queue->fmt->num_planes; i++) {
302                         plane_fmt[i].sizeimage = queue->sizeimage[i];
303                         plane_fmt[i].bytesperline = queue->bytesperline[i];
304                 }
305
306         } else {
307                 pix_mp->colorspace = V4L2_COLORSPACE_JPEG;
308                 plane_fmt[0].bytesperline = 0;
309                 plane_fmt[0].sizeimage = queue->sizeimage[0];
310         }
311         pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
312         pix_mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
313         pix_mp->quantization = V4L2_QUANTIZATION_DEFAULT;
314
315         return 0;
316 }
317
318 static int e5010_jpeg_try_fmt(struct v4l2_format *f, struct e5010_context *ctx)
319 {
320         struct e5010_fmt *fmt;
321         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
322         struct v4l2_plane_pix_format *plane_fmt = pix_mp->plane_fmt;
323
324         fmt = find_format(f);
325         if (!fmt) {
326                 if (V4L2_TYPE_IS_OUTPUT(f->type))
327                         pix_mp->pixelformat = V4L2_PIX_FMT_NV12;
328                 else
329                         pix_mp->pixelformat = V4L2_PIX_FMT_JPEG;
330                 fmt = find_format(f);
331                 if (!fmt)
332                         return -EINVAL;
333         }
334
335         if (V4L2_TYPE_IS_OUTPUT(f->type)) {
336                 if (!pix_mp->colorspace)
337                         pix_mp->colorspace = V4L2_COLORSPACE_JPEG;
338                 if (!pix_mp->ycbcr_enc)
339                         pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
340                 if (!pix_mp->quantization)
341                         pix_mp->quantization = V4L2_QUANTIZATION_DEFAULT;
342                 if (!pix_mp->xfer_func)
343                         pix_mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
344
345                 v4l2_apply_frmsize_constraints(&pix_mp->width,
346                                                &pix_mp->height,
347                                                &fmt->frmsize);
348
349                 v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat,
350                                     pix_mp->width, pix_mp->height);
351
352         } else {
353                 pix_mp->colorspace = V4L2_COLORSPACE_JPEG;
354                 pix_mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
355                 pix_mp->quantization = V4L2_QUANTIZATION_DEFAULT;
356                 pix_mp->xfer_func = V4L2_XFER_FUNC_DEFAULT;
357                 v4l2_apply_frmsize_constraints(&pix_mp->width,
358                                                &pix_mp->height,
359                                                &fmt->frmsize);
360                 plane_fmt[0].sizeimage = pix_mp->width * pix_mp->height * JPEG_MAX_BYTES_PER_PIXEL;
361                 plane_fmt[0].sizeimage += HEADER_SIZE;
362                 plane_fmt[0].bytesperline = 0;
363                 pix_mp->pixelformat = fmt->fourcc;
364                 pix_mp->num_planes = fmt->num_planes;
365         }
366         pix_mp->flags = 0;
367         pix_mp->field = V4L2_FIELD_NONE;
368
369         dprintk(ctx->e5010, 2,
370                 "ctx: 0x%p: format type %s:, wxh: %dx%d (plane0 : %d bytes, plane1 : %d bytes),fmt: %c%c%c%c\n",
371                 ctx, type_name(f->type), pix_mp->width, pix_mp->height,
372                 plane_fmt[0].sizeimage, plane_fmt[1].sizeimage,
373                 (fmt->fourcc & 0xff),
374                 (fmt->fourcc >>  8) & 0xff,
375                 (fmt->fourcc >> 16) & 0xff,
376                 (fmt->fourcc >> 24) & 0xff);
377
378         return 0;
379 }
380
381 static int e5010_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
382 {
383         struct e5010_context *ctx = file->private_data;
384
385         return e5010_jpeg_try_fmt(f, ctx);
386 }
387
388 static int e5010_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
389 {
390         struct e5010_context *ctx = file->private_data;
391         struct vb2_queue *vq;
392         int ret = 0, i = 0;
393         struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
394         struct v4l2_plane_pix_format *plane_fmt = pix_mp->plane_fmt;
395         struct e5010_q_data *queue;
396         struct e5010_fmt *fmt;
397
398         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
399         if (!vq)
400                 return -EINVAL;
401
402         if (vb2_is_busy(vq)) {
403                 v4l2_err(&ctx->e5010->v4l2_dev, "queue busy\n");
404                 return -EBUSY;
405         }
406
407         ret = e5010_jpeg_try_fmt(f, ctx);
408         if (ret)
409                 return ret;
410
411         fmt = find_format(f);
412         queue = get_queue(ctx, f->type);
413
414         queue->fmt = fmt;
415         queue->width = pix_mp->width;
416         queue->height = pix_mp->height;
417
418         if (V4L2_TYPE_IS_OUTPUT(f->type)) {
419                 for (i = 0; i < fmt->num_planes; i++) {
420                         queue->bytesperline[i] = plane_fmt[i].bytesperline;
421                         queue->sizeimage[i] = plane_fmt[i].sizeimage;
422                 }
423                 queue->crop.left = 0;
424                 queue->crop.top = 0;
425                 queue->crop.width = queue->width;
426                 queue->crop.height = queue->height;
427         } else {
428                 queue->sizeimage[0] = plane_fmt[0].sizeimage;
429                 queue->sizeimage[1] = 0;
430                 queue->bytesperline[0] = 0;
431                 queue->bytesperline[1] = 0;
432         }
433
434         return 0;
435 }
436
437 static int e5010_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *fsize)
438 {
439         struct v4l2_format f;
440         struct e5010_fmt *fmt;
441
442         if (fsize->index != 0)
443                 return -EINVAL;
444
445         f.fmt.pix_mp.pixelformat = fsize->pixel_format;
446         if (f.fmt.pix_mp.pixelformat ==  V4L2_PIX_FMT_JPEG)
447                 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
448         else
449                 f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
450
451         fmt = find_format(&f);
452         if (!fmt)
453                 return -EINVAL;
454
455         fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
456         fsize->stepwise = fmt->frmsize;
457         fsize->reserved[0] = 0;
458         fsize->reserved[1] = 0;
459
460         return 0;
461 }
462
463 static int e5010_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
464 {
465         struct e5010_context *ctx = file->private_data;
466         struct e5010_q_data *queue;
467
468         if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
469                 return -EINVAL;
470
471         queue = get_queue(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
472
473         switch (s->target) {
474         case V4L2_SEL_TGT_CROP_DEFAULT:
475         case V4L2_SEL_TGT_CROP_BOUNDS:
476                 s->r.left = 0;
477                 s->r.top = 0;
478                 s->r.width = queue->width;
479                 s->r.height = queue->height;
480                 break;
481         case V4L2_SEL_TGT_CROP:
482                 memcpy(&s->r, &queue->crop, sizeof(s->r));
483                 break;
484         default:
485                 return -EINVAL;
486         }
487
488         return 0;
489 }
490
491 static int e5010_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
492 {
493         struct e5010_context *ctx = file->private_data;
494         struct e5010_q_data *queue;
495         struct vb2_queue *vq;
496         struct v4l2_rect base_rect;
497
498         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, s->type);
499         if (!vq)
500                 return -EINVAL;
501
502         if (vb2_is_streaming(vq))
503                 return -EBUSY;
504
505         if (s->target != V4L2_SEL_TGT_CROP ||
506             s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
507                 return -EINVAL;
508
509         queue = get_queue(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
510         base_rect.top = 0;
511         base_rect.left = 0;
512         base_rect.width = queue->width;
513         base_rect.height = queue->height;
514
515         switch (s->flags) {
516         case 0:
517                 s->r.width = round_down(s->r.width, queue->fmt->frmsize.step_width);
518                 s->r.height = round_down(s->r.height, queue->fmt->frmsize.step_height);
519                 s->r.left = round_down(s->r.left, queue->fmt->frmsize.step_width);
520                 s->r.top = round_down(s->r.top, 2);
521
522                 if (s->r.left + s->r.width > queue->width)
523                         s->r.width = round_down(s->r.width + s->r.left - queue->width,
524                                                 queue->fmt->frmsize.step_width);
525                 if (s->r.top + s->r.height > queue->height)
526                         s->r.top = round_down(s->r.top + s->r.height - queue->height, 2);
527                 break;
528         case V4L2_SEL_FLAG_GE:
529                 s->r.width = round_up(s->r.width, queue->fmt->frmsize.step_width);
530                 s->r.height = round_up(s->r.height, queue->fmt->frmsize.step_height);
531                 s->r.left = round_up(s->r.left, queue->fmt->frmsize.step_width);
532                 s->r.top = round_up(s->r.top, 2);
533                 break;
534         case V4L2_SEL_FLAG_LE:
535                 s->r.width = round_down(s->r.width, queue->fmt->frmsize.step_width);
536                 s->r.height = round_down(s->r.height, queue->fmt->frmsize.step_height);
537                 s->r.left = round_down(s->r.left, queue->fmt->frmsize.step_width);
538                 s->r.top = round_down(s->r.top, 2);
539                 break;
540         case V4L2_SEL_FLAG_LE | V4L2_SEL_FLAG_GE:
541                 if (!IS_ALIGNED(s->r.width, queue->fmt->frmsize.step_width) ||
542                     !IS_ALIGNED(s->r.height, queue->fmt->frmsize.step_height) ||
543                     !IS_ALIGNED(s->r.left, queue->fmt->frmsize.step_width) ||
544                     !IS_ALIGNED(s->r.top, 2))
545                         return -ERANGE;
546                 break;
547         default:
548                 return -EINVAL;
549         }
550
551         if (!v4l2_rect_enclosed(&s->r, &base_rect))
552                 return -ERANGE;
553
554         memcpy(&queue->crop, &s->r, sizeof(s->r));
555
556         if (!v4l2_rect_equal(&s->r, &base_rect))
557                 queue->crop_set = true;
558
559         dprintk(ctx->e5010, 2, "ctx: 0x%p: crop rectangle: w: %d, h : %d, l : %d, t : %d\n",
560                 ctx, queue->crop.width, queue->crop.height, queue->crop.left, queue->crop.top);
561
562         return 0;
563 }
564
565 static int e5010_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
566 {
567         switch (sub->type) {
568         case V4L2_EVENT_EOS:
569                 return v4l2_event_subscribe(fh, sub, 0, NULL);
570         case V4L2_EVENT_CTRL:
571                 return v4l2_ctrl_subscribe_event(fh, sub);
572         default:
573                 return -EINVAL;
574         }
575
576         return 0;
577 }
578
579 static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
580 {
581         struct e5010_context *ctx = priv;
582         struct e5010_dev *e5010 = ctx->e5010;
583         int ret = 0;
584
585         /* src_vq */
586         memset(src_vq, 0, sizeof(*src_vq));
587         src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
588         src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
589         src_vq->drv_priv = ctx;
590         src_vq->buf_struct_size = sizeof(struct e5010_buffer);
591         src_vq->ops = &e5010_video_ops;
592         src_vq->mem_ops = &vb2_dma_contig_memops;
593         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
594         src_vq->lock = &e5010->mutex;
595         src_vq->dev = e5010->v4l2_dev.dev;
596
597         ret = vb2_queue_init(src_vq);
598         if (ret)
599                 return ret;
600
601         /* dst_vq */
602         memset(dst_vq, 0, sizeof(*dst_vq));
603         dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
604         dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
605         dst_vq->drv_priv = ctx;
606         dst_vq->buf_struct_size = sizeof(struct e5010_buffer);
607         dst_vq->ops = &e5010_video_ops;
608         dst_vq->mem_ops = &vb2_dma_contig_memops;
609         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
610         dst_vq->lock = &e5010->mutex;
611         dst_vq->dev = e5010->v4l2_dev.dev;
612
613         ret = vb2_queue_init(dst_vq);
614         if (ret) {
615                 vb2_queue_release(src_vq);
616                 return ret;
617         }
618
619         return 0;
620 }
621
622 static int e5010_s_ctrl(struct v4l2_ctrl *ctrl)
623 {
624         struct e5010_context *ctx =
625                 container_of(ctrl->handler, struct e5010_context, ctrl_handler);
626
627         switch (ctrl->id) {
628         case V4L2_CID_JPEG_COMPRESSION_QUALITY:
629                 ctx->quality = ctrl->val;
630                 calculate_qp_tables(ctx);
631                 dprintk(ctx->e5010, 2, "ctx: 0x%p compression quality set to : %d\n", ctx,
632                         ctx->quality);
633                 break;
634         default:
635                 return -EINVAL;
636         }
637
638         return 0;
639 }
640
641 static const struct v4l2_ctrl_ops e5010_ctrl_ops = {
642         .s_ctrl = e5010_s_ctrl,
643 };
644
645 static void e5010_encode_ctrls(struct e5010_context *ctx)
646 {
647         v4l2_ctrl_new_std(&ctx->ctrl_handler, &e5010_ctrl_ops,
648                           V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 75);
649 }
650
651 static int e5010_ctrls_setup(struct e5010_context *ctx)
652 {
653         int err;
654
655         v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1);
656
657         e5010_encode_ctrls(ctx);
658
659         if (ctx->ctrl_handler.error) {
660                 err = ctx->ctrl_handler.error;
661                 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
662
663                 return err;
664         }
665
666         err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
667         if (err)
668                 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
669
670         return err;
671 }
672
673 static void e5010_jpeg_set_default_params(struct e5010_context *ctx)
674 {
675         struct e5010_q_data *queue;
676         struct v4l2_format f;
677         struct e5010_fmt *fmt;
678         struct v4l2_pix_format_mplane *pix_mp = &f.fmt.pix_mp;
679         struct v4l2_plane_pix_format *plane_fmt = pix_mp->plane_fmt;
680         int i = 0;
681
682         f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
683         f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12;
684         fmt = find_format(&f);
685         queue = &ctx->out_queue;
686         queue->fmt = fmt;
687         queue->width = DEFAULT_WIDTH;
688         queue->height = DEFAULT_HEIGHT;
689         pix_mp->width = queue->width;
690         pix_mp->height = queue->height;
691         queue->crop.left = 0;
692         queue->crop.top = 0;
693         queue->crop.width = queue->width;
694         queue->crop.height = queue->height;
695         v4l2_apply_frmsize_constraints(&pix_mp->width,
696                                        &pix_mp->height,
697                                        &fmt->frmsize);
698         v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat,
699                             pix_mp->width, pix_mp->height);
700         for (i = 0; i < fmt->num_planes; i++) {
701                 queue->bytesperline[i] = plane_fmt[i].bytesperline;
702                 queue->sizeimage[i] = plane_fmt[i].sizeimage;
703         }
704         queue->width_adjusted = pix_mp->width;
705         queue->height_adjusted = pix_mp->height;
706
707         f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
708         f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_JPEG;
709         fmt = find_format(&f);
710         queue = &ctx->cap_queue;
711         queue->fmt = fmt;
712         queue->width = DEFAULT_WIDTH;
713         queue->height = DEFAULT_HEIGHT;
714         pix_mp->width = queue->width;
715         pix_mp->height = queue->height;
716         v4l2_apply_frmsize_constraints(&pix_mp->width,
717                                        &pix_mp->height,
718                                        &fmt->frmsize);
719         queue->sizeimage[0] = pix_mp->width * pix_mp->height * JPEG_MAX_BYTES_PER_PIXEL;
720         queue->sizeimage[0] += HEADER_SIZE;
721         queue->sizeimage[1] = 0;
722         queue->bytesperline[0] = 0;
723         queue->bytesperline[1] = 0;
724         queue->width_adjusted = pix_mp->width;
725         queue->height_adjusted = pix_mp->height;
726 }
727
728 static int e5010_open(struct file *file)
729 {
730         struct e5010_dev *e5010 = video_drvdata(file);
731         struct video_device *vdev = video_devdata(file);
732         struct e5010_context *ctx;
733         int ret = 0;
734
735         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
736         if (!ctx)
737                 return -ENOMEM;
738
739         if (mutex_lock_interruptible(&e5010->mutex)) {
740                 ret = -ERESTARTSYS;
741                 goto free;
742         }
743
744         v4l2_fh_init(&ctx->fh, vdev);
745         file->private_data = ctx;
746         v4l2_fh_add(&ctx->fh);
747
748         ctx->e5010 = e5010;
749         ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(e5010->m2m_dev, ctx, queue_init);
750         if (IS_ERR(ctx->fh.m2m_ctx)) {
751                 v4l2_err(&e5010->v4l2_dev, "failed to init m2m ctx\n");
752                 ret = PTR_ERR(ctx->fh.m2m_ctx);
753                 goto exit;
754         }
755
756         ret = e5010_ctrls_setup(ctx);
757         if (ret) {
758                 v4l2_err(&e5010->v4l2_dev, "failed to setup e5010 jpeg controls\n");
759                 goto err_ctrls_setup;
760         }
761         ctx->fh.ctrl_handler = &ctx->ctrl_handler;
762
763         e5010_jpeg_set_default_params(ctx);
764
765         dprintk(e5010, 1, "Created instance: 0x%p, m2m_ctx: 0x%p\n", ctx, ctx->fh.m2m_ctx);
766
767         mutex_unlock(&e5010->mutex);
768         return 0;
769
770 err_ctrls_setup:
771         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
772 exit:
773         v4l2_fh_del(&ctx->fh);
774         v4l2_fh_exit(&ctx->fh);
775         mutex_unlock(&e5010->mutex);
776 free:
777         kfree(ctx);
778         return ret;
779 }
780
781 static int e5010_release(struct file *file)
782 {
783         struct e5010_dev *e5010 = video_drvdata(file);
784         struct e5010_context *ctx = file->private_data;
785
786         dprintk(e5010, 1, "Releasing instance: 0x%p, m2m_ctx: 0x%p\n", ctx, ctx->fh.m2m_ctx);
787         mutex_lock(&e5010->mutex);
788         v4l2_ctrl_handler_free(&ctx->ctrl_handler);
789         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
790         v4l2_fh_del(&ctx->fh);
791         v4l2_fh_exit(&ctx->fh);
792         kfree(ctx);
793         mutex_unlock(&e5010->mutex);
794
795         return 0;
796 }
797
798 static void header_write(struct e5010_context *ctx, u8 *addr, unsigned int *offset,
799                          unsigned int no_bytes, unsigned long bits)
800 {
801         u8 *w_addr = addr + *offset;
802         int i;
803
804         if ((*offset + no_bytes) > HEADER_SIZE) {
805                 v4l2_warn(&ctx->e5010->v4l2_dev, "%s: %s: %d: Problem writing header. %d > HEADER_SIZE %d\n",
806                           __FILE__, __func__, __LINE__, *offset + no_bytes, HEADER_SIZE);
807                 return;
808         }
809
810         for (i = no_bytes - 1; i >= 0; i--)
811                 *(w_addr++) = ((u8 *)&bits)[i];
812
813         *offset += no_bytes;
814 }
815
816 static void encode_marker_segment(struct e5010_context *ctx, void *addr, unsigned int *offset)
817 {
818         u8 *buffer = (u8 *)addr;
819         int i;
820
821         header_write(ctx, buffer, offset, 2, START_OF_IMAGE);
822         header_write(ctx, buffer, offset, 2, DQT_MARKER);
823         header_write(ctx, buffer, offset, 3, LQPQ << 4);
824         for (i = 0; i < V4L2_JPEG_PIXELS_IN_BLOCK; i++)
825                 header_write(ctx, buffer, offset, 1, ctx->luma_qp[v4l2_jpeg_zigzag_scan_index[i]]);
826
827         header_write(ctx, buffer, offset, 2, DQT_MARKER);
828         header_write(ctx, buffer, offset, 3, (LQPQ << 4) | 1);
829         for (i = 0; i < V4L2_JPEG_PIXELS_IN_BLOCK; i++)
830                 header_write(ctx, buffer, offset, 1,
831                              ctx->chroma_qp[v4l2_jpeg_zigzag_scan_index[i]]);
832
833         /* Huffman tables */
834         header_write(ctx, buffer, offset, 2, DHT_MARKER);
835         header_write(ctx, buffer, offset, 2, LH_DC);
836         header_write(ctx, buffer, offset, 1, V4L2_JPEG_LUM_HT | V4L2_JPEG_DC_HT);
837         for (i = 0 ; i < V4L2_JPEG_REF_HT_DC_LEN; i++)
838                 header_write(ctx, buffer, offset, 1, v4l2_jpeg_ref_table_luma_dc_ht[i]);
839
840         header_write(ctx, buffer, offset, 2, DHT_MARKER);
841         header_write(ctx, buffer, offset, 2, LH_AC);
842         header_write(ctx, buffer, offset, 1, V4L2_JPEG_LUM_HT | V4L2_JPEG_AC_HT);
843         for (i = 0 ; i < V4L2_JPEG_REF_HT_AC_LEN; i++)
844                 header_write(ctx, buffer, offset, 1, v4l2_jpeg_ref_table_luma_ac_ht[i]);
845
846         header_write(ctx, buffer, offset, 2, DHT_MARKER);
847         header_write(ctx, buffer, offset, 2, LH_DC);
848         header_write(ctx, buffer, offset, 1, V4L2_JPEG_CHR_HT | V4L2_JPEG_DC_HT);
849         for (i = 0 ; i < V4L2_JPEG_REF_HT_DC_LEN; i++)
850                 header_write(ctx, buffer, offset, 1, v4l2_jpeg_ref_table_chroma_dc_ht[i]);
851
852         header_write(ctx, buffer, offset, 2, DHT_MARKER);
853         header_write(ctx, buffer, offset, 2, LH_AC);
854         header_write(ctx, buffer, offset, 1, V4L2_JPEG_CHR_HT | V4L2_JPEG_AC_HT);
855         for (i = 0 ; i < V4L2_JPEG_REF_HT_AC_LEN; i++)
856                 header_write(ctx, buffer, offset, 1, v4l2_jpeg_ref_table_chroma_ac_ht[i]);
857 }
858
859 static void encode_frame_header(struct e5010_context *ctx, void *addr, unsigned int *offset)
860 {
861         u8 *buffer = (u8 *)addr;
862
863         header_write(ctx, buffer, offset, 2, SOF_BASELINE_DCT);
864         header_write(ctx, buffer, offset, 2, 8 + (3 * UC_NUM_COMP));
865         header_write(ctx, buffer, offset, 1, PRECISION);
866         header_write(ctx, buffer, offset, 2, ctx->out_queue.crop.height);
867         header_write(ctx, buffer, offset, 2, ctx->out_queue.crop.width);
868         header_write(ctx, buffer, offset, 1, UC_NUM_COMP);
869
870         /* Luma details */
871         header_write(ctx, buffer, offset, 1, 1);
872         if (ctx->out_queue.fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422)
873                 header_write(ctx, buffer, offset, 1,
874                              HORZ_SAMPLING_FACTOR | (VERT_SAMPLING_FACTOR_422));
875         else
876                 header_write(ctx, buffer, offset, 1,
877                              HORZ_SAMPLING_FACTOR | (VERT_SAMPLING_FACTOR_420));
878         header_write(ctx, buffer, offset, 1, 0);
879         /* Chroma details */
880         header_write(ctx, buffer, offset, 1, 2);
881         header_write(ctx, buffer, offset, 1, (HORZ_SAMPLING_FACTOR >> 1) | 1);
882         header_write(ctx, buffer, offset, 1, 1);
883         header_write(ctx, buffer, offset, 1, 3);
884         header_write(ctx, buffer, offset, 1, (HORZ_SAMPLING_FACTOR >> 1) | 1);
885         header_write(ctx, buffer, offset, 1, 1);
886 }
887
888 static void jpg_encode_sos_header(struct e5010_context *ctx, void *addr, unsigned int *offset)
889 {
890         u8 *buffer = (u8 *)addr;
891         int i;
892
893         header_write(ctx, buffer, offset, 2, START_OF_SCAN);
894         header_write(ctx, buffer, offset, 2, 6 + (COMPONENTS_IN_SCAN << 1));
895         header_write(ctx, buffer, offset, 1, COMPONENTS_IN_SCAN);
896
897         for (i = 0; i < COMPONENTS_IN_SCAN; i++) {
898                 header_write(ctx, buffer, offset, 1, i + 1);
899                 if (i == 0)
900                         header_write(ctx, buffer, offset, 1, 0);
901                 else
902                         header_write(ctx, buffer, offset, 1, 17);
903         }
904
905         header_write(ctx, buffer, offset, 1, 0);
906         header_write(ctx, buffer, offset, 1, 63);
907         header_write(ctx, buffer, offset, 1, 0);
908 }
909
910 static void write_header(struct e5010_context *ctx, void *addr)
911 {
912         unsigned int offset = 0;
913
914         encode_marker_segment(ctx, addr, &offset);
915         encode_frame_header(ctx, addr, &offset);
916         jpg_encode_sos_header(ctx, addr, &offset);
917 }
918
919 static irqreturn_t e5010_irq(int irq, void *data)
920 {
921         struct e5010_dev *e5010 = data;
922         struct e5010_context *ctx;
923         int output_size;
924         struct vb2_v4l2_buffer *src_buf, *dst_buf;
925         bool pic_done, out_addr_err;
926
927         spin_lock(&e5010->hw_lock);
928         pic_done = e5010_hw_pic_done_irq(e5010->core_base);
929         out_addr_err = e5010_hw_output_address_irq(e5010->core_base);
930
931         if (!pic_done && !out_addr_err) {
932                 spin_unlock(&e5010->hw_lock);
933                 return IRQ_NONE;
934         }
935
936         ctx = v4l2_m2m_get_curr_priv(e5010->m2m_dev);
937         if (WARN_ON(!ctx))
938                 goto job_unlock;
939
940         dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
941         src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
942         if (!dst_buf || !src_buf) {
943                 v4l2_err(&e5010->v4l2_dev, "ctx: 0x%p No source or destination buffer\n", ctx);
944                 goto job_unlock;
945         }
946
947         if (out_addr_err) {
948                 e5010_hw_clear_output_error(e5010->core_base, 1);
949                 v4l2_warn(&e5010->v4l2_dev,
950                           "ctx: 0x%p Output bitstream size exceeded max size\n", ctx);
951                 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR);
952                 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, dst_buf->planes[0].length);
953                 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
954                 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
955                         dst_buf->flags |= V4L2_BUF_FLAG_LAST;
956                         v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
957                         v4l2_event_queue_fh(&ctx->fh, &e5010_eos_event);
958                         dprintk(e5010, 2, "ctx: 0x%p Sending EOS\n", ctx);
959                 }
960         }
961
962         if (pic_done) {
963                 e5010_hw_clear_picture_done(e5010->core_base, 1);
964                 dprintk(e5010, 3, "ctx: 0x%p Got output bitstream of size %d bytes\n",
965                         ctx, readl(e5010->core_base + JASPER_OUTPUT_SIZE_OFFSET));
966
967                 if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) {
968                         dst_buf->flags |= V4L2_BUF_FLAG_LAST;
969                         v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx);
970                         v4l2_event_queue_fh(&ctx->fh, &e5010_eos_event);
971                         dprintk(e5010, 2, "ctx: 0x%p Sending EOS\n", ctx);
972                 }
973                 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
974                 output_size = e5010_hw_get_output_size(e5010->core_base);
975                 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, output_size + HEADER_SIZE);
976                 v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
977                 dprintk(e5010, 3,
978                         "ctx: 0x%p frame done for dst_buf->sequence: %d src_buf->sequence: %d\n",
979                         ctx, dst_buf->sequence, src_buf->sequence);
980         }
981
982         v4l2_m2m_job_finish(e5010->m2m_dev, ctx->fh.m2m_ctx);
983         dprintk(e5010, 3, "ctx: 0x%p Finish job\n", ctx);
984
985 job_unlock:
986         spin_unlock(&e5010->hw_lock);
987         return IRQ_HANDLED;
988 }
989
990 static int e5010_init_device(struct e5010_dev *e5010)
991 {
992         int ret = 0;
993
994         /*TODO: Set MMU in bypass mode until support for the same is added in driver*/
995         e5010_hw_bypass_mmu(e5010->mmu_base, 1);
996
997         if (e5010_hw_enable_auto_clock_gating(e5010->core_base, 1))
998                 v4l2_warn(&e5010->v4l2_dev, "failed to enable auto clock gating\n");
999
1000         if (e5010_hw_enable_manual_clock_gating(e5010->core_base, 0))
1001                 v4l2_warn(&e5010->v4l2_dev, "failed to disable manual clock gating\n");
1002
1003         if (e5010_hw_enable_crc_check(e5010->core_base, 0))
1004                 v4l2_warn(&e5010->v4l2_dev, "failed to disable CRC check\n");
1005
1006         if (e5010_hw_enable_output_address_error_irq(e5010->core_base, 1))
1007                 v4l2_err(&e5010->v4l2_dev, "failed to enable Output Address Error interrupts\n");
1008
1009         ret = e5010_hw_set_input_source_to_memory(e5010->core_base, 1);
1010         if (ret) {
1011                 v4l2_err(&e5010->v4l2_dev, "failed to set input source to memory\n");
1012                 return ret;
1013         }
1014
1015         ret = e5010_hw_enable_picture_done_irq(e5010->core_base, 1);
1016         if (ret)
1017                 v4l2_err(&e5010->v4l2_dev, "failed to enable Picture Done interrupts\n");
1018
1019         return ret;
1020 }
1021
1022 static int e5010_probe(struct platform_device *pdev)
1023 {
1024         struct e5010_dev *e5010;
1025         int irq, ret = 0;
1026         struct device *dev = &pdev->dev;
1027
1028         ret = dma_set_mask(dev, DMA_BIT_MASK(32));
1029         if (ret)
1030                 return dev_err_probe(dev, ret, "32-bit consistent DMA enable failed\n");
1031
1032         e5010 = devm_kzalloc(dev, sizeof(*e5010), GFP_KERNEL);
1033         if (!e5010)
1034                 return -ENOMEM;
1035
1036         platform_set_drvdata(pdev, e5010);
1037
1038         e5010->dev = dev;
1039
1040         mutex_init(&e5010->mutex);
1041         spin_lock_init(&e5010->hw_lock);
1042
1043         e5010->vdev = video_device_alloc();
1044         if (!e5010->vdev) {
1045                 dev_err(dev, "failed to allocate video device\n");
1046                 return -ENOMEM;
1047         }
1048
1049         snprintf(e5010->vdev->name, sizeof(e5010->vdev->name), "%s", E5010_MODULE_NAME);
1050         e5010->vdev->fops = &e5010_fops;
1051         e5010->vdev->ioctl_ops = &e5010_ioctl_ops;
1052         e5010->vdev->minor = -1;
1053         e5010->vdev->release = video_device_release;
1054         e5010->vdev->vfl_dir = VFL_DIR_M2M;
1055         e5010->vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
1056         e5010->vdev->v4l2_dev = &e5010->v4l2_dev;
1057         e5010->vdev->lock = &e5010->mutex;
1058
1059         ret = v4l2_device_register(dev, &e5010->v4l2_dev);
1060         if (ret)
1061                 return dev_err_probe(dev, ret, "failed to register v4l2 device\n");
1062
1063         e5010->m2m_dev = v4l2_m2m_init(&e5010_m2m_ops);
1064         if (IS_ERR(e5010->m2m_dev)) {
1065                 ret = PTR_ERR(e5010->m2m_dev);
1066                 e5010->m2m_dev = NULL;
1067                 dev_err_probe(dev, ret, "failed to init mem2mem device\n");
1068                 goto fail_after_v4l2_register;
1069         }
1070
1071         video_set_drvdata(e5010->vdev, e5010);
1072
1073         e5010->core_base = devm_platform_ioremap_resource_byname(pdev, "core");
1074         if (IS_ERR(e5010->core_base)) {
1075                 ret = PTR_ERR(e5010->core_base);
1076                 dev_err_probe(dev, ret, "Missing 'core' resources area\n");
1077                 goto fail_after_v4l2_register;
1078         }
1079
1080         e5010->mmu_base = devm_platform_ioremap_resource_byname(pdev, "mmu");
1081         if (IS_ERR(e5010->mmu_base)) {
1082                 ret = PTR_ERR(e5010->mmu_base);
1083                 dev_err_probe(dev, ret, "Missing 'mmu' resources area\n");
1084                 goto fail_after_v4l2_register;
1085         }
1086
1087         e5010->last_context_run = NULL;
1088
1089         irq = platform_get_irq(pdev, 0);
1090         ret = devm_request_irq(dev, irq, e5010_irq, 0,
1091                                E5010_MODULE_NAME, e5010);
1092         if (ret) {
1093                 dev_err_probe(dev, ret, "failed to register IRQ %d\n", irq);
1094                 goto fail_after_v4l2_register;
1095         }
1096
1097         e5010->clk = devm_clk_get(dev, NULL);
1098         if (IS_ERR(e5010->clk)) {
1099                 ret = PTR_ERR(e5010->clk);
1100                 dev_err_probe(dev, ret, "failed to get clock\n");
1101                 goto fail_after_v4l2_register;
1102         }
1103
1104         pm_runtime_enable(dev);
1105
1106         ret = video_register_device(e5010->vdev, VFL_TYPE_VIDEO, 0);
1107         if (ret) {
1108                 dev_err_probe(dev, ret, "failed to register video device\n");
1109                 goto fail_after_video_register_device;
1110         }
1111
1112         v4l2_info(&e5010->v4l2_dev, "Device registered as /dev/video%d\n",
1113                   e5010->vdev->num);
1114
1115         return 0;
1116
1117 fail_after_video_register_device:
1118         v4l2_m2m_release(e5010->m2m_dev);
1119 fail_after_v4l2_register:
1120         v4l2_device_unregister(&e5010->v4l2_dev);
1121         return ret;
1122 }
1123
1124 static void e5010_remove(struct platform_device *pdev)
1125 {
1126         struct e5010_dev *e5010 = platform_get_drvdata(pdev);
1127
1128         pm_runtime_disable(e5010->dev);
1129         video_unregister_device(e5010->vdev);
1130         v4l2_m2m_release(e5010->m2m_dev);
1131         v4l2_device_unregister(&e5010->v4l2_dev);
1132 }
1133
1134 static void e5010_vb2_buffers_return(struct vb2_queue *q, enum vb2_buffer_state state)
1135 {
1136         struct vb2_v4l2_buffer *vbuf;
1137         struct e5010_context *ctx = vb2_get_drv_priv(q);
1138
1139         if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1140                 while ((vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx))) {
1141                         dprintk(ctx->e5010, 2, "ctx: 0x%p, buf type %s | index %d\n",
1142                                 ctx, type_name(vbuf->vb2_buf.type), vbuf->vb2_buf.index);
1143                         v4l2_m2m_buf_done(vbuf, state);
1144                 }
1145         } else {
1146                 while ((vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx))) {
1147                         dprintk(ctx->e5010, 2, "ctx: 0x%p, buf type %s | index %d\n",
1148                                 ctx, type_name(vbuf->vb2_buf.type), vbuf->vb2_buf.index);
1149                         vb2_set_plane_payload(&vbuf->vb2_buf, 0, 0);
1150                         v4l2_m2m_buf_done(vbuf, state);
1151                 }
1152         }
1153 }
1154
1155 static int e5010_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes,
1156                              unsigned int sizes[], struct device *alloc_devs[])
1157 {
1158         struct e5010_context *ctx = vb2_get_drv_priv(vq);
1159         struct e5010_q_data *queue;
1160         int i;
1161
1162         queue = get_queue(ctx, vq->type);
1163
1164         if (*nplanes) {
1165                 if (*nplanes != queue->fmt->num_planes)
1166                         return -EINVAL;
1167                 for (i = 0; i < *nplanes; i++) {
1168                         if (sizes[i] < queue->sizeimage[i])
1169                                 return -EINVAL;
1170                 }
1171                 return 0;
1172         }
1173
1174         *nplanes = queue->fmt->num_planes;
1175         for (i = 0; i < *nplanes; i++)
1176                 sizes[i] = queue->sizeimage[i];
1177
1178         dprintk(ctx->e5010, 2,
1179                 "ctx: 0x%p, type %s, buffer(s): %d, planes %d, plane1: bytes %d plane2: %d bytes\n",
1180                 ctx, type_name(vq->type), *nbuffers, *nplanes, sizes[0], sizes[1]);
1181
1182         return 0;
1183 }
1184
1185 static void e5010_buf_finish(struct vb2_buffer *vb)
1186 {
1187         struct e5010_context *ctx = vb2_get_drv_priv(vb->vb2_queue);
1188         void *d_addr;
1189
1190         if (vb->state != VB2_BUF_STATE_DONE || V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type))
1191                 return;
1192
1193         d_addr = vb2_plane_vaddr(vb, 0);
1194         write_header(ctx, d_addr);
1195 }
1196
1197 static int e5010_buf_out_validate(struct vb2_buffer *vb)
1198 {
1199         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1200         struct e5010_context *ctx = vb2_get_drv_priv(vb->vb2_queue);
1201
1202         if (vbuf->field != V4L2_FIELD_NONE)
1203                 dprintk(ctx->e5010, 1, "ctx: 0x%p, field isn't supported\n", ctx);
1204
1205         vbuf->field = V4L2_FIELD_NONE;
1206
1207         return 0;
1208 }
1209
1210 static int e5010_buf_prepare(struct vb2_buffer *vb)
1211 {
1212         struct e5010_context *ctx = vb2_get_drv_priv(vb->vb2_queue);
1213         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1214         struct e5010_q_data *queue;
1215         int i;
1216
1217         vbuf->field = V4L2_FIELD_NONE;
1218
1219         queue = get_queue(ctx, vb->vb2_queue->type);
1220
1221         for (i = 0; i < queue->fmt->num_planes; i++) {
1222                 if (vb2_plane_size(vb, i) < (unsigned long)queue->sizeimage[i]) {
1223                         v4l2_err(&ctx->e5010->v4l2_dev, "plane %d too small (%lu < %lu)", i,
1224                                  vb2_plane_size(vb, i), (unsigned long)queue->sizeimage[i]);
1225
1226                         return -EINVAL;
1227                 }
1228         }
1229
1230         if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) {
1231                 vb2_set_plane_payload(vb, 0, 0);
1232                 vb2_set_plane_payload(vb, 1, 0);
1233         }
1234
1235         return 0;
1236 }
1237
1238 static void e5010_buf_queue(struct vb2_buffer *vb)
1239 {
1240         struct e5010_context *ctx = vb2_get_drv_priv(vb->vb2_queue);
1241         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1242
1243         if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) &&
1244             vb2_is_streaming(vb->vb2_queue) &&
1245             v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) {
1246                 struct e5010_q_data *queue = get_queue(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1247
1248                 vbuf->sequence = queue->sequence++;
1249                 v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf);
1250                 v4l2_event_queue_fh(&ctx->fh, &e5010_eos_event);
1251                 return;
1252         }
1253
1254         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1255 }
1256
1257 static int e5010_encoder_cmd(struct file *file, void *priv,
1258                              struct v4l2_encoder_cmd *cmd)
1259 {
1260         struct e5010_context *ctx = file->private_data;
1261         int ret;
1262         struct vb2_queue *cap_vq;
1263
1264         cap_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
1265
1266         ret = v4l2_m2m_ioctl_try_encoder_cmd(file, &ctx->fh, cmd);
1267         if (ret < 0)
1268                 return ret;
1269
1270         if (!vb2_is_streaming(v4l2_m2m_get_src_vq(ctx->fh.m2m_ctx)) ||
1271             !vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx)))
1272                 return 0;
1273
1274         ret = v4l2_m2m_ioctl_encoder_cmd(file, &ctx->fh, cmd);
1275         if (ret < 0)
1276                 return ret;
1277
1278         if (cmd->cmd == V4L2_ENC_CMD_STOP &&
1279             v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1280                 v4l2_event_queue_fh(&ctx->fh, &e5010_eos_event);
1281
1282         if (cmd->cmd == V4L2_ENC_CMD_START &&
1283             v4l2_m2m_has_stopped(ctx->fh.m2m_ctx))
1284                 vb2_clear_last_buffer_dequeued(cap_vq);
1285
1286         return 0;
1287 }
1288
1289 static int e5010_start_streaming(struct vb2_queue *q, unsigned int count)
1290 {
1291         struct e5010_context *ctx = vb2_get_drv_priv(q);
1292         int ret;
1293
1294         struct e5010_q_data *queue = get_queue(ctx, q->type);
1295
1296         v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q);
1297         queue->sequence = 0;
1298
1299         ret = pm_runtime_resume_and_get(ctx->e5010->dev);
1300         if (ret < 0) {
1301                 v4l2_err(&ctx->e5010->v4l2_dev, "failed to power up jpeg\n");
1302                 goto fail;
1303         }
1304
1305         ret = e5010_init_device(ctx->e5010);
1306         if (ret) {
1307                 v4l2_err(&ctx->e5010->v4l2_dev, "failed to Enable e5010 device\n");
1308                 goto fail;
1309         }
1310
1311         return 0;
1312
1313 fail:
1314         e5010_vb2_buffers_return(q, VB2_BUF_STATE_QUEUED);
1315
1316         return ret;
1317 }
1318
1319 static void e5010_stop_streaming(struct vb2_queue *q)
1320 {
1321         struct e5010_context *ctx = vb2_get_drv_priv(q);
1322
1323         e5010_vb2_buffers_return(q, VB2_BUF_STATE_ERROR);
1324
1325         if (V4L2_TYPE_IS_OUTPUT(q->type))
1326                 v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q);
1327
1328         if (V4L2_TYPE_IS_OUTPUT(q->type) &&
1329             v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) {
1330                 v4l2_event_queue_fh(&ctx->fh, &e5010_eos_event);
1331         }
1332
1333         pm_runtime_put_sync(ctx->e5010->dev);
1334 }
1335
1336 static void e5010_device_run(void *priv)
1337 {
1338         struct e5010_context *ctx = priv;
1339         struct e5010_dev *e5010 = ctx->e5010;
1340         struct vb2_v4l2_buffer *s_vb, *d_vb;
1341         u32 reg = 0;
1342         int ret = 0, luma_crop_offset = 0, chroma_crop_offset = 0;
1343         unsigned long flags;
1344         int num_planes = ctx->out_queue.fmt->num_planes;
1345
1346         spin_lock_irqsave(&e5010->hw_lock, flags);
1347         s_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1348         WARN_ON(!s_vb);
1349         d_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1350         WARN_ON(!d_vb);
1351         if (!s_vb || !d_vb)
1352                 goto no_ready_buf_err;
1353
1354         s_vb->sequence = ctx->out_queue.sequence++;
1355         d_vb->sequence = ctx->cap_queue.sequence++;
1356
1357         v4l2_m2m_buf_copy_metadata(s_vb, d_vb, false);
1358
1359         if (ctx != e5010->last_context_run || ctx->update_qp) {
1360                 dprintk(e5010, 1, "ctx updated: 0x%p -> 0x%p, updating qp tables\n",
1361                         e5010->last_context_run, ctx);
1362                 ret = update_qp_tables(ctx);
1363         }
1364
1365         if (ret) {
1366                 ctx->update_qp = true;
1367                 v4l2_err(&e5010->v4l2_dev, "failed to update QP tables\n");
1368                 goto device_busy_err;
1369         } else {
1370                 e5010->last_context_run = ctx;
1371                 ctx->update_qp = false;
1372         }
1373
1374         /* Set I/O Buffer addresses */
1375         reg = (u32)vb2_dma_contig_plane_dma_addr(&s_vb->vb2_buf, 0);
1376
1377         if (ctx->out_queue.crop_set) {
1378                 luma_crop_offset = ctx->out_queue.bytesperline[0] * ctx->out_queue.crop.top +
1379                                    ctx->out_queue.crop.left;
1380
1381                 if (ctx->out_queue.fmt->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_422) {
1382                         chroma_crop_offset =
1383                                 ctx->out_queue.bytesperline[0] * ctx->out_queue.crop.top
1384                                 + ctx->out_queue.crop.left;
1385                 } else {
1386                         chroma_crop_offset =
1387                                 ctx->out_queue.bytesperline[0] * ctx->out_queue.crop.top / 2
1388                                 + ctx->out_queue.crop.left;
1389                 }
1390
1391                 dprintk(e5010, 1, "Luma crop offset : %x, chroma crop offset : %x\n",
1392                         luma_crop_offset, chroma_crop_offset);
1393         }
1394
1395         ret = e5010_hw_set_input_luma_addr(e5010->core_base, reg + luma_crop_offset);
1396         if (ret || !reg) {
1397                 v4l2_err(&e5010->v4l2_dev, "failed to set input luma address\n");
1398                 goto device_busy_err;
1399         }
1400
1401         if (num_planes == 1)
1402                 reg += (ctx->out_queue.bytesperline[0]) * (ctx->out_queue.height);
1403         else
1404                 reg = (u32)vb2_dma_contig_plane_dma_addr(&s_vb->vb2_buf, 1);
1405
1406         dprintk(e5010, 3,
1407                 "ctx: 0x%p, luma_addr: 0x%x, chroma_addr: 0x%x, out_addr: 0x%x\n",
1408                 ctx, (u32)vb2_dma_contig_plane_dma_addr(&s_vb->vb2_buf, 0) + luma_crop_offset,
1409                 reg + chroma_crop_offset, (u32)vb2_dma_contig_plane_dma_addr(&d_vb->vb2_buf, 0));
1410
1411         dprintk(e5010, 3,
1412                 "ctx: 0x%p, buf indices: src_index: %d, dst_index: %d\n",
1413                 ctx, s_vb->vb2_buf.index, d_vb->vb2_buf.index);
1414
1415         ret = e5010_hw_set_input_chroma_addr(e5010->core_base, reg + chroma_crop_offset);
1416         if (ret || !reg) {
1417                 v4l2_err(&e5010->v4l2_dev, "failed to set input chroma address\n");
1418                 goto device_busy_err;
1419         }
1420
1421         reg = (u32)vb2_dma_contig_plane_dma_addr(&d_vb->vb2_buf, 0);
1422         reg += HEADER_SIZE;
1423         ret = e5010_hw_set_output_base_addr(e5010->core_base, reg);
1424         if (ret || !reg) {
1425                 v4l2_err(&e5010->v4l2_dev, "failed to set output base address\n");
1426                 goto device_busy_err;
1427         }
1428
1429         /* Set input settings */
1430         ret = e5010_hw_set_horizontal_size(e5010->core_base, ctx->out_queue.crop.width - 1);
1431         if (ret) {
1432                 v4l2_err(&e5010->v4l2_dev, "failed to set input width\n");
1433                 goto device_busy_err;
1434         }
1435
1436         ret = e5010_hw_set_vertical_size(e5010->core_base, ctx->out_queue.crop.height - 1);
1437         if (ret) {
1438                 v4l2_err(&e5010->v4l2_dev, "failed to set input width\n");
1439                 goto device_busy_err;
1440         }
1441
1442         ret = e5010_hw_set_luma_stride(e5010->core_base, ctx->out_queue.bytesperline[0]);
1443         if (ret) {
1444                 v4l2_err(&e5010->v4l2_dev, "failed to set luma stride\n");
1445                 goto device_busy_err;
1446         }
1447
1448         ret = e5010_hw_set_chroma_stride(e5010->core_base, ctx->out_queue.bytesperline[0]);
1449         if (ret) {
1450                 v4l2_err(&e5010->v4l2_dev, "failed to set chroma stride\n");
1451                 goto device_busy_err;
1452         }
1453
1454         ret = e5010_set_input_subsampling(e5010->core_base, ctx->out_queue.fmt->subsampling);
1455         if (ret) {
1456                 v4l2_err(&e5010->v4l2_dev, "failed to set input subsampling\n");
1457                 goto device_busy_err;
1458         }
1459
1460         ret = e5010_hw_set_chroma_order(e5010->core_base, ctx->out_queue.fmt->chroma_order);
1461         if (ret) {
1462                 v4l2_err(&e5010->v4l2_dev, "failed to set chroma order\n");
1463                 goto device_busy_err;
1464         }
1465
1466         e5010_hw_set_output_max_size(e5010->core_base, d_vb->planes[0].length);
1467         e5010_hw_encode_start(e5010->core_base, 1);
1468
1469         spin_unlock_irqrestore(&e5010->hw_lock, flags);
1470
1471         return;
1472
1473 device_busy_err:
1474         e5010_reset(e5010->dev, e5010->core_base, e5010->mmu_base);
1475
1476 no_ready_buf_err:
1477         if (s_vb) {
1478                 v4l2_m2m_src_buf_remove_by_buf(ctx->fh.m2m_ctx, s_vb);
1479                 v4l2_m2m_buf_done(s_vb, VB2_BUF_STATE_ERROR);
1480         }
1481
1482         if (d_vb) {
1483                 v4l2_m2m_dst_buf_remove_by_buf(ctx->fh.m2m_ctx, d_vb);
1484                 /* Payload set to 1 since 0 payload can trigger EOS */
1485                 vb2_set_plane_payload(&d_vb->vb2_buf, 0, 1);
1486                 v4l2_m2m_buf_done(d_vb, VB2_BUF_STATE_ERROR);
1487         }
1488         v4l2_m2m_job_finish(e5010->m2m_dev, ctx->fh.m2m_ctx);
1489         spin_unlock_irqrestore(&e5010->hw_lock, flags);
1490 }
1491
1492 #ifdef CONFIG_PM
1493 static int e5010_runtime_resume(struct device *dev)
1494 {
1495         struct e5010_dev *e5010 = dev_get_drvdata(dev);
1496         int ret;
1497
1498         ret = clk_prepare_enable(e5010->clk);
1499         if (ret < 0) {
1500                 v4l2_err(&e5010->v4l2_dev, "failed to enable clock\n");
1501                 return ret;
1502         }
1503
1504         return 0;
1505 }
1506
1507 static int e5010_runtime_suspend(struct device *dev)
1508 {
1509         struct e5010_dev *e5010 = dev_get_drvdata(dev);
1510
1511         clk_disable_unprepare(e5010->clk);
1512
1513         return 0;
1514 }
1515 #endif
1516
1517 #ifdef CONFIG_PM_SLEEP
1518 static int e5010_suspend(struct device *dev)
1519 {
1520         struct e5010_dev *e5010 = dev_get_drvdata(dev);
1521
1522         v4l2_m2m_suspend(e5010->m2m_dev);
1523
1524         return pm_runtime_force_suspend(dev);
1525 }
1526
1527 static int e5010_resume(struct device *dev)
1528 {
1529         struct e5010_dev *e5010 = dev_get_drvdata(dev);
1530         int ret;
1531
1532         ret = pm_runtime_force_resume(dev);
1533         if (ret < 0)
1534                 return ret;
1535
1536         ret = e5010_init_device(e5010);
1537         if (ret) {
1538                 dev_err(dev, "Failed to re-enable e5010 device\n");
1539                 return ret;
1540         }
1541
1542         v4l2_m2m_resume(e5010->m2m_dev);
1543
1544         return ret;
1545 }
1546 #endif
1547
1548 static const struct dev_pm_ops  e5010_pm_ops = {
1549         SET_RUNTIME_PM_OPS(e5010_runtime_suspend,
1550                            e5010_runtime_resume, NULL)
1551         SET_SYSTEM_SLEEP_PM_OPS(e5010_suspend, e5010_resume)
1552 };
1553
1554 static const struct v4l2_ioctl_ops e5010_ioctl_ops = {
1555         .vidioc_querycap = e5010_querycap,
1556
1557         .vidioc_enum_fmt_vid_cap = e5010_enum_fmt,
1558         .vidioc_g_fmt_vid_cap_mplane = e5010_g_fmt,
1559         .vidioc_try_fmt_vid_cap_mplane = e5010_try_fmt,
1560         .vidioc_s_fmt_vid_cap_mplane = e5010_s_fmt,
1561
1562         .vidioc_enum_fmt_vid_out = e5010_enum_fmt,
1563         .vidioc_g_fmt_vid_out_mplane = e5010_g_fmt,
1564         .vidioc_try_fmt_vid_out_mplane = e5010_try_fmt,
1565         .vidioc_s_fmt_vid_out_mplane = e5010_s_fmt,
1566
1567         .vidioc_g_selection = e5010_g_selection,
1568         .vidioc_s_selection = e5010_s_selection,
1569
1570         .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1571         .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1572         .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1573         .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1574         .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
1575         .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs,
1576         .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf,
1577
1578         .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1579         .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1580         .vidioc_log_status = v4l2_ctrl_log_status,
1581
1582         .vidioc_subscribe_event = e5010_subscribe_event,
1583         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1584         .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
1585         .vidioc_encoder_cmd = e5010_encoder_cmd,
1586
1587         .vidioc_enum_framesizes = e5010_enum_framesizes,
1588 };
1589
1590 static const struct vb2_ops e5010_video_ops = {
1591         .queue_setup = e5010_queue_setup,
1592         .buf_queue = e5010_buf_queue,
1593         .buf_finish = e5010_buf_finish,
1594         .buf_prepare = e5010_buf_prepare,
1595         .buf_out_validate = e5010_buf_out_validate,
1596         .start_streaming = e5010_start_streaming,
1597         .stop_streaming = e5010_stop_streaming,
1598 };
1599
1600 static const struct v4l2_file_operations e5010_fops = {
1601         .owner = THIS_MODULE,
1602         .open = e5010_open,
1603         .release = e5010_release,
1604         .poll = v4l2_m2m_fop_poll,
1605         .unlocked_ioctl = video_ioctl2,
1606         .mmap = v4l2_m2m_fop_mmap,
1607 };
1608
1609 static const struct v4l2_m2m_ops e5010_m2m_ops = {
1610         .device_run = e5010_device_run,
1611 };
1612
1613 static const struct of_device_id e5010_of_match[] = {
1614         {.compatible = "img,e5010-jpeg-enc"},   { /* end */},
1615 };
1616 MODULE_DEVICE_TABLE(of, e5010_of_match);
1617
1618 static struct platform_driver e5010_driver = {
1619         .probe = e5010_probe,
1620         .remove = e5010_remove,
1621         .driver = {
1622                 .name = E5010_MODULE_NAME,
1623                 .of_match_table = e5010_of_match,
1624                 .pm = &e5010_pm_ops,
1625         },
1626 };
1627 module_platform_driver(e5010_driver);
1628
1629 MODULE_LICENSE("GPL");
1630 MODULE_DESCRIPTION("Imagination E5010 JPEG encoder driver");
This page took 0.126156 seconds and 4 git commands to generate.