]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/platform/s5p-jpeg/jpeg-core.c
8202fed79345b199e415f5420d2e54d90d511b62
[karo-tx-linux.git] / drivers / media / platform / s5p-jpeg / jpeg-core.c
1 /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
2  *
3  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7  * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/clk.h>
15 #include <linux/err.h>
16 #include <linux/gfp.h>
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/slab.h>
25 #include <linux/spinlock.h>
26 #include <linux/string.h>
27 #include <media/v4l2-mem2mem.h>
28 #include <media/v4l2-ioctl.h>
29 #include <media/videobuf2-core.h>
30 #include <media/videobuf2-dma-contig.h>
31
32 #include "jpeg-core.h"
33 #include "jpeg-hw-s5p.h"
34 #include "jpeg-hw-exynos4.h"
35 #include "jpeg-regs.h"
36
37 static struct s5p_jpeg_fmt sjpeg_formats[] = {
38         {
39                 .name           = "JPEG JFIF",
40                 .fourcc         = V4L2_PIX_FMT_JPEG,
41                 .flags          = SJPEG_FMT_FLAG_ENC_CAPTURE |
42                                   SJPEG_FMT_FLAG_DEC_OUTPUT |
43                                   SJPEG_FMT_FLAG_S5P |
44                                   SJPEG_FMT_FLAG_EXYNOS4,
45         },
46         {
47                 .name           = "YUV 4:2:2 packed, YCbYCr",
48                 .fourcc         = V4L2_PIX_FMT_YUYV,
49                 .depth          = 16,
50                 .colplanes      = 1,
51                 .h_align        = 4,
52                 .v_align        = 3,
53                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
54                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
55                                   SJPEG_FMT_FLAG_S5P |
56                                   SJPEG_FMT_NON_RGB,
57                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
58         },
59         {
60                 .name           = "YUV 4:2:2 packed, YCbYCr",
61                 .fourcc         = V4L2_PIX_FMT_YUYV,
62                 .depth          = 16,
63                 .colplanes      = 1,
64                 .h_align        = 1,
65                 .v_align        = 0,
66                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
67                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
68                                   SJPEG_FMT_FLAG_EXYNOS4 |
69                                   SJPEG_FMT_NON_RGB,
70                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
71         },
72         {
73                 .name           = "YUV 4:2:2 packed, YCrYCb",
74                 .fourcc         = V4L2_PIX_FMT_YVYU,
75                 .depth          = 16,
76                 .colplanes      = 1,
77                 .h_align        = 1,
78                 .v_align        = 0,
79                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
80                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
81                                   SJPEG_FMT_FLAG_EXYNOS4 |
82                                   SJPEG_FMT_NON_RGB,
83                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
84         },
85         {
86                 .name           = "RGB565",
87                 .fourcc         = V4L2_PIX_FMT_RGB565,
88                 .depth          = 16,
89                 .colplanes      = 1,
90                 .h_align        = 0,
91                 .v_align        = 0,
92                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
93                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
94                                   SJPEG_FMT_FLAG_EXYNOS4 |
95                                   SJPEG_FMT_RGB,
96                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
97         },
98         {
99                 .name           = "RGB565",
100                 .fourcc         = V4L2_PIX_FMT_RGB565,
101                 .depth          = 16,
102                 .colplanes      = 1,
103                 .h_align        = 0,
104                 .v_align        = 0,
105                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
106                                   SJPEG_FMT_FLAG_S5P |
107                                   SJPEG_FMT_RGB,
108                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
109         },
110         {
111                 .name           = "ARGB8888, 32 bpp",
112                 .fourcc         = V4L2_PIX_FMT_RGB32,
113                 .depth          = 32,
114                 .colplanes      = 1,
115                 .h_align        = 0,
116                 .v_align        = 0,
117                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
118                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
119                                   SJPEG_FMT_FLAG_EXYNOS4 |
120                                   SJPEG_FMT_RGB,
121                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
122         },
123         {
124                 .name           = "YUV 4:4:4 planar, Y/CbCr",
125                 .fourcc         = V4L2_PIX_FMT_NV24,
126                 .depth          = 24,
127                 .colplanes      = 2,
128                 .h_align        = 0,
129                 .v_align        = 0,
130                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
131                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
132                                   SJPEG_FMT_FLAG_EXYNOS4 |
133                                   SJPEG_FMT_NON_RGB,
134                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
135         },
136         {
137                 .name           = "YUV 4:4:4 planar, Y/CrCb",
138                 .fourcc         = V4L2_PIX_FMT_NV42,
139                 .depth          = 24,
140                 .colplanes      = 2,
141                 .h_align        = 0,
142                 .v_align        = 0,
143                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
144                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
145                                   SJPEG_FMT_FLAG_EXYNOS4 |
146                                   SJPEG_FMT_NON_RGB,
147                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
148         },
149         {
150                 .name           = "YUV 4:2:2 planar, Y/CrCb",
151                 .fourcc         = V4L2_PIX_FMT_NV61,
152                 .depth          = 16,
153                 .colplanes      = 2,
154                 .h_align        = 1,
155                 .v_align        = 0,
156                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
157                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
158                                   SJPEG_FMT_FLAG_EXYNOS4 |
159                                   SJPEG_FMT_NON_RGB,
160                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
161         },
162         {
163                 .name           = "YUV 4:2:2 planar, Y/CbCr",
164                 .fourcc         = V4L2_PIX_FMT_NV16,
165                 .depth          = 16,
166                 .colplanes      = 2,
167                 .h_align        = 1,
168                 .v_align        = 0,
169                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
170                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
171                                   SJPEG_FMT_FLAG_EXYNOS4 |
172                                   SJPEG_FMT_NON_RGB,
173                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
174         },
175         {
176                 .name           = "YUV 4:2:0 planar, Y/CbCr",
177                 .fourcc         = V4L2_PIX_FMT_NV12,
178                 .depth          = 12,
179                 .colplanes      = 2,
180                 .h_align        = 1,
181                 .v_align        = 1,
182                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
183                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
184                                   SJPEG_FMT_FLAG_EXYNOS4 |
185                                   SJPEG_FMT_NON_RGB,
186                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
187         },
188         {
189                 .name           = "YUV 4:2:0 planar, Y/CbCr",
190                 .fourcc         = V4L2_PIX_FMT_NV12,
191                 .depth          = 12,
192                 .colplanes      = 2,
193                 .h_align        = 4,
194                 .v_align        = 4,
195                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
196                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
197                                   SJPEG_FMT_FLAG_S5P |
198                                   SJPEG_FMT_NON_RGB,
199                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
200         },
201         {
202                 .name           = "YUV 4:2:0 planar, Y/CrCb",
203                 .fourcc         = V4L2_PIX_FMT_NV21,
204                 .depth          = 12,
205                 .colplanes      = 2,
206                 .h_align        = 1,
207                 .v_align        = 1,
208                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
209                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
210                                   SJPEG_FMT_FLAG_EXYNOS4 |
211                                   SJPEG_FMT_NON_RGB,
212                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
213         },
214         {
215                 .name           = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
216                 .fourcc         = V4L2_PIX_FMT_YUV420,
217                 .depth          = 12,
218                 .colplanes      = 3,
219                 .h_align        = 1,
220                 .v_align        = 1,
221                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
222                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
223                                   SJPEG_FMT_FLAG_EXYNOS4 |
224                                   SJPEG_FMT_NON_RGB,
225                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
226         },
227         {
228                 .name           = "Gray",
229                 .fourcc         = V4L2_PIX_FMT_GREY,
230                 .depth          = 8,
231                 .colplanes      = 1,
232                 .flags          = SJPEG_FMT_FLAG_ENC_OUTPUT |
233                                   SJPEG_FMT_FLAG_DEC_CAPTURE |
234                                   SJPEG_FMT_FLAG_EXYNOS4 |
235                                   SJPEG_FMT_NON_RGB,
236                 .subsampling    = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
237         },
238 };
239 #define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
240
241 static const unsigned char qtbl_luminance[4][64] = {
242         {/*level 0 - high compression quality */
243                 20, 16, 25, 39, 50, 46, 62, 68,
244                 16, 18, 23, 38, 38, 53, 65, 68,
245                 25, 23, 31, 38, 53, 65, 68, 68,
246                 39, 38, 38, 53, 65, 68, 68, 68,
247                 50, 38, 53, 65, 68, 68, 68, 68,
248                 46, 53, 65, 68, 68, 68, 68, 68,
249                 62, 65, 68, 68, 68, 68, 68, 68,
250                 68, 68, 68, 68, 68, 68, 68, 68
251         },
252         {/* level 1 */
253                 16, 11, 11, 16, 23, 27, 31, 30,
254                 11, 12, 12, 15, 20, 23, 23, 30,
255                 11, 12, 13, 16, 23, 26, 35, 47,
256                 16, 15, 16, 23, 26, 37, 47, 64,
257                 23, 20, 23, 26, 39, 51, 64, 64,
258                 27, 23, 26, 37, 51, 64, 64, 64,
259                 31, 23, 35, 47, 64, 64, 64, 64,
260                 30, 30, 47, 64, 64, 64, 64, 64
261         },
262         {/* level 2 */
263                 12,  8,  8, 12, 17, 21, 24, 23,
264                  8,  9,  9, 11, 15, 19, 18, 23,
265                  8,  9, 10, 12, 19, 20, 27, 36,
266                 12, 11, 12, 21, 20, 28, 36, 53,
267                 17, 15, 19, 20, 30, 39, 51, 59,
268                 21, 19, 20, 28, 39, 51, 59, 59,
269                 24, 18, 27, 36, 51, 59, 59, 59,
270                 23, 23, 36, 53, 59, 59, 59, 59
271         },
272         {/* level 3 - low compression quality */
273                  8,  6,  6,  8, 12, 14, 16, 17,
274                  6,  6,  6,  8, 10, 13, 12, 15,
275                  6,  6,  7,  8, 13, 14, 18, 24,
276                  8,  8,  8, 14, 13, 19, 24, 35,
277                 12, 10, 13, 13, 20, 26, 34, 39,
278                 14, 13, 14, 19, 26, 34, 39, 39,
279                 16, 12, 18, 24, 34, 39, 39, 39,
280                 17, 15, 24, 35, 39, 39, 39, 39
281         }
282 };
283
284 static const unsigned char qtbl_chrominance[4][64] = {
285         {/*level 0 - high compression quality */
286                 21, 25, 32, 38, 54, 68, 68, 68,
287                 25, 28, 24, 38, 54, 68, 68, 68,
288                 32, 24, 32, 43, 66, 68, 68, 68,
289                 38, 38, 43, 53, 68, 68, 68, 68,
290                 54, 54, 66, 68, 68, 68, 68, 68,
291                 68, 68, 68, 68, 68, 68, 68, 68,
292                 68, 68, 68, 68, 68, 68, 68, 68,
293                 68, 68, 68, 68, 68, 68, 68, 68
294         },
295         {/* level 1 */
296                 17, 15, 17, 21, 20, 26, 38, 48,
297                 15, 19, 18, 17, 20, 26, 35, 43,
298                 17, 18, 20, 22, 26, 30, 46, 53,
299                 21, 17, 22, 28, 30, 39, 53, 64,
300                 20, 20, 26, 30, 39, 48, 64, 64,
301                 26, 26, 30, 39, 48, 63, 64, 64,
302                 38, 35, 46, 53, 64, 64, 64, 64,
303                 48, 43, 53, 64, 64, 64, 64, 64
304         },
305         {/* level 2 */
306                 13, 11, 13, 16, 20, 20, 29, 37,
307                 11, 14, 14, 14, 16, 20, 26, 32,
308                 13, 14, 15, 17, 20, 23, 35, 40,
309                 16, 14, 17, 21, 23, 30, 40, 50,
310                 20, 16, 20, 23, 30, 37, 50, 59,
311                 20, 20, 23, 30, 37, 48, 59, 59,
312                 29, 26, 35, 40, 50, 59, 59, 59,
313                 37, 32, 40, 50, 59, 59, 59, 59
314         },
315         {/* level 3 - low compression quality */
316                  9,  8,  9, 11, 14, 17, 19, 24,
317                  8, 10,  9, 11, 14, 13, 17, 22,
318                  9,  9, 13, 14, 13, 15, 23, 26,
319                 11, 11, 14, 14, 15, 20, 26, 33,
320                 14, 14, 13, 15, 20, 24, 33, 39,
321                 17, 13, 15, 20, 24, 32, 39, 39,
322                 19, 17, 23, 26, 33, 39, 39, 39,
323                 24, 22, 26, 33, 39, 39, 39, 39
324         }
325 };
326
327 static const unsigned char hdctbl0[16] = {
328         0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
329 };
330
331 static const unsigned char hdctblg0[12] = {
332         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
333 };
334 static const unsigned char hactbl0[16] = {
335         0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
336 };
337 static const unsigned char hactblg0[162] = {
338         0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
339         0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
340         0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
341         0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
342         0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
343         0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
344         0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
345         0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
346         0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
347         0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
348         0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
349         0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
350         0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
351         0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
352         0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
353         0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
354         0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
355         0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
356         0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
357         0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
358         0xf9, 0xfa
359 };
360
361 /*
362  * Fourcc downgrade schema lookup tables for 422 and 420
363  * chroma subsampling - fourcc on each position maps on the
364  * fourcc from the table fourcc_to_dwngrd_schema_id which allows
365  * to get the most suitable fourcc counterpart for the given
366  * downgraded subsampling property.
367  */
368 static const u32 subs422_fourcc_dwngrd_schema[] = {
369         V4L2_PIX_FMT_NV16,
370         V4L2_PIX_FMT_NV61,
371 };
372
373 static const u32 subs420_fourcc_dwngrd_schema[] = {
374         V4L2_PIX_FMT_NV12,
375         V4L2_PIX_FMT_NV21,
376         V4L2_PIX_FMT_NV12,
377         V4L2_PIX_FMT_NV21,
378         V4L2_PIX_FMT_NV12,
379         V4L2_PIX_FMT_NV21,
380         V4L2_PIX_FMT_GREY,
381         V4L2_PIX_FMT_GREY,
382         V4L2_PIX_FMT_GREY,
383         V4L2_PIX_FMT_GREY,
384 };
385
386 /*
387  * Lookup table for translation of a fourcc to the position
388  * of its downgraded counterpart in the *fourcc_dwngrd_schema
389  * tables.
390  */
391 static const u32 fourcc_to_dwngrd_schema_id[] = {
392         V4L2_PIX_FMT_NV24,
393         V4L2_PIX_FMT_NV42,
394         V4L2_PIX_FMT_NV16,
395         V4L2_PIX_FMT_NV61,
396         V4L2_PIX_FMT_YUYV,
397         V4L2_PIX_FMT_YVYU,
398         V4L2_PIX_FMT_NV12,
399         V4L2_PIX_FMT_NV21,
400         V4L2_PIX_FMT_YUV420,
401         V4L2_PIX_FMT_GREY,
402 };
403
404 static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
405 {
406         int i;
407         for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
408                 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
409                         return i;
410         }
411
412         return -EINVAL;
413 }
414
415 static int s5p_jpeg_adjust_fourcc_to_subsampling(
416                                         enum v4l2_jpeg_chroma_subsampling subs,
417                                         u32 in_fourcc,
418                                         u32 *out_fourcc,
419                                         struct s5p_jpeg_ctx *ctx)
420 {
421         int dwngrd_sch_id;
422
423         if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
424                 dwngrd_sch_id =
425                         s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
426                 if (dwngrd_sch_id < 0)
427                         return -EINVAL;
428         }
429
430         switch (ctx->subsampling) {
431         case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
432                 *out_fourcc = V4L2_PIX_FMT_GREY;
433                 break;
434         case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
435                 if (dwngrd_sch_id >
436                                 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
437                         return -EINVAL;
438                 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
439                 break;
440         case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
441                 if (dwngrd_sch_id >
442                                 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
443                         return -EINVAL;
444                 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
445                 break;
446         default:
447                 *out_fourcc = V4L2_PIX_FMT_GREY;
448                 break;
449         }
450
451         return 0;
452 }
453
454 static int exynos4x12_decoded_subsampling[] = {
455         V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
456         V4L2_JPEG_CHROMA_SUBSAMPLING_444,
457         V4L2_JPEG_CHROMA_SUBSAMPLING_422,
458         V4L2_JPEG_CHROMA_SUBSAMPLING_420,
459 };
460
461 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
462 {
463         return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
464 }
465
466 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
467 {
468         return container_of(fh, struct s5p_jpeg_ctx, fh);
469 }
470
471 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
472 {
473         WARN_ON(ctx->subsampling > 3);
474
475         if (ctx->jpeg->variant->version == SJPEG_S5P) {
476                 if (ctx->subsampling > 2)
477                         return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
478                 return ctx->subsampling;
479         } else {
480                 if (ctx->subsampling > 2)
481                         return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
482                 return exynos4x12_decoded_subsampling[ctx->subsampling];
483         }
484 }
485
486 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
487                                      const unsigned char *qtbl,
488                                      unsigned long tab, int len)
489 {
490         int i;
491
492         for (i = 0; i < len; i++)
493                 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
494 }
495
496 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
497 {
498         /* this driver fills quantisation table 0 with data for luma */
499         s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
500                           S5P_JPG_QTBL_CONTENT(0),
501                           ARRAY_SIZE(qtbl_luminance[quality]));
502 }
503
504 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
505 {
506         /* this driver fills quantisation table 1 with data for chroma */
507         s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
508                           S5P_JPG_QTBL_CONTENT(1),
509                           ARRAY_SIZE(qtbl_chrominance[quality]));
510 }
511
512 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
513                                      const unsigned char *htbl,
514                                      unsigned long tab, int len)
515 {
516         int i;
517
518         for (i = 0; i < len; i++)
519                 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
520 }
521
522 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
523 {
524         /* this driver fills table 0 for this component */
525         s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
526                                                 ARRAY_SIZE(hdctbl0));
527 }
528
529 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
530 {
531         /* this driver fills table 0 for this component */
532         s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
533                                                 ARRAY_SIZE(hdctblg0));
534 }
535
536 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
537 {
538         /* this driver fills table 0 for this component */
539         s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
540                                                 ARRAY_SIZE(hactbl0));
541 }
542
543 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
544 {
545         /* this driver fills table 0 for this component */
546         s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
547                                                 ARRAY_SIZE(hactblg0));
548 }
549
550 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
551                                         const unsigned char *tbl,
552                                         unsigned long tab, int len)
553 {
554         int i;
555         unsigned int dword;
556
557         for (i = 0; i < len; i += 4) {
558                 dword = tbl[i] |
559                         (tbl[i + 1] << 8) |
560                         (tbl[i + 2] << 16) |
561                         (tbl[i + 3] << 24);
562                 writel(dword, regs + tab + i);
563         }
564 }
565
566 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
567 {
568         /* this driver fills quantisation table 0 with data for luma */
569         exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
570                              EXYNOS4_QTBL_CONTENT(0),
571                              ARRAY_SIZE(qtbl_luminance[quality]));
572 }
573
574 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
575 {
576         /* this driver fills quantisation table 1 with data for chroma */
577         exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
578                              EXYNOS4_QTBL_CONTENT(1),
579                              ARRAY_SIZE(qtbl_chrominance[quality]));
580 }
581
582 void exynos4_jpeg_set_huff_tbl(void __iomem *base)
583 {
584         exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
585                                                         ARRAY_SIZE(hdctbl0));
586         exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
587                                                         ARRAY_SIZE(hdctbl0));
588         exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
589                                                         ARRAY_SIZE(hdctblg0));
590         exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
591                                                         ARRAY_SIZE(hdctblg0));
592         exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
593                                                         ARRAY_SIZE(hactbl0));
594         exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
595                                                         ARRAY_SIZE(hactbl0));
596         exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
597                                                         ARRAY_SIZE(hactblg0));
598         exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
599                                                         ARRAY_SIZE(hactblg0));
600 }
601
602 /*
603  * ============================================================================
604  * Device file operations
605  * ============================================================================
606  */
607
608 static int queue_init(void *priv, struct vb2_queue *src_vq,
609                       struct vb2_queue *dst_vq);
610 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
611                                 __u32 pixelformat, unsigned int fmt_type);
612 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
613
614 static int s5p_jpeg_open(struct file *file)
615 {
616         struct s5p_jpeg *jpeg = video_drvdata(file);
617         struct video_device *vfd = video_devdata(file);
618         struct s5p_jpeg_ctx *ctx;
619         struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
620         int ret = 0;
621
622         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
623         if (!ctx)
624                 return -ENOMEM;
625
626         if (mutex_lock_interruptible(&jpeg->lock)) {
627                 ret = -ERESTARTSYS;
628                 goto free;
629         }
630
631         v4l2_fh_init(&ctx->fh, vfd);
632         /* Use separate control handler per file handle */
633         ctx->fh.ctrl_handler = &ctx->ctrl_handler;
634         file->private_data = &ctx->fh;
635         v4l2_fh_add(&ctx->fh);
636
637         ctx->jpeg = jpeg;
638         if (vfd == jpeg->vfd_encoder) {
639                 ctx->mode = S5P_JPEG_ENCODE;
640                 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
641                                                         FMT_TYPE_OUTPUT);
642                 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
643                                                         FMT_TYPE_CAPTURE);
644         } else {
645                 ctx->mode = S5P_JPEG_DECODE;
646                 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
647                                                         FMT_TYPE_OUTPUT);
648                 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
649                                                         FMT_TYPE_CAPTURE);
650         }
651
652         ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
653         if (IS_ERR(ctx->fh.m2m_ctx)) {
654                 ret = PTR_ERR(ctx->fh.m2m_ctx);
655                 goto error;
656         }
657
658         ctx->out_q.fmt = out_fmt;
659         ctx->cap_q.fmt = cap_fmt;
660
661         ret = s5p_jpeg_controls_create(ctx);
662         if (ret < 0)
663                 goto error;
664
665         mutex_unlock(&jpeg->lock);
666         return 0;
667
668 error:
669         v4l2_fh_del(&ctx->fh);
670         v4l2_fh_exit(&ctx->fh);
671         mutex_unlock(&jpeg->lock);
672 free:
673         kfree(ctx);
674         return ret;
675 }
676
677 static int s5p_jpeg_release(struct file *file)
678 {
679         struct s5p_jpeg *jpeg = video_drvdata(file);
680         struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
681
682         mutex_lock(&jpeg->lock);
683         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
684         v4l2_ctrl_handler_free(&ctx->ctrl_handler);
685         v4l2_fh_del(&ctx->fh);
686         v4l2_fh_exit(&ctx->fh);
687         kfree(ctx);
688         mutex_unlock(&jpeg->lock);
689
690         return 0;
691 }
692
693 static const struct v4l2_file_operations s5p_jpeg_fops = {
694         .owner          = THIS_MODULE,
695         .open           = s5p_jpeg_open,
696         .release        = s5p_jpeg_release,
697         .poll           = v4l2_m2m_fop_poll,
698         .unlocked_ioctl = video_ioctl2,
699         .mmap           = v4l2_m2m_fop_mmap,
700 };
701
702 /*
703  * ============================================================================
704  * video ioctl operations
705  * ============================================================================
706  */
707
708 static int get_byte(struct s5p_jpeg_buffer *buf)
709 {
710         if (buf->curr >= buf->size)
711                 return -1;
712
713         return ((unsigned char *)buf->data)[buf->curr++];
714 }
715
716 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
717 {
718         unsigned int temp;
719         int byte;
720
721         byte = get_byte(buf);
722         if (byte == -1)
723                 return -1;
724         temp = byte << 8;
725         byte = get_byte(buf);
726         if (byte == -1)
727                 return -1;
728         *word = (unsigned int)byte | temp;
729         return 0;
730 }
731
732 static void skip(struct s5p_jpeg_buffer *buf, long len)
733 {
734         if (len <= 0)
735                 return;
736
737         while (len--)
738                 get_byte(buf);
739 }
740
741 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
742                                unsigned long buffer, unsigned long size,
743                                struct s5p_jpeg_ctx *ctx)
744 {
745         int c, components, notfound;
746         unsigned int height, width, word, subsampling = 0;
747         long length;
748         struct s5p_jpeg_buffer jpeg_buffer;
749
750         jpeg_buffer.size = size;
751         jpeg_buffer.data = buffer;
752         jpeg_buffer.curr = 0;
753
754         notfound = 1;
755         while (notfound) {
756                 c = get_byte(&jpeg_buffer);
757                 if (c == -1)
758                         break;
759                 if (c != 0xff)
760                         continue;
761                 do
762                         c = get_byte(&jpeg_buffer);
763                 while (c == 0xff);
764                 if (c == -1)
765                         break;
766                 if (c == 0)
767                         continue;
768                 length = 0;
769                 switch (c) {
770                 /* SOF0: baseline JPEG */
771                 case SOF0:
772                         if (get_word_be(&jpeg_buffer, &word))
773                                 break;
774                         if (get_byte(&jpeg_buffer) == -1)
775                                 break;
776                         if (get_word_be(&jpeg_buffer, &height))
777                                 break;
778                         if (get_word_be(&jpeg_buffer, &width))
779                                 break;
780                         components = get_byte(&jpeg_buffer);
781                         if (components == -1)
782                                 break;
783                         notfound = 0;
784
785                         if (components == 1) {
786                                 subsampling = 0x33;
787                         } else {
788                                 skip(&jpeg_buffer, 1);
789                                 subsampling = get_byte(&jpeg_buffer);
790                                 skip(&jpeg_buffer, 1);
791                         }
792
793                         skip(&jpeg_buffer, components * 2);
794                         break;
795
796                 /* skip payload-less markers */
797                 case RST ... RST + 7:
798                 case SOI:
799                 case EOI:
800                 case TEM:
801                         break;
802
803                 /* skip uninteresting payload markers */
804                 default:
805                         if (get_word_be(&jpeg_buffer, &word))
806                                 break;
807                         length = (long)word - 2;
808                         skip(&jpeg_buffer, length);
809                         break;
810                 }
811         }
812         result->w = width;
813         result->h = height;
814         result->size = components;
815
816         switch (subsampling) {
817         case 0x11:
818                 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
819                 break;
820         case 0x21:
821                 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
822                 break;
823         case 0x22:
824                 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
825                 break;
826         case 0x33:
827                 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
828                 break;
829         default:
830                 return false;
831         }
832
833         return !notfound;
834 }
835
836 static int s5p_jpeg_querycap(struct file *file, void *priv,
837                            struct v4l2_capability *cap)
838 {
839         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
840
841         if (ctx->mode == S5P_JPEG_ENCODE) {
842                 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
843                         sizeof(cap->driver));
844                 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
845                         sizeof(cap->card));
846         } else {
847                 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
848                         sizeof(cap->driver));
849                 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
850                         sizeof(cap->card));
851         }
852         cap->bus_info[0] = 0;
853         /*
854          * This is only a mem-to-mem video device. The capture and output
855          * device capability flags are left only for backward compatibility
856          * and are scheduled for removal.
857          */
858         cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
859                             V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
860         return 0;
861 }
862
863 static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
864                     struct v4l2_fmtdesc *f, u32 type)
865 {
866         int i, num = 0;
867
868         for (i = 0; i < n; ++i) {
869                 if (sjpeg_formats[i].flags & type) {
870                         /* index-th format of type type found ? */
871                         if (num == f->index)
872                                 break;
873                         /* Correct type but haven't reached our index yet,
874                          * just increment per-type index */
875                         ++num;
876                 }
877         }
878
879         /* Format not found */
880         if (i >= n)
881                 return -EINVAL;
882
883         strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
884         f->pixelformat = sjpeg_formats[i].fourcc;
885
886         return 0;
887 }
888
889 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
890                                    struct v4l2_fmtdesc *f)
891 {
892         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
893
894         if (ctx->mode == S5P_JPEG_ENCODE)
895                 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
896                                 SJPEG_FMT_FLAG_ENC_CAPTURE);
897
898         return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
899                                         SJPEG_FMT_FLAG_DEC_CAPTURE);
900 }
901
902 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
903                                    struct v4l2_fmtdesc *f)
904 {
905         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
906
907         if (ctx->mode == S5P_JPEG_ENCODE)
908                 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
909                                 SJPEG_FMT_FLAG_ENC_OUTPUT);
910
911         return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
912                                         SJPEG_FMT_FLAG_DEC_OUTPUT);
913 }
914
915 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
916                                           enum v4l2_buf_type type)
917 {
918         if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
919                 return &ctx->out_q;
920         if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
921                 return &ctx->cap_q;
922
923         return NULL;
924 }
925
926 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
927 {
928         struct vb2_queue *vq;
929         struct s5p_jpeg_q_data *q_data = NULL;
930         struct v4l2_pix_format *pix = &f->fmt.pix;
931         struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
932
933         vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
934         if (!vq)
935                 return -EINVAL;
936
937         if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
938             ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
939                 return -EINVAL;
940         q_data = get_q_data(ct, f->type);
941         BUG_ON(q_data == NULL);
942
943         pix->width = q_data->w;
944         pix->height = q_data->h;
945         pix->field = V4L2_FIELD_NONE;
946         pix->pixelformat = q_data->fmt->fourcc;
947         pix->bytesperline = 0;
948         if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
949                 u32 bpl = q_data->w;
950                 if (q_data->fmt->colplanes == 1)
951                         bpl = (bpl * q_data->fmt->depth) >> 3;
952                 pix->bytesperline = bpl;
953         }
954         pix->sizeimage = q_data->size;
955
956         return 0;
957 }
958
959 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
960                                 u32 pixelformat, unsigned int fmt_type)
961 {
962         unsigned int k, fmt_flag;
963
964         if (ctx->mode == S5P_JPEG_ENCODE)
965                 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
966                                 SJPEG_FMT_FLAG_ENC_OUTPUT :
967                                 SJPEG_FMT_FLAG_ENC_CAPTURE;
968         else
969                 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
970                                 SJPEG_FMT_FLAG_DEC_OUTPUT :
971                                 SJPEG_FMT_FLAG_DEC_CAPTURE;
972
973         for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
974                 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
975                 if (fmt->fourcc == pixelformat &&
976                     fmt->flags & fmt_flag &&
977                     fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
978                         return fmt;
979                 }
980         }
981
982         return NULL;
983 }
984
985 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
986                                    unsigned int walign,
987                                    u32 *h, unsigned int hmin, unsigned int hmax,
988                                    unsigned int halign)
989 {
990         int width, height, w_step, h_step;
991
992         width = *w;
993         height = *h;
994
995         w_step = 1 << walign;
996         h_step = 1 << halign;
997         v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
998
999         if (*w < width && (*w + w_step) < wmax)
1000                 *w += w_step;
1001         if (*h < height && (*h + h_step) < hmax)
1002                 *h += h_step;
1003
1004 }
1005
1006 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1007                           struct s5p_jpeg_ctx *ctx, int q_type)
1008 {
1009         struct v4l2_pix_format *pix = &f->fmt.pix;
1010
1011         if (pix->field == V4L2_FIELD_ANY)
1012                 pix->field = V4L2_FIELD_NONE;
1013         else if (pix->field != V4L2_FIELD_NONE)
1014                 return -EINVAL;
1015
1016         /* V4L2 specification suggests the driver corrects the format struct
1017          * if any of the dimensions is unsupported */
1018         if (q_type == FMT_TYPE_OUTPUT)
1019                 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1020                                        S5P_JPEG_MAX_WIDTH, 0,
1021                                        &pix->height, S5P_JPEG_MIN_HEIGHT,
1022                                        S5P_JPEG_MAX_HEIGHT, 0);
1023         else
1024                 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1025                                        S5P_JPEG_MAX_WIDTH, fmt->h_align,
1026                                        &pix->height, S5P_JPEG_MIN_HEIGHT,
1027                                        S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1028
1029         if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1030                 if (pix->sizeimage <= 0)
1031                         pix->sizeimage = PAGE_SIZE;
1032                 pix->bytesperline = 0;
1033         } else {
1034                 u32 bpl = pix->bytesperline;
1035
1036                 if (fmt->colplanes > 1 && bpl < pix->width)
1037                         bpl = pix->width; /* planar */
1038
1039                 if (fmt->colplanes == 1 && /* packed */
1040                     (bpl << 3) / fmt->depth < pix->width)
1041                         bpl = (pix->width * fmt->depth) >> 3;
1042
1043                 pix->bytesperline = bpl;
1044                 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1045         }
1046
1047         return 0;
1048 }
1049
1050 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1051                                   struct v4l2_format *f)
1052 {
1053         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1054         struct v4l2_pix_format *pix = &f->fmt.pix;
1055         struct s5p_jpeg_fmt *fmt;
1056         int ret;
1057
1058         fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1059                                                 FMT_TYPE_CAPTURE);
1060         if (!fmt) {
1061                 v4l2_err(&ctx->jpeg->v4l2_dev,
1062                          "Fourcc format (0x%08x) invalid.\n",
1063                          f->fmt.pix.pixelformat);
1064                 return -EINVAL;
1065         }
1066
1067         /*
1068          * The exynos4x12 device requires resulting YUV image
1069          * subsampling not to be lower than the input jpeg subsampling.
1070          * If this requirement is not met then downgrade the requested
1071          * capture format to the one with subsampling equal to the input jpeg.
1072          */
1073         if ((ctx->jpeg->variant->version != SJPEG_S5P) &&
1074             (ctx->mode == S5P_JPEG_DECODE) &&
1075             (fmt->flags & SJPEG_FMT_NON_RGB) &&
1076             (fmt->subsampling < ctx->subsampling)) {
1077                 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1078                                                             fmt->fourcc,
1079                                                             &pix->pixelformat,
1080                                                             ctx);
1081                 if (ret < 0)
1082                         pix->pixelformat = V4L2_PIX_FMT_GREY;
1083
1084                 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1085                                                         FMT_TYPE_CAPTURE);
1086         }
1087
1088         return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1089 }
1090
1091 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1092                                   struct v4l2_format *f)
1093 {
1094         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1095         struct s5p_jpeg_fmt *fmt;
1096
1097         fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1098                                                 FMT_TYPE_OUTPUT);
1099         if (!fmt) {
1100                 v4l2_err(&ctx->jpeg->v4l2_dev,
1101                          "Fourcc format (0x%08x) invalid.\n",
1102                          f->fmt.pix.pixelformat);
1103                 return -EINVAL;
1104         }
1105
1106         return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1107 }
1108
1109 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1110 {
1111         struct vb2_queue *vq;
1112         struct s5p_jpeg_q_data *q_data = NULL;
1113         struct v4l2_pix_format *pix = &f->fmt.pix;
1114         struct v4l2_ctrl *ctrl_subs;
1115         unsigned int f_type;
1116
1117         vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1118         if (!vq)
1119                 return -EINVAL;
1120
1121         q_data = get_q_data(ct, f->type);
1122         BUG_ON(q_data == NULL);
1123
1124         if (vb2_is_busy(vq)) {
1125                 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1126                 return -EBUSY;
1127         }
1128
1129         f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1130                         FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1131
1132         q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1133         q_data->w = pix->width;
1134         q_data->h = pix->height;
1135         if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
1136                 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1137         else
1138                 q_data->size = pix->sizeimage;
1139
1140         if (f_type == FMT_TYPE_OUTPUT) {
1141                 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1142                                         V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1143                 if (ctrl_subs)
1144                         v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1145         }
1146
1147         return 0;
1148 }
1149
1150 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1151                                 struct v4l2_format *f)
1152 {
1153         int ret;
1154
1155         ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1156         if (ret)
1157                 return ret;
1158
1159         return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1160 }
1161
1162 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1163                                 struct v4l2_format *f)
1164 {
1165         int ret;
1166
1167         ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1168         if (ret)
1169                 return ret;
1170
1171         return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1172 }
1173
1174 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1175                          struct v4l2_selection *s)
1176 {
1177         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1178
1179         if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1180             s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1181             ctx->jpeg->variant->version != SJPEG_S5P)
1182                 return -EINVAL;
1183
1184         /* For JPEG blob active == default == bounds */
1185         switch (s->target) {
1186         case V4L2_SEL_TGT_CROP:
1187         case V4L2_SEL_TGT_CROP_BOUNDS:
1188         case V4L2_SEL_TGT_CROP_DEFAULT:
1189         case V4L2_SEL_TGT_COMPOSE:
1190         case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1191                 s->r.width = ctx->out_q.w;
1192                 s->r.height = ctx->out_q.h;
1193                 break;
1194         case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1195         case V4L2_SEL_TGT_COMPOSE_PADDED:
1196                 s->r.width = ctx->cap_q.w;
1197                 s->r.height = ctx->cap_q.h;
1198                 break;
1199         default:
1200                 return -EINVAL;
1201         }
1202         s->r.left = 0;
1203         s->r.top = 0;
1204         return 0;
1205 }
1206
1207 /*
1208  * V4L2 controls
1209  */
1210
1211 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1212 {
1213         struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1214         struct s5p_jpeg *jpeg = ctx->jpeg;
1215         unsigned long flags;
1216
1217         switch (ctrl->id) {
1218         case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1219                 spin_lock_irqsave(&jpeg->slock, flags);
1220                 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1221                 spin_unlock_irqrestore(&jpeg->slock, flags);
1222                 break;
1223         }
1224
1225         return 0;
1226 }
1227
1228 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1229 {
1230         struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1231         unsigned long flags;
1232         int ret = 0;
1233
1234         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1235
1236         if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) {
1237                 if (ctx->jpeg->variant->version == SJPEG_S5P)
1238                         goto error_free;
1239                 /*
1240                  * The exynos4x12 device requires input raw image fourcc
1241                  * to be V4L2_PIX_FMT_GREY if gray jpeg format
1242                  * is to be set.
1243                  */
1244                 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1245                     ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
1246                         ret = -EINVAL;
1247                         goto error_free;
1248                 }
1249                 /*
1250                  * The exynos4x12 device requires resulting jpeg subsampling
1251                  * not to be lower than the input raw image subsampling.
1252                  */
1253                 if (ctx->out_q.fmt->subsampling > ctrl->val)
1254                         ctrl->val = ctx->out_q.fmt->subsampling;
1255         }
1256
1257 error_free:
1258         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1259         return ret;
1260 }
1261
1262 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1263 {
1264         struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1265         unsigned long flags;
1266
1267         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1268
1269         switch (ctrl->id) {
1270         case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1271                 ctx->compr_quality = ctrl->val;
1272                 break;
1273         case V4L2_CID_JPEG_RESTART_INTERVAL:
1274                 ctx->restart_interval = ctrl->val;
1275                 break;
1276         case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1277                 ctx->subsampling = ctrl->val;
1278                 break;
1279         }
1280
1281         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1282         return 0;
1283 }
1284
1285 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1286         .g_volatile_ctrl        = s5p_jpeg_g_volatile_ctrl,
1287         .try_ctrl               = s5p_jpeg_try_ctrl,
1288         .s_ctrl                 = s5p_jpeg_s_ctrl,
1289 };
1290
1291 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1292 {
1293         unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1294         struct v4l2_ctrl *ctrl;
1295         int ret;
1296
1297         v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1298
1299         if (ctx->mode == S5P_JPEG_ENCODE) {
1300                 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1301                                   V4L2_CID_JPEG_COMPRESSION_QUALITY,
1302                                   0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1303
1304                 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1305                                   V4L2_CID_JPEG_RESTART_INTERVAL,
1306                                   0, 3, 0xffff, 0);
1307                 if (ctx->jpeg->variant->version == SJPEG_S5P)
1308                         mask = ~0x06; /* 422, 420 */
1309         }
1310
1311         ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1312                                       V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1313                                       V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1314                                       V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1315
1316         if (ctx->ctrl_handler.error) {
1317                 ret = ctx->ctrl_handler.error;
1318                 goto error_free;
1319         }
1320
1321         if (ctx->mode == S5P_JPEG_DECODE)
1322                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1323                         V4L2_CTRL_FLAG_READ_ONLY;
1324
1325         ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1326         if (ret < 0)
1327                 goto error_free;
1328
1329         return ret;
1330
1331 error_free:
1332         v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1333         return ret;
1334 }
1335
1336 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1337         .vidioc_querycap                = s5p_jpeg_querycap,
1338
1339         .vidioc_enum_fmt_vid_cap        = s5p_jpeg_enum_fmt_vid_cap,
1340         .vidioc_enum_fmt_vid_out        = s5p_jpeg_enum_fmt_vid_out,
1341
1342         .vidioc_g_fmt_vid_cap           = s5p_jpeg_g_fmt,
1343         .vidioc_g_fmt_vid_out           = s5p_jpeg_g_fmt,
1344
1345         .vidioc_try_fmt_vid_cap         = s5p_jpeg_try_fmt_vid_cap,
1346         .vidioc_try_fmt_vid_out         = s5p_jpeg_try_fmt_vid_out,
1347
1348         .vidioc_s_fmt_vid_cap           = s5p_jpeg_s_fmt_vid_cap,
1349         .vidioc_s_fmt_vid_out           = s5p_jpeg_s_fmt_vid_out,
1350
1351         .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
1352         .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
1353         .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
1354         .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
1355
1356         .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
1357         .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
1358
1359         .vidioc_g_selection             = s5p_jpeg_g_selection,
1360 };
1361
1362 /*
1363  * ============================================================================
1364  * mem2mem callbacks
1365  * ============================================================================
1366  */
1367
1368 static void s5p_jpeg_device_run(void *priv)
1369 {
1370         struct s5p_jpeg_ctx *ctx = priv;
1371         struct s5p_jpeg *jpeg = ctx->jpeg;
1372         struct vb2_buffer *src_buf, *dst_buf;
1373         unsigned long src_addr, dst_addr, flags;
1374
1375         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1376
1377         src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1378         dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1379         src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1380         dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1381
1382         s5p_jpeg_reset(jpeg->regs);
1383         s5p_jpeg_poweron(jpeg->regs);
1384         s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1385         if (ctx->mode == S5P_JPEG_ENCODE) {
1386                 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1387                         s5p_jpeg_input_raw_mode(jpeg->regs,
1388                                                         S5P_JPEG_RAW_IN_565);
1389                 else
1390                         s5p_jpeg_input_raw_mode(jpeg->regs,
1391                                                         S5P_JPEG_RAW_IN_422);
1392                 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1393                 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1394                 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1395                 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1396                 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1397                 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1398
1399                 /* ultimately comes from sizeimage from userspace */
1400                 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1401
1402                 /* JPEG RGB to YCbCr conversion matrix */
1403                 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1404                 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1405                 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1406                 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1407                 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1408                 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1409                 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1410                 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1411                 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1412
1413                 /*
1414                  * JPEG IP allows storing 4 quantization tables
1415                  * We fill table 0 for luma and table 1 for chroma
1416                  */
1417                 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1418                 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1419                 /* use table 0 for Y */
1420                 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1421                 /* use table 1 for Cb and Cr*/
1422                 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1423                 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1424
1425                 /* Y, Cb, Cr use Huffman table 0 */
1426                 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1427                 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1428                 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1429                 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1430                 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1431                 s5p_jpeg_htbl_dc(jpeg->regs, 3);
1432         } else { /* S5P_JPEG_DECODE */
1433                 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1434                 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1435                 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1436                 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1437                         s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1438                 else
1439                         s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1440                 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1441                 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1442         }
1443
1444         s5p_jpeg_start(jpeg->regs);
1445
1446         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1447 }
1448
1449 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1450 {
1451         struct s5p_jpeg *jpeg = ctx->jpeg;
1452         struct s5p_jpeg_fmt *fmt;
1453         struct vb2_buffer *vb;
1454         struct s5p_jpeg_addr jpeg_addr;
1455         u32 pix_size, padding_bytes = 0;
1456
1457         pix_size = ctx->cap_q.w * ctx->cap_q.h;
1458
1459         if (ctx->mode == S5P_JPEG_ENCODE) {
1460                 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1461                 fmt = ctx->out_q.fmt;
1462                 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1463                         padding_bytes = ctx->out_q.h;
1464         } else {
1465                 fmt = ctx->cap_q.fmt;
1466                 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1467         }
1468
1469         jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1470
1471         if (fmt->colplanes == 2) {
1472                 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1473         } else if (fmt->colplanes == 3) {
1474                 jpeg_addr.cb = jpeg_addr.y + pix_size;
1475                 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1476                         jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1477                 else
1478                         jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1479         }
1480
1481         exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1482 }
1483
1484 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1485 {
1486         struct s5p_jpeg *jpeg = ctx->jpeg;
1487         struct vb2_buffer *vb;
1488         unsigned int jpeg_addr = 0;
1489
1490         if (ctx->mode == S5P_JPEG_ENCODE)
1491                 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1492         else
1493                 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1494
1495         jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1496         exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1497 }
1498
1499 static void exynos4_jpeg_device_run(void *priv)
1500 {
1501         struct s5p_jpeg_ctx *ctx = priv;
1502         struct s5p_jpeg *jpeg = ctx->jpeg;
1503         unsigned int bitstream_size;
1504         unsigned long flags;
1505
1506         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1507
1508         if (ctx->mode == S5P_JPEG_ENCODE) {
1509                 exynos4_jpeg_sw_reset(jpeg->regs);
1510                 exynos4_jpeg_set_interrupt(jpeg->regs);
1511                 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1512
1513                 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1514
1515                 /*
1516                  * JPEG IP allows storing 4 quantization tables
1517                  * We fill table 0 for luma and table 1 for chroma
1518                  */
1519                 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1520                 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1521
1522                 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1523                                                         ctx->compr_quality);
1524                 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1525                                                         ctx->cap_q.h);
1526
1527                 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1528                 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1529                 exynos4_jpeg_set_img_addr(ctx);
1530                 exynos4_jpeg_set_jpeg_addr(ctx);
1531                 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1532                                                         ctx->out_q.fmt->fourcc);
1533         } else {
1534                 exynos4_jpeg_sw_reset(jpeg->regs);
1535                 exynos4_jpeg_set_interrupt(jpeg->regs);
1536                 exynos4_jpeg_set_img_addr(ctx);
1537                 exynos4_jpeg_set_jpeg_addr(ctx);
1538                 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1539
1540                 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1541
1542                 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1543         }
1544
1545         exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1546
1547         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1548 }
1549
1550 static int s5p_jpeg_job_ready(void *priv)
1551 {
1552         struct s5p_jpeg_ctx *ctx = priv;
1553
1554         if (ctx->mode == S5P_JPEG_DECODE)
1555                 return ctx->hdr_parsed;
1556         return 1;
1557 }
1558
1559 static void s5p_jpeg_job_abort(void *priv)
1560 {
1561 }
1562
1563 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1564         .device_run     = s5p_jpeg_device_run,
1565         .job_ready      = s5p_jpeg_job_ready,
1566         .job_abort      = s5p_jpeg_job_abort,
1567 }
1568 ;
1569 static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1570         .device_run     = exynos4_jpeg_device_run,
1571         .job_ready      = s5p_jpeg_job_ready,
1572         .job_abort      = s5p_jpeg_job_abort,
1573 };
1574
1575 /*
1576  * ============================================================================
1577  * Queue operations
1578  * ============================================================================
1579  */
1580
1581 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1582                            const struct v4l2_format *fmt,
1583                            unsigned int *nbuffers, unsigned int *nplanes,
1584                            unsigned int sizes[], void *alloc_ctxs[])
1585 {
1586         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1587         struct s5p_jpeg_q_data *q_data = NULL;
1588         unsigned int size, count = *nbuffers;
1589
1590         q_data = get_q_data(ctx, vq->type);
1591         BUG_ON(q_data == NULL);
1592
1593         size = q_data->size;
1594
1595         /*
1596          * header is parsed during decoding and parsed information stored
1597          * in the context so we do not allow another buffer to overwrite it
1598          */
1599         if (ctx->mode == S5P_JPEG_DECODE)
1600                 count = 1;
1601
1602         *nbuffers = count;
1603         *nplanes = 1;
1604         sizes[0] = size;
1605         alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1606
1607         return 0;
1608 }
1609
1610 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1611 {
1612         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1613         struct s5p_jpeg_q_data *q_data = NULL;
1614
1615         q_data = get_q_data(ctx, vb->vb2_queue->type);
1616         BUG_ON(q_data == NULL);
1617
1618         if (vb2_plane_size(vb, 0) < q_data->size) {
1619                 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1620                                 __func__, vb2_plane_size(vb, 0),
1621                                 (long)q_data->size);
1622                 return -EINVAL;
1623         }
1624
1625         vb2_set_plane_payload(vb, 0, q_data->size);
1626
1627         return 0;
1628 }
1629
1630 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1631 {
1632         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1633
1634         if (ctx->mode == S5P_JPEG_DECODE &&
1635             vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1636                 struct s5p_jpeg_q_data tmp, *q_data;
1637                 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1638                      (unsigned long)vb2_plane_vaddr(vb, 0),
1639                      min((unsigned long)ctx->out_q.size,
1640                          vb2_get_plane_payload(vb, 0)), ctx);
1641                 if (!ctx->hdr_parsed) {
1642                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1643                         return;
1644                 }
1645
1646                 q_data = &ctx->out_q;
1647                 q_data->w = tmp.w;
1648                 q_data->h = tmp.h;
1649
1650                 q_data = &ctx->cap_q;
1651                 q_data->w = tmp.w;
1652                 q_data->h = tmp.h;
1653         }
1654
1655         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
1656 }
1657
1658 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1659 {
1660         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1661         int ret;
1662
1663         ret = pm_runtime_get_sync(ctx->jpeg->dev);
1664
1665         return ret > 0 ? 0 : ret;
1666 }
1667
1668 static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
1669 {
1670         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1671
1672         pm_runtime_put(ctx->jpeg->dev);
1673 }
1674
1675 static struct vb2_ops s5p_jpeg_qops = {
1676         .queue_setup            = s5p_jpeg_queue_setup,
1677         .buf_prepare            = s5p_jpeg_buf_prepare,
1678         .buf_queue              = s5p_jpeg_buf_queue,
1679         .wait_prepare           = vb2_ops_wait_prepare,
1680         .wait_finish            = vb2_ops_wait_finish,
1681         .start_streaming        = s5p_jpeg_start_streaming,
1682         .stop_streaming         = s5p_jpeg_stop_streaming,
1683 };
1684
1685 static int queue_init(void *priv, struct vb2_queue *src_vq,
1686                       struct vb2_queue *dst_vq)
1687 {
1688         struct s5p_jpeg_ctx *ctx = priv;
1689         int ret;
1690
1691         src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1692         src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1693         src_vq->drv_priv = ctx;
1694         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1695         src_vq->ops = &s5p_jpeg_qops;
1696         src_vq->mem_ops = &vb2_dma_contig_memops;
1697         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1698         src_vq->lock = &ctx->jpeg->lock;
1699
1700         ret = vb2_queue_init(src_vq);
1701         if (ret)
1702                 return ret;
1703
1704         dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1705         dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1706         dst_vq->drv_priv = ctx;
1707         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1708         dst_vq->ops = &s5p_jpeg_qops;
1709         dst_vq->mem_ops = &vb2_dma_contig_memops;
1710         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1711         dst_vq->lock = &ctx->jpeg->lock;
1712
1713         return vb2_queue_init(dst_vq);
1714 }
1715
1716 /*
1717  * ============================================================================
1718  * ISR
1719  * ============================================================================
1720  */
1721
1722 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1723 {
1724         struct s5p_jpeg *jpeg = dev_id;
1725         struct s5p_jpeg_ctx *curr_ctx;
1726         struct vb2_buffer *src_buf, *dst_buf;
1727         unsigned long payload_size = 0;
1728         enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1729         bool enc_jpeg_too_large = false;
1730         bool timer_elapsed = false;
1731         bool op_completed = false;
1732
1733         spin_lock(&jpeg->slock);
1734
1735         curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1736
1737         src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1738         dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1739
1740         if (curr_ctx->mode == S5P_JPEG_ENCODE)
1741                 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1742         timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1743         op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
1744         if (curr_ctx->mode == S5P_JPEG_DECODE)
1745                 op_completed = op_completed &&
1746                                         s5p_jpeg_stream_stat_ok(jpeg->regs);
1747
1748         if (enc_jpeg_too_large) {
1749                 state = VB2_BUF_STATE_ERROR;
1750                 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
1751         } else if (timer_elapsed) {
1752                 state = VB2_BUF_STATE_ERROR;
1753                 s5p_jpeg_clear_timer_stat(jpeg->regs);
1754         } else if (!op_completed) {
1755                 state = VB2_BUF_STATE_ERROR;
1756         } else {
1757                 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
1758         }
1759
1760         dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
1761         dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
1762         dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
1763         dst_buf->v4l2_buf.flags |=
1764                 src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
1765
1766         v4l2_m2m_buf_done(src_buf, state);
1767         if (curr_ctx->mode == S5P_JPEG_ENCODE)
1768                 vb2_set_plane_payload(dst_buf, 0, payload_size);
1769         v4l2_m2m_buf_done(dst_buf, state);
1770         v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1771
1772         curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
1773         spin_unlock(&jpeg->slock);
1774
1775         s5p_jpeg_clear_int(jpeg->regs);
1776
1777         return IRQ_HANDLED;
1778 }
1779
1780 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1781 {
1782         unsigned int int_status;
1783         struct vb2_buffer *src_vb, *dst_vb;
1784         struct s5p_jpeg *jpeg = priv;
1785         struct s5p_jpeg_ctx *curr_ctx;
1786         unsigned long payload_size = 0;
1787
1788         spin_lock(&jpeg->slock);
1789
1790         curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1791
1792         src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1793         dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1794
1795         int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1796
1797         if (int_status) {
1798                 switch (int_status & 0x1f) {
1799                 case 0x1:
1800                         jpeg->irq_ret = ERR_PROT;
1801                         break;
1802                 case 0x2:
1803                         jpeg->irq_ret = OK_ENC_OR_DEC;
1804                         break;
1805                 case 0x4:
1806                         jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1807                         break;
1808                 case 0x8:
1809                         jpeg->irq_ret = ERR_MULTI_SCAN;
1810                         break;
1811                 case 0x10:
1812                         jpeg->irq_ret = ERR_FRAME;
1813                         break;
1814                 default:
1815                         jpeg->irq_ret = ERR_UNKNOWN;
1816                         break;
1817                 }
1818         } else {
1819                 jpeg->irq_ret = ERR_UNKNOWN;
1820         }
1821
1822         if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1823                 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1824                         payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1825                         vb2_set_plane_payload(dst_vb, 0, payload_size);
1826                 }
1827                 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1828                 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1829         } else {
1830                 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1831                 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1832         }
1833
1834         v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1835         curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1836
1837         spin_unlock(&jpeg->slock);
1838         return IRQ_HANDLED;
1839 }
1840
1841 static void *jpeg_get_drv_data(struct platform_device *pdev);
1842
1843 /*
1844  * ============================================================================
1845  * Driver basic infrastructure
1846  * ============================================================================
1847  */
1848
1849 static int s5p_jpeg_probe(struct platform_device *pdev)
1850 {
1851         struct s5p_jpeg *jpeg;
1852         struct resource *res;
1853         struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
1854         int ret;
1855
1856         if (!pdev->dev.of_node)
1857                 return -ENODEV;
1858
1859         /* JPEG IP abstraction struct */
1860         jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1861         if (!jpeg)
1862                 return -ENOMEM;
1863
1864         jpeg->variant = jpeg_get_drv_data(pdev);
1865
1866         mutex_init(&jpeg->lock);
1867         spin_lock_init(&jpeg->slock);
1868         jpeg->dev = &pdev->dev;
1869
1870         /* memory-mapped registers */
1871         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1872
1873         jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
1874         if (IS_ERR(jpeg->regs))
1875                 return PTR_ERR(jpeg->regs);
1876
1877         /* interrupt service routine registration */
1878         jpeg->irq = ret = platform_get_irq(pdev, 0);
1879         if (ret < 0) {
1880                 dev_err(&pdev->dev, "cannot find IRQ\n");
1881                 return ret;
1882         }
1883
1884         ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1885                                 0, dev_name(&pdev->dev), jpeg);
1886         if (ret) {
1887                 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1888                 return ret;
1889         }
1890
1891         /* clocks */
1892         jpeg->clk = clk_get(&pdev->dev, "jpeg");
1893         if (IS_ERR(jpeg->clk)) {
1894                 dev_err(&pdev->dev, "cannot get clock\n");
1895                 ret = PTR_ERR(jpeg->clk);
1896                 return ret;
1897         }
1898         dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1899
1900         /* v4l2 device */
1901         ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1902         if (ret) {
1903                 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1904                 goto clk_get_rollback;
1905         }
1906
1907         if (jpeg->variant->version == SJPEG_S5P)
1908                 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1909         else
1910                 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1911
1912         /* mem2mem device */
1913         jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
1914         if (IS_ERR(jpeg->m2m_dev)) {
1915                 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1916                 ret = PTR_ERR(jpeg->m2m_dev);
1917                 goto device_register_rollback;
1918         }
1919
1920         jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1921         if (IS_ERR(jpeg->alloc_ctx)) {
1922                 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1923                 ret = PTR_ERR(jpeg->alloc_ctx);
1924                 goto m2m_init_rollback;
1925         }
1926
1927         /* JPEG encoder /dev/videoX node */
1928         jpeg->vfd_encoder = video_device_alloc();
1929         if (!jpeg->vfd_encoder) {
1930                 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1931                 ret = -ENOMEM;
1932                 goto vb2_allocator_rollback;
1933         }
1934         snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1935                                 "%s-enc", S5P_JPEG_M2M_NAME);
1936         jpeg->vfd_encoder->fops         = &s5p_jpeg_fops;
1937         jpeg->vfd_encoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
1938         jpeg->vfd_encoder->minor        = -1;
1939         jpeg->vfd_encoder->release      = video_device_release;
1940         jpeg->vfd_encoder->lock         = &jpeg->lock;
1941         jpeg->vfd_encoder->v4l2_dev     = &jpeg->v4l2_dev;
1942         jpeg->vfd_encoder->vfl_dir      = VFL_DIR_M2M;
1943
1944         ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1945         if (ret) {
1946                 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1947                 goto enc_vdev_alloc_rollback;
1948         }
1949
1950         video_set_drvdata(jpeg->vfd_encoder, jpeg);
1951         v4l2_info(&jpeg->v4l2_dev,
1952                   "encoder device registered as /dev/video%d\n",
1953                   jpeg->vfd_encoder->num);
1954
1955         /* JPEG decoder /dev/videoX node */
1956         jpeg->vfd_decoder = video_device_alloc();
1957         if (!jpeg->vfd_decoder) {
1958                 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1959                 ret = -ENOMEM;
1960                 goto enc_vdev_register_rollback;
1961         }
1962         snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1963                                 "%s-dec", S5P_JPEG_M2M_NAME);
1964         jpeg->vfd_decoder->fops         = &s5p_jpeg_fops;
1965         jpeg->vfd_decoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
1966         jpeg->vfd_decoder->minor        = -1;
1967         jpeg->vfd_decoder->release      = video_device_release;
1968         jpeg->vfd_decoder->lock         = &jpeg->lock;
1969         jpeg->vfd_decoder->v4l2_dev     = &jpeg->v4l2_dev;
1970         jpeg->vfd_decoder->vfl_dir      = VFL_DIR_M2M;
1971
1972         ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1973         if (ret) {
1974                 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1975                 goto dec_vdev_alloc_rollback;
1976         }
1977
1978         video_set_drvdata(jpeg->vfd_decoder, jpeg);
1979         v4l2_info(&jpeg->v4l2_dev,
1980                   "decoder device registered as /dev/video%d\n",
1981                   jpeg->vfd_decoder->num);
1982
1983         /* final statements & power management */
1984         platform_set_drvdata(pdev, jpeg);
1985
1986         pm_runtime_enable(&pdev->dev);
1987
1988         v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1989
1990         return 0;
1991
1992 dec_vdev_alloc_rollback:
1993         video_device_release(jpeg->vfd_decoder);
1994
1995 enc_vdev_register_rollback:
1996         video_unregister_device(jpeg->vfd_encoder);
1997
1998 enc_vdev_alloc_rollback:
1999         video_device_release(jpeg->vfd_encoder);
2000
2001 vb2_allocator_rollback:
2002         vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2003
2004 m2m_init_rollback:
2005         v4l2_m2m_release(jpeg->m2m_dev);
2006
2007 device_register_rollback:
2008         v4l2_device_unregister(&jpeg->v4l2_dev);
2009
2010 clk_get_rollback:
2011         clk_put(jpeg->clk);
2012
2013         return ret;
2014 }
2015
2016 static int s5p_jpeg_remove(struct platform_device *pdev)
2017 {
2018         struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2019
2020         pm_runtime_disable(jpeg->dev);
2021
2022         video_unregister_device(jpeg->vfd_decoder);
2023         video_device_release(jpeg->vfd_decoder);
2024         video_unregister_device(jpeg->vfd_encoder);
2025         video_device_release(jpeg->vfd_encoder);
2026         vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2027         v4l2_m2m_release(jpeg->m2m_dev);
2028         v4l2_device_unregister(&jpeg->v4l2_dev);
2029
2030         if (!pm_runtime_status_suspended(&pdev->dev))
2031                 clk_disable_unprepare(jpeg->clk);
2032
2033         clk_put(jpeg->clk);
2034
2035         return 0;
2036 }
2037
2038 static int s5p_jpeg_runtime_suspend(struct device *dev)
2039 {
2040         struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2041
2042         clk_disable_unprepare(jpeg->clk);
2043
2044         return 0;
2045 }
2046
2047 static int s5p_jpeg_runtime_resume(struct device *dev)
2048 {
2049         struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2050         unsigned long flags;
2051         int ret;
2052
2053         ret = clk_prepare_enable(jpeg->clk);
2054         if (ret < 0)
2055                 return ret;
2056
2057         spin_lock_irqsave(&jpeg->slock, flags);
2058
2059         /*
2060          * JPEG IP allows storing two Huffman tables for each component
2061          * We fill table 0 for each component and do this here only
2062          * for S5PC210 device as Exynos4x12 requires programming its
2063          * Huffman tables each time the encoding process is initialized.
2064          */
2065         if (jpeg->variant->version == SJPEG_S5P) {
2066                 s5p_jpeg_set_hdctbl(jpeg->regs);
2067                 s5p_jpeg_set_hdctblg(jpeg->regs);
2068                 s5p_jpeg_set_hactbl(jpeg->regs);
2069                 s5p_jpeg_set_hactblg(jpeg->regs);
2070         }
2071
2072         spin_unlock_irqrestore(&jpeg->slock, flags);
2073
2074         return 0;
2075 }
2076
2077 static int s5p_jpeg_suspend(struct device *dev)
2078 {
2079         if (pm_runtime_suspended(dev))
2080                 return 0;
2081
2082         return s5p_jpeg_runtime_suspend(dev);
2083 }
2084
2085 static int s5p_jpeg_resume(struct device *dev)
2086 {
2087         if (pm_runtime_suspended(dev))
2088                 return 0;
2089
2090         return s5p_jpeg_runtime_resume(dev);
2091 }
2092
2093 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
2094         SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2095         SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
2096 };
2097
2098 #ifdef CONFIG_OF
2099 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2100         .version        = SJPEG_S5P,
2101         .jpeg_irq       = s5p_jpeg_irq,
2102         .fmt_ver_flag   = SJPEG_FMT_FLAG_S5P,
2103 };
2104
2105 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2106         .version        = SJPEG_EXYNOS4,
2107         .jpeg_irq       = exynos4_jpeg_irq,
2108         .fmt_ver_flag   = SJPEG_FMT_FLAG_EXYNOS4,
2109 };
2110
2111 static const struct of_device_id samsung_jpeg_match[] = {
2112         {
2113                 .compatible = "samsung,s5pv210-jpeg",
2114                 .data = &s5p_jpeg_drvdata,
2115         }, {
2116                 .compatible = "samsung,exynos4210-jpeg",
2117                 .data = &s5p_jpeg_drvdata,
2118         }, {
2119                 .compatible = "samsung,exynos4212-jpeg",
2120                 .data = &exynos4_jpeg_drvdata,
2121         },
2122         {},
2123 };
2124
2125 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2126
2127 static void *jpeg_get_drv_data(struct platform_device *pdev)
2128 {
2129         struct s5p_jpeg_variant *driver_data = NULL;
2130         const struct of_device_id *match;
2131
2132         match = of_match_node(of_match_ptr(samsung_jpeg_match),
2133                                          pdev->dev.of_node);
2134         if (match)
2135                 driver_data = (struct s5p_jpeg_variant *)match->data;
2136
2137         return driver_data;
2138 }
2139 #endif
2140
2141 static struct platform_driver s5p_jpeg_driver = {
2142         .probe = s5p_jpeg_probe,
2143         .remove = s5p_jpeg_remove,
2144         .driver = {
2145                 .of_match_table = of_match_ptr(samsung_jpeg_match),
2146                 .owner          = THIS_MODULE,
2147                 .name           = S5P_JPEG_M2M_NAME,
2148                 .pm             = &s5p_jpeg_pm_ops,
2149         },
2150 };
2151
2152 module_platform_driver(s5p_jpeg_driver);
2153
2154 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
2155 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
2156 MODULE_DESCRIPTION("Samsung JPEG codec driver");
2157 MODULE_LICENSE("GPL");