x86: Disable generation of traditional x87 instructions
[cascardo/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          = 16,
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          = 16,
192                 .colplanes      = 4,
193                 .h_align        = 4,
194                 .v_align        = 1,
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, ver_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         if (ctx->jpeg->variant->version == SJPEG_S5P)
974                 ver_flag = SJPEG_FMT_FLAG_S5P;
975         else
976                 ver_flag = SJPEG_FMT_FLAG_EXYNOS4;
977
978         for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
979                 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
980                 if (fmt->fourcc == pixelformat &&
981                     fmt->flags & fmt_flag &&
982                     fmt->flags & ver_flag) {
983                         return fmt;
984                 }
985         }
986
987         return NULL;
988 }
989
990 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
991                                    unsigned int walign,
992                                    u32 *h, unsigned int hmin, unsigned int hmax,
993                                    unsigned int halign)
994 {
995         int width, height, w_step, h_step;
996
997         width = *w;
998         height = *h;
999
1000         w_step = 1 << walign;
1001         h_step = 1 << halign;
1002         v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1003
1004         if (*w < width && (*w + w_step) < wmax)
1005                 *w += w_step;
1006         if (*h < height && (*h + h_step) < hmax)
1007                 *h += h_step;
1008
1009 }
1010
1011 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1012                           struct s5p_jpeg_ctx *ctx, int q_type)
1013 {
1014         struct v4l2_pix_format *pix = &f->fmt.pix;
1015
1016         if (pix->field == V4L2_FIELD_ANY)
1017                 pix->field = V4L2_FIELD_NONE;
1018         else if (pix->field != V4L2_FIELD_NONE)
1019                 return -EINVAL;
1020
1021         /* V4L2 specification suggests the driver corrects the format struct
1022          * if any of the dimensions is unsupported */
1023         if (q_type == FMT_TYPE_OUTPUT)
1024                 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1025                                        S5P_JPEG_MAX_WIDTH, 0,
1026                                        &pix->height, S5P_JPEG_MIN_HEIGHT,
1027                                        S5P_JPEG_MAX_HEIGHT, 0);
1028         else
1029                 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1030                                        S5P_JPEG_MAX_WIDTH, fmt->h_align,
1031                                        &pix->height, S5P_JPEG_MIN_HEIGHT,
1032                                        S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1033
1034         if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1035                 if (pix->sizeimage <= 0)
1036                         pix->sizeimage = PAGE_SIZE;
1037                 pix->bytesperline = 0;
1038         } else {
1039                 u32 bpl = pix->bytesperline;
1040
1041                 if (fmt->colplanes > 1 && bpl < pix->width)
1042                         bpl = pix->width; /* planar */
1043
1044                 if (fmt->colplanes == 1 && /* packed */
1045                     (bpl << 3) / fmt->depth < pix->width)
1046                         bpl = (pix->width * fmt->depth) >> 3;
1047
1048                 pix->bytesperline = bpl;
1049                 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1050         }
1051
1052         return 0;
1053 }
1054
1055 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1056                                   struct v4l2_format *f)
1057 {
1058         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1059         struct v4l2_pix_format *pix = &f->fmt.pix;
1060         struct s5p_jpeg_fmt *fmt;
1061         int ret;
1062
1063         fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1064                                                 FMT_TYPE_CAPTURE);
1065         if (!fmt) {
1066                 v4l2_err(&ctx->jpeg->v4l2_dev,
1067                          "Fourcc format (0x%08x) invalid.\n",
1068                          f->fmt.pix.pixelformat);
1069                 return -EINVAL;
1070         }
1071
1072         /*
1073          * The exynos4x12 device requires resulting YUV image
1074          * subsampling not to be lower than the input jpeg subsampling.
1075          * If this requirement is not met then downgrade the requested
1076          * capture format to the one with subsampling equal to the input jpeg.
1077          */
1078         if ((ctx->jpeg->variant->version != SJPEG_S5P) &&
1079             (ctx->mode == S5P_JPEG_DECODE) &&
1080             (fmt->flags & SJPEG_FMT_NON_RGB) &&
1081             (fmt->subsampling < ctx->subsampling)) {
1082                 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1083                                                             fmt->fourcc,
1084                                                             &pix->pixelformat,
1085                                                             ctx);
1086                 if (ret < 0)
1087                         pix->pixelformat = V4L2_PIX_FMT_GREY;
1088
1089                 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1090                                                         FMT_TYPE_CAPTURE);
1091         }
1092
1093         return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1094 }
1095
1096 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1097                                   struct v4l2_format *f)
1098 {
1099         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1100         struct s5p_jpeg_fmt *fmt;
1101
1102         fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1103                                                 FMT_TYPE_OUTPUT);
1104         if (!fmt) {
1105                 v4l2_err(&ctx->jpeg->v4l2_dev,
1106                          "Fourcc format (0x%08x) invalid.\n",
1107                          f->fmt.pix.pixelformat);
1108                 return -EINVAL;
1109         }
1110
1111         return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1112 }
1113
1114 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1115 {
1116         struct vb2_queue *vq;
1117         struct s5p_jpeg_q_data *q_data = NULL;
1118         struct v4l2_pix_format *pix = &f->fmt.pix;
1119         struct v4l2_ctrl *ctrl_subs;
1120         unsigned int f_type;
1121
1122         vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1123         if (!vq)
1124                 return -EINVAL;
1125
1126         q_data = get_q_data(ct, f->type);
1127         BUG_ON(q_data == NULL);
1128
1129         if (vb2_is_busy(vq)) {
1130                 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1131                 return -EBUSY;
1132         }
1133
1134         f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1135                         FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1136
1137         q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1138         q_data->w = pix->width;
1139         q_data->h = pix->height;
1140         if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
1141                 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1142         else
1143                 q_data->size = pix->sizeimage;
1144
1145         if (f_type == FMT_TYPE_OUTPUT) {
1146                 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1147                                         V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1148                 if (ctrl_subs)
1149                         v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1150         }
1151
1152         return 0;
1153 }
1154
1155 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1156                                 struct v4l2_format *f)
1157 {
1158         int ret;
1159
1160         ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1161         if (ret)
1162                 return ret;
1163
1164         return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1165 }
1166
1167 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1168                                 struct v4l2_format *f)
1169 {
1170         int ret;
1171
1172         ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1173         if (ret)
1174                 return ret;
1175
1176         return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1177 }
1178
1179 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1180                          struct v4l2_selection *s)
1181 {
1182         struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1183
1184         if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1185             s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1186             ctx->jpeg->variant->version != SJPEG_S5P)
1187                 return -EINVAL;
1188
1189         /* For JPEG blob active == default == bounds */
1190         switch (s->target) {
1191         case V4L2_SEL_TGT_CROP:
1192         case V4L2_SEL_TGT_CROP_BOUNDS:
1193         case V4L2_SEL_TGT_CROP_DEFAULT:
1194         case V4L2_SEL_TGT_COMPOSE:
1195         case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1196                 s->r.width = ctx->out_q.w;
1197                 s->r.height = ctx->out_q.h;
1198                 break;
1199         case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1200         case V4L2_SEL_TGT_COMPOSE_PADDED:
1201                 s->r.width = ctx->cap_q.w;
1202                 s->r.height = ctx->cap_q.h;
1203                 break;
1204         default:
1205                 return -EINVAL;
1206         }
1207         s->r.left = 0;
1208         s->r.top = 0;
1209         return 0;
1210 }
1211
1212 /*
1213  * V4L2 controls
1214  */
1215
1216 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1217 {
1218         struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1219         struct s5p_jpeg *jpeg = ctx->jpeg;
1220         unsigned long flags;
1221
1222         switch (ctrl->id) {
1223         case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1224                 spin_lock_irqsave(&jpeg->slock, flags);
1225                 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1226                 spin_unlock_irqrestore(&jpeg->slock, flags);
1227                 break;
1228         }
1229
1230         return 0;
1231 }
1232
1233 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1234 {
1235         struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1236         unsigned long flags;
1237         int ret = 0;
1238
1239         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1240
1241         if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) {
1242                 if (ctx->jpeg->variant->version == SJPEG_S5P)
1243                         goto error_free;
1244                 /*
1245                  * The exynos4x12 device requires input raw image fourcc
1246                  * to be V4L2_PIX_FMT_GREY if gray jpeg format
1247                  * is to be set.
1248                  */
1249                 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1250                     ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
1251                         ret = -EINVAL;
1252                         goto error_free;
1253                 }
1254                 /*
1255                  * The exynos4x12 device requires resulting jpeg subsampling
1256                  * not to be lower than the input raw image subsampling.
1257                  */
1258                 if (ctx->out_q.fmt->subsampling > ctrl->val)
1259                         ctrl->val = ctx->out_q.fmt->subsampling;
1260         }
1261
1262 error_free:
1263         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1264         return ret;
1265 }
1266
1267 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1268 {
1269         struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1270         unsigned long flags;
1271
1272         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1273
1274         switch (ctrl->id) {
1275         case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1276                 ctx->compr_quality = ctrl->val;
1277                 break;
1278         case V4L2_CID_JPEG_RESTART_INTERVAL:
1279                 ctx->restart_interval = ctrl->val;
1280                 break;
1281         case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1282                 ctx->subsampling = ctrl->val;
1283                 break;
1284         }
1285
1286         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1287         return 0;
1288 }
1289
1290 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1291         .g_volatile_ctrl        = s5p_jpeg_g_volatile_ctrl,
1292         .try_ctrl               = s5p_jpeg_try_ctrl,
1293         .s_ctrl                 = s5p_jpeg_s_ctrl,
1294 };
1295
1296 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1297 {
1298         unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1299         struct v4l2_ctrl *ctrl;
1300         int ret;
1301
1302         v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1303
1304         if (ctx->mode == S5P_JPEG_ENCODE) {
1305                 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1306                                   V4L2_CID_JPEG_COMPRESSION_QUALITY,
1307                                   0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1308
1309                 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1310                                   V4L2_CID_JPEG_RESTART_INTERVAL,
1311                                   0, 3, 0xffff, 0);
1312                 if (ctx->jpeg->variant->version == SJPEG_S5P)
1313                         mask = ~0x06; /* 422, 420 */
1314         }
1315
1316         ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1317                                       V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1318                                       V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1319                                       V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1320
1321         if (ctx->ctrl_handler.error) {
1322                 ret = ctx->ctrl_handler.error;
1323                 goto error_free;
1324         }
1325
1326         if (ctx->mode == S5P_JPEG_DECODE)
1327                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1328                         V4L2_CTRL_FLAG_READ_ONLY;
1329
1330         ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1331         if (ret < 0)
1332                 goto error_free;
1333
1334         return ret;
1335
1336 error_free:
1337         v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1338         return ret;
1339 }
1340
1341 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1342         .vidioc_querycap                = s5p_jpeg_querycap,
1343
1344         .vidioc_enum_fmt_vid_cap        = s5p_jpeg_enum_fmt_vid_cap,
1345         .vidioc_enum_fmt_vid_out        = s5p_jpeg_enum_fmt_vid_out,
1346
1347         .vidioc_g_fmt_vid_cap           = s5p_jpeg_g_fmt,
1348         .vidioc_g_fmt_vid_out           = s5p_jpeg_g_fmt,
1349
1350         .vidioc_try_fmt_vid_cap         = s5p_jpeg_try_fmt_vid_cap,
1351         .vidioc_try_fmt_vid_out         = s5p_jpeg_try_fmt_vid_out,
1352
1353         .vidioc_s_fmt_vid_cap           = s5p_jpeg_s_fmt_vid_cap,
1354         .vidioc_s_fmt_vid_out           = s5p_jpeg_s_fmt_vid_out,
1355
1356         .vidioc_reqbufs                 = v4l2_m2m_ioctl_reqbufs,
1357         .vidioc_querybuf                = v4l2_m2m_ioctl_querybuf,
1358         .vidioc_qbuf                    = v4l2_m2m_ioctl_qbuf,
1359         .vidioc_dqbuf                   = v4l2_m2m_ioctl_dqbuf,
1360
1361         .vidioc_streamon                = v4l2_m2m_ioctl_streamon,
1362         .vidioc_streamoff               = v4l2_m2m_ioctl_streamoff,
1363
1364         .vidioc_g_selection             = s5p_jpeg_g_selection,
1365 };
1366
1367 /*
1368  * ============================================================================
1369  * mem2mem callbacks
1370  * ============================================================================
1371  */
1372
1373 static void s5p_jpeg_device_run(void *priv)
1374 {
1375         struct s5p_jpeg_ctx *ctx = priv;
1376         struct s5p_jpeg *jpeg = ctx->jpeg;
1377         struct vb2_buffer *src_buf, *dst_buf;
1378         unsigned long src_addr, dst_addr, flags;
1379
1380         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1381
1382         src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1383         dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1384         src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1385         dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1386
1387         s5p_jpeg_reset(jpeg->regs);
1388         s5p_jpeg_poweron(jpeg->regs);
1389         s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1390         if (ctx->mode == S5P_JPEG_ENCODE) {
1391                 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1392                         s5p_jpeg_input_raw_mode(jpeg->regs,
1393                                                         S5P_JPEG_RAW_IN_565);
1394                 else
1395                         s5p_jpeg_input_raw_mode(jpeg->regs,
1396                                                         S5P_JPEG_RAW_IN_422);
1397                 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1398                 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1399                 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1400                 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1401                 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1402                 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1403
1404                 /* ultimately comes from sizeimage from userspace */
1405                 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1406
1407                 /* JPEG RGB to YCbCr conversion matrix */
1408                 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1409                 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1410                 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1411                 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1412                 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1413                 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1414                 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1415                 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1416                 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1417
1418                 /*
1419                  * JPEG IP allows storing 4 quantization tables
1420                  * We fill table 0 for luma and table 1 for chroma
1421                  */
1422                 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1423                 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1424                 /* use table 0 for Y */
1425                 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1426                 /* use table 1 for Cb and Cr*/
1427                 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1428                 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1429
1430                 /* Y, Cb, Cr use Huffman table 0 */
1431                 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1432                 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1433                 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1434                 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1435                 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1436                 s5p_jpeg_htbl_dc(jpeg->regs, 3);
1437         } else { /* S5P_JPEG_DECODE */
1438                 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1439                 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1440                 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1441                 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1442                         s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1443                 else
1444                         s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1445                 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1446                 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1447         }
1448
1449         s5p_jpeg_start(jpeg->regs);
1450
1451         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1452 }
1453
1454 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1455 {
1456         struct s5p_jpeg *jpeg = ctx->jpeg;
1457         struct s5p_jpeg_fmt *fmt;
1458         struct vb2_buffer *vb;
1459         struct s5p_jpeg_addr jpeg_addr;
1460         u32 pix_size, padding_bytes = 0;
1461
1462         pix_size = ctx->cap_q.w * ctx->cap_q.h;
1463
1464         if (ctx->mode == S5P_JPEG_ENCODE) {
1465                 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1466                 fmt = ctx->out_q.fmt;
1467                 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1468                         padding_bytes = ctx->out_q.h;
1469         } else {
1470                 fmt = ctx->cap_q.fmt;
1471                 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1472         }
1473
1474         jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1475
1476         if (fmt->colplanes == 2) {
1477                 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1478         } else if (fmt->colplanes == 3) {
1479                 jpeg_addr.cb = jpeg_addr.y + pix_size;
1480                 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1481                         jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1482                 else
1483                         jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1484         }
1485
1486         exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1487 }
1488
1489 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1490 {
1491         struct s5p_jpeg *jpeg = ctx->jpeg;
1492         struct vb2_buffer *vb;
1493         unsigned int jpeg_addr = 0;
1494
1495         if (ctx->mode == S5P_JPEG_ENCODE)
1496                 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1497         else
1498                 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1499
1500         jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1501         exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1502 }
1503
1504 static void exynos4_jpeg_device_run(void *priv)
1505 {
1506         struct s5p_jpeg_ctx *ctx = priv;
1507         struct s5p_jpeg *jpeg = ctx->jpeg;
1508         unsigned int bitstream_size;
1509         unsigned long flags;
1510
1511         spin_lock_irqsave(&ctx->jpeg->slock, flags);
1512
1513         if (ctx->mode == S5P_JPEG_ENCODE) {
1514                 exynos4_jpeg_sw_reset(jpeg->regs);
1515                 exynos4_jpeg_set_interrupt(jpeg->regs);
1516                 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1517
1518                 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1519
1520                 /*
1521                  * JPEG IP allows storing 4 quantization tables
1522                  * We fill table 0 for luma and table 1 for chroma
1523                  */
1524                 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1525                 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1526
1527                 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1528                                                         ctx->compr_quality);
1529                 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1530                                                         ctx->cap_q.h);
1531
1532                 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1533                 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1534                 exynos4_jpeg_set_img_addr(ctx);
1535                 exynos4_jpeg_set_jpeg_addr(ctx);
1536                 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1537                                                         ctx->out_q.fmt->fourcc);
1538         } else {
1539                 exynos4_jpeg_sw_reset(jpeg->regs);
1540                 exynos4_jpeg_set_interrupt(jpeg->regs);
1541                 exynos4_jpeg_set_img_addr(ctx);
1542                 exynos4_jpeg_set_jpeg_addr(ctx);
1543                 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1544
1545                 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1546
1547                 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1548         }
1549
1550         exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1551
1552         spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1553 }
1554
1555 static int s5p_jpeg_job_ready(void *priv)
1556 {
1557         struct s5p_jpeg_ctx *ctx = priv;
1558
1559         if (ctx->mode == S5P_JPEG_DECODE)
1560                 return ctx->hdr_parsed;
1561         return 1;
1562 }
1563
1564 static void s5p_jpeg_job_abort(void *priv)
1565 {
1566 }
1567
1568 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1569         .device_run     = s5p_jpeg_device_run,
1570         .job_ready      = s5p_jpeg_job_ready,
1571         .job_abort      = s5p_jpeg_job_abort,
1572 }
1573 ;
1574 static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1575         .device_run     = exynos4_jpeg_device_run,
1576         .job_ready      = s5p_jpeg_job_ready,
1577         .job_abort      = s5p_jpeg_job_abort,
1578 };
1579
1580 /*
1581  * ============================================================================
1582  * Queue operations
1583  * ============================================================================
1584  */
1585
1586 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1587                            const struct v4l2_format *fmt,
1588                            unsigned int *nbuffers, unsigned int *nplanes,
1589                            unsigned int sizes[], void *alloc_ctxs[])
1590 {
1591         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1592         struct s5p_jpeg_q_data *q_data = NULL;
1593         unsigned int size, count = *nbuffers;
1594
1595         q_data = get_q_data(ctx, vq->type);
1596         BUG_ON(q_data == NULL);
1597
1598         size = q_data->size;
1599
1600         /*
1601          * header is parsed during decoding and parsed information stored
1602          * in the context so we do not allow another buffer to overwrite it
1603          */
1604         if (ctx->mode == S5P_JPEG_DECODE)
1605                 count = 1;
1606
1607         *nbuffers = count;
1608         *nplanes = 1;
1609         sizes[0] = size;
1610         alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1611
1612         return 0;
1613 }
1614
1615 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1616 {
1617         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1618         struct s5p_jpeg_q_data *q_data = NULL;
1619
1620         q_data = get_q_data(ctx, vb->vb2_queue->type);
1621         BUG_ON(q_data == NULL);
1622
1623         if (vb2_plane_size(vb, 0) < q_data->size) {
1624                 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1625                                 __func__, vb2_plane_size(vb, 0),
1626                                 (long)q_data->size);
1627                 return -EINVAL;
1628         }
1629
1630         vb2_set_plane_payload(vb, 0, q_data->size);
1631
1632         return 0;
1633 }
1634
1635 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1636 {
1637         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1638
1639         if (ctx->mode == S5P_JPEG_DECODE &&
1640             vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1641                 struct s5p_jpeg_q_data tmp, *q_data;
1642                 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1643                      (unsigned long)vb2_plane_vaddr(vb, 0),
1644                      min((unsigned long)ctx->out_q.size,
1645                          vb2_get_plane_payload(vb, 0)), ctx);
1646                 if (!ctx->hdr_parsed) {
1647                         vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1648                         return;
1649                 }
1650
1651                 q_data = &ctx->out_q;
1652                 q_data->w = tmp.w;
1653                 q_data->h = tmp.h;
1654
1655                 q_data = &ctx->cap_q;
1656                 q_data->w = tmp.w;
1657                 q_data->h = tmp.h;
1658         }
1659
1660         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
1661 }
1662
1663 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1664 {
1665         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1666         int ret;
1667
1668         ret = pm_runtime_get_sync(ctx->jpeg->dev);
1669
1670         return ret > 0 ? 0 : ret;
1671 }
1672
1673 static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1674 {
1675         struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1676
1677         pm_runtime_put(ctx->jpeg->dev);
1678
1679         return 0;
1680 }
1681
1682 static struct vb2_ops s5p_jpeg_qops = {
1683         .queue_setup            = s5p_jpeg_queue_setup,
1684         .buf_prepare            = s5p_jpeg_buf_prepare,
1685         .buf_queue              = s5p_jpeg_buf_queue,
1686         .wait_prepare           = vb2_ops_wait_prepare,
1687         .wait_finish            = vb2_ops_wait_finish,
1688         .start_streaming        = s5p_jpeg_start_streaming,
1689         .stop_streaming         = s5p_jpeg_stop_streaming,
1690 };
1691
1692 static int queue_init(void *priv, struct vb2_queue *src_vq,
1693                       struct vb2_queue *dst_vq)
1694 {
1695         struct s5p_jpeg_ctx *ctx = priv;
1696         int ret;
1697
1698         src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1699         src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1700         src_vq->drv_priv = ctx;
1701         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1702         src_vq->ops = &s5p_jpeg_qops;
1703         src_vq->mem_ops = &vb2_dma_contig_memops;
1704         src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1705         src_vq->lock = &ctx->jpeg->lock;
1706
1707         ret = vb2_queue_init(src_vq);
1708         if (ret)
1709                 return ret;
1710
1711         dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1712         dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1713         dst_vq->drv_priv = ctx;
1714         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1715         dst_vq->ops = &s5p_jpeg_qops;
1716         dst_vq->mem_ops = &vb2_dma_contig_memops;
1717         dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1718         dst_vq->lock = &ctx->jpeg->lock;
1719
1720         return vb2_queue_init(dst_vq);
1721 }
1722
1723 /*
1724  * ============================================================================
1725  * ISR
1726  * ============================================================================
1727  */
1728
1729 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1730 {
1731         struct s5p_jpeg *jpeg = dev_id;
1732         struct s5p_jpeg_ctx *curr_ctx;
1733         struct vb2_buffer *src_buf, *dst_buf;
1734         unsigned long payload_size = 0;
1735         enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1736         bool enc_jpeg_too_large = false;
1737         bool timer_elapsed = false;
1738         bool op_completed = false;
1739
1740         spin_lock(&jpeg->slock);
1741
1742         curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1743
1744         src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1745         dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1746
1747         if (curr_ctx->mode == S5P_JPEG_ENCODE)
1748                 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1749         timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1750         op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
1751         if (curr_ctx->mode == S5P_JPEG_DECODE)
1752                 op_completed = op_completed &&
1753                                         s5p_jpeg_stream_stat_ok(jpeg->regs);
1754
1755         if (enc_jpeg_too_large) {
1756                 state = VB2_BUF_STATE_ERROR;
1757                 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
1758         } else if (timer_elapsed) {
1759                 state = VB2_BUF_STATE_ERROR;
1760                 s5p_jpeg_clear_timer_stat(jpeg->regs);
1761         } else if (!op_completed) {
1762                 state = VB2_BUF_STATE_ERROR;
1763         } else {
1764                 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
1765         }
1766
1767         dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
1768         dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
1769
1770         v4l2_m2m_buf_done(src_buf, state);
1771         if (curr_ctx->mode == S5P_JPEG_ENCODE)
1772                 vb2_set_plane_payload(dst_buf, 0, payload_size);
1773         v4l2_m2m_buf_done(dst_buf, state);
1774         v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1775
1776         curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
1777         spin_unlock(&jpeg->slock);
1778
1779         s5p_jpeg_clear_int(jpeg->regs);
1780
1781         return IRQ_HANDLED;
1782 }
1783
1784 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1785 {
1786         unsigned int int_status;
1787         struct vb2_buffer *src_vb, *dst_vb;
1788         struct s5p_jpeg *jpeg = priv;
1789         struct s5p_jpeg_ctx *curr_ctx;
1790         unsigned long payload_size = 0;
1791
1792         spin_lock(&jpeg->slock);
1793
1794         curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1795
1796         src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1797         dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1798
1799         int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1800
1801         if (int_status) {
1802                 switch (int_status & 0x1f) {
1803                 case 0x1:
1804                         jpeg->irq_ret = ERR_PROT;
1805                         break;
1806                 case 0x2:
1807                         jpeg->irq_ret = OK_ENC_OR_DEC;
1808                         break;
1809                 case 0x4:
1810                         jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1811                         break;
1812                 case 0x8:
1813                         jpeg->irq_ret = ERR_MULTI_SCAN;
1814                         break;
1815                 case 0x10:
1816                         jpeg->irq_ret = ERR_FRAME;
1817                         break;
1818                 default:
1819                         jpeg->irq_ret = ERR_UNKNOWN;
1820                         break;
1821                 }
1822         } else {
1823                 jpeg->irq_ret = ERR_UNKNOWN;
1824         }
1825
1826         if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1827                 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1828                         payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1829                         vb2_set_plane_payload(dst_vb, 0, payload_size);
1830                 }
1831                 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1832                 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1833         } else {
1834                 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1835                 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1836         }
1837
1838         v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1839         curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1840
1841         spin_unlock(&jpeg->slock);
1842         return IRQ_HANDLED;
1843 }
1844
1845 static void *jpeg_get_drv_data(struct platform_device *pdev);
1846
1847 /*
1848  * ============================================================================
1849  * Driver basic infrastructure
1850  * ============================================================================
1851  */
1852
1853 static int s5p_jpeg_probe(struct platform_device *pdev)
1854 {
1855         struct s5p_jpeg *jpeg;
1856         struct resource *res;
1857         struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
1858         int ret;
1859
1860         if (!pdev->dev.of_node)
1861                 return -ENODEV;
1862
1863         /* JPEG IP abstraction struct */
1864         jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1865         if (!jpeg)
1866                 return -ENOMEM;
1867
1868         jpeg->variant = jpeg_get_drv_data(pdev);
1869
1870         mutex_init(&jpeg->lock);
1871         spin_lock_init(&jpeg->slock);
1872         jpeg->dev = &pdev->dev;
1873
1874         /* memory-mapped registers */
1875         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1876
1877         jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
1878         if (IS_ERR(jpeg->regs))
1879                 return PTR_ERR(jpeg->regs);
1880
1881         /* interrupt service routine registration */
1882         jpeg->irq = ret = platform_get_irq(pdev, 0);
1883         if (ret < 0) {
1884                 dev_err(&pdev->dev, "cannot find IRQ\n");
1885                 return ret;
1886         }
1887
1888         ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1889                                 0, dev_name(&pdev->dev), jpeg);
1890         if (ret) {
1891                 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1892                 return ret;
1893         }
1894
1895         /* clocks */
1896         jpeg->clk = clk_get(&pdev->dev, "jpeg");
1897         if (IS_ERR(jpeg->clk)) {
1898                 dev_err(&pdev->dev, "cannot get clock\n");
1899                 ret = PTR_ERR(jpeg->clk);
1900                 return ret;
1901         }
1902         dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1903
1904         /* v4l2 device */
1905         ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1906         if (ret) {
1907                 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1908                 goto clk_get_rollback;
1909         }
1910
1911         if (jpeg->variant->version == SJPEG_S5P)
1912                 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1913         else
1914                 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1915
1916         /* mem2mem device */
1917         jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
1918         if (IS_ERR(jpeg->m2m_dev)) {
1919                 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1920                 ret = PTR_ERR(jpeg->m2m_dev);
1921                 goto device_register_rollback;
1922         }
1923
1924         jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1925         if (IS_ERR(jpeg->alloc_ctx)) {
1926                 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1927                 ret = PTR_ERR(jpeg->alloc_ctx);
1928                 goto m2m_init_rollback;
1929         }
1930
1931         /* JPEG encoder /dev/videoX node */
1932         jpeg->vfd_encoder = video_device_alloc();
1933         if (!jpeg->vfd_encoder) {
1934                 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1935                 ret = -ENOMEM;
1936                 goto vb2_allocator_rollback;
1937         }
1938         snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1939                                 "%s-enc", S5P_JPEG_M2M_NAME);
1940         jpeg->vfd_encoder->fops         = &s5p_jpeg_fops;
1941         jpeg->vfd_encoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
1942         jpeg->vfd_encoder->minor        = -1;
1943         jpeg->vfd_encoder->release      = video_device_release;
1944         jpeg->vfd_encoder->lock         = &jpeg->lock;
1945         jpeg->vfd_encoder->v4l2_dev     = &jpeg->v4l2_dev;
1946         jpeg->vfd_encoder->vfl_dir      = VFL_DIR_M2M;
1947
1948         ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1949         if (ret) {
1950                 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1951                 goto enc_vdev_alloc_rollback;
1952         }
1953
1954         video_set_drvdata(jpeg->vfd_encoder, jpeg);
1955         v4l2_info(&jpeg->v4l2_dev,
1956                   "encoder device registered as /dev/video%d\n",
1957                   jpeg->vfd_encoder->num);
1958
1959         /* JPEG decoder /dev/videoX node */
1960         jpeg->vfd_decoder = video_device_alloc();
1961         if (!jpeg->vfd_decoder) {
1962                 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1963                 ret = -ENOMEM;
1964                 goto enc_vdev_register_rollback;
1965         }
1966         snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1967                                 "%s-dec", S5P_JPEG_M2M_NAME);
1968         jpeg->vfd_decoder->fops         = &s5p_jpeg_fops;
1969         jpeg->vfd_decoder->ioctl_ops    = &s5p_jpeg_ioctl_ops;
1970         jpeg->vfd_decoder->minor        = -1;
1971         jpeg->vfd_decoder->release      = video_device_release;
1972         jpeg->vfd_decoder->lock         = &jpeg->lock;
1973         jpeg->vfd_decoder->v4l2_dev     = &jpeg->v4l2_dev;
1974         jpeg->vfd_decoder->vfl_dir      = VFL_DIR_M2M;
1975
1976         ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1977         if (ret) {
1978                 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1979                 goto dec_vdev_alloc_rollback;
1980         }
1981
1982         video_set_drvdata(jpeg->vfd_decoder, jpeg);
1983         v4l2_info(&jpeg->v4l2_dev,
1984                   "decoder device registered as /dev/video%d\n",
1985                   jpeg->vfd_decoder->num);
1986
1987         /* final statements & power management */
1988         platform_set_drvdata(pdev, jpeg);
1989
1990         pm_runtime_enable(&pdev->dev);
1991
1992         v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1993
1994         return 0;
1995
1996 dec_vdev_alloc_rollback:
1997         video_device_release(jpeg->vfd_decoder);
1998
1999 enc_vdev_register_rollback:
2000         video_unregister_device(jpeg->vfd_encoder);
2001
2002 enc_vdev_alloc_rollback:
2003         video_device_release(jpeg->vfd_encoder);
2004
2005 vb2_allocator_rollback:
2006         vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2007
2008 m2m_init_rollback:
2009         v4l2_m2m_release(jpeg->m2m_dev);
2010
2011 device_register_rollback:
2012         v4l2_device_unregister(&jpeg->v4l2_dev);
2013
2014 clk_get_rollback:
2015         clk_put(jpeg->clk);
2016
2017         return ret;
2018 }
2019
2020 static int s5p_jpeg_remove(struct platform_device *pdev)
2021 {
2022         struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2023
2024         pm_runtime_disable(jpeg->dev);
2025
2026         video_unregister_device(jpeg->vfd_decoder);
2027         video_device_release(jpeg->vfd_decoder);
2028         video_unregister_device(jpeg->vfd_encoder);
2029         video_device_release(jpeg->vfd_encoder);
2030         vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2031         v4l2_m2m_release(jpeg->m2m_dev);
2032         v4l2_device_unregister(&jpeg->v4l2_dev);
2033
2034         if (!pm_runtime_status_suspended(&pdev->dev))
2035                 clk_disable_unprepare(jpeg->clk);
2036
2037         clk_put(jpeg->clk);
2038
2039         return 0;
2040 }
2041
2042 static int s5p_jpeg_runtime_suspend(struct device *dev)
2043 {
2044         struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2045
2046         clk_disable_unprepare(jpeg->clk);
2047
2048         return 0;
2049 }
2050
2051 static int s5p_jpeg_runtime_resume(struct device *dev)
2052 {
2053         struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2054         unsigned long flags;
2055         int ret;
2056
2057         ret = clk_prepare_enable(jpeg->clk);
2058         if (ret < 0)
2059                 return ret;
2060
2061         spin_lock_irqsave(&jpeg->slock, flags);
2062
2063         /*
2064          * JPEG IP allows storing two Huffman tables for each component
2065          * We fill table 0 for each component and do this here only
2066          * for S5PC210 device as Exynos4x12 requires programming its
2067          * Huffman tables each time the encoding process is initialized.
2068          */
2069         if (jpeg->variant->version == SJPEG_S5P) {
2070                 s5p_jpeg_set_hdctbl(jpeg->regs);
2071                 s5p_jpeg_set_hdctblg(jpeg->regs);
2072                 s5p_jpeg_set_hactbl(jpeg->regs);
2073                 s5p_jpeg_set_hactblg(jpeg->regs);
2074         }
2075
2076         spin_unlock_irqrestore(&jpeg->slock, flags);
2077
2078         return 0;
2079 }
2080
2081 static int s5p_jpeg_suspend(struct device *dev)
2082 {
2083         if (pm_runtime_suspended(dev))
2084                 return 0;
2085
2086         return s5p_jpeg_runtime_suspend(dev);
2087 }
2088
2089 static int s5p_jpeg_resume(struct device *dev)
2090 {
2091         if (pm_runtime_suspended(dev))
2092                 return 0;
2093
2094         return s5p_jpeg_runtime_resume(dev);
2095 }
2096
2097 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
2098         SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2099         SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
2100 };
2101
2102 #ifdef CONFIG_OF
2103 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2104         .version        = SJPEG_S5P,
2105         .jpeg_irq       = s5p_jpeg_irq,
2106 };
2107
2108 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2109         .version        = SJPEG_EXYNOS4,
2110         .jpeg_irq       = exynos4_jpeg_irq,
2111 };
2112
2113 static const struct of_device_id samsung_jpeg_match[] = {
2114         {
2115                 .compatible = "samsung,s5pv210-jpeg",
2116                 .data = &s5p_jpeg_drvdata,
2117         }, {
2118                 .compatible = "samsung,exynos4210-jpeg",
2119                 .data = &s5p_jpeg_drvdata,
2120         }, {
2121                 .compatible = "samsung,exynos4212-jpeg",
2122                 .data = &exynos4_jpeg_drvdata,
2123         },
2124         {},
2125 };
2126
2127 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2128
2129 static void *jpeg_get_drv_data(struct platform_device *pdev)
2130 {
2131         struct s5p_jpeg_variant *driver_data = NULL;
2132         const struct of_device_id *match;
2133
2134         match = of_match_node(of_match_ptr(samsung_jpeg_match),
2135                                          pdev->dev.of_node);
2136         if (match)
2137                 driver_data = (struct s5p_jpeg_variant *)match->data;
2138
2139         return driver_data;
2140 }
2141 #endif
2142
2143 static struct platform_driver s5p_jpeg_driver = {
2144         .probe = s5p_jpeg_probe,
2145         .remove = s5p_jpeg_remove,
2146         .driver = {
2147                 .of_match_table = of_match_ptr(samsung_jpeg_match),
2148                 .owner          = THIS_MODULE,
2149                 .name           = S5P_JPEG_M2M_NAME,
2150                 .pm             = &s5p_jpeg_pm_ops,
2151         },
2152 };
2153
2154 module_platform_driver(s5p_jpeg_driver);
2155
2156 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
2157 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
2158 MODULE_DESCRIPTION("Samsung JPEG codec driver");
2159 MODULE_LICENSE("GPL");