aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/samsung_duallcd/extension
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/samsung_duallcd/extension')
-rw-r--r--drivers/video/samsung_duallcd/extension/Makefile6
-rw-r--r--drivers/video/samsung_duallcd/extension/cmc623.h725
-rw-r--r--drivers/video/samsung_duallcd/extension/mdnie.c729
-rw-r--r--drivers/video/samsung_duallcd/extension/mdnie.h134
-rw-r--r--drivers/video/samsung_duallcd/extension/regs-mdnie.h166
-rw-r--r--drivers/video/samsung_duallcd/extension/regs_fimd_lite.h396
-rw-r--r--drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c209
-rw-r--r--drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h30
-rw-r--r--drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c502
-rw-r--r--drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h37
10 files changed, 2934 insertions, 0 deletions
diff --git a/drivers/video/samsung_duallcd/extension/Makefile b/drivers/video/samsung_duallcd/extension/Makefile
new file mode 100644
index 0000000..190c9cd
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for fimd extension driver.
+#
+obj-$(CONFIG_FIMD_EXT_SUPPORT) += s5p_fimd_ext.o
+obj-$(CONFIG_FIMD_LITE_SUPPORT) += s5p_fimd_lite.o
+obj-$(CONFIG_MDNIE_SUPPORT) += mdnie.o
diff --git a/drivers/video/samsung_duallcd/extension/cmc623.h b/drivers/video/samsung_duallcd/extension/cmc623.h
new file mode 100644
index 0000000..8da2e79
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/cmc623.h
@@ -0,0 +1,725 @@
+/*
+ * CMC623 Setting table for SLP7 Machine.
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Eunchul Kim <chulspro.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "mdnie.h"
+
+static const unsigned short dynamic_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0040, /*DE pe*/
+ 0x0093, 0x0040, /*DE pf*/
+ 0x0094, 0x0040, /*DE pb*/
+ 0x0095, 0x0040, /*DE ne*/
+ 0x0096, 0x0040, /*DE nf*/
+ 0x0097, 0x0040, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short dynamic_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0080, /*DE pe*/
+ 0x0093, 0x0080, /*DE pf*/
+ 0x0094, 0x0080, /*DE pb*/
+ 0x0095, 0x0080, /*DE ne*/
+ 0x0096, 0x0080, /*DE nf*/
+ 0x0097, 0x0080, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1404, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short dynamic_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0080, /*DE pe*/
+ 0x0093, 0x0080, /*DE pf*/
+ 0x0094, 0x0080, /*DE pb*/
+ 0x0095, 0x0080, /*DE ne*/
+ 0x0096, 0x0080, /*DE nf*/
+ 0x0097, 0x0080, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1404, /*CS weight grayTH*/
+ 0x00e1, 0xff00, /*SCR RrCr*/
+ 0x00e2, 0x00ff, /*SCR RgCg*/
+ 0x00e3, 0x00ff, /*SCR RbCb*/
+ 0x00e4, 0x00ff, /*SCR GrMr*/
+ 0x00e5, 0xff00, /*SCR GgMg*/
+ 0x00e6, 0x00ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00ff, /*SCR BgYg*/
+ 0x00e9, 0xff00, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00ff, /*SCR KgWg*/
+ 0x00ec, 0x00ff, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short dynamic_vtcall[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008e, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/
+ 0x0039, 0x0080, /*FA dnrWeight*/
+ 0x0080, 0x0fff, /*DNR dirTh*/
+ 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082, 0xff16, /*DNR decon5Th maskTh*/
+ 0x0083, 0x0000, /*DNR blTh*/
+ 0x0092, 0x00e0, /*DE pe*/
+ 0x0093, 0x00e0, /*DE pf*/
+ 0x0094, 0x00e0, /*DE pb*/
+ 0x0095, 0x00e0, /*DE ne*/
+ 0x0096, 0x00e0, /*DE nf*/
+ 0x0097, 0x00e0, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1a04, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short movie_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short movie_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short movie_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0000, /*DE pe*/
+ 0x0093, 0x0000, /*DE pf*/
+ 0x0094, 0x0000, /*DE pb*/
+ 0x0095, 0x0000, /*DE ne*/
+ 0x0096, 0x0000, /*DE nf*/
+ 0x0097, 0x0000, /*DE nb*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1004, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0000, /*CC chsel strength*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short movie_vtcall[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x002e, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/
+ 0x0039, 0x0080, /*FA dnrWeight*/
+ 0x0080, 0x0fff, /*DNR dirTh*/
+ 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082, 0xff16, /*DNR decon5Th maskTh*/
+ 0x0083, 0x0000, /*DNR blTh*/
+ 0x0092, 0x0040, /*DE pe*/
+ 0x0093, 0x0040, /*DE pf*/
+ 0x0094, 0x0040, /*DE pb*/
+ 0x0095, 0x0040, /*DE ne*/
+ 0x0096, 0x0040, /*DE nf*/
+ 0x0097, 0x0040, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short natural_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x002c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0020, /*DE pe*/
+ 0x0093, 0x0020, /*DE pf*/
+ 0x0094, 0x0020, /*DE pb*/
+ 0x0095, 0x0020, /*DE ne*/
+ 0x0096, 0x0020, /*DE nf*/
+ 0x0097, 0x0020, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short natural_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x002c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*DE ne*/
+ 0x0096, 0x0060, /*DE nf*/
+ 0x0097, 0x0060, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short natural_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x002c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*DE ne*/
+ 0x0096, 0x0060, /*DE nf*/
+ 0x0097, 0x0060, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0000, /*CC chsel strength*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short natural_vtcall[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x002e, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/
+ 0x0039, 0x0080, /*FA dnrWeight*/
+ 0x0080, 0x0fff, /*DNR dirTh*/
+ 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082, 0xff16, /*DNR decon5Th maskTh*/
+ 0x0083, 0x0000, /*DNR blTh*/
+ 0x0092, 0x00c0, /*DE pe*/
+ 0x0093, 0x00c0, /*DE pf*/
+ 0x0094, 0x00c0, /*DE pb*/
+ 0x0095, 0x00c0, /*DE ne*/
+ 0x0096, 0x00c0, /*DE nf*/
+ 0x0097, 0x00c0, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short standard_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0020, /*DE pe*/
+ 0x0093, 0x0020, /*DE pf*/
+ 0x0094, 0x0020, /*DE pb*/
+ 0x0095, 0x0020, /*DE ne*/
+ 0x0096, 0x0020, /*DE nf*/
+ 0x0097, 0x0020, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1604, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short standard_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*DE ne*/
+ 0x0096, 0x0060, /*DE nf*/
+ 0x0097, 0x0060, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short standard_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*DE ne*/
+ 0x0096, 0x0060, /*DE nf*/
+ 0x0097, 0x0060, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00e1, 0xff00, /*SCR RrCr*/
+ 0x00e2, 0x00ff, /*SCR RgCg*/
+ 0x00e3, 0x00ff, /*SCR RbCb*/
+ 0x00e4, 0x00ff, /*SCR GrMr*/
+ 0x00e5, 0xff00, /*SCR GgMg*/
+ 0x00e6, 0x00ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00ff, /*SCR BgYg*/
+ 0x00e9, 0xff00, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00ff, /*SCR KgWg*/
+ 0x00ec, 0x00ff, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0000, /*CC chsel strength*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short standard_vtcall[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000e, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 hdr2 fa1*/
+ 0x0039, 0x0080, /*FA dnrWeight*/
+ 0x0080, 0x0fff, /*DNR dirTh*/
+ 0x0081, 0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082, 0xff16, /*DNR decon5Th maskTh*/
+ 0x0083, 0x0000, /*DNR blTh*/
+ 0x0092, 0x00c0, /*DE pe*/
+ 0x0093, 0x00c0, /*DE pf*/
+ 0x0094, 0x00c0, /*DE pb*/
+ 0x0095, 0x00c0, /*DE ne*/
+ 0x0096, 0x00c0, /*DE nf*/
+ 0x0097, 0x00c0, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short camera[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*DE ne*/
+ 0x0096, 0x0060, /*DE nf*/
+ 0x0097, 0x0060, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short camera_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x040c, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*DE ne*/
+ 0x0096, 0x0060, /*DE nf*/
+ 0x0097, 0x0060, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0100, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg RY*/
+ 0x00b1, 0x1010, /*CS hg GC*/
+ 0x00b2, 0x1010, /*CS hg BM*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short browser_tone1[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0xaf00, /*SCR RrCr*/
+ 0x00e2, 0x00b7, /*SCR RgCg*/
+ 0x00e3, 0x00bc, /*SCR RbCb*/
+ 0x00e4, 0x00af, /*SCR GrMr*/
+ 0x00e5, 0xb700, /*SCR GgMg*/
+ 0x00e6, 0x00bc, /*SCR GbMb*/
+ 0x00e7, 0x00af, /*SCR BrYr*/
+ 0x00e8, 0x00b7, /*SCR BgYg*/
+ 0x00e9, 0xbc00, /*SCR BbYb*/
+ 0x00ea, 0x00af, /*SCR KrWr*/
+ 0x00eb, 0x00b7, /*SCR KgWg*/
+ 0x00ec, 0x00bc, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short browser_tone2[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0xa000, /*SCR RrCr*/
+ 0x00e2, 0x00a8, /*SCR RgCg*/
+ 0x00e3, 0x00b2, /*SCR RbCb*/
+ 0x00e4, 0x00a0, /*SCR GrMr*/
+ 0x00e5, 0xa800, /*SCR GgMg*/
+ 0x00e6, 0x00b2, /*SCR GbMb*/
+ 0x00e7, 0x00a0, /*SCR BrYr*/
+ 0x00e8, 0x00a8, /*SCR BgYg*/
+ 0x00e9, 0xb200, /*SCR BbYb*/
+ 0x00ea, 0x00a0, /*SCR KrWr*/
+ 0x00eb, 0x00a8, /*SCR KgWg*/
+ 0x00ec, 0x00b2, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short browser_tone3[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0x9100, /*SCR RrCr*/
+ 0x00e2, 0x0099, /*SCR RgCg*/
+ 0x00e3, 0x00a3, /*SCR RbCb*/
+ 0x00e4, 0x0091, /*SCR GrMr*/
+ 0x00e5, 0x9900, /*SCR GgMg*/
+ 0x00e6, 0x00a3, /*SCR GbMb*/
+ 0x00e7, 0x0091, /*SCR BrYr*/
+ 0x00e8, 0x0099, /*SCR BgYg*/
+ 0x00e9, 0xa300, /*SCR BbYb*/
+ 0x00ea, 0x0091, /*SCR KrWr*/
+ 0x00eb, 0x0099, /*SCR KgWg*/
+ 0x00ec, 0x00a3, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short bypass[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0000, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 | de8 hdr2 fa1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short negative[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*SCR*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0xff00, /*SCR KrWr*/
+ 0x00eb, 0xff00, /*SCR KgWg*/
+ 0x00ec, 0xff00, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x04ac, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short cold[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ec, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0064, /*MCM 10000K*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short cold_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x04ec, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0064, /*MCM 10000K*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short warm[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ec, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0028, /*MCM 4000K*/
+ 0x0007, 0x7878, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static const unsigned short warm_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x04ec, /*Dither8 UC4 ABC2 CP1 |
+ CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0028, /*MCM 4000K*/
+ 0x0007, 0x7878, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+const struct mdnie_tables mdnie_main_tables[] = {
+ { "dynamic_ui", dynamic_ui, ARRAY_SIZE(dynamic_ui) },
+ { "dynamic_gallery", dynamic_gallery, ARRAY_SIZE(dynamic_gallery) },
+ { "dynamic_video", dynamic_video, ARRAY_SIZE(dynamic_video) },
+ { "dynamic_vtcall", dynamic_vtcall, ARRAY_SIZE(dynamic_vtcall) },
+ { "standard_ui", standard_ui, ARRAY_SIZE(standard_ui) },
+ { "standard_gallery", standard_gallery, ARRAY_SIZE(standard_gallery) },
+ { "standard_video", standard_video, ARRAY_SIZE(standard_video) },
+ { "standard_vtcall", standard_vtcall, ARRAY_SIZE(standard_vtcall) },
+ { "natural_ui", natural_ui, ARRAY_SIZE(natural_ui) },
+ { "natural_gallery", natural_gallery, ARRAY_SIZE(natural_gallery) },
+ { "natural_video", natural_video, ARRAY_SIZE(natural_video) },
+ { "natural_vtcall", natural_vtcall, ARRAY_SIZE(natural_vtcall) },
+ { "movie_ui", movie_ui, ARRAY_SIZE(movie_ui) },
+ { "movie_gallery", movie_gallery, ARRAY_SIZE(movie_gallery) },
+ { "movie_video", movie_video, ARRAY_SIZE(movie_video) },
+ { "movie_vtcall", movie_vtcall, ARRAY_SIZE(movie_vtcall) },
+ { "camera", camera, ARRAY_SIZE(camera) },
+ { "camera_outdoor", camera_outdoor, ARRAY_SIZE(camera_outdoor) },
+ { "browser_tone1", browser_tone1, ARRAY_SIZE(browser_tone1) },
+ { "browser_tone2", browser_tone2, ARRAY_SIZE(browser_tone2) },
+ { "browser_tone3", browser_tone3, ARRAY_SIZE(browser_tone3) },
+ { "negative", negative, ARRAY_SIZE(negative) },
+ { "bypass", bypass, ARRAY_SIZE(bypass) },
+ { "outdoor", outdoor, ARRAY_SIZE(outdoor) },
+ { "warm", warm, ARRAY_SIZE(warm) },
+ { "warm_outdoor", warm_outdoor, ARRAY_SIZE(warm_outdoor) },
+ { "cold", cold, ARRAY_SIZE(cold) },
+ { "cold_outdoor", cold_outdoor, ARRAY_SIZE(cold_outdoor) },
+};
+
diff --git a/drivers/video/samsung_duallcd/extension/mdnie.c b/drivers/video/samsung_duallcd/extension/mdnie.c
new file mode 100644
index 0000000..e2ad4cc
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/mdnie.c
@@ -0,0 +1,729 @@
+/* /linux/driver/video/samsung/mdnie.c
+ *
+ * Samsung SoC mDNIe driver.
+ *
+ * Copyright (c) 2011 Samsung Electronics.
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Eunchul Kim <chulspro.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/firmware.h>
+
+#include <plat/fimd_lite_ext.h>
+#include <mach/map.h>
+
+#include "regs-mdnie.h"
+#include "mdnie.h"
+#include "s5p_fimd_ext.h"
+#include "cmc623.h"
+
+/* FIXME:!! need to change chip id dynamically */
+#define MDNIE_CHIP_ID "cmc623p"
+
+static const char *mode_name[MODE_MAX] = {
+ "dynamic",
+ "standard",
+ "natural",
+ "movie"
+};
+
+static const char *scenario_name[SCENARIO_MAX] = {
+ "ui",
+ "gallery",
+ "video",
+ "vtcall",
+ "camera",
+ "browser",
+ "negative",
+ "bypass"
+};
+
+static const char *tone_name[TONE_MAX] = {
+ "",
+ "warm",
+ "cold",
+};
+
+static const char *tone_browser_name[TONE_BR_MAX] = {
+ "tone1",
+ "tone2",
+ "tone3"
+};
+
+static const char *outdoor_name[OUTDOOR_MAX] = {
+ "",
+ "outdoor"
+};
+
+#if defined(DEBUG)
+#define mdnie_info(fmt, args...) \
+ do { \
+ printk(KERN_NOTICE"%s:"fmt"\n", __func__, ##args); \
+ } while (0);
+#else
+#define mdnie_info(fmt, args...)
+#endif
+
+static struct mdnie_platform_data
+ *to_mdnie_platform_data(struct s5p_fimd_ext_device *fx_dev)
+{
+ return fx_dev->dev.platform_data ?
+ (struct mdnie_platform_data *)fx_dev->dev.platform_data : NULL;
+}
+
+static void mdnie_write_tune(struct s5p_mdnie *mdnie,
+ const unsigned short *tune,
+ unsigned int size)
+{
+ unsigned int i = 0;
+
+ mdnie_info("size[%d]", size);
+ while (i < size) {
+ writel(tune[i + 1], mdnie->regs + tune[i] * 4);
+ i += 2;
+ }
+}
+
+static int mdnie_request_fw(struct s5p_mdnie *mdnie, const char *name)
+{
+ const struct firmware *fw;
+ char fw_path[MDNIE_MAX_STR+1];
+ int ret;
+
+ snprintf(fw_path, MDNIE_MAX_STR, MDNIE_FW_PATH, MDNIE_CHIP_ID, name);
+ mdnie_info("fw_path[%s]", fw_path);
+ mutex_lock(&mdnie->lock);
+
+ ret = request_firmware(&fw, fw_path, mdnie->dev);
+ if (ret) {
+ dev_err(mdnie->dev, "failed to request firmware.\n");
+ mutex_unlock(&mdnie->lock);
+ return ret;
+ }
+
+ mdnie_write_tune(mdnie, (const unsigned short *)fw->data,
+ fw->size / sizeof(const unsigned short));
+ release_firmware(fw);
+
+ mutex_unlock(&mdnie->lock);
+
+ return 0;
+}
+
+static int mdnie_request_tables(struct s5p_mdnie *mdnie, const char *name)
+{
+ struct mdnie_tables *tables;
+ int i;
+
+ mdnie_info("name[%s]", name);
+ tables = (struct mdnie_tables *)&mdnie_main_tables;
+ if (!tables) {
+ dev_err(mdnie->dev, "mode mdnie tables is NULL.\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mdnie_main_tables); i++) {
+ if (strcmp(name , tables[i].name) == 0) {
+ mdnie_info("tune_id[%d]name[%s]", i, tables[i].name);
+ mdnie_write_tune(mdnie, tables[i].value,
+ tables[i].size);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int mdnie_get_name(struct s5p_mdnie *mdnie, char *name,
+ enum mdnie_set set)
+{
+ enum mdnie_mode mode = mdnie->mode;
+ enum mdnie_scenario scenario = mdnie->scenario;
+ int tone = mdnie->tone;
+ enum mdnie_outdoor outdoor = mdnie->outdoor;
+
+ mdnie_info("set[%d]:mode[%d]scenario[%d]tone[%d]outdoor[%d]",
+ set, mode, scenario, tone, outdoor);
+ switch (scenario) {
+ case SCENARIO_CAMERA:
+ strcat(name, scenario_name[scenario]);
+ if (outdoor == OUTDOOR_ON) {
+ strcat(name, "_");
+ strcat(name , outdoor_name[outdoor]);
+ }
+ break;
+ case SCENARIO_BROWSER:
+ strcat(name, scenario_name[scenario]);
+ strcat(name, "_");
+ strcat(name, tone_browser_name[tone]);
+ break;
+ default:
+ if (set == SET_MAIN ||
+ (tone == TONE_NORMAL && outdoor == OUTDOOR_OFF)) {
+ if (scenario < SCENARIO_MODE_MAX) {
+ if (mode < MODE_MAX)
+ strcat(name, mode_name[mode]);
+
+ strcat(name, "_");
+
+ if (scenario < SCENARIO_MODE_MAX)
+ strcat(name,
+ scenario_name[scenario]);
+ } else
+ strcat(name, scenario_name[scenario]);
+ } else {
+ if (tone < TONE_MAX)
+ strcat(name, tone_name[tone]);
+
+ if (tone != TONE_NORMAL && outdoor == OUTDOOR_ON)
+ strcat(name, "_");
+
+ if (outdoor < OUTDOOR_MAX)
+ strcat(name , outdoor_name[outdoor]);
+ }
+ break;
+ }
+
+ return strlen(name);
+}
+
+static int mdnie_set_commit(struct s5p_mdnie *mdnie,
+ enum mdnie_set set)
+{
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ char name[MDNIE_MAX_STR+1];
+ int ret = 0, len = 0;
+
+ memset(name, 0, MDNIE_MAX_STR+1);
+ len = mdnie_get_name(mdnie, name, set);
+ if (len == 0) {
+ dev_err(mdnie->dev, "failed to find tune.\n");
+ return ret;
+ }
+
+ if (mops && mops->tune) {
+ ret = mops->tune(mdnie, name);
+ if (ret) {
+ dev_err(mdnie->dev, "failed to set tune.\n");
+ return ret;
+ }
+ } else {
+ dev_err(mdnie->dev, "invalid mdnie mops.\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mdnie_check_tone(struct s5p_mdnie *mdnie, int tone)
+{
+ unsigned long max_tone;
+
+ if (mdnie->scenario == SCENARIO_BROWSER)
+ max_tone = TONE_BR_MAX;
+ else
+ max_tone = TONE_MAX;
+
+ if (tone >= max_tone) {
+ dev_err(mdnie->dev, "invalid mdnie tone.\n");
+ return -EINVAL;
+ }
+
+ if (mdnie->scenario != SCENARIO_VIDEO
+ && mdnie->scenario != SCENARIO_BROWSER) {
+ /* Set to default */
+ mdnie->tone = 0;
+ dev_err(mdnie->dev, "invalid mdnie scenario.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+struct mdnie_manager_ops mdnie_set_mops = {
+ .tune = mdnie_request_tables,
+ .commit = mdnie_set_commit,
+ .check_tone = mdnie_check_tone,
+};
+
+static void mdnie_set_size(struct s5p_mdnie *mdnie,
+ unsigned int width, unsigned int height)
+{
+ unsigned int size;
+
+ writel(0x0, mdnie->regs + MDNIE_R0);
+
+ /* Input Data Unmask */
+ writel(0x077, mdnie->regs + MDNIE_R1);
+
+ /* LCD width */
+ size = readl(mdnie->regs + MDNIE_R3);
+ size &= ~MDNIE_R34_WIDTH_MASK;
+ size |= width;
+ writel(size, mdnie->regs + MDNIE_R3);
+
+ /* LCD height */
+ size = readl(mdnie->regs + MDNIE_R4);
+ size &= ~MDNIE_R35_HEIGHT_MASK;
+ size |= height;
+ writel(size, mdnie->regs + MDNIE_R4);
+
+ /* unmask all */
+ writel(0, mdnie->regs + MDNIE_R28);
+}
+
+static void mdnie_init_hardware(struct s5p_mdnie *mdnie)
+{
+ struct mdnie_platform_data *pdata = NULL;
+
+ pdata = mdnie->pdata;
+
+ /* set display size. */
+ mdnie_set_size(mdnie, pdata->width, pdata->height);
+}
+
+static int mdnie_setup(struct s5p_fimd_ext_device *fx_dev, unsigned int enable)
+{
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ int ret = 0;
+
+ mdnie_info("enable[%d]", enable);
+ if (enable) {
+ int i;
+ mdnie_init_hardware(mdnie);
+ if (mops && mops->commit) {
+ for (i = 0; i < SET_MAX; i++) {
+ ret = mops->commit(mdnie, i);
+ if (ret) {
+ dev_err(mdnie->dev, "invalid mdnie set.\n");
+ goto error;
+ }
+ }
+ } else {
+ dev_err(mdnie->dev, "invalid mdnie mops.\n");
+ goto error;
+ }
+ }
+
+ return 0;
+
+error:
+ return ret;
+}
+
+static ssize_t store_mdnie_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ unsigned long prev_mode;
+ unsigned long mode;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &mode);
+ if (ret) {
+ dev_err(&fx_dev->dev, "invalid mode value.\n");
+ return -EINVAL;
+ }
+
+ if (mode >= MODE_MAX) {
+ dev_err(&fx_dev->dev, "invalid mdnie mode.\n");
+ return -EINVAL;
+ }
+
+ if (mdnie->scenario >= SCENARIO_MODE_MAX) {
+ dev_err(&fx_dev->dev, "invalid mdnie scenario.\n");
+ mdnie->scenario = SCENARIO_UI;
+ }
+
+ prev_mode = mdnie->mode;
+ mdnie->mode = mode;
+ mdnie_info("mode[%d]", mdnie->mode);
+ if (mops && mops->commit) {
+ ret = mops->commit(mdnie, SET_MAIN);
+ if (ret) {
+ dev_err(&fx_dev->dev, "failed to set mode.\n");
+ goto error_restore;
+ }
+ } else {
+ dev_err(&fx_dev->dev, "invalid mdnie mops.\n");
+ ret = -EINVAL;
+ goto error_restore;
+ }
+
+ return count;
+
+error_restore:
+ mdnie->mode = prev_mode;
+ return ret;
+}
+
+static ssize_t show_mdnie_mode(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+
+ mdnie_info("mode[%d]", mdnie->mode);
+ return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->mode);
+}
+
+static ssize_t store_mdnie_scenario(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ unsigned long prev_scenario;
+ unsigned long scenario;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &scenario);
+ if (ret) {
+ dev_err(&fx_dev->dev, "invalid scenario value.\n");
+ return -EINVAL;
+ }
+
+ if (scenario >= SCENARIO_MAX) {
+ dev_err(&fx_dev->dev, "invalid mdnie scenario.\n");
+ return -EINVAL;
+ }
+
+ prev_scenario = mdnie->scenario;
+ mdnie->scenario = scenario;
+ mdnie_info("scenario[%d]", mdnie->scenario);
+ if (mops && mops->commit) {
+ ret = mops->commit(mdnie, SET_MAIN);
+ if (ret) {
+ dev_err(&fx_dev->dev, "failed to set scenario.\n");
+ goto error_restore;
+ }
+ } else {
+ dev_err(&fx_dev->dev, "invalid mdnie mops.\n");
+ ret = -EINVAL;
+ goto error_restore;
+ }
+
+ return count;
+
+error_restore:
+ mdnie->scenario = prev_scenario;
+ return ret;
+}
+
+static ssize_t show_mdnie_scenario(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+
+ mdnie_info("scenario[%d]", mdnie->scenario);
+ return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->scenario);
+}
+
+static ssize_t store_mdnie_tone(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ unsigned long prev_tone;
+ unsigned long tone;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &tone);
+ if (ret) {
+ dev_err(&fx_dev->dev, "invalid tone value.\n");
+ return -EINVAL;
+ }
+
+ if (mops && mops->check_tone) {
+ ret = mops->check_tone(mdnie, tone);
+ if (ret) {
+ dev_err(&fx_dev->dev, "failed to set tone.\n");
+ return ret;
+ }
+ } else {
+ dev_err(&fx_dev->dev, "invalid mdnie mops.\n");
+ ret = -EINVAL;
+ goto error_mops;
+ }
+
+ prev_tone = mdnie->tone;
+ mdnie->tone = tone;
+ mdnie_info("tone[%d]", mdnie->tone);
+ if (mops && mops->commit) {
+ ret = mops->commit(mdnie, SET_OPTIONAL);
+ if (ret) {
+ dev_err(&fx_dev->dev, "failed to set tone.\n");
+ goto error_restore;
+ }
+ } else {
+ dev_err(&fx_dev->dev, "invalid mdnie mops.\n");
+ ret = -EINVAL;
+ goto error_restore;
+ }
+
+ return count;
+
+error_restore:
+ mdnie->tone = prev_tone;
+error_mops:
+ return ret;
+}
+
+static ssize_t show_mdnie_tone(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+
+ mdnie_info("tone[%d]", mdnie->tone);
+ return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->tone);
+}
+
+static ssize_t store_mdnie_outdoor(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ unsigned long prev_outdoor;
+ unsigned long outdoor;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &outdoor);
+ if (ret) {
+ dev_err(&fx_dev->dev, "invalid outdoor value.\n");
+ return -EINVAL;
+ }
+
+ if (outdoor >= OUTDOOR_MAX) {
+ dev_err(&fx_dev->dev, "invalid mdnie outdoor.\n");
+ return -EINVAL;
+ }
+
+ if (mdnie->scenario != SCENARIO_VIDEO
+ && mdnie->scenario != SCENARIO_CAMERA) {
+ /* Set to default */
+ mdnie->outdoor = OUTDOOR_OFF;
+ dev_err(&fx_dev->dev, "invalid mdnie scenario.\n");
+ return -EIO;
+ }
+
+ prev_outdoor = mdnie->outdoor;
+ mdnie->outdoor = outdoor;
+ mdnie_info("outdoor[%d]", mdnie->outdoor);
+ if (mops && mops->commit) {
+ ret = mops->commit(mdnie, SET_OPTIONAL);
+ if (ret) {
+ dev_err(&fx_dev->dev, "failed to set outdoor.\n");
+ goto error_restore;
+ }
+ } else {
+ dev_err(&fx_dev->dev, "invalid mdnie mops.\n");
+ ret = -EINVAL;
+ goto error_restore;
+ }
+
+ return count;
+
+error_restore:
+ mdnie->outdoor = prev_outdoor;
+ return ret;
+}
+
+static ssize_t show_mdnie_outdoor(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+
+ mdnie_info("outdoor[%d]", mdnie->outdoor);
+ return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->outdoor);
+}
+
+static ssize_t store_mdnie_tune(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+ struct mdnie_manager_ops *mops = mdnie->mops;
+ unsigned long prev_tune;
+ unsigned long tune;
+ int ret;
+
+ ret = kstrtoul(buf, 0, &tune);
+ if (ret) {
+ dev_err(&fx_dev->dev, "invalid tune value.\n");
+ return -EINVAL;
+ }
+
+ if (tune >= TUNE_MAX) {
+ dev_err(&fx_dev->dev, "invalid mdnie tune.\n");
+ return -EINVAL;
+ }
+
+ prev_tune = mdnie->tune;
+ mdnie->tune = tune;
+ mdnie_info("tune[%d]", mdnie->tune);
+ if (mops) {
+ if (mdnie->tune == TUNE_FW)
+ mops->tune = mdnie_request_fw;
+ else
+ mops->tune = mdnie_request_tables;
+ } else {
+ dev_err(&fx_dev->dev, "invalid mdnie mops.\n");
+ ret = -EINVAL;
+ goto error_restore;
+ }
+
+ return count;
+
+error_restore:
+ mdnie->tune = prev_tune;
+ return ret;
+}
+
+static ssize_t show_mdnie_tune(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ struct s5p_mdnie *mdnie = fimd_ext_get_drvdata(fx_dev);
+
+ mdnie_info("tune[%d]", mdnie->tune);
+ return snprintf(buf, PAGE_SIZE, "%d\n", mdnie->tune);
+}
+
+/* sys/devices/platform/mdnie */
+static struct device_attribute mdnie_device_attrs[] = {
+ __ATTR(mode, S_IRUGO|S_IWUSR, show_mdnie_mode,
+ store_mdnie_mode),
+ __ATTR(scenario, S_IRUGO|S_IWUSR, show_mdnie_scenario,
+ store_mdnie_scenario),
+ __ATTR(tone, S_IRUGO|S_IWUSR, show_mdnie_tone,
+ store_mdnie_tone),
+ __ATTR(outdoor, S_IRUGO|S_IWUSR, show_mdnie_outdoor,
+ store_mdnie_outdoor),
+ __ATTR(tune, S_IRUGO|S_IWUSR, show_mdnie_tune,
+ store_mdnie_tune),
+};
+
+static int mdnie_probe(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct resource *res;
+ struct s5p_mdnie *mdnie;
+ int ret = -EINVAL;
+ int i;
+
+ mdnie = kzalloc(sizeof(struct s5p_mdnie), GFP_KERNEL);
+ if (!mdnie) {
+ dev_err(&fx_dev->dev, "failed to alloc mdnie object.\n");
+ return -EFAULT;
+ }
+
+ mdnie->dev = &fx_dev->dev;
+
+ mdnie->pdata = to_mdnie_platform_data(fx_dev);
+ if (mdnie->pdata == NULL) {
+ dev_err(&fx_dev->dev, "platform_data is NULL.\n");
+ return -EFAULT;
+ }
+
+ res = s5p_fimd_ext_get_resource(fx_dev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&fx_dev->dev, "failed to get io memory region.\n");
+ return -EINVAL;
+ }
+
+ mdnie->regs = ioremap(res->start, resource_size(res));
+ if (!mdnie->regs) {
+ dev_err(&fx_dev->dev, "failed to remap io region.\n'");
+ return -EFAULT;
+ }
+
+ mdnie->mode = MODE_STANDARD;
+ mdnie->scenario = SCENARIO_UI;
+ mdnie->tone = TONE_NORMAL;
+ mdnie->outdoor = OUTDOOR_OFF;
+ mdnie->tune = TUNE_TBL;
+ mdnie->mops = &mdnie_set_mops;
+
+ mutex_init(&mdnie->lock);
+
+ fimd_ext_set_drvdata(fx_dev, mdnie);
+
+ for (i = 0; i < ARRAY_SIZE(mdnie_device_attrs); i++) {
+ ret = device_create_file(&fx_dev->dev,
+ &mdnie_device_attrs[i]);
+ if (ret)
+ break;
+ }
+
+ if (ret < 0)
+ dev_err(&fx_dev->dev, "failed to add sysfs entries\n");
+
+ dev_info(&fx_dev->dev, "mDNIe driver has been probed.\n");
+
+ return 0;
+}
+
+static struct s5p_fimd_ext_driver fimd_ext_driver = {
+ .driver = {
+ .name = "mdnie",
+ .owner = THIS_MODULE,
+ },
+ .probe = mdnie_probe,
+ .setup = mdnie_setup,
+};
+
+static int __init mdnie_init(void)
+{
+ return s5p_fimd_ext_driver_register(&fimd_ext_driver);
+}
+
+static void __exit mdnie_exit(void)
+{
+}
+
+arch_initcall(mdnie_init);
+module_exit(mdnie_exit);
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>");
+MODULE_DESCRIPTION("mDNIe Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/samsung_duallcd/extension/mdnie.h b/drivers/video/samsung_duallcd/extension/mdnie.h
new file mode 100644
index 0000000..145efc1
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/mdnie.h
@@ -0,0 +1,134 @@
+/* linux/arch/arm/plat-s5p/mdnie.h
+ *
+ * mDNIe Platform Specific Header Definitions.
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ * InKi Dae <inki.dae@samsung.com>
+ * Eunchul Kim <chulspro.kim@samsung.com>
+ *
+ * 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 _MDNIE_H_
+#define _MDNIE_H_
+
+#define MDNIE_MAX_STR 255
+#define MDNIE_FW_PATH "mdnie/%s/%s.bin"
+
+/* set - main, optional */
+enum mdnie_set {
+ SET_MAIN = 0,
+ SET_OPTIONAL,
+ SET_MAX
+};
+
+/* mode - dynamic, standard, natural, movie */
+enum mdnie_mode {
+ MODE_DYNAMIC = 0,
+ MODE_STANDARD,
+ MODE_NATURAL,
+ MODE_MOVIE,
+ MODE_MAX
+};
+
+/* scenario - ui, gallery, video, vtcall, camera, browser, negative, bypass */
+enum mdnie_scenario {
+ SCENARIO_UI = 0,
+ SCENARIO_GALLERY,
+ SCENARIO_VIDEO,
+ SCENARIO_VTCALL,
+ SCENARIO_MODE_MAX,
+ SCENARIO_CAMERA = SCENARIO_MODE_MAX,
+ SCENARIO_BROWSER,
+ SCENARIO_NEGATIVE,
+ SCENARIO_BYPASS,
+ SCENARIO_MAX
+};
+
+/* tone - normal, warm, cold */
+enum mdnie_tone {
+ TONE_NORMAL = 0,
+ TONE_WARM,
+ TONE_COLD,
+ TONE_MAX
+};
+
+/* tone browser - tone1, tone2, tone3 */
+enum mdnie_tone_br {
+ TONE_1 = 0,
+ TONE_2,
+ TONE_3,
+ TONE_BR_MAX
+};
+
+/* outdoor - off, on */
+enum mdnie_outdoor {
+ OUTDOOR_OFF = 0,
+ OUTDOOR_ON,
+ OUTDOOR_MAX
+};
+
+/* tune - tables, fw */
+enum mdnie_tune {
+ TUNE_TBL = 0,
+ TUNE_FW,
+ TUNE_MAX
+};
+
+/*
+ * A main structure for mDNIe.
+ *
+ * @dev: pointer to device object for sysfs
+ * @regs: memory mapped register map
+ * @mode: mdnie mode value
+ * @scenario: mdnie scenario value
+ * @tone: mdnie tone value
+ * @outdoor: mdnie outdoor value
+ * @lock: lock for request firmware waiting
+ * @pdata: platform data of width, height
+ * @mops: manager ops
+ */
+struct s5p_mdnie {
+ struct device *dev;
+ void __iomem *regs;
+
+ enum mdnie_mode mode;
+ enum mdnie_scenario scenario;
+ int tone;
+ enum mdnie_outdoor outdoor;
+ enum mdnie_tune tune;
+
+ struct mutex lock;
+ struct mdnie_platform_data *pdata;
+ struct mdnie_manager_ops *mops;
+};
+
+/**
+ * A structure for data tables.
+ *
+ * @name: table name
+ * @value: table value
+ * @size: table size
+ */
+struct mdnie_tables {
+ const char *name;
+ const unsigned short *value;
+ unsigned int size;
+};
+
+/*
+ * mDNIe manager ops.
+ *
+ * @tune: api of tune settings
+ * @commit: api of main,optional settings
+ * @check_tone: api of check tone
+ */
+struct mdnie_manager_ops {
+ int (*tune)(struct s5p_mdnie *mdnie, const char *name);
+ int (*commit)(struct s5p_mdnie *mdnie, enum mdnie_set set);
+ int (*check_tone)(struct s5p_mdnie *mdnie, int tone);
+};
+
+#endif /* _MDNIE_H_ */
diff --git a/drivers/video/samsung_duallcd/extension/regs-mdnie.h b/drivers/video/samsung_duallcd/extension/regs-mdnie.h
new file mode 100644
index 0000000..a0ec8d7
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/regs-mdnie.h
@@ -0,0 +1,166 @@
+/* linux/arch/arm/plat-s5p/include/plat/regs-mdnie.h
+ *
+ * Header file for Samsung SoC mDNIe device.
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Author : Inki Dae <inki.dae@samsung.com>
+ *
+ * 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 _REGS_MDNIE_H
+#define _REGS_MDNIE_H
+
+#define MDNIE_R0 0x0000
+#define MDNIE_R1 0x0004
+#define MDNIE_R2 0x0008
+#define MDNIE_R3 0x000C
+#define MDNIE_R4 0x0010
+#define MDNIE_R5 0x0014
+#define MDNIE_R28 0x00A0
+
+/* R1 */
+#define MDNIE_R1_MCM_BYPASS_MODE (1 << 2)
+#define MDNIE_R1_ALG_DNR_HDTR_MASK (0x3 << 0)
+#define MDNIE_R1_ALG_DNR_HDTR(x) (((x) & 0x3) << 0)
+#define MDNIE_R1_ROI_PCA_OVE (1 << 10)
+#define MDNIE_R1_ROI_HDTR (1 << 9)
+#define MDNIE_R1_ROI_DNR (1 << 8)
+#define MDNIE_R1_ROI_OUTSIDE (1 << 7)
+#define MDNIE_R1_ABC_SEL_MASK (0x3 << 4)
+#define MDNIE_R1_ABC_SEL(x) (((x) & 0x3) << 4)
+
+/* R2 */
+#define MDNIE_R2_H_START_MASK (0x7ff << 0)
+#define MDNIE_R2_H_START(x) (((x) & 0x7ff) << 0)
+
+/* R3 */
+#define MDNIE_R3_WIDTH_MASK (0x7ff << 0)
+
+/* R4 */
+#define MDNIE_R4_HEIGHT_MASK (0x7ff << 0)
+
+/* R5 */
+#define MDNIE_R5_V_END_MASK (0x7ff << 0)
+#define MDNIE_R5_V_END(x) (((x) & 0x7ff) << 0)
+
+/* R6 */
+#define MDNIE_R6_DITHER_ENABLE (1 << 4)
+
+/* R34 */
+#define MDNIE_R34_WIDTH_MASK (0x7ff << 0)
+#define MDNIE_R34_WIDTH(x) (((x) & 0x7ff) << 0)
+
+/* R35 */
+#define MDNIE_R35_HEIGHT_MASK (0x7ff << 0)
+#define MDNIE_R35_HEIGHT(x) (((x) & 0x7ff) << 0)
+
+/* R44 */
+#define MDNIE_R44_DNR_BYPASS_MODE (1 << 14)
+
+/* R58 */
+#define MDNIE_R58_HDTR_BYPASS_MODE (0x1f << 0)
+
+/* R73 */
+#define MDNIE_R73_SN_LVL_MASK (0x3 << 10)
+#define MDNIE_R73_SN_LVL(x) (((x) & 0x3) << 10)
+#define MDNIE_R73_SY_LVL_MASK (0x3 << 8)
+#define MDNIE_R73_SY_LVL(x) (((x) & 0x3) << 8)
+#define MDNIE_R73_GR_LVL_MASK (0x3 << 6)
+#define MDNIE_R73_GR_LVL(x) (((x) & 0x3) << 6)
+#define MDNIE_R73_RD_LVL_MASK (0x3 << 4)
+#define MDNIE_R73_RD_LVL(x) (((x) & 0x3) << 4)
+#define MDNIE_R73_YE_LVL_MASK (0x3 << 2)
+#define MDNIE_R73_YE_LVL(x) (((x) & 0x3) << 2)
+#define MDNIE_R73_PU_LVL_MASK (0x3 << 0)
+#define MDNIE_R73_PU_LVL(x) (((x) & 0x3) << 0)
+
+/* R82 */
+#define MDNIE_R82_SN_CC_OFF (1 << 5)
+#define MDNIE_R82_SY_CC_OFF (1 << 4)
+#define MDNIE_R82_GR_CC_OFF (1 << 3)
+#define MDNIE_R82_RD_CC_OFF (1 << 2)
+#define MDNIE_R82_YE_CC_OFF (1 << 1)
+#define MDNIE_R82_PU_CC_OFF (1 << 0)
+
+/* R84 */
+#define MDNIE_R84_LIGHT_P_MASK (0xff << 8)
+#define MDNIE_R84_LIGHT_P(x) (((x) & 0xff) << 8)
+#define MDNIE_R84_CHROMA_P_MASK (0xff << 0)
+#define MDNIE_R84_CHROMA_P(x) (((x) & 0xff) << 0)
+
+/* R91 */
+#define MDNIE_R91_QUADRANT_ON (1 << 8)
+#define MDNIE_R91_COLOR_TEMP_DEST_MASK (0xff << 0)
+#define MDNIE_R91_COLOR_TEMP_DEST(x) (((x) & 0xff) << 0)
+
+/* R106 */
+#define MDNIE_R106_QUADRANT_TMP1_MASK (0xff << 8)
+#define MDNIE_R106_QUADRANT_TMP1(x) (((x) & 0xff) << 8)
+#define MDNIE_R106_QUADRANT_TMP2_MASK (0xff << 0)
+#define MDNIE_R106_QUADRANT_TMP2(x) (((x) & 0xff) << 0)
+
+/* R107 */
+#define MDNIE_R107_QUADRANT_TMP3_MASK (0xff << 8)
+#define MDNIE_R107_QUADRANT_TMP3(x) (((x) & 0xff) << 8)
+#define MDNIE_R107_QUADRANT_TMP4_MASK (0xff << 0)
+#define MDNIE_R107_QUADRANT_TMP4(x) (((x) & 0xff) << 0)
+
+/* R124 */
+#define MDNIE_R124_CABC_BLU_ENABLE (1 << 1)
+#define MDNIE_R124_DISPLAY_SEL_OLED (1 << 0)
+
+/* R125 */
+#define MDNIE_R125_ALS_FLAG_UPDATED (1 << 0)
+
+/* R126 */
+#define MDNIE_R126_ALS_DATA_MASK (0xffff << 0)
+#define MDNIE_R126_ALS_DATA(x) (((x) & 0xffff) << 0)
+
+/* R127 */
+#define MDNIE_R127_WIN_SIZE_MASK (0xf << 4)
+#define MDNIE_R127_WIN_SIZE(x) (((x) & 0xf) << 4)
+#define MDNIE_R127_ALS_MODE_MASK (0x3 << 0)
+#define MDNIE_R127_ALS_MODE(x) (((x) & 0x3) << 0)
+
+/* R130 */
+#define MDNIE_R130_AMB_LVL_MASK (0x4 << 0)
+#define MDNIE_R130_AMB_LVL(x) (((x) & 0x4) << 0)
+
+/* R179 */
+#define MDNIE_R179_UP_SL_MASK (0xff << 8)
+#define MDNIE_R179_UP_SL(x) (((x) & 0xff) << 8)
+#define MDNIE_R179_DOWN_SL_MASK (0xff << 0)
+#define MDNIE_R179_DOWN_SL(x) (((x) & 0xff) << 0)
+
+/* R180 */
+#define MDNIE_R180_PWM_CE_PWM_COEFF (1 << 15)
+#define MDNIE_R180_POLARITY_HIGH_ACTIVE (1 << 14)
+#define MDNIE_R180_LABC_MODE_MASK (0x3 << 12)
+#define MDNIE_R180_LABC_MODE(x) (((x) & 0x3) << 12)
+#define MDNIE_R180_ALC_EN (1 << 11)
+#define MDNIE_R180_PWM_COEFF_COUNT_MASK (0x7ff << 0)
+#define MDNIE_R180_PWM_COEFF_COUNT(x) (((x) & 0x7ff) << 0)
+
+/* R238 */
+#define MDNIE_R238_ROI_DITHER (1 << 15)
+#define MDNIE_R238_ROI_OUTSIDE (1 << 14)
+#define MDNIE_R238_H_START_MASK (0x7ff << 0)
+#define MDNIE_R238_H_START(x) (((x) & 0x7ff) << 0)
+
+/* R239 */
+#define MDNIE_R239_H_END_MASK (0x7ff << 0)
+#define MDNIE_R239_H_END(x) (((x) & 0x7ff) << 0)
+
+/* R240 */
+#define MDNIE_R240_V_START_MASK (0x7ff << 0)
+#define MDNIE_R240_V_START(x) (((x) & 0x7ff) << 0)
+
+/* R241 */
+#define MDNIE_R241_V_END_MASK (0x7ff << 0)
+#define MDNIE_R241_V_END(x) (((x) & 0x7ff) << 0)
+
+#endif
diff --git a/drivers/video/samsung_duallcd/extension/regs_fimd_lite.h b/drivers/video/samsung_duallcd/extension/regs_fimd_lite.h
new file mode 100644
index 0000000..fda0d2a
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/regs_fimd_lite.h
@@ -0,0 +1,396 @@
+/* linux/asm/arch/regs-ielcd.h
+ *
+ * Register definition file for Samsung Display Controller (FIMD-lite) driver
+ *
+ * InKi Dae, <inki.dae@samsung.com>
+ *
+ * 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 _REGS_IELCD_H
+#define _REGS_IELCD_H
+
+#define S5P_LCDREG(x) (x)
+#define S5P_WINCON(x) S5P_LCDREG(0x0020 + (x * 0x04))
+#define S5P_VIDOSD_A(x) S5P_LCDREG(0x0040 + (x * 0x10))
+#define S5P_VIDOSD_B(x) S5P_LCDREG(0x0044 + (x * 0x10))
+#define S5P_VIDOSD_C(x) S5P_LCDREG(0x0048 + (x * 0x10))
+#define S5P_VIDOSD_D(x) S5P_LCDREG(0x004C + (x * 0x10))
+#define S5P_VIDADDR_START0(x) S5P_LCDREG(0x00A0 + (x * 0x08))
+#define S5P_VIDADDR_START1(x) S5P_LCDREG(0x00A4 + (x * 0x08))
+#define S5P_VIDADDR_END0(x) S5P_LCDREG(0x00D0 + (x * 0x08))
+#define S5P_VIDADDR_END1(x) S5P_LCDREG(0x00D4 + (x * 0x08))
+#define S5P_VIDADDR_SIZE(x) S5P_LCDREG(0x0100 + (x * 0x04))
+#define S5P_KEYCON(x) S5P_LCDREG(0x0140 + ((x - 1) * 0x08))
+#define S5P_KEYVAL(x) S5P_LCDREG(0x0144 + ((x - 1) * 0x08))
+
+/*
+ * Register Map
+*/
+#define S5P_VIDCON0 S5P_LCDREG(0x0000)
+#define S5P_VIDCON1 S5P_LCDREG(0x0004)
+#define S5P_VIDCON2 S5P_LCDREG(0x0008)
+#define S5P_PRTCON S5P_LCDREG(0x000C)
+
+#define S5P_VIDTCON0 S5P_LCDREG(0x0010)
+#define S5P_VIDTCON1 S5P_LCDREG(0x0014)
+#define S5P_VIDTCON2 S5P_LCDREG(0x0018)
+#define S5P_VIDTCON3 S5P_LCDREG(0x001C)
+
+#define S5P_WINCON0 S5P_LCDREG(0x0020)
+#define S5P_WINCON1 S5P_LCDREG(0x0024)
+#define S5P_WINCON2 S5P_LCDREG(0x0028)
+#define S5P_WINCON3 S5P_LCDREG(0x002C)
+#define S5P_WINCON4 S5P_LCDREG(0x0030)
+
+#define S5P_VIDOSD0A S5P_LCDREG(0x0040)
+#define S5P_VIDOSD0B S5P_LCDREG(0x0044)
+#define S5P_VIDOSD0C S5P_LCDREG(0x0048)
+
+#define S5P_VIDOSD1A S5P_LCDREG(0x0050)
+#define S5P_VIDOSD1B S5P_LCDREG(0x0054)
+#define S5P_VIDOSD1C S5P_LCDREG(0x0058)
+#define S5P_VIDOSD1D S5P_LCDREG(0x005C)
+
+#define S5P_VIDOSD2A S5P_LCDREG(0x0060)
+#define S5P_VIDOSD2B S5P_LCDREG(0x0064)
+#define S5P_VIDOSD2C S5P_LCDREG(0x0068)
+#define S5P_VIDOSD2D S5P_LCDREG(0x006C)
+
+#define S5P_VIDOSD3A S5P_LCDREG(0x0070)
+#define S5P_VIDOSD3B S5P_LCDREG(0x0074)
+#define S5P_VIDOSD3C S5P_LCDREG(0x0078)
+
+#define S5P_VIDOSD4A S5P_LCDREG(0x0080)
+#define S5P_VIDOSD4B S5P_LCDREG(0x0084)
+#define S5P_VIDOSD4C S5P_LCDREG(0x0088)
+
+#define S5P_VIDW00ADD0B0 S5P_LCDREG(0x00A0)
+#define S5P_VIDW00ADD0B1 S5P_LCDREG(0x00A4)
+#define S5P_VIDW01ADD0B0 S5P_LCDREG(0x00A8)
+#define S5P_VIDW01ADD0B1 S5P_LCDREG(0x00AC)
+#define S5P_VIDW02ADD0 S5P_LCDREG(0x00B0)
+#define S5P_VIDW03ADD0 S5P_LCDREG(0x00B8)
+#define S5P_VIDW04ADD0 S5P_LCDREG(0x00C0)
+#define S5P_VIDW00ADD1B0 S5P_LCDREG(0x00D0)
+#define S5P_VIDW00ADD1B1 S5P_LCDREG(0x00D4)
+#define S5P_VIDW01ADD1B0 S5P_LCDREG(0x00D8)
+#define S5P_VIDW01ADD1B1 S5P_LCDREG(0x00DC)
+#define S5P_VIDW02ADD1 S5P_LCDREG(0x00E0)
+#define S5P_VIDW03ADD1 S5P_LCDREG(0x00E8)
+#define S5P_VIDW04ADD1 S5P_LCDREG(0x00F0)
+#define S5P_VIDW00ADD2 S5P_LCDREG(0x0100)
+#define S5P_VIDW01ADD2 S5P_LCDREG(0x0104)
+#define S5P_VIDW02ADD2 S5P_LCDREG(0x0108)
+#define S5P_VIDW03ADD2 S5P_LCDREG(0x010C)
+#define S5P_VIDW04ADD2 S5P_LCDREG(0x0110)
+
+#define S5P_VP1TCON0 S5P_LCDREG(0x0118)
+#define S5P_VP1TCON1 S5P_LCDREG(0x011C)
+
+#define S5P_VIDINTCON0 S5P_LCDREG(0x0130)
+#define S5P_VIDINTCON1 S5P_LCDREG(0x0134)
+
+#define S5P_W1KEYCON0 S5P_LCDREG(0x0140) /* Color key control */
+#define S5P_W1KEYCON1 S5P_LCDREG(0x0144)
+#define S5P_W2KEYCON0 S5P_LCDREG(0x0148)
+#define S5P_W2KEYCON1 S5P_LCDREG(0x014C)
+#define S5P_W3KEYCON0 S5P_LCDREG(0x0150)
+#define S5P_W3KEYCON1 S5P_LCDREG(0x0154)
+#define S5P_W4KEYCON0 S5P_LCDREG(0x0158)
+#define S5P_W4KEYCON1 S5P_LCDREG(0x015C)
+
+#define S5P_W1KEYALPHA S5P_LCDREG(0x0160)
+#define S5P_W2KEYALPHA S5P_LCDREG(0x0164)
+#define S5P_W3KEYALPHA S5P_LCDREG(0x0168)
+#define S5P_W4KEYALPHA S5P_LCDREG(0x016C)
+
+#define S5P_DITHMODE S5P_LCDREG(0x0170)
+
+#define S5P_WIN0MAP S5P_LCDREG(0x0180)
+#define S5P_WIN1MAP S5P_LCDREG(0x0184)
+#define S5P_WIN2MAP S5P_LCDREG(0x0188)
+#define S5P_WIN3MAP S5P_LCDREG(0x018C)
+#define S5P_WIN4MAP S5P_LCDREG(0x0190)
+
+#define S5P_WPALCON_H S5P_LCDREG(0x019C)
+#define S5P_WPALCON_L S5P_LCDREG(0x01A0)
+
+#define S5P_VIDW0ALPHA0 S5P_LCDREG(0x0200)
+#define S5P_VIDW0ALPHA1 S5P_LCDREG(0x0204)
+#define S5P_VIDW1ALPHA0 S5P_LCDREG(0x0208)
+#define S5P_VIDW1ALPHA1 S5P_LCDREG(0x020C)
+#define S5P_VIDW2ALPHA0 S5P_LCDREG(0x0210)
+#define S5P_VIDW2ALPHA1 S5P_LCDREG(0x0214)
+#define S5P_VIDW3ALPHA0 S5P_LCDREG(0x0218)
+#define S5P_VIDW3ALPHA1 S5P_LCDREG(0x021C)
+#define S5P_VIDW4ALPHA0 S5P_LCDREG(0x0220)
+#define S5P_VIDW4ALPHA1 S5P_LCDREG(0x0224)
+
+#define S5P_BLENDEQ1 S5P_LCDREG(0x0244)
+#define S5P_BLENDEQ2 S5P_LCDREG(0x0248)
+#define S5P_BLENDEQ3 S5P_LCDREG(0x024C)
+#define S5P_BLENDEQ4 S5P_LCDREG(0x0250)
+#define S5P_BLENDCON S5P_LCDREG(0x0260) /* Blending control */
+#define S5P_GPOUTCON0 S5P_LCDREG(0x0278) /* mDNIe */
+#define S5P_DUALRGB S5P_LCDREG(0x027C) /* DUALRGB Register */
+
+/*
+ * Bit Definitions
+*/
+
+/* VIDCON0 */
+#define S5P_VIDCON0_DSI_DISABLE (0 << 30)
+#define S5P_VIDCON0_DSI_ENABLE (1 << 30)
+#define S5P_VIDCON0_SCAN_PROGRESSIVE (0 << 29)
+#define S5P_VIDCON0_SCAN_INTERLACE (1 << 29)
+#define S5P_VIDCON0_SCAN_MASK (1 << 29)
+#define S5P_VIDCON0_VIDOUT_RGB (0 << 26)
+#define S5P_VIDCON0_VIDOUT_ITU (1 << 26)
+#define S5P_VIDCON0_VIDOUT_I80LDI0 (2 << 26)
+#define S5P_VIDCON0_VIDOUT_I80LDI1 (3 << 26)
+#define S5P_VIDCON0_VIDOUT_MASK (3 << 26)
+#define S5P_VIDCON0_PNRMODE_RGB_P (0 << 17)
+#define S5P_VIDCON0_PNRMODE_BGR_P (1 << 17)
+#define S5P_VIDCON0_PNRMODE_RGB_S (2 << 17)
+#define S5P_VIDCON0_PNRMODE_BGR_S (3 << 17)
+#define S5P_VIDCON0_PNRMODE_MASK (3 << 17)
+#define S5P_VIDCON0_PNRMODE_SHIFT (17)
+#define S5P_VIDCON0_CLKVALUP_ALWAYS (0 << 16)
+#define S5P_VIDCON0_CLKVALUP_START_FRAME (1 << 16)
+#define S5P_VIDCON0_CLKVALUP_MASK (1 << 16)
+#define S5P_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6)
+#define S5P_VIDCON0_VCLKEN_NORMAL (0 << 5)
+#define S5P_VIDCON0_VCLKEN_FREERUN (1 << 5)
+#define S5P_VIDCON0_VCLKEN_MASK (1 << 5)
+#define S5P_VIDCON0_CLKDIR_DIRECTED (0 << 4)
+#define S5P_VIDCON0_CLKDIR_DIVIDED (1 << 4)
+#define S5P_VIDCON0_CLKDIR_MASK (1 << 4)
+#define S5P_VIDCON0_CLKSEL_HCLK (0 << 2)
+#define S5P_VIDCON0_CLKSEL_SCLK (1 << 2)
+#define S5P_VIDCON0_CLKSEL_MASK (1 << 2)
+#define S5P_VIDCON0_ENVID_ENABLE (1 << 1)
+#define S5P_VIDCON0_ENVID_DISABLE (0 << 1)
+#define S5P_VIDCON0_ENVID_F_ENABLE (1 << 0)
+#define S5P_VIDCON0_ENVID_F_DISABLE (0 << 0)
+
+/* VIDCON1 */
+
+#define S5P_VIDCON1_VSTATUS_VSYNC 0x0
+#define S5P_VIDCON1_VSTATUS_BACKPORCH 0x1
+#define S5P_VIDCON1_VSTATUS_ACTIVE 0x2
+#define S5P_VIDCON1_VSTATUS_FRONTPORCH 0x3
+#define S5P_VIDCON1_VSTATUS_MASK 0x3
+
+#define S5P_VIDCON1_FIXVCLK_VDEN_DISABLE (3 << 9)
+#define S5P_VIDCON1_FIXVCLK_RUNNING (1 << 9)
+#define S5P_VIDCON1_FIXVCLK_HOLD (0 << 9)
+#define S5P_VIDCON1_IVCLK_FALLING_EDGE (0 << 7)
+#define S5P_VIDCON1_IVCLK_RISING_EDGE (1 << 7)
+#define S5P_VIDCON1_IHSYNC_NORMAL (0 << 6)
+#define S5P_VIDCON1_IHSYNC_INVERT (1 << 6)
+#define S5P_VIDCON1_IVSYNC_NORMAL (0 << 5)
+#define S5P_VIDCON1_IVSYNC_INVERT (1 << 5)
+#define S5P_VIDCON1_IVDEN_NORMAL (0 << 4)
+#define S5P_VIDCON1_IVDEN_INVERT (1 << 4)
+
+/* VIDCON2 */
+#define S5P_VIDCON2_EN601_DISABLE (0 << 23)
+#define S5P_VIDCON2_EN601_ENABLE (1 << 23)
+#define S5P_VIDCON2_EN601_MASK (1 << 23)
+#define S5P_VIDCON2_ORGYUV_YCBCR (0 << 8)
+#define S5P_VIDCON2_ORGYUV_CBCRY (1 << 8)
+#define S5P_VIDCON2_ORGYUV_MASK (1 << 8)
+#define S5P_VIDCON2_YUVORD_CBCR (0 << 7)
+#define S5P_VIDCON2_YUVORD_CRCB (1 << 7)
+#define S5P_VIDCON2_YUVORD_MASK (1 << 7)
+
+/* PRTCON */
+#define S5P_PRTCON_UPDATABLE (0 << 11)
+#define S5P_PRTCON_PROTECT (1 << 11)
+
+/* VIDTCON0 */
+#define S5P_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24)
+#define S5P_VIDTCON0_VBPD(x) (((x) & 0xff) << 16)
+#define S5P_VIDTCON0_VFPD(x) (((x) & 0xff) << 8)
+#define S5P_VIDTCON0_VSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON1 */
+#define S5P_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24)
+#define S5P_VIDTCON1_HBPD(x) (((x) & 0xff) << 16)
+#define S5P_VIDTCON1_HFPD(x) (((x) & 0xff) << 8)
+#define S5P_VIDTCON1_HSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON2 */
+#define S5P_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11)
+#define S5P_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0)
+
+/* VIDTCON3 */
+#define S5P_VIDTCON3_VSYNCEN (1 << 31)
+#define S5P_VIDTCON3_FRMEN (1 << 29)
+#define S5P_VIDTCON3_FRMVRATE(x) ((x) << 24)
+
+/* Window 0~4 Control - WINCONx */
+#define S5P_WINCON_DATAPATH_DMA (0 << 22)
+#define S5P_WINCON_DATAPATH_LOCAL (1 << 22)
+#define S5P_WINCON_DATAPATH_MASK (1 << 22)
+#define S5P_WINCON_BUFSEL_0 (0 << 20)
+#define S5P_WINCON_BUFSEL_1 (1 << 20)
+#define S5P_WINCON_BUFSEL_MASK (1 << 20)
+#define S5P_WINCON_BUFSEL_SHIFT (20)
+#define S5P_WINCON_BUFAUTO_DISABLE (0 << 19)
+#define S5P_WINCON_BUFAUTO_ENABLE (1 << 19)
+#define S5P_WINCON_BUFAUTO_MASK (1 << 19)
+#define S5P_WINCON_BITSWP_DISABLE (0 << 18)
+#define S5P_WINCON_BITSWP_ENABLE (1 << 18)
+#define S5P_WINCON_BITSWP_SHIFT (18)
+#define S5P_WINCON_BYTESWP_DISABLE (0 << 17)
+#define S5P_WINCON_BYTESWP_ENABLE (1 << 17)
+#define S5P_WINCON_BYTESWP_SHIFT (17)
+#define S5P_WINCON_HAWSWP_DISABLE (0 << 16)
+#define S5P_WINCON_HAWSWP_ENABLE (1 << 16)
+#define S5P_WINCON_HAWSWP_SHIFT (16)
+#define S5P_WINCON_WSWP_DISABLE (0 << 15)
+#define S5P_WINCON_WSWP_ENABLE (1 << 15)
+#define S5P_WINCON_WSWP_SHIFT (15)
+#define S5P_WINCON_INRGB_RGB (0 << 13)
+#define S5P_WINCON_INRGB_YUV (1 << 13)
+#define S5P_WINCON_INRGB_MASK (1 << 13)
+#define S5P_WINCON_BURSTLEN_16WORD (0 << 9)
+#define S5P_WINCON_BURSTLEN_8WORD (1 << 9)
+#define S5P_WINCON_BURSTLEN_4WORD (2 << 9)
+#define S5P_WINCON_BURSTLEN_MASK (3 << 9)
+#define S5P_WINCON_ALPHA_MULTI_DISABLE (0 << 7)
+#define S5P_WINCON_ALPHA_MULTI_ENABLE (1 << 7)
+#define S5P_WINCON_BLD_PLANE (0 << 6)
+#define S5P_WINCON_BLD_PIXEL (1 << 6)
+#define S5P_WINCON_BLD_MASK (1 << 6)
+#define S5P_WINCON_BPPMODE_1BPP (0 << 2)
+#define S5P_WINCON_BPPMODE_2BPP (1 << 2)
+#define S5P_WINCON_BPPMODE_4BPP (2 << 2)
+#define S5P_WINCON_BPPMODE_8BPP_PAL (3 << 2)
+#define S5P_WINCON_BPPMODE_8BPP (4 << 2)
+#define S5P_WINCON_BPPMODE_16BPP_565 (5 << 2)
+#define S5P_WINCON_BPPMODE_16BPP_A555 (6 << 2)
+#define S5P_WINCON_BPPMODE_18BPP_666 (8 << 2)
+#define S5P_WINCON_BPPMODE_18BPP_A665 (9 << 2)
+#define S5P_WINCON_BPPMODE_24BPP_888 (0xb << 2)
+#define S5P_WINCON_BPPMODE_24BPP_A887 (0xc << 2)
+#define S5P_WINCON_BPPMODE_32BPP (0xd << 2)
+#define S5P_WINCON_BPPMODE_16BPP_A444 (0xe << 2)
+#define S5P_WINCON_BPPMODE_15BPP_555 (0xf << 2)
+#define S5P_WINCON_BPPMODE_MASK (0xf << 2)
+#define S5P_WINCON_BPPMODE_SHIFT (2)
+#define S5P_WINCON_ALPHA0_SEL (0 << 1)
+#define S5P_WINCON_ALPHA1_SEL (1 << 1)
+#define S5P_WINCON_ALPHA_SEL_MASK (1 << 1)
+#define S5P_WINCON_ENWIN_DISABLE (0 << 0)
+#define S5P_WINCON_ENWIN_ENABLE (1 << 0)
+
+/* WINCON1 special */
+#define S5P_WINCON1_VP_DISABLE (0 << 24)
+#define S5P_WINCON1_VP_ENABLE (1 << 24)
+#define S5P_WINCON1_LOCALSEL_FIMC1 (0 << 23)
+#define S5P_WINCON1_LOCALSEL_VP (1 << 23)
+#define S5P_WINCON1_LOCALSEL_MASK (1 << 23)
+
+/* VIDOSDxA, VIDOSDxB */
+#define S5P_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11)
+#define S5P_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0)
+#define S5P_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11)
+#define S5P_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0)
+
+/* VIDOSD0C, VIDOSDxD */
+#define S5P_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0)
+
+/* VIDOSDxC (1~4) */
+#define S5P_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20)
+#define S5P_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16)
+#define S5P_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12)
+#define S5P_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8)
+#define S5P_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4)
+#define S5P_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0)
+#define S5P_VIDOSD_ALPHA0_SHIFT (12)
+#define S5P_VIDOSD_ALPHA1_SHIFT (0)
+
+/* Start Address */
+#define S5P_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24)
+#define S5P_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0)
+
+/* End Address */
+#define S5P_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0)
+
+/* Buffer Size */
+#define S5P_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13)
+#define S5P_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0)
+
+/* VIDINTCON0 */
+#define S5P_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19)
+#define S5P_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19)
+#define S5P_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18)
+#define S5P_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18)
+#define S5P_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17)
+#define S5P_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17)
+#define S5P_VIDINTCON0_FRAMESEL0_BACK (0 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_FRONT (3 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_MASK (3 << 15)
+#define S5P_VIDINTCON0_FRAMESEL1_NONE (0 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_BACK (1 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_FRONT (3 << 13)
+#define S5P_VIDINTCON0_INTFRMEN_DISABLE (0 << 12)
+#define S5P_VIDINTCON0_INTFRMEN_ENABLE (1 << 12)
+#define S5P_VIDINTCON0_FIFOSEL_WIN4 (1 << 11)
+#define S5P_VIDINTCON0_FIFOSEL_WIN3 (1 << 10)
+#define S5P_VIDINTCON0_FIFOSEL_WIN2 (1 << 9)
+#define S5P_VIDINTCON0_FIFOSEL_WIN1 (1 << 6)
+#define S5P_VIDINTCON0_FIFOSEL_WIN0 (1 << 5)
+#define S5P_VIDINTCON0_FIFOSEL_ALL (0x73 << 5)
+#define S5P_VIDINTCON0_FIFOSEL_MASK (0x73 << 5)
+#define S5P_VIDINTCON0_FIFOLEVEL_25 (0 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_50 (1 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_75 (2 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_FULL (4 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_MASK (7 << 2)
+#define S5P_VIDINTCON0_INTFIFO_DISABLE (0 << 1)
+#define S5P_VIDINTCON0_INTFIFO_ENABLE (1 << 1)
+#define S5P_VIDINTCON0_INT_DISABLE (0 << 0)
+#define S5P_VIDINTCON0_INT_ENABLE (1 << 0)
+#define S5P_VIDINTCON0_INT_MASK (1 << 0)
+
+/* VIDINTCON1 */
+#define S5P_VIDINTCON1_INTVPPEND (1 << 5)
+#define S5P_VIDINTCON1_INTI80PEND (1 << 2)
+#define S5P_VIDINTCON1_INTFRMPEND (1 << 1)
+#define S5P_VIDINTCON1_INTFIFOPEND (1 << 0)
+
+/* WxKEYCON0 (1~4) */
+#define S5P_KEYCON0_KEYBLEN_DISABLE (0 << 26)
+#define S5P_KEYCON0_KEYBLEN_ENABLE (1 << 26)
+#define S5P_KEYCON0_KEY_DISABLEi (0 << 25)
+#define S5P_KEYCON0_KEY_ENABLE (1 << 25)
+#define S5P_KEYCON0_DIRCON_MATCH_FG (0 << 24)
+#define S5P_KEYCON0_DIRCON_MATCH_BG (1 << 24)
+#define S5P_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0)
+
+/* WxKEYCON1 (1~4) */
+#define S5P_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0)
+
+/* DUALRGB */
+#define S5P_DUALRGB_BYPASS_SINGLE (0x00 << 0)
+#define S5P_DUALRGB_BYPASS_DUAL (0x01 << 0)
+#define S5P_DUALRGB_MIE_DUAL (0x10 << 0)
+#define S5P_DUALRGB_MIE_SINGLE (0x11 << 0)
+#define S5P_DUALRGB_LINESPLIT (0x0 << 2)
+#define S5P_DUALRGB_FRAMESPLIT (0x1 << 2)
+#define S5P_DUALRGB_SUB_CNT(x) ((x & 0xfff) << 4)
+#define S5P_DUALRGB_VDEN_EN_DISABLE (0x0 << 16)
+#define S5P_DUALRGB_VDEN_EN_ENABLE (0x1 << 16)
+#define S5P_DUALRGB_MAIN_CNT(x) ((x & 0xfff) << 18)
+
+#endif /* _REGS_IELCD_H */
diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c
new file mode 100644
index 0000000..0c197b6
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.c
@@ -0,0 +1,209 @@
+/* linux/drivers/video/samsung/s5p_fimd_ext.c
+ *
+ * Samsung SoC FIMD Extension Device Framework.
+ *
+ * Inki Dae <inki.dae@samsung.com>
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <plat/fimd_lite_ext.h>
+
+#include "s5p_fimd_ext.h"
+
+struct s5p_fimd_ext {
+ struct list_head list;
+ struct device *dev;
+};
+
+static LIST_HEAD(fimd_ext_list);
+static DEFINE_MUTEX(fimd_ext_lock);
+
+struct s5p_fimd_ext_device *to_fimd_ext_device(struct device *dev)
+{
+ return dev ? container_of(dev, struct s5p_fimd_ext_device, dev) : NULL;
+}
+EXPORT_SYMBOL(to_fimd_ext_device);
+
+struct s5p_fimd_ext_driver *to_fimd_ext_driver(struct device_driver *drv)
+{
+ return drv ? container_of(drv, struct s5p_fimd_ext_driver, driver) :
+ NULL;
+}
+EXPORT_SYMBOL(to_fimd_ext_driver);
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
+ char *buf)
+{
+ struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", fx_dev->name);
+
+ return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
+}
+
+static struct device_attribute s5p_fimd_ext_dev_attrs[] = {
+ __ATTR_RO(modalias),
+ __ATTR_NULL,
+};
+
+static int s5p_fimd_ext_match_device(struct device *dev,
+ struct device_driver *drv)
+{
+ const struct s5p_fimd_ext_device *fx_dev = to_fimd_ext_device(dev);
+ const struct s5p_fimd_ext_driver *fx_drv = to_fimd_ext_driver(drv);
+
+ return strcmp(fx_dev->name, fx_drv->driver.name) == 0;
+}
+
+struct bus_type s5p_fimd_ext_bus_type = {
+ .name = "fimd_ext",
+ .dev_attrs = s5p_fimd_ext_dev_attrs,
+ .match = s5p_fimd_ext_match_device,
+};
+
+static int s5p_fimd_ext_drv_probe(struct device *dev)
+{
+ const struct s5p_fimd_ext_driver *fx_drv =
+ to_fimd_ext_driver(dev->driver);
+
+ return fx_drv->probe(to_fimd_ext_device(dev));
+}
+
+struct resource *s5p_fimd_ext_get_resource(struct s5p_fimd_ext_device *fx_dev,
+ unsigned int type, unsigned int num)
+{
+ int i;
+
+ for (i = 0; i < fx_dev->num_resources; i++) {
+ struct resource *r = &fx_dev->resource[i];
+
+ if (type == resource_type(r) && num-- == 0)
+ return r;
+ }
+
+ return NULL;
+}
+
+int s5p_fimd_ext_get_irq(struct s5p_fimd_ext_device *fx_dev, unsigned int num)
+{
+ struct resource *r = s5p_fimd_ext_get_resource(fx_dev,
+ IORESOURCE_IRQ, num);
+
+ return r ? r->start : -ENXIO;
+}
+
+int s5p_fimd_ext_device_register(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct s5p_fimd_ext *fimd_ext;
+ int i, ret = 0;
+
+ fimd_ext = kzalloc(sizeof(struct s5p_fimd_ext), GFP_KERNEL);
+ if (!fimd_ext) {
+ printk(KERN_ERR "failed to allocate fimd_ext object.\n");
+ return -EFAULT;
+ }
+
+ fimd_ext->dev = &fx_dev->dev;
+
+ device_initialize(&fx_dev->dev);
+
+ if (!fx_dev->dev.parent)
+ fx_dev->dev.parent = &platform_bus;
+
+ fx_dev->dev.bus = &s5p_fimd_ext_bus_type;
+
+ if (fx_dev->id != -1)
+ dev_set_name(&fx_dev->dev, "%s.%d", fx_dev->name, fx_dev->id);
+ else
+ dev_set_name(&fx_dev->dev, "%s", fx_dev->name);
+
+ for (i = 0; i < fx_dev->num_resources; i++) {
+ struct resource *r = &fx_dev->resource[i];
+
+ if (r->name == NULL)
+ r->name = dev_name(&fx_dev->dev);
+ }
+
+ ret = device_add(&fx_dev->dev);
+ if (ret == 0) {
+ mutex_lock(&fimd_ext_lock);
+ list_add_tail(&fimd_ext->list, &fimd_ext_list);
+ mutex_unlock(&fimd_ext_lock);
+
+ return ret;
+ }
+
+ kfree(fimd_ext);
+
+ return ret;
+}
+EXPORT_SYMBOL(s5p_fimd_ext_device_register);
+
+int s5p_fimd_ext_driver_register(struct s5p_fimd_ext_driver *fx_drv)
+{
+ fx_drv->driver.bus = &s5p_fimd_ext_bus_type;
+ if (fx_drv->probe)
+ fx_drv->driver.probe = s5p_fimd_ext_drv_probe;
+
+ /* add some callbacks here. */
+
+ printk(KERN_DEBUG "registered a driver(%s) to fimd_ext driver.\n",
+ fx_drv->driver.name);
+
+ return driver_register(&fx_drv->driver);
+}
+EXPORT_SYMBOL(s5p_fimd_ext_driver_register);
+
+struct s5p_fimd_ext_device *s5p_fimd_ext_find_device(const char *name)
+{
+ struct s5p_fimd_ext *fimd_ext;
+ struct s5p_fimd_ext_device *fx_dev;
+ struct device *dev;
+
+ mutex_lock(&fimd_ext_lock);
+
+ printk(KERN_DEBUG "find ext driver (%s).\n", name);
+
+ list_for_each_entry(fimd_ext, &fimd_ext_list, list) {
+ dev = fimd_ext->dev;
+ fx_dev = to_fimd_ext_device(dev);
+
+ if ((strcmp(fx_dev->name, name)) == 0) {
+ mutex_unlock(&fimd_ext_lock);
+ printk(KERN_DEBUG "found!!!(%s).\n", fx_dev->name);
+ return fx_dev;
+ }
+ }
+
+ printk(KERN_WARNING "failed to find ext device(%s).\n", name);
+
+ mutex_unlock(&fimd_ext_lock);
+
+ return NULL;
+}
+
+static int __init s5p_fimd_ext_init(void)
+{
+ return bus_register(&s5p_fimd_ext_bus_type);
+}
+
+static void __exit s5p_fimd_ext_exit(void)
+{
+}
+
+early_initcall(s5p_fimd_ext_init);
+module_exit(s5p_fimd_ext_exit);
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("Samsung SoC FIMD Extension Framework");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h
new file mode 100644
index 0000000..3a4dc3a
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_ext.h
@@ -0,0 +1,30 @@
+/* linux/driver/video/samsung/s5p_fimd_ext.h
+ *
+ * Samsung SoC FIMD Extension Framework Header.
+ *
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * 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 _S5P_FIMD_EXT_H
+#define _S5P_FIMD_EXT_H
+
+#include <linux/device.h>
+
+struct s5p_fimd_ext_device
+ *to_fimd_ext_device(struct device *dev);
+
+struct resource *s5p_fimd_ext_get_resource(struct s5p_fimd_ext_device *fx_dev,
+ unsigned int type, unsigned int num);
+
+int s5p_fimd_ext_get_irq(struct s5p_fimd_ext_device *fx_dev,
+ unsigned int num);
+
+int s5p_fimd_ext_device_register(struct s5p_fimd_ext_device *fx_dev);
+
+int s5p_fimd_ext_driver_register(struct s5p_fimd_ext_driver *fx_drv);
+
+#endif /* _S5P_FIMD_EXT_H */
diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c
new file mode 100644
index 0000000..3e128b8
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.c
@@ -0,0 +1,502 @@
+/* /linux/driver/video/samsung/s5p_fimd_lite.c
+ *
+ * Samsung SoC FIMD Lite driver.
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+
+#include <plat/clock.h>
+#include <plat/fb.h>
+#include <plat/cpu.h>
+#include <plat/fimd_lite_ext.h>
+#include <plat/regs-fb.h>
+
+#include <mach/map.h>
+
+#include "s5p_fimd_ext.h"
+#include "s5p_fimd_lite.h"
+#include "regs_fimd_lite.h"
+
+static void *to_fimd_lite_platform_data(struct s5p_fimd_ext_device *fx_dev)
+{
+ return fx_dev->dev.platform_data ? (void *)fx_dev->dev.platform_data :
+ NULL;
+}
+
+static void s5p_fimd_lite_set_par(struct s5p_fimd_lite *fimd_lite,
+ unsigned int win_id)
+{
+ struct exynos_drm_fimd_pdata *lcd;
+ struct fb_videomode timing;
+ unsigned int cfg;
+
+ lcd = fimd_lite->lcd;
+ timing = lcd->panel.timing;
+
+ /* set window control */
+ cfg = readl(fimd_lite->iomem_base + S5P_WINCON(win_id));
+
+ cfg &= ~(S5P_WINCON_BITSWP_ENABLE | S5P_WINCON_BYTESWP_ENABLE | \
+ S5P_WINCON_HAWSWP_ENABLE | S5P_WINCON_WSWP_ENABLE | \
+ S5P_WINCON_BURSTLEN_MASK | S5P_WINCON_BPPMODE_MASK | \
+ S5P_WINCON_INRGB_MASK | S5P_WINCON_DATAPATH_MASK);
+
+ /* DATAPATH is LOCAL */
+ cfg |= S5P_WINCON_DATAPATH_LOCAL;
+
+ /* pixel format is unpacked RGB888 */
+ cfg |= S5P_WINCON_INRGB_RGB | S5P_WINCON_BPPMODE_32BPP;
+
+ writel(cfg, fimd_lite->iomem_base + S5P_WINCON(win_id));
+
+ /* set window position to x=0, y=0*/
+ cfg = S5P_VIDOSD_LEFT_X(0) | S5P_VIDOSD_TOP_Y(0);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDOSD_A(win_id));
+
+ cfg = S5P_VIDOSD_RIGHT_X(timing.xres - 1) |
+ S5P_VIDOSD_BOTTOM_Y(timing.yres - 1);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDOSD_B(win_id));
+
+ /* set window size for window0*/
+ cfg = S5P_VIDOSD_SIZE(timing.xres * timing.yres);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDOSD_C(win_id));
+
+ return;
+}
+
+static void s5p_fimd_lite_set_clock(struct s5p_fimd_lite *fimd_lite)
+{
+ unsigned int cfg = 0, div = 0;
+ unsigned int pixel_clock, src_clock, max_clock;
+ struct clk *clk;
+ struct exynos_drm_fimd_pdata *lcd;
+ struct fb_videomode timing;
+
+ lcd = fimd_lite->lcd;
+ timing = lcd->panel.timing;
+
+ clk = fimd_lite->clk;
+
+ max_clock = 86 * 1000000;
+
+ pixel_clock = timing.refresh *
+ (timing.left_margin + timing.right_margin +
+ timing.hsync_len + timing.xres) * (timing.upper_margin +
+ timing.lower_margin + timing.vsync_len + timing.yres);
+
+ src_clock = clk_get_rate(clk->parent);
+
+ cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0);
+ cfg &= ~(S5P_VIDCON0_VCLKEN_MASK | S5P_VIDCON0_CLKVALUP_MASK |
+ S5P_VIDCON0_CLKVAL_F(0xFF));
+ cfg |= (S5P_VIDCON0_CLKVALUP_ALWAYS | S5P_VIDCON0_VCLKEN_NORMAL);
+
+ cfg |= S5P_VIDCON0_CLKSEL_HCLK;
+
+ if (pixel_clock > max_clock)
+ pixel_clock = max_clock;
+
+ div = (unsigned int)(src_clock / pixel_clock);
+ if (src_clock % pixel_clock)
+ div++;
+
+ cfg |= S5P_VIDCON0_CLKVAL_F(div - 1);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0);
+
+ return;
+}
+
+static void s5p_fimd_lite_window_on(struct s5p_fimd_lite *fimd_lite,
+ unsigned int win_id, unsigned int enable)
+{
+ unsigned int cfg;
+
+ /* enable window */
+ cfg = readl(fimd_lite->iomem_base + S5P_WINCON(win_id));
+
+ cfg &= ~S5P_WINCON_ENWIN_ENABLE;
+
+ if (enable)
+ cfg |= S5P_WINCON_ENWIN_ENABLE;
+
+ writel(cfg, fimd_lite->iomem_base + S5P_WINCON(win_id));
+}
+
+static void s5p_fimd_lite_lcd_on(struct s5p_fimd_lite *fimd_lite,
+ unsigned int enable)
+{
+ unsigned int cfg;
+
+ cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0);
+
+ cfg &= ~(S5P_VIDCON0_ENVID_ENABLE | S5P_VIDCON0_ENVID_F_ENABLE);
+
+ if (enable)
+ cfg |= (S5P_VIDCON0_ENVID_ENABLE | S5P_VIDCON0_ENVID_F_ENABLE);
+
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0);
+}
+
+void s5p_fimd_lite_get_vsync_interrupt(struct s5p_fimd_lite *fimd_lite,
+ unsigned int enable)
+{
+ unsigned int cfg;
+
+ cfg = readl(fimd_lite->iomem_base + S5P_VIDINTCON0);
+ cfg &= ~(S5P_VIDINTCON0_INTFRMEN_ENABLE | S5P_VIDINTCON0_INT_ENABLE |
+ S5P_VIDINTCON0_FRAMESEL0_VSYNC);
+
+ if (enable) {
+ cfg |= (S5P_VIDINTCON0_INTFRMEN_ENABLE |
+ S5P_VIDINTCON0_INT_ENABLE |
+ S5P_VIDINTCON0_FRAMESEL0_VSYNC);
+ } else {
+ cfg |= (S5P_VIDINTCON0_INTFRMEN_DISABLE |
+ S5P_VIDINTCON0_INT_DISABLE);
+
+ cfg &= ~S5P_VIDINTCON0_FRAMESEL0_VSYNC;
+ }
+
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDINTCON0);
+}
+
+static void s5p_change_dynamic_refresh(struct s5p_fimd_dynamic_refresh
+ *fimd_refresh, struct s5p_fimd_ext_device *fx_dev)
+{
+ unsigned int cfg = 0, ret = 0;
+ struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev);
+ struct exynos_drm_fimd_pdata *lcd;
+ struct fb_videomode timing;
+ unsigned long flags;
+ u32 vclk, src_clk, refresh;
+
+ lcd = fimd_lite->lcd;
+ timing = lcd->panel.timing;
+
+ cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0);
+ cfg &= ~(S5P_VIDCON0_CLKVALUP_START_FRAME | S5P_VIDCON0_CLKVAL_F(0xFF));
+ cfg |= (S5P_VIDCON0_CLKVALUP_ALWAYS | S5P_VIDCON0_VCLKEN_NORMAL);
+ cfg |= S5P_VIDCON0_CLKVAL_F(fimd_refresh->clkdiv - 1);
+
+ if (!irqs_disabled())
+ local_irq_save(flags);
+
+ if (timing.refresh == 60) {
+ while (1) {
+ ret = (__raw_readl(fimd_lite->iomem_base +
+ S5P_VIDCON1) >> 13) &
+ S5P_VIDCON1_VSTATUS_MASK;
+ if (ret == S5P_VIDCON1_VSTATUS_BACKPORCH) {
+ __raw_writel(cfg, fimd_lite->iomem_base +
+ S5P_VIDCON0);
+ ret = (__raw_readl(fimd_refresh->regs +
+ VIDCON1) >> 13) &
+ S5P_VIDCON1_VSTATUS_MASK;
+ if (ret == S5P_VIDCON1_VSTATUS_ACTIVE) {
+ __raw_writel(cfg,
+ fimd_refresh->regs + VIDCON0);
+ break;
+ }
+ }
+ }
+ } else {
+ while (1) {
+ ret = (__raw_readl(fimd_refresh->regs + VIDCON1) >> 13)
+ & S5P_VIDCON1_VSTATUS_MASK;
+ if (ret == S5P_VIDCON1_VSTATUS_ACTIVE) {
+ ret = (__raw_readl(fimd_lite->iomem_base +
+ S5P_VIDCON1) >> 13) &
+ S5P_VIDCON1_VSTATUS_MASK;
+ if (ret == S5P_VIDCON1_VSTATUS_FRONTPORCH) {
+ __raw_writel(cfg,
+ fimd_refresh->regs + VIDCON0);
+ __raw_writel(cfg,
+ fimd_lite->iomem_base +
+ S5P_VIDCON0);
+ break;
+ }
+ }
+ }
+ }
+ if (irqs_disabled())
+ local_irq_restore(flags);
+
+ src_clk = clk_get_rate(fimd_lite->clk->parent);
+ vclk = timing.refresh * (timing.left_margin + timing.hsync_len +
+ timing.right_margin + timing.xres) *
+ (timing.upper_margin + timing.vsync_len +
+ timing.lower_margin + timing.yres);
+
+ refresh = timing.refresh -
+ ((vclk - (src_clk / fimd_refresh->clkdiv)) / MHZ);
+ dev_dbg(fimd_lite->dev, "expected refresh rate: %d fps\n", refresh);
+}
+
+static irqreturn_t s5p_fimd_lite_irq_frame(int irq, void *dev_id)
+{
+ struct s5p_fimd_lite *fimd_lite;
+
+ fimd_lite = (struct s5p_fimd_lite *)dev_id;
+
+ disable_irq_nosync(fimd_lite->irq);
+
+ enable_irq(fimd_lite->irq);
+
+ return IRQ_HANDLED;
+}
+
+static void s5p_fimd_lite_logic_start(struct s5p_fimd_lite *fimd_lite,
+ unsigned int enable)
+{
+ unsigned int cfg;
+
+ cfg = 0x2ff47;
+
+ if (enable)
+ writel(cfg, fimd_lite->iomem_base + S5P_GPOUTCON0);
+ else
+ writel(0, fimd_lite->iomem_base + S5P_GPOUTCON0);
+}
+
+static void s5p_fimd_lite_lcd_init(struct s5p_fimd_lite *fimd_lite)
+{
+ unsigned int cfg, rgb_mode, win_id = 0;
+ struct exynos_drm_fimd_pdata *lcd;
+ struct fb_videomode timing;
+
+ lcd = fimd_lite->lcd;
+ timing = lcd->panel.timing;
+
+ cfg = 0;
+ cfg |= lcd->vidcon1;
+
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDCON1);
+
+ /* set timing */
+ cfg = 0;
+ cfg |= S5P_VIDTCON0_VBPD(timing.upper_margin - 1);
+ cfg |= S5P_VIDTCON0_VFPD(timing.lower_margin - 1);
+ cfg |= S5P_VIDTCON0_VSPW(timing.vsync_len - 1);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDTCON0);
+
+ cfg = 0;
+ cfg |= S5P_VIDTCON1_HBPD(timing.left_margin - 1);
+ cfg |= S5P_VIDTCON1_HFPD(timing.right_margin - 1);
+ cfg |= S5P_VIDTCON1_HSPW(timing.hsync_len - 1);
+
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDTCON1);
+
+ /* set lcd size */
+ cfg = 0;
+ cfg |= S5P_VIDTCON2_HOZVAL(timing.xres - 1);
+ cfg |= S5P_VIDTCON2_LINEVAL(timing.yres - 1);
+
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDTCON2);
+
+ writel(0, fimd_lite->iomem_base + S5P_DITHMODE);
+
+ /* set output to RGB */
+ rgb_mode = 0; /* MODE_RGB_P */
+ cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0);
+ cfg &= ~S5P_VIDCON0_VIDOUT_MASK;
+
+ cfg |= S5P_VIDCON0_VIDOUT_RGB;
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0);
+
+ /* set display mode */
+ cfg = readl(fimd_lite->iomem_base + S5P_VIDCON0);
+ cfg &= ~S5P_VIDCON0_PNRMODE_MASK;
+ cfg |= (rgb_mode << S5P_VIDCON0_PNRMODE_SHIFT);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDCON0);
+
+ s5p_fimd_lite_get_vsync_interrupt(fimd_lite, 0);
+
+ /* set par */
+ s5p_fimd_lite_set_par(fimd_lite, win_id);
+
+ /* set buffer size */
+ cfg = S5P_VIDADDR_PAGEWIDTH(timing.xres * lcd->bpp / 8);
+ writel(cfg, fimd_lite->iomem_base + S5P_VIDADDR_SIZE(win_id));
+
+ /* set clock */
+ s5p_fimd_lite_set_clock(fimd_lite);
+
+ return;
+}
+
+static int s5p_fimd_lite_setup(struct s5p_fimd_ext_device *fx_dev,
+ unsigned int enable)
+{
+ struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev);
+
+ s5p_fimd_lite_logic_start(fimd_lite, enable);
+
+ s5p_fimd_lite_lcd_init(fimd_lite);
+
+
+ s5p_fimd_lite_window_on(fimd_lite, 0, 1);
+
+ return 0;
+}
+
+static int s5p_fimd_lite_start(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev);
+
+ s5p_fimd_lite_lcd_on(fimd_lite, 1);
+
+ return 0;
+}
+
+static void s5p_fimd_lite_stop(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev);
+
+ s5p_fimd_lite_lcd_on(fimd_lite, 0);
+}
+
+static void s5p_fimd_lite_power_on(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev);
+
+ clk_enable(fimd_lite->clk);
+}
+
+static void s5p_fimd_lite_power_off(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct s5p_fimd_lite *fimd_lite = fimd_ext_get_drvdata(fx_dev);
+
+ clk_disable(fimd_lite->clk);
+}
+
+static int s5p_fimd_lite_probe(struct s5p_fimd_ext_device *fx_dev)
+{
+ struct clk *sclk = NULL;
+ struct resource *res;
+ struct s5p_fimd_lite *fimd_lite;
+ int ret = -1;
+
+ fimd_lite = kzalloc(sizeof(struct s5p_fimd_lite), GFP_KERNEL);
+ if (!fimd_lite) {
+ dev_err(&fx_dev->dev, "failed to alloc fimd_lite object.\n");
+ return -EFAULT;
+ }
+
+ fimd_lite->dev = &fx_dev->dev;
+ fimd_lite->lcd = (struct exynos_drm_fimd_pdata *)
+ to_fimd_lite_platform_data(fx_dev);
+
+ res = s5p_fimd_ext_get_resource(fx_dev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&fx_dev->dev, "failed to get io memory region.\n");
+ ret = -EINVAL;
+ goto err0;
+ }
+
+ fimd_lite->iomem_base = ioremap(res->start, resource_size(res));
+ if (!fimd_lite->iomem_base) {
+ dev_err(&fx_dev->dev, "failed to remap io region\n");
+ ret = -EFAULT;
+ goto err0;
+ }
+
+ fimd_lite->clk = clk_get(&fx_dev->dev, "mdnie0");
+ if (IS_ERR(fimd_lite->clk)) {
+ dev_err(&fx_dev->dev, "failed to get FIMD LITE clock source\n");
+ ret = -EINVAL;
+ goto err1;
+ }
+
+ sclk = clk_get(&fx_dev->dev, "sclk_mdnie");
+ if (IS_ERR(sclk)) {
+ dev_err(&fx_dev->dev, "failed to get sclk_mdnie clock\n");
+ ret = -EINVAL;
+ goto err2;
+ }
+ fimd_lite->clk->parent = sclk;
+
+ fimd_lite->irq = s5p_fimd_ext_get_irq(fx_dev, 0);
+
+ /* register interrupt handler for fimd-lite. */
+ if (request_irq(fimd_lite->irq, s5p_fimd_lite_irq_frame, IRQF_DISABLED,
+ fx_dev->name, (void *)fimd_lite)) {
+ dev_err(&fx_dev->dev, "request_irq failed\n");
+ ret = -EINVAL;
+ goto err3;
+ }
+
+ fimd_ext_set_drvdata(fx_dev, fimd_lite);
+
+ dev_info(&fx_dev->dev, "fimd lite driver has been probed.\n");
+
+ return 0;
+
+err3:
+ free_irq(fimd_lite->irq, fx_dev);
+err2:
+ clk_put(sclk);
+err1:
+ iounmap(fimd_lite->iomem_base);
+ clk_put(fimd_lite->clk);
+err0:
+ kfree(fimd_lite);
+
+ return ret;
+
+}
+
+static struct s5p_fimd_ext_driver fimd_ext_driver = {
+ .driver = {
+ .name = "fimd_lite",
+ .owner = THIS_MODULE,
+ },
+ .change_clock = s5p_change_dynamic_refresh,
+ .power_on = s5p_fimd_lite_power_on,
+ .power_off = s5p_fimd_lite_power_off,
+ .setup = s5p_fimd_lite_setup,
+ .start = s5p_fimd_lite_start,
+ .stop = s5p_fimd_lite_stop,
+ .probe = s5p_fimd_lite_probe,
+};
+
+static int __init s5p_fimd_lite_init(void)
+{
+ return s5p_fimd_ext_driver_register(&fimd_ext_driver);
+}
+
+static void __exit s5p_fimd_lite_exit(void)
+{
+}
+
+arch_initcall(s5p_fimd_lite_init);
+module_exit(s5p_fimd_lite_exit);
+
+MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
+MODULE_DESCRIPTION("FIMD Lite Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h
new file mode 100644
index 0000000..a8ef492
--- /dev/null
+++ b/drivers/video/samsung_duallcd/extension/s5p_fimd_lite.h
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s5p/s5p_fimd_lite.h
+ *
+ * FIMD Lite Platform Specific Header Definitions.
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * InKi Dae <inki.dae@samsung.com>
+ *
+ * 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 _S5P_FIMD_LITE_H_
+#define _S5P_FIMD_LITE_H_
+
+#include <drm/exynos_drm.h>
+
+struct s5p_fimd_lite_platform_data {
+ unsigned int reg_base;
+ unsigned int reg_map_size;
+ unsigned int irq;
+};
+
+struct s5p_fimd_lite {
+ struct device *dev;
+ struct clk *clk;
+ void __iomem *iomem_base;
+ unsigned int irq;
+ unsigned int dynamic_refresh;
+
+ struct exynos_drm_fimd_pdata *lcd;
+};
+
+void s5p_fimd_lite_get_vsync_interrupt(struct s5p_fimd_lite *fimd_lite,
+ unsigned int enable);
+
+#endif /* _S5P_FIMD_LITE_H_ */