aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanghyuck Kim <janghyuck.kim@samsung.com>2010-08-10 16:31:34 +0900
committerArve Hjønnevåg <arve@android.com>2011-11-17 17:40:48 -0800
commit27f1fec5123fa480604c747d73639027c5e5ae93 (patch)
tree675007c12eb001718c8f22ea6bd1bed68d697fec
parentfc7408d4d5e1dd43c4fa204a6d45c0b843496b52 (diff)
downloadkernel_samsung_crespo-27f1fec5123fa480604c747d73639027c5e5ae93.zip
kernel_samsung_crespo-27f1fec5123fa480604c747d73639027c5e5ae93.tar.gz
kernel_samsung_crespo-27f1fec5123fa480604c747d73639027c5e5ae93.tar.bz2
S5PC110: JPEG: Add JPEG driver files
Signed-off-by: Janghyuck Kim <janghyuck.kim@samsung.com>
-rw-r--r--drivers/media/video/samsung/jpeg_v2/Kconfig15
-rw-r--r--drivers/media/video/samsung/jpeg_v2/Makefile10
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_conf.h259
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_mem.c62
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_mem.h144
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_misc.c80
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_misc.h34
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_opr.c310
-rw-r--r--drivers/media/video/samsung/jpeg_v2/jpg_opr.h153
-rw-r--r--drivers/media/video/samsung/jpeg_v2/regs-jpeg.h147
-rw-r--r--drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c536
-rw-r--r--drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h33
12 files changed, 1783 insertions, 0 deletions
diff --git a/drivers/media/video/samsung/jpeg_v2/Kconfig b/drivers/media/video/samsung/jpeg_v2/Kconfig
new file mode 100644
index 0000000..291aa90
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/Kconfig
@@ -0,0 +1,15 @@
+#
+# Configuration for JPEG
+#
+
+config VIDEO_JPEG_V2
+ bool "Samsung JPEG driver"
+ depends on VIDEO_SAMSUNG
+ default n
+ ---help---
+ This is a JPEG for Samsung S5PV210
+
+config VIDEO_JPEG_DEBUG
+ bool "print JPEG debug message"
+ depends on VIDEO_JPEG_V2
+ default n
diff --git a/drivers/media/video/samsung/jpeg_v2/Makefile b/drivers/media/video/samsung/jpeg_v2/Makefile
new file mode 100644
index 0000000..d7ed17f
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/Makefile
@@ -0,0 +1,10 @@
+#################################################
+# Makefile for JPEG_V2
+# 2009 (C) Samsung Electronics
+# Author : Jaeryul peter Oh <jaeryul.oh@samsung.com>
+#################################################
+
+obj-$(CONFIG_VIDEO_JPEG_V2) += jpg_mem.o jpg_misc.o jpg_opr.o s3c-jpeg.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_conf.h b/drivers/media/video/samsung/jpeg_v2/jpg_conf.h
new file mode 100644
index 0000000..90d8c2d
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_conf.h
@@ -0,0 +1,259 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg-conf.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition Quantization Table for Jpeg encoder/docoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_CONF_H__
+#define __JPG_CONF_H__
+
+
+const unsigned char qtbl_luminance[4][64] = {
+ // level 1 - high quality
+ {
+ 8, 6, 6, 8, 12, 14, 16, 17,
+ 6, 6, 6, 8, 10, 13, 12, 15,
+ 6, 6, 7, 8, 13, 14, 18, 24,
+ 8, 8, 8, 14, 13, 19, 24, 35,
+ 12, 10, 13, 13, 20, 26, 34, 39,
+ 14, 13, 14, 19, 26, 34, 39, 39,
+ 16, 12, 18, 24, 34, 39, 39, 39,
+ 17, 15, 24, 35, 39, 39, 39, 39
+ },
+
+ // level 2
+ {
+ 12, 8, 8, 12, 17, 21, 24, 23,
+ 8, 9, 9, 11, 15, 19, 18, 23,
+ 8, 9, 10, 12, 19, 20, 27, 36,
+ 12, 11, 12, 21, 20, 28, 36, 53,
+ 17, 15, 19, 20, 30, 39, 51, 59,
+ 21, 19, 20, 28, 39, 51, 59, 59,
+ 24, 18, 27, 36, 51, 59, 59, 59,
+ 23, 23, 36, 53, 59, 59, 59, 59
+ },
+
+ // level 3
+ {
+ 16, 11, 11, 16, 23, 27, 31, 30,
+ 11, 12, 12, 15, 20, 23, 23, 30,
+ 11, 12, 13, 16, 23, 26, 35, 47,
+ 16, 15, 16, 23, 26, 37, 47, 64,
+ 23, 20, 23, 26, 39, 51, 64, 64,
+ 27, 23, 26, 37, 51, 64, 64, 64,
+ 31, 23, 35, 47, 64, 64, 64, 64,
+ 30, 30, 47, 64, 64, 64, 64, 64
+
+ },
+
+ // level 4 - low quality
+ {
+ 20, 16, 25, 39, 50, 46, 62, 68,
+ 16, 18, 23, 38, 38, 53, 65, 68,
+ 25, 23, 31, 38, 53, 65, 68, 68,
+ 39, 38, 38, 53, 65, 68, 68, 68,
+ 50, 38, 53, 65, 68, 68, 68, 68,
+ 46, 53, 65, 68, 68, 68, 68, 68,
+ 62, 65, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68
+ }
+
+
+};
+
+const unsigned char qtbl_chrominance[4][64] = {
+ // level 1 - high quality
+ {
+ 9, 8, 9, 11, 14, 17, 19, 24,
+ 8, 10, 9, 11, 14, 13, 17, 22,
+ 9, 9, 13, 14, 13, 15, 23, 26,
+ 11, 11, 14, 14, 15, 20, 26, 33,
+ 14, 14, 13, 15, 20, 24, 33, 39,
+ 17, 13, 15, 20, 24, 32, 39, 39,
+ 19, 17, 23, 26, 33, 39, 39, 39,
+ 24, 22, 26, 33, 39, 39, 39, 39
+ },
+
+ // level 2
+ {
+ 13, 11, 13, 16, 20, 20, 29, 37,
+ 11, 14, 14, 14, 16, 20, 26, 32,
+ 13, 14, 15, 17, 20, 23, 35, 40,
+ 16, 14, 17, 21, 23, 30, 40, 50,
+ 20, 16, 20, 23, 30, 37, 50, 59,
+ 20, 20, 23, 30, 37, 48, 59, 59,
+ 29, 26, 35, 40, 50, 59, 59, 59,
+ 37, 32, 40, 50, 59, 59, 59, 59
+ },
+
+
+ // level 3
+ {
+ 17, 15, 17, 21, 20, 26, 38, 48,
+ 15, 19, 18, 17, 20, 26, 35, 43,
+ 17, 18, 20, 22, 26, 30, 46, 53,
+ 21, 17, 22, 28, 30, 39, 53, 64,
+ 20, 20, 26, 30, 39, 48, 64, 64,
+ 26, 26, 30, 39, 48, 63, 64, 64,
+ 38, 35, 46, 53, 64, 64, 64, 64,
+ 48, 43, 53, 64, 64, 64, 64, 64
+
+
+ },
+
+ // level 4 - low quality
+ {
+ 21, 25, 32, 38, 54, 68, 68, 68,
+ 25, 28, 24, 38, 54, 68, 68, 68,
+ 32, 24, 32, 43, 66, 68, 68, 68,
+ 38, 38, 43, 53, 68, 68, 68, 68,
+ 54, 54, 66, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68,
+ 68, 68, 68, 68, 68, 68, 68, 68
+
+ }
+
+};
+
+const unsigned char qtbl0[64] = {
+ 0x10, 0x0B, 0x0A, 0x10, 0x18, 0x28, 0x33, 0x3D,
+ 0x0C, 0x0C, 0x0E, 0x13, 0x1A, 0x3A, 0x3C, 0x37,
+ 0x0E, 0x0D, 0x10, 0x18, 0x28, 0x39, 0x45, 0x38,
+ 0x0E, 0x11, 0x16, 0x1D, 0x33, 0x57, 0x50, 0x3E,
+ 0x12, 0x16, 0x25, 0x38, 0x44, 0x6D, 0x67, 0x4D,
+ 0x18, 0x23, 0x37, 0x40, 0x51, 0x68, 0x71, 0x5C,
+ 0x31, 0x40, 0x4E, 0x57, 0x67, 0x79, 0x78, 0x65,
+ 0x48, 0x5C, 0x5F, 0x62, 0x70, 0x64, 0x67, 0x63
+};
+
+//Added Quantization Table
+const unsigned char std_chrominance_quant_tbl_plus[64] = {
+ 0x11, 0x12, 0x18, 0x2F, 0x63, 0x63, 0x63, 0x63,
+ 0x12, 0x15, 0x1A, 0x42, 0x63, 0x63, 0x63, 0x63,
+ 0x18, 0x1A, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x2F, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
+};
+
+//Quantization Table0
+unsigned char std_luminance_quant_tbl[64] = {
+ 1, 1, 2, 1, 1, 2, 2, 2,
+ 2, 3, 2, 2, 3, 3, 6, 4,
+ 3, 3, 3, 3, 7, 5, 8, 4,
+ 6, 8, 8, 10, 9, 8, 7, 11,
+ 8, 10, 14, 13, 11, 10, 10, 12,
+ 10, 8, 8, 11, 16, 12, 12, 13,
+ 15, 15, 15, 15, 9, 11, 16, 17,
+ 15, 14, 17, 13, 14, 14, 14, 1
+};
+
+//Quantization Table1
+unsigned char std_chrominance_quant_tbl[64] = {
+ 4, 4, 4, 5, 4, 5, 9, 5,
+ 5, 9, 15, 10, 8, 10, 15, 26,
+ 19, 9, 9, 19, 26, 26, 26, 26,
+ 13, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26
+};
+
+//Huffman Table
+unsigned char hdctbl0[16] = {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};
+unsigned char hdctblg0[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb};
+
+unsigned char hactbl0[16] = {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};
+const unsigned char hactblg0[162] = {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+//Huffman Table0
+unsigned char len_dc_luminance[16] = { 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+unsigned char val_dc_luminance[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+unsigned char len_ac_luminance[16] = { 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+unsigned char val_ac_luminance[162] = {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+//Huffman Table1
+unsigned char len_dc_chrominance[16] = { 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+unsigned char val_dc_chrominance[12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+unsigned char len_ac_chrominance[16] = { 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+unsigned char val_ac_chrominance[162] = {
+ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x81, 0x08, 0x14, 0x42,
+ 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52,
+ 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24,
+ 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a,
+ 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86,
+ 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
+ 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
+ 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
+ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
+ 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
+ 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+ 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+ 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9
+};
+
+#endif
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_mem.c b/drivers/media/video/samsung/jpeg_v2/jpg_mem.c
new file mode 100644
index 0000000..55ced19
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_mem.c
@@ -0,0 +1,62 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_mem.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Operation for Jpeg encoder/docoder with memory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <asm/io.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <linux/types.h>
+
+#include "jpg_mem.h"
+#include "jpg_misc.h"
+#include "jpg_opr.h"
+
+/*----------------------------------------------------------------------------
+*Function: phy_to_vir_addr
+
+*Parameters: dwContext :
+*Return Value: True/False
+*Implementation Notes: memory mapping from physical addr to virtual addr
+-----------------------------------------------------------------------------*/
+void *phy_to_vir_addr(UINT32 phy_addr, int mem_size)
+{
+ void *reserved_mem;
+
+ reserved_mem = (void *)ioremap((unsigned long)phy_addr, (int)mem_size);
+
+ if (reserved_mem == NULL) {
+ jpg_err("phyical to virtual memory mapping was failed!\r\n");
+ return NULL;
+ }
+
+ return reserved_mem;
+}
+
+void *mem_move(void *dst, const void *src, unsigned int size)
+{
+ return memmove(dst, src, size);
+}
+
+void *mem_alloc(unsigned int size)
+{
+ void *alloc_mem;
+
+ alloc_mem = (void *)kmalloc((int)size, GFP_KERNEL);
+
+ if (alloc_mem == NULL) {
+ jpg_err("memory allocation failed!\r\n");
+ return NULL;
+ }
+
+ return alloc_mem;
+}
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_mem.h b/drivers/media/video/samsung/jpeg_v2/jpg_mem.h
new file mode 100644
index 0000000..f72d694
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_mem.h
@@ -0,0 +1,144 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_mem.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition for Operation of Jpeg encoder/docoder with memory
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_MEM_H__
+#define __JPG_MEM_H__
+
+#include "jpg_misc.h"
+
+#include <linux/version.h>
+#include <plat/media.h>
+
+#define JPG_REG_BASE_ADDR (0xFB600000)
+
+#define jpg_data_base_addr (UINT32)s3c_get_media_memory_bank(S3C_MDEV_JPEG, 0)
+
+#define MAX_JPG_WIDTH 2560
+#define MAX_JPG_HEIGHT 1920
+#define MAX_JPG_RESOLUTION (MAX_JPG_WIDTH * MAX_JPG_HEIGHT)
+
+/* It assumes that JPG thumbnail is not used
+ * Set the resolution when you need to use */
+#define MAX_JPG_THUMBNAIL_WIDTH 0
+#define MAX_JPG_THUMBNAIL_HEIGHT 0
+#define MAX_JPG_THUMBNAIL_RESOLUTION (MAX_JPG_THUMBNAIL_WIDTH * MAX_JPG_THUMBNAIL_HEIGHT)
+
+/* It assumes that RGB data encoding is not used
+ * Set the resolution when you need to use */
+#define MAX_RGB_WIDTH 0
+#define MAX_RGB_HEIGHT 0
+#define MAX_RGB_RESOLUTION (MAX_RGB_WIDTH * MAX_RGB_HEIGHT)
+
+/*******************************************************************************/
+/* define JPG & image memory */
+/* memory area is 4k(PAGE_SIZE) aligned because of VirtualCopyEx() */
+
+/* Below definitions assume that JPEG_V2 uses only decoding without thumbnail.
+ * Max jpeg size of camera input is 3M, and decoded output data is YUV422.
+ * To reduce unnecessary memory reservation,
+ * useless definitions are set to 0. */
+#define JPG_STREAM_BUF_SIZE 3*1024*1024
+#define JPG_STREAM_THUMB_BUF_SIZE 0
+#define JPG_FRAME_BUF_SIZE \
+ ((MAX_JPG_RESOLUTION * 2) / PAGE_SIZE + 1) * PAGE_SIZE
+#define JPG_FRAME_THUMB_BUF_SIZE 0
+#define JPG_RGB_BUF_SIZE 0
+
+/* Use below definitions if you need to use encoding and thumbnail
+ * Begin of definitions
+#define JPG_STREAM_BUF_SIZE \
+ (MAX_JPG_RESOLUTION / PAGE_SIZE + 1) * PAGE_SIZE
+#define JPG_STREAM_THUMB_BUF_SIZE \
+ (MAX_JPG_THUMBNAIL_RESOLUTION / PAGE_SIZE + 1) * PAGE_SIZE
+#define JPG_FRAME_BUF_SIZE \
+ ((MAX_JPG_RESOLUTION * 3) / PAGE_SIZE + 1) * PAGE_SIZE
+#define JPG_FRAME_THUMB_BUF_SIZE \
+ ((MAX_JPG_THUMBNAIL_RESOLUTION * 3) / PAGE_SIZE + 1) * PAGE_SIZE
+#define JPG_RGB_BUF_SIZE \
+ ((MAX_RGB_RESOLUTION * 4) / PAGE_SIZE + 1) * PAGE_SIZE
+end of definitions */
+
+
+#define JPG_TOTAL_BUF_SIZE (JPG_STREAM_BUF_SIZE + \
+ JPG_STREAM_THUMB_BUF_SIZE + \
+ JPG_FRAME_BUF_SIZE + \
+ JPG_FRAME_THUMB_BUF_SIZE + \
+ JPG_RGB_BUF_SIZE)
+
+#define JPG_MAIN_STRART 0x00
+#define JPG_THUMB_START JPG_STREAM_BUF_SIZE
+#define IMG_MAIN_START (JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE)
+#define IMG_THUMB_START (IMG_MAIN_START + JPG_FRAME_BUF_SIZE)
+
+/*******************************************************************************/
+#define COEF1_RGB_2_YUV 0x4d971e
+#define COEF2_RGB_2_YUV 0x2c5783
+#define COEF3_RGB_2_YUV 0x836e13
+
+/*
+ * JPEG HW Register Macro Definition
+ */
+#define JPG_1BIT_MASK 1
+#define JPG_4BIT_MASK 0xF
+
+/* SubSampling_Mode Mask is JPGMOD Register [2:0] bits mask */
+#define JPG_SMPL_MODE_MASK 0x07
+
+/* Restart Interval value in JPGDRI Register is 2*/
+#define JPG_RESTART_INTRAVEL 2
+
+/* HCLK_JPEG is CLK_GATE_D1_1 Register 5th bit */
+#define JPG_HCLK_JPEG_BIT 5
+/* SubSampling_Mode is JPGMOD Register 0th bit */
+#define JPG_SMPL_MODE_BIT 0
+/* Quantization Table #1 is JPGQHNO Register 8th bit */
+#define JPG_QUANT_TABLE1_BIT 8
+/* Quantization Table #2 is JPGQHNO Register 10th bit */
+#define JPG_QUANT_TABLE2_BIT 10
+/* Quantization Table #3 is JPGQHNO Register 12th bit */
+#define JPG_QUANT_TABLE3_BIT 12
+/* Mode Sel is JPGCMOD Register 5th bit */
+#define JPG_MODE_SEL_BIT 5
+
+#define JPG_DECODE (0x1 << 3)
+#define JPG_ENCODE (0x0 << 3)
+
+#define JPG_RESERVE_ZERO (0b000 << 2)
+
+#define ENABLE_MOTION_ENC (0x1<<3)
+#define DISABLE_MOTION_ENC (0x0<<3)
+
+#define ENABLE_MOTION_DEC (0x1<<0)
+#define DISABLE_MOTION_DEC (0x0<<0)
+
+#define ENABLE_HW_DEC (0x1<<2)
+#define DISABLE_HW_DEC (0x0<<2)
+
+#define INCREMENTAL_DEC (0x1<<3)
+#define NORMAL_DEC (0x0<<3)
+#define YCBCR_MEMORY (0x1<<5)
+
+#define ENABLE_IRQ (0xf<<3)
+
+typedef struct __s5pc100_jpg_ctx {
+ volatile UINT32 jpg_data_addr;
+ volatile UINT32 img_data_addr;
+ volatile UINT32 jpg_thumb_data_addr;
+ volatile UINT32 img_thumb_data_addr;
+ int caller_process;
+} sspc100_jpg_ctx;
+
+void *phy_to_vir_addr(UINT32 phy_addr, int mem_size);
+void *mem_move(void *dst, const void *src, unsigned int size);
+void *mem_alloc(unsigned int size);
+#endif
+
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_misc.c b/drivers/media/video/samsung/jpeg_v2/jpg_misc.c
new file mode 100644
index 0000000..85c8f34
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_misc.c
@@ -0,0 +1,80 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_misc.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Operation for Jpeg encoder/docoder with mutex
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <stdarg.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+
+#include "jpg_misc.h"
+#include "jpg_mem.h"
+
+static HANDLE h_mutex = NULL;
+
+/*----------------------------------------------------------------------------
+*Function: create_jpg_mutex
+*Implementation Notes: Create Mutex handle
+-----------------------------------------------------------------------------*/
+HANDLE create_jpg_mutex(void)
+{
+ h_mutex = (HANDLE)kmalloc(sizeof(struct mutex), GFP_KERNEL);
+
+ if (h_mutex == NULL)
+ return NULL;
+
+ mutex_init(h_mutex);
+
+ return h_mutex;
+}
+
+/*----------------------------------------------------------------------------
+*Function: lock_jpg_mutex
+*Implementation Notes: lock mutex
+-----------------------------------------------------------------------------*/
+DWORD lock_jpg_mutex(void)
+{
+ mutex_lock(h_mutex);
+ return 1;
+}
+
+/*----------------------------------------------------------------------------
+*Function: unlock_jpg_mutex
+*Implementation Notes: unlock mutex
+-----------------------------------------------------------------------------*/
+DWORD unlock_jpg_mutex(void)
+{
+ mutex_unlock(h_mutex);
+
+ return 1;
+}
+
+/*----------------------------------------------------------------------------
+*Function: delete_jpg_mutex
+*Implementation Notes: delete mutex handle
+-----------------------------------------------------------------------------*/
+void delete_jpg_mutex(void)
+{
+ if (h_mutex == NULL)
+ return;
+
+ mutex_destroy(h_mutex);
+}
+
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_misc.h b/drivers/media/video/samsung/jpeg_v2/jpg_misc.h
new file mode 100644
index 0000000..8581f55
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_misc.h
@@ -0,0 +1,34 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_misc.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition for Operation of Jpeg encoder/docoder with mutex
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_MISC_H__
+#define __JPG_MISC_H__
+
+#include <linux/types.h>
+
+typedef unsigned char UCHAR;
+typedef unsigned long ULONG;
+typedef unsigned int UINT;
+typedef struct mutex * HANDLE;
+typedef unsigned long DWORD;
+typedef unsigned int UINT32;
+typedef unsigned char UINT8;
+typedef enum {FALSE, TRUE} BOOL;
+
+#define INT_TIMEOUT 1000
+
+HANDLE create_jpg_mutex(void);
+DWORD lock_jpg_mutex(void);
+DWORD unlock_jpg_mutex(void);
+void delete_jpg_mutex(void);
+
+#endif
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_opr.c b/drivers/media/video/samsung/jpeg_v2/jpg_opr.c
new file mode 100644
index 0000000..a512c80
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_opr.c
@@ -0,0 +1,310 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_opr.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Operation for Jpeg encoder/docoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include "jpg_mem.h"
+#include "jpg_misc.h"
+#include "jpg_opr.h"
+#include "jpg_conf.h"
+
+#include "regs-jpeg.h"
+
+extern void __iomem *s3c_jpeg_base;
+extern int jpg_irq_reason;
+
+enum {
+ UNKNOWN,
+ BASELINE = 0xC0,
+ EXTENDED_SEQ = 0xC1,
+ PROGRESSIVE = 0xC2
+} jpg_sof_marker;
+
+jpg_return_status wait_for_interrupt(void)
+{
+ if (interruptible_sleep_on_timeout(&wait_queue_jpeg, INT_TIMEOUT) == 0) {
+ jpg_err("waiting for interrupt is timeout\n");
+ }
+
+ return jpg_irq_reason;
+}
+
+jpg_return_status decode_jpg(sspc100_jpg_ctx *jpg_ctx,
+ jpg_dec_proc_param *dec_param)
+{
+ volatile int ret;
+ sample_mode_t sample_mode;
+ UINT32 width, height;
+ jpg_dbg("enter decode_jpg function\n");
+
+ if (jpg_ctx)
+ reset_jpg(jpg_ctx);
+ else {
+ jpg_err("jpg ctx is NULL\n");
+ return JPG_FAIL;
+ }
+
+/* set jpeg clock register : power on */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_CLKCON_REG) |
+ (S3C_JPEG_CLKCON_REG_POWER_ON_ACTIVATE),
+ s3c_jpeg_base + S3C_JPEG_CLKCON_REG);
+ /* set jpeg mod register : decode */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_MOD_REG) |
+ (S3C_JPEG_MOD_REG_PROC_DEC),
+ s3c_jpeg_base + S3C_JPEG_MOD_REG);
+ /* set jpeg interrupt setting register */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_INTSE_REG) |
+ (S3C_JPEG_INTSE_REG_RSTM_INT_EN |
+ S3C_JPEG_INTSE_REG_DATA_NUM_INT_EN |
+ S3C_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN),
+ s3c_jpeg_base + S3C_JPEG_INTSE_REG);
+ /* set jpeg deocde ouput format register */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_OUTFORM_REG) &
+ ~(S3C_JPEG_OUTFORM_REG_YCBCY420),
+ s3c_jpeg_base + S3C_JPEG_OUTFORM_REG);
+ writel(readl(s3c_jpeg_base + S3C_JPEG_OUTFORM_REG) |
+ (dec_param->out_format << 0),
+ s3c_jpeg_base + S3C_JPEG_OUTFORM_REG);
+
+ /* set the address of compressed input data */
+ writel(jpg_ctx->img_data_addr, s3c_jpeg_base + S3C_JPEG_IMGADR_REG);
+
+ /* set the address of decompressed image */
+ writel(jpg_ctx->jpg_data_addr, s3c_jpeg_base + S3C_JPEG_JPGADR_REG);
+
+ /* start decoding */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_JRSTART_REG) |
+ S3C_JPEG_JRSTART_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_JSTART_REG);
+
+ ret = wait_for_interrupt();
+
+ if (ret != OK_ENC_OR_DEC) {
+ jpg_err("jpg decode error(%d)\n", ret);
+ return JPG_FAIL;
+ }
+
+ sample_mode = get_sample_type(jpg_ctx);
+ jpg_dbg("sample_mode : %d\n", sample_mode);
+
+ if (sample_mode == JPG_SAMPLE_UNKNOWN) {
+ jpg_err("jpg has invalid sample_mode\r\n");
+ return JPG_FAIL;
+ }
+
+ dec_param->sample_mode = sample_mode;
+
+ get_xy(jpg_ctx, &width, &height);
+ jpg_dbg("decode size:: width : %d height : %d\n", width, height);
+
+ dec_param->data_size = get_yuv_size(dec_param->out_format, width, height);
+ dec_param->width = width;
+ dec_param->height = height;
+
+ return JPG_SUCCESS;
+}
+
+void reset_jpg(sspc100_jpg_ctx *jpg_ctx)
+{
+jpg_dbg("s3c_jpeg_base %p \n", s3c_jpeg_base);
+ writel(S3C_JPEG_SW_RESET_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_SW_RESET_REG);
+
+ do {
+ writel(S3C_JPEG_SW_RESET_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_SW_RESET_REG);
+ } while (((readl(s3c_jpeg_base + S3C_JPEG_SW_RESET_REG))
+ & S3C_JPEG_SW_RESET_REG_ENABLE) == S3C_JPEG_SW_RESET_REG_ENABLE);
+}
+
+sample_mode_t get_sample_type(sspc100_jpg_ctx *jpg_ctx)
+{
+ ULONG jpgMode;
+ sample_mode_t sample_mode = JPG_SAMPLE_UNKNOWN;
+
+ jpgMode = readl(s3c_jpeg_base + S3C_JPEG_MOD_REG);
+
+ sample_mode =
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_444) ? JPG_444 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_422) ? JPG_422 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_420) ? JPG_420 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_400) ? JPG_400 :
+ ((jpgMode & JPG_SMPL_MODE_MASK) == JPG_411) ? JPG_411 : JPG_SAMPLE_UNKNOWN;
+
+ return(sample_mode);
+}
+
+void get_xy(sspc100_jpg_ctx *jpg_ctx, UINT32 *x, UINT32 *y)
+{
+ *x = (readl(s3c_jpeg_base + S3C_JPEG_X_U_REG)<<8)|
+ readl(s3c_jpeg_base + S3C_JPEG_X_L_REG);
+ *y = (readl(s3c_jpeg_base + S3C_JPEG_Y_U_REG)<<8)|
+ readl(s3c_jpeg_base + S3C_JPEG_Y_L_REG);
+}
+
+UINT32 get_yuv_size(out_mode_t out_format, UINT32 width, UINT32 height)
+{
+ switch (out_format) {
+ case YCBCR_422 :
+
+ if (width % 16 != 0)
+ width += 16 - (width % 16);
+
+ if (height % 8 != 0)
+ height += 8 - (height % 8);
+
+ break;
+
+ case YCBCR_420 :
+
+ if (width % 16 != 0)
+ width += 16 - (width % 16);
+
+ if (height % 16 != 0)
+ height += 16 - (height % 16);
+
+ break;
+
+ case YCBCR_SAMPLE_UNKNOWN:
+ break;
+ }
+
+ jpg_dbg("get_yuv_size width(%d) height(%d)\n", width, height);
+
+ switch (out_format) {
+ case YCBCR_422 :
+ return(width*height*2);
+ case YCBCR_420 :
+ return((width*height) + (width*height >> 1));
+ default :
+ return(0);
+ }
+}
+
+jpg_return_status encode_jpg(sspc100_jpg_ctx *jpg_ctx,
+ jpg_enc_proc_param *enc_param)
+{
+
+ UINT i, ret;
+ UINT32 cmd_val;
+
+ if (enc_param->width <= 0 || enc_param->width > MAX_JPG_WIDTH
+ || enc_param->height <= 0 || enc_param->height > MAX_JPG_HEIGHT) {
+ jpg_err("::encoder : width: %d, height: %d \n",
+ enc_param->width, enc_param->height);
+ jpg_err("::encoder : invalid width/height \n");
+ return JPG_FAIL;
+ }
+
+/* SW reset */
+ if (jpg_ctx)
+ reset_jpg(jpg_ctx);
+ else {
+ jpg_err("::jpg ctx is NULL\n");
+ return JPG_FAIL;
+ }
+ /* set jpeg clock register : power on */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_CLKCON_REG) |
+ (S3C_JPEG_CLKCON_REG_POWER_ON_ACTIVATE),
+ s3c_jpeg_base + S3C_JPEG_CLKCON_REG);
+ /* set jpeg mod register : encode */
+ writel(readl(s3c_jpeg_base + S3C_JPEG_CMOD_REG) |
+ (enc_param->in_format << JPG_MODE_SEL_BIT),
+ s3c_jpeg_base + S3C_JPEG_CMOD_REG);
+ cmd_val = (enc_param->sample_mode == JPG_422) ?
+ (S3C_JPEG_MOD_REG_SUBSAMPLE_422) : (S3C_JPEG_MOD_REG_SUBSAMPLE_420);
+
+ writel(cmd_val | S3C_JPEG_MOD_REG_PROC_ENC, s3c_jpeg_base + S3C_JPEG_MOD_REG);
+
+ /* set DRI(Define Restart Interval) */
+ writel(JPG_RESTART_INTRAVEL, s3c_jpeg_base + S3C_JPEG_DRI_L_REG);
+ writel((JPG_RESTART_INTRAVEL>>8), s3c_jpeg_base + S3C_JPEG_DRI_U_REG);
+
+ writel(S3C_JPEG_QHTBL_REG_QT_NUM1, s3c_jpeg_base + S3C_JPEG_QTBL_REG);
+ writel(0x00, s3c_jpeg_base + S3C_JPEG_HTBL_REG);
+
+ /* Horizontal resolution */
+ writel((enc_param->width>>8), s3c_jpeg_base + S3C_JPEG_X_U_REG);
+ writel(enc_param->width, s3c_jpeg_base + S3C_JPEG_X_L_REG);
+
+ /* Vertical resolution */
+ writel((enc_param->height>>8), s3c_jpeg_base + S3C_JPEG_Y_U_REG);
+ writel(enc_param->height, s3c_jpeg_base + S3C_JPEG_Y_L_REG);
+
+ jpg_dbg("enc_param->enc_type : %d\n", enc_param->enc_type);
+
+ if (enc_param->enc_type == JPG_MAIN) {
+ jpg_dbg("encode image size width: %d, height: %d\n",
+ enc_param->width, enc_param->height);
+ writel(jpg_ctx->img_data_addr, s3c_jpeg_base + S3C_JPEG_IMGADR_REG);
+ writel(jpg_ctx->jpg_data_addr, s3c_jpeg_base + S3C_JPEG_JPGADR_REG);
+ } else { // thumbnail encoding
+ jpg_dbg("thumb image size width: %d, height: %d\n",
+ enc_param->width, enc_param->height);
+ writel(jpg_ctx->img_thumb_data_addr, s3c_jpeg_base + S3C_JPEG_IMGADR_REG);
+ writel(jpg_ctx->jpg_thumb_data_addr, s3c_jpeg_base + S3C_JPEG_JPGADR_REG);
+ }
+
+ /* Coefficient value 1~3 for RGB to YCbCr */
+ writel(COEF1_RGB_2_YUV, s3c_jpeg_base + S3C_JPEG_COEF1_REG);
+ writel(COEF2_RGB_2_YUV, s3c_jpeg_base + S3C_JPEG_COEF2_REG);
+ writel(COEF3_RGB_2_YUV, s3c_jpeg_base + S3C_JPEG_COEF3_REG);
+
+ /* Quantiazation and Huffman Table setting */
+ for (i = 0; i < 64; i++) {
+ writel((UINT32)qtbl_luminance[enc_param->quality][i],
+ s3c_jpeg_base + S3C_JPEG_QTBL0_REG + (i*0x04));
+ }
+ for (i = 0; i < 64; i++) {
+ writel((UINT32)qtbl_chrominance[enc_param->quality][i],
+ s3c_jpeg_base + S3C_JPEG_QTBL1_REG + (i*0x04));
+ }
+ for (i = 0; i < 16; i++) {
+ writel((UINT32)hdctbl0[i],
+ s3c_jpeg_base + S3C_JPEG_HDCTBL0_REG + (i*0x04));
+ }
+ for (i = 0; i < 12; i++) {
+ writel((UINT32)hdctblg0[i],
+ s3c_jpeg_base + S3C_JPEG_HDCTBLG0_REG + (i*0x04));
+ }
+ for (i = 0; i < 16; i++) {
+ writel((UINT32)hactbl0[i],
+ s3c_jpeg_base + S3C_JPEG_HACTBL0_REG + (i*0x04));
+ }
+ for (i = 0; i < 162; i++) {
+ writel((UINT32)hactblg0[i],
+ s3c_jpeg_base + S3C_JPEG_HACTBLG0_REG + (i*0x04));
+ }
+ writel(readl(s3c_jpeg_base + S3C_JPEG_INTSE_REG) |
+ (S3C_JPEG_INTSE_REG_RSTM_INT_EN |
+ S3C_JPEG_INTSE_REG_DATA_NUM_INT_EN |
+ S3C_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN),
+ s3c_jpeg_base + S3C_JPEG_INTSE_REG);
+
+ writel(readl(s3c_jpeg_base + S3C_JPEG_JSTART_REG) |
+ S3C_JPEG_JSTART_REG_ENABLE,
+ s3c_jpeg_base + S3C_JPEG_JSTART_REG);
+ ret = wait_for_interrupt();
+
+ if (ret != OK_ENC_OR_DEC) {
+ jpg_err("jpeg encoding error(%d)\n", ret);
+ return JPG_FAIL;
+ }
+
+ enc_param->file_size = readl(s3c_jpeg_base + S3C_JPEG_CNT_U_REG) << 16;
+ enc_param->file_size |= readl(s3c_jpeg_base + S3C_JPEG_CNT_M_REG) << 8;
+ enc_param->file_size |= readl(s3c_jpeg_base + S3C_JPEG_CNT_L_REG);
+
+ return JPG_SUCCESS;
+
+}
diff --git a/drivers/media/video/samsung/jpeg_v2/jpg_opr.h b/drivers/media/video/samsung/jpeg_v2/jpg_opr.h
new file mode 100644
index 0000000..5ad142c
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/jpg_opr.h
@@ -0,0 +1,153 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/jpg_opr.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Definition for Operation of Jpeg encoder/docoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __JPG_OPR_H__
+#define __JPG_OPR_H__
+
+#include <linux/interrupt.h>
+
+
+/* debug macro */
+#define JPG_DEBUG(fmt, ...) \
+ do { \
+ printk(KERN_DEBUG \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while(0)
+
+
+#define JPG_WARN(fmt, ...) \
+ do { \
+ printk(KERN_WARNING \
+ fmt, ##__VA_ARGS__); \
+ } while (0)
+
+
+
+#define JPG_ERROR(fmt, ...) \
+ do { \
+ printk(KERN_ERR \
+ "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+
+
+#ifdef CONFIG_VIDEO_JPEG_DEBUG
+#define jpg_dbg(fmt, ...) JPG_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define jpg_dbg(fmt, ...)
+#endif
+
+#define jpg_warn(fmt, ...) JPG_WARN(fmt, ##__VA_ARGS__)
+#define jpg_err(fmt, ...) JPG_ERROR(fmt, ##__VA_ARGS__)
+
+extern wait_queue_head_t wait_queue_jpeg;
+
+typedef enum {
+ JPG_FAIL,
+ JPG_SUCCESS,
+ OK_HD_PARSING,
+ ERR_HD_PARSING,
+ OK_ENC_OR_DEC,
+ ERR_ENC_OR_DEC,
+ ERR_UNKNOWN
+} jpg_return_status;
+
+typedef enum {
+ JPG_RGB16,
+ JPG_YCBYCR,
+ JPG_TYPE_UNKNOWN
+} image_type_t;
+
+typedef enum {
+ JPG_444,
+ JPG_422,
+ JPG_420,
+ JPG_400,
+ RESERVED1,
+ RESERVED2,
+ JPG_411,
+ JPG_SAMPLE_UNKNOWN
+} sample_mode_t;
+
+typedef enum {
+ YCBCR_422,
+ YCBCR_420,
+ YCBCR_SAMPLE_UNKNOWN
+} out_mode_t;
+
+typedef enum {
+ JPG_MODESEL_YCBCR = 1,
+ JPG_MODESEL_RGB,
+ JPG_MODESEL_UNKNOWN
+} in_mode_t;
+
+typedef enum {
+ JPG_MAIN,
+ JPG_THUMBNAIL
+} encode_type_t;
+
+typedef enum {
+ JPG_QUALITY_LEVEL_1 = 0, /*high quality*/
+ JPG_QUALITY_LEVEL_2,
+ JPG_QUALITY_LEVEL_3,
+ JPG_QUALITY_LEVEL_4 /*low quality*/
+} image_quality_type_t;
+
+typedef struct {
+ sample_mode_t sample_mode;
+ encode_type_t dec_type;
+ out_mode_t out_format;
+ UINT32 width;
+ UINT32 height;
+ UINT32 data_size;
+ UINT32 file_size;
+} jpg_dec_proc_param;
+
+typedef struct {
+ sample_mode_t sample_mode;
+ encode_type_t enc_type;
+ in_mode_t in_format;
+ image_quality_type_t quality;
+ UINT32 width;
+ UINT32 height;
+ UINT32 data_size;
+ UINT32 file_size;
+} jpg_enc_proc_param;
+
+typedef struct {
+ char *in_buf;
+ char *phy_in_buf;
+ int in_buf_size;
+ char *out_buf;
+ char *phy_out_buf;
+ int out_buf_size;
+ char *in_thumb_buf;
+ char *phy_in_thumb_buf;
+ int in_thumb_buf_size;
+ char *out_thumb_buf;
+ char *phy_out_thumb_buf;
+ int out_thumb_buf_size;
+ char *mapped_addr;
+ jpg_dec_proc_param *dec_param;
+ jpg_enc_proc_param *enc_param;
+ jpg_enc_proc_param *thumb_enc_param;
+} jpg_args;
+
+void reset_jpg(sspc100_jpg_ctx *jpg_ctx);
+jpg_return_status decode_jpg(sspc100_jpg_ctx *jpg_ctx, jpg_dec_proc_param *dec_param);
+jpg_return_status encode_jpg(sspc100_jpg_ctx *jpg_ctx, jpg_enc_proc_param *enc_param);
+jpg_return_status wait_for_interrupt(void);
+sample_mode_t get_sample_type(sspc100_jpg_ctx *jpg_ctx);
+void get_xy(sspc100_jpg_ctx *jpg_ctx, UINT32 *x, UINT32 *y);
+UINT32 get_yuv_size(out_mode_t out_format, UINT32 width, UINT32 height);
+
+#endif
diff --git a/drivers/media/video/samsung/jpeg_v2/regs-jpeg.h b/drivers/media/video/samsung/jpeg_v2/regs-jpeg.h
new file mode 100644
index 0000000..e156e7b
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/regs-jpeg.h
@@ -0,0 +1,147 @@
+/* linux/drivers/media/video/samsung/jpeg/regs-jpeg.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Register definition file for Samsung JPEG Encoder/Decoder
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARM_REGS_S3C_JPEG_H
+#define __ASM_ARM_REGS_S3C_JPEG_H
+
+/*************************************************************************/
+/*JPEG Registers part */
+/*************************************************************************/
+#define S3C_JPEG_REG(x) ((x))
+
+/* JPEG Codec Control Registers */
+
+#define S3C_JPEG_MOD_REG S3C_JPEG_REG(0x00) /* Sub-sampling Mode Register */
+#define S3C_JPEG_OPR_REG S3C_JPEG_REG(0x04) /* Operation Status Register */
+#define S3C_JPEG_QTBL_REG S3C_JPEG_REG(0x08) /* Quantization Table Number Register and Huffman Table Number Register */
+#define S3C_JPEG_HTBL_REG S3C_JPEG_REG(0x0c) /* Huffman Table Number Register */
+#define S3C_JPEG_DRI_U_REG S3C_JPEG_REG(0x10) /* MCU, which inserts RST marker(upper 8bit) */
+#define S3C_JPEG_DRI_L_REG S3C_JPEG_REG(0x14) /* MCU, which inserts RST marker(lower 8bit) */
+#define S3C_JPEG_Y_U_REG S3C_JPEG_REG(0x18) /* Vertical Resolution (upper 8bit) */
+#define S3C_JPEG_Y_L_REG S3C_JPEG_REG(0x1c) /* Vertical Resolution (lower 8bit) */
+#define S3C_JPEG_X_U_REG S3C_JPEG_REG(0x20) /* Horizontal Resolution (upper 8bit) */
+#define S3C_JPEG_X_L_REG S3C_JPEG_REG(0x24) /* Horizontal Resolution (lower 8bit) */
+#define S3C_JPEG_CNT_U_REG S3C_JPEG_REG(0x28) /* The amount of the compressed data in bytes (upper 8bit) */
+#define S3C_JPEG_CNT_M_REG S3C_JPEG_REG(0x2c) /* The amount of the compressed data in bytes (middle 8bit) */
+#define S3C_JPEG_CNT_L_REG S3C_JPEG_REG(0x30) /* The amount of the compressed data in bytes (lowerz 8bit) */
+#define S3C_JPEG_INTSE_REG S3C_JPEG_REG(0x34) /* Interrupt setting register */
+#define S3C_JPEG_INTST_REG S3C_JPEG_REG(0x38) /* Interrupt status */
+
+#define S3C_JPEG_COM_REG S3C_JPEG_REG(0x4c) /* Command register */
+
+#define S3C_JPEG_IMGADR_REG S3C_JPEG_REG(0x50) /* Source or destination image addresss */
+
+#define S3C_JPEG_JPGADR_REG S3C_JPEG_REG(0x58) /* Source or destination JPEG file address */
+#define S3C_JPEG_COEF1_REG S3C_JPEG_REG(0x5c) /* Coefficient values for RGB <-> YCbCr converter */
+#define S3C_JPEG_COEF2_REG S3C_JPEG_REG(0x60) /* Coefficient values for RGB <-> YCbCr converter */
+#define S3C_JPEG_COEF3_REG S3C_JPEG_REG(0x64) /* Coefficient values for RGB <-> YCbCr converter */
+
+#define S3C_JPEG_CMOD_REG S3C_JPEG_REG(0x68) /* Mode selection and core clock setting */
+#define S3C_JPEG_CLKCON_REG S3C_JPEG_REG(0x6c) /* Power on/off and clock down control */
+
+#define S3C_JPEG_JSTART_REG S3C_JPEG_REG(0x70) /* Start compression or decompression */
+#define S3C_JPEG_JRSTART_REG S3C_JPEG_REG(0x74) /* Restart decompression after header analysis */
+#define S3C_JPEG_SW_RESET_REG S3C_JPEG_REG(0x78) /* S/W reset */
+
+#define S3C_JPEG_TIMER_SE_REG S3C_JPEG_REG(0x7c) /* Internal timer setting register */
+#define S3C_JPEG_TIMER_ST_REG S3C_JPEG_REG(0x80) /* Internal timer status register */
+#define S3C_JPEG_COMSTAT_REG S3C_JPEG_REG(0x84) /* Command status register */
+#define S3C_JPEG_OUTFORM_REG S3C_JPEG_REG(0x88) /* Output color format of decompression */
+#define S3C_JPEG_VERSION_REG S3C_JPEG_REG(0x8c) /* Version register */
+
+#define S3C_JPEG_ENC_STREAM_INTSE_REG S3C_JPEG_REG(0x98) /* Compressed stream size interrupt setting register */
+#define S3C_JPEG_ENC_STREAM_INTST_REG S3C_JPEG_REG(0x9c) /* Compressed stream size interrupt status register */
+
+#define S3C_JPEG_QTBL0_REG S3C_JPEG_REG(0x400) /* Quantization table 0 */
+#define S3C_JPEG_QTBL1_REG S3C_JPEG_REG(0x500) /* Quantization table 1 */
+#define S3C_JPEG_QTBL2_REG S3C_JPEG_REG(0x600) /* Quantization table 2 */
+#define S3C_JPEG_QTBL3_REG S3C_JPEG_REG(0x700) /* Quantization table 3 */
+
+#define S3C_JPEG_HDCTBL0_REG S3C_JPEG_REG(0x800) /* DC huffman table 0 */
+#define S3C_JPEG_HDCTBLG0_REG S3C_JPEG_REG(0x840) /* DC huffman table group 0 */
+#define S3C_JPEG_HACTBL0_REG S3C_JPEG_REG(0x880) /* AC huffman table 0 */
+#define S3C_JPEG_HACTBLG0_REG S3C_JPEG_REG(0x8c0) /* AC huffman table group 0 */
+#define S3C_JPEG_HDCTBL1_REG S3C_JPEG_REG(0xc00) /* DC huffman table 1 */
+#define S3C_JPEG_HDCTBLG1_REG S3C_JPEG_REG(0xc40) /* DC huffman table group 1 */
+#define S3C_JPEG_HACTBL1_REG S3C_JPEG_REG(0xc80) /* AC huffman table 1 */
+#define S3C_JPEG_HACTBLG1_REG S3C_JPEG_REG(0xcc0) /* AC huffman table group 1 */
+
+/*************************************************************************/
+/* Bit definition part */
+/*************************************************************************/
+
+/* JPEG Mode Register bit */
+#define S3C_JPEG_MOD_REG_PROC_ENC (0<<3)
+#define S3C_JPEG_MOD_REG_PROC_DEC (1<<3)
+
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_444 (0<<0)
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_422 (1<<0)
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_420 (2<<0)
+#define S3C_JPEG_MOD_REG_SUBSAMPLE_GRAY (3<<0)
+
+/* JPEG Operation Status Register bit */
+#define S3C_JPEG_OPR_REG_OPERATE (1<<0)
+#define S3C_JPEG_OPR_REG_NO_OPERATE (0<<0)
+
+/* Quantization Table And Huffman Table Number Register bit */
+#define S3C_JPEG_QHTBL_REG_QT_NUM4 (1<<6)
+#define S3C_JPEG_QHTBL_REG_QT_NUM3 (1<<4)
+#define S3C_JPEG_QHTBL_REG_QT_NUM2 (1<<2)
+#define S3C_JPEG_QHTBL_REG_QT_NUM1 (1<<0)
+
+#define S3C_JPEG_QHTBL_REG_HT_NUM4_AC (1<<7)
+#define S3C_JPEG_QHTBL_REG_HT_NUM4_DC (1<<6)
+#define S3C_JPEG_QHTBL_REG_HT_NUM3_AC (1<<5)
+#define S3C_JPEG_QHTBL_REG_HT_NUM3_DC (1<<4)
+#define S3C_JPEG_QHTBL_REG_HT_NUM2_AC (1<<3)
+#define S3C_JPEG_QHTBL_REG_HT_NUM2_DC (1<<2)
+#define S3C_JPEG_QHTBL_REG_HT_NUM1_AC (1<<1)
+#define S3C_JPEG_QHTBL_REG_HT_NUM1_DC (1<<0)
+
+
+/* JPEG Color Mode Register bit */
+#define S3C_JPEG_CMOD_REG_MOD_SEL_RGB (2<<5)
+#define S3C_JPEG_CMOD_REG_MOD_SEL_YCBCR422 (1<<5)
+#define S3C_JPEG_CMOD_REG_MOD_MODE_Y16 (1<<1)
+#define S3C_JPEG_CMOD_REG_MOD_MODE_0 (0<<1)
+
+/* JPEG Clock Control Register bit */
+#define S3C_JPEG_CLKCON_REG_CLK_DOWN_READY_ENABLE (0<<1)
+#define S3C_JPEG_CLKCON_REG_CLK_DOWN_READY_DISABLE (1<<1)
+#define S3C_JPEG_CLKCON_REG_POWER_ON_ACTIVATE (1<<0)
+#define S3C_JPEG_CLKCON_REG_POWER_ON_DISABLE (0<<0)
+
+/* JPEG Start Register bit */
+#define S3C_JPEG_JSTART_REG_ENABLE (1<<0)
+
+/* JPEG Rdstart Register bit */
+#define S3C_JPEG_JRSTART_REG_ENABLE (1<<0)
+
+/* JPEG SW Reset Register bit */
+#define S3C_JPEG_SW_RESET_REG_ENABLE (1<<0)
+
+/* JPEG Interrupt Setting Register bit */
+#define S3C_JPEG_INTSE_REG_RSTM_INT_EN (1<<7)
+#define S3C_JPEG_INTSE_REG_DATA_NUM_INT_EN (1<<6)
+#define S3C_JPEG_INTSE_REG_FINAL_MCU_NUM_INT_EN (1<<5)
+
+/* JPEG Decompression Output Format Register bit */
+#define S3C_JPEG_OUTFORM_REG_YCBCY422 (0<<0)
+#define S3C_JPEG_OUTFORM_REG_YCBCY420 (1<<0)
+
+/* JPEG Decompression Input Stream Size Register bit */
+#define S3C_JPEG_DEC_STREAM_SIZE_REG_PROHIBIT (0x1FFFFFFF<<0)
+
+/* JPEG Command Register bit */
+#define S3C_JPEG_COM_INT_RELEASE (1<<2)
+
+#endif //__ASM_ARM_REGS_S3C_JPEG_H
diff --git a/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c
new file mode 100644
index 0000000..bca4834
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c
@@ -0,0 +1,536 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Core file for Samsung Jpeg Interface driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/signal.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/kmod.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <mach/irqs.h>
+#include <linux/semaphore.h>
+#include <mach/map.h>
+#include <mach/pd.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+
+#include <linux/version.h>
+#include <plat/media.h>
+
+#include <linux/time.h>
+#include <linux/clk.h>
+
+#include "s3c-jpeg.h"
+#include "jpg_mem.h"
+#include "jpg_misc.h"
+#include "jpg_opr.h"
+#include "regs-jpeg.h"
+
+static struct clk *s3c_jpeg_clk;
+
+static struct resource *s3c_jpeg_mem;
+void __iomem *s3c_jpeg_base;
+static int irq_no;
+static int instanceNo = 0;
+volatile int jpg_irq_reason;
+wait_queue_head_t wait_queue_jpeg;
+
+
+DECLARE_WAIT_QUEUE_HEAD(WaitQueue_JPEG);
+irqreturn_t s3c_jpeg_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned int int_status;
+ unsigned int status;
+
+ jpg_dbg("=====enter s3c_jpeg_irq===== \r\n");
+
+ int_status = readl(s3c_jpeg_base + S3C_JPEG_INTST_REG);
+
+ do{
+ status = readl(s3c_jpeg_base + S3C_JPEG_OPR_REG);
+ }while(status);
+
+ writel(S3C_JPEG_COM_INT_RELEASE, s3c_jpeg_base + S3C_JPEG_COM_REG);
+ jpg_dbg("int_status : 0x%08x status : 0x%08x\n", int_status, status);
+
+ if (int_status) {
+ switch (int_status) {
+ case 0x40 :
+ jpg_irq_reason = OK_ENC_OR_DEC;
+ break;
+ case 0x20 :
+ jpg_irq_reason = ERR_ENC_OR_DEC;
+ break;
+ default :
+ jpg_irq_reason = ERR_UNKNOWN;
+ }
+
+ wake_up_interruptible(&wait_queue_jpeg);
+ } else {
+ jpg_irq_reason = ERR_UNKNOWN;
+ wake_up_interruptible(&wait_queue_jpeg);
+ }
+
+ return IRQ_HANDLED;
+}
+static int s3c_jpeg_open(struct inode *inode, struct file *file)
+{
+ sspc100_jpg_ctx *jpg_reg_ctx;
+ DWORD ret;
+
+ ret = s5pv210_pd_enable("jpeg_pd");
+ if (ret < 0) {
+ jpg_err("failed to enable jpeg power domain\n");
+ return FALSE;
+ }
+
+ /* clock enable */
+ clk_enable(s3c_jpeg_clk);
+
+ jpg_dbg("JPG_open \r\n");
+
+ jpg_reg_ctx = (sspc100_jpg_ctx *)mem_alloc(sizeof(sspc100_jpg_ctx));
+ memset(jpg_reg_ctx, 0x00, sizeof(sspc100_jpg_ctx));
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ unlock_jpg_mutex();
+ kfree(jpg_reg_ctx);
+ return FALSE;
+ }
+
+ if (instanceNo > MAX_INSTANCE_NUM) {
+ jpg_err("Instance Number error-JPEG is running, \
+ instance number is %d\n", instanceNo);
+ unlock_jpg_mutex();
+ kfree(jpg_reg_ctx);
+ return FALSE;
+ }
+
+ instanceNo++;
+
+ unlock_jpg_mutex();
+
+ file->private_data = (sspc100_jpg_ctx *)jpg_reg_ctx;
+
+ return 0;
+}
+
+
+static int s3c_jpeg_release(struct inode *inode, struct file *file)
+{
+ DWORD ret;
+ sspc100_jpg_ctx *jpg_reg_ctx;
+
+ jpg_dbg("JPG_Close\n");
+
+ jpg_reg_ctx = (sspc100_jpg_ctx *)file->private_data;
+
+ if (!jpg_reg_ctx) {
+ jpg_err("JPG Invalid Input Handle\r\n");
+ return FALSE;
+ }
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ return FALSE;
+ }
+
+ if ((--instanceNo) < 0)
+ instanceNo = 0;
+
+ unlock_jpg_mutex();
+ kfree(jpg_reg_ctx);
+
+/* clock disable */
+ clk_disable(s3c_jpeg_clk);
+ ret = s5pv210_pd_disable("jpeg_pd");
+ if (ret < 0) {
+ jpg_err("failed to disable jpeg power domain\n");
+ return FALSE;
+ }
+
+ return 0;
+}
+
+
+static ssize_t s3c_jpeg_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+{
+ return 0;
+}
+
+static ssize_t s3c_jpeg_read(struct file *file, char *buf, size_t count, loff_t *pos)
+{
+ return 0;
+}
+
+static int s3c_jpeg_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ static sspc100_jpg_ctx *jpg_reg_ctx;
+ jpg_args param;
+ BOOL result = TRUE;
+ DWORD ret;
+ int out;
+
+
+ jpg_reg_ctx = (sspc100_jpg_ctx *)file->private_data;
+
+ if (!jpg_reg_ctx) {
+ jpg_err("JPG Invalid Input Handle\r\n");
+ return FALSE;
+ }
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ return FALSE;
+ }
+
+ switch (cmd) {
+ case IOCTL_JPG_DECODE:
+
+ jpg_dbg("IOCTL_JPEG_DECODE\n");
+
+ out = copy_from_user(&param, (jpg_args *)arg, sizeof(jpg_args));
+
+ jpg_reg_ctx->jpg_data_addr = (UINT32)jpg_data_base_addr;
+ jpg_reg_ctx->img_data_addr = (UINT32)jpg_data_base_addr
+ + JPG_STREAM_BUF_SIZE
+ + JPG_STREAM_THUMB_BUF_SIZE;
+
+ result = decode_jpg(jpg_reg_ctx, param.dec_param);
+ out = copy_to_user((void *)arg, (void *) & param, sizeof(jpg_args));
+ break;
+
+ case IOCTL_JPG_ENCODE:
+
+ jpg_dbg("IOCTL_JPEG_ENCODE\n");
+
+ out = copy_from_user(&param, (jpg_args *)arg, sizeof(jpg_args));
+
+ jpg_dbg("encode size :: width : %d hegiht : %d\n",
+ param.enc_param->width, param.enc_param->height);
+
+ if (param.enc_param->enc_type == JPG_MAIN) {
+ jpg_reg_ctx->jpg_data_addr = (UINT32)jpg_data_base_addr ;
+ jpg_reg_ctx->img_data_addr = (UINT32)jpg_data_base_addr
+ + JPG_STREAM_BUF_SIZE
+ + JPG_STREAM_THUMB_BUF_SIZE;
+ jpg_dbg("enc_img_data_addr=0x%08x, enc_jpg_data_addr=0x%08x\n"
+ , jpg_reg_ctx->img_data_addr,jpg_reg_ctx->jpg_data_addr);
+
+ result = encode_jpg(jpg_reg_ctx, param.enc_param);
+ } else {
+ jpg_reg_ctx->img_thumb_data_addr = (UINT32)jpg_data_base_addr
+ + JPG_STREAM_BUF_SIZE
+ + JPG_STREAM_THUMB_BUF_SIZE
+ + JPG_FRAME_BUF_SIZE;
+ jpg_reg_ctx->jpg_thumb_data_addr = (UINT32)jpg_data_base_addr
+ + JPG_STREAM_BUF_SIZE;
+
+ result = encode_jpg(jpg_reg_ctx, param.thumb_enc_param);
+ }
+ out = copy_to_user((void *)arg, (void *) & param, sizeof(jpg_args));
+ break;
+
+ case IOCTL_JPG_GET_STRBUF:
+ jpg_dbg("IOCTL_JPG_GET_STRBUF\n");
+ unlock_jpg_mutex();
+ return arg + JPG_MAIN_STRART;
+
+ case IOCTL_JPG_GET_THUMB_STRBUF:
+ jpg_dbg("IOCTL_JPG_GET_THUMB_STRBUF\n");
+ unlock_jpg_mutex();
+ return arg + JPG_THUMB_START;
+
+ case IOCTL_JPG_GET_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_FRMBUF\n");
+ unlock_jpg_mutex();
+ return arg + IMG_MAIN_START;
+
+ case IOCTL_JPG_GET_THUMB_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_THUMB_FRMBUF\n");
+ unlock_jpg_mutex();
+ return arg + IMG_THUMB_START;
+
+ case IOCTL_JPG_GET_PHY_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_PHY_FRMBUF\n");
+ unlock_jpg_mutex();
+ return jpg_data_base_addr + JPG_STREAM_BUF_SIZE + JPG_STREAM_THUMB_BUF_SIZE;
+
+ case IOCTL_JPG_GET_PHY_THUMB_FRMBUF:
+ jpg_dbg("IOCTL_JPG_GET_PHY_THUMB_FRMBUF\n");
+ unlock_jpg_mutex();
+ return jpg_data_base_addr + JPG_STREAM_BUF_SIZE
+ + JPG_STREAM_THUMB_BUF_SIZE + JPG_FRAME_BUF_SIZE;
+
+ default :
+ jpg_dbg("JPG Invalid ioctl : 0x%X\n", cmd);
+ }
+
+ unlock_jpg_mutex();
+
+ return result;
+}
+
+static unsigned int s3c_jpeg_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask = 0;
+
+ jpg_dbg("enter poll \n");
+ poll_wait(file, &wait_queue_jpeg, wait);
+ mask = POLLOUT | POLLWRNORM;
+ return mask;
+}
+int s3c_jpeg_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned long size = vma->vm_end - vma->vm_start;
+ unsigned long max_size;
+ unsigned long page_frame_no;
+
+ page_frame_no = __phys_to_pfn(jpg_data_base_addr);
+
+ max_size = JPG_TOTAL_BUF_SIZE + PAGE_SIZE - (JPG_TOTAL_BUF_SIZE % PAGE_SIZE);
+
+ if (size > max_size) {
+ return -EINVAL;
+ }
+
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ if (remap_pfn_range(vma, vma->vm_start, page_frame_no, size, \
+ vma->vm_page_prot)) {
+ jpg_err("jpeg remap error");
+ return -EAGAIN;
+ }
+
+ return 0;
+}
+
+
+static const struct file_operations jpeg_fops = {
+ owner: THIS_MODULE,
+ open: s3c_jpeg_open,
+ release: s3c_jpeg_release,
+ ioctl: s3c_jpeg_ioctl,
+ read: s3c_jpeg_read,
+ write: s3c_jpeg_write,
+ mmap: s3c_jpeg_mmap,
+ poll: s3c_jpeg_poll,
+};
+
+
+static struct miscdevice s3c_jpeg_miscdev = {
+ minor: 254,
+ name: "s3c-jpg",
+ fops: &jpeg_fops
+};
+
+
+static int s3c_jpeg_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ static int size;
+ static int ret;
+ HANDLE h_mutex;
+
+ s3c_jpeg_clk = clk_get(&pdev->dev, "jpeg");
+
+ if (IS_ERR(s3c_jpeg_clk)) {
+ jpg_err("failed to find jpeg clock source\n");
+ return -ENOENT;
+ }
+
+ clk_enable(s3c_jpeg_clk);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res == NULL) {
+ jpg_err("failed to get memory region resouce\n");
+ return -ENOENT;
+ }
+
+ size = (res->end - res->start) + 1;
+ s3c_jpeg_mem = request_mem_region(res->start, size, pdev->name);
+
+ if (s3c_jpeg_mem == NULL) {
+ jpg_err("failed to get memory region\n");
+ return -ENOENT;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (res == NULL) {
+ jpg_err("failed to get irq resource\n");
+ return -ENOENT;
+ }
+
+ irq_no = res->start;
+ ret = request_irq(res->start, (void *)s3c_jpeg_irq, 0, pdev->name, pdev);
+
+ if (ret != 0) {
+ jpg_err("failed to install irq (%d)\n", ret);
+ return ret;
+ }
+
+ s3c_jpeg_base = ioremap(s3c_jpeg_mem->start, size);
+
+ if (s3c_jpeg_base == 0) {
+ jpg_err("failed to ioremap() region\n");
+ return -EINVAL;
+ }
+
+ init_waitqueue_head(&wait_queue_jpeg);
+
+ jpg_dbg("JPG_Init\n");
+
+ // Mutex initialization
+ h_mutex = create_jpg_mutex();
+
+ if (h_mutex == NULL) {
+ jpg_err("JPG Mutex Initialize error\r\n");
+ return FALSE;
+ }
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\n");
+ return FALSE;
+ }
+
+ instanceNo = 0;
+
+ unlock_jpg_mutex();
+
+ ret = misc_register(&s3c_jpeg_miscdev);
+
+ /* clock disable */
+ clk_disable(s3c_jpeg_clk);
+
+ return 0;
+}
+
+static int s3c_jpeg_remove(struct platform_device *dev)
+{
+ if (s3c_jpeg_mem != NULL) {
+ release_resource(s3c_jpeg_mem);
+ kfree(s3c_jpeg_mem);
+ s3c_jpeg_mem = NULL;
+ }
+
+ free_irq(irq_no, dev);
+ misc_deregister(&s3c_jpeg_miscdev);
+ return 0;
+}
+
+#ifdef CONFIG_CPU_S5PV210
+static int s3c_jpeg_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ int ret;
+ /* clock disable */
+ clk_disable(s3c_jpeg_clk);
+
+ ret = s5pv210_pd_disable("jpeg_pd");
+ if (ret < 0) {
+ jpg_err("failed to disable jpeg power domain\n");
+ return FALSE;
+ }
+ return 0;
+}
+
+static int s3c_jpeg_resume(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = s5pv210_pd_enable("jpeg_pd");
+ if (ret < 0) {
+ jpg_err("failed to enable jpeg power domain\n");
+ return FALSE;
+ }
+
+ /* clock enable */
+ clk_enable(s3c_jpeg_clk);
+
+ return 0;
+}
+#endif
+
+static struct platform_driver s3c_jpeg_driver = {
+ .probe = s3c_jpeg_probe,
+ .remove = s3c_jpeg_remove,
+ .shutdown = NULL,
+ .suspend = s3c_jpeg_suspend,
+ .resume = s3c_jpeg_resume,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s3c-jpg",
+ },
+};
+
+static char banner[] __initdata = KERN_INFO "S3C JPEG Driver, (c) 2007 Samsung Electronics\n";
+
+static int __init s3c_jpeg_init(void)
+{
+ printk(banner);
+ printk("JPEG driver for S5PV210 \n");
+ return platform_driver_register(&s3c_jpeg_driver);
+}
+
+static void __exit s3c_jpeg_exit(void)
+{
+ DWORD ret;
+
+ jpg_dbg("JPG_Deinit\n");
+
+ ret = lock_jpg_mutex();
+
+ if (!ret) {
+ jpg_err("JPG Mutex Lock Fail\r\n");
+ }
+
+ unlock_jpg_mutex();
+
+ delete_jpg_mutex();
+
+ platform_driver_unregister(&s3c_jpeg_driver);
+ jpg_dbg("S3C JPEG driver module exit\n");
+}
+
+module_init(s3c_jpeg_init);
+module_exit(s3c_jpeg_exit);
+
+MODULE_AUTHOR("Peter, Oh");
+MODULE_DESCRIPTION("S3C JPEG Encoder/Decoder Device Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h
new file mode 100644
index 0000000..11c359e
--- /dev/null
+++ b/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h
@@ -0,0 +1,33 @@
+/* linux/drivers/media/video/samsung/jpeg_v2/s3c-jpeg.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Header file for Samsung Jpeg Interface driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#ifndef __JPEG_DRIVER_H__
+#define __JPEG_DRIVER_H__
+
+
+#define MAX_INSTANCE_NUM 1
+#define MAX_PROCESSING_THRESHOLD 1000 // 1Sec
+
+#define JPEG_IOCTL_MAGIC 'J'
+
+#define IOCTL_JPG_DECODE _IO(JPEG_IOCTL_MAGIC, 1)
+#define IOCTL_JPG_ENCODE _IO(JPEG_IOCTL_MAGIC, 2)
+#define IOCTL_JPG_GET_STRBUF _IO(JPEG_IOCTL_MAGIC, 3)
+#define IOCTL_JPG_GET_FRMBUF _IO(JPEG_IOCTL_MAGIC, 4)
+#define IOCTL_JPG_GET_THUMB_STRBUF _IO(JPEG_IOCTL_MAGIC, 5)
+#define IOCTL_JPG_GET_THUMB_FRMBUF _IO(JPEG_IOCTL_MAGIC, 6)
+#define IOCTL_JPG_GET_PHY_FRMBUF _IO(JPEG_IOCTL_MAGIC, 7)
+#define IOCTL_JPG_GET_PHY_THUMB_FRMBUF _IO(JPEG_IOCTL_MAGIC, 8)
+#define JPG_CLOCK_DIVIDER_RATIO_QUARTER 4
+
+#endif /*__JPEG_DRIVER_H__*/