1 /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
3 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
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.
14 #include <linux/clk.h>
15 #include <linux/err.h>
16 #include <linux/gfp.h>
17 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/module.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>
32 #include "jpeg-core.h"
33 #include "jpeg-hw-s5p.h"
34 #include "jpeg-hw-exynos4.h"
35 #include "jpeg-regs.h"
37 static struct s5p_jpeg_fmt sjpeg_formats[] = {
40 .fourcc = V4L2_PIX_FMT_JPEG,
41 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
42 SJPEG_FMT_FLAG_DEC_OUTPUT |
44 SJPEG_FMT_FLAG_EXYNOS4,
47 .name = "YUV 4:2:2 packed, YCbYCr",
48 .fourcc = V4L2_PIX_FMT_YUYV,
53 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
54 SJPEG_FMT_FLAG_DEC_CAPTURE |
57 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
60 .name = "YUV 4:2:2 packed, YCbYCr",
61 .fourcc = V4L2_PIX_FMT_YUYV,
66 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
67 SJPEG_FMT_FLAG_DEC_CAPTURE |
68 SJPEG_FMT_FLAG_EXYNOS4 |
70 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
73 .name = "YUV 4:2:2 packed, YCrYCb",
74 .fourcc = V4L2_PIX_FMT_YVYU,
79 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
80 SJPEG_FMT_FLAG_DEC_CAPTURE |
81 SJPEG_FMT_FLAG_EXYNOS4 |
83 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
87 .fourcc = V4L2_PIX_FMT_RGB565,
92 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
93 SJPEG_FMT_FLAG_DEC_CAPTURE |
94 SJPEG_FMT_FLAG_EXYNOS4 |
96 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
100 .fourcc = V4L2_PIX_FMT_RGB565,
105 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
108 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
111 .name = "ARGB8888, 32 bpp",
112 .fourcc = V4L2_PIX_FMT_RGB32,
117 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
118 SJPEG_FMT_FLAG_DEC_CAPTURE |
119 SJPEG_FMT_FLAG_EXYNOS4 |
121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
124 .name = "YUV 4:4:4 planar, Y/CbCr",
125 .fourcc = V4L2_PIX_FMT_NV24,
130 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
131 SJPEG_FMT_FLAG_DEC_CAPTURE |
132 SJPEG_FMT_FLAG_EXYNOS4 |
134 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
137 .name = "YUV 4:4:4 planar, Y/CrCb",
138 .fourcc = V4L2_PIX_FMT_NV42,
143 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
144 SJPEG_FMT_FLAG_DEC_CAPTURE |
145 SJPEG_FMT_FLAG_EXYNOS4 |
147 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
150 .name = "YUV 4:2:2 planar, Y/CrCb",
151 .fourcc = V4L2_PIX_FMT_NV61,
156 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
157 SJPEG_FMT_FLAG_DEC_CAPTURE |
158 SJPEG_FMT_FLAG_EXYNOS4 |
160 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
163 .name = "YUV 4:2:2 planar, Y/CbCr",
164 .fourcc = V4L2_PIX_FMT_NV16,
169 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
170 SJPEG_FMT_FLAG_DEC_CAPTURE |
171 SJPEG_FMT_FLAG_EXYNOS4 |
173 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
176 .name = "YUV 4:2:0 planar, Y/CbCr",
177 .fourcc = V4L2_PIX_FMT_NV12,
182 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
183 SJPEG_FMT_FLAG_DEC_CAPTURE |
184 SJPEG_FMT_FLAG_EXYNOS4 |
186 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
189 .name = "YUV 4:2:0 planar, Y/CbCr",
190 .fourcc = V4L2_PIX_FMT_NV12,
195 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
196 SJPEG_FMT_FLAG_DEC_CAPTURE |
199 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
202 .name = "YUV 4:2:0 planar, Y/CrCb",
203 .fourcc = V4L2_PIX_FMT_NV21,
208 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
209 SJPEG_FMT_FLAG_DEC_CAPTURE |
210 SJPEG_FMT_FLAG_EXYNOS4 |
212 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
215 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
216 .fourcc = V4L2_PIX_FMT_YUV420,
221 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
222 SJPEG_FMT_FLAG_DEC_CAPTURE |
223 SJPEG_FMT_FLAG_EXYNOS4 |
225 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
229 .fourcc = V4L2_PIX_FMT_GREY,
232 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
233 SJPEG_FMT_FLAG_DEC_CAPTURE |
234 SJPEG_FMT_FLAG_EXYNOS4 |
236 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
239 #define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
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
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
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
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
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
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
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
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
327 static const unsigned char hdctbl0[16] = {
328 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
331 static const unsigned char hdctblg0[12] = {
332 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
334 static const unsigned char hactbl0[16] = {
335 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
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,
361 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
363 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
366 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
368 return container_of(fh, struct s5p_jpeg_ctx, fh);
371 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
372 const unsigned char *qtbl,
373 unsigned long tab, int len)
377 for (i = 0; i < len; i++)
378 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
381 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
383 /* this driver fills quantisation table 0 with data for luma */
384 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
385 S5P_JPG_QTBL_CONTENT(0),
386 ARRAY_SIZE(qtbl_luminance[quality]));
389 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
391 /* this driver fills quantisation table 1 with data for chroma */
392 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
393 S5P_JPG_QTBL_CONTENT(1),
394 ARRAY_SIZE(qtbl_chrominance[quality]));
397 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
398 const unsigned char *htbl,
399 unsigned long tab, int len)
403 for (i = 0; i < len; i++)
404 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
407 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
409 /* this driver fills table 0 for this component */
410 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
411 ARRAY_SIZE(hdctbl0));
414 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
416 /* this driver fills table 0 for this component */
417 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
418 ARRAY_SIZE(hdctblg0));
421 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
423 /* this driver fills table 0 for this component */
424 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
425 ARRAY_SIZE(hactbl0));
428 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
430 /* this driver fills table 0 for this component */
431 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
432 ARRAY_SIZE(hactblg0));
435 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
436 const unsigned char *tbl,
437 unsigned long tab, int len)
442 for (i = 0; i < len; i += 4) {
447 writel(dword, regs + tab + i);
451 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
453 /* this driver fills quantisation table 0 with data for luma */
454 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
455 EXYNOS4_QTBL_CONTENT(0),
456 ARRAY_SIZE(qtbl_luminance[quality]));
459 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
461 /* this driver fills quantisation table 1 with data for chroma */
462 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
463 EXYNOS4_QTBL_CONTENT(1),
464 ARRAY_SIZE(qtbl_chrominance[quality]));
467 void exynos4_jpeg_set_huff_tbl(void __iomem *base)
469 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
470 ARRAY_SIZE(hdctbl0));
471 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
472 ARRAY_SIZE(hdctbl0));
473 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
474 ARRAY_SIZE(hdctblg0));
475 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
476 ARRAY_SIZE(hdctblg0));
477 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
478 ARRAY_SIZE(hactbl0));
479 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
480 ARRAY_SIZE(hactbl0));
481 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
482 ARRAY_SIZE(hactblg0));
483 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
484 ARRAY_SIZE(hactblg0));
488 * ============================================================================
489 * Device file operations
490 * ============================================================================
493 static int queue_init(void *priv, struct vb2_queue *src_vq,
494 struct vb2_queue *dst_vq);
495 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
496 __u32 pixelformat, unsigned int fmt_type);
497 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
499 static int s5p_jpeg_open(struct file *file)
501 struct s5p_jpeg *jpeg = video_drvdata(file);
502 struct video_device *vfd = video_devdata(file);
503 struct s5p_jpeg_ctx *ctx;
504 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
507 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
511 if (mutex_lock_interruptible(&jpeg->lock)) {
516 v4l2_fh_init(&ctx->fh, vfd);
517 /* Use separate control handler per file handle */
518 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
519 file->private_data = &ctx->fh;
520 v4l2_fh_add(&ctx->fh);
523 if (vfd == jpeg->vfd_encoder) {
524 ctx->mode = S5P_JPEG_ENCODE;
525 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
527 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
530 ctx->mode = S5P_JPEG_DECODE;
531 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
533 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
537 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
538 if (IS_ERR(ctx->fh.m2m_ctx)) {
539 ret = PTR_ERR(ctx->fh.m2m_ctx);
543 ctx->out_q.fmt = out_fmt;
544 ctx->cap_q.fmt = cap_fmt;
546 ret = s5p_jpeg_controls_create(ctx);
550 mutex_unlock(&jpeg->lock);
554 v4l2_fh_del(&ctx->fh);
555 v4l2_fh_exit(&ctx->fh);
556 mutex_unlock(&jpeg->lock);
562 static int s5p_jpeg_release(struct file *file)
564 struct s5p_jpeg *jpeg = video_drvdata(file);
565 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
567 mutex_lock(&jpeg->lock);
568 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
569 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
570 v4l2_fh_del(&ctx->fh);
571 v4l2_fh_exit(&ctx->fh);
573 mutex_unlock(&jpeg->lock);
578 static const struct v4l2_file_operations s5p_jpeg_fops = {
579 .owner = THIS_MODULE,
580 .open = s5p_jpeg_open,
581 .release = s5p_jpeg_release,
582 .poll = v4l2_m2m_fop_poll,
583 .unlocked_ioctl = video_ioctl2,
584 .mmap = v4l2_m2m_fop_mmap,
588 * ============================================================================
589 * video ioctl operations
590 * ============================================================================
593 static int get_byte(struct s5p_jpeg_buffer *buf)
595 if (buf->curr >= buf->size)
598 return ((unsigned char *)buf->data)[buf->curr++];
601 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
606 byte = get_byte(buf);
610 byte = get_byte(buf);
613 *word = (unsigned int)byte | temp;
617 static void skip(struct s5p_jpeg_buffer *buf, long len)
626 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
627 unsigned long buffer, unsigned long size,
628 struct s5p_jpeg_ctx *ctx)
630 int c, components, notfound;
631 unsigned int height, width, word, subsampling = 0;
633 struct s5p_jpeg_buffer jpeg_buffer;
635 jpeg_buffer.size = size;
636 jpeg_buffer.data = buffer;
637 jpeg_buffer.curr = 0;
641 c = get_byte(&jpeg_buffer);
647 c = get_byte(&jpeg_buffer);
655 /* SOF0: baseline JPEG */
657 if (get_word_be(&jpeg_buffer, &word))
659 if (get_byte(&jpeg_buffer) == -1)
661 if (get_word_be(&jpeg_buffer, &height))
663 if (get_word_be(&jpeg_buffer, &width))
665 components = get_byte(&jpeg_buffer);
666 if (components == -1)
670 if (components == 1) {
673 skip(&jpeg_buffer, 1);
674 subsampling = get_byte(&jpeg_buffer);
675 skip(&jpeg_buffer, 1);
678 skip(&jpeg_buffer, components * 2);
681 /* skip payload-less markers */
682 case RST ... RST + 7:
688 /* skip uninteresting payload markers */
690 if (get_word_be(&jpeg_buffer, &word))
692 length = (long)word - 2;
693 skip(&jpeg_buffer, length);
699 result->size = components;
701 switch (subsampling) {
703 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
706 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
709 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
712 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
721 static int s5p_jpeg_querycap(struct file *file, void *priv,
722 struct v4l2_capability *cap)
724 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
726 if (ctx->mode == S5P_JPEG_ENCODE) {
727 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
728 sizeof(cap->driver));
729 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
732 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
733 sizeof(cap->driver));
734 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
737 cap->bus_info[0] = 0;
739 * This is only a mem-to-mem video device. The capture and output
740 * device capability flags are left only for backward compatibility
741 * and are scheduled for removal.
743 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
744 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
748 static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
749 struct v4l2_fmtdesc *f, u32 type)
753 for (i = 0; i < n; ++i) {
754 if (sjpeg_formats[i].flags & type) {
755 /* index-th format of type type found ? */
758 /* Correct type but haven't reached our index yet,
759 * just increment per-type index */
764 /* Format not found */
768 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
769 f->pixelformat = sjpeg_formats[i].fourcc;
774 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
775 struct v4l2_fmtdesc *f)
777 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
779 if (ctx->mode == S5P_JPEG_ENCODE)
780 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
781 SJPEG_FMT_FLAG_ENC_CAPTURE);
783 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
784 SJPEG_FMT_FLAG_DEC_CAPTURE);
787 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
788 struct v4l2_fmtdesc *f)
790 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
792 if (ctx->mode == S5P_JPEG_ENCODE)
793 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
794 SJPEG_FMT_FLAG_ENC_OUTPUT);
796 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
797 SJPEG_FMT_FLAG_DEC_OUTPUT);
800 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
801 enum v4l2_buf_type type)
803 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
805 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
811 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
813 struct vb2_queue *vq;
814 struct s5p_jpeg_q_data *q_data = NULL;
815 struct v4l2_pix_format *pix = &f->fmt.pix;
816 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
818 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
822 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
823 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
825 q_data = get_q_data(ct, f->type);
826 BUG_ON(q_data == NULL);
828 pix->width = q_data->w;
829 pix->height = q_data->h;
830 pix->field = V4L2_FIELD_NONE;
831 pix->pixelformat = q_data->fmt->fourcc;
832 pix->bytesperline = 0;
833 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
835 if (q_data->fmt->colplanes == 1)
836 bpl = (bpl * q_data->fmt->depth) >> 3;
837 pix->bytesperline = bpl;
839 pix->sizeimage = q_data->size;
844 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
845 u32 pixelformat, unsigned int fmt_type)
847 unsigned int k, fmt_flag, ver_flag;
849 if (ctx->mode == S5P_JPEG_ENCODE)
850 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
851 SJPEG_FMT_FLAG_ENC_OUTPUT :
852 SJPEG_FMT_FLAG_ENC_CAPTURE;
854 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
855 SJPEG_FMT_FLAG_DEC_OUTPUT :
856 SJPEG_FMT_FLAG_DEC_CAPTURE;
858 if (ctx->jpeg->variant->version == SJPEG_S5P)
859 ver_flag = SJPEG_FMT_FLAG_S5P;
861 ver_flag = SJPEG_FMT_FLAG_EXYNOS4;
863 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
864 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
865 if (fmt->fourcc == pixelformat &&
866 fmt->flags & fmt_flag &&
867 fmt->flags & ver_flag) {
875 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
877 u32 *h, unsigned int hmin, unsigned int hmax,
880 int width, height, w_step, h_step;
885 w_step = 1 << walign;
886 h_step = 1 << halign;
887 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
889 if (*w < width && (*w + w_step) < wmax)
891 if (*h < height && (*h + h_step) < hmax)
896 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
897 struct s5p_jpeg_ctx *ctx, int q_type)
899 struct v4l2_pix_format *pix = &f->fmt.pix;
901 if (pix->field == V4L2_FIELD_ANY)
902 pix->field = V4L2_FIELD_NONE;
903 else if (pix->field != V4L2_FIELD_NONE)
906 /* V4L2 specification suggests the driver corrects the format struct
907 * if any of the dimensions is unsupported */
908 if (q_type == FMT_TYPE_OUTPUT)
909 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
910 S5P_JPEG_MAX_WIDTH, 0,
911 &pix->height, S5P_JPEG_MIN_HEIGHT,
912 S5P_JPEG_MAX_HEIGHT, 0);
914 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
915 S5P_JPEG_MAX_WIDTH, fmt->h_align,
916 &pix->height, S5P_JPEG_MIN_HEIGHT,
917 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
919 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
920 if (pix->sizeimage <= 0)
921 pix->sizeimage = PAGE_SIZE;
922 pix->bytesperline = 0;
924 u32 bpl = pix->bytesperline;
926 if (fmt->colplanes > 1 && bpl < pix->width)
927 bpl = pix->width; /* planar */
929 if (fmt->colplanes == 1 && /* packed */
930 (bpl << 3) / fmt->depth < pix->width)
931 bpl = (pix->width * fmt->depth) >> 3;
933 pix->bytesperline = bpl;
934 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
940 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
941 struct v4l2_format *f)
943 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
944 struct s5p_jpeg_fmt *fmt;
946 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
949 v4l2_err(&ctx->jpeg->v4l2_dev,
950 "Fourcc format (0x%08x) invalid.\n",
951 f->fmt.pix.pixelformat);
955 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
958 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
959 struct v4l2_format *f)
961 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
962 struct s5p_jpeg_fmt *fmt;
964 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
967 v4l2_err(&ctx->jpeg->v4l2_dev,
968 "Fourcc format (0x%08x) invalid.\n",
969 f->fmt.pix.pixelformat);
973 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
976 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
978 struct vb2_queue *vq;
979 struct s5p_jpeg_q_data *q_data = NULL;
980 struct v4l2_pix_format *pix = &f->fmt.pix;
983 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
987 q_data = get_q_data(ct, f->type);
988 BUG_ON(q_data == NULL);
990 if (vb2_is_busy(vq)) {
991 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
995 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
996 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
998 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
999 q_data->w = pix->width;
1000 q_data->h = pix->height;
1001 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
1002 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1004 q_data->size = pix->sizeimage;
1009 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1010 struct v4l2_format *f)
1014 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1018 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1021 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1022 struct v4l2_format *f)
1026 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1030 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1033 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1034 struct v4l2_selection *s)
1036 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1038 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1039 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1040 ctx->jpeg->variant->version != SJPEG_S5P)
1043 /* For JPEG blob active == default == bounds */
1044 switch (s->target) {
1045 case V4L2_SEL_TGT_CROP:
1046 case V4L2_SEL_TGT_CROP_BOUNDS:
1047 case V4L2_SEL_TGT_CROP_DEFAULT:
1048 case V4L2_SEL_TGT_COMPOSE:
1049 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1050 s->r.width = ctx->out_q.w;
1051 s->r.height = ctx->out_q.h;
1053 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1054 case V4L2_SEL_TGT_COMPOSE_PADDED:
1055 s->r.width = ctx->cap_q.w;
1056 s->r.height = ctx->cap_q.h;
1070 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1072 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1073 struct s5p_jpeg *jpeg = ctx->jpeg;
1074 unsigned long flags;
1077 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1078 spin_lock_irqsave(&jpeg->slock, flags);
1080 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
1081 if (ctx->subsampling > 2)
1082 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1084 ctrl->val = ctx->subsampling;
1085 spin_unlock_irqrestore(&jpeg->slock, flags);
1092 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1094 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1095 unsigned long flags;
1097 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1100 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1101 ctx->compr_quality = ctrl->val;
1103 case V4L2_CID_JPEG_RESTART_INTERVAL:
1104 ctx->restart_interval = ctrl->val;
1106 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1107 ctx->subsampling = ctrl->val;
1111 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1115 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1116 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1117 .s_ctrl = s5p_jpeg_s_ctrl,
1120 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1122 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1123 struct v4l2_ctrl *ctrl;
1126 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1128 if (ctx->mode == S5P_JPEG_ENCODE) {
1129 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1130 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1131 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1133 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1134 V4L2_CID_JPEG_RESTART_INTERVAL,
1136 mask = ~0x06; /* 422, 420 */
1139 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1140 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1141 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1142 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1144 if (ctx->ctrl_handler.error) {
1145 ret = ctx->ctrl_handler.error;
1149 if (ctx->mode == S5P_JPEG_DECODE)
1150 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1151 V4L2_CTRL_FLAG_READ_ONLY;
1153 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1160 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1164 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1165 .vidioc_querycap = s5p_jpeg_querycap,
1167 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
1168 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
1170 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
1171 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
1173 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
1174 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
1176 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
1177 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
1179 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1180 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1181 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1182 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1184 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1185 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1187 .vidioc_g_selection = s5p_jpeg_g_selection,
1191 * ============================================================================
1193 * ============================================================================
1196 static void s5p_jpeg_device_run(void *priv)
1198 struct s5p_jpeg_ctx *ctx = priv;
1199 struct s5p_jpeg *jpeg = ctx->jpeg;
1200 struct vb2_buffer *src_buf, *dst_buf;
1201 unsigned long src_addr, dst_addr, flags;
1203 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1205 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1206 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1207 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1208 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1210 s5p_jpeg_reset(jpeg->regs);
1211 s5p_jpeg_poweron(jpeg->regs);
1212 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1213 if (ctx->mode == S5P_JPEG_ENCODE) {
1214 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1215 s5p_jpeg_input_raw_mode(jpeg->regs,
1216 S5P_JPEG_RAW_IN_565);
1218 s5p_jpeg_input_raw_mode(jpeg->regs,
1219 S5P_JPEG_RAW_IN_422);
1220 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1221 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1222 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1223 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1224 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1225 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1227 /* ultimately comes from sizeimage from userspace */
1228 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1230 /* JPEG RGB to YCbCr conversion matrix */
1231 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1232 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1233 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1234 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1235 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1236 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1237 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1238 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1239 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1242 * JPEG IP allows storing 4 quantization tables
1243 * We fill table 0 for luma and table 1 for chroma
1245 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1246 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1247 /* use table 0 for Y */
1248 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1249 /* use table 1 for Cb and Cr*/
1250 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1251 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1253 /* Y, Cb, Cr use Huffman table 0 */
1254 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1255 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1256 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1257 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1258 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1259 s5p_jpeg_htbl_dc(jpeg->regs, 3);
1260 } else { /* S5P_JPEG_DECODE */
1261 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1262 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1263 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1264 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1265 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1267 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1268 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1269 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1272 s5p_jpeg_start(jpeg->regs);
1274 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1277 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1279 struct s5p_jpeg *jpeg = ctx->jpeg;
1280 struct s5p_jpeg_fmt *fmt;
1281 struct vb2_buffer *vb;
1282 struct s5p_jpeg_addr jpeg_addr;
1283 u32 pix_size, padding_bytes = 0;
1285 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1287 if (ctx->mode == S5P_JPEG_ENCODE) {
1288 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1289 fmt = ctx->out_q.fmt;
1290 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1291 padding_bytes = ctx->out_q.h;
1293 fmt = ctx->cap_q.fmt;
1294 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1297 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1299 if (fmt->colplanes == 2) {
1300 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1301 } else if (fmt->colplanes == 3) {
1302 jpeg_addr.cb = jpeg_addr.y + pix_size;
1303 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1304 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1306 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1309 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1312 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1314 struct s5p_jpeg *jpeg = ctx->jpeg;
1315 struct vb2_buffer *vb;
1316 unsigned int jpeg_addr = 0;
1318 if (ctx->mode == S5P_JPEG_ENCODE)
1319 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1321 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1323 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1324 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1327 static void exynos4_jpeg_device_run(void *priv)
1329 struct s5p_jpeg_ctx *ctx = priv;
1330 struct s5p_jpeg *jpeg = ctx->jpeg;
1331 unsigned int bitstream_size;
1332 unsigned long flags;
1334 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1336 if (ctx->mode == S5P_JPEG_ENCODE) {
1337 exynos4_jpeg_sw_reset(jpeg->regs);
1338 exynos4_jpeg_set_interrupt(jpeg->regs);
1339 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1341 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1344 * JPEG IP allows storing 4 quantization tables
1345 * We fill table 0 for luma and table 1 for chroma
1347 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1348 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1350 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1351 ctx->compr_quality);
1352 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1355 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1356 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1357 exynos4_jpeg_set_img_addr(ctx);
1358 exynos4_jpeg_set_jpeg_addr(ctx);
1359 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1360 ctx->out_q.fmt->fourcc);
1362 exynos4_jpeg_sw_reset(jpeg->regs);
1363 exynos4_jpeg_set_interrupt(jpeg->regs);
1364 exynos4_jpeg_set_img_addr(ctx);
1365 exynos4_jpeg_set_jpeg_addr(ctx);
1366 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1368 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1370 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1373 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1375 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1378 static int s5p_jpeg_job_ready(void *priv)
1380 struct s5p_jpeg_ctx *ctx = priv;
1382 if (ctx->mode == S5P_JPEG_DECODE)
1383 return ctx->hdr_parsed;
1387 static void s5p_jpeg_job_abort(void *priv)
1391 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1392 .device_run = s5p_jpeg_device_run,
1393 .job_ready = s5p_jpeg_job_ready,
1394 .job_abort = s5p_jpeg_job_abort,
1397 static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1398 .device_run = exynos4_jpeg_device_run,
1399 .job_ready = s5p_jpeg_job_ready,
1400 .job_abort = s5p_jpeg_job_abort,
1404 * ============================================================================
1406 * ============================================================================
1409 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1410 const struct v4l2_format *fmt,
1411 unsigned int *nbuffers, unsigned int *nplanes,
1412 unsigned int sizes[], void *alloc_ctxs[])
1414 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1415 struct s5p_jpeg_q_data *q_data = NULL;
1416 unsigned int size, count = *nbuffers;
1418 q_data = get_q_data(ctx, vq->type);
1419 BUG_ON(q_data == NULL);
1421 size = q_data->size;
1424 * header is parsed during decoding and parsed information stored
1425 * in the context so we do not allow another buffer to overwrite it
1427 if (ctx->mode == S5P_JPEG_DECODE)
1433 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1438 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1440 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1441 struct s5p_jpeg_q_data *q_data = NULL;
1443 q_data = get_q_data(ctx, vb->vb2_queue->type);
1444 BUG_ON(q_data == NULL);
1446 if (vb2_plane_size(vb, 0) < q_data->size) {
1447 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1448 __func__, vb2_plane_size(vb, 0),
1449 (long)q_data->size);
1453 vb2_set_plane_payload(vb, 0, q_data->size);
1458 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1460 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1462 if (ctx->mode == S5P_JPEG_DECODE &&
1463 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1464 struct s5p_jpeg_q_data tmp, *q_data;
1465 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1466 (unsigned long)vb2_plane_vaddr(vb, 0),
1467 min((unsigned long)ctx->out_q.size,
1468 vb2_get_plane_payload(vb, 0)), ctx);
1469 if (!ctx->hdr_parsed) {
1470 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1474 q_data = &ctx->out_q;
1478 q_data = &ctx->cap_q;
1483 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
1486 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1488 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1491 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1493 return ret > 0 ? 0 : ret;
1496 static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1498 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1500 pm_runtime_put(ctx->jpeg->dev);
1505 static struct vb2_ops s5p_jpeg_qops = {
1506 .queue_setup = s5p_jpeg_queue_setup,
1507 .buf_prepare = s5p_jpeg_buf_prepare,
1508 .buf_queue = s5p_jpeg_buf_queue,
1509 .wait_prepare = vb2_ops_wait_prepare,
1510 .wait_finish = vb2_ops_wait_finish,
1511 .start_streaming = s5p_jpeg_start_streaming,
1512 .stop_streaming = s5p_jpeg_stop_streaming,
1515 static int queue_init(void *priv, struct vb2_queue *src_vq,
1516 struct vb2_queue *dst_vq)
1518 struct s5p_jpeg_ctx *ctx = priv;
1521 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1522 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1523 src_vq->drv_priv = ctx;
1524 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1525 src_vq->ops = &s5p_jpeg_qops;
1526 src_vq->mem_ops = &vb2_dma_contig_memops;
1527 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1528 src_vq->lock = &ctx->jpeg->lock;
1530 ret = vb2_queue_init(src_vq);
1534 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1535 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1536 dst_vq->drv_priv = ctx;
1537 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1538 dst_vq->ops = &s5p_jpeg_qops;
1539 dst_vq->mem_ops = &vb2_dma_contig_memops;
1540 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1541 dst_vq->lock = &ctx->jpeg->lock;
1543 return vb2_queue_init(dst_vq);
1547 * ============================================================================
1549 * ============================================================================
1552 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1554 struct s5p_jpeg *jpeg = dev_id;
1555 struct s5p_jpeg_ctx *curr_ctx;
1556 struct vb2_buffer *src_buf, *dst_buf;
1557 unsigned long payload_size = 0;
1558 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1559 bool enc_jpeg_too_large = false;
1560 bool timer_elapsed = false;
1561 bool op_completed = false;
1563 spin_lock(&jpeg->slock);
1565 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1567 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1568 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1570 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1571 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1572 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1573 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
1574 if (curr_ctx->mode == S5P_JPEG_DECODE)
1575 op_completed = op_completed &&
1576 s5p_jpeg_stream_stat_ok(jpeg->regs);
1578 if (enc_jpeg_too_large) {
1579 state = VB2_BUF_STATE_ERROR;
1580 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
1581 } else if (timer_elapsed) {
1582 state = VB2_BUF_STATE_ERROR;
1583 s5p_jpeg_clear_timer_stat(jpeg->regs);
1584 } else if (!op_completed) {
1585 state = VB2_BUF_STATE_ERROR;
1587 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
1590 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
1591 dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
1593 v4l2_m2m_buf_done(src_buf, state);
1594 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1595 vb2_set_plane_payload(dst_buf, 0, payload_size);
1596 v4l2_m2m_buf_done(dst_buf, state);
1597 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1599 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
1600 spin_unlock(&jpeg->slock);
1602 s5p_jpeg_clear_int(jpeg->regs);
1607 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1609 unsigned int int_status;
1610 struct vb2_buffer *src_vb, *dst_vb;
1611 struct s5p_jpeg *jpeg = priv;
1612 struct s5p_jpeg_ctx *curr_ctx;
1613 unsigned long payload_size = 0;
1615 spin_lock(&jpeg->slock);
1617 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1619 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1620 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1622 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1625 switch (int_status & 0x1f) {
1627 jpeg->irq_ret = ERR_PROT;
1630 jpeg->irq_ret = OK_ENC_OR_DEC;
1633 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1636 jpeg->irq_ret = ERR_MULTI_SCAN;
1639 jpeg->irq_ret = ERR_FRAME;
1642 jpeg->irq_ret = ERR_UNKNOWN;
1646 jpeg->irq_ret = ERR_UNKNOWN;
1649 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1650 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1651 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1652 vb2_set_plane_payload(dst_vb, 0, payload_size);
1654 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1655 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1657 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1658 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1661 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1662 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1664 spin_unlock(&jpeg->slock);
1668 static void *jpeg_get_drv_data(struct platform_device *pdev);
1671 * ============================================================================
1672 * Driver basic infrastructure
1673 * ============================================================================
1676 static int s5p_jpeg_probe(struct platform_device *pdev)
1678 struct s5p_jpeg *jpeg;
1679 struct resource *res;
1680 struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
1683 if (!pdev->dev.of_node)
1686 /* JPEG IP abstraction struct */
1687 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1691 jpeg->variant = jpeg_get_drv_data(pdev);
1693 mutex_init(&jpeg->lock);
1694 spin_lock_init(&jpeg->slock);
1695 jpeg->dev = &pdev->dev;
1697 /* memory-mapped registers */
1698 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1700 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
1701 if (IS_ERR(jpeg->regs))
1702 return PTR_ERR(jpeg->regs);
1704 /* interrupt service routine registration */
1705 jpeg->irq = ret = platform_get_irq(pdev, 0);
1707 dev_err(&pdev->dev, "cannot find IRQ\n");
1711 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1712 0, dev_name(&pdev->dev), jpeg);
1714 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1719 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1720 if (IS_ERR(jpeg->clk)) {
1721 dev_err(&pdev->dev, "cannot get clock\n");
1722 ret = PTR_ERR(jpeg->clk);
1725 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1728 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1730 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1731 goto clk_get_rollback;
1734 if (jpeg->variant->version == SJPEG_S5P)
1735 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1737 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1739 /* mem2mem device */
1740 jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
1741 if (IS_ERR(jpeg->m2m_dev)) {
1742 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1743 ret = PTR_ERR(jpeg->m2m_dev);
1744 goto device_register_rollback;
1747 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1748 if (IS_ERR(jpeg->alloc_ctx)) {
1749 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1750 ret = PTR_ERR(jpeg->alloc_ctx);
1751 goto m2m_init_rollback;
1754 /* JPEG encoder /dev/videoX node */
1755 jpeg->vfd_encoder = video_device_alloc();
1756 if (!jpeg->vfd_encoder) {
1757 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1759 goto vb2_allocator_rollback;
1761 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1762 "%s-enc", S5P_JPEG_M2M_NAME);
1763 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1764 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1765 jpeg->vfd_encoder->minor = -1;
1766 jpeg->vfd_encoder->release = video_device_release;
1767 jpeg->vfd_encoder->lock = &jpeg->lock;
1768 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1769 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
1771 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1773 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1774 goto enc_vdev_alloc_rollback;
1777 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1778 v4l2_info(&jpeg->v4l2_dev,
1779 "encoder device registered as /dev/video%d\n",
1780 jpeg->vfd_encoder->num);
1782 /* JPEG decoder /dev/videoX node */
1783 jpeg->vfd_decoder = video_device_alloc();
1784 if (!jpeg->vfd_decoder) {
1785 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1787 goto enc_vdev_register_rollback;
1789 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1790 "%s-dec", S5P_JPEG_M2M_NAME);
1791 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1792 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1793 jpeg->vfd_decoder->minor = -1;
1794 jpeg->vfd_decoder->release = video_device_release;
1795 jpeg->vfd_decoder->lock = &jpeg->lock;
1796 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1797 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
1799 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1801 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1802 goto dec_vdev_alloc_rollback;
1805 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1806 v4l2_info(&jpeg->v4l2_dev,
1807 "decoder device registered as /dev/video%d\n",
1808 jpeg->vfd_decoder->num);
1810 /* final statements & power management */
1811 platform_set_drvdata(pdev, jpeg);
1813 pm_runtime_enable(&pdev->dev);
1815 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1819 dec_vdev_alloc_rollback:
1820 video_device_release(jpeg->vfd_decoder);
1822 enc_vdev_register_rollback:
1823 video_unregister_device(jpeg->vfd_encoder);
1825 enc_vdev_alloc_rollback:
1826 video_device_release(jpeg->vfd_encoder);
1828 vb2_allocator_rollback:
1829 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1832 v4l2_m2m_release(jpeg->m2m_dev);
1834 device_register_rollback:
1835 v4l2_device_unregister(&jpeg->v4l2_dev);
1843 static int s5p_jpeg_remove(struct platform_device *pdev)
1845 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
1847 pm_runtime_disable(jpeg->dev);
1849 video_unregister_device(jpeg->vfd_decoder);
1850 video_device_release(jpeg->vfd_decoder);
1851 video_unregister_device(jpeg->vfd_encoder);
1852 video_device_release(jpeg->vfd_encoder);
1853 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1854 v4l2_m2m_release(jpeg->m2m_dev);
1855 v4l2_device_unregister(&jpeg->v4l2_dev);
1857 if (!pm_runtime_status_suspended(&pdev->dev))
1858 clk_disable_unprepare(jpeg->clk);
1865 static int s5p_jpeg_runtime_suspend(struct device *dev)
1867 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1869 clk_disable_unprepare(jpeg->clk);
1874 static int s5p_jpeg_runtime_resume(struct device *dev)
1876 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1877 unsigned long flags;
1880 ret = clk_prepare_enable(jpeg->clk);
1884 spin_lock_irqsave(&jpeg->slock, flags);
1887 * JPEG IP allows storing two Huffman tables for each component
1888 * We fill table 0 for each component and do this here only
1889 * for S5PC210 device as Exynos4x12 requires programming its
1890 * Huffman tables each time the encoding process is initialized.
1892 if (jpeg->variant->version == SJPEG_S5P) {
1893 s5p_jpeg_set_hdctbl(jpeg->regs);
1894 s5p_jpeg_set_hdctblg(jpeg->regs);
1895 s5p_jpeg_set_hactbl(jpeg->regs);
1896 s5p_jpeg_set_hactblg(jpeg->regs);
1899 spin_unlock_irqrestore(&jpeg->slock, flags);
1904 static int s5p_jpeg_suspend(struct device *dev)
1906 if (pm_runtime_suspended(dev))
1909 return s5p_jpeg_runtime_suspend(dev);
1912 static int s5p_jpeg_resume(struct device *dev)
1914 if (pm_runtime_suspended(dev))
1917 return s5p_jpeg_runtime_resume(dev);
1920 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
1921 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
1922 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
1926 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
1927 .version = SJPEG_S5P,
1928 .jpeg_irq = s5p_jpeg_irq,
1931 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
1932 .version = SJPEG_EXYNOS4,
1933 .jpeg_irq = exynos4_jpeg_irq,
1936 static const struct of_device_id samsung_jpeg_match[] = {
1938 .compatible = "samsung,s5pv210-jpeg",
1939 .data = &s5p_jpeg_drvdata,
1941 .compatible = "samsung,exynos4210-jpeg",
1942 .data = &s5p_jpeg_drvdata,
1944 .compatible = "samsung,exynos4212-jpeg",
1945 .data = &exynos4_jpeg_drvdata,
1950 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
1952 static void *jpeg_get_drv_data(struct platform_device *pdev)
1954 struct s5p_jpeg_variant *driver_data = NULL;
1955 const struct of_device_id *match;
1957 match = of_match_node(of_match_ptr(samsung_jpeg_match),
1960 driver_data = (struct s5p_jpeg_variant *)match->data;
1966 static struct platform_driver s5p_jpeg_driver = {
1967 .probe = s5p_jpeg_probe,
1968 .remove = s5p_jpeg_remove,
1970 .of_match_table = of_match_ptr(samsung_jpeg_match),
1971 .owner = THIS_MODULE,
1972 .name = S5P_JPEG_M2M_NAME,
1973 .pm = &s5p_jpeg_pm_ops,
1977 module_platform_driver(s5p_jpeg_driver);
1979 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
1980 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
1981 MODULE_DESCRIPTION("Samsung JPEG codec driver");
1982 MODULE_LICENSE("GPL");