1 /* linux/drivers/media/platform/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 if (mutex_lock_interruptible(&jpeg->lock)) {
300 v4l2_fh_init(&ctx->fh, vfd);
301 /* Use separate control handler per file handle */
302 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
303 file->private_data = &ctx->fh;
304 v4l2_fh_add(&ctx->fh);
307 if (vfd == jpeg->vfd_encoder) {
308 ctx->mode = S5P_JPEG_ENCODE;
309 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_RGB565);
311 ctx->mode = S5P_JPEG_DECODE;
312 out_fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_JPEG);
315 ret = s5p_jpeg_controls_create(ctx);
319 ctx->m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
320 if (IS_ERR(ctx->m2m_ctx)) {
321 ret = PTR_ERR(ctx->m2m_ctx);
325 ctx->out_q.fmt = out_fmt;
326 ctx->cap_q.fmt = s5p_jpeg_find_format(ctx->mode, V4L2_PIX_FMT_YUYV);
327 mutex_unlock(&jpeg->lock);
331 v4l2_fh_del(&ctx->fh);
332 v4l2_fh_exit(&ctx->fh);
333 mutex_unlock(&jpeg->lock);
339 static int s5p_jpeg_release(struct file *file)
341 struct s5p_jpeg *jpeg = video_drvdata(file);
342 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
344 mutex_lock(&jpeg->lock);
345 v4l2_m2m_ctx_release(ctx->m2m_ctx);
346 mutex_unlock(&jpeg->lock);
347 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
348 v4l2_fh_del(&ctx->fh);
349 v4l2_fh_exit(&ctx->fh);
355 static unsigned int s5p_jpeg_poll(struct file *file,
356 struct poll_table_struct *wait)
358 struct s5p_jpeg *jpeg = video_drvdata(file);
359 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
362 mutex_lock(&jpeg->lock);
363 res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait);
364 mutex_unlock(&jpeg->lock);
368 static int s5p_jpeg_mmap(struct file *file, struct vm_area_struct *vma)
370 struct s5p_jpeg *jpeg = video_drvdata(file);
371 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
374 if (mutex_lock_interruptible(&jpeg->lock))
376 ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma);
377 mutex_unlock(&jpeg->lock);
381 static const struct v4l2_file_operations s5p_jpeg_fops = {
382 .owner = THIS_MODULE,
383 .open = s5p_jpeg_open,
384 .release = s5p_jpeg_release,
385 .poll = s5p_jpeg_poll,
386 .unlocked_ioctl = video_ioctl2,
387 .mmap = s5p_jpeg_mmap,
391 * ============================================================================
392 * video ioctl operations
393 * ============================================================================
396 static int get_byte(struct s5p_jpeg_buffer *buf)
398 if (buf->curr >= buf->size)
401 return ((unsigned char *)buf->data)[buf->curr++];
404 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
409 byte = get_byte(buf);
413 byte = get_byte(buf);
416 *word = (unsigned int)byte | temp;
420 static void skip(struct s5p_jpeg_buffer *buf, long len)
429 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
430 unsigned long buffer, unsigned long size)
432 int c, components, notfound;
433 unsigned int height, width, word;
435 struct s5p_jpeg_buffer jpeg_buffer;
437 jpeg_buffer.size = size;
438 jpeg_buffer.data = buffer;
439 jpeg_buffer.curr = 0;
443 c = get_byte(&jpeg_buffer);
449 c = get_byte(&jpeg_buffer);
457 /* SOF0: baseline JPEG */
459 if (get_word_be(&jpeg_buffer, &word))
461 if (get_byte(&jpeg_buffer) == -1)
463 if (get_word_be(&jpeg_buffer, &height))
465 if (get_word_be(&jpeg_buffer, &width))
467 components = get_byte(&jpeg_buffer);
468 if (components == -1)
472 skip(&jpeg_buffer, components * 3);
475 /* skip payload-less markers */
476 case RST ... RST + 7:
482 /* skip uninteresting payload markers */
484 if (get_word_be(&jpeg_buffer, &word))
486 length = (long)word - 2;
487 skip(&jpeg_buffer, length);
493 result->size = components;
497 static int s5p_jpeg_querycap(struct file *file, void *priv,
498 struct v4l2_capability *cap)
500 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
502 if (ctx->mode == S5P_JPEG_ENCODE) {
503 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
504 sizeof(cap->driver));
505 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
508 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
509 sizeof(cap->driver));
510 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
513 cap->bus_info[0] = 0;
515 * This is only a mem-to-mem video device. The capture and output
516 * device capability flags are left only for backward compatibility
517 * and are scheduled for removal.
519 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
520 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
524 static int enum_fmt(struct s5p_jpeg_fmt *formats, int n,
525 struct v4l2_fmtdesc *f, u32 type)
529 for (i = 0; i < n; ++i) {
530 if (formats[i].types & type) {
531 /* index-th format of type type found ? */
534 /* Correct type but haven't reached our index yet,
535 * just increment per-type index */
540 /* Format not found */
544 strlcpy(f->description, formats[i].name, sizeof(f->description));
545 f->pixelformat = formats[i].fourcc;
550 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
551 struct v4l2_fmtdesc *f)
553 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
555 if (ctx->mode == S5P_JPEG_ENCODE)
556 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
559 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_CAPTURE);
562 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
563 struct v4l2_fmtdesc *f)
565 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
567 if (ctx->mode == S5P_JPEG_ENCODE)
568 return enum_fmt(formats_enc, NUM_FORMATS_ENC, f,
571 return enum_fmt(formats_dec, NUM_FORMATS_DEC, f, MEM2MEM_OUTPUT);
574 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
575 enum v4l2_buf_type type)
577 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
579 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
585 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
587 struct vb2_queue *vq;
588 struct s5p_jpeg_q_data *q_data = NULL;
589 struct v4l2_pix_format *pix = &f->fmt.pix;
590 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
592 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
596 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
597 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
599 q_data = get_q_data(ct, f->type);
600 BUG_ON(q_data == NULL);
602 pix->width = q_data->w;
603 pix->height = q_data->h;
604 pix->field = V4L2_FIELD_NONE;
605 pix->pixelformat = q_data->fmt->fourcc;
606 pix->bytesperline = 0;
607 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
609 if (q_data->fmt->colplanes == 1)
610 bpl = (bpl * q_data->fmt->depth) >> 3;
611 pix->bytesperline = bpl;
613 pix->sizeimage = q_data->size;
618 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(unsigned int mode,
622 struct s5p_jpeg_fmt *formats;
625 if (mode == S5P_JPEG_ENCODE) {
626 formats = formats_enc;
629 formats = formats_dec;
633 for (k = 0; k < n; k++) {
634 struct s5p_jpeg_fmt *fmt = &formats[k];
635 if (fmt->fourcc == pixelformat)
643 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
645 u32 *h, unsigned int hmin, unsigned int hmax,
648 int width, height, w_step, h_step;
653 w_step = 1 << walign;
654 h_step = 1 << halign;
655 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
657 if (*w < width && (*w + w_step) < wmax)
659 if (*h < height && (*h + h_step) < hmax)
664 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
665 struct s5p_jpeg_ctx *ctx, int q_type)
667 struct v4l2_pix_format *pix = &f->fmt.pix;
669 if (pix->field == V4L2_FIELD_ANY)
670 pix->field = V4L2_FIELD_NONE;
671 else if (pix->field != V4L2_FIELD_NONE)
674 /* V4L2 specification suggests the driver corrects the format struct
675 * if any of the dimensions is unsupported */
676 if (q_type == MEM2MEM_OUTPUT)
677 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
678 S5P_JPEG_MAX_WIDTH, 0,
679 &pix->height, S5P_JPEG_MIN_HEIGHT,
680 S5P_JPEG_MAX_HEIGHT, 0);
682 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
683 S5P_JPEG_MAX_WIDTH, fmt->h_align,
684 &pix->height, S5P_JPEG_MIN_HEIGHT,
685 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
687 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
688 if (pix->sizeimage <= 0)
689 pix->sizeimage = PAGE_SIZE;
690 pix->bytesperline = 0;
692 u32 bpl = pix->bytesperline;
694 if (fmt->colplanes > 1 && bpl < pix->width)
695 bpl = pix->width; /* planar */
697 if (fmt->colplanes == 1 && /* packed */
698 (bpl << 3) * fmt->depth < pix->width)
699 bpl = (pix->width * fmt->depth) >> 3;
701 pix->bytesperline = bpl;
702 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
708 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
709 struct v4l2_format *f)
711 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
712 struct s5p_jpeg_fmt *fmt;
714 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
715 if (!fmt || !(fmt->types & MEM2MEM_CAPTURE)) {
716 v4l2_err(&ctx->jpeg->v4l2_dev,
717 "Fourcc format (0x%08x) invalid.\n",
718 f->fmt.pix.pixelformat);
722 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_CAPTURE);
725 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
726 struct v4l2_format *f)
728 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
729 struct s5p_jpeg_fmt *fmt;
731 fmt = s5p_jpeg_find_format(ctx->mode, f->fmt.pix.pixelformat);
732 if (!fmt || !(fmt->types & MEM2MEM_OUTPUT)) {
733 v4l2_err(&ctx->jpeg->v4l2_dev,
734 "Fourcc format (0x%08x) invalid.\n",
735 f->fmt.pix.pixelformat);
739 return vidioc_try_fmt(f, fmt, ctx, MEM2MEM_OUTPUT);
742 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
744 struct vb2_queue *vq;
745 struct s5p_jpeg_q_data *q_data = NULL;
746 struct v4l2_pix_format *pix = &f->fmt.pix;
748 vq = v4l2_m2m_get_vq(ct->m2m_ctx, f->type);
752 q_data = get_q_data(ct, f->type);
753 BUG_ON(q_data == NULL);
755 if (vb2_is_busy(vq)) {
756 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
760 q_data->fmt = s5p_jpeg_find_format(ct->mode, pix->pixelformat);
761 q_data->w = pix->width;
762 q_data->h = pix->height;
763 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
764 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
766 q_data->size = pix->sizeimage;
771 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
772 struct v4l2_format *f)
776 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
780 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
783 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
784 struct v4l2_format *f)
788 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
792 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
795 static int s5p_jpeg_reqbufs(struct file *file, void *priv,
796 struct v4l2_requestbuffers *reqbufs)
798 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
800 return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs);
803 static int s5p_jpeg_querybuf(struct file *file, void *priv,
804 struct v4l2_buffer *buf)
806 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
808 return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf);
811 static int s5p_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
813 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
815 return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf);
818 static int s5p_jpeg_dqbuf(struct file *file, void *priv,
819 struct v4l2_buffer *buf)
821 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
823 return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
826 static int s5p_jpeg_streamon(struct file *file, void *priv,
827 enum v4l2_buf_type type)
829 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
831 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
834 static int s5p_jpeg_streamoff(struct file *file, void *priv,
835 enum v4l2_buf_type type)
837 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
839 return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type);
842 static int s5p_jpeg_g_selection(struct file *file, void *priv,
843 struct v4l2_selection *s)
845 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
847 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
848 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
851 /* For JPEG blob active == default == bounds */
853 case V4L2_SEL_TGT_CROP:
854 case V4L2_SEL_TGT_CROP_BOUNDS:
855 case V4L2_SEL_TGT_CROP_DEFAULT:
856 case V4L2_SEL_TGT_COMPOSE:
857 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
858 s->r.width = ctx->out_q.w;
859 s->r.height = ctx->out_q.h;
861 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
862 case V4L2_SEL_TGT_COMPOSE_PADDED:
863 s->r.width = ctx->cap_q.w;
864 s->r.height = ctx->cap_q.h;
878 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
880 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
881 struct s5p_jpeg *jpeg = ctx->jpeg;
885 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
886 spin_lock_irqsave(&jpeg->slock, flags);
888 WARN_ON(ctx->subsampling > S5P_SUBSAMPLING_MODE_GRAY);
889 if (ctx->subsampling > 2)
890 ctrl->val = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
892 ctrl->val = ctx->subsampling;
893 spin_unlock_irqrestore(&jpeg->slock, flags);
900 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
902 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
905 spin_lock_irqsave(&ctx->jpeg->slock, flags);
908 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
909 ctx->compr_quality = S5P_JPEG_COMPR_QUAL_WORST - ctrl->val;
911 case V4L2_CID_JPEG_RESTART_INTERVAL:
912 ctx->restart_interval = ctrl->val;
914 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
915 ctx->subsampling = ctrl->val;
919 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
923 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
924 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
925 .s_ctrl = s5p_jpeg_s_ctrl,
928 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
930 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
931 struct v4l2_ctrl *ctrl;
933 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
935 if (ctx->mode == S5P_JPEG_ENCODE) {
936 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
937 V4L2_CID_JPEG_COMPRESSION_QUALITY,
940 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
941 V4L2_CID_JPEG_RESTART_INTERVAL,
943 mask = ~0x06; /* 422, 420 */
946 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
947 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
948 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
949 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
951 if (ctx->ctrl_handler.error)
952 return ctx->ctrl_handler.error;
954 if (ctx->mode == S5P_JPEG_DECODE)
955 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
956 V4L2_CTRL_FLAG_READ_ONLY;
960 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
961 .vidioc_querycap = s5p_jpeg_querycap,
963 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
964 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
966 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
967 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
969 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
970 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
972 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
973 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
975 .vidioc_reqbufs = s5p_jpeg_reqbufs,
976 .vidioc_querybuf = s5p_jpeg_querybuf,
978 .vidioc_qbuf = s5p_jpeg_qbuf,
979 .vidioc_dqbuf = s5p_jpeg_dqbuf,
981 .vidioc_streamon = s5p_jpeg_streamon,
982 .vidioc_streamoff = s5p_jpeg_streamoff,
984 .vidioc_g_selection = s5p_jpeg_g_selection,
988 * ============================================================================
990 * ============================================================================
993 static void s5p_jpeg_device_run(void *priv)
995 struct s5p_jpeg_ctx *ctx = priv;
996 struct s5p_jpeg *jpeg = ctx->jpeg;
997 struct vb2_buffer *src_buf, *dst_buf;
998 unsigned long src_addr, dst_addr;
1000 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
1001 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
1002 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1003 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1005 jpeg_reset(jpeg->regs);
1006 jpeg_poweron(jpeg->regs);
1007 jpeg_proc_mode(jpeg->regs, ctx->mode);
1008 if (ctx->mode == S5P_JPEG_ENCODE) {
1009 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1010 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
1012 jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
1013 jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1014 jpeg_dri(jpeg->regs, ctx->restart_interval);
1015 jpeg_x(jpeg->regs, ctx->out_q.w);
1016 jpeg_y(jpeg->regs, ctx->out_q.h);
1017 jpeg_imgadr(jpeg->regs, src_addr);
1018 jpeg_jpgadr(jpeg->regs, dst_addr);
1020 /* ultimately comes from sizeimage from userspace */
1021 jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1023 /* JPEG RGB to YCbCr conversion matrix */
1024 jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1025 jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1026 jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1027 jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1028 jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1029 jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1030 jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1031 jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1032 jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1035 * JPEG IP allows storing 4 quantization tables
1036 * We fill table 0 for luma and table 1 for chroma
1038 jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1039 jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1040 /* use table 0 for Y */
1041 jpeg_qtbl(jpeg->regs, 1, 0);
1042 /* use table 1 for Cb and Cr*/
1043 jpeg_qtbl(jpeg->regs, 2, 1);
1044 jpeg_qtbl(jpeg->regs, 3, 1);
1046 /* Y, Cb, Cr use Huffman table 0 */
1047 jpeg_htbl_ac(jpeg->regs, 1);
1048 jpeg_htbl_dc(jpeg->regs, 1);
1049 jpeg_htbl_ac(jpeg->regs, 2);
1050 jpeg_htbl_dc(jpeg->regs, 2);
1051 jpeg_htbl_ac(jpeg->regs, 3);
1052 jpeg_htbl_dc(jpeg->regs, 3);
1053 } else { /* S5P_JPEG_DECODE */
1054 jpeg_rst_int_enable(jpeg->regs, true);
1055 jpeg_data_num_int_enable(jpeg->regs, true);
1056 jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1057 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1058 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1060 jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1061 jpeg_jpgadr(jpeg->regs, src_addr);
1062 jpeg_imgadr(jpeg->regs, dst_addr);
1065 jpeg_start(jpeg->regs);
1068 static int s5p_jpeg_job_ready(void *priv)
1070 struct s5p_jpeg_ctx *ctx = priv;
1072 if (ctx->mode == S5P_JPEG_DECODE)
1073 return ctx->hdr_parsed;
1077 static void s5p_jpeg_job_abort(void *priv)
1081 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1082 .device_run = s5p_jpeg_device_run,
1083 .job_ready = s5p_jpeg_job_ready,
1084 .job_abort = s5p_jpeg_job_abort,
1088 * ============================================================================
1090 * ============================================================================
1093 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1094 const struct v4l2_format *fmt,
1095 unsigned int *nbuffers, unsigned int *nplanes,
1096 unsigned int sizes[], void *alloc_ctxs[])
1098 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1099 struct s5p_jpeg_q_data *q_data = NULL;
1100 unsigned int size, count = *nbuffers;
1102 q_data = get_q_data(ctx, vq->type);
1103 BUG_ON(q_data == NULL);
1105 size = q_data->size;
1108 * header is parsed during decoding and parsed information stored
1109 * in the context so we do not allow another buffer to overwrite it
1111 if (ctx->mode == S5P_JPEG_DECODE)
1117 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1122 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1124 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1125 struct s5p_jpeg_q_data *q_data = NULL;
1127 q_data = get_q_data(ctx, vb->vb2_queue->type);
1128 BUG_ON(q_data == NULL);
1130 if (vb2_plane_size(vb, 0) < q_data->size) {
1131 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1132 __func__, vb2_plane_size(vb, 0),
1133 (long)q_data->size);
1137 vb2_set_plane_payload(vb, 0, q_data->size);
1142 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1144 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1146 if (ctx->mode == S5P_JPEG_DECODE &&
1147 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1148 struct s5p_jpeg_q_data tmp, *q_data;
1149 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1150 (unsigned long)vb2_plane_vaddr(vb, 0),
1151 min((unsigned long)ctx->out_q.size,
1152 vb2_get_plane_payload(vb, 0)));
1153 if (!ctx->hdr_parsed) {
1154 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1158 q_data = &ctx->out_q;
1162 q_data = &ctx->cap_q;
1166 jpeg_bound_align_image(&q_data->w, S5P_JPEG_MIN_WIDTH,
1167 S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
1168 &q_data->h, S5P_JPEG_MIN_HEIGHT,
1169 S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align
1171 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1174 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
1177 static void s5p_jpeg_wait_prepare(struct vb2_queue *vq)
1179 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1181 mutex_unlock(&ctx->jpeg->lock);
1184 static void s5p_jpeg_wait_finish(struct vb2_queue *vq)
1186 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1188 mutex_lock(&ctx->jpeg->lock);
1191 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1193 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1196 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1198 return ret > 0 ? 0 : ret;
1201 static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1203 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1205 pm_runtime_put(ctx->jpeg->dev);
1210 static struct vb2_ops s5p_jpeg_qops = {
1211 .queue_setup = s5p_jpeg_queue_setup,
1212 .buf_prepare = s5p_jpeg_buf_prepare,
1213 .buf_queue = s5p_jpeg_buf_queue,
1214 .wait_prepare = s5p_jpeg_wait_prepare,
1215 .wait_finish = s5p_jpeg_wait_finish,
1216 .start_streaming = s5p_jpeg_start_streaming,
1217 .stop_streaming = s5p_jpeg_stop_streaming,
1220 static int queue_init(void *priv, struct vb2_queue *src_vq,
1221 struct vb2_queue *dst_vq)
1223 struct s5p_jpeg_ctx *ctx = priv;
1226 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1227 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1228 src_vq->drv_priv = ctx;
1229 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1230 src_vq->ops = &s5p_jpeg_qops;
1231 src_vq->mem_ops = &vb2_dma_contig_memops;
1233 ret = vb2_queue_init(src_vq);
1237 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1238 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1239 dst_vq->drv_priv = ctx;
1240 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1241 dst_vq->ops = &s5p_jpeg_qops;
1242 dst_vq->mem_ops = &vb2_dma_contig_memops;
1244 return vb2_queue_init(dst_vq);
1248 * ============================================================================
1250 * ============================================================================
1253 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1255 struct s5p_jpeg *jpeg = dev_id;
1256 struct s5p_jpeg_ctx *curr_ctx;
1257 struct vb2_buffer *src_buf, *dst_buf;
1258 unsigned long payload_size = 0;
1259 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1260 bool enc_jpeg_too_large = false;
1261 bool timer_elapsed = false;
1262 bool op_completed = false;
1264 spin_lock(&jpeg->slock);
1266 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1268 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
1269 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
1271 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1272 enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
1273 timer_elapsed = jpeg_timer_stat(jpeg->regs);
1274 op_completed = jpeg_result_stat_ok(jpeg->regs);
1275 if (curr_ctx->mode == S5P_JPEG_DECODE)
1276 op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
1278 if (enc_jpeg_too_large) {
1279 state = VB2_BUF_STATE_ERROR;
1280 jpeg_clear_enc_stream_stat(jpeg->regs);
1281 } else if (timer_elapsed) {
1282 state = VB2_BUF_STATE_ERROR;
1283 jpeg_clear_timer_stat(jpeg->regs);
1284 } else if (!op_completed) {
1285 state = VB2_BUF_STATE_ERROR;
1287 payload_size = jpeg_compressed_size(jpeg->regs);
1290 v4l2_m2m_buf_done(src_buf, state);
1291 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1292 vb2_set_plane_payload(dst_buf, 0, payload_size);
1293 v4l2_m2m_buf_done(dst_buf, state);
1294 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
1296 curr_ctx->subsampling = jpeg_get_subsampling_mode(jpeg->regs);
1297 spin_unlock(&jpeg->slock);
1299 jpeg_clear_int(jpeg->regs);
1305 * ============================================================================
1306 * Driver basic infrastructure
1307 * ============================================================================
1310 static int s5p_jpeg_probe(struct platform_device *pdev)
1312 struct s5p_jpeg *jpeg;
1313 struct resource *res;
1316 /* JPEG IP abstraction struct */
1317 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1321 mutex_init(&jpeg->lock);
1322 spin_lock_init(&jpeg->slock);
1323 jpeg->dev = &pdev->dev;
1325 /* memory-mapped registers */
1326 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1328 jpeg->regs = devm_request_and_ioremap(&pdev->dev, res);
1329 if (jpeg->regs == NULL) {
1330 dev_err(&pdev->dev, "Failed to obtain io memory\n");
1334 /* interrupt service routine registration */
1335 jpeg->irq = ret = platform_get_irq(pdev, 0);
1337 dev_err(&pdev->dev, "cannot find IRQ\n");
1341 ret = devm_request_irq(&pdev->dev, jpeg->irq, s5p_jpeg_irq, 0,
1342 dev_name(&pdev->dev), jpeg);
1344 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1349 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1350 if (IS_ERR(jpeg->clk)) {
1351 dev_err(&pdev->dev, "cannot get clock\n");
1352 ret = PTR_ERR(jpeg->clk);
1355 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1356 clk_prepare_enable(jpeg->clk);
1359 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1361 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1362 goto clk_get_rollback;
1365 /* mem2mem device */
1366 jpeg->m2m_dev = v4l2_m2m_init(&s5p_jpeg_m2m_ops);
1367 if (IS_ERR(jpeg->m2m_dev)) {
1368 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1369 ret = PTR_ERR(jpeg->m2m_dev);
1370 goto device_register_rollback;
1373 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1374 if (IS_ERR(jpeg->alloc_ctx)) {
1375 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1376 ret = PTR_ERR(jpeg->alloc_ctx);
1377 goto m2m_init_rollback;
1380 /* JPEG encoder /dev/videoX node */
1381 jpeg->vfd_encoder = video_device_alloc();
1382 if (!jpeg->vfd_encoder) {
1383 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1385 goto vb2_allocator_rollback;
1387 strlcpy(jpeg->vfd_encoder->name, S5P_JPEG_M2M_NAME,
1388 sizeof(jpeg->vfd_encoder->name));
1389 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1390 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1391 jpeg->vfd_encoder->minor = -1;
1392 jpeg->vfd_encoder->release = video_device_release;
1393 jpeg->vfd_encoder->lock = &jpeg->lock;
1394 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1395 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
1397 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1399 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1400 goto enc_vdev_alloc_rollback;
1403 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1404 v4l2_info(&jpeg->v4l2_dev,
1405 "encoder device registered as /dev/video%d\n",
1406 jpeg->vfd_encoder->num);
1408 /* JPEG decoder /dev/videoX node */
1409 jpeg->vfd_decoder = video_device_alloc();
1410 if (!jpeg->vfd_decoder) {
1411 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1413 goto enc_vdev_register_rollback;
1415 strlcpy(jpeg->vfd_decoder->name, S5P_JPEG_M2M_NAME,
1416 sizeof(jpeg->vfd_decoder->name));
1417 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1418 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1419 jpeg->vfd_decoder->minor = -1;
1420 jpeg->vfd_decoder->release = video_device_release;
1421 jpeg->vfd_decoder->lock = &jpeg->lock;
1422 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1424 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1426 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1427 goto dec_vdev_alloc_rollback;
1430 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1431 v4l2_info(&jpeg->v4l2_dev,
1432 "decoder device registered as /dev/video%d\n",
1433 jpeg->vfd_decoder->num);
1435 /* final statements & power management */
1436 platform_set_drvdata(pdev, jpeg);
1438 pm_runtime_enable(&pdev->dev);
1440 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1444 dec_vdev_alloc_rollback:
1445 video_device_release(jpeg->vfd_decoder);
1447 enc_vdev_register_rollback:
1448 video_unregister_device(jpeg->vfd_encoder);
1450 enc_vdev_alloc_rollback:
1451 video_device_release(jpeg->vfd_encoder);
1453 vb2_allocator_rollback:
1454 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1457 v4l2_m2m_release(jpeg->m2m_dev);
1459 device_register_rollback:
1460 v4l2_device_unregister(&jpeg->v4l2_dev);
1463 clk_disable_unprepare(jpeg->clk);
1469 static int s5p_jpeg_remove(struct platform_device *pdev)
1471 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
1473 pm_runtime_disable(jpeg->dev);
1475 video_unregister_device(jpeg->vfd_decoder);
1476 video_device_release(jpeg->vfd_decoder);
1477 video_unregister_device(jpeg->vfd_encoder);
1478 video_device_release(jpeg->vfd_encoder);
1479 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
1480 v4l2_m2m_release(jpeg->m2m_dev);
1481 v4l2_device_unregister(&jpeg->v4l2_dev);
1483 clk_disable_unprepare(jpeg->clk);
1489 static int s5p_jpeg_runtime_suspend(struct device *dev)
1494 static int s5p_jpeg_runtime_resume(struct device *dev)
1496 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
1498 * JPEG IP allows storing two Huffman tables for each component
1499 * We fill table 0 for each component
1501 jpeg_set_hdctbl(jpeg->regs);
1502 jpeg_set_hdctblg(jpeg->regs);
1503 jpeg_set_hactbl(jpeg->regs);
1504 jpeg_set_hactblg(jpeg->regs);
1508 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
1509 .runtime_suspend = s5p_jpeg_runtime_suspend,
1510 .runtime_resume = s5p_jpeg_runtime_resume,
1513 static struct platform_driver s5p_jpeg_driver = {
1514 .probe = s5p_jpeg_probe,
1515 .remove = s5p_jpeg_remove,
1517 .owner = THIS_MODULE,
1518 .name = S5P_JPEG_M2M_NAME,
1519 .pm = &s5p_jpeg_pm_ops,
1523 module_platform_driver(s5p_jpeg_driver);
1525 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
1526 MODULE_DESCRIPTION("Samsung JPEG codec driver");
1527 MODULE_LICENSE("GPL");