1 /* linux/drivers/media/video/s5p-jpeg/jpeg-core.c
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/clk.h>
14 #include <linux/err.h>
15 #include <linux/gfp.h>
16 #include <linux/interrupt.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/slab.h>
23 #include <linux/spinlock.h>
24 #include <linux/string.h>
25 #include <media/v4l2-mem2mem.h>
26 #include <media/v4l2-ioctl.h>
27 #include <media/videobuf2-core.h>
28 #include <media/videobuf2-dma-contig.h>
30 #include "jpeg-core.h"
33 static struct s5p_jpeg_fmt formats_enc[] = {
36 .fourcc = V4L2_PIX_FMT_JPEG,
38 .types = MEM2MEM_CAPTURE,
41 .name = "YUV 4:2:2 packed, YCbYCr",
42 .fourcc = V4L2_PIX_FMT_YUYV,
45 .types = MEM2MEM_OUTPUT,
49 .fourcc = V4L2_PIX_FMT_RGB565,
52 .types = MEM2MEM_OUTPUT,
55 #define NUM_FORMATS_ENC ARRAY_SIZE(formats_enc)
57 static struct s5p_jpeg_fmt formats_dec[] = {
59 .name = "YUV 4:2:0 planar, YCbCr",
60 .fourcc = V4L2_PIX_FMT_YUV420,
65 .types = MEM2MEM_CAPTURE,
68 .name = "YUV 4:2:2 packed, YCbYCr",
69 .fourcc = V4L2_PIX_FMT_YUYV,
74 .types = MEM2MEM_CAPTURE,
78 .fourcc = V4L2_PIX_FMT_JPEG,
80 .types = MEM2MEM_OUTPUT,
83 #define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec)
85 static const unsigned char qtbl_luminance[4][64] = {
86 {/* level 1 - high quality */
87 8, 6, 6, 8, 12, 14, 16, 17,
88 6, 6, 6, 8, 10, 13, 12, 15,
89 6, 6, 7, 8, 13, 14, 18, 24,
90 8, 8, 8, 14, 13, 19, 24, 35,
91 12, 10, 13, 13, 20, 26, 34, 39,
92 14, 13, 14, 19, 26, 34, 39, 39,
93 16, 12, 18, 24, 34, 39, 39, 39,
94 17, 15, 24, 35, 39, 39, 39, 39
97 12, 8, 8, 12, 17, 21, 24, 23,
98 8, 9, 9, 11, 15, 19, 18, 23,
99 8, 9, 10, 12, 19, 20, 27, 36,
100 12, 11, 12, 21, 20, 28, 36, 53,
101 17, 15, 19, 20, 30, 39, 51, 59,
102 21, 19, 20, 28, 39, 51, 59, 59,
103 24, 18, 27, 36, 51, 59, 59, 59,
104 23, 23, 36, 53, 59, 59, 59, 59
107 16, 11, 11, 16, 23, 27, 31, 30,
108 11, 12, 12, 15, 20, 23, 23, 30,
109 11, 12, 13, 16, 23, 26, 35, 47,
110 16, 15, 16, 23, 26, 37, 47, 64,
111 23, 20, 23, 26, 39, 51, 64, 64,
112 27, 23, 26, 37, 51, 64, 64, 64,
113 31, 23, 35, 47, 64, 64, 64, 64,
114 30, 30, 47, 64, 64, 64, 64, 64
116 {/*level 4 - low quality */
117 20, 16, 25, 39, 50, 46, 62, 68,
118 16, 18, 23, 38, 38, 53, 65, 68,
119 25, 23, 31, 38, 53, 65, 68, 68,
120 39, 38, 38, 53, 65, 68, 68, 68,
121 50, 38, 53, 65, 68, 68, 68, 68,
122 46, 53, 65, 68, 68, 68, 68, 68,
123 62, 65, 68, 68, 68, 68, 68, 68,
124 68, 68, 68, 68, 68, 68, 68, 68
128 static const unsigned char qtbl_chrominance[4][64] = {
129 {/* level 1 - high quality */
130 9, 8, 9, 11, 14, 17, 19, 24,
131 8, 10, 9, 11, 14, 13, 17, 22,
132 9, 9, 13, 14, 13, 15, 23, 26,
133 11, 11, 14, 14, 15, 20, 26, 33,
134 14, 14, 13, 15, 20, 24, 33, 39,
135 17, 13, 15, 20, 24, 32, 39, 39,
136 19, 17, 23, 26, 33, 39, 39, 39,
137 24, 22, 26, 33, 39, 39, 39, 39
140 13, 11, 13, 16, 20, 20, 29, 37,
141 11, 14, 14, 14, 16, 20, 26, 32,
142 13, 14, 15, 17, 20, 23, 35, 40,
143 16, 14, 17, 21, 23, 30, 40, 50,
144 20, 16, 20, 23, 30, 37, 50, 59,
145 20, 20, 23, 30, 37, 48, 59, 59,
146 29, 26, 35, 40, 50, 59, 59, 59,
147 37, 32, 40, 50, 59, 59, 59, 59
150 17, 15, 17, 21, 20, 26, 38, 48,
151 15, 19, 18, 17, 20, 26, 35, 43,
152 17, 18, 20, 22, 26, 30, 46, 53,
153 21, 17, 22, 28, 30, 39, 53, 64,
154 20, 20, 26, 30, 39, 48, 64, 64,
155 26, 26, 30, 39, 48, 63, 64, 64,
156 38, 35, 46, 53, 64, 64, 64, 64,
157 48, 43, 53, 64, 64, 64, 64, 64
159 {/*level 4 - low quality */
160 21, 25, 32, 38, 54, 68, 68, 68,
161 25, 28, 24, 38, 54, 68, 68, 68,
162 32, 24, 32, 43, 66, 68, 68, 68,
163 38, 38, 43, 53, 68, 68, 68, 68,
164 54, 54, 66, 68, 68, 68, 68, 68,
165 68, 68, 68, 68, 68, 68, 68, 68,
166 68, 68, 68, 68, 68, 68, 68, 68,
167 68, 68, 68, 68, 68, 68, 68, 68
171 static const unsigned char hdctbl0[16] = {
172 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
175 static const unsigned char hdctblg0[12] = {
176 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
178 static const unsigned char hactbl0[16] = {
179 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
181 static const unsigned char hactblg0[162] = {
182 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
183 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
184 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
185 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
186 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
187 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
188 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
189 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
190 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
191 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
192 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
193 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
194 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
195 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
196 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
197 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
198 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
199 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
200 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
201 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
205 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
207 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
210 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
212 return container_of(fh, struct s5p_jpeg_ctx, fh);
215 static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
216 unsigned long tab, int len)
220 for (i = 0; i < len; i++)
221 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
224 static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality)
226 /* this driver fills quantisation table 0 with data for luma */
227 jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0),
228 ARRAY_SIZE(qtbl_luminance[quality]));
231 static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality)
233 /* this driver fills quantisation table 1 with data for chroma */
234 jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1),
235 ARRAY_SIZE(qtbl_chrominance[quality]));
238 static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
239 unsigned long tab, int len)
243 for (i = 0; i < len; i++)
244 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
247 static inline void jpeg_set_hdctbl(void __iomem *regs)
249 /* this driver fills table 0 for this component */
250 jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0));
253 static inline void jpeg_set_hdctblg(void __iomem *regs)
255 /* this driver fills table 0 for this component */
256 jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0));
259 static inline void jpeg_set_hactbl(void __iomem *regs)
261 /* this driver fills table 0 for this component */
262 jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0));
265 static inline void jpeg_set_hactblg(void __iomem *regs)
267 /* this driver fills table 0 for this component */
268 jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
272 * ============================================================================
273 * Device file operations
274 * ============================================================================
277 static int queue_init(void *priv, struct vb2_queue *src_vq,
278 struct vb2_queue *dst_vq);
279 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
281 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
283 static int s5p_jpeg_open(struct file *file)
285 struct s5p_jpeg *jpeg = video_drvdata(file);
286 struct video_device *vfd = video_devdata(file);
287 struct s5p_jpeg_ctx *ctx;
288 struct s5p_jpeg_fmt *out_fmt;
291 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
295 v4l2_fh_init(&ctx->fh, vfd);
296 /* Use separate control handler per file handle */
297 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
298 file->private_data = &ctx->fh;
299 v4l2_fh_add(&ctx->fh);
302 if (vfd == jpeg->vfd_encoder) {
303 ctx->mode = S5P_JPEG_ENCODE;
304 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
306 ctx->mode = S5P_JPEG_DECODE;
307 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
310 ret = s5p_jpeg_controls_create(ctx);
314 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
315 if (IS_ERR(ctx->m2m_ctx)) {
316 ret = PTR_ERR(ctx->m2m_ctx);
320 ctx->out_q.fmt = out_fmt;
321 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
325 v4l2_fh_del(&ctx->fh);
326 v4l2_fh_exit(&ctx->fh);
331 static int s5p_jpeg_release(struct file *file)
333 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
335 v4l2_m2m_ctx_release(ctx->m2m_ctx);
336 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
337 v4l2_fh_del(&ctx->fh);
338 v4l2_fh_exit(&ctx->fh);
344 static unsigned int s5p_jpeg_poll(struct file *file,
345 struct poll_table_struct *wait)
347 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
349 return v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
352 static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
354 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
356 return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
359 static const struct v4l2_file_operations s5p_jpeg_fops = {
360 .owner = THIS_MODULE,
361 .open = s5p_jpeg_open,
362 .release = s5p_jpeg_release,
363 .poll = s5p_jpeg_poll,
364 .unlocked_ioctl = video_ioctl2,
365 .mmap = s5p_jpeg_mmap,
369 * ============================================================================
370 * video ioctl operations
371 * ============================================================================
374 static int get_byte(struct s5p_jpeg_buffer *buf)
376 if (buf->curr >= buf->size)
379 return ((unsigned char *)buf->data)[buf->curr++];
382 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
387 byte = get_byte(buf);
391 byte = get_byte(buf);
394 *word = (unsigned int)byte | temp;
398 static void skip(struct s5p_jpeg_buffer *buf, long len)
407 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
408 unsigned long buffer, unsigned long size)
410 int c, components, notfound;
411 unsigned int height, width, word;
413 struct s5p_jpeg_buffer jpeg_buffer;
415 jpeg_buffer.size = size;
416 jpeg_buffer.data = buffer;
417 jpeg_buffer.curr = 0;
421 c = get_byte(&jpeg_buffer);
427 c = get_byte(&jpeg_buffer);
435 /* SOF0: baseline JPEG */
437 if (get_word_be(&jpeg_buffer, &word))
439 if (get_byte(&jpeg_buffer) == -1)
441 if (get_word_be(&jpeg_buffer, &height))
443 if (get_word_be(&jpeg_buffer, &width))
445 components = get_byte(&jpeg_buffer);
446 if (components == -1)
450 skip(&jpeg_buffer, components * 3);
453 /* skip payload-less markers */
454 case RST ... RST + 7:
460 /* skip uninteresting payload markers */
462 if (get_word_be(&jpeg_buffer, &word))
464 length = (long)word - 2;
465 skip(&jpeg_buffer, length);
471 result->size = components;
475 static int s5p_jpeg_querycap(struct file *file, void *priv,
476 struct v4l2_capability *cap)
478 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
480 if (ctx->mode == S5P_JPEG_ENCODE) {
481 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
482 sizeof(cap->driver));
483 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
486 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
487 sizeof(cap->driver));
488 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
491 cap->bus_info[0] = 0;
492 cap->capabilities = V4L2_CAP_STREAMING |
493 V4L2_CAP_VIDEO_CAPTURE |
494 V4L2_CAP_VIDEO_OUTPUT;
498 static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
499 struct v4l2_fmtdesc *f, u32 type)
503 for (i = 0; i < n; ++i) {
504 if (formats[i].types & type) {
505 /* index-th format of type type found ? */
508 /* Correct type but haven't reached our index yet,
509 * just increment per-type index */
514 /* Format not found */
518 strlcpy(f->description, formats[i].name, sizeof(f->description));
519 f->pixelformat = formats[i].fourcc;
524 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
525 struct v4l2_fmtdesc *f)
527 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
529 if (ctx->mode == S5P_JPEG_ENCODE)
530 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
533 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE);
536 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
537 struct v4l2_fmtdesc *f)
539 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
541 if (ctx->mode == S5P_JPEG_ENCODE)
542 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
545 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT);
548 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
549 enum v4l2_buf_type type)
551 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
553 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
559 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
561 struct vb2_queue *vq;
562 struct s5p_jpeg_q_data *q_data = NULL;
563 struct v4l2_pix_format *pix = &f->fmt.pix;
564 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
566 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
570 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
571 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
573 q_data = get_q_data(ct, f->type);
574 BUG_ON(q_data == NULL);
576 pix->width = q_data->w;
577 pix->height = q_data->h;
578 pix->field = V4L2_FIELD_NONE;
579 pix->pixelformat = q_data->fmt->fourcc;
580 pix->bytesperline = 0;
581 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
583 if (q_data->fmt->colplanes == 1)
584 bpl = (bpl * q_data->fmt->depth) >> 3;
585 pix->bytesperline = bpl;
587 pix->sizeimage = q_data->size;
592 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
596 struct s5p_jpeg_fmt *formats;
599 if (mode == S5P_JPEG_ENCODE) {
600 formats = formats_enc;
603 formats = formats_dec;
607 for (k = 0; k < n; k++) {
608 struct s5p_jpeg_fmt *fmt = &formats[k];
609 if (fmt->fourcc == pixelformat)
617 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
619 u32 *h, unsigned int hmin, unsigned int hmax,
622 int width, height, w_step, h_step;
627 w_step = 1 << walign;
628 h_step = 1 << halign;
629 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
631 if (*w < width && (*w + w_step) < wmax)
633 if (*h < height && (*h + h_step) < hmax)
638 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
639 struct s5p_jpeg_ctx *ctx, int q_type)
641 struct v4l2_pix_format *pix = &f->fmt.pix;
643 if (pix->field == V4L2_FIELD_ANY)
644 pix->field = V4L2_FIELD_NONE;
645 else if (pix->field != V4L2_FIELD_NONE)
648 /* V4L2 specification suggests the driver corrects the format struct
649 * if any of the dimensions is unsupported */
650 if (q_type == MEM2MEM_OUTPUT)
651 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
652 S5P_JPEG_MAX_WIDTH, 0,
653 &pix->height, S5P_JPEG_MIN_HEIGHT,
654 S5P_JPEG_MAX_HEIGHT, 0);
656 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
657 S5P_JPEG_MAX_WIDTH, fmt->h_align,
658 &pix->height, S5P_JPEG_MIN_HEIGHT,
659 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
661 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
662 if (pix->sizeimage <= 0)
663 pix->sizeimage = PAGE_SIZE;
664 pix->bytesperline = 0;
666 u32 bpl = pix->bytesperline;
668 if (fmt->colplanes > 1 && bpl < pix->width)
669 bpl = pix->width; /* planar */
671 if (fmt->colplanes == 1 && /* packed */
672 (bpl << 3) * fmt->depth < pix->width)
673 bpl = (pix->width * fmt->depth) >> 3;
675 pix->bytesperline = bpl;
676 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
682 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
683 struct v4l2_format *f)
685 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
686 struct s5p_jpeg_fmt *fmt;
688 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
689 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
690 v4l2_err(&ctx->jpeg->v4l2_dev,
691 "Fourcc format (0x%08x) invalid.\n",
692 f->fmt.pix.pixelformat);
696 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE);
699 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
700 struct v4l2_format *f)
702 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
703 struct s5p_jpeg_fmt *fmt;
705 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
706 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
707 v4l2_err(&ctx->jpeg->v4l2_dev,
708 "Fourcc format (0x%08x) invalid.\n",
709 f->fmt.pix.pixelformat);
713 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT);
716 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
718 struct vb2_queue *vq;
719 struct s5p_jpeg_q_data *q_data = NULL;
720 struct v4l2_pix_format *pix = &f->fmt.pix;
722 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
726 q_data = get_q_data(ct, f->type);
727 BUG_ON(q_data == NULL);
729 if (vb2_is_busy(vq)) {
730 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
734 q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat);
735 q_data->w = pix->width;
736 q_data->h = pix->height;
737 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
738 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
740 q_data->size = pix->sizeimage;
745 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
746 struct v4l2_format *f)
750 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
754 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
757 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
758 struct v4l2_format *f)
762 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
766 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
769 static int s5p_jpeg_reqbufs(struct file *file, void *priv,
770 struct v4l2_requestbuffers *reqbufs)
772 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
774 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
777 static int s5p_jpeg_querybuf(struct file *file, void *priv,
778 struct v4l2_buffer *buf)
780 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
782 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
785 static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
787 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
789 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
792 static int s5p_jpeg_dqbuf(struct file *file, void *priv,
793 struct v4l2_buffer *buf)
795 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
797 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
800 static int s5p_jpeg_streamon(struct file *file, void *priv,
801 enum v4l2_buf_type type)
803 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
805 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
808 static int s5p_jpeg_streamoff(struct file *file, void *priv,
809 enum v4l2_buf_type type)
811 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
813 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
816 int s5p_jpeg_g_selection(struct file *file, void *priv,
817 struct v4l2_selection *s)
819 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
821 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
822 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
825 /* For JPEG blob active == default == bounds */
827 case V4L2_SEL_TGT_CROP_ACTIVE:
828 case V4L2_SEL_TGT_CROP_BOUNDS:
829 case V4L2_SEL_TGT_CROP_DEFAULT:
830 case V4L2_SEL_TGT_COMPOSE_ACTIVE:
831 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
832 s->r.width = ctx->out_q.w;
833 s->r.height = ctx->out_q.h;
835 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
836 case V4L2_SEL_TGT_COMPOSE_PADDED:
837 s->r.width = ctx->cap_q.w;
838 s->r.height = ctx->cap_q.h;
852 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
854 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
855 struct s5p_jpeg *jpeg = ctx->jpeg;
859 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
860 spin_lock_irqsave(&jpeg->slock, flags);
862 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
863 if (ctx->subsampling > 2)
864 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
866 ctrl->val = ctx->subsampling;
867 spin_unlock_irqrestore(&jpeg->slock, flags);
874 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
876 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
879 spin_lock_irqsave(&ctx->jpeg->slock, flags);
882 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
883 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
885 case V4L2_CID_JPEG_RESTART_INTERVAL:
886 ctx->restart_interval = ctrl->val;
888 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
889 ctx->subsampling = ctrl->val;
893 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
897 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
898 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
899 .s_ctrl = s5p_jpeg_s_ctrl,
902 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
904 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
905 struct v4l2_ctrl *ctrl;
907 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
909 if (ctx->mode == S5P_JPEG_ENCODE) {
910 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
911 V4L2_CID_JPEG_COMPRESSION_QUALITY,
914 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
915 V4L2_CID_JPEG_RESTART_INTERVAL,
917 mask = ~0x06; /* 422, 420 */
920 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
921 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
922 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
923 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
925 if (ctx->ctrl_handler.error)
926 return ctx->ctrl_handler.error;
928 if (ctx->mode == S5P_JPEG_DECODE)
929 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
930 V4L2_CTRL_FLAG_READ_ONLY;
934 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
935 .vidioc_querycap = s5p_jpeg_querycap,
937 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
938 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
940 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
941 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
943 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
944 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
946 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
947 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
949 .vidioc_reqbufs = s5p_jpeg_reqbufs,
950 .vidioc_querybuf = s5p_jpeg_querybuf,
952 .vidioc_qbuf = s5p_jpeg_qbuf,
953 .vidioc_dqbuf = s5p_jpeg_dqbuf,
955 .vidioc_streamon = s5p_jpeg_streamon,
956 .vidioc_streamoff = s5p_jpeg_streamoff,
958 .vidioc_g_selection = s5p_jpeg_g_selection,
962 * ============================================================================
964 * ============================================================================
967 static void s5p_jpeg_device_run(void *priv)
969 struct s5p_jpeg_ctx *ctx = priv;
970 struct s5p_jpeg *jpeg = ctx->jpeg;
971 struct vb2_buffer *src_buf, *dst_buf;
972 unsigned long src_addr, dst_addr;
974 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
975 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
976 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
977 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
979 jpeg_reset(jpeg->regs);
980 jpeg_poweron(jpeg->regs);
981 jpeg_proc_mode(jpeg->regs, ctx->mode);
982 if (ctx->mode == S5P_JPEG_ENCODE) {
983 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
984 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
986 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
987 jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
988 jpeg_dri(jpeg->regs, ctx->restart_interval);
989 jpeg_x(jpeg->regs, ctx->out_q.w);
990 jpeg_y(jpeg->regs, ctx->out_q.h);
991 jpeg_imgadr(jpeg->regs, src_addr);
992 jpeg_jpgadr(jpeg->regs, dst_addr);
994 /* ultimately comes from sizeimage from userspace */
995 jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
997 /* JPEG RGB to YCbCr conversion matrix */
998 jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
999 jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1000 jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1001 jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1002 jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1003 jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1004 jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1005 jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1006 jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1009 * JPEG IP allows storing 4 quantization tables
1010 * We fill table 0 for luma and table 1 for chroma
1012 jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1013 jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1014 /* use table 0 for Y */
1015 jpeg_qtbl(jpeg->regs, 1, 0);
1016 /* use table 1 for Cb and Cr*/
1017 jpeg_qtbl(jpeg->regs, 2, 1);
1018 jpeg_qtbl(jpeg->regs, 3, 1);
1020 /* Y, Cb, Cr use Huffman table 0 */
1021 jpeg_htbl_ac(jpeg->regs, 1);
1022 jpeg_htbl_dc(jpeg->regs, 1);
1023 jpeg_htbl_ac(jpeg->regs, 2);
1024 jpeg_htbl_dc(jpeg->regs, 2);
1025 jpeg_htbl_ac(jpeg->regs, 3);
1026 jpeg_htbl_dc(jpeg->regs, 3);
1027 } else { /* S5P_JPEG_DECODE */
1028 jpeg_rst_int_enable(jpeg->regs, true);
1029 jpeg_data_num_int_enable(jpeg->regs, true);
1030 jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1031 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1032 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1034 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1035 jpeg_jpgadr(jpeg->regs, src_addr);
1036 jpeg_imgadr(jpeg->regs, dst_addr);
1039 jpeg_start(jpeg->regs);
1042 static int s5p_jpeg_job_ready(void *priv)
1044 struct s5p_jpeg_ctx *ctx = priv;
1046 if (ctx->mode == S5P_JPEG_DECODE)
1047 return ctx->hdr_parsed;
1051 static void s5p_jpeg_job_abort(void *priv)
1055 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1056 .device_run = s5p_jpeg_device_run,
1057 .job_ready = s5p_jpeg_job_ready,
1058 .job_abort = s5p_jpeg_job_abort,
1062 * ============================================================================
1064 * ============================================================================
1067 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1068 const struct v4l2_format *fmt,
1069 unsigned int *nbuffers, unsigned int *nplanes,
1070 unsigned int sizes[], void *alloc_ctxs[])
1072 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1073 struct s5p_jpeg_q_data *q_data = NULL;
1074 unsigned int size, count = *nbuffers;
1076 q_data = get_q_data(ctx, vq->type);
1077 BUG_ON(q_data == NULL);
1079 size = q_data->size;
1082 * header is parsed during decoding and parsed information stored
1083 * in the context so we do not allow another buffer to overwrite it
1085 if (ctx->mode == S5P_JPEG_DECODE)
1091 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1096 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1098 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1099 struct s5p_jpeg_q_data *q_data = NULL;
1101 q_data = get_q_data(ctx, vb->vb2_queue->type);
1102 BUG_ON(q_data == NULL);
1104 if (vb2_plane_size(vb, 0) < q_data->size) {
1105 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1106 __func__, vb2_plane_size(vb, 0),
1107 (long)q_data->size);
1111 vb2_set_plane_payload(vb, 0, q_data->size);
1116 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1118 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1120 if (ctx->mode == S5P_JPEG_DECODE &&
1121 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1122 struct s5p_jpeg_q_data tmp, *q_data;
1123 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1124 (unsigned long)vb2_plane_vaddr(vb, 0),
1125 min((unsigned long)ctx->out_q.size,
1126 vb2_get_plane_payload(vb, 0)));
1127 if (!ctx->hdr_parsed) {
1128 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1132 q_data = &ctx->out_q;
1136 q_data = &ctx->cap_q;
1140 jpeg_bound_align_image(&q_data->w, S5P_JPEG_MIN_WIDTH,
1141 S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1142 &q_data->h, S5P_JPEG_MIN_HEIGHT,
1143 S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
1145 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1148 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
1151 static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
1153 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1155 mutex_unlock(&ctx->jpeg->lock);
1158 static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
1160 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1162 mutex_lock(&ctx->jpeg->lock);
1165 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1167 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1170 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1172 return ret > 0 ? 0 : ret;
1175 static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1177 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1179 pm_runtime_put(ctx->jpeg->dev);
1184 static struct vb2_ops s5p_jpeg_qops = {
1185 .queue_setup = s5p_jpeg_queue_setup,
1186 .buf_prepare = s5p_jpeg_buf_prepare,
1187 .buf_queue = s5p_jpeg_buf_queue,
1188 .wait_prepare = s5p_jpeg_wait_prepare,
1189 .wait_finish = s5p_jpeg_wait_finish,
1190 .start_streaming = s5p_jpeg_start_streaming,
1191 .stop_streaming = s5p_jpeg_stop_streaming,
1194 static int queue_init(void *priv, struct vb2_queue *src_vq,
1195 struct vb2_queue *dst_vq)
1197 struct s5p_jpeg_ctx *ctx = priv;
1200 memset(src_vq, 0, sizeof(*src_vq));
1201 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1202 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1203 src_vq->drv_priv = ctx;
1204 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1205 src_vq->ops = &s5p_jpeg_qops;
1206 src_vq->mem_ops = &vb2_dma_contig_memops;
1208 ret = vb2_queue_init(src_vq);
1212 memset(dst_vq, 0, sizeof(*dst_vq));
1213 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1214 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1215 dst_vq->drv_priv = ctx;
1216 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1217 dst_vq->ops = &s5p_jpeg_qops;
1218 dst_vq->mem_ops = &vb2_dma_contig_memops;
1220 return vb2_queue_init(dst_vq);
1224 * ============================================================================
1226 * ============================================================================
1229 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1231 struct s5p_jpeg *jpeg = dev_id;
1232 struct s5p_jpeg_ctx *curr_ctx;
1233 struct vb2_buffer *src_buf, *dst_buf;
1234 unsigned long payload_size = 0;
1235 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1236 bool enc_jpeg_too_large = false;
1237 bool timer_elapsed = false;
1238 bool op_completed = false;
1240 spin_lock(&jpeg->slock);
1242 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1244 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
1245 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
1247 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1248 enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
1249 timer_elapsed = jpeg_timer_stat(jpeg->regs);
1250 op_completed = jpeg_result_stat_ok(jpeg->regs);
1251 if (curr_ctx->mode == S5P_JPEG_DECODE)
1252 op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
1254 if (enc_jpeg_too_large) {
1255 state = VB2_BUF_STATE_ERROR;
1256 jpeg_clear_enc_stream_stat(jpeg->regs);
1257 } else if (timer_elapsed) {
1258 state = VB2_BUF_STATE_ERROR;
1259 jpeg_clear_timer_stat(jpeg->regs);
1260 } else if (!op_completed) {
1261 state = VB2_BUF_STATE_ERROR;
1263 payload_size = jpeg_compressed_size(jpeg->regs);
1266 v4l2_m2m_buf_done(src_buf, state);
1267 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1268 vb2_set_plane_payload(dst_buf, 0, payload_size);
1269 v4l2_m2m_buf_done(dst_buf, state);
1270 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
1272 curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
1273 spin_unlock(&jpeg->slock);
1275 jpeg_clear_int(jpeg->regs);
1281 * ============================================================================
1282 * Driver basic infrastructure
1283 * ============================================================================
1286 static int s5p_jpeg_probe(struct platform_device *pdev)
1288 struct s5p_jpeg *jpeg;
1289 struct resource *res;
1292 /* JPEG IP abstraction struct */
1293 jpeg = kzalloc(sizeof(struct s5p_jpeg), GFP_KERNEL);
1297 mutex_init(&jpeg->lock);
1298 spin_lock_init(&jpeg->slock);
1299 jpeg->dev = &pdev->dev;
1301 /* memory-mapped registers */
1302 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1304 dev_err(&pdev->dev, "cannot find IO resource\n");
1306 goto jpeg_alloc_rollback;
1309 jpeg->ioarea = request_mem_region(res->start, resource_size(res),
1311 if (!jpeg->ioarea) {
1312 dev_err(&pdev->dev, "cannot request IO\n");
1314 goto jpeg_alloc_rollback;
1317 jpeg->regs = ioremap(res->start, resource_size(res));
1319 dev_err(&pdev->dev, "cannot map IO\n");
1321 goto mem_region_rollback;
1324 dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
1325 jpeg->regs, jpeg->ioarea, res);
1327 /* interrupt service routine registration */
1328 jpeg->irq = ret = platform_get_irq(pdev, 0);
1330 dev_err(&pdev->dev, "cannot find IRQ\n");
1331 goto ioremap_rollback;
1334 ret = request_irq(jpeg->irq, s5p_jpeg_irq, 0,
1335 dev_name(&pdev->dev), jpeg);
1338 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1339 goto ioremap_rollback;
1343 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1344 if (IS_ERR(jpeg->clk)) {
1345 dev_err(&pdev->dev, "cannot get clock\n");
1346 ret = PTR_ERR(jpeg->clk);
1347 goto request_irq_rollback;
1349 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1350 clk_enable(jpeg->clk);
1353 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1355 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1356 goto clk_get_rollback;
1359 /* mem2mem device */
1360 jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops);
1361 if (IS_ERR(jpeg->m2m_dev)) {
1362 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1363 ret = PTR_ERR(jpeg->m2m_dev);
1364 goto device_register_rollback;
1367 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1368 if (IS_ERR(jpeg->alloc_ctx)) {
1369 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1370 ret = PTR_ERR(jpeg->alloc_ctx);
1371 goto m2m_init_rollback;
1374 /* JPEG encoder /dev/videoX node */
1375 jpeg->vfd_encoder = video_device_alloc();
1376 if (!jpeg->vfd_encoder) {
1377 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1379 goto vb2_allocator_rollback;
1381 strlcpy(jpeg->vfd_encoder->name, S5P_JPEG_M2M_NAME,
1382 sizeof(jpeg->vfd_encoder->name));
1383 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1384 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1385 jpeg->vfd_encoder->minor = -1;
1386 jpeg->vfd_encoder->release = video_device_release;
1387 jpeg->vfd_encoder->lock = &jpeg->lock;
1388 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1390 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1392 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1393 goto enc_vdev_alloc_rollback;
1396 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1397 v4l2_info(&jpeg->v4l2_dev,
1398 "encoder device registered as /dev/video%d\n",
1399 jpeg->vfd_encoder->num);
1401 /* JPEG decoder /dev/videoX node */
1402 jpeg->vfd_decoder = video_device_alloc();
1403 if (!jpeg->vfd_decoder) {
1404 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1406 goto enc_vdev_register_rollback;
1408 strlcpy(jpeg->vfd_decoder->name, S5P_JPEG_M2M_NAME,
1409 sizeof(jpeg->vfd_decoder->name));
1410 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1411 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1412 jpeg->vfd_decoder->minor = -1;
1413 jpeg->vfd_decoder->release = video_device_release;
1414 jpeg->vfd_decoder->lock = &jpeg->lock;
1415 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1417 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1419 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1420 goto dec_vdev_alloc_rollback;
1423 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1424 v4l2_info(&jpeg->v4l2_dev,
1425 "decoder device registered as /dev/video%d\n",
1426 jpeg->vfd_decoder->num);
1428 /* final statements & power management */
1429 platform_set_drvdata(pdev, jpeg);
1431 pm_runtime_enable(&pdev->dev);
1433 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1437 dec_vdev_alloc_rollback:
1438 video_device_release(jpeg->vfd_decoder);
1440 enc_vdev_register_rollback:
1441 video_unregister_device(jpeg->vfd_encoder);
1443 enc_vdev_alloc_rollback:
1444 video_device_release(jpeg->vfd_encoder);
1446 vb2_allocator_rollback:
1447 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1450 v4l2_m2m_release(jpeg->m2m_dev);
1452 device_register_rollback:
1453 v4l2_device_unregister(&jpeg->v4l2_dev);
1456 clk_disable(jpeg->clk);
1459 request_irq_rollback:
1460 free_irq(jpeg->irq, jpeg);
1463 iounmap(jpeg->regs);
1465 mem_region_rollback:
1466 release_resource(jpeg->ioarea);
1467 release_mem_region(jpeg->ioarea->start, resource_size(jpeg->ioarea));
1469 jpeg_alloc_rollback:
1474 static int s5p_jpeg_remove(struct platform_device *pdev)
1476 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
1478 pm_runtime_disable(jpeg->dev);
1480 video_unregister_device(jpeg->vfd_decoder);
1481 video_device_release(jpeg->vfd_decoder);
1482 video_unregister_device(jpeg->vfd_encoder);
1483 video_device_release(jpeg->vfd_encoder);
1484 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1485 v4l2_m2m_release(jpeg->m2m_dev);
1486 v4l2_device_unregister(&jpeg->v4l2_dev);
1488 clk_disable(jpeg->clk);
1491 free_irq(jpeg->irq, jpeg);
1493 iounmap(jpeg->regs);
1495 release_resource(jpeg->ioarea);
1496 release_mem_region(jpeg->ioarea->start, resource_size(jpeg->ioarea));
1502 static int s5p_jpeg_runtime_suspend(struct device *dev)
1507 static int s5p_jpeg_runtime_resume(struct device *dev)
1509 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1511 * JPEG IP allows storing two Huffman tables for each component
1512 * We fill table 0 for each component
1514 jpeg_set_hdctbl(jpeg->regs);
1515 jpeg_set_hdctblg(jpeg->regs);
1516 jpeg_set_hactbl(jpeg->regs);
1517 jpeg_set_hactblg(jpeg->regs);
1521 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
1522 .runtime_suspend = s5p_jpeg_runtime_suspend,
1523 .runtime_resume = s5p_jpeg_runtime_resume,
1526 static struct platform_driver s5p_jpeg_driver = {
1527 .probe = s5p_jpeg_probe,
1528 .remove = s5p_jpeg_remove,
1530 .owner = THIS_MODULE,
1531 .name = S5P_JPEG_M2M_NAME,
1532 .pm = &s5p_jpeg_pm_ops,
1537 s5p_jpeg_register(void)
1541 pr_info("S5P JPEG V4L2 Driver, (c) 2011 Samsung Electronics\n");
1543 ret = platform_driver_register(&s5p_jpeg_driver);
1546 pr_err("%s: failed to register jpeg driver\n", __func__);
1552 s5p_jpeg_unregister(void)
1554 platform_driver_unregister(&s5p_jpeg_driver);
1557 module_init(s5p_jpeg_register);
1558 module_exit(s5p_jpeg_unregister);
1560 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
1561 MODULE_DESCRIPTION("Samsung JPEG codec driver");
1562 MODULE_LICENSE("GPL");