]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/media/platform/s5p-jpeg/jpeg-core.c
[media] s5p-jpeg: Ensure correct capture format for Exynos4x12
[mirror_ubuntu-hirsute-kernel.git] / drivers / media / platform / s5p-jpeg / jpeg-core.c
CommitLineData
2c3fb08b 1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
bb677f3a 2 *
80529ae5 3 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
bb677f3a
AP
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
80529ae5 7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
bb677f3a
AP
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>
f7074ab3 21#include <linux/of.h>
bb677f3a
AP
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"
9f7b62d9 33#include "jpeg-hw-s5p.h"
80529ae5
JA
34#include "jpeg-hw-exynos4.h"
35#include "jpeg-regs.h"
bb677f3a 36
80529ae5 37static struct s5p_jpeg_fmt sjpeg_formats[] = {
bb677f3a 38 {
fb6f8c02
AP
39 .name = "JPEG JFIF",
40 .fourcc = V4L2_PIX_FMT_JPEG,
80529ae5
JA
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,
fb6f8c02 50 .colplanes = 1,
80529ae5
JA
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,
bb677f3a
AP
58 },
59 {
60 .name = "YUV 4:2:2 packed, YCbYCr",
61 .fourcc = V4L2_PIX_FMT_YUYV,
62 .depth = 16,
63 .colplanes = 1,
80529ae5
JA
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,
bb677f3a
AP
84 },
85 {
86 .name = "RGB565",
87 .fourcc = V4L2_PIX_FMT_RGB565,
88 .depth = 16,
89 .colplanes = 1,
80529ae5
JA
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,
bb677f3a 161 },
bb677f3a 162 {
80529ae5
JA
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",
c97ba28b 177 .fourcc = V4L2_PIX_FMT_NV12,
80529ae5
JA
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,
bb677f3a
AP
187 },
188 {
80529ae5
JA
189 .name = "YUV 4:2:0 planar, Y/CbCr",
190 .fourcc = V4L2_PIX_FMT_NV12,
bb677f3a 191 .depth = 16,
80529ae5 192 .colplanes = 4,
bb677f3a 193 .h_align = 4,
80529ae5
JA
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,
bb677f3a
AP
200 },
201 {
80529ae5
JA
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,
bb677f3a 231 .colplanes = 1,
80529ae5
JA
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,
bb677f3a
AP
237 },
238};
80529ae5 239#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
bb677f3a
AP
240
241static const unsigned char qtbl_luminance[4][64] = {
78e5a3ce
JA
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
bb677f3a
AP
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 },
78e5a3ce
JA
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
bb677f3a
AP
281 }
282};
283
284static const unsigned char qtbl_chrominance[4][64] = {
78e5a3ce
JA
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
bb677f3a
AP
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 },
78e5a3ce
JA
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
bb677f3a
AP
324 }
325};
326
327static const unsigned char hdctbl0[16] = {
328 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
329};
330
331static const unsigned char hdctblg0[12] = {
332 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
333};
334static const unsigned char hactbl0[16] = {
335 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
336};
337static 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
337777a4
JA
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 */
368static const u32 subs422_fourcc_dwngrd_schema[] = {
369 V4L2_PIX_FMT_NV16,
370 V4L2_PIX_FMT_NV61,
371};
372
373static 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 */
391static 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
404static 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
415static 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
15f4bc3b
SN
454static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
455{
456 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
457}
458
275de24d
SN
459static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
460{
461 return container_of(fh, struct s5p_jpeg_ctx, fh);
462}
463
31dc0ac0
JA
464static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
465 const unsigned char *qtbl,
466 unsigned long tab, int len)
bb677f3a
AP
467{
468 int i;
469
470 for (i = 0; i < len; i++)
471 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
472}
473
31dc0ac0 474static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
bb677f3a
AP
475{
476 /* this driver fills quantisation table 0 with data for luma */
31dc0ac0
JA
477 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
478 S5P_JPG_QTBL_CONTENT(0),
479 ARRAY_SIZE(qtbl_luminance[quality]));
bb677f3a
AP
480}
481
31dc0ac0 482static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
bb677f3a
AP
483{
484 /* this driver fills quantisation table 1 with data for chroma */
31dc0ac0
JA
485 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
486 S5P_JPG_QTBL_CONTENT(1),
487 ARRAY_SIZE(qtbl_chrominance[quality]));
bb677f3a
AP
488}
489
31dc0ac0
JA
490static inline void s5p_jpeg_set_htbl(void __iomem *regs,
491 const unsigned char *htbl,
492 unsigned long tab, int len)
bb677f3a
AP
493{
494 int i;
495
496 for (i = 0; i < len; i++)
497 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
498}
499
31dc0ac0 500static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
bb677f3a
AP
501{
502 /* this driver fills table 0 for this component */
31dc0ac0
JA
503 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
504 ARRAY_SIZE(hdctbl0));
bb677f3a
AP
505}
506
31dc0ac0 507static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
bb677f3a
AP
508{
509 /* this driver fills table 0 for this component */
31dc0ac0
JA
510 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
511 ARRAY_SIZE(hdctblg0));
bb677f3a
AP
512}
513
31dc0ac0 514static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
bb677f3a
AP
515{
516 /* this driver fills table 0 for this component */
31dc0ac0
JA
517 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
518 ARRAY_SIZE(hactbl0));
bb677f3a
AP
519}
520
31dc0ac0 521static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
bb677f3a
AP
522{
523 /* this driver fills table 0 for this component */
31dc0ac0
JA
524 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
525 ARRAY_SIZE(hactblg0));
bb677f3a
AP
526}
527
80529ae5
JA
528static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
529 const unsigned char *tbl,
530 unsigned long tab, int len)
531{
532 int i;
533 unsigned int dword;
534
535 for (i = 0; i < len; i += 4) {
536 dword = tbl[i] |
537 (tbl[i + 1] << 8) |
538 (tbl[i + 2] << 16) |
539 (tbl[i + 3] << 24);
540 writel(dword, regs + tab + i);
541 }
542}
543
544static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
545{
546 /* this driver fills quantisation table 0 with data for luma */
547 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
548 EXYNOS4_QTBL_CONTENT(0),
549 ARRAY_SIZE(qtbl_luminance[quality]));
550}
551
552static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
553{
554 /* this driver fills quantisation table 1 with data for chroma */
555 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
556 EXYNOS4_QTBL_CONTENT(1),
557 ARRAY_SIZE(qtbl_chrominance[quality]));
558}
559
560void exynos4_jpeg_set_huff_tbl(void __iomem *base)
561{
562 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
563 ARRAY_SIZE(hdctbl0));
564 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
565 ARRAY_SIZE(hdctbl0));
566 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
567 ARRAY_SIZE(hdctblg0));
568 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
569 ARRAY_SIZE(hdctblg0));
570 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
571 ARRAY_SIZE(hactbl0));
572 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
573 ARRAY_SIZE(hactbl0));
574 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
575 ARRAY_SIZE(hactblg0));
576 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
577 ARRAY_SIZE(hactblg0));
578}
579
bb677f3a
AP
580/*
581 * ============================================================================
582 * Device file operations
583 * ============================================================================
584 */
585
586static int queue_init(void *priv, struct vb2_queue *src_vq,
587 struct vb2_queue *dst_vq);
80529ae5
JA
588static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
589 __u32 pixelformat, unsigned int fmt_type);
15f4bc3b 590static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
bb677f3a
AP
591
592static int s5p_jpeg_open(struct file *file)
593{
594 struct s5p_jpeg *jpeg = video_drvdata(file);
595 struct video_device *vfd = video_devdata(file);
596 struct s5p_jpeg_ctx *ctx;
80529ae5 597 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
275de24d 598 int ret = 0;
bb677f3a 599
b5146c96 600 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
bb677f3a
AP
601 if (!ctx)
602 return -ENOMEM;
603
b0d5cd6b
HV
604 if (mutex_lock_interruptible(&jpeg->lock)) {
605 ret = -ERESTARTSYS;
606 goto free;
607 }
608
275de24d 609 v4l2_fh_init(&ctx->fh, vfd);
15f4bc3b
SN
610 /* Use separate control handler per file handle */
611 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
275de24d
SN
612 file->private_data = &ctx->fh;
613 v4l2_fh_add(&ctx->fh);
614
bb677f3a
AP
615 ctx->jpeg = jpeg;
616 if (vfd == jpeg->vfd_encoder) {
617 ctx->mode = S5P_JPEG_ENCODE;
80529ae5
JA
618 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
619 FMT_TYPE_OUTPUT);
620 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
621 FMT_TYPE_CAPTURE);
bb677f3a
AP
622 } else {
623 ctx->mode = S5P_JPEG_DECODE;
80529ae5
JA
624 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
625 FMT_TYPE_OUTPUT);
626 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
627 FMT_TYPE_CAPTURE);
bb677f3a
AP
628 }
629
718cf4a9
SN
630 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
631 if (IS_ERR(ctx->fh.m2m_ctx)) {
632 ret = PTR_ERR(ctx->fh.m2m_ctx);
275de24d 633 goto error;
bb677f3a
AP
634 }
635
636 ctx->out_q.fmt = out_fmt;
80529ae5
JA
637 ctx->cap_q.fmt = cap_fmt;
638
639 ret = s5p_jpeg_controls_create(ctx);
640 if (ret < 0)
641 goto error;
642
b0d5cd6b 643 mutex_unlock(&jpeg->lock);
bb677f3a 644 return 0;
275de24d
SN
645
646error:
647 v4l2_fh_del(&ctx->fh);
648 v4l2_fh_exit(&ctx->fh);
b0d5cd6b
HV
649 mutex_unlock(&jpeg->lock);
650free:
275de24d
SN
651 kfree(ctx);
652 return ret;
bb677f3a
AP
653}
654
655static int s5p_jpeg_release(struct file *file)
656{
b0d5cd6b 657 struct s5p_jpeg *jpeg = video_drvdata(file);
275de24d 658 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
bb677f3a 659
b0d5cd6b 660 mutex_lock(&jpeg->lock);
718cf4a9 661 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
15f4bc3b 662 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
275de24d
SN
663 v4l2_fh_del(&ctx->fh);
664 v4l2_fh_exit(&ctx->fh);
bb677f3a 665 kfree(ctx);
80529ae5 666 mutex_unlock(&jpeg->lock);
bb677f3a
AP
667
668 return 0;
669}
670
bb677f3a
AP
671static const struct v4l2_file_operations s5p_jpeg_fops = {
672 .owner = THIS_MODULE,
673 .open = s5p_jpeg_open,
674 .release = s5p_jpeg_release,
718cf4a9 675 .poll = v4l2_m2m_fop_poll,
bb677f3a 676 .unlocked_ioctl = video_ioctl2,
718cf4a9 677 .mmap = v4l2_m2m_fop_mmap,
bb677f3a
AP
678};
679
680/*
681 * ============================================================================
682 * video ioctl operations
683 * ============================================================================
684 */
685
686static int get_byte(struct s5p_jpeg_buffer *buf)
687{
688 if (buf->curr >= buf->size)
689 return -1;
690
691 return ((unsigned char *)buf->data)[buf->curr++];
692}
693
694static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
695{
696 unsigned int temp;
697 int byte;
698
699 byte = get_byte(buf);
700 if (byte == -1)
701 return -1;
702 temp = byte << 8;
703 byte = get_byte(buf);
704 if (byte == -1)
705 return -1;
706 *word = (unsigned int)byte | temp;
707 return 0;
708}
709
710static void skip(struct s5p_jpeg_buffer *buf, long len)
711{
712 if (len <= 0)
713 return;
714
715 while (len--)
716 get_byte(buf);
717}
718
719static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
f8433962
JA
720 unsigned long buffer, unsigned long size,
721 struct s5p_jpeg_ctx *ctx)
bb677f3a
AP
722{
723 int c, components, notfound;
f8433962 724 unsigned int height, width, word, subsampling = 0;
bb677f3a
AP
725 long length;
726 struct s5p_jpeg_buffer jpeg_buffer;
727
728 jpeg_buffer.size = size;
729 jpeg_buffer.data = buffer;
730 jpeg_buffer.curr = 0;
731
732 notfound = 1;
733 while (notfound) {
734 c = get_byte(&jpeg_buffer);
735 if (c == -1)
736 break;
737 if (c != 0xff)
738 continue;
739 do
740 c = get_byte(&jpeg_buffer);
741 while (c == 0xff);
742 if (c == -1)
743 break;
744 if (c == 0)
745 continue;
746 length = 0;
747 switch (c) {
748 /* SOF0: baseline JPEG */
749 case SOF0:
750 if (get_word_be(&jpeg_buffer, &word))
751 break;
752 if (get_byte(&jpeg_buffer) == -1)
753 break;
754 if (get_word_be(&jpeg_buffer, &height))
755 break;
756 if (get_word_be(&jpeg_buffer, &width))
757 break;
758 components = get_byte(&jpeg_buffer);
759 if (components == -1)
760 break;
761 notfound = 0;
762
f8433962
JA
763 if (components == 1) {
764 subsampling = 0x33;
765 } else {
766 skip(&jpeg_buffer, 1);
767 subsampling = get_byte(&jpeg_buffer);
768 skip(&jpeg_buffer, 1);
769 }
770
771 skip(&jpeg_buffer, components * 2);
bb677f3a
AP
772 break;
773
774 /* skip payload-less markers */
775 case RST ... RST + 7:
776 case SOI:
777 case EOI:
778 case TEM:
779 break;
780
781 /* skip uninteresting payload markers */
782 default:
783 if (get_word_be(&jpeg_buffer, &word))
784 break;
785 length = (long)word - 2;
786 skip(&jpeg_buffer, length);
787 break;
788 }
789 }
790 result->w = width;
791 result->h = height;
792 result->size = components;
f8433962
JA
793
794 switch (subsampling) {
795 case 0x11:
796 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
797 break;
798 case 0x21:
799 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
800 break;
801 case 0x22:
802 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
803 break;
804 case 0x33:
805 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
806 break;
807 default:
808 return false;
809 }
810
bb677f3a
AP
811 return !notfound;
812}
813
814static int s5p_jpeg_querycap(struct file *file, void *priv,
815 struct v4l2_capability *cap)
816{
275de24d 817 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
818
819 if (ctx->mode == S5P_JPEG_ENCODE) {
820 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
821 sizeof(cap->driver));
822 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
823 sizeof(cap->card));
824 } else {
825 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
826 sizeof(cap->driver));
827 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
828 sizeof(cap->card));
829 }
830 cap->bus_info[0] = 0;
f0476a83
SN
831 /*
832 * This is only a mem-to-mem video device. The capture and output
833 * device capability flags are left only for backward compatibility
834 * and are scheduled for removal.
835 */
836 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
837 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
bb677f3a
AP
838 return 0;
839}
840
80529ae5 841static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
bb677f3a
AP
842 struct v4l2_fmtdesc *f, u32 type)
843{
844 int i, num = 0;
845
846 for (i = 0; i < n; ++i) {
80529ae5 847 if (sjpeg_formats[i].flags & type) {
bb677f3a
AP
848 /* index-th format of type type found ? */
849 if (num == f->index)
850 break;
851 /* Correct type but haven't reached our index yet,
852 * just increment per-type index */
853 ++num;
854 }
855 }
856
857 /* Format not found */
858 if (i >= n)
859 return -EINVAL;
860
80529ae5
JA
861 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
862 f->pixelformat = sjpeg_formats[i].fourcc;
bb677f3a
AP
863
864 return 0;
865}
866
867static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
868 struct v4l2_fmtdesc *f)
869{
275de24d 870 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
871
872 if (ctx->mode == S5P_JPEG_ENCODE)
80529ae5
JA
873 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
874 SJPEG_FMT_FLAG_ENC_CAPTURE);
bb677f3a 875
80529ae5
JA
876 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
877 SJPEG_FMT_FLAG_DEC_CAPTURE);
bb677f3a
AP
878}
879
880static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
881 struct v4l2_fmtdesc *f)
882{
275de24d 883 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
884
885 if (ctx->mode == S5P_JPEG_ENCODE)
80529ae5
JA
886 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
887 SJPEG_FMT_FLAG_ENC_OUTPUT);
bb677f3a 888
80529ae5
JA
889 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
890 SJPEG_FMT_FLAG_DEC_OUTPUT);
bb677f3a
AP
891}
892
893static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
894 enum v4l2_buf_type type)
895{
896 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
897 return &ctx->out_q;
898 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
899 return &ctx->cap_q;
900
901 return NULL;
902}
903
904static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
905{
906 struct vb2_queue *vq;
907 struct s5p_jpeg_q_data *q_data = NULL;
908 struct v4l2_pix_format *pix = &f->fmt.pix;
275de24d 909 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
bb677f3a 910
718cf4a9 911 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
bb677f3a
AP
912 if (!vq)
913 return -EINVAL;
914
915 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
916 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
917 return -EINVAL;
918 q_data = get_q_data(ct, f->type);
919 BUG_ON(q_data == NULL);
920
921 pix->width = q_data->w;
922 pix->height = q_data->h;
923 pix->field = V4L2_FIELD_NONE;
924 pix->pixelformat = q_data->fmt->fourcc;
925 pix->bytesperline = 0;
926 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
927 u32 bpl = q_data->w;
928 if (q_data->fmt->colplanes == 1)
929 bpl = (bpl * q_data->fmt->depth) >> 3;
930 pix->bytesperline = bpl;
931 }
932 pix->sizeimage = q_data->size;
933
934 return 0;
935}
936
80529ae5
JA
937static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
938 u32 pixelformat, unsigned int fmt_type)
bb677f3a 939{
80529ae5 940 unsigned int k, fmt_flag, ver_flag;
bb677f3a 941
80529ae5
JA
942 if (ctx->mode == S5P_JPEG_ENCODE)
943 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
944 SJPEG_FMT_FLAG_ENC_OUTPUT :
945 SJPEG_FMT_FLAG_ENC_CAPTURE;
946 else
947 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
948 SJPEG_FMT_FLAG_DEC_OUTPUT :
949 SJPEG_FMT_FLAG_DEC_CAPTURE;
bb677f3a 950
80529ae5
JA
951 if (ctx->jpeg->variant->version == SJPEG_S5P)
952 ver_flag = SJPEG_FMT_FLAG_S5P;
953 else
954 ver_flag = SJPEG_FMT_FLAG_EXYNOS4;
955
956 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
957 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
958 if (fmt->fourcc == pixelformat &&
959 fmt->flags & fmt_flag &&
960 fmt->flags & ver_flag) {
bb677f3a 961 return fmt;
80529ae5 962 }
bb677f3a
AP
963 }
964
965 return NULL;
bb677f3a
AP
966}
967
968static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
969 unsigned int walign,
970 u32 *h, unsigned int hmin, unsigned int hmax,
971 unsigned int halign)
972{
973 int width, height, w_step, h_step;
974
975 width = *w;
976 height = *h;
977
978 w_step = 1 << walign;
979 h_step = 1 << halign;
980 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
981
982 if (*w < width && (*w + w_step) < wmax)
983 *w += w_step;
984 if (*h < height && (*h + h_step) < hmax)
985 *h += h_step;
986
987}
988
989static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
990 struct s5p_jpeg_ctx *ctx, int q_type)
991{
992 struct v4l2_pix_format *pix = &f->fmt.pix;
993
994 if (pix->field == V4L2_FIELD_ANY)
995 pix->field = V4L2_FIELD_NONE;
996 else if (pix->field != V4L2_FIELD_NONE)
997 return -EINVAL;
998
999 /* V4L2 specification suggests the driver corrects the format struct
1000 * if any of the dimensions is unsupported */
80529ae5 1001 if (q_type == FMT_TYPE_OUTPUT)
bb677f3a
AP
1002 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1003 S5P_JPEG_MAX_WIDTH, 0,
1004 &pix->height, S5P_JPEG_MIN_HEIGHT,
1005 S5P_JPEG_MAX_HEIGHT, 0);
1006 else
1007 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1008 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1009 &pix->height, S5P_JPEG_MIN_HEIGHT,
1010 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1011
1012 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1013 if (pix->sizeimage <= 0)
1014 pix->sizeimage = PAGE_SIZE;
1015 pix->bytesperline = 0;
1016 } else {
1017 u32 bpl = pix->bytesperline;
1018
1019 if (fmt->colplanes > 1 && bpl < pix->width)
1020 bpl = pix->width; /* planar */
1021
1022 if (fmt->colplanes == 1 && /* packed */
cc690904 1023 (bpl << 3) / fmt->depth < pix->width)
bb677f3a
AP
1024 bpl = (pix->width * fmt->depth) >> 3;
1025
1026 pix->bytesperline = bpl;
1027 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1028 }
1029
1030 return 0;
1031}
1032
1033static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1034 struct v4l2_format *f)
1035{
275de24d 1036 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
337777a4 1037 struct v4l2_pix_format *pix = &f->fmt.pix;
bb677f3a 1038 struct s5p_jpeg_fmt *fmt;
337777a4 1039 int ret;
bb677f3a 1040
80529ae5
JA
1041 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1042 FMT_TYPE_CAPTURE);
1043 if (!fmt) {
bb677f3a
AP
1044 v4l2_err(&ctx->jpeg->v4l2_dev,
1045 "Fourcc format (0x%08x) invalid.\n",
1046 f->fmt.pix.pixelformat);
1047 return -EINVAL;
1048 }
1049
337777a4
JA
1050 /*
1051 * The exynos4x12 device requires resulting YUV image
1052 * subsampling not to be lower than the input jpeg subsampling.
1053 * If this requirement is not met then downgrade the requested
1054 * capture format to the one with subsampling equal to the input jpeg.
1055 */
1056 if ((ctx->jpeg->variant->version != SJPEG_S5P) &&
1057 (ctx->mode == S5P_JPEG_DECODE) &&
1058 (fmt->flags & SJPEG_FMT_NON_RGB) &&
1059 (fmt->subsampling < ctx->subsampling)) {
1060 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1061 fmt->fourcc,
1062 &pix->pixelformat,
1063 ctx);
1064 if (ret < 0)
1065 pix->pixelformat = V4L2_PIX_FMT_GREY;
1066
1067 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1068 FMT_TYPE_CAPTURE);
1069 }
1070
80529ae5 1071 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
bb677f3a
AP
1072}
1073
1074static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1075 struct v4l2_format *f)
1076{
275de24d 1077 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a 1078 struct s5p_jpeg_fmt *fmt;
bb677f3a 1079
80529ae5
JA
1080 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1081 FMT_TYPE_OUTPUT);
1082 if (!fmt) {
bb677f3a
AP
1083 v4l2_err(&ctx->jpeg->v4l2_dev,
1084 "Fourcc format (0x%08x) invalid.\n",
1085 f->fmt.pix.pixelformat);
1086 return -EINVAL;
1087 }
1088
80529ae5 1089 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
bb677f3a
AP
1090}
1091
1092static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1093{
1094 struct vb2_queue *vq;
1095 struct s5p_jpeg_q_data *q_data = NULL;
1096 struct v4l2_pix_format *pix = &f->fmt.pix;
80529ae5 1097 unsigned int f_type;
bb677f3a 1098
718cf4a9 1099 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
bb677f3a
AP
1100 if (!vq)
1101 return -EINVAL;
1102
1103 q_data = get_q_data(ct, f->type);
1104 BUG_ON(q_data == NULL);
1105
1106 if (vb2_is_busy(vq)) {
1107 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1108 return -EBUSY;
1109 }
1110
80529ae5
JA
1111 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1112 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1113
1114 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
bb677f3a
AP
1115 q_data->w = pix->width;
1116 q_data->h = pix->height;
1117 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
1118 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1119 else
1120 q_data->size = pix->sizeimage;
1121
1122 return 0;
1123}
1124
1125static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1126 struct v4l2_format *f)
1127{
1128 int ret;
1129
1130 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1131 if (ret)
1132 return ret;
1133
275de24d 1134 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
bb677f3a
AP
1135}
1136
1137static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1138 struct v4l2_format *f)
1139{
1140 int ret;
1141
1142 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1143 if (ret)
1144 return ret;
1145
275de24d 1146 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
bb677f3a
AP
1147}
1148
9f3bd320 1149static int s5p_jpeg_g_selection(struct file *file, void *priv,
bb677f3a
AP
1150 struct v4l2_selection *s)
1151{
275de24d 1152 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
1153
1154 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
80529ae5
JA
1155 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1156 ctx->jpeg->variant->version != SJPEG_S5P)
bb677f3a
AP
1157 return -EINVAL;
1158
1159 /* For JPEG blob active == default == bounds */
1160 switch (s->target) {
c1334823 1161 case V4L2_SEL_TGT_CROP:
bb677f3a
AP
1162 case V4L2_SEL_TGT_CROP_BOUNDS:
1163 case V4L2_SEL_TGT_CROP_DEFAULT:
c1334823 1164 case V4L2_SEL_TGT_COMPOSE:
bb677f3a
AP
1165 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1166 s->r.width = ctx->out_q.w;
1167 s->r.height = ctx->out_q.h;
1168 break;
1169 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1170 case V4L2_SEL_TGT_COMPOSE_PADDED:
1171 s->r.width = ctx->cap_q.w;
1172 s->r.height = ctx->cap_q.h;
1173 break;
1174 default:
1175 return -EINVAL;
1176 }
1177 s->r.left = 0;
1178 s->r.top = 0;
1179 return 0;
1180}
1181
15f4bc3b
SN
1182/*
1183 * V4L2 controls
1184 */
1185
1186static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
bb677f3a 1187{
15f4bc3b
SN
1188 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1189 struct s5p_jpeg *jpeg = ctx->jpeg;
1190 unsigned long flags;
bb677f3a 1191
15f4bc3b
SN
1192 switch (ctrl->id) {
1193 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1194 spin_lock_irqsave(&jpeg->slock, flags);
bb677f3a 1195
15f4bc3b
SN
1196 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
1197 if (ctx->subsampling > 2)
1198 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1199 else
1200 ctrl->val = ctx->subsampling;
1201 spin_unlock_irqrestore(&jpeg->slock, flags);
1202 break;
1203 }
bb677f3a
AP
1204
1205 return 0;
1206}
1207
15f4bc3b 1208static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
bb677f3a 1209{
15f4bc3b
SN
1210 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1211 unsigned long flags;
bb677f3a 1212
15f4bc3b 1213 spin_lock_irqsave(&ctx->jpeg->slock, flags);
bb677f3a 1214
15f4bc3b
SN
1215 switch (ctrl->id) {
1216 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
78e5a3ce 1217 ctx->compr_quality = ctrl->val;
15f4bc3b
SN
1218 break;
1219 case V4L2_CID_JPEG_RESTART_INTERVAL:
1220 ctx->restart_interval = ctrl->val;
1221 break;
1222 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1223 ctx->subsampling = ctrl->val;
1224 break;
1225 }
1226
1227 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1228 return 0;
1229}
1230
1231static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1232 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1233 .s_ctrl = s5p_jpeg_s_ctrl,
1234};
1235
1236static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1237{
1238 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1239 struct v4l2_ctrl *ctrl;
088f8300 1240 int ret;
15f4bc3b
SN
1241
1242 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
bb677f3a 1243
15f4bc3b
SN
1244 if (ctx->mode == S5P_JPEG_ENCODE) {
1245 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1246 V4L2_CID_JPEG_COMPRESSION_QUALITY,
78e5a3ce 1247 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
15f4bc3b
SN
1248
1249 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1250 V4L2_CID_JPEG_RESTART_INTERVAL,
1251 0, 3, 0xffff, 0);
1252 mask = ~0x06; /* 422, 420 */
1253 }
1254
1255 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1256 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1257 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1258 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
bb677f3a 1259
088f8300
JA
1260 if (ctx->ctrl_handler.error) {
1261 ret = ctx->ctrl_handler.error;
1262 goto error_free;
1263 }
15f4bc3b
SN
1264
1265 if (ctx->mode == S5P_JPEG_DECODE)
1266 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1267 V4L2_CTRL_FLAG_READ_ONLY;
088f8300
JA
1268
1269 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1270 if (ret < 0)
1271 goto error_free;
1272
1273 return ret;
1274
1275error_free:
1276 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1277 return ret;
bb677f3a
AP
1278}
1279
1280static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1281 .vidioc_querycap = s5p_jpeg_querycap,
1282
1283 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
1284 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
1285
1286 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
1287 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
1288
1289 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
1290 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
1291
1292 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
1293 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
1294
718cf4a9
SN
1295 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1296 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1297 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1298 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
bb677f3a 1299
718cf4a9
SN
1300 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1301 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
bb677f3a
AP
1302
1303 .vidioc_g_selection = s5p_jpeg_g_selection,
bb677f3a
AP
1304};
1305
1306/*
1307 * ============================================================================
1308 * mem2mem callbacks
1309 * ============================================================================
1310 */
1311
1312static void s5p_jpeg_device_run(void *priv)
1313{
1314 struct s5p_jpeg_ctx *ctx = priv;
1315 struct s5p_jpeg *jpeg = ctx->jpeg;
1316 struct vb2_buffer *src_buf, *dst_buf;
b3c932a9
JA
1317 unsigned long src_addr, dst_addr, flags;
1318
1319 spin_lock_irqsave(&ctx->jpeg->slock, flags);
bb677f3a 1320
718cf4a9
SN
1321 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1322 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
bb677f3a
AP
1323 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1324 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1325
9f7b62d9
JA
1326 s5p_jpeg_reset(jpeg->regs);
1327 s5p_jpeg_poweron(jpeg->regs);
1328 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
bb677f3a
AP
1329 if (ctx->mode == S5P_JPEG_ENCODE) {
1330 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
9f7b62d9
JA
1331 s5p_jpeg_input_raw_mode(jpeg->regs,
1332 S5P_JPEG_RAW_IN_565);
bb677f3a 1333 else
9f7b62d9
JA
1334 s5p_jpeg_input_raw_mode(jpeg->regs,
1335 S5P_JPEG_RAW_IN_422);
1336 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1337 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1338 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1339 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1340 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1341 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
bb677f3a
AP
1342
1343 /* ultimately comes from sizeimage from userspace */
9f7b62d9 1344 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
bb677f3a
AP
1345
1346 /* JPEG RGB to YCbCr conversion matrix */
9f7b62d9
JA
1347 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1348 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1349 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1350 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1351 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1352 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1353 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1354 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1355 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
bb677f3a
AP
1356
1357 /*
1358 * JPEG IP allows storing 4 quantization tables
1359 * We fill table 0 for luma and table 1 for chroma
1360 */
31dc0ac0
JA
1361 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1362 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
bb677f3a 1363 /* use table 0 for Y */
9f7b62d9 1364 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
bb677f3a 1365 /* use table 1 for Cb and Cr*/
9f7b62d9
JA
1366 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1367 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
bb677f3a
AP
1368
1369 /* Y, Cb, Cr use Huffman table 0 */
9f7b62d9
JA
1370 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1371 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1372 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1373 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1374 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1375 s5p_jpeg_htbl_dc(jpeg->regs, 3);
fb6f8c02 1376 } else { /* S5P_JPEG_DECODE */
9f7b62d9
JA
1377 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1378 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1379 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
fb6f8c02 1380 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
9f7b62d9 1381 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
fb6f8c02 1382 else
9f7b62d9
JA
1383 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1384 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1385 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
bb677f3a 1386 }
15f4bc3b 1387
9f7b62d9 1388 s5p_jpeg_start(jpeg->regs);
b3c932a9
JA
1389
1390 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
bb677f3a
AP
1391}
1392
80529ae5
JA
1393static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1394{
1395 struct s5p_jpeg *jpeg = ctx->jpeg;
1396 struct s5p_jpeg_fmt *fmt;
1397 struct vb2_buffer *vb;
1398 struct s5p_jpeg_addr jpeg_addr;
1399 u32 pix_size, padding_bytes = 0;
1400
1401 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1402
1403 if (ctx->mode == S5P_JPEG_ENCODE) {
1404 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1405 fmt = ctx->out_q.fmt;
1406 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1407 padding_bytes = ctx->out_q.h;
1408 } else {
1409 fmt = ctx->cap_q.fmt;
1410 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1411 }
1412
1413 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1414
1415 if (fmt->colplanes == 2) {
1416 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1417 } else if (fmt->colplanes == 3) {
1418 jpeg_addr.cb = jpeg_addr.y + pix_size;
1419 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1420 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1421 else
1422 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1423 }
1424
1425 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1426}
1427
1428static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1429{
1430 struct s5p_jpeg *jpeg = ctx->jpeg;
1431 struct vb2_buffer *vb;
1432 unsigned int jpeg_addr = 0;
1433
1434 if (ctx->mode == S5P_JPEG_ENCODE)
1435 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1436 else
1437 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1438
1439 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1440 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1441}
1442
1443static void exynos4_jpeg_device_run(void *priv)
1444{
1445 struct s5p_jpeg_ctx *ctx = priv;
1446 struct s5p_jpeg *jpeg = ctx->jpeg;
1447 unsigned int bitstream_size;
1448 unsigned long flags;
1449
1450 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1451
1452 if (ctx->mode == S5P_JPEG_ENCODE) {
1453 exynos4_jpeg_sw_reset(jpeg->regs);
1454 exynos4_jpeg_set_interrupt(jpeg->regs);
1455 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1456
1457 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1458
1459 /*
1460 * JPEG IP allows storing 4 quantization tables
1461 * We fill table 0 for luma and table 1 for chroma
1462 */
1463 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1464 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1465
1466 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1467 ctx->compr_quality);
1468 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1469 ctx->cap_q.h);
1470
1471 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1472 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1473 exynos4_jpeg_set_img_addr(ctx);
1474 exynos4_jpeg_set_jpeg_addr(ctx);
1475 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1476 ctx->out_q.fmt->fourcc);
1477 } else {
1478 exynos4_jpeg_sw_reset(jpeg->regs);
1479 exynos4_jpeg_set_interrupt(jpeg->regs);
1480 exynos4_jpeg_set_img_addr(ctx);
1481 exynos4_jpeg_set_jpeg_addr(ctx);
1482 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1483
1484 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1485
1486 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1487 }
1488
1489 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1490
1491 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1492}
1493
bb677f3a
AP
1494static int s5p_jpeg_job_ready(void *priv)
1495{
1496 struct s5p_jpeg_ctx *ctx = priv;
1497
1498 if (ctx->mode == S5P_JPEG_DECODE)
1499 return ctx->hdr_parsed;
1500 return 1;
1501}
1502
1503static void s5p_jpeg_job_abort(void *priv)
1504{
1505}
1506
1507static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1508 .device_run = s5p_jpeg_device_run,
1509 .job_ready = s5p_jpeg_job_ready,
1510 .job_abort = s5p_jpeg_job_abort,
80529ae5
JA
1511}
1512;
1513static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1514 .device_run = exynos4_jpeg_device_run,
1515 .job_ready = s5p_jpeg_job_ready,
1516 .job_abort = s5p_jpeg_job_abort,
bb677f3a
AP
1517};
1518
1519/*
1520 * ============================================================================
1521 * Queue operations
1522 * ============================================================================
1523 */
1524
719c174e
MS
1525static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1526 const struct v4l2_format *fmt,
1527 unsigned int *nbuffers, unsigned int *nplanes,
1528 unsigned int sizes[], void *alloc_ctxs[])
bb677f3a
AP
1529{
1530 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1531 struct s5p_jpeg_q_data *q_data = NULL;
1532 unsigned int size, count = *nbuffers;
1533
1534 q_data = get_q_data(ctx, vq->type);
1535 BUG_ON(q_data == NULL);
1536
1537 size = q_data->size;
1538
1539 /*
1540 * header is parsed during decoding and parsed information stored
1541 * in the context so we do not allow another buffer to overwrite it
1542 */
1543 if (ctx->mode == S5P_JPEG_DECODE)
1544 count = 1;
1545
1546 *nbuffers = count;
1547 *nplanes = 1;
1548 sizes[0] = size;
1549 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1550
1551 return 0;
1552}
1553
1554static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1555{
1556 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1557 struct s5p_jpeg_q_data *q_data = NULL;
1558
1559 q_data = get_q_data(ctx, vb->vb2_queue->type);
1560 BUG_ON(q_data == NULL);
1561
1562 if (vb2_plane_size(vb, 0) < q_data->size) {
1563 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1564 __func__, vb2_plane_size(vb, 0),
1565 (long)q_data->size);
1566 return -EINVAL;
1567 }
1568
1569 vb2_set_plane_payload(vb, 0, q_data->size);
1570
1571 return 0;
1572}
1573
1574static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1575{
1576 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1577
1578 if (ctx->mode == S5P_JPEG_DECODE &&
1579 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1580 struct s5p_jpeg_q_data tmp, *q_data;
1581 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1582 (unsigned long)vb2_plane_vaddr(vb, 0),
1583 min((unsigned long)ctx->out_q.size,
f8433962 1584 vb2_get_plane_payload(vb, 0)), ctx);
bb677f3a
AP
1585 if (!ctx->hdr_parsed) {
1586 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1587 return;
1588 }
1589
1590 q_data = &ctx->out_q;
1591 q_data->w = tmp.w;
1592 q_data->h = tmp.h;
1593
1594 q_data = &ctx->cap_q;
1595 q_data->w = tmp.w;
1596 q_data->h = tmp.h;
bb677f3a 1597 }
bb677f3a 1598
718cf4a9 1599 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
bb677f3a
AP
1600}
1601
1602static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1603{
1604 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1605 int ret;
1606
1607 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1608
1609 return ret > 0 ? 0 : ret;
1610}
1611
1612static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1613{
1614 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1615
1616 pm_runtime_put(ctx->jpeg->dev);
1617
1618 return 0;
1619}
1620
1621static struct vb2_ops s5p_jpeg_qops = {
1622 .queue_setup = s5p_jpeg_queue_setup,
1623 .buf_prepare = s5p_jpeg_buf_prepare,
1624 .buf_queue = s5p_jpeg_buf_queue,
718cf4a9
SN
1625 .wait_prepare = vb2_ops_wait_prepare,
1626 .wait_finish = vb2_ops_wait_finish,
bb677f3a
AP
1627 .start_streaming = s5p_jpeg_start_streaming,
1628 .stop_streaming = s5p_jpeg_stop_streaming,
1629};
1630
1631static int queue_init(void *priv, struct vb2_queue *src_vq,
1632 struct vb2_queue *dst_vq)
1633{
1634 struct s5p_jpeg_ctx *ctx = priv;
1635 int ret;
1636
bb677f3a
AP
1637 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1638 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1639 src_vq->drv_priv = ctx;
1640 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1641 src_vq->ops = &s5p_jpeg_qops;
1642 src_vq->mem_ops = &vb2_dma_contig_memops;
aca326ae 1643 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
718cf4a9 1644 src_vq->lock = &ctx->jpeg->lock;
bb677f3a
AP
1645
1646 ret = vb2_queue_init(src_vq);
1647 if (ret)
1648 return ret;
1649
bb677f3a
AP
1650 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1651 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1652 dst_vq->drv_priv = ctx;
1653 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1654 dst_vq->ops = &s5p_jpeg_qops;
1655 dst_vq->mem_ops = &vb2_dma_contig_memops;
aca326ae 1656 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
718cf4a9 1657 dst_vq->lock = &ctx->jpeg->lock;
bb677f3a
AP
1658
1659 return vb2_queue_init(dst_vq);
1660}
1661
1662/*
1663 * ============================================================================
1664 * ISR
1665 * ============================================================================
1666 */
1667
1668static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1669{
1670 struct s5p_jpeg *jpeg = dev_id;
1671 struct s5p_jpeg_ctx *curr_ctx;
1672 struct vb2_buffer *src_buf, *dst_buf;
1673 unsigned long payload_size = 0;
1674 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1675 bool enc_jpeg_too_large = false;
1676 bool timer_elapsed = false;
1677 bool op_completed = false;
1678
15f4bc3b
SN
1679 spin_lock(&jpeg->slock);
1680
bb677f3a
AP
1681 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1682
718cf4a9
SN
1683 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1684 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
bb677f3a
AP
1685
1686 if (curr_ctx->mode == S5P_JPEG_ENCODE)
9f7b62d9
JA
1687 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1688 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1689 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
bb677f3a 1690 if (curr_ctx->mode == S5P_JPEG_DECODE)
9f7b62d9
JA
1691 op_completed = op_completed &&
1692 s5p_jpeg_stream_stat_ok(jpeg->regs);
bb677f3a
AP
1693
1694 if (enc_jpeg_too_large) {
1695 state = VB2_BUF_STATE_ERROR;
9f7b62d9 1696 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
bb677f3a
AP
1697 } else if (timer_elapsed) {
1698 state = VB2_BUF_STATE_ERROR;
9f7b62d9 1699 s5p_jpeg_clear_timer_stat(jpeg->regs);
bb677f3a
AP
1700 } else if (!op_completed) {
1701 state = VB2_BUF_STATE_ERROR;
1702 } else {
9f7b62d9 1703 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
bb677f3a
AP
1704 }
1705
aca326ae
KD
1706 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
1707 dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
1708
bb677f3a
AP
1709 v4l2_m2m_buf_done(src_buf, state);
1710 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1711 vb2_set_plane_payload(dst_buf, 0, payload_size);
1712 v4l2_m2m_buf_done(dst_buf, state);
718cf4a9 1713 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
bb677f3a 1714
9f7b62d9 1715 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
15f4bc3b 1716 spin_unlock(&jpeg->slock);
fb6f8c02 1717
9f7b62d9 1718 s5p_jpeg_clear_int(jpeg->regs);
bb677f3a
AP
1719
1720 return IRQ_HANDLED;
1721}
1722
80529ae5
JA
1723static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1724{
1725 unsigned int int_status;
1726 struct vb2_buffer *src_vb, *dst_vb;
1727 struct s5p_jpeg *jpeg = priv;
1728 struct s5p_jpeg_ctx *curr_ctx;
1729 unsigned long payload_size = 0;
1730
1731 spin_lock(&jpeg->slock);
1732
1733 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1734
1735 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1736 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1737
1738 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1739
1740 if (int_status) {
1741 switch (int_status & 0x1f) {
1742 case 0x1:
1743 jpeg->irq_ret = ERR_PROT;
1744 break;
1745 case 0x2:
1746 jpeg->irq_ret = OK_ENC_OR_DEC;
1747 break;
1748 case 0x4:
1749 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1750 break;
1751 case 0x8:
1752 jpeg->irq_ret = ERR_MULTI_SCAN;
1753 break;
1754 case 0x10:
1755 jpeg->irq_ret = ERR_FRAME;
1756 break;
1757 default:
1758 jpeg->irq_ret = ERR_UNKNOWN;
1759 break;
1760 }
1761 } else {
1762 jpeg->irq_ret = ERR_UNKNOWN;
1763 }
1764
1765 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1766 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1767 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1768 vb2_set_plane_payload(dst_vb, 0, payload_size);
1769 }
1770 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1771 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1772 } else {
1773 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1774 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1775 }
1776
1777 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1778 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1779
1780 spin_unlock(&jpeg->slock);
1781 return IRQ_HANDLED;
1782}
1783
1784static void *jpeg_get_drv_data(struct platform_device *pdev);
1785
bb677f3a
AP
1786/*
1787 * ============================================================================
1788 * Driver basic infrastructure
1789 * ============================================================================
1790 */
1791
1792static int s5p_jpeg_probe(struct platform_device *pdev)
1793{
1794 struct s5p_jpeg *jpeg;
1795 struct resource *res;
80529ae5 1796 struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
bb677f3a
AP
1797 int ret;
1798
80529ae5
JA
1799 if (!pdev->dev.of_node)
1800 return -ENODEV;
1801
bb677f3a 1802 /* JPEG IP abstraction struct */
5b58b954 1803 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
bb677f3a
AP
1804 if (!jpeg)
1805 return -ENOMEM;
1806
80529ae5
JA
1807 jpeg->variant = jpeg_get_drv_data(pdev);
1808
bb677f3a 1809 mutex_init(&jpeg->lock);
15f4bc3b 1810 spin_lock_init(&jpeg->slock);
bb677f3a
AP
1811 jpeg->dev = &pdev->dev;
1812
1813 /* memory-mapped registers */
1814 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bb677f3a 1815
f23999ec
TR
1816 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
1817 if (IS_ERR(jpeg->regs))
1818 return PTR_ERR(jpeg->regs);
bb677f3a 1819
bb677f3a
AP
1820 /* interrupt service routine registration */
1821 jpeg->irq = ret = platform_get_irq(pdev, 0);
1822 if (ret < 0) {
1823 dev_err(&pdev->dev, "cannot find IRQ\n");
5b58b954 1824 return ret;
bb677f3a
AP
1825 }
1826
80529ae5
JA
1827 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1828 0, dev_name(&pdev->dev), jpeg);
bb677f3a
AP
1829 if (ret) {
1830 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
5b58b954 1831 return ret;
bb677f3a
AP
1832 }
1833
1834 /* clocks */
1835 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1836 if (IS_ERR(jpeg->clk)) {
1837 dev_err(&pdev->dev, "cannot get clock\n");
1838 ret = PTR_ERR(jpeg->clk);
5b58b954 1839 return ret;
bb677f3a
AP
1840 }
1841 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
bb677f3a
AP
1842
1843 /* v4l2 device */
1844 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1845 if (ret) {
1846 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1847 goto clk_get_rollback;
1848 }
1849
80529ae5
JA
1850 if (jpeg->variant->version == SJPEG_S5P)
1851 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1852 else
1853 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1854
bb677f3a 1855 /* mem2mem device */
80529ae5 1856 jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
bb677f3a
AP
1857 if (IS_ERR(jpeg->m2m_dev)) {
1858 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1859 ret = PTR_ERR(jpeg->m2m_dev);
1860 goto device_register_rollback;
1861 }
1862
1863 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1864 if (IS_ERR(jpeg->alloc_ctx)) {
1865 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1866 ret = PTR_ERR(jpeg->alloc_ctx);
1867 goto m2m_init_rollback;
1868 }
1869
1870 /* JPEG encoder /dev/videoX node */
1871 jpeg->vfd_encoder = video_device_alloc();
1872 if (!jpeg->vfd_encoder) {
1873 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1874 ret = -ENOMEM;
1875 goto vb2_allocator_rollback;
1876 }
baaf046d
SWK
1877 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1878 "%s-enc", S5P_JPEG_M2M_NAME);
bb677f3a
AP
1879 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1880 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1881 jpeg->vfd_encoder->minor = -1;
1882 jpeg->vfd_encoder->release = video_device_release;
1883 jpeg->vfd_encoder->lock = &jpeg->lock;
1884 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
954f340f 1885 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
bb677f3a
AP
1886
1887 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1888 if (ret) {
1889 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1890 goto enc_vdev_alloc_rollback;
1891 }
1892
1893 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1894 v4l2_info(&jpeg->v4l2_dev,
1895 "encoder device registered as /dev/video%d\n",
1896 jpeg->vfd_encoder->num);
1897
1898 /* JPEG decoder /dev/videoX node */
1899 jpeg->vfd_decoder = video_device_alloc();
1900 if (!jpeg->vfd_decoder) {
1901 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1902 ret = -ENOMEM;
1903 goto enc_vdev_register_rollback;
1904 }
baaf046d
SWK
1905 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1906 "%s-dec", S5P_JPEG_M2M_NAME);
bb677f3a
AP
1907 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1908 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1909 jpeg->vfd_decoder->minor = -1;
1910 jpeg->vfd_decoder->release = video_device_release;
1911 jpeg->vfd_decoder->lock = &jpeg->lock;
1912 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
7f7d8fe2 1913 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
bb677f3a
AP
1914
1915 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1916 if (ret) {
1917 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1918 goto dec_vdev_alloc_rollback;
1919 }
1920
1921 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1922 v4l2_info(&jpeg->v4l2_dev,
1923 "decoder device registered as /dev/video%d\n",
1924 jpeg->vfd_decoder->num);
1925
1926 /* final statements & power management */
1927 platform_set_drvdata(pdev, jpeg);
1928
1929 pm_runtime_enable(&pdev->dev);
1930
1931 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1932
1933 return 0;
1934
1935dec_vdev_alloc_rollback:
1936 video_device_release(jpeg->vfd_decoder);
1937
1938enc_vdev_register_rollback:
1939 video_unregister_device(jpeg->vfd_encoder);
1940
1941enc_vdev_alloc_rollback:
1942 video_device_release(jpeg->vfd_encoder);
1943
1944vb2_allocator_rollback:
1945 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1946
1947m2m_init_rollback:
1948 v4l2_m2m_release(jpeg->m2m_dev);
1949
1950device_register_rollback:
1951 v4l2_device_unregister(&jpeg->v4l2_dev);
1952
1953clk_get_rollback:
bb677f3a
AP
1954 clk_put(jpeg->clk);
1955
bb677f3a
AP
1956 return ret;
1957}
1958
1959static int s5p_jpeg_remove(struct platform_device *pdev)
1960{
1961 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
1962
1963 pm_runtime_disable(jpeg->dev);
1964
1965 video_unregister_device(jpeg->vfd_decoder);
1966 video_device_release(jpeg->vfd_decoder);
1967 video_unregister_device(jpeg->vfd_encoder);
1968 video_device_release(jpeg->vfd_encoder);
1969 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1970 v4l2_m2m_release(jpeg->m2m_dev);
1971 v4l2_device_unregister(&jpeg->v4l2_dev);
1972
f1347132
JA
1973 if (!pm_runtime_status_suspended(&pdev->dev))
1974 clk_disable_unprepare(jpeg->clk);
1975
bb677f3a
AP
1976 clk_put(jpeg->clk);
1977
bb677f3a
AP
1978 return 0;
1979}
1980
1981static int s5p_jpeg_runtime_suspend(struct device *dev)
1982{
f1347132
JA
1983 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1984
1985 clk_disable_unprepare(jpeg->clk);
1986
bb677f3a
AP
1987 return 0;
1988}
1989
1990static int s5p_jpeg_runtime_resume(struct device *dev)
1991{
1992 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
b3c932a9 1993 unsigned long flags;
f1347132
JA
1994 int ret;
1995
1996 ret = clk_prepare_enable(jpeg->clk);
1997 if (ret < 0)
1998 return ret;
31dc0ac0 1999
b3c932a9
JA
2000 spin_lock_irqsave(&jpeg->slock, flags);
2001
bb677f3a
AP
2002 /*
2003 * JPEG IP allows storing two Huffman tables for each component
80529ae5
JA
2004 * We fill table 0 for each component and do this here only
2005 * for S5PC210 device as Exynos4x12 requires programming its
2006 * Huffman tables each time the encoding process is initialized.
bb677f3a 2007 */
80529ae5
JA
2008 if (jpeg->variant->version == SJPEG_S5P) {
2009 s5p_jpeg_set_hdctbl(jpeg->regs);
2010 s5p_jpeg_set_hdctblg(jpeg->regs);
2011 s5p_jpeg_set_hactbl(jpeg->regs);
2012 s5p_jpeg_set_hactblg(jpeg->regs);
2013 }
31dc0ac0 2014
b3c932a9
JA
2015 spin_unlock_irqrestore(&jpeg->slock, flags);
2016
bb677f3a
AP
2017 return 0;
2018}
2019
f1347132
JA
2020static int s5p_jpeg_suspend(struct device *dev)
2021{
2022 if (pm_runtime_suspended(dev))
2023 return 0;
2024
2025 return s5p_jpeg_runtime_suspend(dev);
2026}
2027
2028static int s5p_jpeg_resume(struct device *dev)
2029{
2030 if (pm_runtime_suspended(dev))
2031 return 0;
2032
2033 return s5p_jpeg_runtime_resume(dev);
2034}
2035
bb677f3a 2036static const struct dev_pm_ops s5p_jpeg_pm_ops = {
f1347132
JA
2037 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2038 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
bb677f3a
AP
2039};
2040
f7074ab3 2041#ifdef CONFIG_OF
80529ae5
JA
2042static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2043 .version = SJPEG_S5P,
2044 .jpeg_irq = s5p_jpeg_irq,
f7074ab3 2045};
80529ae5
JA
2046
2047static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2048 .version = SJPEG_EXYNOS4,
2049 .jpeg_irq = exynos4_jpeg_irq,
2050};
2051
2052static const struct of_device_id samsung_jpeg_match[] = {
2053 {
2054 .compatible = "samsung,s5pv210-jpeg",
2055 .data = &s5p_jpeg_drvdata,
2056 }, {
2057 .compatible = "samsung,exynos4210-jpeg",
2058 .data = &s5p_jpeg_drvdata,
2059 }, {
2060 .compatible = "samsung,exynos4212-jpeg",
2061 .data = &exynos4_jpeg_drvdata,
2062 },
2063 {},
2064};
2065
2066MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2067
2068static void *jpeg_get_drv_data(struct platform_device *pdev)
2069{
2070 struct s5p_jpeg_variant *driver_data = NULL;
2071 const struct of_device_id *match;
2072
2073 match = of_match_node(of_match_ptr(samsung_jpeg_match),
2074 pdev->dev.of_node);
2075 if (match)
2076 driver_data = (struct s5p_jpeg_variant *)match->data;
2077
2078 return driver_data;
2079}
f7074ab3
SN
2080#endif
2081
bb677f3a
AP
2082static struct platform_driver s5p_jpeg_driver = {
2083 .probe = s5p_jpeg_probe,
2084 .remove = s5p_jpeg_remove,
2085 .driver = {
80529ae5
JA
2086 .of_match_table = of_match_ptr(samsung_jpeg_match),
2087 .owner = THIS_MODULE,
2088 .name = S5P_JPEG_M2M_NAME,
2089 .pm = &s5p_jpeg_pm_ops,
bb677f3a
AP
2090 },
2091};
2092
87e94294 2093module_platform_driver(s5p_jpeg_driver);
bb677f3a
AP
2094
2095MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
80529ae5 2096MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
bb677f3a
AP
2097MODULE_DESCRIPTION("Samsung JPEG codec driver");
2098MODULE_LICENSE("GPL");