aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/samsung
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/samsung')
-rw-r--r--drivers/video/samsung/Kconfig47
-rw-r--r--drivers/video/samsung/Makefile4
-rw-r--r--drivers/video/samsung/aid_ea8061.h337
-rw-r--r--drivers/video/samsung/aid_s6e8aa0.h36
-rw-r--r--drivers/video/samsung/aid_s6evr02.h248
-rw-r--r--drivers/video/samsung/ea8061_param.h391
-rw-r--r--drivers/video/samsung/ea8061_volt_tbl.h667
-rw-r--r--drivers/video/samsung/lcdfreq.c105
-rw-r--r--drivers/video/samsung/ld9040.c87
-rw-r--r--drivers/video/samsung/lms501xx.h156
-rw-r--r--drivers/video/samsung/mdnie_table_baffin.h803
-rw-r--r--drivers/video/samsung/mdnie_table_t0.h763
-rw-r--r--drivers/video/samsung/s3cfb.h122
-rw-r--r--drivers/video/samsung/s3cfb_ea8061.c1289
-rw-r--r--drivers/video/samsung/s3cfb_fimd6x.c66
-rw-r--r--drivers/video/samsung/s3cfb_ielcd.c2
-rw-r--r--drivers/video/samsung/s3cfb_lms501xx.c737
-rw-r--r--drivers/video/samsung/s3cfb_main.c293
-rw-r--r--drivers/video/samsung/s3cfb_mdnie.c2
-rw-r--r--drivers/video/samsung/s3cfb_ops.c694
-rw-r--r--drivers/video/samsung/s3cfb_s6c1372.c21
-rw-r--r--drivers/video/samsung/s3cfb_s6e39a0.c223
-rw-r--r--drivers/video/samsung/s3cfb_s6e63m0.c1718
-rw-r--r--drivers/video/samsung/s3cfb_s6e8aa0.c390
-rw-r--r--drivers/video/samsung/s3cfb_s6e8ab0.c177
-rw-r--r--drivers/video/samsung/s3cfb_s6evr02.c1352
-rw-r--r--drivers/video/samsung/s5p-dsim.c176
-rw-r--r--drivers/video/samsung/s5p-dsim.h3
-rw-r--r--drivers/video/samsung/s6d6aa1.c393
-rw-r--r--drivers/video/samsung/s6dr171.c146
-rw-r--r--drivers/video/samsung/s6e63m0_gamma_grande.h229
-rw-r--r--drivers/video/samsung/s6e63m0_gamma_l.h311
-rw-r--r--drivers/video/samsung/s6e63m0_param.h375
-rw-r--r--drivers/video/samsung/s6e8aa0_gamma_q1.h6
-rw-r--r--drivers/video/samsung/s6e8aa0_param.h6
-rw-r--r--drivers/video/samsung/s6e8aa1.c568
-rw-r--r--drivers/video/samsung/s6e8aa1_param.h74
-rw-r--r--drivers/video/samsung/s6evr02_param.h351
-rw-r--r--drivers/video/samsung/s6evr02_volt_tbl.h665
-rw-r--r--drivers/video/samsung/smart_dimming_ea8061.c918
-rw-r--r--drivers/video/samsung/smart_dimming_ea8061.h133
-rw-r--r--drivers/video/samsung/smart_dimming_s6evr02.c948
-rw-r--r--drivers/video/samsung/smart_dimming_s6evr02.h133
43 files changed, 15383 insertions, 782 deletions
diff --git a/drivers/video/samsung/Kconfig b/drivers/video/samsung/Kconfig
index 3cb946f..09711d3 100644
--- a/drivers/video/samsung/Kconfig
+++ b/drivers/video/samsung/Kconfig
@@ -7,11 +7,19 @@ config FB_S5P
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select SYNC
+ select SW_SYNC
+ select SW_SYNC_USER
depends on FB && (ARCH_S5PV210 || ARCH_EXYNOS4) && !FB_S3C
default n
help
This enables support for Samsung Display Controller (FIMD)
+config FB_S5P_SYSMMU
+ bool "S5P FIMD SYSMMU enable"
+ depends on FB_S5P
+ default n
+
config FB_S5P_SPLASH_SCREEN
bool "SPLASH_SCREEN on LCD"
depends on FB_S5P
@@ -26,6 +34,10 @@ config FB_S5P_DEBUG
bool "S5P Framebuffer debug messages"
depends on FB_S5P
+config FB_S5P_VSYNC_THREAD
+ bool "S5P Framebuffer vsync thread"
+ depends on FB_S5P
+
config FB_S5P_TRACE_UNDERRUN
bool "S5P Framebuffer FIFO underrun trace"
depends on FB_S5P
@@ -111,6 +123,21 @@ endif # FIMD_EXT_SUPPORT
choice
depends on FB_S5P
+prompt "Select RGB Order"
+default FB_BGRA_ORDER
+config FB_BGRA_ORDER
+ bool "BGRA8888"
+ help
+ This enables use BGRA order.
+
+config FB_RGBA_ORDER
+ bool "RGBA8888"
+ help
+ This enables use RGBA order.
+endchoice
+
+choice
+depends on FB_S5P
prompt "Select LCD Type"
default FB_S5P_AMS369FG06
config FB_S5P_LTE480WV
@@ -180,6 +207,12 @@ config FB_S5P_LMS501KF03
help
This enables support for Samsung LMS501KF03 5.01" WVGA TFT LCD panel
+config FB_S5P_LMS501XX
+ bool "LMS501XX MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ help
+ This enables support for Samsung LMS501XX 5.01" WVGA TFT LCD panel
+
config FB_S5P_DUMMY_MIPI_LCD
bool "DUMMY MIPI LCD"
depends on FB_S5P_MIPI_DSIM
@@ -192,6 +225,18 @@ config FB_S5P_S6E8AA0
---help---
This enables support for Samsung S6E8AA0 MIPI LCD
+config FB_S5P_EA8061
+ bool "EA8061 MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ ---help---
+ This enables support for Samsung EA8061 MIPI LCD
+
+config FB_S5P_S6EVR02
+ bool "S6EVR02 MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ ---help---
+ This enables support for Samsung S6EVR02 MIPI LCD
+
config FB_S5P_S6E8AB0
bool "S6E8AB0 MIPI LCD"
depends on MACH_PX && FB_S5P_MIPI_DSIM
@@ -199,7 +244,7 @@ config FB_S5P_S6E8AB0
This enables support for Samsung S6E8AB0 MIPI LCD
config FB_S5P_S6D6AA1
- bool "S6E8AB0 MIPI LCD"
+ bool "S6D6AA1 MIPI LCD"
depends on FB_S5P_MIPI_DSIM
---help---
This enables support for Samsung S6D6AA1 MIPI LCD
diff --git a/drivers/video/samsung/Makefile b/drivers/video/samsung/Makefile
index 16ed689..75995be 100644
--- a/drivers/video/samsung/Makefile
+++ b/drivers/video/samsung/Makefile
@@ -17,10 +17,14 @@ obj-$(CONFIG_FB_S5P_LD9040) += ld9040.o smart_dimming_ld9042.o
obj-$(CONFIG_FB_S5P_NT35560) += nt35560.o
obj-$(CONFIG_FB_S5P_MDNIE) += s3cfb_mdnie.o s3cfb_ielcd.o mdnie.o mdnie_tunning.o
obj-$(CONFIG_FB_S5P_LMS501KF03) += s3cfb_lms501kf03.o
+obj-$(CONFIG_FB_S5P_LMS501XX) += s3cfb_lms501xx.o
obj-$(CONFIG_FB_S5P_DUMMY_MIPI_LCD) += s3cfb_dummymipilcd.o
obj-$(CONFIG_FB_S5P_S6E8AA0) += s3cfb_s6e8aa0.o smart_dimming.o
+obj-$(CONFIG_FB_S5P_EA8061) += s3cfb_ea8061.o smart_dimming_ea8061.o
+obj-$(CONFIG_FB_S5P_S6EVR02) += s3cfb_s6evr02.o smart_dimming_s6evr02.o s3cfb_ea8061.o smart_dimming_ea8061.o
obj-$(CONFIG_FB_S5P_S6E8AB0) += s3cfb_s6e8ab0.o smart_dimming_s6e8ab0.o
obj-$(CONFIG_FB_S5P_S6E39A0) += s3cfb_s6e39a0.o smart_dimming.o
+obj-$(CONFIG_FB_S5P_S6E63M0) += s3cfb_s6e63m0.o smart_dimming.o
obj-$(CONFIG_FB_S5P_S6D6AA1) += s6d6aa1.o
obj-$(CONFIG_FB_S5P_MIPI_DSIM) += s5p_dsim_lowlevel.o
obj-$(CONFIG_FB_S5P_MIPI_DSIM) += s5p-dsim.o
diff --git a/drivers/video/samsung/aid_ea8061.h b/drivers/video/samsung/aid_ea8061.h
new file mode 100644
index 0000000..9b92d80
--- /dev/null
+++ b/drivers/video/samsung/aid_ea8061.h
@@ -0,0 +1,337 @@
+#ifndef __AID_EA8061_H__
+#define __AID_EA8061_H__
+
+#include "smart_dimming_ea8061.h"
+
+#define aid_300nit_260nit_B3_1st 0x00
+#define aid_300nit_260nit_B3_2nd 0x0A
+#define aid_250nit_190nit_B3_1st 0x00
+#define aid_250nit_190nit_B3_2nd 0x0A
+#define aid_188nit_186nit_B3_1st 0x00
+#define aid_184nit_182nit_B3_1st 0x01
+#define aid_188nit_B3_2nd 0x68
+#define aid_186nit_B3_2nd 0xCF
+#define aid_184nit_B3_2nd 0x37
+#define aid_182nit_B3_2nd 0x9F
+#define aid_180nit_110nit_B3_1st 0x02
+#define aid_180nit_110nit_B3_2nd 0x06
+#define aid_102nit_B3_1st 0x00
+#define aid_108nit_104nit_B3_1st 0x01
+#define aid_108nit_B3_2nd 0xC4
+#define aid_106nit_B3_2nd 0x82
+#define aid_104nit_B3_2nd 0x40
+#define aid_102nit_B3_2nd 0xFE
+#define aid_100nit_B3_1st 0x00
+#define aid_90nit_80nit_B3_1st 0x01
+#define aid_70nit_60nit_B3_1st 0x02
+#define aid_50nit_30nit_B3_1st 0x03
+#define aid_20nit_B3_1st 0x04
+#define aid_100nit_B3_2nd 0xBC
+#define aid_90nit_B3_2nd 0x36
+#define aid_80nit_B3_2nd 0xAB
+#define aid_70nit_B3_2nd 0x25
+#define aid_60nit_B3_2nd 0x95
+#define aid_50nit_B3_2nd 0x0A
+#define aid_40nit_B3_2nd 0x74
+#define aid_30nit_B3_2nd 0xDF
+#define aid_20nit_B3_2nd 0x45
+#define AOR40_BASE_188 202
+#define AOR40_BASE_186 215
+#define AOR40_BASE_184 230
+#define AOR40_BASE_182 250
+#define AOR40_BASE_180 275
+#define AOR40_BASE_170 260
+#define AOR40_BASE_160 246
+#define AOR40_BASE_150 230
+#define AOR40_BASE_140 217
+#define AOR40_BASE_130 202
+#define AOR40_BASE_120 184
+#define AOR40_BASE_110 169
+#define AOR40_BASE_108 154
+#define AOR40_BASE_106 141
+#define AOR40_BASE_104 130
+#define AOR40_BASE_102 120
+#define base_20to100 110
+
+static const struct rgb_offset_info aid_rgb_fix_table_SM2[] = {
+ {GAMMA_184CD, IV_11, CI_BLUE, 1},
+ {GAMMA_182CD, IV_11, CI_GREEN, -1}, {GAMMA_182CD, IV_11, CI_BLUE, 2},
+ {GAMMA_180CD, IV_11, CI_RED, -1}, {GAMMA_180CD, IV_11, CI_GREEN, -2}, {GAMMA_180CD, IV_11, CI_BLUE, 3},
+ {GAMMA_170CD, IV_11, CI_RED, -1}, {GAMMA_170CD, IV_11, CI_GREEN, -2}, {GAMMA_170CD, IV_11, CI_BLUE, 3},
+ {GAMMA_160CD, IV_11, CI_RED, -1}, {GAMMA_160CD, IV_11, CI_GREEN, -2}, {GAMMA_160CD, IV_11, CI_BLUE, 3},
+ {GAMMA_150CD, IV_11, CI_RED, -1}, {GAMMA_150CD, IV_11, CI_GREEN, -2}, {GAMMA_150CD, IV_11, CI_BLUE, 3},
+ {GAMMA_140CD, IV_11, CI_RED, -1}, {GAMMA_140CD, IV_11, CI_GREEN, -2}, {GAMMA_140CD, IV_11, CI_BLUE, 3},
+ {GAMMA_130CD, IV_11, CI_RED, -1}, {GAMMA_130CD, IV_11, CI_GREEN, -2}, {GAMMA_130CD, IV_11, CI_BLUE, 3},
+ {GAMMA_120CD, IV_11, CI_RED, -1}, {GAMMA_120CD, IV_11, CI_GREEN, -2}, {GAMMA_120CD, IV_11, CI_BLUE, 3},
+ {GAMMA_110CD, IV_11, CI_RED, -1}, {GAMMA_110CD, IV_11, CI_GREEN, -2}, {GAMMA_110CD, IV_11, CI_BLUE, 3},
+ {GAMMA_108CD, IV_11, CI_RED, -1}, {GAMMA_108CD, IV_11, CI_GREEN, -2}, {GAMMA_108CD, IV_11, CI_BLUE, 3},
+ {GAMMA_106CD, IV_11, CI_RED, -1}, {GAMMA_106CD, IV_11, CI_GREEN, -1}, {GAMMA_106CD, IV_11, CI_BLUE, 3},
+ {GAMMA_104CD, IV_11, CI_RED, -2}, {GAMMA_104CD, IV_11, CI_GREEN, -1}, {GAMMA_104CD, IV_11, CI_BLUE, 4},
+ {GAMMA_102CD, IV_11, CI_RED, -2}, {GAMMA_102CD, IV_11, CI_BLUE, 4},
+ {GAMMA_100CD, IV_11, CI_RED, -2}, {GAMMA_100CD, IV_11, CI_BLUE, 5},
+ {GAMMA_90CD, IV_11, CI_RED, -5}, {GAMMA_90CD, IV_11, CI_BLUE, 6},
+ {GAMMA_80CD, IV_11, CI_RED, -6}, {GAMMA_80CD, IV_11, CI_BLUE, 8},
+ {GAMMA_70CD, IV_11, CI_RED, -7}, {GAMMA_70CD, IV_11, CI_BLUE, 11},
+ {GAMMA_60CD, IV_11, CI_RED, -10}, {GAMMA_60CD, IV_11, CI_BLUE, 14},
+ {GAMMA_50CD, IV_11, CI_RED, -12}, {GAMMA_50CD, IV_11, CI_BLUE, 19},
+ {GAMMA_40CD, IV_11, CI_RED, -18}, {GAMMA_40CD, IV_11, CI_BLUE, 24},
+ {GAMMA_30CD, IV_11, CI_RED, -18}, {GAMMA_30CD, IV_11, CI_BLUE, 31},
+ {GAMMA_20CD, IV_11, CI_RED, -18}, {GAMMA_20CD, IV_11, CI_BLUE, 39},
+ {GAMMA_90CD, IV_23, CI_GREEN, -3},
+ {GAMMA_80CD, IV_23, CI_RED, -1}, {GAMMA_80CD, IV_23, CI_GREEN, -4},
+ {GAMMA_70CD, IV_23, CI_RED, -3}, {GAMMA_70CD, IV_23, CI_GREEN, -6},
+ {GAMMA_60CD, IV_23, CI_RED, -4}, {GAMMA_60CD, IV_23, CI_GREEN, -9},
+ {GAMMA_50CD, IV_23, CI_RED, -7}, {GAMMA_50CD, IV_23, CI_GREEN, -9},
+ {GAMMA_40CD, IV_23, CI_RED, -12}, {GAMMA_40CD, IV_23, CI_GREEN, -16},
+ {GAMMA_30CD, IV_23, CI_RED, -17}, {GAMMA_30CD, IV_23, CI_GREEN, -16}, {GAMMA_30CD, IV_23, CI_BLUE, 2},
+ {GAMMA_20CD, IV_23, CI_RED, -22}, {GAMMA_20CD, IV_23, CI_GREEN, -16}, {GAMMA_20CD, IV_23, CI_BLUE, 9},
+ {GAMMA_30CD, IV_35, CI_RED, -3}, {GAMMA_30CD, IV_35, CI_GREEN, -14},
+ {GAMMA_20CD, IV_35, CI_RED, -11}, {GAMMA_20CD, IV_35, CI_GREEN, -30},
+};
+
+static const struct rgb_offset_info aid_rgb_fix_table_M4[] = {
+ {GAMMA_180CD, IV_11, CI_GREEN, 1},
+ {GAMMA_170CD, IV_11, CI_GREEN, 1},
+ {GAMMA_160CD, IV_11, CI_GREEN, 1},
+ {GAMMA_150CD, IV_11, CI_GREEN, 1},
+ {GAMMA_140CD, IV_11, CI_GREEN, 1},
+ {GAMMA_130CD, IV_11, CI_GREEN, 1},
+ {GAMMA_120CD, IV_11, CI_GREEN, 1},
+ {GAMMA_110CD, IV_11, CI_GREEN, 1},
+ {GAMMA_180CD, IV_23, CI_GREEN, 1},
+ {GAMMA_170CD, IV_23, CI_GREEN, 1},
+ {GAMMA_160CD, IV_23, CI_GREEN, 1},
+ {GAMMA_150CD, IV_23, CI_GREEN, 1},
+ {GAMMA_140CD, IV_23, CI_GREEN, 1},
+ {GAMMA_130CD, IV_23, CI_GREEN, 1},
+ {GAMMA_120CD, IV_23, CI_GREEN, 1},
+ {GAMMA_110CD, IV_23, CI_GREEN, 1},
+ {GAMMA_180CD, IV_35, CI_RED, -10}, {GAMMA_180CD, IV_35, CI_GREEN, 2},
+ {GAMMA_170CD, IV_35, CI_RED, -11}, {GAMMA_170CD, IV_35, CI_GREEN, 2},
+ {GAMMA_160CD, IV_35, CI_RED, -12}, {GAMMA_160CD, IV_35, CI_GREEN, 2},
+ {GAMMA_150CD, IV_35, CI_RED, -13}, {GAMMA_150CD, IV_35, CI_GREEN, 2},
+ {GAMMA_140CD, IV_35, CI_RED, -14}, {GAMMA_140CD, IV_35, CI_GREEN, 2},
+ {GAMMA_130CD, IV_35, CI_RED, -15}, {GAMMA_130CD, IV_35, CI_GREEN, 2},
+ {GAMMA_120CD, IV_35, CI_RED, -16}, {GAMMA_120CD, IV_35, CI_GREEN, 2},
+ {GAMMA_110CD, IV_35, CI_RED, -17}, {GAMMA_110CD, IV_35, CI_GREEN, 2},
+ {GAMMA_90CD, IV_11, CI_GREEN, 12}, {GAMMA_90CD, IV_11, CI_BLUE, -7},
+ {GAMMA_80CD, IV_11, CI_GREEN, 20}, {GAMMA_80CD, IV_11, CI_BLUE, 2},
+ {GAMMA_70CD, IV_11, CI_RED, -17}, {GAMMA_70CD, IV_11, CI_GREEN, 20}, {GAMMA_70CD, IV_11, CI_BLUE, 5},
+ {GAMMA_60CD, IV_11, CI_RED, -17}, {GAMMA_60CD, IV_11, CI_GREEN, 29}, {GAMMA_60CD, IV_11, CI_BLUE, 16},
+ {GAMMA_50CD, IV_11, CI_RED, -17}, {GAMMA_50CD, IV_11, CI_GREEN, 39}, {GAMMA_50CD, IV_11, CI_BLUE, 27},
+ {GAMMA_40CD, IV_11, CI_RED, -17}, {GAMMA_40CD, IV_11, CI_GREEN, 49}, {GAMMA_40CD, IV_11, CI_BLUE, 37},
+ {GAMMA_30CD, IV_11, CI_RED, -52}, {GAMMA_30CD, IV_11, CI_GREEN, 60}, {GAMMA_30CD, IV_11, CI_BLUE, 52},
+ {GAMMA_20CD, IV_11, CI_RED, -56}, {GAMMA_20CD, IV_11, CI_GREEN, 76}, {GAMMA_20CD, IV_11, CI_BLUE, 72},
+ {GAMMA_70CD, IV_23, CI_RED, -6}, {GAMMA_70CD, IV_23, CI_GREEN, 3},
+ {GAMMA_60CD, IV_23, CI_RED, -13}, {GAMMA_60CD, IV_23, CI_GREEN, 4},
+ {GAMMA_50CD, IV_23, CI_RED, -20}, {GAMMA_50CD, IV_23, CI_GREEN, 5},
+ {GAMMA_40CD, IV_23, CI_RED, -30}, {GAMMA_40CD, IV_23, CI_GREEN, 6},
+ {GAMMA_30CD, IV_23, CI_RED, -35}, {GAMMA_30CD, IV_23, CI_GREEN, -2},
+ {GAMMA_20CD, IV_23, CI_RED, -46}, {GAMMA_20CD, IV_23, CI_GREEN, -6}, {GAMMA_20CD, IV_23, CI_BLUE, 11},
+ {GAMMA_30CD, IV_35, CI_RED, -23}, {GAMMA_30CD, IV_35, CI_GREEN, 11},
+ {GAMMA_20CD, IV_35, CI_RED, -39}, {GAMMA_20CD, IV_35, CI_GREEN, 26},
+};
+
+static unsigned char aid_command_20[] = {
+ aid_20nit_B3_1st,
+ aid_20nit_B3_2nd,
+};
+
+static unsigned char aid_command_30[] = {
+ aid_50nit_30nit_B3_1st,
+ aid_30nit_B3_2nd,
+};
+
+static unsigned char aid_command_40[] = {
+ aid_50nit_30nit_B3_1st,
+ aid_40nit_B3_2nd,
+};
+
+static unsigned char aid_command_50[] = {
+ aid_50nit_30nit_B3_1st,
+ aid_50nit_B3_2nd,
+};
+
+static unsigned char aid_command_60[] = {
+ aid_70nit_60nit_B3_1st,
+ aid_60nit_B3_2nd,
+};
+
+static unsigned char aid_command_70[] = {
+ aid_70nit_60nit_B3_1st,
+ aid_70nit_B3_2nd,
+};
+
+static unsigned char aid_command_80[] = {
+ aid_90nit_80nit_B3_1st,
+ aid_80nit_B3_2nd,
+};
+
+static unsigned char aid_command_90[] = {
+ aid_90nit_80nit_B3_1st,
+ aid_90nit_B3_2nd,
+};
+
+static unsigned char aid_command_100[] = {
+ aid_100nit_B3_1st,
+ aid_100nit_B3_2nd,
+};
+
+static unsigned char aid_command_102[] = {
+ aid_102nit_B3_1st,
+ aid_102nit_B3_2nd,
+};
+
+static unsigned char aid_command_104[] = {
+ aid_108nit_104nit_B3_1st,
+ aid_104nit_B3_2nd,
+};
+
+static unsigned char aid_command_106[] = {
+ aid_108nit_104nit_B3_1st,
+ aid_106nit_B3_2nd,
+};
+
+static unsigned char aid_command_108[] = {
+ aid_108nit_104nit_B3_1st,
+ aid_108nit_B3_2nd,
+};
+
+static unsigned char aid_command_110[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_120[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_130[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_140[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_150[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_160[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_170[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_180[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_182[] = {
+ aid_184nit_182nit_B3_1st,
+ aid_182nit_B3_2nd,
+};
+
+static unsigned char aid_command_184[] = {
+ aid_184nit_182nit_B3_1st,
+ aid_184nit_B3_2nd,
+};
+
+static unsigned char aid_command_186[] = {
+ aid_188nit_186nit_B3_1st,
+ aid_186nit_B3_2nd,
+};
+
+static unsigned char aid_command_188[] = {
+ aid_188nit_186nit_B3_1st,
+ aid_188nit_B3_2nd,
+};
+
+static unsigned char aid_command_190[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_200[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_210[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_220[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_230[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_240[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_250[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_300[] = {
+ aid_300nit_260nit_B3_1st,
+ aid_300nit_260nit_B3_2nd,
+
+};
+
+static unsigned char *aid_command_table[GAMMA_MAX] = {
+ aid_command_20,
+ aid_command_30,
+ aid_command_40,
+ aid_command_50,
+ aid_command_60,
+ aid_command_70,
+ aid_command_80,
+ aid_command_90,
+ aid_command_100,
+ aid_command_102,
+ aid_command_104,
+ aid_command_106,
+ aid_command_108,
+ aid_command_110,
+ aid_command_120,
+ aid_command_130,
+ aid_command_140,
+ aid_command_150,
+ aid_command_160,
+ aid_command_170,
+ aid_command_180,
+ aid_command_182,
+ aid_command_184,
+ aid_command_186,
+ aid_command_188,
+ aid_command_190,
+ aid_command_200,
+ aid_command_210,
+ aid_command_220,
+ aid_command_230,
+ aid_command_240,
+ aid_command_250,
+ aid_command_300
+};
+
+#endif
diff --git a/drivers/video/samsung/aid_s6e8aa0.h b/drivers/video/samsung/aid_s6e8aa0.h
index cf8058a..c06eaf8 100644
--- a/drivers/video/samsung/aid_s6e8aa0.h
+++ b/drivers/video/samsung/aid_s6e8aa0.h
@@ -15,6 +15,10 @@
#define aid_180nit_110nit_F8_18th 0x42
#define aid_180nit_110nit_F8_1st 0x59
#define aid_100nit_20nit_F8_1st 0x59
+#define aid_108nit_F8_18th 0x38
+#define aid_106nit_F8_18th 0x2F
+#define aid_104nit_F8_18th 0x25
+#define aid_102nit_F8_18th 0x1C
#define aid_100nit_F8_18th 0x12
#define aid_90nit_F8_18th 0x22
#define aid_80nit_F8_18th 0x32
@@ -36,6 +40,10 @@
#define AOR40_BASE_130 200
#define AOR40_BASE_120 186
#define AOR40_BASE_110 171
+#define AOR40_BASE_108 156
+#define AOR40_BASE_106 143
+#define AOR40_BASE_104 130
+#define AOR40_BASE_102 120
#define base_20to100 110
const struct rgb_offset_info aid_rgb_fix_table[] = {
@@ -47,6 +55,10 @@ const struct rgb_offset_info aid_rgb_fix_table[] = {
{GAMMA_130CD, IV_15, CI_RED, 1}, {GAMMA_130CD, IV_15, CI_GREEN, -1}, {GAMMA_130CD, IV_15, CI_BLUE, 5},
{GAMMA_120CD, IV_15, CI_RED, 1}, {GAMMA_120CD, IV_15, CI_GREEN, -1}, {GAMMA_120CD, IV_15, CI_BLUE, 5},
{GAMMA_110CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_108CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_106CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_104CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_102CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
{GAMMA_100CD, IV_15, CI_RED, -2}, {GAMMA_100CD, IV_15, CI_GREEN, -3},
{GAMMA_90CD, IV_15, CI_RED, -6}, {GAMMA_90CD, IV_15, CI_GREEN, -7},
{GAMMA_80CD, IV_15, CI_RED, -10}, {GAMMA_80CD, IV_15, CI_GREEN, -12},
@@ -104,6 +116,26 @@ static unsigned char aid_command_100[] = {
aid_100nit_20nit_F8_1st,
};
+static unsigned char aid_command_102[] = {
+ aid_102nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
+static unsigned char aid_command_104[] = {
+ aid_104nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
+static unsigned char aid_command_106[] = {
+ aid_106nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
+static unsigned char aid_command_108[] = {
+ aid_108nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
static unsigned char aid_command_110[] = {
aid_180nit_110nit_F8_18th,
aid_180nit_110nit_F8_1st,
@@ -214,6 +246,10 @@ static unsigned char *aid_command_table[GAMMA_MAX] = {
aid_command_80,
aid_command_90,
aid_command_100,
+ aid_command_102,
+ aid_command_104,
+ aid_command_106,
+ aid_command_108,
aid_command_110,
aid_command_120,
aid_command_130,
diff --git a/drivers/video/samsung/aid_s6evr02.h b/drivers/video/samsung/aid_s6evr02.h
new file mode 100644
index 0000000..2adf731
--- /dev/null
+++ b/drivers/video/samsung/aid_s6evr02.h
@@ -0,0 +1,248 @@
+#ifndef __AID_S6EVR02_H__
+#define __AID_S6EVR02_H__
+
+#include "smart_dimming_s6evr02.h"
+
+#define aid_300nit 0xFF
+#define aid_190nit_250nit 0xFF
+#define aid_188nit 0xEA
+#define aid_186nit 0xD6
+#define aid_184nit 0xC2
+#define aid_182nit 0xAD
+#define aid_110nit_180nit 0x99
+#define aid_108nit 0xF6
+#define aid_106nit 0xEF
+#define aid_104nit 0xE8
+#define aid_102nit 0xE1
+#define aid_100nit 0xDA
+#define aid_90nit 0xC2
+#define aid_80nit 0xAB
+#define aid_70nit 0x93
+#define aid_60nit 0x7D
+#define aid_50nit 0x66
+#define aid_40nit 0x51
+#define aid_30nit 0x3C
+#define aid_20nit 0x28
+#define AOR40_BASE_188 202
+#define AOR40_BASE_186 215
+#define AOR40_BASE_184 230
+#define AOR40_BASE_182 250
+#define AOR40_BASE_180 275
+#define AOR40_BASE_170 260
+#define AOR40_BASE_160 246
+#define AOR40_BASE_150 231
+#define AOR40_BASE_140 217
+#define AOR40_BASE_130 202
+#define AOR40_BASE_120 188
+#define AOR40_BASE_110 169
+#define AOR40_BASE_108 110
+#define AOR40_BASE_106 110
+#define AOR40_BASE_104 110
+#define AOR40_BASE_102 110
+#define base_20to100 110
+
+static const struct rgb_offset_info aid_rgb_fix_table[] = {
+ {GAMMA_184CD, IV_11, CI_BLUE, 1},
+ {GAMMA_182CD, IV_11, CI_GREEN, -1}, {GAMMA_182CD, IV_11, CI_BLUE, 2},
+ {GAMMA_180CD, IV_11, CI_RED, -1}, {GAMMA_180CD, IV_11, CI_GREEN, -2}, {GAMMA_180CD, IV_11, CI_BLUE, 3},
+ {GAMMA_170CD, IV_11, CI_RED, -1}, {GAMMA_170CD, IV_11, CI_GREEN, -2}, {GAMMA_170CD, IV_11, CI_BLUE, 3},
+ {GAMMA_160CD, IV_11, CI_RED, -1}, {GAMMA_160CD, IV_11, CI_GREEN, -2}, {GAMMA_160CD, IV_11, CI_BLUE, 3},
+ {GAMMA_150CD, IV_11, CI_RED, -1}, {GAMMA_150CD, IV_11, CI_GREEN, -2}, {GAMMA_150CD, IV_11, CI_BLUE, 3},
+ {GAMMA_140CD, IV_11, CI_RED, -1}, {GAMMA_140CD, IV_11, CI_GREEN, -2}, {GAMMA_140CD, IV_11, CI_BLUE, 3},
+ {GAMMA_130CD, IV_11, CI_RED, -1}, {GAMMA_130CD, IV_11, CI_GREEN, -2}, {GAMMA_130CD, IV_11, CI_BLUE, 3},
+ {GAMMA_120CD, IV_11, CI_RED, -1}, {GAMMA_120CD, IV_11, CI_GREEN, -2}, {GAMMA_120CD, IV_11, CI_BLUE, 3},
+ {GAMMA_110CD, IV_11, CI_RED, -1}, {GAMMA_110CD, IV_11, CI_GREEN, -2}, {GAMMA_110CD, IV_11, CI_BLUE, 3},
+ {GAMMA_108CD, IV_11, CI_RED, -1}, {GAMMA_108CD, IV_11, CI_GREEN, -2}, {GAMMA_104CD, IV_11, CI_BLUE, 3},
+ {GAMMA_106CD, IV_11, CI_RED, -1}, {GAMMA_106CD, IV_11, CI_GREEN, -1}, {GAMMA_104CD, IV_11, CI_BLUE, 3},
+ {GAMMA_104CD, IV_11, CI_RED, -2}, {GAMMA_104CD, IV_11, CI_GREEN, -1}, {GAMMA_104CD, IV_11, CI_BLUE, 4},
+ {GAMMA_102CD, IV_11, CI_RED, -2}, {GAMMA_102CD, IV_11, CI_BLUE, 4},
+ {GAMMA_100CD, IV_11, CI_RED, -2}, {GAMMA_100CD, IV_11, CI_BLUE, 5},
+ {GAMMA_90CD, IV_11, CI_RED, -5}, {GAMMA_90CD, IV_11, CI_BLUE, 6},
+ {GAMMA_80CD, IV_11, CI_RED, -6}, {GAMMA_80CD, IV_11, CI_BLUE, 8},
+ {GAMMA_70CD, IV_11, CI_RED, -7}, {GAMMA_70CD, IV_11, CI_BLUE, 11},
+ {GAMMA_60CD, IV_11, CI_RED, -10}, {GAMMA_60CD, IV_11, CI_BLUE, 14},
+ {GAMMA_50CD, IV_11, CI_RED, -12}, {GAMMA_50CD, IV_11, CI_BLUE, 19},
+ {GAMMA_40CD, IV_11, CI_RED, -18}, {GAMMA_40CD, IV_11, CI_BLUE, 24},
+ {GAMMA_30CD, IV_11, CI_RED, -18}, {GAMMA_30CD, IV_11, CI_BLUE, 31},
+ {GAMMA_20CD, IV_11, CI_RED, -18}, {GAMMA_20CD, IV_11, CI_BLUE, 39},
+ {GAMMA_90CD, IV_23, CI_GREEN, -3},
+ {GAMMA_80CD, IV_23, CI_RED, -1}, {GAMMA_80CD, IV_23, CI_GREEN, -4},
+ {GAMMA_70CD, IV_23, CI_RED, -3}, {GAMMA_70CD, IV_23, CI_GREEN, -6},
+ {GAMMA_60CD, IV_23, CI_RED, -4}, {GAMMA_60CD, IV_23, CI_GREEN, -9},
+ {GAMMA_50CD, IV_23, CI_RED, -7}, {GAMMA_50CD, IV_23, CI_GREEN, -9},
+ {GAMMA_40CD, IV_23, CI_RED, -12}, {GAMMA_40CD, IV_23, CI_GREEN, -16},
+ {GAMMA_30CD, IV_23, CI_RED, -17}, {GAMMA_30CD, IV_23, CI_GREEN, -16}, {GAMMA_30CD, IV_23, CI_BLUE, 2},
+ {GAMMA_20CD, IV_23, CI_RED, -22}, {GAMMA_20CD, IV_23, CI_GREEN, -16}, {GAMMA_20CD, IV_23, CI_BLUE, 9},
+ {GAMMA_30CD, IV_35, CI_RED, -3}, {GAMMA_30CD, IV_35, CI_GREEN, -14},
+ {GAMMA_20CD, IV_35, CI_RED, -11}, {GAMMA_20CD, IV_35, CI_GREEN, -30},
+};
+
+static unsigned char aid_command_20[] = {
+ aid_20nit
+};
+
+static unsigned char aid_command_30[] = {
+ aid_30nit
+};
+
+static unsigned char aid_command_40[] = {
+ aid_40nit
+};
+
+static unsigned char aid_command_50[] = {
+ aid_50nit
+};
+
+static unsigned char aid_command_60[] = {
+ aid_60nit
+};
+
+static unsigned char aid_command_70[] = {
+ aid_70nit
+};
+
+static unsigned char aid_command_80[] = {
+ aid_80nit
+};
+
+static unsigned char aid_command_90[] = {
+ aid_90nit
+};
+
+static unsigned char aid_command_100[] = {
+ aid_100nit
+};
+
+static unsigned char aid_command_102[] = {
+ aid_102nit
+};
+
+static unsigned char aid_command_104[] = {
+ aid_104nit
+};
+
+static unsigned char aid_command_106[] = {
+ aid_106nit
+};
+
+static unsigned char aid_command_108[] = {
+ aid_108nit
+};
+
+static unsigned char aid_command_110[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_120[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_130[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_140[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_150[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_160[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_170[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_180[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_182[] = {
+ aid_182nit
+};
+
+static unsigned char aid_command_184[] = {
+ aid_184nit
+};
+
+static unsigned char aid_command_186[] = {
+ aid_186nit
+};
+
+static unsigned char aid_command_188[] = {
+ aid_188nit
+};
+
+static unsigned char aid_command_190[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_200[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_210[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_220[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_230[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_240[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_250[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_300[] = {
+ aid_300nit
+};
+
+static unsigned char *aid_command_table[GAMMA_MAX] = {
+ aid_command_20,
+ aid_command_30,
+ aid_command_40,
+ aid_command_50,
+ aid_command_60,
+ aid_command_70,
+ aid_command_80,
+ aid_command_90,
+ aid_command_100,
+ aid_command_102,
+ aid_command_104,
+ aid_command_106,
+ aid_command_108,
+ aid_command_110,
+ aid_command_120,
+ aid_command_130,
+ aid_command_140,
+ aid_command_150,
+ aid_command_160,
+ aid_command_170,
+ aid_command_180,
+ aid_command_182,
+ aid_command_184,
+ aid_command_186,
+ aid_command_188,
+ aid_command_190,
+ aid_command_200,
+ aid_command_210,
+ aid_command_220,
+ aid_command_230,
+ aid_command_240,
+ aid_command_250,
+ aid_command_300
+};
+
+#endif
diff --git a/drivers/video/samsung/ea8061_param.h b/drivers/video/samsung/ea8061_param.h
new file mode 100644
index 0000000..e40a3d9
--- /dev/null
+++ b/drivers/video/samsung/ea8061_param.h
@@ -0,0 +1,391 @@
+#ifndef __EA8061_PARAM_H__
+#define __EA8061_PARAM_H__
+
+#define GAMMA_PARAM_SIZE 34
+#define ACL_PARAM_SIZE ARRAY_SIZE(acl_cutoff_33)
+#define ELVSS_PARAM_SIZE ARRAY_SIZE(elvss_control_set_20)
+#define AID_PARAM_SIZE ARRAY_SIZE(SEQ_LTPS_AID)
+
+enum {
+ GAMMA_20CD,
+ GAMMA_30CD,
+ GAMMA_40CD,
+ GAMMA_50CD,
+ GAMMA_60CD,
+ GAMMA_70CD,
+ GAMMA_80CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_102CD,
+ GAMMA_104CD,
+ GAMMA_106CD,
+ GAMMA_108CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+ GAMMA_182CD,
+ GAMMA_184CD,
+ GAMMA_186CD,
+ GAMMA_188CD,
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_300CD,
+ GAMMA_MAX
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY_ENABLE[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY_DISABLE[] = {
+ 0xF0,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_3_KEY[] = {
+ 0xFC,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_FRAME_GAMMA_UPDATE_KEY[] = {
+ 0xF7,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_FRAME_GAMMA_UPDATE_KEY2[] = {
+ 0xF7,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_SLEEP_IN[] = {
+ 0x10,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET[] = {
+ 0xC4,
+ 0x4E, 0xBD, 0x00, 0x00, 0x58, 0xA7, 0x0B, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0B, 0x92, 0x0B, 0x92, 0x08, 0x08, 0x07,
+ 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04,
+ 0x04,
+};
+
+static const unsigned char SEQ_M4_PANEL_CONDITION_SET[] = {
+ 0xC4,
+ 0x4E, 0xBD, 0x00, 0x00, 0x58, 0xA7, 0x0B, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0B, 0x92, 0x0B, 0x92, 0x08, 0x08, 0x07,
+ 0x30, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04,
+ 0x04,
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xCA,
+ 0x00, 0xE8, 0x00, 0xF7, 0x01, 0x03, 0xDB, 0xDB, 0xDC, 0xD9,
+ 0xD8, 0xDA, 0xCB, 0xC8, 0xCB, 0xD4, 0xD3, 0xD7, 0xE6, 0xE6,
+ 0xEA, 0xE2, 0xE4, 0xE5, 0xCE, 0xC3, 0xCF, 0xB9, 0x9D, 0xDE,
+ 0x11, 0x00
+};
+
+static const unsigned char SEQ_M4_GAMMA_CONDITION_SET[] = {
+ 0xCA,
+ 0x00, 0xB6, 0x00, 0xB7, 0x00, 0xD5, 0xD7, 0xDA, 0xDC, 0xD3,
+ 0xD6, 0xD8, 0xBC, 0xC0, 0xC3, 0xBF, 0xC5, 0xCC, 0xD0, 0xD5,
+ 0xE0, 0xC8, 0xD1, 0xD8, 0x96, 0xAF, 0xB9, 0x82, 0xB6, 0xC2,
+ 0x11, 0x00,
+};
+
+static const unsigned char SEQ_LTPS_AID[] = {
+ 0xB3,
+ 0x00, 0x0A,
+};
+
+static const unsigned char ELVSS_CONTROL_SET[] = {
+ 0xB2, 0x0E,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_CONDITION_SET[] = {
+ 0x36,
+ 0x02, 0x00
+};
+
+static const unsigned char SEQ_ETC_WCABC_CONTROL[] = {
+ 0x55,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV00[] = {
+ 0xB4,
+ 0x33, 0x0E, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV01[] = {
+ 0xB4,
+ 0x33, 0x0E, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV02[] = {
+ 0xB4,
+ 0x33, 0x09, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV03[] = {
+ 0xB4,
+ 0x33, 0x0D, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV04[] = {
+ 0xB4,
+ 0x33, 0x0A, 0x00
+};
+
+static const unsigned char SEQ_M4_SLEW[] = {
+ 0xB4,
+ 0x33, 0x0D, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+enum {
+ ELVSS_STATUS_20,
+ ELVSS_STATUS_30,
+ ELVSS_STATUS_40,
+ ELVSS_STATUS_50,
+ ELVSS_STATUS_60,
+ ELVSS_STATUS_70,
+ ELVSS_STATUS_80,
+ ELVSS_STATUS_90,
+ ELVSS_STATUS_100,
+ ELVSS_STATUS_110,
+ ELVSS_STATUS_120,
+ ELVSS_STATUS_130,
+ ELVSS_STATUS_140,
+ ELVSS_STATUS_150,
+ ELVSS_STATUS_160,
+ ELVSS_STATUS_170,
+ ELVSS_STATUS_180,
+ ELVSS_STATUS_190,
+ ELVSS_STATUS_200,
+ ELVSS_STATUS_210,
+ ELVSS_STATUS_220,
+ ELVSS_STATUS_230,
+ ELVSS_STATUS_240,
+ ELVSS_STATUS_250,
+ ELVSS_STATUS_300,
+ ELVSS_STATUS_MAX
+};
+
+static const unsigned char elvss_control_set_20[] = {
+ 0xB2, 0x20,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_30[] = {
+ 0xB2, 0x20,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_40[] = {
+ 0xB2, 0x20,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_50[] = {
+ 0xB2, 0x1F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_60[] = {
+ 0xB2, 0x1F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_70[] = {
+ 0xB2, 0x1F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_80[] = {
+ 0xB2, 0x1E,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_90[] = {
+ 0xB2, 0x1E,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_100[] = {
+ 0xB2, 0x1C,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_110[] = {
+ 0xB2, 0x1B,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_120[] = {
+ 0xB2, 0x19,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_130[] = {
+ 0xB2, 0x17,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_140[] = {
+ 0xB2, 0x16,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_150[] = {
+ 0xB2, 0x14,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_160[] = {
+ 0xB2, 0x12,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_170[] = {
+ 0xB2, 0x10,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_180[] = {
+ 0xB2, 0x0F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_190[] = {
+ 0xB2, 0x15,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_200[] = {
+ 0xB2, 0x14,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_210[] = {
+ 0xB2, 0x13,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_220[] = {
+ 0xB2, 0x12,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_230[] = {
+ 0xB2, 0x11,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_240[] = {
+ 0xB2, 0x10,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_250[] = {
+ 0xB2, 0x10,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_300[] = {
+ 0xB2, 0x0B,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+
+const unsigned char *ELVSS_CONTROL_TABLE[ELVSS_STATUS_MAX] = {
+ elvss_control_set_20,
+ elvss_control_set_30,
+ elvss_control_set_40,
+ elvss_control_set_50,
+ elvss_control_set_60,
+ elvss_control_set_70,
+ elvss_control_set_80,
+ elvss_control_set_90,
+ elvss_control_set_100,
+ elvss_control_set_110,
+ elvss_control_set_120,
+ elvss_control_set_130,
+ elvss_control_set_140,
+ elvss_control_set_150,
+ elvss_control_set_160,
+ elvss_control_set_170,
+ elvss_control_set_180,
+ elvss_control_set_190,
+ elvss_control_set_200,
+ elvss_control_set_210,
+ elvss_control_set_220,
+ elvss_control_set_230,
+ elvss_control_set_240,
+ elvss_control_set_250,
+ elvss_control_set_300
+};
+
+
+enum {
+ ACL_STATUS_0P = 0,
+ ACL_STATUS_33P,
+ ACL_STATUS_40P,
+ ACL_STATUS_50P,
+ ACL_STATUS_MAX
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0x55, 0x00,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_33[] = {
+ 0x55, 0x01,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_40[] = {
+ 0x55, 0x02,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_50[] = {
+ 0x55, 0x03,
+ 0x00
+};
+
+static const unsigned char *ACL_CUTOFF_TABLE[ACL_STATUS_MAX] = {
+ SEQ_ACL_OFF,
+ acl_cutoff_33,
+ acl_cutoff_40,
+ acl_cutoff_50,
+};
+#endif /* __EA8061_PARAM_H__ */
diff --git a/drivers/video/samsung/ea8061_volt_tbl.h b/drivers/video/samsung/ea8061_volt_tbl.h
new file mode 100644
index 0000000..990e80e
--- /dev/null
+++ b/drivers/video/samsung/ea8061_volt_tbl.h
@@ -0,0 +1,667 @@
+#ifndef __REF_VOLT_TABLE_H__
+#define __REF_VOLT_TABLE_H__
+
+
+static u32 volt_table_vt[16] = {
+ 399769600, 391840286, 383910971, 375981657,
+ 368052342, 360123028, 352193714, 344264399,
+ 336335085, 328405771, 308582485, 301974723,
+ 295366961, 288759199, 282151437, 276865227,
+};
+
+static u32 volt_table_v255[505] = {
+ 369373895, 368713119, 368052342, 367391566, 366730790, 366070014, 365409238, 364748461,
+ 364087685, 363426909, 362766133, 362105357, 361444580, 360783804, 360123028, 359462252,
+ 358801476, 358140700, 357479923, 356819147, 356158371, 355497595, 354836819, 354176042,
+ 353515266, 352854490, 352193714, 351532938, 350872161, 350211385, 349550609, 348889833,
+ 348229057, 347568280, 346907504, 346246728, 345585952, 344925176, 344264399, 343603623,
+ 342942847, 342282071, 341621295, 340960518, 340299742, 339638966, 338978190, 338317414,
+ 337656637, 336995861, 336335085, 335674309, 335013533, 334352756, 333691980, 333031204,
+ 332370428, 331709652, 331048875, 330388099, 329727323, 329066547, 328405771, 327744994,
+ 327084218, 326423442, 325762666, 325101890, 324441113, 323780337, 323119561, 322458785,
+ 321798009, 321137232, 320476456, 319815680, 319154904, 318494128, 317833351, 317172575,
+ 316511799, 315851023, 315190247, 314529470, 313868694, 313207918, 312547142, 311886366,
+ 311225589, 310564813, 309904037, 309243261, 308582485, 307921708, 307260932, 306600156,
+ 305939380, 305278604, 304617827, 303957051, 303296275, 302635499, 301974723, 301313946,
+ 300653170, 299992394, 299331618, 298670842, 298010065, 297349289, 296688513, 296027737,
+ 295366961, 294706184, 294045408, 293384632, 292723856, 292063080, 291402303, 290741527,
+ 290080751, 289419975, 288759199, 288098422, 287437646, 286776870, 286116094, 285455318,
+ 284794541, 284133765, 283472989, 282812213, 282151437, 281490660, 280829884, 280169108,
+ 279508332, 278847556, 278186780, 277526003, 276865227, 276204451, 275543675, 274882899,
+ 274222122, 273561346, 272900570, 272239794, 271579018, 270918241, 270257465, 269596689,
+ 268935913, 268275137, 267614360, 266953584, 266292808, 265632032, 264971256, 264310479,
+ 263649703, 262988927, 262328151, 261667375, 261006598, 260345822, 259685046, 259024270,
+ 258363494, 257702717, 257041941, 256381165, 255720389, 255059613, 254398836, 253738060,
+ 253077284, 252416508, 251755732, 251094955, 250434179, 249773403, 249112627, 248451851,
+ 247791074, 247130298, 246469522, 245808746, 245147970, 244487193, 243826417, 243165641,
+ 242504865, 241844089, 241183312, 240522536, 239861760, 239200984, 238540208, 237879431,
+ 237218655, 236557879, 235897103, 235236327, 234575550, 233914774, 233253998, 232593222,
+ 231932446, 231271669, 230610893, 229950117, 229289341, 228628565, 227967788, 227307012,
+ 226646236, 225985460, 225324684, 224663907, 224003131, 223342355, 222681579, 222020803,
+ 221360026, 220699250, 220038474, 219377698, 218716922, 218056145, 217395369, 216734593,
+ 216073817, 215413041, 214752264, 214091488, 213430712, 212769936, 212109160, 211448383,
+ 210787607, 210126831, 209466055, 208805279, 208144502, 207483726, 206822950, 206162174,
+ 205501398, 204840621, 204179845, 203519069, 202858293, 202197517, 201536740, 200875964,
+ 200215188, 199554412, 198893636, 198232860, 197572083, 196911307, 196250531, 195589755,
+ 194928979, 194268202, 193607426, 192946650, 192285874, 191625098, 190964321, 190303545,
+ 189642769, 188981993, 188321217, 187660440, 186999664, 186338888, 185678112, 185017336,
+ 184356559, 183695783, 183035007, 182374231, 181713455, 181052678, 180391902, 179731126,
+ 179070350, 178409574, 177748797, 177088021, 176427245, 175766469, 175105693, 174444916,
+ 173784140, 173123364, 172462588, 171801812, 171141035, 170480259, 169819483, 169158707,
+ 168497931, 167837154, 167176378, 166515602, 165854826, 165194050, 164533273, 163872497,
+ 163211721, 162550945, 161890169, 161229392, 160568616, 159907840, 159247064, 158586288,
+ 157925511, 157264735, 156603959, 155943183, 155282407, 154621630, 153960854, 153300078,
+ 152639302, 151978526, 151317749, 150656973, 149996197, 149335421, 148674645, 148013868,
+ 147353092, 146692316, 146031540, 145370764, 144709987, 144049211, 143388435, 142727659,
+ 142066883, 141406106, 140745330, 140084554, 139423778, 138763002, 138102225, 137441449,
+ 136780673, 136119897, 135459121, 134798344, 134137568, 133476792, 132816016, 132155240,
+ 131494463, 130833687, 130172911, 129512135, 128851359, 128190582, 127529806, 126869030,
+ 126208254, 125547478, 124886701, 124225925, 123565149, 122904373, 122243597, 121582820,
+ 120922044, 120261268, 119600492, 118939716, 118278940, 117618163, 116957387, 116296611,
+ 115635835, 114975059, 114314282, 113653506, 112992730, 112331954, 111671178, 111010401,
+ 110349625, 109688849, 109028073, 108367297, 107706520, 107045744, 106384968, 105724192,
+ 105063416, 104402639, 103741863, 103081087, 102420311, 101759535, 101098758, 100437982,
+ 99777206, 99116430, 98455654, 97794877, 97134101, 96473325, 95812549, 95151773,
+ 94490996, 93830220, 93169444, 92508668, 91847892, 91187115, 90526339, 89865563,
+ 89204787, 88544011, 87883234, 87222458, 86561682, 85900906, 85240130, 84579353,
+ 83918577, 83257801, 82597025, 81936249, 81275472, 80614696, 79953920, 79293144,
+ 78632368, 77971591, 77310815, 76650039, 75989263, 75328487, 74667710, 74006934,
+ 73346158, 72685382, 72024606, 71363829, 70703053, 70042277, 69381501, 68720725,
+ 68059948, 67399172, 66738396, 66077620, 65416844, 64756067, 64095291, 63434515,
+ 62773739, 62112963, 61452186, 60791410, 60130634, 59469858, 58809082, 58148305,
+ 57487529, 56826753, 56165977, 55505201, 54844424, 54183648, 53522872, 52862096,
+ 52201320, 51540543, 50879767, 50218991, 49558215, 48897439, 48236662, 47575886,
+ 46915110, 46254334, 45593558, 44932781, 44272005, 43611229, 42950453, 42289677,
+ 41628900, 40968124, 40307348, 39646572, 38985796, 38325020, 37664243, 37003467,
+ 36342691
+};
+
+static u32 volt_table_cv_64_dv_320[256] = {
+ 13107, 13312, 13516, 13721, 13926, 14131, 14336, 14540,
+ 14745, 14950, 15155, 15360, 15564, 15769, 15974, 16179,
+ 16384, 16588, 16793, 16998, 17203, 17408, 17612, 17817,
+ 18022, 18227, 18432, 18636, 18841, 19046, 19251, 19456,
+ 19660, 19865, 20070, 20275, 20480, 20684, 20889, 21094,
+ 21299, 21504, 21708, 21913, 22118, 22323, 22528, 22732,
+ 22937, 23142, 23347, 23552, 23756, 23961, 24166, 24371,
+ 24576, 24780, 24985, 25190, 25395, 25600, 25804, 26009,
+ 26214, 26419, 26624, 26828, 27033, 27238, 27443, 27648,
+ 27852, 28057, 28262, 28467, 28672, 28876, 29081, 29286,
+ 29491, 29696, 29900, 30105, 30310, 30515, 30720, 30924,
+ 31129, 31334, 31539, 31744, 31948, 32153, 32358, 32563,
+ 32768, 32972, 33177, 33382, 33587, 33792, 33996, 34201,
+ 34406, 34611, 34816, 35020, 35225, 35430, 35635, 35840,
+ 36044, 36249, 36454, 36659, 36864, 37068, 37273, 37478,
+ 37683, 37888, 38092, 38297, 38502, 38707, 38912, 39116,
+ 39321, 39526, 39731, 39936, 40140, 40345, 40550, 40755,
+ 40960, 41164, 41369, 41574, 41779, 41984, 42188, 42393,
+ 42598, 42803, 43008, 43212, 43417, 43622, 43827, 44032,
+ 44236, 44441, 44646, 44851, 45056, 45260, 45465, 45670,
+ 45875, 46080, 46284, 46489, 46694, 46899, 47104, 47308,
+ 47513, 47718, 47923, 48128, 48332, 48537, 48742, 48947,
+ 49152, 49356, 49561, 49766, 49971, 50176, 50380, 50585,
+ 50790, 50995, 51200, 51404, 51609, 51814, 52019, 52224,
+ 52428, 52633, 52838, 53043, 53248, 53452, 53657, 53862,
+ 54067, 54272, 54476, 54681, 54886, 55091, 55296, 55500,
+ 55705, 55910, 56115, 56320, 56524, 56729, 56934, 57139,
+ 57344, 57548, 57753, 57958, 58163, 58368, 58572, 58777,
+ 58982, 59187, 59392, 59596, 59801, 60006, 60211, 60416,
+ 60620, 60825, 61030, 61235, 61440, 61644, 61849, 62054,
+ 62259, 62464, 62668, 62873, 63078, 63283, 63488, 63692,
+ 63897, 64102, 64307, 64512, 64716, 64921, 65126, 65331,
+};
+
+static const u32 gamma_300_gra_table[256] = {
+ 0, 2, 7, 17, 32, 53, 78, 110,
+ 148, 191, 241, 298, 361, 430, 506, 589,
+ 679, 776, 880, 991, 1109, 1235, 1368, 1508,
+ 1657, 1812, 1975, 2147, 2325, 2512, 2706, 2909,
+ 3119, 3338, 3564, 3799, 4042, 4293, 4553, 4820,
+ 5096, 5381, 5674, 5975, 6285, 6604, 6931, 7267,
+ 7611, 7965, 8327, 8697, 9077, 9465, 9863, 10269,
+ 10684, 11109, 11542, 11984, 12436, 12896, 13366, 13845,
+ 14333, 14830, 15337, 15852, 16378, 16912, 17456, 18009,
+ 18572, 19144, 19726, 20317, 20918, 21528, 22148, 22778,
+ 23417, 24066, 24724, 25392, 26070, 26758, 27456, 28163,
+ 28880, 29607, 30344, 31090, 31847, 32613, 33390, 34176,
+ 34973, 35779, 36596, 37422, 38259, 39106, 39963, 40830,
+ 41707, 42594, 43492, 44399, 45317, 46246, 47184, 48133,
+ 49092, 50062, 51042, 52032, 53032, 54043, 55065, 56097,
+ 57139, 58192, 59255, 60329, 61413, 62508, 63613, 64729,
+ 65856, 66993, 68141, 69299, 70469, 71648, 72839, 74040,
+ 75252, 76475, 77708, 78952, 80207, 81473, 82750, 84037,
+ 85336, 86645, 87965, 89296, 90638, 91990, 93354, 94729,
+ 96114, 97511, 98919, 100337, 101767, 103208, 104659, 106122,
+ 107596, 109081, 110577, 112085, 113603, 115132, 116673, 118225,
+ 119788, 121362, 122948, 124544, 126152, 127772, 129402, 131044,
+ 132697, 134361, 136037, 137724, 139422, 141132, 142853, 144586,
+ 146330, 148085, 149852, 151630, 153419, 155220, 157033, 158857,
+ 160692, 162540, 164398, 166268, 168150, 170043, 171948, 173864,
+ 175792, 177731, 179683, 181645, 183620, 185606, 187603, 189613,
+ 191634, 193667, 195711, 197767, 199835, 201915, 204006, 206109,
+ 208224, 210351, 212489, 214640, 216802, 218976, 221161, 223359,
+ 225569, 227790, 230023, 232268, 234525, 236794, 239075, 241368,
+ 243672, 245989, 248318, 250658, 253011, 255375, 257752, 260141,
+ 262541, 264954, 267379, 269815, 272264, 274725, 277198, 279683,
+ 282180, 284689, 287211, 289744, 292290, 294848, 297418, 300000
+};
+
+static const u32 gamma_control_set_21[] = {
+ 0, 9, 38, 89, 163, 260, 381, 526,
+ 697, 892, 1113, 1359, 1632, 1930, 2255, 2607,
+ 2985, 3391, 3823, 4283, 4770, 5284, 5826, 6396,
+ 6994, 7620, 8274, 8957, 9668, 10407, 11175, 11971,
+ 12797, 13651, 14534, 15446, 16388, 17358, 18358, 19387,
+ 20446, 21534, 22652, 23799, 24976, 26183, 27420, 28687,
+ 29983, 31310, 32667, 34054, 35471, 36919, 38397, 39905,
+ 41444, 43014, 44614, 46244, 47906, 49598, 51321, 53074,
+ 54859, 56674, 58521, 60399, 62307, 64247, 66218, 68220,
+ 70253, 72318, 74414, 76542, 78700, 80891, 83113, 85366,
+ 87651, 89968, 92316, 94696, 97108, 99551, 102027, 104534,
+ 107073, 109644, 112248, 114883, 117550, 120249, 122980, 125744,
+ 128540, 131367, 134228, 137120, 140045, 143002, 145991, 149013,
+ 152068, 155155, 158274, 161426, 164610, 167827, 171077, 174359,
+ 177674, 181022, 184403, 187816, 191262, 194741, 198253, 201797,
+ 205375, 208985, 212629, 216305, 220015, 223758, 227533, 231342,
+ 235184, 239059, 242967, 246909, 250883, 254891, 258932, 263007,
+ 267115, 271256, 275431, 279639, 283880, 288155, 292464, 296806,
+ 301181, 305590, 310033, 314509, 319019, 323562, 328139, 332750,
+ 337394, 342073, 346785, 351530, 356310, 361123, 365971, 370852,
+ 375767, 380715, 385698, 390715, 395766, 400851, 405969, 411122,
+ 416309, 421530, 426785, 432074, 437397, 442754, 448146, 453572,
+ 459032, 464526, 470054, 475617, 481214, 486845, 492511, 498211,
+ 503945, 509714, 515517, 521355, 527227, 533133, 539074, 545050,
+ 551060, 557104, 563183, 569297, 575445, 581628, 587845, 594097,
+ 600384, 606705, 613061, 619452, 625877, 632338, 638833, 645362,
+ 651927, 658526, 665161, 671830, 678533, 685272, 692046, 698854,
+ 705698, 712576, 719490, 726438, 733421, 740440, 747493, 754581,
+ 761705, 768863, 776057, 783286, 790550, 797848, 805183, 812552,
+ 819956, 827396, 834871, 842381, 849926, 857506, 865122, 872773,
+ 880460, 888181, 895938, 903731, 911558, 919421, 927320, 935254,
+ 943223, 951228, 959268, 967343, 975454, 983601, 991783, 1000000
+};
+
+static const u32 gamma_control_set_213[] = {
+ 0, 8, 33, 78, 144, 231, 341, 473,
+ 628, 807, 1010, 1237, 1489, 1766, 2067, 2395,
+ 2747, 3126, 3531, 3962, 4419, 4903, 5413, 5951,
+ 6516, 7107, 7727, 8373, 9048, 9750, 10480, 11238,
+ 12024, 12839, 13682, 14553, 15453, 16381, 17339, 18325,
+ 19341, 20385, 21459, 22561, 23694, 24855, 26047, 27268,
+ 28518, 29798, 31109, 32449, 33819, 35219, 36650, 38111,
+ 39602, 41123, 42675, 44258, 45871, 47515, 49189, 50894,
+ 52630, 54397, 56196, 58025, 59885, 61776, 63699, 65653,
+ 67638, 69655, 71703, 73782, 75894, 78036, 80211, 82417,
+ 84655, 86925, 89227, 91560, 93926, 96324, 98754, 101216,
+ 103710, 106236, 108795, 111386, 114009, 116665, 119353, 122074,
+ 124827, 127613, 130432, 133283, 136167, 139083, 142033, 145015,
+ 148031, 151079, 154160, 157274, 160422, 163602, 166816, 170063,
+ 173343, 176656, 180002, 183382, 186795, 190242, 193722, 197236,
+ 200783, 204363, 207978, 211626, 215307, 219023, 222772, 226554,
+ 230371, 234221, 238106, 242024, 245976, 249962, 253982, 258037,
+ 262125, 266247, 270404, 274594, 278819, 283079, 287372, 291700,
+ 296062, 300458, 304889, 309354, 313854, 318388, 322957, 327560,
+ 332198, 336870, 341577, 346319, 351096, 355907, 360753, 365633,
+ 370549, 375499, 380484, 385505, 390560, 395650, 400775, 405935,
+ 411130, 416360, 421625, 426925, 432260, 437631, 443037, 448478,
+ 453954, 459466, 465012, 470594, 476212, 481865, 487553, 493277,
+ 499036, 504831, 510661, 516526, 522428, 528364, 534337, 540345,
+ 546388, 552468, 558583, 564733, 570920, 577142, 583400, 589694,
+ 596024, 602389, 608791, 615228, 621702, 628211, 634756, 641337,
+ 647955, 654608, 661297, 668023, 674785, 681582, 688416, 695286,
+ 702193, 709135, 716114, 723129, 730180, 737268, 744392, 751552,
+ 758749, 765982, 773251, 780557, 787900, 795279, 802694, 810146,
+ 817634, 825159, 832721, 840319, 847954, 855625, 863333, 871078,
+ 878860, 886678, 894533, 902425, 910353, 918319, 926321, 934360,
+ 942436, 950548, 958698, 966885, 975108, 983369, 991666, 1000000
+};
+
+static const u32 gamma_control_set_215[] = {
+ 0, 7, 30, 72, 132, 214, 316, 440,
+ 586, 755, 947, 1162, 1401, 1664, 1951, 2263,
+ 2599, 2961, 3348, 3761, 4200, 4664, 5155, 5671,
+ 6215, 6785, 7382, 8006, 8657, 9335, 10041, 10774,
+ 11535, 12324, 13141, 13986, 14859, 15761, 16691, 17650,
+ 18637, 19653, 20698, 21772, 22876, 24008, 25170, 26361,
+ 27581, 28832, 30111, 31421, 32761, 34130, 35530, 36959,
+ 38419, 39909, 41430, 42981, 44562, 46175, 47817, 49491,
+ 51195, 52931, 54697, 56494, 58323, 60182, 62073, 63995,
+ 65949, 67934, 69950, 71998, 74078, 76190, 78333, 80508,
+ 82715, 84954, 87225, 89528, 91863, 94231, 96630, 99062,
+ 101526, 104023, 106552, 109114, 111708, 114335, 116994, 119687,
+ 122412, 125170, 127961, 130784, 133641, 136531, 139454, 142410,
+ 145399, 148422, 151477, 154566, 157689, 160845, 164034, 167257,
+ 170513, 173803, 177127, 180485, 183876, 187301, 190759, 194252,
+ 197779, 201339, 204934, 208562, 212225, 215922, 219653, 223418,
+ 227217, 231051, 234919, 238821, 242758, 246729, 250735, 254775,
+ 258850, 262959, 267103, 271282, 275496, 279744, 284027, 288345,
+ 292697, 297085, 301507, 305965, 310457, 314985, 319548, 324145,
+ 328778, 333446, 338150, 342888, 347662, 352471, 357316, 362195,
+ 367111, 372062, 377048, 382070, 387127, 392220, 397348, 402513,
+ 407713, 412948, 418220, 423527, 428870, 434248, 439663, 445114,
+ 450600, 456123, 461681, 467276, 472906, 478573, 484276, 490014,
+ 495790, 501601, 507448, 513332, 519252, 525209, 531201, 537231,
+ 543296, 549398, 555537, 561712, 567923, 574171, 580456, 586777,
+ 593135, 599529, 605961, 612429, 618933, 625475, 632053, 638668,
+ 645320, 652009, 658735, 665497, 672297, 679133, 686007, 692918,
+ 699865, 706850, 713872, 720931, 728027, 735161, 742331, 749539,
+ 756784, 764067, 771387, 778744, 786138, 793570, 801039, 808546,
+ 816090, 823672, 831291, 838947, 846642, 854374, 862143, 869950,
+ 877795, 885677, 893597, 901555, 909551, 917584, 925655, 933764,
+ 941911, 950096, 958318, 966579, 974877, 983214, 991588, 1000000
+};
+
+static const u32 gamma_control_set_218[] = {
+ 0 , 6, 26, 63, 117, 190, 282, 395,
+ 528, 683, 859, 1057, 1278, 1522, 1788, 2078,
+ 2392, 2730, 3092, 3479, 3891, 4327, 4789, 5277,
+ 5789, 6328, 6893, 7484, 8102, 8746, 9417, 10114,
+ 10839, 11591, 12370, 13177, 14012, 14874, 15765, 16683,
+ 17630, 18605, 19608, 20640, 21701, 22791, 23909, 25057,
+ 26234, 27440, 28675, 29940, 31235, 32559, 33913, 35297,
+ 36711, 38155, 39630, 41134, 42669, 44235, 45831, 47458,
+ 49116, 50804, 52523, 54274, 56055, 57868, 59712, 61587,
+ 63494, 65432, 67402, 69403, 71436, 73501, 75598, 77727,
+ 79888, 82081, 84306, 86564, 88853, 91175, 93530, 95917,
+ 98337, 100789, 103275, 105792, 108343, 110927, 113544, 116193,
+ 118876, 121592, 124342, 127124, 129940, 132790, 135673, 138589,
+ 141539, 144523, 147540, 150592, 153677, 156795, 159948, 163135,
+ 166356, 169611, 172900, 176224, 179582, 182974, 186400, 189861,
+ 193356, 196886, 200451, 204050, 207684, 211352, 215056, 218794,
+ 222567, 226375, 230218, 234096, 238010, 241958, 245941, 249960,
+ 254014, 258104, 262228, 266389, 270584, 274815, 279082, 283384,
+ 287722, 292096, 296505, 300950, 305431, 309948, 314501, 319090,
+ 323714, 328375, 333072, 337805, 342574, 347380, 352221, 357099,
+ 362013, 366964, 371951, 376974, 382034, 387131, 392264, 397434,
+ 402640, 407883, 413163, 418480, 423833, 429223, 434651, 440115,
+ 445616, 451154, 456729, 462341, 467990, 473677, 479401, 485161,
+ 490960, 496795, 502668, 508578, 514526, 520511, 526533, 532593,
+ 538691, 544826, 550999, 557209, 563457, 569743, 576067, 582428,
+ 588828, 595265, 601740, 608253, 614804, 621393, 628020, 634685,
+ 641388, 648129, 654909, 661726, 668582, 675477, 682409, 689380,
+ 696389, 703437, 710523, 717647, 724810, 732011, 739251, 746530,
+ 753847, 761203, 768598, 776031, 783503, 791014, 798563, 806152,
+ 813779, 821445, 829150, 836894, 844677, 852499, 860360, 868261,
+ 876200, 884178, 892196, 900252, 908348, 916484, 924658, 932872,
+ 941125, 949417, 957749, 966121, 974531, 982982, 991471, 1000000
+};
+
+static const u32 gamma_control_set_22[] = {
+ 0, 6, 24, 57, 108, 176, 262, 368,
+ 493, 639, 805, 993, 1202, 1434, 1687, 1964,
+ 2263, 2586, 2933, 3303, 3698, 4117, 4560, 5029,
+ 5522, 6041, 6585, 7156, 7752, 8374, 9022, 9697,
+ 10398, 11127, 11882, 12664, 13474, 14311, 15176, 16068,
+ 16989, 17937, 18913, 19918, 20952, 22013, 23104, 24223,
+ 25372, 26549, 27756, 28992, 30257, 31552, 32876, 34231,
+ 35615, 37029, 38473, 39948, 41452, 42988, 44553, 46149,
+ 47776, 49434, 51123, 52842, 54593, 56375, 58188, 60032,
+ 61908, 63815, 65754, 67725, 69728, 71762, 73828, 75927,
+ 78057, 80220, 82415, 84642, 86902, 89194, 91519, 93876,
+ 96267, 98690, 101146, 103635, 106157, 108712, 111300, 113921,
+ 116576, 119265, 121986, 124741, 127530, 130353, 133209, 136099,
+ 139023, 141981, 144973, 147999, 151059, 154153, 157281, 160444,
+ 163641, 166873, 170139, 173440, 176775, 180145, 183549, 186989,
+ 190463, 193973, 197517, 201096, 204711, 208360, 212045, 215765,
+ 219520, 223311, 227137, 230999, 234896, 238828, 242797, 246801,
+ 250841, 254916, 259028, 263175, 267359, 271578, 275833, 280125,
+ 284453, 288816, 293217, 297653, 302126, 306635, 311181, 315763,
+ 320382, 325037, 329730, 334458, 339224, 344026, 348865, 353741,
+ 358654, 363604, 368591, 373616, 378677, 383775, 388911, 394084,
+ 399294, 404541, 409826, 415149, 420508, 425906, 431341, 436813,
+ 442323, 447871, 453457, 459080, 464742, 470441, 476178, 481953,
+ 487766, 493617, 499506, 505433, 511398, 517402, 523444, 529524,
+ 535642, 541799, 547994, 554228, 560500, 566810, 573159, 579547,
+ 585973, 592439, 598942, 605485, 612066, 618686, 625345, 632043,
+ 638780, 645556, 652371, 659224, 666117, 673050, 680021, 687031,
+ 694081, 701170, 708298, 715466, 722673, 729919, 737205, 744531,
+ 751896, 759300, 766744, 774228, 781751, 789314, 796917, 804560,
+ 812242, 819964, 827726, 835528, 843370, 851252, 859174, 867136,
+ 875138, 883180, 891263, 899385, 907548, 915751, 923994, 932277,
+ 940601, 948965, 957370, 965815, 974301, 982827, 991393, 1000000
+};
+
+static const u32 gamma_control_set_221[] = {
+ 0, 5, 23, 55, 103, 169, 252, 355,
+ 476, 618, 780, 962, 1166, 1392, 1639, 1909,
+ 2202, 2517, 2856, 3219, 3605, 4015, 4450, 4909,
+ 5393, 5902, 6437, 6997, 7582, 8194, 8831, 9495,
+ 10185, 10901, 11645, 12415, 13213, 14037, 14890, 15769,
+ 16677, 17612, 18575, 19567, 20587, 21635, 22712, 23817,
+ 24952, 26115, 27307, 28529, 29780, 31060, 32370, 33710,
+ 35079, 36478, 37908, 39367, 40857, 42377, 43928, 45509,
+ 47120, 48763, 50436, 52141, 53876, 55642, 57440, 59269,
+ 61130, 63022, 64946, 66901, 68889, 70908, 72959, 75042,
+ 77157, 79305, 81485, 83697, 85942, 88219, 90530, 92872,
+ 95248, 97656, 100098, 102572, 105080, 107621, 110195, 112802,
+ 115443, 118117, 120825, 123567, 126342, 129151, 131994, 134871,
+ 137782, 140727, 143706, 146719, 149766, 152848, 155964, 159115,
+ 162300, 165520, 168775, 172064, 175388, 178747, 182141, 185569,
+ 189033, 192532, 196066, 199635, 203240, 206880, 210555, 214266,
+ 218012, 221794, 225612, 229465, 233354, 237279, 241240, 245236,
+ 249269, 253338, 257442, 261583, 265760, 269974, 274223, 278509,
+ 282832, 287191, 291586, 296018, 300487, 304992, 309534, 314113,
+ 318729, 323381, 328071, 332797, 337561, 342362, 347199, 352074,
+ 356987, 361936, 366923, 371947, 377009, 382108, 387245, 392419,
+ 397631, 402881, 408168, 413493, 418856, 424257, 429695, 435172,
+ 440686, 446239, 451830, 457459, 463126, 468831, 474575, 480356,
+ 486177, 492035, 497932, 503868, 509842, 515854, 521906, 527996,
+ 534124, 540292, 546498, 552743, 559027, 565349, 571711, 578112,
+ 584552, 591030, 597548, 604106, 610702, 617337, 624012, 630726,
+ 637480, 644273, 651105, 657977, 664888, 671839, 678830, 685860,
+ 692930, 700039, 707189, 714378, 721607, 728876, 736184, 743533,
+ 750922, 758350, 765819, 773328, 780877, 788466, 796095, 803765,
+ 811475, 819225, 827015, 834846, 842717, 850629, 858582, 866574,
+ 874608, 882682, 890796, 898952, 907148, 915384, 923662, 931980,
+ 940339, 948740, 957181, 965662, 974185, 982749, 991354, 1000000
+};
+
+static const u32 gamma_control_set_222[] = {
+ 0, 5, 22, 53, 99, 162, 243, 342,
+ 460, 597, 755, 932, 1131, 1351, 1592, 1856,
+ 2142, 2450, 2781, 3136, 3514, 3916, 4342, 4792,
+ 5267, 5767, 6292, 6841, 7417, 8017, 8644, 9297,
+ 9976, 10681, 11413, 12171, 12957, 13769, 14609, 15476,
+ 16371, 17293, 18243, 19222, 20228, 21263, 22326, 23418,
+ 24538, 25688, 26866, 28073, 29310, 30576, 31871, 33197,
+ 34551, 35936, 37351, 38795, 40270, 41775, 43311, 44877,
+ 46473, 48101, 49759, 51448, 53169, 54920, 56703, 58516,
+ 60362, 62239, 64147, 66088, 68060, 70064, 72100, 74168,
+ 76268, 78401, 80566, 82763, 84993, 87256, 89551, 91879,
+ 94240, 96634, 99061, 101521, 104014, 106541, 109100, 111694,
+ 114321, 116981, 119675, 122403, 125165, 127961, 130790, 133654,
+ 136551, 139483, 142450, 145450, 148485, 151555, 154659, 157797,
+ 160970, 164178, 167421, 170699, 174012, 177360, 180742, 184160,
+ 187614, 191102, 194626, 198185, 201780, 205410, 209076, 212778,
+ 216515, 220288, 224097, 227942, 231823, 235740, 239692, 243682,
+ 247707, 251768, 255866, 260001, 264171, 268379, 272623, 276903,
+ 281220, 285574, 289965, 294392, 298856, 303358, 307896, 312471,
+ 317084, 321734, 326421, 331145, 335906, 340705, 345541, 350415,
+ 355327, 360276, 365262, 370286, 375349, 380448, 385586, 390762,
+ 395975, 401227, 406516, 411844, 417210, 422614, 428056, 433537,
+ 439055, 444613, 450208, 455843, 461515, 467227, 472977, 478765,
+ 484593, 490459, 496364, 502307, 508290, 514312, 520372, 526472,
+ 532611, 538789, 545006, 551262, 557558, 563892, 570267, 576680,
+ 583133, 589626, 596158, 602729, 609341, 615992, 622682, 629412,
+ 636183, 642992, 649842, 656732, 663662, 670631, 677641, 684691,
+ 691781, 698911, 706081, 713291, 720542, 727833, 735165, 742537,
+ 749949, 757402, 764895, 772429, 780003, 787618, 795274, 802971,
+ 810708, 818486, 826305, 834165, 842065, 850007, 857989, 866013,
+ 874078, 882183, 890330, 898518, 906748, 915018, 923330, 931683,
+ 940078, 948514, 956991, 965510, 974070, 982672, 991315, 1000000
+};
+
+static const u32 gamma_control_set_223[] = {
+ 0, 5, 21, 50, 95, 156, 234, 330,
+ 444, 578, 731, 904, 1097, 1311, 1547, 1804,
+ 2083, 2385, 2709, 3056, 3426, 3820, 4237, 4679,
+ 5144, 5635, 6150, 6689, 7255, 7845, 8461, 9103,
+ 9771, 10465, 11185, 11932, 12705, 13506, 14333, 15188,
+ 16070, 16980, 17917, 18883, 19876, 20897, 21947, 23025,
+ 24132, 25267, 26432, 27625, 28848, 30099, 31381, 32691,
+ 34031, 35402, 36802, 38231, 39692, 41182, 42703, 44254,
+ 45835, 47448, 49091, 50765, 52470, 54207, 55974, 57773,
+ 59603, 61465, 63359, 65284, 67241, 69230, 71251, 73304,
+ 75389, 77507, 79657, 81839, 84054, 86302, 88583, 90896,
+ 93243, 95622, 98034, 100480, 102959, 105471, 108017, 110596,
+ 113209, 115856, 118536, 121251, 123999, 126781, 129597, 132448,
+ 135332, 138251, 141205, 144193, 147215, 150272, 153364, 156490,
+ 159651, 162848, 166079, 169345, 172647, 175983, 179355, 182762,
+ 186205, 189683, 193196, 196746, 200330, 203951, 207607, 211300,
+ 215028, 218792, 222592, 226429, 230301, 234210, 238155, 242137,
+ 246155, 250209, 254300, 258428, 262592, 266793, 271031, 275306,
+ 279618, 283966, 288352, 292775, 297235, 301732, 306267, 310838,
+ 315448, 320094, 324779, 329500, 334260, 339057, 343891, 348764,
+ 353674, 358623, 363609, 368633, 373695, 378796, 383934, 389111,
+ 394326, 399580, 404871, 410202, 415570, 420977, 426423, 431908,
+ 437431, 442992, 448593, 454232, 459911, 465628, 471384, 477180,
+ 483014, 488887, 494800, 500752, 506743, 512774, 518843, 524953,
+ 531102, 537290, 543518, 549785, 556092, 562439, 568826, 575252,
+ 581718, 588224, 594770, 601356, 607982, 614649, 621355, 628101,
+ 634888, 641715, 648582, 655489, 662437, 669425, 676454, 683524,
+ 690633, 697784, 704975, 712207, 719479, 726793, 734147, 741542,
+ 748977, 756454, 763972, 771531, 779131, 786772, 794454, 802177,
+ 809942, 817748, 825595, 833483, 841413, 849385, 857398, 865452,
+ 873548, 881685, 889865, 898085, 906348, 914652, 922998, 931386,
+ 939816, 948288, 956801, 965357, 973955, 982595, 991276, 1000000
+};
+
+static const u32 gamma_control_set_224[] = {
+ 0, 5, 20, 48, 91, 150, 226, 318,
+ 429, 559, 707, 876, 1064, 1273, 1503, 1754,
+ 2026, 2321, 2638, 2977, 3340, 3725, 4135, 4567,
+ 5024, 5505, 6011, 6541, 7096, 7676, 8282, 8913,
+ 9570, 10253, 10962, 11697, 12459, 13248, 14063, 14906,
+ 15775, 16672, 17597, 18549, 19530, 20538, 21574, 22639,
+ 23732, 24854, 26005, 27184, 28393, 29630, 30897, 32194,
+ 33520, 34875, 36261, 37676, 39121, 40597, 42103, 43639,
+ 45206, 46804, 48432, 50091, 51781, 53503, 55255, 57039,
+ 58854, 60701, 62580, 64490, 66432, 68406, 70412, 72450,
+ 74520, 76623, 78758, 80926, 83126, 85359, 87625, 89924,
+ 92256, 94621, 97019, 99450, 101915, 104413, 106944, 109510,
+ 112109, 114742, 117408, 120109, 122843, 125612, 128415, 131252,
+ 134124, 137030, 139971, 142946, 145956, 149000, 152080, 155194,
+ 158343, 161528, 164747, 168002, 171292, 174617, 177978, 181375,
+ 184806, 188274, 191777, 195316, 198891, 202502, 206149, 209832,
+ 213551, 217306, 221098, 224925, 228790, 232690, 236628, 240602,
+ 244612, 248659, 252744, 256864, 261022, 265217, 269449, 273718,
+ 278024, 282368, 286748, 291167, 295622, 300115, 304646, 309214,
+ 313820, 318463, 323145, 327864, 332621, 337416, 342249, 347120,
+ 352030, 356977, 361963, 366987, 372050, 377150, 382290, 387468,
+ 392684, 397939, 403233, 408566, 413937, 419347, 424796, 430285,
+ 435812, 441378, 446983, 452628, 458312, 464035, 469797, 475599,
+ 481440, 487321, 493241, 499201, 505201, 511240, 517319, 523438,
+ 529597, 535795, 542034, 548312, 554631, 560989, 567388, 573827,
+ 580307, 586826, 593386, 599987, 606627, 613309, 620030, 626793,
+ 633596, 640439, 647324, 654249, 661215, 668222, 675270, 682358,
+ 689488, 696659, 703871, 711124, 718418, 725753, 733130, 740548,
+ 748007, 755508, 763050, 770634, 778259, 785926, 793635, 801385,
+ 809177, 817010, 824886, 832803, 840762, 848763, 856806, 864891,
+ 873018, 881188, 889399, 897653, 905948, 914286, 922667, 931089,
+ 939555, 948062, 956612, 965205, 973840, 982517, 991238, 1000000
+};
+
+static const u32 gamma_control_set_225[] = {
+ 0, 4, 19, 46, 88, 144, 217, 307,
+ 415, 540, 685, 849, 1032, 1235, 1460, 1705,
+ 1971, 2259, 2569, 2901, 3256, 3634, 4034, 4459,
+ 4907, 5379, 5875, 6396, 6941, 7511, 8107, 8727,
+ 9373, 10045, 10743, 11467, 12218, 12994, 13798, 14628,
+ 15486, 16370, 17283, 18222, 19190, 20185, 21208, 22259,
+ 23339, 24448, 25584, 26750, 27945, 29168, 30421, 31704,
+ 33015, 34357, 35728, 37129, 38559, 40020, 41512, 43033,
+ 44586, 46168, 47782, 49426, 51102, 52808, 54546, 56314,
+ 58115, 59947, 61810, 63705, 65632, 67591, 69583, 71606,
+ 73661, 75749, 77870, 80023, 82208, 84427, 86678, 88962,
+ 91279, 93630, 96014, 98431, 100881, 103365, 105883, 108434,
+ 111019, 113638, 116291, 118978, 121699, 124454, 127244, 130068,
+ 132926, 135819, 138747, 141710, 144707, 147739, 150806, 153909,
+ 157046, 160218, 163426, 166669, 169948, 173262, 176612, 179997,
+ 183419, 186876, 190369, 193898, 197462, 201063, 204701, 208374,
+ 212084, 215830, 219613, 223432, 227288, 231181, 235110, 239076,
+ 243079, 247119, 251196, 255311, 259462, 263650, 267876, 272139,
+ 276440, 280778, 285154, 289567, 294018, 298507, 303034, 307598,
+ 312200, 316841, 321519, 326236, 330991, 335784, 340615, 345485,
+ 350393, 355339, 360325, 365348, 370411, 375512, 380652, 385831,
+ 391049, 396306, 401601, 406936, 412310, 417723, 423176, 428668,
+ 434199, 439769, 445379, 451029, 456718, 462447, 468215, 474024,
+ 479872, 485760, 491687, 497655, 503663, 509711, 515799, 521927,
+ 528096, 534305, 540554, 546843, 553173, 559544, 565955, 572406,
+ 578899, 585432, 592005, 598620, 605275, 611971, 618709, 625487,
+ 632306, 639167, 646068, 653011, 659995, 667020, 674087, 681195,
+ 688345, 695536, 702768, 710042, 717358, 724715, 732115, 739556,
+ 747038, 754563, 762130, 769738, 777389, 785081, 792816, 800593,
+ 808412, 816273, 824177, 832123, 840111, 848142, 856215, 864331,
+ 872489, 880690, 888934, 897220, 905549, 913921, 922335, 930793,
+ 939293, 947836, 956423, 965052, 973724, 982440, 991199, 1000000
+};
+
+static const u32 *GAMMA_CONTROL_TABLE[G_MAX] = {
+ gamma_control_set_21,
+ gamma_control_set_213,
+ gamma_control_set_215,
+ gamma_control_set_218,
+ gamma_control_set_22,
+ gamma_control_set_221,
+ gamma_control_set_222,
+ gamma_control_set_223,
+ gamma_control_set_224,
+ gamma_control_set_225
+};
+
+static const struct str_flookup_table flookup_table[302] = {
+ { 0, 0}, { 1, 20},
+ { 20, 7}, { 27, 5},
+ { 32, 4}, { 36, 4},
+ { 40, 4}, { 44, 3},
+ { 47, 3}, { 50, 2},
+ { 52, 3}, { 55, 2},
+ { 57, 3}, { 60, 2},
+ { 62, 2}, { 64, 2},
+ { 66, 2}, { 68, 2},
+ { 70, 1}, { 71, 2},
+ { 73, 2}, { 75, 2},
+ { 77, 1}, { 78, 2},
+ { 80, 1}, { 81, 2},
+ { 83, 1}, { 84, 2},
+ { 86, 1}, { 87, 2},
+ { 89, 1}, { 90, 1},
+ { 91, 2}, { 93, 1},
+ { 94, 1}, { 95, 2},
+ { 97, 1}, { 98, 1},
+ { 99, 1}, {100, 1},
+ {101, 2}, {103, 1},
+ {104, 1}, {105, 1},
+ {106, 1}, {107, 1},
+ {108, 1}, {109, 1},
+ {110, 1}, {111, 1},
+ {112, 1}, {113, 1},
+ {114, 1}, {115, 1},
+ {116, 1}, {117, 1},
+ {118, 1}, {119, 1},
+ {120, 1}, {121, 1},
+ {122, 1}, {123, 1},
+ {124, 1}, {125, 1},
+ {126, 1}, {127, 1},
+ {128, 1}, {129, 1},
+ { 0, 0}, {130, 1},
+ {131, 1}, {132, 1},
+ {133, 1}, {134, 1},
+ { 0, 0}, {135, 1},
+ {136, 1}, {137, 1},
+ {138, 1}, {139, 1},
+ { 0, 0}, {140, 1},
+ {141, 1}, {142, 1},
+ { 0, 0}, {143, 1},
+ {144, 1}, {145, 1},
+ {146, 1}, { 0, 0},
+ {147, 1}, {148, 1},
+ {149, 1}, { 0, 0},
+ {150, 1}, {151, 1},
+ { 0, 0}, {152, 1},
+ {153, 1}, {154, 1},
+ { 0, 0}, {155, 1},
+ {156, 1}, { 0, 0},
+ {157, 1}, {158, 1},
+ { 0, 0}, {159, 1},
+ {160, 1}, { 0, 0},
+ {161, 1}, {162, 1},
+ { 0, 0}, {163, 1},
+ {164, 1}, { 0, 0},
+ {165, 1}, {166, 1},
+ { 0, 0}, {167, 1},
+ {168, 1}, { 0, 0},
+ {169, 1}, {170, 1},
+ { 0, 0}, {171, 1},
+ { 0, 0}, {172, 1},
+ {173, 1}, { 0, 0},
+ {174, 1}, { 0, 0},
+ {175, 1}, {176, 1},
+ { 0, 0}, {177, 1},
+ { 0, 0}, {178, 1},
+ {179, 1}, { 0, 0},
+ {180, 1}, { 0, 0},
+ {181, 1}, {182, 1},
+ { 0, 0}, {183, 1},
+ { 0, 0}, {184, 1},
+ { 0, 0}, {185, 1},
+ {186, 1}, { 0, 0},
+ {187, 1}, { 0, 0},
+ {188, 1}, { 0, 0},
+ {189, 1}, { 0, 0},
+ {190, 1}, {191, 1},
+ { 0, 0}, {192, 1},
+ { 0, 0}, {193, 1},
+ { 0, 0}, {194, 1},
+ { 0, 0}, {195, 1},
+ { 0, 0}, {196, 1},
+ { 0, 0}, {197, 1},
+ {198, 1}, { 0, 0},
+ {199, 1}, { 0, 0},
+ {200, 1}, { 0, 0},
+ {201, 1}, { 0, 0},
+ {202, 1}, { 0, 0},
+ {203, 1}, { 0, 0},
+ {204, 1}, { 0, 0},
+ {205, 1}, { 0, 0},
+ {206, 1}, { 0, 0},
+ {207, 1}, { 0, 0},
+ {208, 1}, { 0, 0},
+ {209, 1}, { 0, 0},
+ {210, 1}, { 0, 0},
+ {211, 1}, { 0, 0},
+ {212, 1}, { 0, 0},
+ {213, 1}, { 0, 0},
+ { 0, 0}, {214, 1},
+ { 0, 0}, {215, 1},
+ { 0, 0}, {216, 1},
+ { 0, 0}, {217, 1},
+ { 0, 0}, {218, 1},
+ { 0, 0}, {219, 1},
+ { 0, 0}, {220, 1},
+ { 0, 0}, {221, 1},
+ { 0, 0}, { 0, 0},
+ {222, 1}, { 0, 0},
+ {223, 1}, { 0, 0},
+ {224, 1}, { 0, 0},
+ {225, 1}, { 0, 0},
+ { 0, 0}, {226, 1},
+ { 0, 0}, {227, 1},
+ { 0, 0}, {228, 1},
+ { 0, 0}, {229, 1},
+ { 0, 0}, { 0, 0},
+ {230, 1}, { 0, 0},
+ {231, 1}, { 0, 0},
+ {232, 1}, { 0, 0},
+ {233, 1}, { 0, 0},
+ { 0, 0}, {234, 1},
+ { 0, 0}, {235, 1},
+ { 0, 0}, { 0, 0},
+ {236, 1}, { 0, 0},
+ {237, 1}, { 0, 0},
+ {238, 1}, { 0, 0},
+ { 0, 0}, {239, 1},
+ { 0, 0}, {240, 1},
+ { 0, 0}, {241, 1},
+ { 0, 0}, { 0, 0},
+ {242, 1}, { 0, 0},
+ {243, 1}, { 0, 0},
+ { 0, 0}, {244, 1},
+ { 0, 0}, {245, 1},
+ { 0, 0}, { 0, 0},
+ {246, 1}, { 0, 0},
+ {247, 1}, { 0, 0},
+ { 0, 0}, {248, 1},
+ { 0, 0}, {249, 1},
+ { 0, 0}, { 0, 0},
+ {250, 1}, { 0, 0},
+ {251, 1}, { 0, 0},
+ { 0, 0}, {252, 1},
+ { 0, 0}, {253, 1},
+ { 0, 0}, { 0, 0},
+ {254, 1}, { 0, 0},
+ { 0, 0}, {255, 1},
+};
+
+#endif
+
diff --git a/drivers/video/samsung/lcdfreq.c b/drivers/video/samsung/lcdfreq.c
index 8c25c22..7e4af07 100644
--- a/drivers/video/samsung/lcdfreq.c
+++ b/drivers/video/samsung/lcdfreq.c
@@ -21,8 +21,6 @@
#include "s3cfb.h"
-#define LCDFREQ_LIMIT_HZ 40
-
enum lcdfreq_level_idx {
LEVEL_NORMAL,
LEVEL_LIMIT,
@@ -217,30 +215,44 @@ int get_divider(struct fb_info *fb)
fimd_div = gcd(lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv, lcdfreq->table[LEVEL_LIMIT].cmu_clkdiv);
+ if ((!fimd_div) || (fimd_div > 16)) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
+
lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv /= fimd_div;
lcdfreq->table[LEVEL_LIMIT].cmu_clkdiv /= fimd_div;
dev_info(fb->dev, "%s rate is %d, fimd divider=%d\n", clk->name, rate, fimd_div);
+ fimd_div--;
for (i = 0; i < LCDFREQ_LEVEL_END; i++) {
- lcdfreq->table[i].cmu_clkdiv--;
- dev_info(fb->dev, "%dHZ divider is %d\n",
+ if (lcdfreq->table[i].cmu_clkdiv > 16) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
+ dev_info(fb->dev, "%dhz div is %d\n",
lcdfreq->table[i].hz, lcdfreq->table[i].cmu_clkdiv);
+ lcdfreq->table[i].cmu_clkdiv--;
}
reg = (readl(fbdev->regs + S3C_VIDCON0) & (S3C_VIDCON0_CLKVAL_F(0xff))) >> 6;
- reg++;
-
- if (fimd_div != reg)
- return -EINVAL;
+ if (fimd_div != reg) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
reg = (readl(sclk->reg_div.reg)) >> sclk->reg_div.shift;
reg &= 0xf;
-
- if (lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv != reg)
- return -EINVAL;
+ if (lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv != reg) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
return 0;
+
+err:
+ return -EINVAL;
}
static ssize_t level_show(struct device *dev,
@@ -256,7 +268,7 @@ static ssize_t level_show(struct device *dev,
return -EINVAL;
}
- return sprintf(buf, "%dHZ, div=%d\n", lcdfreq->table[lcdfreq->level].hz, get_div(fbdev));
+ return sprintf(buf, "%dhz, div=%d\n", lcdfreq->table[lcdfreq->level].hz, get_div(fbdev));
}
static ssize_t level_store(struct device *dev,
@@ -296,12 +308,61 @@ static ssize_t usage_show(struct device *dev,
return sprintf(buf, "%d\n", atomic_read(&lcdfreq->usage));
}
+#if 0
+static ssize_t freq_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fb = dev_get_drvdata(dev);
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev = get_fimd_global(win->id);
+ struct s3cfb_lcd *lcd = fbdev->lcd;
+
+ return sprintf(buf, "%dhz, hfp=%d, hbp=%d, hsw=%d, div=%d\n", lcd->freq,
+ lcd->timing.h_fp, lcd->timing.h_bp, lcd->timing.h_sw, get_div(fbdev)+1);
+}
+
+extern void s5p_dsim_set_lcd_freq_change(struct s3cfb_lcd_timing *timing);
+
+static ssize_t freq_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct fb_info *fb = dev_get_drvdata(dev);
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev = get_fimd_global(win->id);
+ struct s3cfb_lcd *lcd = fbdev->lcd;
+ struct s3cfb_lcd_timing *timing = &lcd->timing;
+ struct fb_var_screeninfo *var = &fb->var;
+
+ lcd->freq_limit = 0;
+ sscanf(buf, "%d %d %d %d", &lcd->freq,
+ &timing->h_fp, &timing->h_bp, &timing->h_sw);
+
+ var->hsync_len = timing->h_sw;
+ var->left_margin = timing->h_bp;
+ var->right_margin = timing->h_fp;
+
+ var->pixclock = (lcd->freq *
+ (var->left_margin + var->right_margin
+ + var->hsync_len + var->xres) *
+ (var->upper_margin + var->lower_margin
+ + var->vsync_len + var->yres));
+ var->pixclock = KHZ2PICOS(var->pixclock/1000);
+
+ s5p_dsim_set_lcd_freq_change(timing);
+
+ return count;
+}
+
+static DEVICE_ATTR(freq, S_IRUGO|S_IWUSR, freq_show, freq_store);
+#endif
+
static DEVICE_ATTR(level, S_IRUGO|S_IWUSR, level_show, level_store);
static DEVICE_ATTR(usage, S_IRUGO, usage_show, NULL);
static struct attribute *lcdfreq_attributes[] = {
&dev_attr_level.attr,
&dev_attr_usage.attr,
+/* &dev_attr_freq.attr, */
NULL,
};
@@ -323,7 +384,7 @@ static void lcdfreq_early_suspend(struct early_suspend *h)
atomic_set(&lcdfreq->usage, 0);
mutex_unlock(&lcdfreq->lock);
- return ;
+ return;
}
static void lcdfreq_late_resume(struct early_suspend *h)
@@ -392,7 +453,7 @@ static void lcdfreq_status_work(struct work_struct *work)
cancel_delayed_work(&lcdfreq->work);
- dev_info(lcdfreq->dev, "\tHZ=%d, usage=%d\n", hz, atomic_read(&lcdfreq->usage));
+ dev_info(lcdfreq->dev, "\thz=%d, usage=%d\n", hz, atomic_read(&lcdfreq->usage));
schedule_delayed_work(&lcdfreq->work, HZ*120);
}
@@ -405,8 +466,8 @@ int lcdfreq_init(struct fb_info *fb)
struct fb_var_screeninfo *var = &fb->var;
struct lcdfreq_info *lcdfreq = NULL;
- u32 vclk = 0;
- int ret;
+ u32 vclk;
+ int ret = 0;
lcdfreq = kzalloc(sizeof(struct lcdfreq_info), GFP_KERNEL);
if (!lcdfreq) {
@@ -415,6 +476,11 @@ int lcdfreq_init(struct fb_info *fb)
goto err_1;
}
+ if (!lcd->freq_limit) {
+ ret = -EINVAL;
+ goto err_2;
+ }
+
fbdev->data = lcdfreq;
lcdfreq->dev = fb->dev;
@@ -430,7 +496,7 @@ int lcdfreq_init(struct fb_info *fb)
lcdfreq->table[LEVEL_NORMAL].pixclock = var->pixclock;
lcdfreq->table[LEVEL_NORMAL].hz = lcd->freq;
- vclk = (LCDFREQ_LIMIT_HZ *
+ vclk = (lcd->freq_limit *
(var->left_margin + var->right_margin
+ var->hsync_len + var->xres) *
(var->upper_margin + var->lower_margin
@@ -438,11 +504,11 @@ int lcdfreq_init(struct fb_info *fb)
lcdfreq->table[LEVEL_LIMIT].level = LEVEL_LIMIT;
lcdfreq->table[LEVEL_LIMIT].vclk = vclk;
lcdfreq->table[LEVEL_LIMIT].pixclock = KHZ2PICOS(vclk/1000);
- lcdfreq->table[LEVEL_LIMIT].hz = LCDFREQ_LIMIT_HZ;
+ lcdfreq->table[LEVEL_LIMIT].hz = lcd->freq_limit;
ret = get_divider(fb);
if (ret < 0) {
- pr_err("fail to init lcd freq switch");
+ pr_err("skip lcd freq switch init");
fbdev->data = NULL;
goto err_1;
}
@@ -489,4 +555,3 @@ err_1:
return ret;
}
-
diff --git a/drivers/video/samsung/ld9040.c b/drivers/video/samsung/ld9040.c
index 2ff3af0..9c75788 100644
--- a/drivers/video/samsung/ld9040.c
+++ b/drivers/video/samsung/ld9040.c
@@ -75,7 +75,7 @@ struct lcd_info {
unsigned int auto_brightness;
unsigned int ldi_enable;
unsigned int acl_enable;
- unsigned int cur_acl;
+ unsigned int current_acl;
struct mutex lock;
struct mutex bl_lock;
struct lcd_device *ld;
@@ -461,56 +461,49 @@ elvss_err:
return ret;
}
-static int ld9040_set_acl(struct lcd_info *lcd)
+static int ld9040_set_acl(struct lcd_info *lcd, u8 force)
{
- int ret = 0;
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
struct ld9040_panel_data *pdata = lcd->lcd_pd->pdata;
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0 || lcd->bl == 1) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[0]);
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_on);
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- }
- switch (lcd->bl) {
- case GAMMA_30CD ... GAMMA_40CD: /* 30cd ~ 40cd */
- if (lcd->cur_acl != 0) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[0]);
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_70CD ... GAMMA_250CD: /* 70cd ~ 250cd */
- if (lcd->cur_acl != 40) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[1]);
- lcd->cur_acl = 40;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 50) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[2]);
- lcd->cur_acl = 50;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[0]);
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
+ switch (candela) {
+ case 0 ... 69:
+ level = ACL_STATUS_0P;
+ break;
+ case 70 ... 250:
+ level = ACL_STATUS_40P;
+ break;
+ default:
+ level = ACL_STATUS_50P;
+ break;
}
- if (ret) {
+ if (!lcd->acl_enable)
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = ld9040_panel_send_sequence(lcd, pdata->acl_on);
+ else {
+ ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[ACL_STATUS_0P]);
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[level]);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
ret = -EPERM;
- goto acl_err;
- }
-acl_err:
+exit:
return ret;
}
@@ -578,7 +571,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
ret = ld9040_gamma_ctl(lcd);
- ret |= ld9040_set_acl(lcd);
+ ret |= ld9040_set_acl(lcd, force);
ret |= ld9040_set_elvss(lcd);
@@ -836,7 +829,7 @@ device_attribute *attr, const char *buf, size_t size)
mutex_lock(&lcd->bl_lock);
lcd->acl_enable = value;
if (lcd->ldi_enable)
- ld9040_set_acl(lcd);
+ ld9040_set_acl(lcd, 0);
mutex_unlock(&lcd->bl_lock);
}
}
@@ -1076,7 +1069,7 @@ static int ld9040_probe(struct spi_device *spi)
lcd->current_gamma_mode = 0;
lcd->acl_enable = 0;
- lcd->cur_acl = 0;
+ lcd->current_acl = 0;
lcd->auto_brightness = 1;
diff --git a/drivers/video/samsung/lms501xx.h b/drivers/video/samsung/lms501xx.h
new file mode 100644
index 0000000..0d5ca54
--- /dev/null
+++ b/drivers/video/samsung/lms501xx.h
@@ -0,0 +1,156 @@
+#ifndef __LMS501XX_H__
+#define __LMS501XX_H__
+
+const unsigned char SEQ_SET_EXTC[] = {
+ 0xB9,
+ 0xFF, 0x83, 0x69,
+};
+
+const unsigned char SEQ_SET_MIPI_DSI[] = {
+ 0xBA,
+ 0x11, 0x00, 0x16, 0xC6, 0x80, 0x0A, 0x00, 0x10, 0x24, 0x02,
+ 0x21, 0x21, 0x9A, 0x11, 0x14,
+};
+
+const unsigned char SEQ_SET_GIP[] = {
+ 0xD5,
+ 0x00, 0x00, 0x09, 0x03, 0x2D, 0x00, 0x00, 0x12, 0x31, 0x23,
+ 0x00, 0x00, 0x10, 0x70, 0x37, 0x00, 0x00, 0x0D, 0x01, 0x40,
+ 0x37, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xEF, 0x00, 0x13, 0x57,
+ 0x71, 0x00, 0x00, 0x00, 0xEF, 0xEF, 0x00, 0x64, 0x20, 0x06,
+ 0x00, 0x00, 0x00, 0xEF, 0xEF, 0x00, 0x02, 0x46, 0x60, 0x00,
+ 0x00, 0x00, 0xEF, 0xEF, 0x00, 0x75, 0x31, 0x17, 0x00, 0x00,
+ 0x00, 0xEF, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F,
+ 0xFC, 0x0C, 0xFC, 0xFF, 0x0F, 0xFC, 0x0C, 0xFC, 0xFF, 0x00,
+ 0x00, 0x5A,
+};
+
+const unsigned char SEQ_SET_POWER[] = {
+ 0xB1,
+ 0x0A, 0x83, 0x77, 0x00, 0x91, 0x0F, 0x1C, 0x1C, 0x0C, 0x2A,
+ 0x20, 0x4E,
+};
+
+const unsigned char SEQ_SET_RGB[] = {
+ 0xB3,
+ 0x03, 0x00, 0x30, 0x0B,
+};
+
+const unsigned char SEQ_SET_CYC[] = {
+ 0xB4, 0x02,
+};
+
+const unsigned char SEQ_SET_VCOM[] = {
+ 0xB6,
+ 0xB1, 0xa8, 0x00,
+};
+
+const unsigned char SEQ_SET_PTBA[] = {
+ 0xBF,
+ 0x5F, 0x00, 0x00, 0x06,
+};
+
+const unsigned char SEQ_SET_PANEL[] = {
+ 0xCC, 0x0e,
+};
+
+const unsigned char SEQ_SET_DGC[] = {
+ 0xC1, 0x00,
+};
+
+const unsigned char SEQ_SET_STBA[] = {
+ 0xC0,
+ 0x73, 0x50, 0x00, 0x1f, 0x04, 0x04,
+};
+
+const unsigned char SEQ_SET_EQ[] = {
+ 0xE3,
+ 0x03, 0x03, 0x03, 0x03,
+};
+
+const unsigned char SEQ_SET_VCOM_POWER[] = {
+ 0xEA, 0x7A,
+};
+
+const unsigned char SEQ_SET_ECO[] = {
+ 0xC6, 0x40,
+};
+
+const unsigned char SEQ_SET_GAMMA[] = {
+ 0xE0,
+ 0x00, 0x1C, 0x20, 0x35, 0x3A, 0x3F, 0x31, 0x4c, 0x08, 0x0E,
+ 0x0E, 0x12, 0x13, 0x11, 0x13, 0x18, 0x1D, 0x00, 0x1C, 0x20,
+ 0x35, 0x3A, 0x3F, 0x31, 0x4c, 0x08, 0x0E, 0x0E, 0x12, 0x13,
+ 0x11, 0x13, 0x18, 0x1D, 0x01,
+};
+
+const unsigned char SEQ_SET_CABC_PWM[] = {
+ 0xC9,
+ 0x0F, 0x00,
+};
+
+unsigned char SEQ_SET_BL[] = {
+ 0x51, 0xFF,
+};
+
+const unsigned char SEQ_SET_DISP[] = {
+ 0x53, 0x24,
+};
+
+const unsigned char SEQ_SET_CABC_ON[] = {
+ 0x55, 0x02,
+};
+
+const unsigned char SEQ_SET_CABC_OFF[] = {
+ 0x55, 0x00,
+};
+
+const unsigned char SEQ_SLEEP_IN[] = {
+ 0x10,
+};
+
+const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+};
+
+const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+};
+
+const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+};
+
+enum {
+ GAMMA_30CD = 0,
+ GAMMA_40CD,
+ GAMMA_70CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_260CD,
+ GAMMA_270CD,
+ GAMMA_280CD,
+ GAMMA_290CD,
+ GAMMA_300CD = 24,
+ GAMMA_MAX
+};
+
+#define GAMMA_PARAM_SIZE 26
+
+#endif /* __LMS501XX_H__ */
diff --git a/drivers/video/samsung/mdnie_table_baffin.h b/drivers/video/samsung/mdnie_table_baffin.h
new file mode 100644
index 0000000..a3df222
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_baffin.h
@@ -0,0 +1,803 @@
+#ifndef __MDNIE_TABLE_H__
+#define __MDNIE_TABLE_H__
+
+#include "mdnie.h"
+
+
+static const unsigned short tune_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, 0x0293, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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, 0x0293, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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, 0x0293, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_vt[] = {
+ 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, 0x0293, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a0,
+ /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a0,
+ /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a0,
+ /*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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae,
+ /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_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, 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*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_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, 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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_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, 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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_vt[] = {
+ 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, 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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ac,
+ /*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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ac,
+ /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ac,
+ /*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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae,
+ /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_normal_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+struct mdnie_tunning_info etc_table[CABC_MAX][OUTDOOR_MAX][TONE_MAX] = {
+ {
+ {
+ {"NORMAL", NULL},
+ {"WARM", tune_warm},
+ {"COLD", tune_cold},
+ },
+ {
+ {"NORMAL_OUTDOOR", tune_normal_outdoor},
+ {"WARM_OUTDOOR", tune_warm_outdoor},
+ {"COLD_OUTDOOR", tune_cold_outdoor},
+ },
+ }
+};
+
+struct mdnie_tunning_info tunning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
+ {
+ {
+ {"DYNAMIC_UI", tune_dynamic_ui},
+ {"DYNAMIC_VIDEO", tune_dynamic_video},
+ {"DYNAMIC_VIDEO", tune_dynamic_video},
+ {"DYNAMIC_VIDEO", tune_dynamic_video},
+ {"CAMERA", NULL},
+ {"DYNAMIC_UI", tune_dynamic_ui},
+ {"DYNAMIC_GALLERY", tune_dynamic_gallery},
+ {"DYNAMIC_VT", tune_dynamic_vt},
+ }, {
+ {"STANDARD_UI", tune_standard_ui},
+ {"STANDARD_VIDEO", tune_standard_video},
+ {"STANDARD_VIDEO", tune_standard_video},
+ {"STANDARD_VIDEO", tune_standard_video},
+ {"CAMERA", NULL},
+ {"STANDARD_UI", tune_standard_ui},
+ {"STANDARD_GALLERY", tune_standard_gallery},
+ {"STANDARD_VT", tune_standard_vt},
+ }, {
+ {"NATURAL_UI", tune_natural_ui},
+ {"NATURAL_VIDEO", tune_natural_video},
+ {"NATURAL_VIDEO_WARM", tune_natural_video},
+ {"NATURAL_VIDEO_COLD", tune_natural_video},
+ {"CAMERA", NULL},
+ {"NATURAL_UI", tune_natural_ui},
+ {"NATURAL_GALLERY", tune_natural_gallery},
+ {"NATURAL_VT", tune_natural_vt},
+ }, {
+ {"MOVIE_UI", tune_movie_ui},
+ {"MOVIE_VIDEO", tune_movie_video},
+ {"MOVIE_VIDEO", tune_movie_video},
+ {"MOVIE_VIDEO", tune_movie_video},
+ {"CAMERA", NULL},
+ {"MOVIE_UI", tune_movie_ui},
+ {"MOVIE_GALLERY", tune_movie_gallery},
+ {"MOVIE_VT", tune_movie_vt},
+ },
+ }
+};
+
+struct mdnie_tunning_info camera_table[OUTDOOR_MAX] = {
+ {"CAMERA", tune_camera},
+ {"CAMERA_OUTDOOR", tune_camera_outdoor},
+};
+
+#endif/* __MDNIE_TABLE_H__ */
diff --git a/drivers/video/samsung/mdnie_table_t0.h b/drivers/video/samsung/mdnie_table_t0.h
new file mode 100644
index 0000000..a3e9325
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_t0.h
@@ -0,0 +1,763 @@
+#ifndef __MDNIE_TABLE_H__
+#define __MDNIE_TABLE_H__
+
+#include "mdnie.h"
+
+
+static const unsigned short tune_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*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x0092, 0x0030, /*DE pe*/
+ 0x0093, 0x0080, /*DE pf*/
+ 0x0094, 0x0080, /*DE pb*/
+ 0x0095, 0x0030, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0088, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_vt[] = {
+ 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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a0, /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a0, /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a0, /*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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae, /*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, 0x0042, /*DE pe*/
+ 0x0093, 0x0042, /*DE pf*/
+ 0x0094, 0x0042, /*DE pb*/
+ 0x0095, 0x0042, /*DE ne*/
+ 0x0096, 0x0042, /*DE nf*/
+ 0x0097, 0x0042, /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_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*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x0092, 0x0030, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0030, /*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*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0088, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1604, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_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, 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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_standard_vt[] = {
+ 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, 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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x0092, 0x0030, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0030, /*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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00a8, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x0092, 0x0030, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0030, /*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, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_natural_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae, /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x1090, /*CC lut r 16 144*/
+ 0x0022, 0x20a0, /*CC lut r 32 160*/
+ 0x0023, 0x30b0, /*CC lut r 48 176*/
+ 0x0024, 0x40c0, /*CC lut r 64 192*/
+ 0x0025, 0x50d0, /*CC lut r 80 208*/
+ 0x0026, 0x60e0, /*CC lut r 96 224*/
+ 0x0027, 0x70f0, /*CC lut r 112 240*/
+ 0x0028, 0x80ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x0092, 0x0030, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0030, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x0092, 0x0030, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0030, /*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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_normal_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_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*/
+ END_SEQ, 0x0000,
+};
+
+struct mdnie_tunning_info etc_table[CABC_MAX][OUTDOOR_MAX][TONE_MAX] = {
+ {
+ {
+ {"NORMAL", NULL},
+ {"WARM", tune_warm},
+ {"COLD", tune_cold},
+ },
+ {
+ {"NORMAL_OUTDOOR", tune_normal_outdoor},
+ {"WARM_OUTDOOR", tune_warm_outdoor},
+ {"COLD_OUTDOOR", tune_cold_outdoor},
+ },
+ }
+};
+
+struct mdnie_tunning_info tunning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
+ {
+ {
+ {"DYNAMIC_UI", tune_dynamic_ui},
+ {"DYNAMIC_VIDEO", tune_dynamic_video},
+ {"DYNAMIC_VIDEO", tune_dynamic_video},
+ {"DYNAMIC_VIDEO", tune_dynamic_video},
+ {"CAMERA", NULL},
+ {"DYNAMIC_UI", tune_dynamic_ui},
+ {"DYNAMIC_GALLERY", tune_dynamic_gallery},
+ {"DYNAMIC_VT", tune_dynamic_vt},
+ }, {
+ {"STANDARD_UI", tune_standard_ui},
+ {"STANDARD_VIDEO", tune_standard_video},
+ {"STANDARD_VIDEO", tune_standard_video},
+ {"STANDARD_VIDEO", tune_standard_video},
+ {"CAMERA", NULL},
+ {"STANDARD_UI", tune_standard_ui},
+ {"STANDARD_GALLERY", tune_standard_gallery},
+ {"STANDARD_VT", tune_standard_vt},
+ }, {
+ {"NATURAL_UI", tune_natural_ui},
+ {"NATURAL_VIDEO", tune_natural_video},
+ {"NATURAL_VIDEO_WARM", tune_natural_video},
+ {"NATURAL_VIDEO_COLD", tune_natural_video},
+ {"CAMERA", NULL},
+ {"NATURAL_UI", tune_natural_ui},
+ {"NATURAL_GALLERY", tune_natural_gallery},
+ {"NATURAL_VT", tune_natural_vt},
+ }, {
+ {"MOVIE_UI", tune_movie_ui},
+ {"MOVIE_VIDEO", tune_movie_video},
+ {"MOVIE_VIDEO", tune_movie_video},
+ {"MOVIE_VIDEO", tune_movie_video},
+ {"CAMERA", NULL},
+ {"MOVIE_UI", tune_movie_ui},
+ {"MOVIE_GALLERY", tune_movie_gallery},
+ {"MOVIE_VT", tune_movie_vt},
+ },
+ }
+};
+
+struct mdnie_tunning_info camera_table[OUTDOOR_MAX] = {
+ {"CAMERA", tune_camera},
+ {"CAMERA_OUTDOOR", tune_camera_outdoor},
+};
+
+#endif/* __MDNIE_TABLE_H__ */
+
diff --git a/drivers/video/samsung/s3cfb.h b/drivers/video/samsung/s3cfb.h
index b278184..0831ac8 100644
--- a/drivers/video/samsung/s3cfb.h
+++ b/drivers/video/samsung/s3cfb.h
@@ -22,6 +22,7 @@
#endif
#include <plat/fb-s5p.h>
#endif
+#include <linux/kthread.h>
#include <mach/cpufreq.h>
#define S3CFB_NAME "s3cfb"
@@ -42,10 +43,19 @@
#define POWER_ON 1
#define POWER_OFF 0
+#define VSYNC_TIMEOUT_MSEC 50
+
#if defined(CONFIG_MACH_PX) || defined(CONFIG_MACH_Q1_BD)
#define FEATURE_BUSFREQ_LOCK /* Now, this feature only avaliable in 4210 */
#endif
+/* S3C_FB_MAX_WIN
+ * Set to the maximum number of windows that any of the supported hardware
+ * can use. Since the platform data uses this for an array size, having it
+ * set to the maximum of any version of the hardware can do is safe.
+ */
+#define S3C_FB_MAX_WIN (5)
+
enum s3cfb_data_path_t {
DATA_PATH_FIFO = 0,
DATA_PATH_DMA = 1,
@@ -145,6 +155,7 @@ struct s3cfb_lcd {
int p_height;
int bpp;
int freq;
+ int freq_limit;
int vclk;
struct s3cfb_lcd_timing timing;
struct s3cfb_lcd_polarity polarity;
@@ -161,6 +172,32 @@ struct s3cfb_fimd_desc {
struct s3cfb_global *fbdev[FIMD_MAX];
};
+/**
+ * struct s3cfb_vsync - vsync information+
+ * @wait: a queue for processes waiting for vsync
+ * @timestamp: the time of the last vsync interrupt
+ * @active: whether userspace is requesting vsync uevents
+ * @irq_refcount: reference count for the underlying irq
+ * @irq_lock: mutex protecting the irq refcount and register
+ * @thread: uevent-generating thread
+ */
+struct s3cfb_vsync {
+ wait_queue_head_t wait;
+ ktime_t timestamp;
+ bool active;
+ int irq_refcount;
+ struct mutex irq_lock;
+ struct task_struct *thread;
+};
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+struct sysmmu_flag {
+ bool enabled;
+ unsigned long default_fb_addr;
+ unsigned long pgd;
+};
+#endif
+
struct s3cfb_global {
void __iomem *regs;
void __iomem *regs_org;
@@ -172,21 +209,29 @@ struct s3cfb_global {
#ifdef CONFIG_BUSFREQ_OPP
struct device *bus_dev;
#endif
+ spinlock_t vsync_slock;
struct clk *clock;
int irq;
wait_queue_head_t wq;
unsigned int wq_count;
struct fb_info **fb;
-
- ktime_t vsync_timestamp;
- int vsync_state;
- struct task_struct *vsync_thread;
+ struct s3cfb_vsync vsync_info;
atomic_t enabled_win;
enum s3cfb_output_t output;
enum s3cfb_rgb_mode_t rgb_mode;
struct s3cfb_lcd *lcd;
int system_state;
+
+ /* New added */
+ struct list_head update_regs_list;
+ struct mutex update_regs_list_lock;
+ struct kthread_worker update_regs_worker;
+ struct task_struct *update_regs_thread;
+ struct kthread_work update_regs_work;
+
+ struct sw_sync_timeline *timeline;
+ int timeline_max;
#ifdef CONFIG_HAS_WAKELOCK
struct early_suspend early_suspend;
struct wake_lock idle_lock;
@@ -195,6 +240,9 @@ struct s3cfb_global {
atomic_t busfreq_lock_cnt; /* Bus frequency Lock count */
int busfreq_flag; /* context bus frequency flag*/
#endif
+#ifdef CONFIG_FB_S5P_SYSMMU
+ struct sysmmu_flag sysmmu;
+#endif
};
struct s3cfb_window {
@@ -232,6 +280,61 @@ struct s3cfb_user_chroma {
unsigned char blue;
};
+enum s3c_fb_pixel_format {
+ S3C_FB_PIXEL_FORMAT_RGBA_8888 = 0,
+ S3C_FB_PIXEL_FORMAT_RGB_888 = 1,
+ S3C_FB_PIXEL_FORMAT_BGRA_8888 = 2,
+ S3C_FB_PIXEL_FORMAT_RGB_565 = 3,
+ S3C_FB_PIXEL_FORMAT_RGBX_8888 = 4,
+ S3C_FB_PIXEL_FORMAT_RGBA_5551 = 5,
+ S3C_FB_PIXEL_FORMAT_RGBA_4444 = 6,
+ S3C_FB_PIXEL_FORMAT_MAX = 7,
+};
+
+struct s3c_fb_win_config {
+ enum {
+ S3C_FB_WIN_STATE_DISABLED = 0,
+ S3C_FB_WIN_STATE_COLOR,
+ S3C_FB_WIN_STATE_BUFFER,
+ } state;
+
+ union {
+ __u32 color;
+ struct {
+ int fd;
+ __u32 phys_addr;
+ __u32 virt_addr;
+ __u32 offset;
+ __u32 stride;
+ enum s3c_fb_pixel_format format;
+ };
+ };
+
+ int x;
+ int y;
+ __u32 w;
+ __u32 h;
+};
+
+struct s3c_fb_win_config_data {
+ int fence;
+ struct s3c_fb_win_config config[S3C_FB_MAX_WIN];
+};
+
+struct s3c_reg_data {
+ struct list_head list;
+ u32 shadowcon;
+ u32 wincon[S3C_FB_MAX_WIN];
+ u32 winmap[S3C_FB_MAX_WIN];
+ u32 vidosd_a[S3C_FB_MAX_WIN];
+ u32 vidosd_b[S3C_FB_MAX_WIN];
+ u32 vidosd_c[S3C_FB_MAX_WIN];
+ u32 vidosd_d[S3C_FB_MAX_WIN];
+ u32 vidw_buf_start[S3C_FB_MAX_WIN];
+ u32 vidw_buf_end[S3C_FB_MAX_WIN];
+ u32 vidw_buf_size[S3C_FB_MAX_WIN];
+};
+
#define BLENDING_NONE 0x0100
#define BLENDING_PREMULT 0x0105
#define BLENDING_COVERAGE 0x0405
@@ -245,6 +348,8 @@ struct s3cfb_user_chroma {
struct s3cfb_user_chroma)
#define S3CFB_SET_VSYNC_INT _IOW('F', 206, u32)
#define S3CFB_GET_VSYNC_INT_STATUS _IOR('F', 207, u32)
+#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, struct s3c_fb_user_ion_client)
+#define S3CFB_WIN_CONFIG _IOW('F', 209, struct s3c_fb_win_config_data)
#define S3CFB_GET_LCD_WIDTH _IOR('F', 302, int)
#define S3CFB_GET_LCD_HEIGHT _IOR('F', 303, int)
#define S3CFB_SET_WRITEBACK _IOW('F', 304, u32)
@@ -342,8 +447,17 @@ extern int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, int id);
extern int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id);
extern int s3cfb_channel_localpath_on(struct s3cfb_global *ctrl, int id);
extern int s3cfb_channel_localpath_off(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_vsync_int(struct fb_info *info, bool active);
extern int s3cfb_check_vsync_status(struct s3cfb_global *ctrl);
extern int s3cfb_set_dualrgb(struct s3cfb_global *ctrl, int mode);
+extern int s3cfb_set_window_protect(struct s3cfb_global *ctrl, int id, bool protect);
+extern void s3c_fb_update_regs(struct s3cfb_global *fbdev, struct s3c_reg_data *regs);
+#ifdef CONFIG_FB_S5P_SYSMMU
+extern void s3cfb_clean_outer_pagetable(unsigned long vaddr, size_t size);
+#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+extern int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev, u32 timeout);
+#endif
#ifdef CONFIG_FB_S5P_MIPI_DSIM
extern int s3cfb_vsync_status_check(void);
#endif
diff --git a/drivers/video/samsung/s3cfb_ea8061.c b/drivers/video/samsung/s3cfb_ea8061.c
new file mode 100644
index 0000000..5edeaaf
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ea8061.c
@@ -0,0 +1,1289 @@
+/* linux/drivers/video/samsung/s3cfb_ea8061.c
+ *
+ * MIPI-DSI based AMS555HBxx AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-dsim.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "s5p-dsim.h"
+#include "s3cfb.h"
+#include "ea8061_param.h"
+
+#define SMART_DIMMING
+#undef SMART_DIMMING_DEBUG
+
+#ifdef SMART_DIMMING
+#include "smart_dimming_ea8061.h"
+#include "aid_ea8061.h"
+#endif
+
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 130
+#define DEFAULT_GAMMA_LEVEL GAMMA_130CD
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+#ifdef SMART_DIMMING
+#define LDI_MTP_LENGTH 32
+#define LDI_MTP_ADDR 0xDA
+#endif
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int current_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+ unsigned char id[LDI_ID_LEN];
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+#ifdef SMART_DIMMING
+ struct str_smart_dim smart;
+ unsigned char b3[GAMMA_MAX][ARRAY_SIZE(SEQ_LTPS_AID)];
+#endif
+ unsigned int irq;
+ unsigned int connected;
+
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
+
+ struct dsim_global *dsim;
+};
+
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 102, 104, 106, 108,
+ 110, 120, 130, 140, 150, 160, 170, 180,
+ 182, 184, 186, 188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+#ifdef SMART_DIMMING
+static unsigned int aid_candela_table[GAMMA_MAX] = {
+ base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100,
+ AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150,
+ AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180, AOR40_BASE_182, AOR40_BASE_184,
+ AOR40_BASE_186, AOR40_BASE_188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+#endif
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->oled_detection_count, oled_det_level);
+
+ if (!oled_det_level) {
+ if (lcd->oled_detection_count < 10) {
+ schedule_delayed_work(&lcd->oled_detection, HZ/8);
+ lcd->oled_detection_count++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int _ea8061_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+ int ret = 0;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int ea8061_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int ret = 0;
+ int retry_cnt = 1;
+
+retry:
+ ret = _ea8061_write(lcd, seq, len);
+ if (!ret) {
+ if (retry_cnt) {
+ dev_dbg(&lcd->ld->dev, "%s :: retry: %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto retry;
+ } else
+ dev_dbg(&lcd->ld->dev, "%s :: 0x%02x\n", __func__, seq[1]);
+ }
+
+ return ret;
+}
+
+static int _ea8061_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+{
+ int ret = 0;
+
+ if (!lcd->connected)
+ return ret;
+
+ mutex_lock(&lcd->lock);
+
+ if (lcd->dsim->ops->cmd_dcs_read)
+ ret = lcd->dsim->ops->cmd_dcs_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int ea8061_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+retry:
+ ret = _ea8061_read(lcd, addr, count, buf);
+ if (!ret) {
+ if (retry_cnt) {
+ dev_dbg(&lcd->ld->dev, "%s :: retry: %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto retry;
+ } else
+ dev_dbg(&lcd->ld->dev, "%s :: 0x%02x\n", __func__, addr);
+ }
+
+ return ret;
+}
+
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_20CD;
+ break;
+ case 30 ... 39:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 40 ... 49:
+ backlightlevel = GAMMA_40CD;
+ break;
+ case 50 ... 59:
+ backlightlevel = GAMMA_50CD;
+ break;
+ case 60 ... 69:
+ backlightlevel = GAMMA_60CD;
+ break;
+ case 70 ... 79:
+ backlightlevel = GAMMA_70CD;
+ break;
+ case 80 ... 89:
+ backlightlevel = GAMMA_80CD;
+ break;
+ case 90 ... 99:
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 101:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 102 ... 103:
+ backlightlevel = GAMMA_102CD;
+ break;
+ case 104 ... 105:
+ backlightlevel = GAMMA_104CD;
+ break;
+ case 106 ... 107:
+ backlightlevel = GAMMA_106CD;
+ break;
+ case 108 ... 109:
+ backlightlevel = GAMMA_108CD;
+ break;
+ case 110 ... 119:
+ backlightlevel = GAMMA_110CD;
+ break;
+ case 120 ... 129:
+ backlightlevel = GAMMA_120CD;
+ break;
+ case 130 ... 139:
+ backlightlevel = GAMMA_130CD;
+ break;
+ case 140 ... 149:
+ backlightlevel = GAMMA_140CD;
+ break;
+ case 150 ... 159:
+ backlightlevel = GAMMA_150CD;
+ break;
+ case 160 ... 169:
+ backlightlevel = GAMMA_160CD;
+ break;
+ case 170 ... 179:
+ backlightlevel = GAMMA_170CD;
+ break;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
+ break;
+ case 190 ... 199:
+ backlightlevel = GAMMA_190CD;
+ break;
+ case 200 ... 209:
+ backlightlevel = GAMMA_200CD;
+ break;
+ case 210 ... 219:
+ backlightlevel = GAMMA_210CD;
+ break;
+ case 220 ... 229:
+ backlightlevel = GAMMA_220CD;
+ break;
+ case 230 ... 239:
+ backlightlevel = GAMMA_230CD;
+ break;
+ case 240 ... 249:
+ backlightlevel = GAMMA_240CD;
+ break;
+ case 250 ... 254:
+ backlightlevel = GAMMA_250CD;
+ break;
+ case 255:
+ backlightlevel = GAMMA_300CD;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+#ifdef SMART_DIMMING
+static int ea8061_aid_parameter_ctl(struct lcd_info *lcd, u8 force)
+{
+ if (force)
+ goto aor_update;
+ else if (aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0])
+ goto aor_update;
+ else if (aid_command_table[lcd->bl][1] != aid_command_table[lcd->current_bl][1])
+ goto aor_update;
+ else
+ goto exit;
+
+aor_update:
+ ea8061_write(lcd, lcd->b3[lcd->bl], AID_PARAM_SIZE);
+
+exit:
+ return 0;
+}
+#endif
+
+static int ea8061_gamma_ctl(struct lcd_info *lcd)
+{
+ /* ea8061_write(lcd, SEQ_APPLY_LEVEL_2_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY_ENABLE)); */
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY));
+ ea8061_write(lcd, lcd->gamma_table[lcd->bl], GAMMA_PARAM_SIZE-1);
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY2, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY2));
+
+ return 0;
+}
+
+static int ea8061_set_acl(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 29:
+ level = ACL_STATUS_0P;
+ break;
+ case 30 ... 39:
+ level = ACL_STATUS_33P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
+ }
+
+ if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5))
+ level = ACL_STATUS_0P;
+
+ if (force || lcd->current_acl != ACL_CUTOFF_TABLE[level][1]) {
+ ret = ea8061_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = ACL_CUTOFF_TABLE[level][1];
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ }
+
+ if (ret)
+ ret = -EPERM;
+
+ return ret;
+}
+
+static int ea8061_set_elvss(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 49:
+ elvss_level = ELVSS_STATUS_20;
+ break;
+ case 50 ... 79:
+ elvss_level = ELVSS_STATUS_50;
+ break;
+ case 80 ... 99:
+ elvss_level = ELVSS_STATUS_80;
+ break;
+ case 100 ... 109:
+ elvss_level = ELVSS_STATUS_100;
+ break;
+ case 110 ... 119:
+ elvss_level = ELVSS_STATUS_110;
+ break;
+ case 120 ... 129:
+ elvss_level = ELVSS_STATUS_120;
+ break;
+ case 130 ... 139:
+ elvss_level = ELVSS_STATUS_130;
+ break;
+ case 140 ... 149:
+ elvss_level = ELVSS_STATUS_140;
+ break;
+ case 150 ... 159:
+ elvss_level = ELVSS_STATUS_150;
+ break;
+ case 160 ... 169:
+ elvss_level = ELVSS_STATUS_160;
+ break;
+ case 170 ... 179:
+ elvss_level = ELVSS_STATUS_170;
+ break;
+ case 180 ... 189:
+ elvss_level = ELVSS_STATUS_180;
+ break;
+ case 190 ... 199:
+ elvss_level = ELVSS_STATUS_190;
+ break;
+ case 200 ... 209:
+ elvss_level = ELVSS_STATUS_200;
+ break;
+ case 210 ... 219:
+ elvss_level = ELVSS_STATUS_210;
+ break;
+ case 220 ... 229:
+ elvss_level = ELVSS_STATUS_220;
+ break;
+ case 230 ... 239:
+ elvss_level = ELVSS_STATUS_230;
+ break;
+ case 240 ... 250:
+ elvss_level = ELVSS_STATUS_240;
+ break;
+ case 299:
+ elvss_level = ELVSS_STATUS_300;
+ break;
+ }
+
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][1]) {
+ ret = ea8061_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][1];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n", lcd->elvss_table[elvss_level][1]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+
+static int init_elvss_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+#ifdef SMART_DIMMING_DEBUG
+ int j;
+#endif
+ lcd->elvss_table = (unsigned char **)ELVSS_CONTROL_TABLE;
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+
+err_alloc_elvss:
+ while (i > 0) {
+ kfree(lcd->elvss_table[i-1]);
+ i--;
+ }
+ kfree(lcd->elvss_table);
+err_alloc_elvss_table:
+ return ret;
+}
+
+#ifdef SMART_DIMMING
+static int init_gamma_table(struct lcd_info *lcd , const u8 *mtp_data)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xCA;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+
+ if (candela_table[i] == 20)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_21, mtp_data);
+ else if (candela_table[i] == 30)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_213, mtp_data);
+ else if (candela_table[i] == 40)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_215, mtp_data);
+ else if (candela_table[i] == 50)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_218, mtp_data);
+ else if (candela_table[i] == 60)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else if (candela_table[i] == 70)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 80)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 90)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 100)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if (candela_table[i] == 102)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 104)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 106)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 108)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 182)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 184)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 186)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 188)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 190)
+ calc_gamma_table_190_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if ((candela_table[i] > 190) && (candela_table[i] < MAX_GAMMA-1))
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225 , mtp_data);
+ else if (candela_table[i] == MAX_GAMMA-1)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+
+static int init_aid_dimming_table(struct lcd_info *lcd)
+{
+ unsigned int i, j, c;
+ u16 reverse_seq[] = {0, 28, 29, 30, 31, 32, 33, 25, 26, 27, 22, 23, 24, 19, 20, 21, 16, 17, 18, 13, 14, 15, 10, 11, 12, 7, 8, 9, 4, 5, 6, 1, 2, 3};
+ u16 temp[GAMMA_PARAM_SIZE];
+
+ if ((lcd->id[1] == 0x12) || (lcd->id[1] == 0x16)) {
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table_SM2); i++) {
+ j = (aid_rgb_fix_table_SM2[i].gray * 3 + aid_rgb_fix_table_SM2[i].rgb) + 1;
+ c = lcd->gamma_table[aid_rgb_fix_table_SM2[i].candela_idx][j] + aid_rgb_fix_table_SM2[i].offset;
+ if (c > 0xff)
+ lcd->gamma_table[aid_rgb_fix_table_SM2[i].candela_idx][j] = 0xff;
+ else
+ lcd->gamma_table[aid_rgb_fix_table_SM2[i].candela_idx][j] += aid_rgb_fix_table_SM2[i].offset;
+ }
+ }
+
+ if (lcd->id[1] == 0x13) {
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table_M4); i++) {
+ j = (aid_rgb_fix_table_M4[i].gray * 3 + aid_rgb_fix_table_M4[i].rgb) + 1;
+ c = lcd->gamma_table[aid_rgb_fix_table_M4[i].candela_idx][j] + aid_rgb_fix_table_M4[i].offset;
+ if (c > 0xff)
+ lcd->gamma_table[aid_rgb_fix_table_M4[i].candela_idx][j] = 0xff;
+ else
+ lcd->gamma_table[aid_rgb_fix_table_M4[i].candela_idx][j] += aid_rgb_fix_table_M4[i].offset;
+ }
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ memcpy(lcd->b3[i], SEQ_LTPS_AID, AID_PARAM_SIZE);
+ lcd->b3[i][0x02] = aid_command_table[i][1];
+ lcd->b3[i][0x01] = aid_command_table[i][0];
+ }
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+ printk("\n");
+#endif
+
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ temp[j] = lcd->gamma_table[i][reverse_seq[j]];
+
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ lcd->gamma_table[i][j] = temp[j];
+
+ lcd->gamma_table[i][31] = lcd->smart.default_gamma[31]<<4|lcd->smart.default_gamma[30];
+ /*default_gamma 30,31th range 0000~1111 */
+ /*31,30th gamma need to reverse order , because of normal order is R,G,B
+ but Magna DDI VT G,R,B so R,G order change to G,R order*/
+ lcd->gamma_table[i][32] = lcd->smart.default_gamma[32];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE-1; j++)
+ printk("0x%x,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+}
+#endif
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+
+ ea8061_gamma_ctl(lcd);
+
+ ea8061_aid_parameter_ctl(lcd, force);
+
+ ea8061_set_acl(lcd, force);
+
+ ea8061_set_elvss(lcd, force);
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n", brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int slew_rev_control_set(struct lcd_info *lcd)
+{
+ if (lcd->id[2] == 0x00)
+ ea8061_write(lcd, SEQ_SLEW_REV00, ARRAY_SIZE(SEQ_SLEW_REV00));
+ else if (lcd->id[2] == 0x01)
+ ea8061_write(lcd, SEQ_SLEW_REV01, ARRAY_SIZE(SEQ_SLEW_REV01));
+ else if (lcd->id[2] == 0x02)
+ ea8061_write(lcd, SEQ_SLEW_REV02, ARRAY_SIZE(SEQ_SLEW_REV02));
+ else if (lcd->id[2] == 0x03)
+ ea8061_write(lcd, SEQ_SLEW_REV03, ARRAY_SIZE(SEQ_SLEW_REV03));
+ else
+ ea8061_write(lcd, SEQ_SLEW_REV04, ARRAY_SIZE(SEQ_SLEW_REV04));
+ return 0;
+}
+
+static int ea8061_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+ ea8061_write(lcd, SEQ_APPLY_LEVEL_2_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY_ENABLE));
+ ea8061_write(lcd, SEQ_APPLY_LEVEL_3_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY));
+ if (lcd->id[1] == 0x13) { /* M4 */
+ ea8061_write(lcd, SEQ_M4_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_M4_PANEL_CONDITION_SET));
+ ea8061_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+/* ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY));
+ ea8061_write(lcd, SEQ_M4_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_M4_GAMMA_CONDITION_SET));
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY2, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY2)); */
+ ea8061_gamma_ctl(lcd);
+ ea8061_write(lcd, SEQ_LTPS_AID, ARRAY_SIZE(SEQ_LTPS_AID));
+ ea8061_write(lcd, ELVSS_CONTROL_SET, ARRAY_SIZE(ELVSS_CONTROL_SET));
+ ea8061_write(lcd, SEQ_ETC_WCABC_CONTROL, ARRAY_SIZE(SEQ_ETC_WCABC_CONTROL));
+ ea8061_write(lcd, SEQ_M4_SLEW, ARRAY_SIZE(SEQ_M4_SLEW));
+ } else { /* SM2 */
+ ea8061_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ ea8061_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+/* ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY));
+ ea8061_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY2, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY2)); */
+ ea8061_gamma_ctl(lcd);
+ ea8061_write(lcd, SEQ_LTPS_AID, ARRAY_SIZE(SEQ_LTPS_AID));
+ ea8061_write(lcd, ELVSS_CONTROL_SET, ARRAY_SIZE(ELVSS_CONTROL_SET));
+ ea8061_write(lcd, SEQ_ETC_WCABC_CONTROL, ARRAY_SIZE(SEQ_ETC_WCABC_CONTROL));
+ slew_rev_control_set(lcd);
+ }
+
+ ea8061_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+
+ return ret;
+}
+
+static int ea8061_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ ea8061_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int ea8061_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ ea8061_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+
+ msleep(35);
+
+ ea8061_write(lcd, SEQ_SLEEP_IN, ARRAY_SIZE(SEQ_SLEEP_IN));
+
+ msleep(100);
+
+ return ret;
+}
+
+static int ea8061_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ret = ea8061_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = ea8061_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int ea8061_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = ea8061_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int ea8061_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = ea8061_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = ea8061_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int ea8061_set_power(struct lcd_device *ld, int power)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(&lcd->ld->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return ea8061_power(lcd, power);
+}
+
+static int ea8061_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+
+static int ea8061_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n", __func__, brightness); */
+
+ if (brightness < MIN_BRIGHTNESS ||
+ brightness > bd->props.max_brightness) {
+ dev_err(&bd->dev, "lcd brightness should be %d to %d. now %d\n",
+ MIN_BRIGHTNESS, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int ea8061_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static int ea8061_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static struct lcd_ops ea8061_lcd_ops = {
+ .set_power = ea8061_set_power,
+ .get_power = ea8061_get_power,
+ .check_fb = ea8061_check_fb,
+};
+
+static const struct backlight_ops ea8061_backlight_ops = {
+ .get_brightness = ea8061_get_brightness,
+ .update_status = ea8061_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "SMD_AMS555HBxx\n");
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t window_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[15];
+
+ sprintf(temp, "%x %x %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(window_type, 0444, window_type_show, NULL);
+
+static ssize_t gamma_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int i, j;
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+
+ return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct lcd_info *g_lcd;
+
+void ea8061_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+
+ ea8061_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void ea8061_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ ea8061_power(lcd, FB_BLANK_UNBLANK);
+
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+
+static void ea8061_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+ unsigned char wbuf[] = {0xFD, LDI_ID_REG};
+
+ ea8061_write(lcd, wbuf, ARRAY_SIZE(wbuf));
+
+ ret = ea8061_read(lcd, 0xFE, LDI_ID_LEN, buf, 2);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+#ifdef SMART_DIMMING
+static int ea8061_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret;
+
+ unsigned char wbuf[] = {0xFD, LDI_MTP_ADDR};
+
+ ea8061_write(lcd, wbuf, ARRAY_SIZE(wbuf));
+
+ ret = ea8061_read(lcd, 0xFE, LDI_MTP_LENGTH, mtp_data, 1);
+ return ret;
+}
+#endif
+
+static int ea8061_probe(struct device *dev)
+{
+ int ret = 0, i;
+ struct lcd_info *lcd;
+
+#ifdef SMART_DIMMING
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+#endif
+
+ lcd = kzalloc(sizeof(struct lcd_info), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ g_lcd = lcd;
+
+ lcd->ld = lcd_device_register("panel", dev, lcd, &ea8061_lcd_ops);
+ if (IS_ERR(lcd->ld)) {
+ pr_err("failed to register lcd device\n");
+ ret = PTR_ERR(lcd->ld);
+ goto out_free_lcd;
+ }
+
+ lcd->bd = backlight_device_register("panel", dev, lcd, &ea8061_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+ lcd->acl_enable = 0;
+ lcd->current_acl = 0;
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_window_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_gamma_table);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ ea8061_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ dev_info(&lcd->ld->dev, "%s lcd panel driver has been probed.\n", dev_name(dev));
+
+#ifdef SMART_DIMMING
+ for (i = 0; i < LDI_ID_LEN; i++)
+ lcd->smart.panelid[i] = lcd->id[i];
+
+ init_table_info_ea8061(&lcd->smart);
+
+ ret = ea8061_read_mtp(lcd, mtp_data);
+/*
+ for (i = 0; i < LDI_MTP_LENGTH ; i++)
+ printk(" %dth mtp value is %x\n", i, mtp_data[i]);
+*/
+ if (!ret)
+ printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
+
+ calc_voltage_table_ea8061(&lcd->smart, mtp_data);
+
+ ret = init_elvss_table(lcd);
+ ret += init_gamma_table(lcd, mtp_data);
+ ret += init_aid_dimming_table(lcd);
+
+ if (ret)
+ printk(KERN_ERR "gamma table generation is failed\n");
+
+ update_brightness(lcd, 1);
+#endif
+
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = ea8061_early_suspend;
+ lcd_late_resume = ea8061_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit ea8061_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ ea8061_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void ea8061_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ea8061_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver ea8061_mipi_driver = {
+ .name = "ea8061",
+ .probe = ea8061_probe,
+ .remove = __devexit_p(ea8061_remove),
+ .shutdown = ea8061_shutdown,
+};
+
+static int ea8061_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&ea8061_mipi_driver);
+}
+
+static void ea8061_exit(void)
+{
+ return;
+}
+
+module_init(ea8061_init);
+module_exit(ea8061_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI EA8061:AMS555HBXX (720x1280) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_fimd6x.c b/drivers/video/samsung/s3cfb_fimd6x.c
index 71a24ae..02c75e6 100644
--- a/drivers/video/samsung/s3cfb_fimd6x.c
+++ b/drivers/video/samsung/s3cfb_fimd6x.c
@@ -22,6 +22,11 @@
#include "s3cfb.h"
+#ifdef CONFIG_FB_S5P_SYSMMU
+#include <asm/cacheflush.h>
+#include <plat/s5p-sysmmu.h>
+#endif
+
void s3cfb_check_line_count(struct s3cfb_global *ctrl)
{
int timeout = 30 * 5300;
@@ -111,6 +116,12 @@ int s3cfb_set_output(struct s3cfb_global *ctrl)
return -EINVAL;
}
+#if defined(CONFIG_FB_RGBA_ORDER)
+ /* Change format to BGR order */
+ cfg &= ~(0x3F0000);
+ cfg |= 0x240000;
+#endif
+
writel(cfg, ctrl->regs + S3C_VIDCON2);
if (ctrl->output == OUTPUT_I80LDI0) {
@@ -210,7 +221,7 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl)
S3C_VIDCON0_VCLKEN_FREERUN);
src_clk = clk_get_rate(ctrl->clock);
- printk(KERN_DEBUG "FIMD src sclk = %d\n", src_clk);
+ dev_dbg(ctrl->dev, "FIMD src sclk = %d\n", src_clk);
} else {
cfg &= ~(S3C_VIDCON0_CLKSEL_MASK |
S3C_VIDCON0_CLKVALUP_MASK |
@@ -223,12 +234,12 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl)
if (strcmp(pdata->clk_name, "sclk_fimd") == 0) {
cfg |= S3C_VIDCON0_CLKSEL_SCLK;
src_clk = clk_get_rate(ctrl->clock);
- printk(KERN_DEBUG "FIMD src sclk = %d\n", src_clk);
+ dev_dbg(ctrl->dev, "FIMD src sclk = %d\n", src_clk);
} else {
cfg |= S3C_VIDCON0_CLKSEL_HCLK;
src_clk = ctrl->clock->parent->rate;
- printk(KERN_DEBUG "FIMD src hclk = %d\n", src_clk);
+ dev_dbg(ctrl->dev, "FIMD src hclk = %d\n", src_clk);
}
}
@@ -555,6 +566,23 @@ int s3cfb_win_map_off(struct s3cfb_global *ctrl, int id)
return 0;
}
+int s3cfb_set_window_protect(struct s3cfb_global *ctrl, int id, bool protect)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 shw;
+
+ if ((pdata->hw_ver == 0x62) || (pdata->hw_ver == 0x70)) {
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ if (protect)
+ shw |= S3C_WINSHMAP_PROTECT(id);
+ else
+ shw &= ~(S3C_WINSHMAP_PROTECT(id));
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ return 0;
+}
+
int s3cfb_set_window_control(struct s3cfb_global *ctrl, int id)
{
struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
@@ -677,6 +705,38 @@ int s3cfb_get_win_cur_buf_addr(struct s3cfb_global *ctrl, int id)
return start_addr;
}
+#ifdef CONFIG_FB_S5P_SYSMMU
+#define LV1_SHIFT 20
+#define LV1_PT_SIZE SZ_1M
+#define LV2_PT_SIZE SZ_1K
+#define LV2_BASE_MASK 0x3ff
+
+void s3cfb_clean_outer_pagetable(unsigned long vaddr, size_t size)
+{
+ unsigned long *pgd;
+ unsigned long *lv1, *lv1end;
+ unsigned long lv2pa;
+
+ if (!current->mm)
+ return;
+
+ pgd = (unsigned long *)current->mm->pgd;
+
+ lv1 = pgd + (vaddr >> LV1_SHIFT);
+ lv1end = pgd + ((vaddr + size + LV1_PT_SIZE-1) >> LV1_SHIFT);
+
+ /* clean level1 page table */
+ outer_clean_range(virt_to_phys(lv1), virt_to_phys(lv1end));
+
+ do {
+ lv2pa = *lv1 & ~LV2_BASE_MASK; /* lv2 pt base */
+ /* clean level2 page table */
+ outer_clean_range(lv2pa, lv2pa + LV2_PT_SIZE);
+ lv1++;
+ } while (lv1 != lv1end);
+}
+#endif
+
int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id)
{
struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
diff --git a/drivers/video/samsung/s3cfb_ielcd.c b/drivers/video/samsung/s3cfb_ielcd.c
index b86d6f5..f8c90d2 100644
--- a/drivers/video/samsung/s3cfb_ielcd.c
+++ b/drivers/video/samsung/s3cfb_ielcd.c
@@ -59,7 +59,7 @@ int s3c_ielcd_hw_init(void)
return -ENOENT;
}
- printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_ielcd_base);
+ /* printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_ielcd_base); */
ielcd_fbdev = &ielcd_fb;
diff --git a/drivers/video/samsung/s3cfb_lms501xx.c b/drivers/video/samsung/s3cfb_lms501xx.c
new file mode 100644
index 0000000..c57a8be
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_lms501xx.c
@@ -0,0 +1,737 @@
+/* linux/drivers/video/samsung/s3cfb_lms501xx.c
+ *
+ * MIPI-DSI based LMS501XX TFT lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-dsim.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "s5p-dsim.h"
+#include "s3cfb.h"
+#include "lms501xx.h"
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 255
+#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_GAMMA_LEVEL GAMMA_160CD
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int current_cabc;
+ unsigned int current_bl;
+
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+
+ unsigned char id[LDI_ID_LEN];
+
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+
+ unsigned int irq;
+ unsigned int connected;
+
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
+ struct dsim_global *dsim;
+};
+
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
+ 130, 140, 150, 160, 170, 180, 190, 200, 210, 220,
+ 230, 240, 250, MAX_GAMMA
+};
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n",
+ __func__, lcd->oled_detection_count, oled_det_level);
+
+ if (!oled_det_level) {
+ if (lcd->oled_detection_count < 10) {
+ schedule_delayed_work(&lcd->oled_detection, HZ/8);
+ lcd->oled_detection_count++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int lms501xx_write(struct lcd_info *lcd,
+ const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ lcd->dsim->ops->cmd_write(lcd->dsim,
+ DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ lcd->dsim->ops->cmd_write(lcd->dsim,
+ DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ lcd->dsim->ops->cmd_write(lcd->dsim,
+ DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+static int _lms501xx_read(struct lcd_info *lcd,
+ const u8 addr, u16 count, u8 *buf)
+{
+ int ret = 0;
+
+ if (!lcd->connected)
+ return ret;
+
+ mutex_lock(&lcd->lock);
+
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int lms501xx_read(struct lcd_info *lcd,
+ const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _lms501xx_read(lcd, addr, count, buf);
+ if (!ret) {
+ if (retry_cnt) {
+ printk(KERN_WARNING
+ "[WARN:LCD] %s : retry cnt : %d\n",
+ __func__, retry_cnt);
+ retry_cnt--;
+ goto read_retry;
+ } else
+ printk(KERN_ERR
+ "[ERROR:LCD] %s : 0x%02x read failed\n",
+ __func__, addr);
+ }
+
+ return ret;
+}
+
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 30 ... 254:
+ backlightlevel = (brightness - candela_table[0]) / 10;
+ break;
+ case 255:
+ backlightlevel = ARRAY_SIZE(candela_table) - 1;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+static int lms501xx_gamma_ctl(struct lcd_info *lcd)
+{
+ SEQ_SET_BL[1] = candela_table[lcd->bl];
+ lms501xx_write(lcd, SEQ_SET_BL, ARRAY_SIZE(SEQ_SET_BL));
+ lms501xx_write(lcd, SEQ_SET_DISP, ARRAY_SIZE(SEQ_SET_DISP));
+ return 0;
+}
+
+static int lms501xx_set_cabc(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s - %d\n", __func__, lcd->current_cabc);
+ if (lcd->current_cabc)
+ lms501xx_write(lcd,
+ SEQ_SET_CABC_ON, ARRAY_SIZE(SEQ_SET_CABC_ON));
+ else
+ lms501xx_write(lcd,
+ SEQ_SET_CABC_OFF, ARRAY_SIZE(SEQ_SET_CABC_OFF));
+
+ mdelay(5);
+
+ return ret;
+}
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+
+ lms501xx_gamma_ctl(lcd);
+ lms501xx_set_cabc(lcd);
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n",
+ brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int lms501xx_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lms501xx_write(lcd, SEQ_SET_EXTC, ARRAY_SIZE(SEQ_SET_EXTC));
+ mdelay(5);
+ lms501xx_write(lcd, SEQ_SET_MIPI_DSI, ARRAY_SIZE(SEQ_SET_MIPI_DSI));
+ lms501xx_write(lcd, SEQ_SET_GIP, ARRAY_SIZE(SEQ_SET_GIP));
+ lms501xx_write(lcd, SEQ_SET_POWER, ARRAY_SIZE(SEQ_SET_POWER));
+ mdelay(5);
+ lms501xx_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(125);
+ lms501xx_write(lcd, SEQ_SET_RGB, ARRAY_SIZE(SEQ_SET_RGB));
+ lms501xx_write(lcd, SEQ_SET_CYC, ARRAY_SIZE(SEQ_SET_CYC));
+ lms501xx_write(lcd, SEQ_SET_VCOM, ARRAY_SIZE(SEQ_SET_VCOM));
+ lms501xx_write(lcd, SEQ_SET_PTBA, ARRAY_SIZE(SEQ_SET_PTBA));
+ lms501xx_write(lcd, SEQ_SET_PANEL, ARRAY_SIZE(SEQ_SET_PANEL));
+ lms501xx_write(lcd, SEQ_SET_DGC, ARRAY_SIZE(SEQ_SET_DGC));
+ lms501xx_write(lcd, SEQ_SET_STBA, ARRAY_SIZE(SEQ_SET_STBA));
+ lms501xx_write(lcd, SEQ_SET_EQ, ARRAY_SIZE(SEQ_SET_EQ));
+ lms501xx_write(lcd, SEQ_SET_VCOM_POWER, ARRAY_SIZE(SEQ_SET_VCOM_POWER));
+ lms501xx_write(lcd, SEQ_SET_ECO, ARRAY_SIZE(SEQ_SET_ECO));
+ lms501xx_write(lcd, SEQ_SET_GAMMA, ARRAY_SIZE(SEQ_SET_GAMMA));
+ lms501xx_write(lcd, SEQ_SET_CABC_PWM, ARRAY_SIZE(SEQ_SET_CABC_PWM));
+
+ return ret;
+}
+
+static int lms501xx_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ lms501xx_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+ msleep(100);
+
+ return ret;
+}
+
+static int lms501xx_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ lms501xx_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ lms501xx_write(lcd, SEQ_SLEEP_IN, ARRAY_SIZE(SEQ_SLEEP_IN));
+
+ return ret;
+}
+
+static int lms501xx_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ret = lms501xx_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = lms501xx_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int lms501xx_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = lms501xx_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int lms501xx_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = lms501xx_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = lms501xx_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int lms501xx_set_power(struct lcd_device *ld, int power)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(&lcd->ld->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return lms501xx_power(lcd, power);
+}
+
+static int lms501xx_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int lms501xx_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static int lms501xx_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ if (brightness < MIN_BRIGHTNESS ||
+ brightness > bd->props.max_brightness) {
+ dev_err(&bd->dev, "lcd brightness should be %d to %d. now %d\n",
+ MIN_BRIGHTNESS, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int lms501xx_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static struct lcd_ops lms501xx_lcd_ops = {
+ .set_power = lms501xx_set_power,
+ .get_power = lms501xx_get_power,
+ .check_fb = lms501xx_check_fb,
+};
+
+static const struct backlight_ops lms501xx_backlight_ops = {
+ .get_brightness = lms501xx_get_brightness,
+ .update_status = lms501xx_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->current_cabc);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->current_cabc != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->current_cabc, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->current_cabc = value;
+ if (lcd->ldi_enable)
+ lms501xx_set_cabc(lcd);
+ mutex_unlock(&lcd->bl_lock);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "SMD_LMS501KF06\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 0);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644,
+ auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+struct lcd_info *g_lcd;
+
+void lms501xx_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+ lms501xx_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void lms501xx_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ lms501xx_power(lcd, FB_BLANK_UNBLANK);
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+static void lms501xx_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = lms501xx_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+static int lms501xx_probe(struct device *dev)
+{
+ int ret = 0;
+ struct lcd_info *lcd;
+
+ lcd = kzalloc(sizeof(struct lcd_info), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ g_lcd = lcd;
+
+ lcd->ld = lcd_device_register("panel", dev, lcd, &lms501xx_lcd_ops);
+ if (IS_ERR(lcd->ld)) {
+ pr_err("failed to register lcd device\n");
+ ret = PTR_ERR(lcd->ld);
+ goto out_free_lcd;
+ }
+
+ lcd->bd = backlight_device_register("panel",
+ dev, lcd, &lms501xx_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+ lcd->current_cabc = 0;
+
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev,
+ "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev,
+ "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev,
+ "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ dev_info(&lcd->ld->dev, "lms501xx lcd panel driver has been probed.\n");
+
+ update_brightness(lcd, 1);
+
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = lms501xx_early_suspend;
+ lcd_late_resume = lms501xx_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit lms501xx_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ lms501xx_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void lms501xx_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lms501xx_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver lms501xx_mipi_driver = {
+ .name = "lms501xx",
+ .probe = lms501xx_probe,
+ .remove = __devexit_p(lms501xx_remove),
+ .shutdown = lms501xx_shutdown,
+};
+
+static int lms501xx_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&lms501xx_mipi_driver);
+}
+
+static void lms501xx_exit(void)
+{
+ return;
+}
+
+module_init(lms501xx_init);
+module_exit(lms501xx_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI LMS501XX WVGA (480x800) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_main.c b/drivers/video/samsung/s3cfb_main.c
index 2cb7c86..a723306 100644
--- a/drivers/video/samsung/s3cfb_main.c
+++ b/drivers/video/samsung/s3cfb_main.c
@@ -29,7 +29,7 @@
#include <linux/memory.h>
#include <linux/pm_runtime.h>
#include <linux/delay.h>
-#include <linux/kthread.h>
+#include <linux/sw_sync.h>
#include <plat/clock.h>
#include <plat/media.h>
#include <mach/media.h>
@@ -58,11 +58,13 @@
#include <mach/regs-pmu.h>
#include <plat/regs-fb-s5p.h>
-extern int s3cfb_vsync_timestamp_changed(struct s3cfb_global *fbdev, ktime_t prev_timestamp);
+#ifdef CONFIG_FB_S5P_SYSMMU
+#include <plat/s5p-sysmmu.h>
+#endif
struct s3cfb_fimd_desc *fbfimd;
-inline struct s3cfb_global *get_fimd_global(int id)
+struct s3cfb_global *get_fimd_global(int id)
{
struct s3cfb_global *fbdev;
@@ -85,17 +87,57 @@ int s3cfb_vsync_status_check(void)
return 0;
}
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+static void s3cfb_activate_vsync(struct s3cfb_global *fbdev)
+{
+ int prev_refcount;
+
+ mutex_lock(&fbdev->vsync_info.irq_lock);
+ prev_refcount = fbdev->vsync_info.irq_refcount++;
+ if (!prev_refcount) {
+ s3cfb_set_global_interrupt(fbdev, 1);
+ s3cfb_set_vsync_interrupt(fbdev, 1);
+ }
+
+ mutex_unlock(&fbdev->vsync_info.irq_lock);
+}
+
+static void s3cfb_deactivate_vsync(struct s3cfb_global *fbdev)
+{
+ int new_refcount;
+
+ mutex_lock(&fbdev->vsync_info.irq_lock);
+
+ new_refcount = --fbdev->vsync_info.irq_refcount;
+ WARN_ON(new_refcount < 0);
+ if (!new_refcount) {
+ s3cfb_set_global_interrupt(fbdev, 0);
+ s3cfb_set_vsync_interrupt(fbdev, 0);
+ }
+
+ mutex_unlock(&fbdev->vsync_info.irq_lock);
+}
+#endif
+
static irqreturn_t s3cfb_irq_frame(int irq, void *dev_id)
{
struct s3cfb_global *fbdev[2];
fbdev[0] = fbfimd->fbdev[0];
+ spin_lock(&fbdev[0]->vsync_slock);
+
if (fbdev[0]->regs != 0)
s3cfb_clear_interrupt(fbdev[0]);
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ fbdev[0]->vsync_info.timestamp = ktime_get();
+ wake_up_interruptible_all(&fbdev[0]->vsync_info.wait);
+#endif
+
fbdev[0]->wq_count++;
- fbdev[0]->vsync_timestamp = ktime_get();
- wake_up_interruptible(&fbdev[0]->wq);
+ wake_up(&fbdev[0]->wq);
+
+ spin_unlock(&fbdev[0]->vsync_slock);
return IRQ_HANDLED;
}
@@ -113,6 +155,57 @@ static irqreturn_t s3cfb_irq_fifo(int irq, void *dev_id)
}
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+int s3cfb_set_vsync_int(struct fb_info *info, bool active)
+{
+ struct s3cfb_global *fbdev = fbfimd->fbdev[0];
+ bool prev_active = fbdev->vsync_info.active;
+
+ fbdev->vsync_info.active = active;
+
+ if (active && !prev_active)
+ s3cfb_activate_vsync(fbdev);
+ else if (!active && prev_active)
+ s3cfb_deactivate_vsync(fbdev);
+
+ return 0;
+}
+
+/**
+ * s3cfb_wait_for_vsync() - sleep until next VSYNC interrupt or timeout
+ * @sfb: main hardware state
+ * @timeout: timeout in msecs, or 0 to wait indefinitely.
+ */
+int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev, u32 timeout)
+{
+ ktime_t timestamp;
+ int ret;
+
+ pm_runtime_get_sync(fbdev->dev);
+
+ timestamp = fbdev->vsync_info.timestamp;
+ s3cfb_activate_vsync(fbdev);
+ if (timeout) {
+ ret = wait_event_interruptible_timeout(fbdev->vsync_info.wait,
+ !ktime_equal(timestamp,
+ fbdev->vsync_info.timestamp),
+ msecs_to_jiffies(timeout));
+ } else {
+ ret = wait_event_interruptible(fbdev->vsync_info.wait,
+ !ktime_equal(timestamp,
+ fbdev->vsync_info.timestamp));
+ }
+ s3cfb_deactivate_vsync(fbdev);
+
+ pm_runtime_put_sync(fbdev->dev);
+
+ if (timeout && ret == 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+#endif
+
int s3cfb_register_framebuffer(struct s3cfb_global *fbdev)
{
struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
@@ -322,30 +415,53 @@ void s3cfb_trigger(void)
EXPORT_SYMBOL(s3cfb_trigger);
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
static int s3cfb_wait_for_vsync_thread(void *data)
{
- struct s3cfb_global *fbdev = data;
-
- while (!kthread_should_stop()) {
- ktime_t prev_timestamp = fbdev->vsync_timestamp;
-
- int ret = wait_event_interruptible_timeout(fbdev->wq,
- s3cfb_vsync_timestamp_changed(fbdev, prev_timestamp),
- msecs_to_jiffies(100));
-
- if (ret > 0) {
- char *envp[2];
- char buf[64];
+ struct s3cfb_global *fbdev = data;
+
+ while (!kthread_should_stop()) {
+ ktime_t timestamp = fbdev->vsync_info.timestamp;
+ int ret = wait_event_interruptible_timeout(
+ fbdev->vsync_info.wait,
+ !ktime_equal(timestamp,
+ fbdev->vsync_info.timestamp) &&
+ fbdev->vsync_info.active,
+ msecs_to_jiffies(VSYNC_TIMEOUT_MSEC));
+
+ if (ret > 0) {
+ char *envp[2];
+ char buf[64];
+ snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ ktime_to_ns(fbdev->vsync_info.timestamp));
+ envp[0] = buf;
+ envp[1] = NULL;
+ kobject_uevent_env(&fbdev->dev->kobj, KOBJ_CHANGE,
+ envp);
+ }
+ }
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
- ktime_to_ns(fbdev->vsync_timestamp));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&fbdev->dev->kobj, KOBJ_CHANGE, envp);
- }
- }
+ return 0;
+}
+#endif
- return 0;
+static void s3c_fb_update_regs_handler(struct kthread_work *work)
+{
+ struct s3cfb_global *fbdev =
+ container_of(work, struct s3cfb_global, update_regs_work);
+ struct s3c_reg_data *data, *next;
+ struct list_head saved_list;
+
+ mutex_lock(&fbdev->update_regs_list_lock);
+ saved_list = fbdev->update_regs_list;
+ list_replace_init(&fbdev->update_regs_list, &saved_list);
+ mutex_unlock(&fbdev->update_regs_list_lock);
+
+ list_for_each_entry_safe(data, next, &saved_list, list) {
+ s3c_fb_update_regs(fbdev, data);
+ list_del(&data->list);
+ kfree(data);
+ }
}
static int s3cfb_probe(struct platform_device *pdev)
@@ -362,7 +478,13 @@ static int s3cfb_probe(struct platform_device *pdev)
/* enable the power domain */
pm_runtime_get_sync(&pdev->dev);
#endif
+
fbfimd = kzalloc(sizeof(struct s3cfb_fimd_desc), GFP_KERNEL);
+ if (!fbfimd) {
+ printk(KERN_ERR "failed to allocate for fimd fb descriptor\n");
+ ret = -ENOMEM;
+ goto err_fimd_desc;
+ }
if (FIMD_MAX == 2)
fbfimd->dual = 1;
@@ -418,9 +540,30 @@ static int s3cfb_probe(struct platform_device *pdev)
if (!fbdev[i]->regs) {
dev_err(fbdev[i]->dev, "failed to remap io region\n");
ret = -EINVAL;
- goto err1;
+ goto err_ioremap;
}
+ spin_lock_init(&fbdev[i]->vsync_slock);
+
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ INIT_LIST_HEAD(&fbdev[i]->update_regs_list);
+ mutex_init(&fbdev[i]->update_regs_list_lock);
+ init_kthread_worker(&fbdev[i]->update_regs_worker);
+
+ fbdev[i]->update_regs_thread = kthread_run(kthread_worker_fn,
+ &fbdev[i]->update_regs_worker, "s3c-fb");
+ if (IS_ERR(fbdev[i]->update_regs_thread)) {
+ int err = PTR_ERR(fbdev[i]->update_regs_thread);
+ fbdev[i]->update_regs_thread = NULL;
+
+ dev_err(fbdev[i]->dev, "failed to run update_regs thread\n");
+ return err;
+ }
+ init_kthread_work(&fbdev[i]->update_regs_work, s3c_fb_update_regs_handler);
+ fbdev[i]->timeline = sw_sync_timeline_create("s3c-fb");
+ fbdev[i]->timeline_max = 0;
+#endif
+
/* irq */
fbdev[i]->irq = platform_get_irq(pdev, 0);
if (request_irq(fbdev[i]->irq, s3cfb_irq_frame, IRQF_SHARED,
@@ -463,7 +606,7 @@ static int s3cfb_probe(struct platform_device *pdev)
/* register fb_info */
if (s3cfb_register_framebuffer(fbdev[i])) {
dev_err(fbdev[i]->dev, "register error fimd[%d]\n", i);
- return -EINVAL;
+ ret = -EINVAL;
goto err3;
}
@@ -506,6 +649,20 @@ static int s3cfb_probe(struct platform_device *pdev)
register_early_suspend(&fbdev[i]->early_suspend);
#endif
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ init_waitqueue_head(&fbdev[i]->vsync_info.wait);
+
+ /* Create vsync thread */
+ mutex_init(&fbdev[i]->vsync_info.irq_lock);
+
+ fbdev[i]->vsync_info.thread = kthread_run(
+ s3cfb_wait_for_vsync_thread,
+ fbdev[i], "s3c-fb-vsync");
+ if (fbdev[i]->vsync_info.thread == ERR_PTR(-ENOMEM)) {
+ dev_err(fbdev[i]->dev, "failed to run vsync thread\n");
+ fbdev[i]->vsync_info.thread = NULL;
+ }
+#endif
ret = device_create_file(fbdev[i]->dev, &dev_attr_fimd_dump);
if (ret < 0)
dev_err(fbdev[0]->dev, "failed to add sysfs entries\n");
@@ -524,12 +681,6 @@ static int s3cfb_probe(struct platform_device *pdev)
pdata->lcd_on(pdev);
#endif
- fbdev[0]->vsync_thread = kthread_run(s3cfb_wait_for_vsync_thread, fbdev[0], "s3cfb-vsync");
- if (fbdev[0]->vsync_thread == ERR_PTR(-ENOMEM)) {
- dev_err(fbdev[0]->dev, "failed to run vsync thread\n");
- fbdev[0]->vsync_thread = NULL;
- }
-
ret = device_create_file(&(pdev->dev), &dev_attr_win_power);
if (ret < 0)
dev_err(fbdev[0]->dev, "failed to add sysfs entries\n");
@@ -557,10 +708,18 @@ err3:
err2:
for (i = 0; i < FIMD_MAX; i++)
iounmap(fbdev[i]->regs);
+
+err_ioremap:
+ release_mem_region(res->start, res->end - res->start + 1);
+
err1:
- for (i = 0; i < FIMD_MAX; i++)
+ for (i = 0; i < FIMD_MAX; i++) {
pdata->clk_off(pdev, &fbdev[i]->clock);
+ kfree(fbfimd->fbdev[i]);
+ }
err0:
+ kfree(fbfimd);
+err_fimd_desc:
return ret;
}
@@ -600,9 +759,10 @@ static int s3cfb_remove(struct platform_device *pdev)
framebuffer_release(fb);
}
}
-
- if (fbdev[i]->vsync_thread)
- kthread_stop(fbdev[i]->vsync_thread);
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ if (fbdev[i]->vsync_info.thread)
+ kthread_stop(fbdev[i]->vsync_info.thread);
+#endif
kfree(fbdev[i]->fb);
kfree(fbdev[i]);
@@ -694,6 +854,9 @@ void s3cfb_lcd0_pmu_off(void)
#ifdef CONFIG_PM
#ifdef CONFIG_HAS_EARLYSUSPEND
+void (*lcd_early_suspend)(void);
+void (*lcd_late_resume)(void);
+
void s3cfb_early_suspend(struct early_suspend *h)
{
struct s3cfb_global *info = container_of(h, struct s3cfb_global, early_suspend);
@@ -705,11 +868,8 @@ void s3cfb_early_suspend(struct early_suspend *h)
printk(KERN_INFO "+%s\n", __func__);
#ifdef CONFIG_FB_S5P_MIPI_DSIM
-#if defined(CONFIG_FB_S5P_S6E63M0)
- s6e63m0_early_suspend();
-#else
- s6e8ax0_early_suspend();
-#endif
+ if (lcd_early_suspend)
+ lcd_early_suspend();
#endif
for (i = 0; i < FIMD_MAX; i++) {
@@ -765,8 +925,15 @@ void s3cfb_early_suspend(struct early_suspend *h)
pm_runtime_put_sync(&pdev->dev);
#endif
- printk(KERN_INFO "-%s\n", __func__);
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if (fbdev[0]->sysmmu.enabled == true) {
+ fbdev[0]->sysmmu.enabled = false;
+ fbdev[0]->sysmmu.pgd = 0;
+ s5p_sysmmu_disable(fbdev[0]->dev);
+ }
+#endif
+ printk(KERN_INFO "-%s\n", __func__);
return ;
}
@@ -780,28 +947,18 @@ void s3cfb_late_resume(struct early_suspend *h)
int i, j;
struct platform_device *pdev = to_platform_device(info->dev);
- printk(KERN_INFO "+%s\n", __func__);
+ dev_info(info->dev, "+%s\n", __func__);
dev_dbg(info->dev, "wake up from suspend\n");
#ifdef CONFIG_EXYNOS_DEV_PD
/* enable the power domain */
- printk(KERN_DEBUG "s3cfb - enable power domain\n");
+ dev_dbg(info->dev, "s3cfb - enable power domain\n");
pm_runtime_get_sync(&pdev->dev);
#endif
#ifdef CONFIG_FB_S5P_MIPI_DSIM
s5p_dsim_late_resume();
-
- if (s5p_dsim_fifo_clear() == 0) {
- s5p_dsim_early_suspend();
- usleep_range(10000, 10000);
- s5p_dsim_late_resume();
- if (s5p_dsim_fifo_clear() == 0)
- pr_info("dsim resume fail!!!\n");
- }
-
- usleep_range(10000, 10000);
#endif
#if defined(CONFIG_FB_S5P_DUMMYLCD)
@@ -819,6 +976,10 @@ void s3cfb_late_resume(struct early_suspend *h)
/* fbdev[i]->regs_org should be non-zero value */
BUG();
+#if defined(CONFIG_FB_MDNIE_PWM)
+ set_mdnie_pwm_value(g_mdnie, 0);
+#endif
+
if (pdata->set_display_path)
pdata->set_display_path();
@@ -848,6 +1009,9 @@ void s3cfb_late_resume(struct early_suspend *h)
/* Set alpha value width to 8-bit */
s3cfb_set_alpha_value_width(fbdev[i], i);
+#if defined(CONFIG_FB_RGBA_ORDER)
+ s3cfb_set_output(fbdev[i]);
+#else
for (j = 0; j < pdata->nr_wins; j++) {
fb = fbdev[i]->fb[j];
win = fb->par;
@@ -857,6 +1021,7 @@ void s3cfb_late_resume(struct early_suspend *h)
s3cfb_enable_window(fbdev[i], win->id);
}
}
+#endif
if (pdata->cfg_gpio)
pdata->cfg_gpio(pdev);
@@ -869,17 +1034,23 @@ void s3cfb_late_resume(struct early_suspend *h)
if (pdata->backlight_on)
pdata->backlight_on(pdev);
+
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ mutex_lock(&fbdev[i]->vsync_info.irq_lock);
+ if (fbdev[i]->vsync_info.irq_refcount) {
+ s3cfb_set_global_interrupt(fbdev[i], 1);
+ s3cfb_set_vsync_interrupt(fbdev[i], 1);
+ }
+ mutex_unlock(&fbdev[i]->vsync_info.irq_lock);
+#endif
}
#ifdef CONFIG_FB_S5P_MIPI_DSIM
-#if defined(CONFIG_FB_S5P_S6E63M0)
- s6e63m0_late_resume();
-#else
- s6e8ax0_late_resume();
-#endif
+ if (lcd_late_resume)
+ lcd_late_resume();
#endif
- printk(KERN_INFO "-%s\n", __func__);
+ dev_info(info->dev, "-%s\n", __func__);
return;
}
diff --git a/drivers/video/samsung/s3cfb_mdnie.c b/drivers/video/samsung/s3cfb_mdnie.c
index 0fa2f60..a578dac 100644
--- a/drivers/video/samsung/s3cfb_mdnie.c
+++ b/drivers/video/samsung/s3cfb_mdnie.c
@@ -188,7 +188,7 @@ int s3c_mdnie_hw_init(void)
return -ENOENT;
}
- printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_mdnie_base);
+ /* printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_mdnie_base); */
return 0;
}
diff --git a/drivers/video/samsung/s3cfb_ops.c b/drivers/video/samsung/s3cfb_ops.c
index 82ece16..759fb63 100644
--- a/drivers/video/samsung/s3cfb_ops.c
+++ b/drivers/video/samsung/s3cfb_ops.c
@@ -15,6 +15,12 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/sw_sync.h>
+#include <plat/regs-fb.h>
+#include <plat/regs-fb-s5p.h>
+
#if defined(CONFIG_CMA)
#include <linux/cma.h>
#elif defined(CONFIG_S5P_MEM_BOOTMEM)
@@ -43,6 +49,10 @@
#include <mach/dev.h>
#endif
+#ifdef CONFIG_FB_S5P_SYSMMU
+#include <plat/s5p-sysmmu.h>
+#endif
+
struct s3c_platform_fb *to_fb_plat(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -183,7 +193,10 @@ int s3cfb_enable_window(struct s3cfb_global *fbdev, int id)
#endif
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
#ifdef CONFIG_BUSFREQ_OPP
- if (id != CONFIG_FB_S5P_DEFAULT_WINDOW)
+ if (CONFIG_FB_S5P_DEFAULT_WINDOW == 3 &&
+ id == CONFIG_FB_S5P_DEFAULT_WINDOW-1)
+ dev_lock(fbdev->bus_dev, fbdev->dev, 267160);
+ else if (id != CONFIG_FB_S5P_DEFAULT_WINDOW)
dev_lock(fbdev->bus_dev, fbdev->dev, 133133);
#endif
#endif
@@ -394,6 +407,10 @@ int s3cfb_map_default_video_memory(struct s3cfb_global *fbdev,
memset(fb->screen_base, 0, fix->smem_len);
win->owner = DMA_MEM_FIMD;
+#ifdef CONFIG_FB_S5P_SYSMMU
+ fbdev->sysmmu.default_fb_addr = fix->smem_start;
+#endif
+
return 0;
}
@@ -457,11 +474,19 @@ int s3cfb_set_bitfield(struct fb_var_screeninfo *var)
break;
case 32:
+#if defined(CONFIG_FB_RGBA_ORDER)
+ var->red.offset = 0;
+#else
var->red.offset = 16;
+#endif
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
+#if defined(CONFIG_FB_RGBA_ORDER)
+ var->blue.offset = 16;
+#else
var->blue.offset = 0;
+#endif
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8; /* added for LCD RGB32 */
@@ -1082,30 +1107,631 @@ int s3cfb_cursor(struct fb_info *fb, struct fb_cursor *cursor)
return 0;
}
-int s3cfb_vsync_timestamp_changed(struct s3cfb_global *fbdev, ktime_t prev_timestamp)
+#if !defined(CONFIG_FB_S5P_VSYNC_THREAD)
+int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev)
{
- return !ktime_equal(prev_timestamp, fbdev->vsync_timestamp);
+ dev_dbg(fbdev->dev, "waiting for VSYNC interrupt\n");
+
+ sleep_on_timeout(&fbdev->wq, HZ / 10);
+
+ dev_dbg(fbdev->dev, "got a VSYNC interrupt\n");
+
+ return 0;
}
+#endif
-int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev)
+
+/**
+ * s3c_fb_align_word() - align pixel count to word boundary
+ * @bpp: The number of bits per pixel
+ * @pix: The value to be aligned.
+ *
+ * Align the given pixel count so that it will start on an 32bit word
+ * boundary.
+ */
+static int s3c_fb_align_word(unsigned int bpp, unsigned int pix)
+{
+ int pix_per_word;
+
+ if (bpp > 16)
+ return pix;
+
+ pix_per_word = (8 * 32) / bpp;
+ return ALIGN(pix, pix_per_word);
+}
+
+static u32 s3c_fb_red_length(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 5;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 4;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_red_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 0;
+
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 16;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_green_length(int format)
+{
+ if (format == S3C_FB_PIXEL_FORMAT_RGB_565)
+ return 6;
+
+ return s3c_fb_red_length(format);
+}
+
+static u32 s3c_fb_green_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 5;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 4;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_blue_length(int format)
+{
+ return s3c_fb_red_length(format);
+}
+
+static u32 s3c_fb_blue_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 16;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ return 11;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 10;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 0;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_transp_length(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 1;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 4;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 0;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_transp_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 24;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 15;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 12;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return s3c_fb_blue_offset(format);
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_padding(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 0;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+
+}
+
+static inline u32 fb_visual(u32 bits_per_pixel, unsigned short palette_sz)
+{
+ switch (bits_per_pixel) {
+ case 32:
+ case 24:
+ case 16:
+ case 12:
+ return FB_VISUAL_TRUECOLOR;
+ case 8:
+ if (palette_sz >= 256)
+ return FB_VISUAL_PSEUDOCOLOR;
+ else
+ return FB_VISUAL_TRUECOLOR;
+ case 1:
+ return FB_VISUAL_MONO01;
+ default:
+ return FB_VISUAL_PSEUDOCOLOR;
+ }
+}
+
+
+static inline u32 fb_linelength(u32 xres_virtual, u32 bits_per_pixel)
+{
+ return (xres_virtual * bits_per_pixel) / 8;
+}
+
+static inline u16 fb_panstep(u32 res, u32 res_virtual)
+{
+ return res_virtual > res ? 1 : 0;
+}
+
+static inline u32 vidw_buf_size(u32 xres, u32 line_length, u32 bits_per_pixel)
+{
+ u32 pagewidth = (xres * bits_per_pixel) >> 3;
+ return VIDW_BUF_SIZE_OFFSET(line_length - pagewidth) |
+ VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) |
+ VIDW_BUF_SIZE_OFFSET_E(line_length - pagewidth) |
+ VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth);
+}
+
+inline u32 vidosd_a(int x, int y)
+{
+ return VIDOSDxA_TOPLEFT_X(x) |
+ VIDOSDxA_TOPLEFT_Y(y) |
+ VIDOSDxA_TOPLEFT_X_E(x) |
+ VIDOSDxA_TOPLEFT_Y_E(y);
+}
+
+inline u32 vidosd_b(int x, int y, u32 xres, u32 yres, u32 bits_per_pixel)
+{
+ return VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(bits_per_pixel,
+ x + xres - 1)) |
+ VIDOSDxB_BOTRIGHT_Y(y + yres - 1) |
+ VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(bits_per_pixel,
+ x + xres - 1)) |
+ VIDOSDxB_BOTRIGHT_Y_E(y + yres - 1);
+}
+
+static inline u32 wincon(u32 bits_per_pixel, u32 transp_length, u32 red_length)
+{
+ u32 data = 0;
+
+ switch (bits_per_pixel) {
+ case 1:
+ data |= WINCON0_BPPMODE_1BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_4WORD;
+ break;
+ case 2:
+ data |= WINCON0_BPPMODE_2BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_8WORD;
+ break;
+ case 4:
+ data |= WINCON0_BPPMODE_4BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_8WORD;
+ break;
+ case 8:
+ if (transp_length != 0)
+ data |= WINCON1_BPPMODE_8BPP_1232;
+ else
+ data |= WINCON0_BPPMODE_8BPP_PALETTE;
+ data |= WINCONx_BURSTLEN_8WORD;
+ data |= WINCONx_BYTSWP;
+ break;
+ case 16:
+ if (transp_length != 0)
+ data |= WINCON1_BPPMODE_16BPP_A1555;
+ else
+ data |= WINCON0_BPPMODE_16BPP_565;
+ data |= WINCONx_HAWSWP;
+ data |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case 24:
+ case 32:
+ if (red_length == 6) {
+ if (transp_length != 0)
+ data |= WINCON1_BPPMODE_19BPP_A1666;
+ else
+ data |= WINCON1_BPPMODE_18BPP_666;
+ } else if (transp_length == 1)
+ data |= WINCON1_BPPMODE_25BPP_A1888
+ | WINCON1_BLD_PIX;
+ else if ((transp_length == 4) ||
+ (transp_length == 8))
+ data |= WINCON1_BPPMODE_28BPP_A4888
+ | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
+ else
+ data |= WINCON0_BPPMODE_24BPP_888;
+
+ data |= WINCONx_WSWP;
+ data |= WINCONx_BURSTLEN_16WORD;
+ break;
+ }
+
+ return data;
+}
+
+void s3c_fb_update_regs(struct s3cfb_global *fbdev, struct s3c_reg_data *regs)
{
- ktime_t prev_timestamp;
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ unsigned short i;
+ bool wait_for_vsync;
+ struct s3cfb_window *win;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#ifdef CONFIG_BUSFREQ_OPP
+ unsigned int new_num_of_win = 0;
+ unsigned int pre_num_of_win = 0;
+ unsigned int shadow_regs = 0;
+ unsigned int clkval = 0;
+
+ for (i = 0; i < pdata->nr_wins; i++)
+ if (regs->shadowcon & SHADOWCON_CHx_ENABLE(i))
+ new_num_of_win++;
+ shadow_regs = readl(fbdev->regs + S3C_WINSHMAP);
+ for (i = 0; i < pdata->nr_wins; i++)
+ if (shadow_regs & SHADOWCON_CHx_ENABLE(i))
+ pre_num_of_win++;
+
+ if (pre_num_of_win < new_num_of_win) {
+ switch(new_num_of_win) {
+ case 0:
+ case 1:
+ clkval = 100100;
+ break;
+ case 2:
+ clkval = 133133;
+ break;
+ case 3:
+ clkval = 133133;
+ break;
+ case 4:
+ clkval = 133133;
+ break;
+ case 5:
+ clkval = 133133;
+ break;
+ }
+ dev_lock(fbdev->bus_dev, fbdev->dev, clkval);
+ }
+#endif
+#endif
+
+ for (i = 0; i < pdata->nr_wins; i++)
+ s3cfb_set_window_protect(fbdev, i, 1);
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ win = fbdev->fb[i]->par;
+ writel(regs->wincon[i], fbdev->regs + S3C_WINCON(i));
+ writel(regs->vidosd_a[i], fbdev->regs + S3C_VIDOSD_A(i));
+ writel(regs->vidosd_b[i], fbdev->regs + S3C_VIDOSD_B(i));
+ writel(regs->vidosd_c[i], fbdev->regs + S3C_VIDOSD_C(i));
+ if (i == 1 || i == 2)
+ writel(regs->vidosd_d[i], fbdev->regs + S3C_VIDOSD_D(i));
+ writel(regs->vidw_buf_start[i],
+ fbdev->regs + S3C_VIDADDR_START0(i));
+ writel(regs->vidw_buf_end[i],
+ fbdev->regs + S3C_VIDADDR_END0(i));
+ writel(regs->vidw_buf_size[i],
+ fbdev->regs + S3C_VIDADDR_SIZE(i));
+
+ win->enabled = !!(regs->wincon[i] & WINCONx_ENWIN);
+ }
+
+ writel(regs->shadowcon, fbdev->regs + S3C_WINSHMAP);
+
+ for (i = 0; i < pdata->nr_wins; i++)
+ s3cfb_set_window_protect(fbdev, i, 0);
+
+ do {
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ s3cfb_wait_for_vsync(fbdev, 0);
+#else
+ s3cfb_wait_for_vsync(fbdev);
+#endif
+ wait_for_vsync = false;
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ u32 new_start = regs->vidw_buf_start[i];
+ u32 shadow_start = s3cfb_get_win_cur_buf_addr(fbdev, i);
+ if (unlikely(new_start != shadow_start)) {
+ wait_for_vsync = true;
+ break;
+ }
+ }
+ } while (wait_for_vsync);
+
+ sw_sync_timeline_inc(fbdev->timeline, 1);
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if ((fbdev->sysmmu.enabled == false) &&
+ (fbdev->sysmmu.pgd)) {
+ fbdev->sysmmu.enabled = true;
+ s5p_sysmmu_enable(fbdev->dev,
+ (unsigned long)virt_to_phys((unsigned int*)fbdev->sysmmu.pgd));
+ }
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#ifdef CONFIG_BUSFREQ_OPP
+ if (pre_num_of_win > new_num_of_win) {
+ switch(new_num_of_win) {
+ case 0:
+ case 1:
+ clkval = 100100;
+ break;
+ case 2:
+ clkval = 133133;
+ break;
+ case 3:
+ clkval = 133133;
+ break;
+ case 4:
+ clkval = 133133;
+ break;
+ case 5:
+ clkval = 133133;
+ break;
+ }
+ dev_lock(fbdev->bus_dev, fbdev->dev, clkval);
+ }
+#endif
+#endif
+}
+
+static int s3c_fb_set_win_buffer(struct s3cfb_global *fbdev,
+ struct fb_info *fb, struct s3c_fb_win_config *win_config,
+ struct s3c_reg_data *regs)
+{
+ struct s3cfb_window *win = fb->par;
+ struct fb_fix_screeninfo prev_fix = fb->fix;
+ struct fb_var_screeninfo prev_var = fb->var;
+ unsigned short win_no = win->id;
int ret;
+ size_t window_size;
+ u32 alpha, size;
- dev_dbg(fbdev->dev, "waiting for VSYNC interrupt\n");
+ if (win_config->format >= S3C_FB_PIXEL_FORMAT_MAX) {
+ dev_err(fbdev->dev, "unknown pixel format %u\n",
+ win_config->format);
+ return -EINVAL;
+ }
- prev_timestamp = fbdev->vsync_timestamp;
+ fb->var.red.length = s3c_fb_red_length(win_config->format);
+ fb->var.red.offset = s3c_fb_red_offset(win_config->format);
+ fb->var.green.length = s3c_fb_green_length(win_config->format);
+ fb->var.green.offset = s3c_fb_green_offset(win_config->format);
+ fb->var.blue.length = s3c_fb_blue_length(win_config->format);
+ fb->var.blue.offset = s3c_fb_blue_offset(win_config->format);
+ fb->var.transp.length = s3c_fb_transp_length(win_config->format);
+ fb->var.transp.offset = s3c_fb_transp_offset(win_config->format);
+ fb->var.bits_per_pixel = fb->var.red.length +
+ fb->var.green.length +
+ fb->var.blue.length +
+ fb->var.transp.length +
+ s3c_fb_padding(win_config->format);
+
+ window_size = win_config->stride * win_config->h;
+
+ if (win_config->phys_addr != 0)
+ fb->fix.smem_start = win_config->phys_addr + win_config->offset;
+ else
+ fb->fix.smem_start = win_config->virt_addr + win_config->offset;
+ fb->fix.smem_len = window_size;
+ fb->var.xres = win_config->w;
+ fb->var.xres_virtual = win_config->stride * 8 /
+ fb->var.bits_per_pixel;
+ fb->var.yres = fb->var.yres_virtual = win_config->h;
+ fb->var.xoffset = win_config->offset % win_config->stride;
+ fb->var.yoffset = win_config->offset / win_config->stride;
+
+ fb->fix.visual = fb_visual(fb->var.bits_per_pixel, 256);
+ fb->fix.line_length = win_config->stride;
+ fb->fix.xpanstep = fb_panstep(win_config->w,
+ fb->var.xres_virtual);
+ fb->fix.ypanstep = fb_panstep(win_config->h, win_config->h);
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if ((fbdev->sysmmu.enabled == false) &&
+ (current->mm))
+ fbdev->sysmmu.pgd = (unsigned int)current->mm->pgd;
+#endif
- ret = wait_event_interruptible_timeout(fbdev->wq,
- s3cfb_vsync_timestamp_changed(fbdev, prev_timestamp),
- msecs_to_jiffies(100));
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if (win_config->phys_addr != 0)
+ regs->vidw_buf_start[win_no] = (u32)phys_to_virt(fb->fix.smem_start);
+ else
+#endif
+ regs->vidw_buf_start[win_no] = fb->fix.smem_start;
- if (ret == 0)
- return -ETIMEDOUT;
- if (ret < 0)
- return ret;
+ regs->vidw_buf_end[win_no] = regs->vidw_buf_start[win_no] +
+ window_size;
- dev_dbg(fbdev->dev, "got a VSYNC interrupt\n");
+ regs->vidw_buf_size[win_no] = vidw_buf_size(win_config->w,
+ fb->fix.line_length,
+ fb->var.bits_per_pixel);
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if ((fb->fix.smem_start) &&
+ (fb->fix.smem_start != fbdev->sysmmu.default_fb_addr))
+ s3cfb_clean_outer_pagetable(regs->vidw_buf_start[win_no],
+ regs->vidw_buf_end[win_no] - regs->vidw_buf_start[win_no]);
+#endif
+
+
+ regs->vidosd_a[win_no] = vidosd_a(win_config->x, win_config->y);
+ regs->vidosd_b[win_no] = vidosd_b(win_config->x, win_config->y,
+ win_config->w, win_config->h,
+ fb->var.bits_per_pixel);
+
+ alpha = VIDISD14C_ALPHA1_R(0xf) |
+ VIDISD14C_ALPHA1_G(0xf) |
+ VIDISD14C_ALPHA1_B(0xf);
+ regs->vidosd_c[win_no] = alpha;
+
+ if (win_no <= 2) {
+ size = win_config->w * win_config->h;
+ regs->vidosd_d[win_no] = size;
+ }
+
+ regs->shadowcon |= SHADOWCON_CHx_ENABLE(win_no);
+
+ regs->wincon[win_no] = wincon(fb->var.bits_per_pixel,
+ fb->var.transp.length,
+ fb->var.red.length);
+
+ return 0;
+}
+
+static int s3c_fb_set_win_config(struct s3cfb_global *fbdev,
+ struct s3c_fb_win_config_data *win_data)
+{
+ struct fb_info *fb;
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct s3c_fb_win_config *win_config = win_data->config;
+ int ret = 0;
+ unsigned short i;
+ struct s3c_reg_data *regs = kzalloc(sizeof(struct s3c_reg_data),
+ GFP_KERNEL);
+ struct sync_fence *fence;
+ struct sync_pt *pt;
+ int fd;
+
+ if (!regs) {
+ dev_err(fbdev->dev, "could not allocate s3c_reg_data");
+ return -ENOMEM;
+ }
+
+ fd = get_unused_fd();
+
+ for (i = 0; i < pdata->nr_wins && !ret; i++) {
+ struct s3c_fb_win_config *config = &win_config[i];
+ bool enabled = 0;
+ u32 color_map = WINxMAP_MAP | WINxMAP_MAP_COLOUR(0);
+
+ fb = fbdev->fb[i];
+
+ switch (config->state) {
+ case S3C_FB_WIN_STATE_DISABLED:
+ break;
+ case S3C_FB_WIN_STATE_COLOR:
+ enabled = 1;
+ color_map |= WINxMAP_MAP_COLOUR(config->color);
+ break;
+ case S3C_FB_WIN_STATE_BUFFER:
+ ret = s3c_fb_set_win_buffer(fbdev, fb, config, regs);
+ if (!ret) {
+ enabled = 1;
+ color_map = 0;
+ }
+ break;
+ default:
+ dev_warn(fbdev->dev, "unrecognized window state %u",
+ config->state);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (enabled)
+ regs->wincon[i] |= WINCONx_ENWIN;
+ else
+ regs->wincon[i] &= ~WINCONx_ENWIN;
+ regs->winmap[i] = color_map;
+ }
+
+ if (ret) {
+ put_unused_fd(fd);
+ kfree(regs);
+ } else {
+ mutex_lock(&fbdev->update_regs_list_lock);
+ fbdev->timeline_max++;
+ pt = sw_sync_pt_create(fbdev->timeline, fbdev->timeline_max);
+ fence = sync_fence_create("display", pt);
+ sync_fence_install(fence, fd);
+ win_data->fence = fd;
+
+ list_add_tail(&regs->list, &fbdev->update_regs_list);
+ mutex_unlock(&fbdev->update_regs_list_lock);
+ queue_kthread_work(&fbdev->update_regs_worker, &fbdev->update_regs_work);
+ }
return ret;
}
@@ -1128,6 +1754,7 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
struct s3cfb_user_window user_window;
struct s3cfb_user_plane_alpha user_alpha;
struct s3cfb_user_chroma user_chroma;
+ struct s3c_fb_win_config_data win_data;
int vsync;
unsigned int alpha_mode;
} p;
@@ -1149,23 +1776,31 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
if (fbdev->regs == 0)
return 0;
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
- /* Enable Vsync */
#ifdef CONFIG_CPU_EXYNOS4412
if (!fbdev->regs)
return ret;
#endif
+#if !defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ /* Enable Vsync */
s3cfb_set_global_interrupt(fbdev, 1);
s3cfb_set_vsync_interrupt(fbdev, 1);
#endif
+#endif
/* Wait for Vsync */
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ s3cfb_wait_for_vsync(fbdev, HZ/10);
+#else
s3cfb_wait_for_vsync(fbdev);
+#endif
if (fbdev->regs == 0)
return 0;
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#if !defined(CONFIG_FB_S5P_VSYNC_THREAD)
/* Disable Vsync */
s3cfb_set_global_interrupt(fbdev, 0);
s3cfb_set_vsync_interrupt(fbdev, 0);
#endif
+#endif
break;
case S3CFB_WIN_POSITION:
@@ -1238,8 +1873,12 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
if (!fbdev->regs)
return ret;
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ ret = s3cfb_set_vsync_int(fb, p.vsync);
+#else
s3cfb_set_global_interrupt(fbdev, p.vsync);
s3cfb_set_vsync_interrupt(fbdev, p.vsync);
+#endif
}
break;
@@ -1293,7 +1932,30 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
else
s3cfb_set_alpha_mode(fbdev, win->id, p.alpha_mode);
break;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ case S3CFB_WIN_CONFIG:
+ if (copy_from_user(&p.win_data,
+ (struct s3c_fb_win_config_data __user *)arg,
+ sizeof(p.win_data))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = s3c_fb_set_win_config(fbdev, &p.win_data);
+ if (ret)
+ break;
+
+ if (copy_to_user((struct s3c_fb_win_config_data __user *)arg,
+ &p.win_data,
+ sizeof(p.win_data))) {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+#endif
}
+
return ret;
}
diff --git a/drivers/video/samsung/s3cfb_s6c1372.c b/drivers/video/samsung/s3cfb_s6c1372.c
index 46c35ca..4d23708 100644
--- a/drivers/video/samsung/s3cfb_s6c1372.c
+++ b/drivers/video/samsung/s3cfb_s6c1372.c
@@ -83,8 +83,18 @@ static DEVICE_ATTR(lcd_type, 0664, lcdtype_show, NULL);
void s5c1372_ldi_enable(void)
{
+#if defined(CONFIG_FB_S5P_S6C1372)
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ msleep(40);
+#else /* defined(CONFIG_FB_S5P_S6F1202A ) */
gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_HIGH);
msleep(40);
+
+ /* Enable backlight PWM GPIO for P2 device. */
+ gpio_set_value(GPIO_LCD_BACKLIGHT_PWM, 0);
+ s3c_gpio_cfgpin(GPIO_LCD_BACKLIGHT_PWM, S3C_GPIO_SFN(3));
+#endif
}
void s5c1372_ldi_disable(void)
@@ -93,12 +103,21 @@ void s5c1372_ldi_disable(void)
s3c_gpio_cfgpin(GPIO_LCD_PCLK, S3C_GPIO_OUTPUT);
s3c_gpio_setpull(GPIO_LCD_PCLK, S3C_GPIO_PULL_NONE);
gpio_set_value(GPIO_LCD_PCLK, GPIO_LEVEL_LOW);
-#endif
msleep(40);
gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
msleep(600);
+#else /* defined(CONFIG_FB_S5P_S6F1202A ) */
+ /* Disable backlight PWM GPIO for P2 device. */
+ gpio_set_value(GPIO_LCD_BACKLIGHT_PWM, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_LCD_BACKLIGHT_PWM, S3C_GPIO_OUTPUT);
+
+ /* Disable LVDS Panel Power, 1.2, 1.8, display 3.3V */
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+ msleep(300);
+#endif
}
static int __init s6c1372_probe(struct platform_device *pdev)
diff --git a/drivers/video/samsung/s3cfb_s6e39a0.c b/drivers/video/samsung/s3cfb_s6e39a0.c
index 3d0f534..a07e455 100644
--- a/drivers/video/samsung/s3cfb_s6e39a0.c
+++ b/drivers/video/samsung/s3cfb_s6e39a0.c
@@ -110,7 +110,10 @@ struct lcd_info {
struct dsim_global *dsim;
};
-static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+static int s6e39a0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
const unsigned char *wbuf;
@@ -135,7 +138,7 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
return 0;
}
-static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+static int s6e39a0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
{
int ret = 0;
@@ -245,69 +248,69 @@ static int get_backlight_level_from_brightness(int brightness)
return backlightlevel;
}
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e39a0_set_acl(struct lcd_info *lcd)
{
if (lcd->acl_enable) {
if (lcd->cur_acl == 0) {
if (lcd->bl == 0 || lcd->bl == 1) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ s6e39a0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
} else
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ s6e39a0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
}
switch (lcd->bl) {
case 0 ... 1: /* 30cd ~ 40cd - 0%*/
if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ s6e39a0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
lcd->cur_acl = 0;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 2 ... 12: /* 70cd ~ 180cd -40%*/
if (lcd->cur_acl != 40) {
- s6e8ax0_write(lcd, acl_cutoff_table[1], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[1], ACL_PARAM_SIZE);
lcd->cur_acl = 40;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 13: /* 190cd - 43% */
if (lcd->cur_acl != 43) {
- s6e8ax0_write(lcd, acl_cutoff_table[2], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[2], ACL_PARAM_SIZE);
lcd->cur_acl = 43;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 14: /* 200cd - 45% */
if (lcd->cur_acl != 45) {
- s6e8ax0_write(lcd, acl_cutoff_table[3], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[3], ACL_PARAM_SIZE);
lcd->cur_acl = 45;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 15: /* 210cd - 47% */
if (lcd->cur_acl != 47) {
- s6e8ax0_write(lcd, acl_cutoff_table[4], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[4], ACL_PARAM_SIZE);
lcd->cur_acl = 47;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 16: /* 220cd - 48% */
if (lcd->cur_acl != 48) {
- s6e8ax0_write(lcd, acl_cutoff_table[5], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[5], ACL_PARAM_SIZE);
lcd->cur_acl = 48;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
default:
if (lcd->cur_acl != 50) {
- s6e8ax0_write(lcd, acl_cutoff_table[6], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[6], ACL_PARAM_SIZE);
lcd->cur_acl = 50;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
}
} else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ s6e39a0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
lcd->cur_acl = 0;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
@@ -316,12 +319,12 @@ static int s6e8ax0_set_acl(struct lcd_info *lcd)
}
#ifndef SMART_DIMMING
-static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
+static int s6e39a0_gamma_ctl(struct lcd_info *lcd)
{
- s6e8ax0_write(lcd, gamma22_table[lcd->bl], GAMMA_PARAM_SIZE);
+ s6e39a0_write(lcd, gamma22_table[lcd->bl], GAMMA_PARAM_SIZE);
/* Gamma Set Update */
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6e39a0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
lcd->current_bl = lcd->bl;
@@ -332,20 +335,21 @@ static int update_brightness(struct lcd_info *lcd)
{
int ret;
-#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+#if defined(CONFIG_MACH_C1) || \
+ defined(CONFIG_MACH_M3) || \
defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ) || \
- defined(CONFIG_MACH_SLP_PQ_LTE) || defined(CONFIG_MACH_M3)
+ defined(CONFIG_MACH_SLP_PQ_LTE)
#else
- ret = s6e8ax0_gamma_ctl(lcd);
+ ret = s6e39a0_gamma_ctl(lcd);
if (ret)
return -EPERM;
/*
- ret = s6e8ax0_set_elvss(lcd);
+ ret = s6e39a0_set_elvss(lcd);
if (ret)
return -EPERM;
- ret = s6e8ax0_set_acl(lcd);
+ ret = s6e39a0_set_acl(lcd);
if (ret)
return -EPERM;
*/
@@ -356,13 +360,13 @@ static int update_brightness(struct lcd_info *lcd)
#endif
#ifdef SMART_DIMMING
-static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+static int s6e39a0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
{
int ret;
u8 retry_cnt = 3;
read_retry:
- ret = s6e8ax0_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data);
+ ret = s6e39a0_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] : %s : retry cnt : %d\n", __func__, retry_cnt);
@@ -481,9 +485,9 @@ static int s6e8aa0_update_brightness(struct lcd_info *lcd, u32 brightness)
calc_gamma_table(&lcd->smart, gamma, gamma_regs+2);
- s6e8ax0_write(lcd, gamma_regs, GAMMA_PARAM_SIZE);
+ s6e39a0_write(lcd, gamma_regs, GAMMA_PARAM_SIZE);
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, sizeof(SEQ_GAMMA_UPDATE));
+ s6e39a0_write(lcd, SEQ_GAMMA_UPDATE, sizeof(SEQ_GAMMA_UPDATE));
#if 0
printk(KERN_INFO "##### print gamma reg #####\n");
@@ -553,12 +557,12 @@ static int s6e8aa0_update_elvss(struct lcd_info *lcd, u32 candela)
elvss_cmd[2] = elvss;
printk(KERN_DEBUG "elvss reg : %02x\n", elvss_cmd[2]);
- s6e8ax0_write(lcd, elvss_cmd, sizeof(elvss_cmd));
+ s6e39a0_write(lcd, elvss_cmd, sizeof(elvss_cmd));
return 0;
}
-static int s6e8ax0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force)
+static int s6e39a0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force)
{
u32 gamma;
int ret = 0;
@@ -572,7 +576,7 @@ static int s6e8ax0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force
ret = s6e8aa0_update_brightness(lcd, gamma);
- ret = s6e8ax0_set_acl(lcd);
+ ret = s6e39a0_set_acl(lcd);
if (lcd->support_elvss)
ret = s6e8aa0_update_elvss(lcd, gamma);
@@ -587,82 +591,82 @@ static int s6e8ax0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force
}
#endif
-static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+static int s6e39a0_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_2_KEY, \
+ s6e39a0_write(lcd, SEQ_APPLY_LEVEL_2_KEY, \
ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_3_KEY, \
+ s6e39a0_write(lcd, SEQ_APPLY_LEVEL_3_KEY, \
ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY));
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_4_KEY, \
+ s6e39a0_write(lcd, SEQ_APPLY_LEVEL_4_KEY, \
ARRAY_SIZE(SEQ_APPLY_LEVEL_4_KEY));
- s6e8ax0_write(lcd, SEQ_GAMMA_CONDITION_SET, \
+ s6e39a0_write(lcd, SEQ_GAMMA_CONDITION_SET, \
ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE,\
+ s6e39a0_write(lcd, SEQ_GAMMA_UPDATE,\
ARRAY_SIZE(SEQ_GAMMA_UPDATE));
- s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, \
+ s6e39a0_write(lcd, SEQ_PANEL_CONDITION_SET, \
ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_0, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_0, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_0));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_1, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_1, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_1));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_2, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_2, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_2));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_3, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_3, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_3));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_4, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_4, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_4));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_5, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_5, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_5));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_6, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_6, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_6));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_7, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_7, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_7));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_8, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_8, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_8));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_9, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_9, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_9));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_10, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_10, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_10));
- s6e8ax0_write(lcd, SEQ_SLEEP_OUT, \
+ s6e39a0_write(lcd, SEQ_SLEEP_OUT, \
ARRAY_SIZE(SEQ_SLEEP_OUT));
mdelay(120);
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_0, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_0, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_1_0));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_1, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_1, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_1_1));
mdelay(1);
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_1, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_1, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_1));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_2, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_2, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_2));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_3, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_3, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_3));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_4, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_4, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_4));
return ret;
}
-static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+static int s6e39a0_ldi_enable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+ s6e39a0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
return ret;
}
-static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+static int s6e39a0_ldi_disable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
- s6e8ax0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
+ s6e39a0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6e39a0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
return ret;
}
-static int s6e8ax0_power_on(struct lcd_info *lcd)
+static int s6e39a0_power_on(struct lcd_info *lcd)
{
int ret = 0;
struct lcd_platform_data *pd = NULL;
@@ -670,7 +674,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
/* dev_info(&lcd->ld->dev, "%s\n", __func__); */
- ret = s6e8ax0_ldi_init(lcd);
+ ret = s6e39a0_ldi_init(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
@@ -679,7 +683,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
msleep(120);
- ret = s6e8ax0_ldi_enable(lcd);
+ ret = s6e39a0_ldi_enable(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
goto err;
@@ -688,7 +692,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
#ifdef SMART_DIMMING
lcd->ldi_enable = 1;
- s6e8ax0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
+ s6e39a0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
#else
update_brightness(lcd);
@@ -699,7 +703,7 @@ err:
return ret;
}
-static int s6e8ax0_power_off(struct lcd_info *lcd)
+static int s6e39a0_power_off(struct lcd_info *lcd)
{
int ret = 0;
@@ -707,21 +711,21 @@ static int s6e8ax0_power_off(struct lcd_info *lcd)
lcd->ldi_enable = 0;
- ret = s6e8ax0_ldi_disable(lcd);
+ ret = s6e39a0_ldi_disable(lcd);
msleep(120);
return ret;
}
-static int s6e8ax0_power(struct lcd_info *lcd, int power)
+static int s6e39a0_power(struct lcd_info *lcd, int power)
{
int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_on(lcd);
+ ret = s6e39a0_power_on(lcd);
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_off(lcd);
+ ret = s6e39a0_power_off(lcd);
if (!ret)
lcd->power = power;
@@ -729,7 +733,7 @@ static int s6e8ax0_power(struct lcd_info *lcd, int power)
return ret;
}
-static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+static int s6e39a0_set_power(struct lcd_device *ld, int power)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -739,10 +743,10 @@ static int s6e8ax0_set_power(struct lcd_device *ld, int power)
return -EINVAL;
}
- return s6e8ax0_power(lcd, power);
+ return s6e39a0_power(lcd, power);
}
-static int s6e8ax0_get_power(struct lcd_device *ld)
+static int s6e39a0_get_power(struct lcd_device *ld)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -750,7 +754,7 @@ static int s6e8ax0_get_power(struct lcd_device *ld)
}
#ifdef SMART_DIMMING
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6e39a0_set_brightness(struct backlight_device *bd)
{
int ret = 0;
u32 brightness = (u32)bd->props.brightness;
@@ -766,12 +770,12 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
/* dev_info(&lcd->ld->dev, "[%s] brightness=%d\n", __func__, brightness); */
- ret = s6e8ax0_adb_brightness_update(lcd, brightness, 0);
+ ret = s6e39a0_adb_brightness_update(lcd, brightness, 0);
return ret;
}
#else
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6e39a0_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
@@ -802,19 +806,19 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
}
#endif
-static int s6e8ax0_get_brightness(struct backlight_device *bd)
+static int s6e39a0_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
-static struct lcd_ops s6e8ax0_lcd_ops = {
- .set_power = s6e8ax0_set_power,
- .get_power = s6e8ax0_get_power,
+static struct lcd_ops s6e39a0_lcd_ops = {
+ .set_power = s6e39a0_set_power,
+ .get_power = s6e39a0_get_power,
};
-static const struct backlight_ops s6e8ax0_backlight_ops = {
- .get_brightness = s6e8ax0_get_brightness,
- .update_status = s6e8ax0_set_brightness,
+static const struct backlight_ops s6e39a0_backlight_ops = {
+ .get_brightness = s6e39a0_get_brightness,
+ .update_status = s6e39a0_set_brightness,
};
static ssize_t lcd_type_show(struct device *dev,
@@ -855,7 +859,7 @@ static ssize_t power_reduce_store(struct device *dev,
lcd->acl_enable, value);
lcd->acl_enable = value;
if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd);
+ s6e39a0_set_acl(lcd);
}
return size;
}
@@ -865,36 +869,36 @@ static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
#ifdef CONFIG_HAS_EARLYSUSPEND
struct lcd_info *g_lcd;
-void s6e8ax0_early_suspend(void)
+void s6e39a0_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6e39a0_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
-void s6e8ax0_late_resume(void)
+void s6e39a0_late_resume(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
+ s6e39a0_power(lcd, FB_BLANK_UNBLANK);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
#endif
-static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
+static void s6e39a0_read_id(struct lcd_info *lcd, u8 *buf)
{
int ret = 0;
u8 retry_cnt = 3;
read_retry:
- ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf);
+ ret = s6e39a0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] : %s : retry cnt : %d\n",\
@@ -936,7 +940,7 @@ static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf)
}
#endif
-static int s6e8ax0_probe(struct device *dev)
+static int s6e39a0_probe(struct device *dev)
{
int ret = 0;
struct lcd_info *lcd;
@@ -955,7 +959,7 @@ static int s6e8ax0_probe(struct device *dev)
g_lcd = lcd;
lcd->ld = lcd_device_register("panel", dev, \
- lcd, &s6e8ax0_lcd_ops);
+ lcd, &s6e39a0_lcd_ops);
if (IS_ERR(lcd->ld)) {
pr_err("failed to register lcd device\n");
ret = PTR_ERR(lcd->ld);
@@ -963,7 +967,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->bd = backlight_device_register("panel", \
- dev, lcd, &s6e8ax0_backlight_ops, NULL);
+ dev, lcd, &s6e39a0_backlight_ops, NULL);
if (IS_ERR(lcd->bd)) {
pr_err("failed to register backlight device\n");
ret = PTR_ERR(lcd->bd);
@@ -999,8 +1003,8 @@ static int s6e8ax0_probe(struct device *dev)
#if 0
#ifdef CONFIG_HAS_EARLYSUSPEND
- lcd->early_suspend.suspend = s6e8ax0_early_suspend;
- lcd->early_suspend.resume = s6e8ax0_late_resume;
+ lcd->early_suspend.suspend = s6e39a0_early_suspend;
+ lcd->early_suspend.resume = s6e39a0_late_resume;
lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;
register_early_suspend(&lcd->early_suspend);
#endif
@@ -1008,7 +1012,7 @@ static int s6e8ax0_probe(struct device *dev)
mutex_init(&lcd->lock);
- s6e8ax0_read_id(lcd, idbuf);
+ s6e39a0_read_id(lcd, idbuf);
dev_info(&lcd->ld->dev, "ID : %x, %x, %x\n", idbuf[0], idbuf[1], idbuf[2]);
@@ -1020,7 +1024,7 @@ static int s6e8ax0_probe(struct device *dev)
init_table_info(&lcd->smart);
- ret = s6e8ax0_read_mtp(lcd, mtp_data);
+ ret = s6e39a0_read_mtp(lcd, mtp_data);
if (!ret) {
printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
/*return -EPERM;*/
@@ -1030,9 +1034,12 @@ static int s6e8ax0_probe(struct device *dev)
mutex_init(&lcd->bl_lock);
- s6e8ax0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
+ s6e39a0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
#endif
+ lcd_early_suspend = s6e39a0_early_suspend;
+ lcd_late_resume = s6e39a0_late_resume;
+
return 0;
out_free_backlight:
@@ -1048,11 +1055,11 @@ err_alloc:
return ret;
}
-static int __devexit s6e8ax0_remove(struct device *dev)
+static int __devexit s6e39a0_remove(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6e39a0_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
backlight_device_unregister(lcd->bd);
kfree(lcd);
@@ -1061,34 +1068,34 @@ static int __devexit s6e8ax0_remove(struct device *dev)
}
/* Power down all displays on reboot, poweroff or halt. */
-static void s6e8ax0_shutdown(struct device *dev)
+static void s6e39a0_shutdown(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
dev_info(&lcd->ld->dev, "%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6e39a0_power(lcd, FB_BLANK_POWERDOWN);
}
-static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+static struct mipi_lcd_driver s6e39a0_mipi_driver = {
.name = "s6e8aa0",
- .probe = s6e8ax0_probe,
- .remove = __devexit_p(s6e8ax0_remove),
- .shutdown = s6e8ax0_shutdown,
+ .probe = s6e39a0_probe,
+ .remove = __devexit_p(s6e39a0_remove),
+ .shutdown = s6e39a0_shutdown,
};
-static int s6e8ax0_init(void)
+static int s6e39a0_init(void)
{
- return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+ return s5p_dsim_register_lcd_driver(&s6e39a0_mipi_driver);
}
-static void s6e8ax0_exit(void)
+static void s6e39a0_exit(void)
{
return;
}
-module_init(s6e8ax0_init);
-module_exit(s6e8ax0_exit);
+module_init(s6e39a0_init);
+module_exit(s6e39a0_exit);
MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_s6e63m0.c b/drivers/video/samsung/s3cfb_s6e63m0.c
new file mode 100644
index 0000000..0babb31
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_s6e63m0.c
@@ -0,0 +1,1718 @@
+/* linux/drivers/video/samsung/s3cfb_s6e63m0.c
+ *
+ * MIPI-DSI based AMS529HA01 AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-dsim.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "s5p-dsim.h"
+#include "s3cfb.h"
+#include "s6e63m0_gamma_l.h"
+
+#if defined(CONFIG_MACH_Q1_BD)
+#include "s6e8aa0_gamma_q1.h"
+#define SMART_DIMMING
+#else
+#include "s6e63m0_gamma_grande.h"
+#define SMART_DIMMING
+#endif
+
+#ifdef SMART_DIMMING
+#include "smart_dimming.h"
+#ifdef CONFIG_AID_DIMMING
+#include "aid_s6e8aa0.h"
+#endif
+#endif
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#if defined(CONFIG_MACH_Q1_BD)
+#define MAX_GAMMA 290
+#define DEFAULT_BRIGHTNESS 150
+#define DEFAULT_GAMMA_LEVEL GAMMA_150CD
+#else
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_GAMMA_LEVEL GAMMA_160CD
+#endif
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+
+#ifdef SMART_DIMMING
+#define PANEL_A1_M3 0xA1
+
+#define LDI_MTP_LENGTH 24
+#define LDI_MTP_ADDR 0xD3
+
+#define DYNAMIC_ELVSS_MIN_VALUE 0x81
+#define DYNAMIC_ELVSS_MAX_VALUE 0x9F
+
+#define ELVSS_MODE0_MIN_VOLTAGE 62
+#define ELVSS_MODE1_MIN_VOLTAGE 52
+
+struct str_elvss {
+ u8 reference;
+ u8 limit;
+};
+#endif
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int cur_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+
+ unsigned char id[LDI_ID_LEN];
+
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+
+#ifdef SMART_DIMMING
+ unsigned int support_elvss;
+
+ struct str_smart_dim smart;
+ struct str_elvss elvss;
+#endif
+#ifdef CONFIG_AID_DIMMING
+ unsigned int support_aid;
+ unsigned char f8[ARRAY_SIZE(
+ SEQ_PANEL_CONDITION_SET_500MBPS)];
+#endif
+ unsigned int irq;
+ unsigned int connected;
+
+ struct dsim_global *dsim;
+};
+
+#ifdef CONFIG_AID_DIMMING
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 110, 120, 130, 140, 150, 160, 170, 180,
+ 182, 184, 186, 188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+static unsigned int aid_candela_table[GAMMA_MAX] = {
+ base_20to100, base_20to100, base_20to100, base_20to100,
+ base_20to100, base_20to100, base_20to100, base_20to100,
+ base_20to100,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140,
+ AOR40_BASE_150, AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180,
+ AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
+ ELVSS_OFFSET_110,
+ ELVSS_OFFSET_120,
+ ELVSS_OFFSET_130,
+ ELVSS_OFFSET_140,
+ ELVSS_OFFSET_150,
+ ELVSS_OFFSET_160,
+ ELVSS_OFFSET_170,
+ ELVSS_OFFSET_180,
+ ELVSS_OFFSET_190,
+ ELVSS_OFFSET_200,
+ ELVSS_OFFSET_210,
+ ELVSS_OFFSET_220,
+ ELVSS_OFFSET_230,
+ ELVSS_OFFSET_240,
+ ELVSS_OFFSET_250,
+ ELVSS_OFFSET_260,
+ ELVSS_OFFSET_270,
+ ELVSS_OFFSET_280,
+ ELVSS_OFFSET_290,
+ ELVSS_OFFSET_300
+};
+#else
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
+ 130, 140, 150, 160, 170, 180, 190, 200, 210, 220,
+ 230, 240, 250, MAX_GAMMA
+};
+
+static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
+ ELVSS_OFFSET_MIN,
+ ELVSS_OFFSET_1,
+ ELVSS_OFFSET_2,
+ ELVSS_OFFSET_MAX
+};
+#endif
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+struct delayed_work hs_clk_re_try;
+unsigned int count_dsim;
+
+static void hs_clk_re_try_work(struct work_struct *work)
+{
+ int read_oled_det;
+
+ read_oled_det = gpio_get_value(GPIO_OLED_DET);
+
+ printk(KERN_INFO "%s, %d, %d\n", __func__,
+ count_dsim, read_oled_det);
+
+ if (read_oled_det == 0) {
+ if (count_dsim < 10) {
+ schedule_delayed_work(&hs_clk_re_try, HZ/8);
+ count_dsim++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+}
+
+static irqreturn_t oled_det_int(int irq, void *dev_id)
+{
+ printk(KERN_INFO "[DSIM] %s\n", __func__);
+
+ schedule_delayed_work(&hs_clk_re_try, HZ/16);
+
+ count_dsim = 0;
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int s6e63m0_write(struct lcd_info *lcd,
+ const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+static int _s6e63m0_read(struct lcd_info *lcd, const u8 addr,
+ u16 count, u8 *buf)
+{
+ int ret = 0;
+
+ if (!lcd->connected)
+ return ret;
+
+ mutex_lock(&lcd->lock);
+
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6e63m0_read(struct lcd_info *lcd, const u8 addr,
+ u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _s6e63m0_read(lcd, addr, count, buf);
+ if (!ret) {
+ if (retry_cnt) {
+ printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n",
+ __func__, retry_cnt);
+ retry_cnt--;
+ goto read_retry;
+ } else
+ printk(KERN_ERR "[ERROR:LCD] %s : 0x%02x read failed\n",
+ __func__, addr);
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_AID_DIMMING
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is
+ only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_20CD;
+ break;
+ case 30 ... 39:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 40 ... 49:
+ backlightlevel = GAMMA_40CD;
+ break;
+ case 50 ... 59:
+ backlightlevel = GAMMA_50CD;
+ break;
+ case 60 ... 69:
+ backlightlevel = GAMMA_60CD;
+ break;
+ case 70 ... 79:
+ backlightlevel = GAMMA_70CD;
+ break;
+ case 80 ... 89:
+ backlightlevel = GAMMA_80CD;
+ break;
+ case 90 ... 99:
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 109:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 110 ... 119:
+ backlightlevel = GAMMA_110CD;
+ break;
+ case 120 ... 129:
+ backlightlevel = GAMMA_120CD;
+ break;
+ case 130 ... 139:
+ backlightlevel = GAMMA_130CD;
+ break;
+ case 140 ... 149:
+ backlightlevel = GAMMA_140CD;
+ break;
+ case 150 ... 159:
+ backlightlevel = GAMMA_150CD;
+ break;
+ case 160 ... 169:
+ backlightlevel = GAMMA_160CD;
+ break;
+ case 170 ... 179:
+ backlightlevel = GAMMA_170CD;
+ break;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
+ break;
+ case 190 ... 199:
+ backlightlevel = GAMMA_190CD;
+ break;
+ case 200 ... 209:
+ backlightlevel = GAMMA_200CD;
+ break;
+ case 210 ... 219:
+ backlightlevel = GAMMA_210CD;
+ break;
+ case 220 ... 229:
+ backlightlevel = GAMMA_220CD;
+ break;
+ case 230 ... 239:
+ backlightlevel = GAMMA_230CD;
+ break;
+ case 240 ... 249:
+ backlightlevel = GAMMA_240CD;
+ break;
+ case 250 ... 254:
+ backlightlevel = GAMMA_250CD;
+ break;
+ case 255:
+ backlightlevel = GAMMA_300CD;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+static int s6e63m0_gamma_ctl(struct lcd_info *lcd)
+{
+ lcd->f8[0x12] = aid_command_table[lcd->bl][0];
+ lcd->f8[0x01] = aid_command_table[lcd->bl][1];
+
+ s6e63m0_write(lcd, lcd->gamma_table[lcd->bl],
+ GAMMA_PARAM_SIZE);
+ s6e63m0_write(lcd, SEQ_GAMMA_UPDATE,
+ ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+
+ if (likely(lcd->support_aid))
+ s6e63m0_write(lcd, lcd->f8, AID_PARAM_SIZE);
+
+ return 0;
+}
+#else
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is
+ only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 30 ... 254:
+ backlightlevel = (brightness - candela_table[0]) / 10;
+ break;
+ case 255:
+ backlightlevel = ARRAY_SIZE(candela_table) - 1;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+static int s6e63m0_gamma_ctl(struct lcd_info *lcd)
+{
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+ s6e63m0_write(lcd, SEQ_GAMMA_CONDITION_SET,
+ ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+#else
+ s6e63m0_write(lcd, lcd->gamma_table[lcd->bl],
+ GAMMA_PARAM_SIZE);
+#endif
+
+ /* Gamma Set Update */
+ s6e63m0_write(lcd, SEQ_GAMMA_UPDATE,
+ ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MACH_Q1_BD)
+static int s6e63m0_set_acl(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ if (lcd->acl_enable) {
+ if (lcd->cur_acl == 0) {
+ if (lcd->bl == 0 || lcd->bl == 1) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF,
+ ARRAY_SIZE(SEQ_ACL_OFF));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_ON,
+ ARRAY_SIZE(SEQ_ACL_ON));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n",
+ __func__, lcd->cur_acl);
+ }
+ }
+ switch (lcd->bl) {
+ case GAMMA_30CD... GAMMA_40CD:
+ if (lcd->cur_acl != 0) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF,
+ ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_50CD:
+ if (lcd->cur_acl != 200) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 200;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_60CD:
+ if (lcd->cur_acl != 330) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 330;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_70CD:
+ if (lcd->cur_acl != 430) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_43P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 430;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_80CD:
+ if (lcd->cur_acl != 450) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P_80CD],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 450;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_90CD ... GAMMA_150CD:
+ if (lcd->cur_acl != 451) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 451;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_160CD: /* 160cd */
+ if (lcd->cur_acl != 460) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P_160CD],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 460;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_170CD ... GAMMA_250CD:
+ if (lcd->cur_acl != 461) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P],
+ `ACL_PARAM_SIZE);
+ lcd->cur_acl = 461;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ default:
+ if (lcd->cur_acl != 550) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 550;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ }
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ }
+
+ if (ret) {
+ ret = -EPERM;
+ goto acl_err;
+ }
+
+acl_err:
+ return ret;
+}
+#else
+static int s6e63m0_set_acl(struct lcd_info *lcd)
+{
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ if (lcd->acl_enable) {
+ if (lcd->cur_acl == 0) {
+ if (lcd->bl == 0 || lcd->bl == 1) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n",
+ __func__, lcd->cur_acl);
+ }
+ }
+ switch (lcd->bl) {
+ case GAMMA_20CD ... GAMMA_40CD: /* 30cd ~ 40cd - 0%*/
+ if (lcd->cur_acl != 0) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_50CD: /* 50cd - 20%*/
+ if (lcd->cur_acl != 20) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 20;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_60CD: /* 60cd - 33%*/
+ if (lcd->cur_acl != 33) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 33;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_70CD ... GAMMA_250CD: /*70cd ~ 250cd - 40%*/
+ if (lcd->cur_acl != 40) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_40P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 40;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ default:
+ if (lcd->cur_acl != 50) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 50;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ }
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ }
+#endif
+
+ return 0;
+}
+#endif
+
+#ifdef SMART_DIMMING
+#ifdef CONFIG_AID_DIMMING
+static int s6e63m0_set_elvss(struct lcd_info *lcd)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = aid_candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 110:
+ elvss_level = ELVSS_110;
+ break;
+ case 111 ... 120:
+ elvss_level = ELVSS_120;
+ break;
+ case 121 ... 130:
+ elvss_level = ELVSS_130;
+ break;
+ case 131 ... 140:
+ elvss_level = ELVSS_140;
+ break;
+ case 141 ... 150:
+ elvss_level = ELVSS_150;
+ break;
+ case 151 ... 160:
+ elvss_level = ELVSS_160;
+ break;
+ case 161 ... 170:
+ elvss_level = ELVSS_170;
+ break;
+ case 171 ... 180:
+ elvss_level = ELVSS_180;
+ break;
+ case 181 ... 190:
+ elvss_level = ELVSS_190;
+ break;
+ case 191 ... 200:
+ elvss_level = ELVSS_200;
+ break;
+ case 201 ... 210:
+ elvss_level = ELVSS_210;
+ break;
+ case 211 ... 220:
+ elvss_level = ELVSS_220;
+ break;
+ case 221 ... 230:
+ elvss_level = ELVSS_230;
+ break;
+ case 231 ... 240:
+ elvss_level = ELVSS_240;
+ break;
+ case 241 ... 250:
+ elvss_level = ELVSS_250;
+ break;
+ case 251 ... 260:
+ elvss_level = ELVSS_260;
+ break;
+ case 261 ... 270:
+ elvss_level = ELVSS_270;
+ break;
+ case 271 ... 280:
+ elvss_level = ELVSS_280;
+ break;
+ case 281 ... 290:
+ elvss_level = ELVSS_290;
+ break;
+ case 291 ... 300:
+ elvss_level = ELVSS_300;
+ break;
+ }
+
+ if (lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ ret = s6e63m0_write(lcd, lcd->elvss_table[elvss_level],
+ ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][2];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n",
+ lcd->elvss_table[elvss_level][2]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+#else
+static int s6e63m0_set_elvss(struct lcd_info *lcd)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 100:
+ elvss_level = ELVSS_MIN;
+ break;
+ case 101 ... 160:
+ elvss_level = ELVSS_1;
+ break;
+ case 161 ... 200:
+ elvss_level = ELVSS_2;
+ break;
+ case 201 ... 300:
+ elvss_level = ELVSS_MAX;
+ break;
+ default:
+ break;
+ }
+
+ if (lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ ret = s6e63m0_write(lcd, lcd->elvss_table[elvss_level],
+ ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][2];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n",
+ lcd->elvss_table[elvss_level][2]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+#endif
+static u8 get_elvss_value(struct lcd_info *lcd, u8 elvss_level)
+{
+ u8 ref = 0;
+ u8 offset;
+
+ if (lcd->elvss.limit == 0x00)
+ ref = (lcd->elvss.reference | 0x80);
+ else if (lcd->elvss.limit == 0x01)
+ ref = (lcd->elvss.reference + 0x40);
+ else {
+ printk(KERN_ERR "[ERROR:ELVSS]:%s undefined elvss limit value :%x\n",
+ __func__, lcd->elvss.limit);
+ return 0;
+ }
+
+ offset = elvss_offset_table[elvss_level];
+ ref += offset;
+
+ if (ref < DYNAMIC_ELVSS_MIN_VALUE)
+ ref = DYNAMIC_ELVSS_MIN_VALUE;
+ else if (ref > DYNAMIC_ELVSS_MAX_VALUE)
+ ref = DYNAMIC_ELVSS_MAX_VALUE;
+
+ return ref;
+}
+
+static int init_elvss_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+#ifdef SMART_DIMMING_DEBUG
+ int j;
+#endif
+
+ lcd->elvss_table = kzalloc(ELVSS_STATUS_MAX * sizeof(u8 *), GFP_KERNEL);
+
+ if (IS_ERR_OR_NULL(lcd->elvss_table)) {
+ pr_err("failed to allocate elvss table\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss_table;
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ lcd->elvss_table[i] = kzalloc(ELVSS_PARAM_SIZE * sizeof(u8),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->elvss_table[i])) {
+ pr_err("failed to allocate elvss\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss;
+ }
+ lcd->elvss_table[i][0] = 0xB1;
+ lcd->elvss_table[i][1] = 0x04;
+ lcd->elvss_table[i][2] = get_elvss_value(lcd, i);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->elvss_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+
+ return 0;
+
+err_alloc_elvss:
+ while (i > 0) {
+ kfree(lcd->elvss_table[i-1]);
+ i--;
+ }
+ kfree(lcd->elvss_table);
+err_alloc_elvss_table:
+ return ret;
+}
+
+#ifdef CONFIG_AID_DIMMING
+static int init_gamma_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xFA;
+ lcd->gamma_table[i][1] = 0x01;
+ }
+
+ for (i = GAMMA_20CD; i <= GAMMA_180CD; i++)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i],
+ &lcd->gamma_table[i][2], G_21);
+
+ for (i = GAMMA_182CD; i < GAMMA_MAX; i++) {
+ if ((i > GAMMA_188CD) && (i < GAMMA_200CD))
+ calc_gamma_table_215_190(&lcd->smart,
+ aid_candela_table[i], &lcd->gamma_table[i][2]);
+ if ((i > GAMMA_250CD) && (i < GAMMA_MAX))
+ calc_gamma_table(&lcd->smart, aid_candela_table[i],
+ &lcd->gamma_table[i][2], G_22);
+ else
+ calc_gamma_table(&lcd->smart, aid_candela_table[i],
+ &lcd->gamma_table[i][2], G_215);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("%d, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+
+static int init_aid_dimming_table(struct lcd_info *lcd)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table); i++) {
+ j = (aid_rgb_fix_table[i].gray * 3
+ + aid_rgb_fix_table[i].rgb) + 2;
+ lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j]
+ += aid_rgb_fix_table[i].offset;
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("%d, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+ return 0;
+}
+#else
+static int init_gamma_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xFA;
+ lcd->gamma_table[i][1] = 0x01;
+ calc_gamma_table(&lcd->smart, candela_table[i]-1,
+ lcd->gamma_table[i]+2);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+#endif
+#endif
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ int ret;
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) &&
+ (lcd->current_bl != lcd->bl))) {
+
+ ret = s6e63m0_gamma_ctl(lcd);
+ /*ret = s6e63m0_set_acl(lcd);*/
+ /* W2013 temp block */
+ /*ret = s6e63m0_set_elvss(lcd);*/
+ /* W2013 temp block */
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n",
+ brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int s6e63m0_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+ mdelay(25); /* 25ms */
+ s6e63m0_write(lcd, SEQ_SW_RESET,
+ ARRAY_SIZE(SEQ_SW_RESET)); /* SW Reset */
+ mdelay(5); /* Wait 5ms more */
+ s6e63m0_write(lcd, SEQ_APPLY_LEVEL2_KEY_ENABLE,
+ ARRAY_SIZE(SEQ_APPLY_LEVEL2_KEY_ENABLE));
+ s6e63m0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE,
+ ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6e63m0_write(lcd, SEQ_SLEEP_OUT,
+ ARRAY_SIZE(SEQ_SLEEP_OUT));
+ mdelay(10); /* 10ms */
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET1,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET1));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET2,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET2));
+ s6e63m0_write(lcd, SEQ_GAMMA_CONDITION_SET,
+ ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ s6e63m0_write(lcd, SEQ_GAMMA_UPDATE,
+ ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B3h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B3h));
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B5h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B5h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B6h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B6h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B7h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B7h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B8h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B8h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B9h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B9h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_BAh,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_BAh));
+#endif
+ s6e63m0_write(lcd, SEQ_ELVSS_SET, ARRAY_SIZE(SEQ_ELVSS_SET));
+ s6e63m0_write(lcd, SEQ_ELVSS_ON, ARRAY_SIZE(SEQ_ELVSS_ON));
+
+#elif defined(CONFIG_MACH_Q1_BD)
+ s6e63m0_write(lcd, SEQ_APPLY_LEVEL_2_KEY,
+ ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
+ msleep(20);
+ s6e63m0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(5);
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
+ s6e63m0_write(lcd, SEQ_ELVSS_NVM_SETTING,
+ ARRAY_SIZE(SEQ_ELVSS_NVM_SETTING));
+ s6e63m0_write(lcd, SEQ_ELVSS_CONTROL,
+ ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+#else
+ s6e63m0_write(lcd, SEQ_APPLY_LEVEL_2,
+ ARRAY_SIZE(SEQ_APPLY_LEVEL_2));
+ s6e63m0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE,
+ ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6e63m0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(5);
+
+ if (lcd->id[1] == 0x20) { /* 4.8" HD for M0/C1*/
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET_500MBPS,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_500MBPS));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_NVM_SETTING,
+ ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
+ } else if (lcd->id[1] == 0xae) {
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET_480MBPS_46,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_480MBPS_46));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL_46));
+ s6e63m0_write(lcd, SEQ_ETC_NVM_SETTING_46,
+ ARRAY_SIZE(SEQ_ETC_NVM_SETTING_46));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL_46));
+ } else {
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET_500MBPS_46,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_500MBPS_46));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL_46));
+ s6e63m0_write(lcd, SEQ_ETC_NVM_SETTING_46,
+ ARRAY_SIZE(SEQ_ETC_NVM_SETTING_46));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL_46));
+ }
+
+ s6e63m0_write(lcd, SEQ_ELVSS_CONTROL,
+ ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+#endif
+
+ return ret;
+}
+
+static int s6e63m0_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e63m0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int s6e63m0_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e63m0_write(lcd, SEQ_DISPLAY_OFF,
+ ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6e63m0_write(lcd, SEQ_STANDBY_ON,
+ ARRAY_SIZE(SEQ_STANDBY_ON));
+
+ return ret;
+}
+
+static int s6e63m0_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ /* dev_info(&lcd->ld->dev, "%s\n", __func__); */
+
+ ret = s6e63m0_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = s6e63m0_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int s6e63m0_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = s6e63m0_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int s6e63m0_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = s6e63m0_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = s6e63m0_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int s6e63m0_set_power(struct lcd_device *ld, int power)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(&lcd->ld->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return s6e63m0_power(lcd, power);
+}
+
+static int s6e63m0_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int s6e63m0_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n",
+ __func__, brightness); */
+
+ if (brightness < MIN_BRIGHTNESS ||
+ brightness > bd->props.max_brightness) {
+ dev_err(&bd->dev, "lcd brightness should be %d to %d. now %d\n",
+ MIN_BRIGHTNESS, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int s6e63m0_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static struct lcd_ops s6e63m0_lcd_ops = {
+ .set_power = s6e63m0_set_power,
+ .get_power = s6e63m0_get_power,
+};
+
+static const struct backlight_ops s6e63m0_backlight_ops = {
+ .get_brightness = s6e63m0_get_brightness,
+ .update_status = s6e63m0_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0,
+ (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ if (lcd->ldi_enable)
+ s6e63m0_set_acl(lcd);
+ mutex_unlock(&lcd->bl_lock);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show,
+ power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+#if defined(CONFIG_MACH_Q1_BD)
+ sprintf(temp, "SMD_AMS529HA01\n");
+#else
+ sprintf(temp, "SMD_AMS480GYXX\n");
+#endif
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t gamma_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int i, j;
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->elvss_table[i][j]);
+ pr_info("\n");
+ }
+
+ return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 0);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show,
+ auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+struct lcd_info *g_lcd;
+
+void s6e63m0_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+ s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void s6e63m0_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6e63m0_power(lcd, FB_BLANK_UNBLANK);
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+#ifdef CONFIG_INPUT_FLIP
+void samsung_switching_lcd_suspend(int init, int flip)
+{
+ pr_info("%s: flip %s\n", __func__, (flip) ? "OPEN" : "CLOSE");
+ s6e63m0_early_suspend();/*LCD suspend*/
+ s5p_dsim_early_suspend();/*MIPI suspend*/
+}
+EXPORT_SYMBOL(samsung_switching_lcd_suspend);
+
+void samsung_switching_lcd_resume(int init, int flip)
+{
+ pr_info("%s: flip %s\n", __func__, (flip) ? "OPEN" : "CLOSE");
+ s5p_dsim_late_resume();/*MIPI wakeup*/
+#if 0
+ if (s5p_dsim_fifo_clear() == 0) {
+ s5p_dsim_early_suspend();
+ msleep(10);
+ s5p_dsim_late_resume();
+ if (s5p_dsim_fifo_clear() == 0)
+ pr_info("dsim resume fail!!!\n");
+ }
+#endif
+ s6e63m0_late_resume();/*LCD wakeup*/
+}
+EXPORT_SYMBOL(samsung_switching_lcd_resume);
+#endif
+
+static void s6e63m0_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = s6e63m0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+#ifdef SMART_DIMMING
+static int s6e63m0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret;
+
+ ret = s6e63m0_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data, 0);
+
+ return ret;
+}
+
+#if defined(CONFIG_MACH_Q1_BD)
+static void s6e63m0_check_id(struct lcd_info *lcd, u8 *idbuf)
+{
+ u32 i;
+
+ for (i = 0; i < LDI_ID_LEN; i++)
+ lcd->smart.panelid[i] = idbuf[i];
+
+ if (idbuf[2] == 0x33)
+ lcd->support_elvss = 0;
+ else {
+ lcd->support_elvss = 1;
+ lcd->elvss.limit = (idbuf[2] & 0xc0) >> 6;
+ lcd->elvss.reference = idbuf[2] & 0x3f;
+ printk(KERN_DEBUG "Dynamic ELVSS Information, 0x%x\n",
+ lcd->elvss.reference);
+ }
+}
+#else
+static void s6e63m0_check_id(struct lcd_info *lcd, u8 *idbuf)
+{
+ int i;
+
+ for (i = 0; i < LDI_ID_LEN; i++)
+ lcd->smart.panelid[i] = idbuf[i];
+
+ if (idbuf[0] == PANEL_A1_M3)
+ lcd->support_elvss = 0;
+ else {
+ lcd->support_elvss = 1;
+ lcd->elvss.reference = idbuf[2] & (BIT(0) | BIT(1) |
+ BIT(2) | BIT(3) | BIT(4));
+ printk(KERN_DEBUG "Dynamic ELVSS Information, 0x%x\n",
+ lcd->elvss.reference);
+ }
+}
+#endif
+#endif
+
+static int s6e63m0_probe(struct device *dev)
+{
+ int ret = 0;
+ struct lcd_info *lcd;
+#ifdef SMART_DIMMING
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+#endif
+
+ lcd = kzalloc(sizeof(struct lcd_info), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ g_lcd = lcd;
+
+ lcd->ld = lcd_device_register("panel", dev, lcd, &s6e63m0_lcd_ops);
+ if (IS_ERR(lcd->ld)) {
+ pr_err("failed to register lcd device\n");
+ ret = PTR_ERR(lcd->ld);
+ goto out_free_lcd;
+ }
+
+ lcd->bd = backlight_device_register("panel", dev, lcd,
+ &s6e63m0_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+
+ lcd->acl_enable = 0;
+ lcd->cur_acl = 0;
+
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_gamma_table);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ s6e63m0_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0],
+ lcd->id[1], lcd->id[2]);
+#endif
+
+ dev_info(&lcd->ld->dev, "s6e63m0 lcd panel driver has been probed.\n");
+
+#ifdef SMART_DIMMING
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ s6e63m0_check_id(lcd, lcd->id);
+#endif
+
+ init_table_info(&lcd->smart);
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ ret = s6e63m0_read_mtp(lcd, mtp_data);
+ if (!ret) {
+ printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
+ /*return -EPERM;*/
+ }
+#endif
+
+ calc_voltage_table(&lcd->smart, mtp_data);
+
+ if (lcd->support_elvss)
+ ret = init_elvss_table(lcd);
+
+ ret = init_gamma_table(lcd);
+
+#ifdef CONFIG_AID_DIMMING
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ if (lcd->id[1] == 0x20) {
+ printk(KERN_INFO "AID Dimming is started\n");
+ lcd->support_aid = 1;
+ ret += init_aid_dimming_table(lcd);
+ memcpy(lcd->f8, SEQ_PANEL_CONDITION_SET_500MBPS,
+ AID_PARAM_SIZE);
+ }
+#endif
+#endif
+
+ if (ret) {
+ lcd->gamma_table = (unsigned char **)gamma22_table;
+ lcd->elvss_table = (unsigned char **)ELVSS_TABLE;
+ }
+
+ update_brightness(lcd, 1);
+#endif
+
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&hs_clk_re_try, hs_clk_re_try_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ if (request_irq(lcd->irq, oled_det_int,
+ IRQF_TRIGGER_FALLING, "esd_detection", 0))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = s6e63m0_early_suspend;
+ lcd_late_resume = s6e63m0_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit s6e63m0_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6e63m0_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver s6e63m0_mipi_driver = {
+ .name = "s6e63m0",
+ .probe = s6e63m0_probe,
+ .remove = __devexit_p(s6e63m0_remove),
+ .shutdown = s6e63m0_shutdown,
+};
+
+static int s6e63m0_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&s6e63m0_mipi_driver);
+}
+
+static void s6e63m0_exit(void)
+{
+ return;
+}
+
+module_init(s6e63m0_init);
+module_exit(s6e63m0_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI S6E63M0:AMS397GEXX (480X800) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_s6e8aa0.c b/drivers/video/samsung/s3cfb_s6e8aa0.c
index ff94492..00b543e 100644
--- a/drivers/video/samsung/s3cfb_s6e8aa0.c
+++ b/drivers/video/samsung/s3cfb_s6e8aa0.c
@@ -88,7 +88,7 @@ struct lcd_info {
unsigned int bl;
unsigned int auto_brightness;
unsigned int acl_enable;
- unsigned int cur_acl;
+ unsigned int current_acl;
unsigned int current_bl;
unsigned int current_elvss;
@@ -131,6 +131,7 @@ struct lcd_info {
#ifdef CONFIG_AID_DIMMING
static const unsigned int candela_table[GAMMA_MAX] = {
20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 102, 104, 106, 108,
110, 120, 130, 140, 150, 160, 170, 180,
182, 184, 186, 188,
190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
@@ -138,9 +139,9 @@ static const unsigned int candela_table[GAMMA_MAX] = {
static unsigned int aid_candela_table[GAMMA_MAX] = {
base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100,
- AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150,
- AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180, AOR40_BASE_182, AOR40_BASE_184,
- AOR40_BASE_186, AOR40_BASE_188,
+ AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150, AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180,
+ AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188,
190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
};
@@ -181,6 +182,9 @@ static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
};
#endif
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
#if defined(GPIO_OLED_DET)
static void oled_detection_work(struct work_struct *work)
{
@@ -286,76 +290,100 @@ static int get_backlight_level_from_brightness(int brightness)
switch (brightness) {
case 0 ... 29:
- backlightlevel = GAMMA_30CD; //GAMMA_20CD;
+ backlightlevel = GAMMA_20CD;
break;
case 30 ... 39:
- backlightlevel = GAMMA_40CD; //GAMMA_30CD;
+ backlightlevel = GAMMA_30CD;
break;
case 40 ... 49:
- backlightlevel = GAMMA_50CD; //GAMMA_40CD;
+ backlightlevel = GAMMA_40CD;
break;
case 50 ... 59:
- backlightlevel = GAMMA_60CD; //GAMMA_50CD;
+ backlightlevel = GAMMA_50CD;
break;
case 60 ... 69:
- backlightlevel = GAMMA_70CD; //GAMMA_60CD;
+ backlightlevel = GAMMA_60CD;
break;
case 70 ... 79:
- backlightlevel = GAMMA_80CD; //GAMMA_70CD;
+ backlightlevel = GAMMA_70CD;
break;
case 80 ... 89:
- backlightlevel = GAMMA_90CD; //GAMMA_80CD;
+ backlightlevel = GAMMA_80CD;
break;
case 90 ... 99:
- backlightlevel = GAMMA_100CD; //GAMMA_90CD;
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 101:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 102 ... 103:
+ backlightlevel = GAMMA_102CD;
+ break;
+ case 104 ... 105:
+ backlightlevel = GAMMA_104CD;
+ break;
+ case 106 ... 107:
+ backlightlevel = GAMMA_106CD;
break;
- case 100 ... 109:
- backlightlevel = GAMMA_110CD; //GAMMA_100CD;
+ case 108 ... 109:
+ backlightlevel = GAMMA_108CD;
break;
case 110 ... 119:
- backlightlevel = GAMMA_130CD; //GAMMA_110CD;
+ backlightlevel = GAMMA_110CD;
break;
case 120 ... 129:
- backlightlevel = GAMMA_140CD; //GAMMA_120CD;
+ backlightlevel = GAMMA_120CD;
break;
case 130 ... 139:
- backlightlevel = GAMMA_150CD; //GAMMA_130CD;
+ backlightlevel = GAMMA_130CD;
break;
case 140 ... 149:
- backlightlevel = GAMMA_160CD; //GAMMA_140CD;
+ backlightlevel = GAMMA_140CD;
break;
case 150 ... 159:
- backlightlevel = GAMMA_180CD; //GAMMA_150CD;
+ backlightlevel = GAMMA_150CD;
break;
case 160 ... 169:
- backlightlevel = GAMMA_190CD; //GAMMA_160CD;
+ backlightlevel = GAMMA_160CD;
break;
case 170 ... 179:
- backlightlevel = GAMMA_200CD; //GAMMA_170CD;
+ backlightlevel = GAMMA_170CD;
break;
- case 180 ... 189:
- backlightlevel = GAMMA_210CD;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
break;
case 190 ... 199:
- backlightlevel = GAMMA_220CD; //GAMMA_190CD;
+ backlightlevel = GAMMA_190CD;
break;
case 200 ... 209:
- backlightlevel = GAMMA_230CD; //GAMMA_200CD;
+ backlightlevel = GAMMA_200CD;
break;
case 210 ... 219:
- backlightlevel = GAMMA_240CD; //GAMMA_210CD;
+ backlightlevel = GAMMA_210CD;
break;
case 220 ... 229:
- backlightlevel = GAMMA_240CD; //GAMMA_220CD;
+ backlightlevel = GAMMA_220CD;
break;
case 230 ... 239:
- backlightlevel = GAMMA_250CD; //GAMMA_230CD;
+ backlightlevel = GAMMA_230CD;
break;
case 240 ... 249:
- backlightlevel = GAMMA_250CD; //GAMMA_240CD;
+ backlightlevel = GAMMA_240CD;
break;
case 250 ... 254:
- backlightlevel = GAMMA_300CD; //GAMMA_250CD;
+ backlightlevel = GAMMA_250CD;
break;
case 255:
backlightlevel = GAMMA_300CD;
@@ -367,14 +395,24 @@ static int get_backlight_level_from_brightness(int brightness)
return backlightlevel;
}
-static int s6e8ax0_aid_parameter_ctl(struct lcd_info *lcd , u8 force)
+static int s6e8ax0_aid_parameter_ctl(struct lcd_info *lcd, u8 force)
{
- if (likely(lcd->support_aid)) {
- if ((lcd->f8[lcd->bl][0x12] != lcd->f8[lcd->current_bl][0x12]) ||
- (lcd->f8[lcd->bl][0x01] != lcd->f8[lcd->current_bl][0x01]) || (force))
- s6e8ax0_write(lcd, lcd->f8[lcd->bl], AID_PARAM_SIZE);
- }
+ if (unlikely(!lcd->support_aid))
+ goto exit;
+
+ if (force)
+ goto aid_update;
+ else if (aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0])
+ goto aid_update;
+ else if (aid_command_table[lcd->bl][1] != aid_command_table[lcd->current_bl][1])
+ goto aid_update;
+ else
+ goto exit;
+aid_update:
+ s6e8ax0_write(lcd, lcd->f8[lcd->bl], AID_PARAM_SIZE);
+
+exit:
return 0;
}
#else
@@ -414,149 +452,112 @@ static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
}
#if defined(CONFIG_S6E8AA0_AMS529HA01)
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force)
{
- int ret = 0;
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0 || lcd->bl == 1) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- }
- switch (lcd->bl) {
- case GAMMA_30CD... GAMMA_40CD:
- if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_50CD:
- if (lcd->cur_acl != 200) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P], ACL_PARAM_SIZE);
- lcd->cur_acl = 200;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_60CD:
- if (lcd->cur_acl != 330) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P], ACL_PARAM_SIZE);
- lcd->cur_acl = 330;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_70CD:
- if (lcd->cur_acl != 430) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_43P], ACL_PARAM_SIZE);
- lcd->cur_acl = 430;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_80CD:
- if (lcd->cur_acl != 450) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P_80CD], ACL_PARAM_SIZE);
- lcd->cur_acl = 450;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_90CD ... GAMMA_150CD:
- if (lcd->cur_acl != 451) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P], ACL_PARAM_SIZE);
- lcd->cur_acl = 451;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_160CD: /* 160cd */
- if (lcd->cur_acl != 460) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P_160CD], ACL_PARAM_SIZE);
- lcd->cur_acl = 460;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_170CD ... GAMMA_250CD:
- if (lcd->cur_acl != 461) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P], ACL_PARAM_SIZE);
- lcd->cur_acl = 461;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 550) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P], ACL_PARAM_SIZE);
- lcd->cur_acl = 550;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
+ switch (candela) {
+ case 0 ... 49:
+ level = ACL_STATUS_0P;
+ break;
+ case 50 ... 59:
+ level = ACL_STATUS_20P;
+ break;
+ case 60 ... 69:
+ level = ACL_STATUS_33P;
+ break;
+ case 70 ... 79:
+ level = ACL_STATUS_43P;
+ break;
+ case 80 ... 89:
+ level = ACL_STATUS_45P_80CD;
+ break;
+ case 90 ... 159:
+ level = ACL_STATUS_45P;
+ break;
+ case 160 ... 169:
+ level = ACL_STATUS_46P_160CD;
+ break;
+ case 170 ... 250:
+ level = ACL_STATUS_46P;
+ break;
+ default:
+ level = ACL_STATUS_50P;
+ break;
}
- if (ret) {
+ if (!lcd->acl_enable)
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ else {
+ ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
ret = -EPERM;
- goto acl_err;
- }
-acl_err:
+exit:
return ret;
}
#else
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force)
{
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- }
- switch (lcd->bl) {
- case 0:
- if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case 1:
- if (lcd->cur_acl != 33) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P], ACL_PARAM_SIZE);
- lcd->cur_acl = 33;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case 2 ... GAMMA_250CD:
- if (lcd->cur_acl != 40) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_40P], ACL_PARAM_SIZE);
- lcd->cur_acl = 40;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 50) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P], ACL_PARAM_SIZE);
- lcd->cur_acl = 50;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 29:
+ level = ACL_STATUS_0P;
+ break;
+ case 30 ... 39:
+ level = ACL_STATUS_33P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
}
- return 0;
+ if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5))
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ else {
+ ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
+ ret = -EPERM;
+
+exit:
+ return ret;
}
#endif
@@ -630,7 +631,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force)
break;
}
- if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) {
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
lcd->current_elvss = lcd->elvss_table[elvss_level][2];
}
@@ -668,7 +669,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force)
break;
}
- if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) {
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
lcd->current_elvss = lcd->elvss_table[elvss_level][2];
}
@@ -893,16 +894,12 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
lcd->bl = get_backlight_level_from_brightness(brightness);
if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+ s6e8ax0_gamma_ctl(lcd);
#ifdef CONFIG_AID_DIMMING
- if ((force) || unlikely(aid_candela_table[lcd->bl] != aid_candela_table[lcd->current_bl]))
-#endif
- s6e8ax0_gamma_ctl(lcd);
-
-#ifdef CONFIG_AID_DIMMING
- s6e8ax0_aid_parameter_ctl(lcd , force);
+ s6e8ax0_aid_parameter_ctl(lcd, force);
#endif
- s6e8ax0_set_acl(lcd);
+ s6e8ax0_set_acl(lcd, force);
s6e8ax0_set_elvss(lcd, force);
@@ -1152,9 +1149,9 @@ static ssize_t power_reduce_store(struct device *dev,
dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
mutex_lock(&lcd->bl_lock);
lcd->acl_enable = value;
- if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd);
mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
}
}
return size;
@@ -1228,7 +1225,7 @@ static ssize_t auto_brightness_store(struct device *dev,
lcd->auto_brightness = value;
mutex_unlock(&lcd->bl_lock);
if (lcd->ldi_enable)
- update_brightness(lcd, 0);
+ update_brightness(lcd, 1);
}
}
return size;
@@ -1336,6 +1333,29 @@ static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf)
#endif
#endif
+static ssize_t read_acl_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char *pos = buf;
+ char temp[ACL_PARAM_SIZE] = {0,};
+ u32 i;
+
+ s6e8ax0_read(lcd, 0xC0, 3, temp, 0);
+ pos += sprintf(pos, "0xC0=0x%02x, 0x%02x\n", temp[0], temp[1]);
+
+ s6e8ax0_read(lcd, 0xC1, ACL_PARAM_SIZE, temp, 0);
+ for (i = 0; i < ACL_PARAM_SIZE; i++) {
+ pos += sprintf(pos, "0x%02x, ", temp[i]);
+ if ((i % 5) == 0)
+ pos += sprintf(pos, "\n");
+ }
+ pos += sprintf(pos, "\n");
+
+ return pos - buf;
+}
+static DEVICE_ATTR(read_acl, 0444, read_acl_show, NULL);
+
static int s6e8ax0_probe(struct device *dev)
{
int ret = 0;
@@ -1375,7 +1395,7 @@ static int s6e8ax0_probe(struct device *dev)
lcd->current_bl = lcd->bl;
lcd->acl_enable = 0;
- lcd->cur_acl = 0;
+ lcd->current_acl = 0;
lcd->power = FB_BLANK_UNBLANK;
lcd->ldi_enable = 1;
@@ -1394,6 +1414,10 @@ static int s6e8ax0_probe(struct device *dev)
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_read_acl);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
@@ -1461,6 +1485,10 @@ static int s6e8ax0_probe(struct device *dev)
pr_err("failed to reqeust irq. %d\n", lcd->irq);
}
#endif
+
+ lcd_early_suspend = s6e8ax0_early_suspend;
+ lcd_late_resume = s6e8ax0_late_resume;
+
return 0;
out_free_backlight:
@@ -1518,5 +1546,5 @@ static void s6e8ax0_exit(void)
module_init(s6e8ax0_init);
module_exit(s6e8ax0_exit);
-MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_DESCRIPTION("MIPI-DSI S6E8AA0: AMS529HA01 (800x1280) / AMS480GYXX (720x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_s6e8ab0.c b/drivers/video/samsung/s3cfb_s6e8ab0.c
index bc47c37..76a98d9 100644
--- a/drivers/video/samsung/s3cfb_s6e8ab0.c
+++ b/drivers/video/samsung/s3cfb_s6e8ab0.c
@@ -75,7 +75,7 @@ struct str_elvss {
struct lcd_info {
unsigned int bl;
unsigned int acl_enable;
- unsigned int cur_acl;
+ unsigned int current_acl;
unsigned int current_bl;
unsigned int ldi_enable;
@@ -105,6 +105,9 @@ struct lcd_info {
struct dsim_global *dsim;
};
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
@@ -165,101 +168,6 @@ read_retry:
return ret;
}
-#if 0
-static int get_backlight_level_from_brightness(int brightness)
-{
- int backlightlevel;
-
- /* brightness setting from platform is from 0 to 255
- * But in this driver, brightness is only supported from 0 to 24 */
-
- switch (brightness) {
- case 0:
- backlightlevel = GAMMA_30CD;
- break;
- case 1 ... 29:
- backlightlevel = GAMMA_30CD;
- break;
- case 30 ... 34:
- backlightlevel = GAMMA_40CD;
- break;
- case 35 ... 44:
- backlightlevel = GAMMA_50CD;
- break;
- case 45 ... 54:
- backlightlevel = GAMMA_60CD;
- break;
- case 55 ... 64:
- backlightlevel = GAMMA_70CD;
- break;
- case 65 ... 74:
- backlightlevel = GAMMA_80CD;
- break;
- case 75 ... 83:
- backlightlevel = GAMMA_90CD;
- break;
- case 84 ... 93:
- backlightlevel = GAMMA_100CD;
- break;
- case 94 ... 103:
- backlightlevel = GAMMA_105CD;
- break;
- case 104 ... 113:
- backlightlevel = GAMMA_110CD;
- break;
- case 114 ... 122:
- backlightlevel = GAMMA_120CD;
- break;
- case 123 ... 132:
- backlightlevel = GAMMA_130CD;
- break;
- case 133 ... 142:
- backlightlevel = GAMMA_140CD;
- break;
- case 143 ... 152:
- backlightlevel = GAMMA_150CD;
- break;
- case 153 ... 162:
- backlightlevel = GAMMA_160CD;
- break;
- case 163 ... 171:
- backlightlevel = GAMMA_170CD;
- break;
- case 172 ... 181:
- backlightlevel = GAMMA_180CD;
- break;
- case 182 ... 191:
- backlightlevel = GAMMA_190CD;
- break;
- case 192 ... 201:
- backlightlevel = GAMMA_200CD;
- break;
- case 202 ... 210:
- backlightlevel = GAMMA_205CD;
- break;
- case 211 ... 220:
- backlightlevel = GAMMA_210CD;
- break;
- case 221 ... 230:
- backlightlevel = GAMMA_220CD;
- break;
- case 231 ... 240:
- backlightlevel = GAMMA_230CD;
- break;
- case 241 ... 250:
- backlightlevel = GAMMA_240CD;
- break;
- case 251 ... 255:
- backlightlevel = GAMMA_250CD;
- break;
- default:
- backlightlevel = DEFAULT_GAMMA_LEVEL;
- break;
- }
- return backlightlevel;
-}
-#endif
-
static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
{
/* Gamma Select */
@@ -273,47 +181,45 @@ static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
return 0;
}
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force)
{
- int ret = 0;
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0 || lcd->bl == 1) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- switch (lcd->bl) {
- case GAMMA_30CD ... GAMMA_40CD: /* 30cd ~ 40cd */
- if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 40) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[1], ACL_PARAM_SIZE);
- lcd->cur_acl = 40;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
+ switch (candela) {
+ case 0 ... 49:
+ level = ACL_STATUS_0P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
}
- if (ret) {
+ if (!lcd->acl_enable)
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ else {
+ ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
ret = -EPERM;
- goto acl_err;
- }
-acl_err:
+exit:
return ret;
}
@@ -499,7 +405,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
ret = s6e8ax0_gamma_ctl(lcd);
- ret = s6e8ax0_set_acl(lcd);
+ ret = s6e8ax0_set_acl(lcd, force);
ret = s6e8ax0_set_elvss(lcd);
@@ -720,7 +626,7 @@ static ssize_t power_reduce_store(struct device *dev,
dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
lcd->acl_enable = value;
if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd);
+ s6e8ax0_set_acl(lcd, 0);
}
}
return size;
@@ -863,7 +769,7 @@ static int s6e8ax0_probe(struct device *dev)
lcd->current_bl = lcd->bl;
lcd->acl_enable = 0;
- lcd->cur_acl = 0;
+ lcd->current_acl = 0;
lcd->power = FB_BLANK_UNBLANK;
lcd->ldi_enable = 1;
@@ -924,6 +830,9 @@ static int s6e8ax0_probe(struct device *dev)
update_brightness(lcd, 1);
#endif
+ lcd_early_suspend = s6e8ax0_early_suspend;
+ lcd_late_resume = s6e8ax0_late_resume;
+
return 0;
out_free_backlight:
diff --git a/drivers/video/samsung/s3cfb_s6evr02.c b/drivers/video/samsung/s3cfb_s6evr02.c
new file mode 100644
index 0000000..dc94822
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_s6evr02.c
@@ -0,0 +1,1352 @@
+/* linux/drivers/video/samsung/s3cfb_s6evr02.c
+ *
+ * MIPI-DSI based AMS555HBxx AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/rtc.h>
+#include <linux/reboot.h>
+#include <linux/syscalls.h> /* sys_sync */
+#include <plat/gpio-cfg.h>
+#include <plat/regs-dsim.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "s5p-dsim.h"
+#include "s3cfb.h"
+#include "s6evr02_param.h"
+
+#define SMART_DIMMING
+#undef SMART_DIMMING_DEBUG
+
+#ifdef SMART_DIMMING
+#include "smart_dimming_s6evr02.h"
+#include "aid_s6evr02.h"
+#endif
+
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 130
+#define DEFAULT_GAMMA_LEVEL GAMMA_130CD
+
+#define LDI_ID_REG 0xD7
+#define LDI_ID_LEN 3
+#ifdef SMART_DIMMING
+#define LDI_MTP_LENGTH 33
+#define LDI_MTP_ADDR 0xC8
+#endif
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int current_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+ unsigned char id[LDI_ID_LEN];
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+#ifdef SMART_DIMMING
+ struct str_smart_dim smart;
+ unsigned char aor[GAMMA_MAX][ARRAY_SIZE(SEQ_AOR_CONTROL)];
+#endif
+ unsigned int irq;
+ unsigned int connected;
+
+#if defined(GPIO_ERR_FG)
+ struct delayed_work err_fg_detection;
+ unsigned int err_fg_detection_count;
+#endif
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
+
+ struct dsim_global *dsim;
+};
+
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 102, 104, 106, 108,
+ 110, 120, 130, 140, 150, 160, 170, 180,
+ 182, 184, 186, 188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+#ifdef SMART_DIMMING
+static unsigned int aid_candela_table[GAMMA_MAX] = {
+ base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100,
+ AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150,
+ AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180,
+ AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+#endif
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_ERR_FG)
+static void err_fg_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, err_fg_detection.work);
+
+ int err_fg_level = gpio_get_value(GPIO_ERR_FG);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->err_fg_detection_count, err_fg_level);
+
+ if (!err_fg_level) {
+ if (lcd->err_fg_detection_count < 10) {
+ schedule_delayed_work(&lcd->err_fg_detection, HZ/8);
+ lcd->err_fg_detection_count++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+
+}
+
+static irqreturn_t err_fg_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "\t\t%s\n", __func__);
+
+ lcd->err_fg_detection_count = 0;
+ schedule_delayed_work(&lcd->err_fg_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+#if defined(GPIO_OLED_DET)
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ struct file *fp;
+ char name[128];
+ struct timespec ts;
+ struct rtc_time tm;
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, GPIO_OLED_DET is %s\n", __func__, oled_det_level ? "high" : "low");
+
+ if (!oled_det_level) {
+ if (lcd->oled_detection_count < 3) {
+ getnstimeofday(&ts);
+ rtc_time_to_tm(ts.tv_sec, &tm);
+ sprintf(name, "%s%02d-%02d_%02d:%02d:%02d_%02d",
+ "/sdcard/", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, lcd->oled_detection_count);
+ fp = filp_open(name, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ if (IS_ERR_OR_NULL(fp))
+ dev_info(&lcd->ld->dev, "fail to create vgh detection log file, %s\n", name);
+
+ schedule_delayed_work(&lcd->oled_detection, msecs_to_jiffies(10));
+ lcd->oled_detection_count++;
+ } else {
+ dev_info(&lcd->ld->dev, "VGH IS NOT OK! LCD SMASH!!!\n");
+ getnstimeofday(&ts);
+ rtc_time_to_tm(ts.tv_sec, &tm);
+ sprintf(name, "%s%02d-%02d_%02d:%02d:%02d_POWEROFF",
+ "/sdcard/", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+ fp = filp_open(name, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ if (IS_ERR_OR_NULL(fp))
+ dev_info(&lcd->ld->dev, "fail to create vgh detection log file, %s\n", name);
+
+ sys_sync();
+ kernel_power_off();
+ }
+ } else
+ dev_info(&lcd->ld->dev, "VGH IS OK\n");
+
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "\t\t%s\n", __func__);
+
+ schedule_delayed_work(&lcd->oled_detection, msecs_to_jiffies(10));
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int _s6evr02_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+ int ret = 0;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6evr02_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int ret = 0;
+ int retry_cnt = 1;
+
+retry:
+ ret = _s6evr02_write(lcd, seq, len);
+ if (!ret) {
+ if (retry_cnt) {
+ dev_dbg(&lcd->ld->dev, "%s :: retry: %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto retry;
+ } else
+ dev_dbg(&lcd->ld->dev, "%s :: 0x%02x\n", __func__, seq[1]);
+ }
+
+ return ret;
+}
+
+static int _s6evr02_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+{
+ int ret = 0;
+
+ if (!lcd->connected)
+ return ret;
+
+ mutex_lock(&lcd->lock);
+
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6evr02_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+retry:
+ ret = _s6evr02_read(lcd, addr, count, buf);
+ if (!ret) {
+ if (retry_cnt) {
+ dev_dbg(&lcd->ld->dev, "%s :: retry: %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto retry;
+ } else
+ dev_dbg(&lcd->ld->dev, "%s :: 0x%02x\n", __func__, addr);
+ }
+
+ return ret;
+}
+
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_20CD;
+ break;
+ case 30 ... 39:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 40 ... 49:
+ backlightlevel = GAMMA_40CD;
+ break;
+ case 50 ... 59:
+ backlightlevel = GAMMA_50CD;
+ break;
+ case 60 ... 69:
+ backlightlevel = GAMMA_60CD;
+ break;
+ case 70 ... 79:
+ backlightlevel = GAMMA_70CD;
+ break;
+ case 80 ... 89:
+ backlightlevel = GAMMA_80CD;
+ break;
+ case 90 ... 99:
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 101:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 102 ... 103:
+ backlightlevel = GAMMA_102CD;
+ break;
+ case 104 ... 105:
+ backlightlevel = GAMMA_104CD;
+ break;
+ case 106 ... 107:
+ backlightlevel = GAMMA_106CD;
+ break;
+ case 108 ... 109:
+ backlightlevel = GAMMA_108CD;
+ break;
+ case 110 ... 119:
+ backlightlevel = GAMMA_110CD;
+ break;
+ case 120 ... 129:
+ backlightlevel = GAMMA_120CD;
+ break;
+ case 130 ... 139:
+ backlightlevel = GAMMA_130CD;
+ break;
+ case 140 ... 149:
+ backlightlevel = GAMMA_140CD;
+ break;
+ case 150 ... 159:
+ backlightlevel = GAMMA_150CD;
+ break;
+ case 160 ... 169:
+ backlightlevel = GAMMA_160CD;
+ break;
+ case 170 ... 179:
+ backlightlevel = GAMMA_170CD;
+ break;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
+ break;
+ case 190 ... 199:
+ backlightlevel = GAMMA_190CD;
+ break;
+ case 200 ... 209:
+ backlightlevel = GAMMA_200CD;
+ break;
+ case 210 ... 219:
+ backlightlevel = GAMMA_210CD;
+ break;
+ case 220 ... 229:
+ backlightlevel = GAMMA_220CD;
+ break;
+ case 230 ... 239:
+ backlightlevel = GAMMA_230CD;
+ break;
+ case 240 ... 249:
+ backlightlevel = GAMMA_240CD;
+ break;
+ case 250 ... 254:
+ backlightlevel = GAMMA_250CD;
+ break;
+ case 255:
+ backlightlevel = GAMMA_300CD;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+#ifdef SMART_DIMMING
+static int s6evr02_aid_parameter_ctl(struct lcd_info *lcd, u8 force)
+{
+ if ((aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0]) || force)
+ s6evr02_write(lcd, lcd->aor[lcd->bl], AID_PARAM_SIZE);
+
+ return 0;
+}
+#endif
+
+static int s6evr02_gamma_ctl(struct lcd_info *lcd)
+{
+ /* s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY)); */
+ s6evr02_write(lcd, lcd->gamma_table[lcd->bl], GAMMA_PARAM_SIZE);
+ s6evr02_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ /* s6evr02_write(lcd, SEQ_BRIGHTNESS_CONTROL_ON, ARRAY_SIZE(SEQ_BRIGHTNESS_CONTROL_ON)); */
+
+ return 0;
+}
+
+static int s6evr02_set_acl(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 29:
+ level = ACL_STATUS_0P;
+ break;
+ case 30 ... 39:
+ level = ACL_STATUS_33P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
+ }
+
+ if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5))
+ level = ACL_STATUS_0P;
+
+ if (force || lcd->current_acl != ACL_CUTOFF_TABLE[level][1]) {
+ ret = s6evr02_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = ACL_CUTOFF_TABLE[level][1];
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ }
+
+ if (ret)
+ ret = -EPERM;
+
+ return ret;
+}
+
+static int s6evr02_set_elvss(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 49:
+ elvss_level = ELVSS_STATUS_20;
+ break;
+ case 50 ... 79:
+ elvss_level = ELVSS_STATUS_50;
+ break;
+ case 80 ... 99:
+ elvss_level = ELVSS_STATUS_80;
+ break;
+ case 100 ... 109:
+ elvss_level = ELVSS_STATUS_100;
+ break;
+ case 110 ... 119:
+ elvss_level = ELVSS_STATUS_110;
+ break;
+ case 120 ... 129:
+ elvss_level = ELVSS_STATUS_120;
+ break;
+ case 130 ... 139:
+ elvss_level = ELVSS_STATUS_130;
+ break;
+ case 140 ... 149:
+ elvss_level = ELVSS_STATUS_140;
+ break;
+ case 150 ... 159:
+ elvss_level = ELVSS_STATUS_150;
+ break;
+ case 160 ... 169:
+ elvss_level = ELVSS_STATUS_160;
+ break;
+ case 170 ... 179:
+ elvss_level = ELVSS_STATUS_170;
+ break;
+ case 180 ... 189:
+ elvss_level = ELVSS_STATUS_180;
+ break;
+ case 190 ... 199:
+ elvss_level = ELVSS_STATUS_190;
+ break;
+ case 200 ... 209:
+ elvss_level = ELVSS_STATUS_200;
+ break;
+ case 210 ... 219:
+ elvss_level = ELVSS_STATUS_210;
+ break;
+ case 220 ... 229:
+ elvss_level = ELVSS_STATUS_220;
+ break;
+ case 230 ... 239:
+ elvss_level = ELVSS_STATUS_230;
+ break;
+ case 240 ... 250:
+ elvss_level = ELVSS_STATUS_240;
+ break;
+ case 299:
+ elvss_level = ELVSS_STATUS_300;
+ break;
+ }
+
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ ret = s6evr02_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][2];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n", lcd->elvss_table[elvss_level][2]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+
+static int init_elvss_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+#ifdef SMART_DIMMING_DEBUG
+ int j;
+#endif
+
+ lcd->elvss_table = kzalloc(ELVSS_STATUS_MAX * sizeof(u8 *), GFP_KERNEL);
+
+ if (IS_ERR_OR_NULL(lcd->elvss_table)) {
+ pr_err("failed to allocate elvss table\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss_table;
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ lcd->elvss_table[i] = kzalloc(ELVSS_PARAM_SIZE * sizeof(u8), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->elvss_table[i])) {
+ pr_err("failed to allocate elvss\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss;
+ }
+ lcd->elvss_table[i][0] = 0xB6;
+ lcd->elvss_table[i][1] = 0x08;
+ lcd->elvss_table[i][2] = ELVSS_CONTROL_TABLE[i][2];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+
+err_alloc_elvss:
+ while (i > 0) {
+ kfree(lcd->elvss_table[i-1]);
+ i--;
+ }
+ kfree(lcd->elvss_table);
+err_alloc_elvss_table:
+ return ret;
+}
+
+#ifdef SMART_DIMMING
+static int init_gamma_table(struct lcd_info *lcd , const u8 *mtp_data)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xCA;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ if (candela_table[i] == 20)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_21, mtp_data);
+ else if (candela_table[i] == 30)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_213, mtp_data);
+ else if (candela_table[i] == 40)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_215, mtp_data);
+ else if (candela_table[i] == 50)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_218, mtp_data);
+ else if (candela_table[i] == 60)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else if (candela_table[i] == 70)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 80)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 90)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 100)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if (candela_table[i] == 102)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 104)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 106)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 108)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 182)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 184)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 186)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 188)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 190)
+ calc_gamma_table_215_190(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if ((candela_table[i] > 190) && (candela_table[i] < MAX_GAMMA-1))
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225 , mtp_data);
+ else if (candela_table[i] == MAX_GAMMA-1)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ }
+
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+
+static int init_aid_dimming_table(struct lcd_info *lcd)
+{
+ unsigned int i, j, c;
+ u16 reverse_seq[] = {0, 28, 29, 30, 31, 32, 33, 25, 26, 27, 22, 23, 24, 19, 20, 21, 16, 17, 18, 13, 14, 15, 10, 11, 12, 7, 8, 9, 4, 5, 6, 1, 2, 3};
+ u16 temp[GAMMA_PARAM_SIZE];
+
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table); i++) {
+ j = (aid_rgb_fix_table[i].gray * 3 + aid_rgb_fix_table[i].rgb) + 1;
+ c = lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j] + aid_rgb_fix_table[i].offset;
+ if (c > 0xff)
+ lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j] = 0xff;
+ else
+ lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j] += aid_rgb_fix_table[i].offset;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ memcpy(lcd->aor[i], SEQ_AOR_CONTROL, AID_PARAM_SIZE);
+ lcd->aor[i][0x01] = aid_command_table[i][0];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+ printk("\n");
+#endif
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ temp[j] = lcd->gamma_table[i][reverse_seq[j]];
+
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ lcd->gamma_table[i][j] = temp[j];
+
+ for (c = CI_RED; c < CI_MAX ; c++)
+ lcd->gamma_table[i][31+c] = lcd->smart.default_gamma[30+c];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+}
+#endif
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+ s6evr02_gamma_ctl(lcd);
+
+ s6evr02_aid_parameter_ctl(lcd, force);
+
+ s6evr02_set_acl(lcd, force);
+
+ s6evr02_set_elvss(lcd, force);
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n", brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int s6evr02_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
+ s6evr02_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+
+ if (lcd->id[1] == 0x10) { /* for S.LSI UB(YOUM) */
+ msleep(20);
+ s6evr02_write(lcd, SEQ_GAMMA_CONDITION_SET_UB, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET_UB));
+ s6evr02_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6evr02_write(lcd, SEQ_BRIGHTNESS_CONTROL_ON, ARRAY_SIZE(SEQ_BRIGHTNESS_CONTROL_ON));
+ s6evr02_write(lcd, SEQ_AOR_CONTROL, ARRAY_SIZE(SEQ_AOR_CONTROL));
+ s6evr02_write(lcd, SEQ_ELVSS_CONDITION_SET_UB, ARRAY_SIZE(SEQ_ELVSS_CONDITION_SET_UB));
+ s6evr02_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ } else {
+ msleep(20);
+ s6evr02_gamma_ctl(lcd);
+ s6evr02_write(lcd, SEQ_BRIGHTNESS_CONTROL_ON, ARRAY_SIZE(SEQ_BRIGHTNESS_CONTROL_ON));
+ s6evr02_write(lcd, SEQ_AOR_CONTROL, ARRAY_SIZE(SEQ_AOR_CONTROL));
+ s6evr02_write(lcd, SEQ_ELVSS_CONDITION_SET, ARRAY_SIZE(SEQ_ELVSS_CONDITION_SET));
+ s6evr02_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ }
+
+ return ret;
+}
+
+static int s6evr02_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6evr02_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int s6evr02_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6evr02_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+
+ msleep(35);
+
+ s6evr02_write(lcd, SEQ_SLEEP_IN, ARRAY_SIZE(SEQ_SLEEP_IN));
+
+ msleep(100);
+
+ return ret;
+}
+
+static int s6evr02_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ret = s6evr02_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = s6evr02_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int s6evr02_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = s6evr02_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int s6evr02_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = s6evr02_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = s6evr02_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int s6evr02_set_power(struct lcd_device *ld, int power)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(&lcd->ld->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return s6evr02_power(lcd, power);
+}
+
+static int s6evr02_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+
+static int s6evr02_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n", __func__, brightness); */
+
+ if (brightness < MIN_BRIGHTNESS ||
+ brightness > bd->props.max_brightness) {
+ dev_err(&bd->dev, "lcd brightness should be %d to %d. now %d\n",
+ MIN_BRIGHTNESS, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int s6evr02_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static int s6evr02_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static struct lcd_ops s6evr02_lcd_ops = {
+ .set_power = s6evr02_set_power,
+ .get_power = s6evr02_get_power,
+ .check_fb = s6evr02_check_fb,
+};
+
+static const struct backlight_ops s6evr02_backlight_ops = {
+ .get_brightness = s6evr02_get_brightness,
+ .update_status = s6evr02_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+
+ sprintf(temp, "SMD_AMS555HBxx\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t window_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[15];
+
+ sprintf(temp, "%x %x %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(window_type, 0444, window_type_show, NULL);
+
+static ssize_t gamma_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int i, j;
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+
+ return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct lcd_info *g_lcd;
+
+void s6evr02_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+
+#if defined(GPIO_ERR_FG)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_ERR_FG, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_ERR_FG, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_ERR_FG, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_ERR_FG, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_ERR_FG);
+#endif
+#if defined(GPIO_OLED_DET)
+ disable_irq(gpio_to_irq(GPIO_OLED_DET));
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+
+ s6evr02_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void s6evr02_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6evr02_power(lcd, FB_BLANK_UNBLANK);
+
+#if defined(GPIO_ERR_FG)
+ s3c_gpio_cfgpin(GPIO_ERR_FG, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ERR_FG, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(gpio_to_irq(GPIO_OLED_DET));
+#endif
+
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+
+static void s6evr02_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = s6evr02_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 2);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+#ifdef SMART_DIMMING
+static int s6evr02_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret;
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_3_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY));
+ msleep(20); /* one frame delay befor reading MTP. */
+ ret = s6evr02_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data, 1);
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_3_KEY_DISABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY_DISABLE));
+ /* s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY_DISABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY_DISABLE)); */
+
+ return ret;
+}
+#endif
+
+static int s6evr02_probe(struct device *dev)
+{
+ int ret = 0, i;
+ struct lcd_info *lcd;
+
+#ifdef SMART_DIMMING
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+#endif
+
+ lcd = kzalloc(sizeof(struct lcd_info), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ g_lcd = lcd;
+
+ lcd->ld = lcd_device_register("panel", dev, lcd, &s6evr02_lcd_ops);
+ if (IS_ERR(lcd->ld)) {
+ pr_err("failed to register lcd device\n");
+ ret = PTR_ERR(lcd->ld);
+ goto out_free_lcd;
+ }
+
+ lcd->bd = backlight_device_register("panel", dev, lcd, &s6evr02_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+ lcd->acl_enable = 0;
+ lcd->current_acl = 0;
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_window_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_gamma_table);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ s6evr02_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ dev_info(&lcd->ld->dev, "%s lcd panel driver has been probed.\n", dev_name(dev));
+
+#ifdef SMART_DIMMING
+ for (i = 0; i < LDI_ID_LEN; i++) {
+ lcd->smart.panelid[i] = lcd->id[i];
+ }
+
+ init_table_info(&lcd->smart);
+
+ ret = s6evr02_read_mtp(lcd, mtp_data);
+/*
+ for (i = 0; i < LDI_MTP_LENGTH ; i++)
+ printk(" %dth mtp value is %x\n", i, mtp_data[i]);
+*/
+ if (!ret) {
+ printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
+ /*return -EPERM;*/
+ }
+
+ calc_voltage_table(&lcd->smart, mtp_data);
+
+ ret = init_elvss_table(lcd);
+ ret += init_gamma_table(lcd, mtp_data);
+ ret += init_aid_dimming_table(lcd);
+
+ if (ret)
+ printk(KERN_ERR "gamma table generation is failed\n");
+
+
+ update_brightness(lcd, 1);
+#endif
+
+#if defined(GPIO_ERR_FG)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->err_fg_detection, err_fg_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_ERR_FG);
+
+ irq_set_irq_type(lcd->irq, IRQ_TYPE_EDGE_RISING);
+
+ s3c_gpio_cfgpin(GPIO_ERR_FG, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ERR_FG, S3C_GPIO_PULL_NONE);
+
+ if (request_irq(lcd->irq, err_fg_detection_int,
+ IRQF_TRIGGER_RISING, "err_fg_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+
+ if (request_irq(gpio_to_irq(GPIO_OLED_DET), oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", gpio_to_irq(GPIO_OLED_DET));
+ }
+#endif
+
+ lcd_early_suspend = s6evr02_early_suspend;
+ lcd_late_resume = s6evr02_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit s6evr02_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ s6evr02_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6evr02_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ s6evr02_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver s6evr02_mipi_driver = {
+ .name = "s6evr02",
+ .probe = s6evr02_probe,
+ .remove = __devexit_p(s6evr02_remove),
+ .shutdown = s6evr02_shutdown,
+};
+
+static int s6evr02_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&s6evr02_mipi_driver);
+}
+
+static void s6evr02_exit(void)
+{
+ return;
+}
+
+module_init(s6evr02_init);
+module_exit(s6evr02_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI S6EVER02:AMS555HBXX (720x1280) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s5p-dsim.c b/drivers/video/samsung/s5p-dsim.c
index d128618..e206cf8 100644
--- a/drivers/video/samsung/s5p-dsim.c
+++ b/drivers/video/samsung/s5p-dsim.c
@@ -23,6 +23,7 @@
#include <linux/fb.h>
#include <linux/ctype.h>
#include <linux/platform_device.h>
+#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/memory.h>
@@ -240,7 +241,12 @@ unsigned char s5p_dsim_wr_data(void *ptr,
{
u32 uCnt = 0;
u32* pWordPtr = (u32 *)data0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dsim->slock, flags);
+
INIT_COMPLETION(dsim_wr_comp);
+ s5p_dsim_clear_interrupt(dsim_base, 0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY);
do {
s5p_dsim_wr_tx_data(dsim_base, pWordPtr[uCnt]);
@@ -251,6 +257,17 @@ unsigned char s5p_dsim_wr_data(void *ptr,
(unsigned char) (((unsigned short) data1) & 0xff),
(unsigned char) ((((unsigned short) data1) & 0xff00) >> 8));
+ /* check interrupt source if fifo empty interrupt source is rised directly after writing tx header.
+ if yes, we consider tx_data as fail. */
+ if (readl(dsim->reg_base + S5P_DSIM_INTSRC) & 0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY) {
+ dev_err(dsim->dev, "%s fifo empty is founded\n", __func__);
+ spin_unlock_irqrestore(&dsim->slock, flags);
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return DSIM_FALSE;
+ }
+
+ spin_unlock_irqrestore(&dsim->slock, flags);
+
if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp, DSIM_TIMEOUT)) {
dev_err(dsim->dev, "[DSIM:ERROR] %s Timeout\n", __func__);
mutex_unlock(&dsim_rd_wr_mutex);
@@ -386,6 +403,102 @@ clear_rx_fifo:
}
+int s5p_dsim_dcs_rd_data(void *ptr, u8 addr, u16 count, u8 *buf)
+{
+ u32 i, temp;
+ u8 response = 0;
+ u16 rxsize;
+ u32 txhd;
+ u32 rxhd;
+ int j;
+ struct dsim_global *dsim = ptr;
+ unsigned int reg_base = dsim->reg_base;
+
+ if (dsim->mipi_ddi_pd->resume_complete == 0) {
+ dev_err(dsim->dev, "DSIM Status: SUSPEND\n");
+ return DSIM_FALSE;
+ }
+
+ mutex_lock(&dsim_rd_wr_mutex);
+ INIT_COMPLETION(dsim_rd_comp);
+
+ switch (count) {
+ case 1:
+ response = MIPI_RESP_DCS_RD_1;
+ break;
+ case 2:
+ response = MIPI_RESP_DCS_RD_2;
+ break;
+ default:
+ response = MIPI_RESP_DCS_RD_LONG;
+ break;
+ }
+
+ /* set return packet size */
+ txhd = MIPI_CMD_DSI_SET_PKT_SZ | count << 8;
+
+ writel(txhd, reg_base + S5P_DSIM_PKTHDR);
+
+ /* set address to read */
+ txhd = MIPI_CMD_DSI_RD_0 | addr << 8;
+
+ writel(txhd, reg_base + S5P_DSIM_PKTHDR);
+
+ if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp, DSIM_TIMEOUT)) {
+ dev_err(dsim->dev, "ERROR:%s timout\n", __func__);
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return 0;
+ }
+
+ rxhd = readl(reg_base + S5P_DSIM_RXFIFO);
+ dev_info(dsim->dev, "rxhd : %x\n", rxhd);
+ if ((u8)(rxhd & 0xff) != response) {
+ dev_err(dsim->dev, "[DSIM:ERROR]:%s wrong response rxhd : %x, response:%x\n"
+ , __func__, rxhd, response);
+ goto error_read;
+ }
+ /* for short packet */
+ if (count <= 2) {
+ for (i = 0; i < count; i++)
+ buf[i] = (rxhd >> (8+(i*8))) & 0xff;
+ rxsize = count;
+ } else {
+ /* for long packet */
+ rxsize = (u16)((rxhd & 0x00ffff00) >> 8);
+ dev_info(dsim->dev, "rcv size : %d\n", rxsize);
+ if (rxsize != count) {
+ dev_err(dsim->dev, "[DSIM:ERROR]:%s received data size mismatch received : %d, requested : %d\n",
+ __func__, rxsize, count);
+ goto error_read;
+ }
+
+ for (i = 0; i < rxsize>>2; i++) {
+ temp = readl(reg_base + S5P_DSIM_RXFIFO);
+ dev_info(dsim->dev, "pkt : %08x\n", temp);
+ for (j = 0; j < 4; j++) {
+ buf[(i*4)+j] = (u8)(temp>>(j*8))&0xff;
+ /* printk("Value : %02x\n",(temp>>(j*8))&0xff); */
+ }
+ }
+ if (rxsize % 4) {
+ temp = readl(reg_base + S5P_DSIM_RXFIFO);
+ dev_info(dsim->dev, "pkt-l : %08x\n", temp);
+ for (j = 0; j < rxsize%4; j++) {
+ buf[(i*4)+j] = (u8)(temp>>(j*8))&0xff;
+ /* printk("Value : %02x\n",(temp>>(j*8))&0xff); */
+ }
+ }
+ }
+
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return rxsize;
+
+error_read:
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return 0;
+
+}
+
static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
{
int i;
@@ -457,7 +570,7 @@ static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
}
}
/* clear irq */
- writel(intsrc, dsim->reg_base + S5P_DSIM_INTSRC);
+ writel(intmsk, dsim->reg_base + S5P_DSIM_INTSRC);
return IRQ_HANDLED;
}
@@ -737,6 +850,24 @@ static int s5p_dsim_init_dsim(struct dsim_global *dsim)
}
#endif
+#if 0
+void s5p_dsim_set_lcd_freq_change(struct s3cfb_lcd_timing *timing)
+{
+ struct dsim_global *dsim = g_dsim;
+ struct dsim_lcd_config *main_lcd = dsim->dsim_lcd_info;
+ struct s3cfb_lcd *main_lcd_panel_info = NULL;
+ struct s3cfb_lcd_timing *main_timing = NULL;
+
+ main_lcd_panel_info = (struct s3cfb_lcd *)main_lcd->lcd_panel_info;
+ main_timing = &main_lcd_panel_info->timing;
+
+ main_timing->h_sw = timing->h_sw;
+ main_timing->h_bp = timing->h_bp;
+ main_timing->h_fp = timing->h_fp;
+}
+EXPORT_SYMBOL(s5p_dsim_set_lcd_freq_change);
+#endif
+
static void s5p_dsim_set_display_mode(struct dsim_global *dsim,
struct dsim_lcd_config *main_lcd, struct dsim_lcd_config *sub_lcd)
{
@@ -770,11 +901,11 @@ static void s5p_dsim_set_display_mode(struct dsim_global *dsim,
s5p_dsim_set_main_disp_vporch(dsim_base,
main_timing->cmd_allow_len,
- main_timing->stable_vfp, (u16) main_timing->v_bp);
+ main_timing->stable_vfp, (u16)main_timing->v_bp);
s5p_dsim_set_main_disp_hporch(dsim_base,
- main_timing->h_fp, (u16) main_timing->h_bp);
+ main_timing->h_fp, (u16)main_timing->h_bp);
s5p_dsim_set_main_disp_sync_area(dsim_base,
- main_timing->v_sw, (u16) main_timing->h_sw);
+ main_timing->v_sw, (u16)main_timing->h_sw);
/* in case of COMMAND MODE (CPU or I80 INTERFACE) */
} else {
@@ -990,10 +1121,10 @@ static void s5p_dsim_interrupt_mask_set(struct dsim_global *dsim)
writel(int_stat, dsim->reg_base + S5P_DSIM_INTMSK);
}
-int s5p_dsim_fifo_clear(void)
+#if defined(CONFIG_CPU_EXYNOS4210)
+static int s5p_dsim_fifo_clear(struct dsim_global *dsim)
{
int dsim_count = 0, ret;
- struct dsim_global *dsim = g_dsim;
writel(SwRstRelease, dsim->reg_base + S5P_DSIM_INTSRC);
@@ -1007,7 +1138,6 @@ int s5p_dsim_fifo_clear(void)
}
if (readl(dsim->reg_base + S5P_DSIM_INTSRC) & SwRstRelease) {
- s5p_dsim_interrupt_mask_set(dsim);
ret = 1;
break;
}
@@ -1015,6 +1145,7 @@ int s5p_dsim_fifo_clear(void)
return ret;
}
+#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
void s5p_dsim_early_suspend(void)
@@ -1087,19 +1218,27 @@ void s5p_dsim_late_resume(void)
dsim->mipi_ddi_pd->lcd_power_on(dsim->dev, 1);
usleep_range(25000, 25000);
+ s5p_dsim_late_resume_init_dsim(dsim);
+ s5p_dsim_init_link(dsim);
+ usleep_range(10000, 10000);
+
if (dsim->mipi_ddi_pd->lcd_reset)
dsim->mipi_ddi_pd->lcd_reset();
usleep_range(5000, 5000);
- s5p_dsim_late_resume_init_dsim(dsim);
- s5p_dsim_init_link(dsim);
- usleep_range(10000, 10000);
s5p_dsim_set_hs_enable(dsim);
s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYCPU, 1);
s5p_dsim_set_display_mode(dsim, dsim->dsim_lcd_info, NULL);
s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYLCDC, 1);
/* s5p_dsim_set_interrupt_mask(dsim->reg_base, AllDsimIntr, 0); */
+#if defined(CONFIG_CPU_EXYNOS4210)
+ if (s5p_dsim_fifo_clear(dsim) == 0)
+ dev_err(dsim->dev, "dsim fifo clear fail!!!\n");
+#endif
+
+ s5p_dsim_interrupt_mask_set(dsim);
+
dsim->mipi_ddi_pd->resume_complete = 1;
dev_info(dsim->dev, "-%s\n", __func__);
@@ -1254,6 +1393,7 @@ static DEVICE_ATTR(dsim_dump, 0444, dsim_dump_show, NULL);
static struct dsim_ops s5p_dsim_ops = {
.cmd_write = s5p_dsim_wr_data,
.cmd_read = s5p_dsim_rd_data,
+ .cmd_dcs_read = s5p_dsim_dcs_rd_data,
.suspend = s5p_dsim_early_suspend,
.resume = s5p_dsim_late_resume,
};
@@ -1277,7 +1417,8 @@ static int s5p_dsim_probe(struct platform_device *pdev)
dsim->pd = to_dsim_plat(&pdev->dev);
if (!dsim->pd) {
dev_err(&pdev->dev, "platform data is NULL\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_plat;
}
dsim->dev = &pdev->dev;
@@ -1298,7 +1439,8 @@ static int s5p_dsim_probe(struct platform_device *pdev)
dsim->clock = clk_get(&pdev->dev, dsim->pd->clk_name);
if (IS_ERR(dsim->clock)) {
dev_err(&pdev->dev, "failed to get dsim clock source\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_clk_get;
}
clk_enable(dsim->clock);
@@ -1343,9 +1485,9 @@ static int s5p_dsim_probe(struct platform_device *pdev)
writel(int_stat, dsim->reg_base + S5P_DSIM_INTSRC);
/* enable interrupts */
- int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK);
+ /* int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK); */
- int_stat &= ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
+ int_stat = ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
(0x01<<S5P_DSIM_INT_BTA_TIMEOUT) | (0x01 << S5P_DSIM_INT_RX_DONE) |
(0x01<<S5P_DSIM_INT_RX_TE) | (0x01<<S5P_DSIM_INT_RX_ACK) |
(0x01<<S5P_DSIM_INT_RX_ECC_ERR) | (0x01<<S5P_DSIM_IMT_RX_CRC_ERR) |
@@ -1356,6 +1498,7 @@ static int s5p_dsim_probe(struct platform_device *pdev)
init_completion(&dsim_rd_comp);
init_completion(&dsim_wr_comp);
mutex_init(&dsim_rd_wr_mutex);
+ spin_lock_init(&dsim->slock);
dsim->mipi_ddi_pd->resume_complete = 1;
dsim->dsim_lcd_info->lcd_enabled = 1;
@@ -1433,6 +1576,11 @@ mipi_drv_err:
err_clk_disable:
clk_disable(dsim->clock);
+
+err_clk_get:
+err_plat:
+ kfree(dsim);
+
err_alloc:
return ret;
}
diff --git a/drivers/video/samsung/s5p-dsim.h b/drivers/video/samsung/s5p-dsim.h
index baf8f66..049e066 100644
--- a/drivers/video/samsung/s5p-dsim.h
+++ b/drivers/video/samsung/s5p-dsim.h
@@ -44,6 +44,7 @@ struct mipi_lcd_driver {
struct dsim_ops {
u8 (*cmd_write)(void *ptr, u32 data0, u32 data1, u32 data2);
int (*cmd_read)(void *ptr, u8 addr, u16 count, u8 *buf);
+ int (*cmd_dcs_read)(void *ptr, u8 addr, u16 count, u8 *buf);
void (*suspend)(void);
void (*resume)(void);
};
@@ -79,6 +80,8 @@ struct dsim_global {
struct delayed_work check_hs_toggle_work;
unsigned int dsim_toggle_per_frame_count;
+ spinlock_t slock;
+
struct dsim_ops *ops;
};
diff --git a/drivers/video/samsung/s6d6aa1.c b/drivers/video/samsung/s6d6aa1.c
index 2a4c4ad..e974b0a 100644
--- a/drivers/video/samsung/s6d6aa1.c
+++ b/drivers/video/samsung/s6d6aa1.c
@@ -37,13 +37,13 @@
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 255
-#define DEFAULT_BRIGHTNESS 170
+#define DEFAULT_BRIGHTNESS 160
+
struct lcd_info {
unsigned int bl;
unsigned int current_bl;
- unsigned int acl_enable;
-
+ unsigned int auto_brightness;
unsigned int ldi_enable;
unsigned int power;
struct mutex lock;
@@ -57,10 +57,69 @@ struct lcd_info {
unsigned int irq;
unsigned int connected;
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
struct dsim_global *dsim;
};
+static const unsigned char SEQ_PASSWD1[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_PASSWD2[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SONY_IP_SET1[] = {
+ 0xC4,
+ 0x7C, 0xE6, 0x7C, 0xE6, 0x7C, 0xE6, 0x7C, 0x7C,
+ 0x05, 0x0F, 0x1F, 0x01, 0x00, 0x00,
+};
+
+static const unsigned char SEQ_SONY_IP_SET2[] = {
+ 0xC5,
+ 0x80, 0x80, 0x80, 0x41, 0x43, 0x34, 0x80, 0x80,
+ 0x01, 0xFF, 0x25, 0x58, 0x50
+};
+
+/* Should be removed when panel nvm is updated */
+static const unsigned char SEQ_PGAMMACTL[] = {
+ 0xFA, 0x9C, 0xBF, 0x1A, 0xD6, 0xE3, 0xE3, 0x1B,
+ 0xDA, 0x9B, 0x16, 0x51, 0x12, 0x15, 0xD9, 0x9B,
+ 0x1A, 0xDD, 0x62, 0x2D, 0x79, 0x6A, 0x2C, 0x7F,
+ 0x11, 0x09, 0x53, 0x91, 0x09, 0x08, 0xCA, 0x06,
+ 0x04, 0x87, 0x0B, 0x4E, 0xD2, 0x13, 0xD7, 0x18,
+ 0x1A, 0x9A, 0xC1, 0x0F, 0xFF, 0xD7, 0x53, 0x61,
+ 0xE2, 0x5A, 0x9A, 0xDC, 0x59, 0x96, 0x98, 0x5C,
+ 0x1F, 0xE3, 0x25, 0xE6, 0x27, 0x23, 0x23, 0x4C,
+};
+
+static const unsigned char SEQ_NGAMMACTL[] = {
+ 0xFB, 0x9C, 0xBF, 0x1A, 0xD6, 0xE3, 0xE3, 0x1B,
+ 0xDA, 0x9B, 0x16, 0x51, 0x12, 0x15, 0xD9, 0x9B,
+ 0x1A, 0xDD, 0x62, 0x2D, 0x79, 0x6A, 0x2C, 0x7F,
+ 0x11, 0x09, 0x53, 0x91, 0x09, 0x08, 0xCA, 0x06,
+ 0x04, 0x87, 0x0B, 0x4E, 0xD2, 0x13, 0xD7, 0x18,
+ 0x1A, 0x9A, 0xC1, 0x0F, 0xFF, 0xD7, 0x53, 0x61,
+ 0xE2, 0x5A, 0x9A, 0xDC, 0x59, 0x96, 0x98, 0x5C,
+ 0x1F, 0xE3, 0x25, 0xE6, 0x27, 0x23, 0x23, 0x4C,
+};
+
+static const unsigned char SEQ_PASSWD1_DISABLE[] = {
+ 0xF0,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_PASSWD2_DISABLE[] = {
+ 0xF1,
+ 0xA5, 0xA5
+};
+
static const unsigned char SEQ_SLPOUT[] = {
0x11,
0x00,
@@ -73,12 +132,6 @@ static const unsigned char SEQ_DSCTL[] = {
0x00
};
-static const unsigned char SEQ_WRDISBV[] = {
- 0x51,
- 0xFF,
- 0x00
-};
-
static const unsigned char SEQ_WRCTRLD[] = {
0x53,
0x2C,
@@ -91,6 +144,12 @@ static const unsigned char SEQ_WRCABC[] = {
0x00
};
+static const unsigned char SEQ_WRCABC_OUTDOOR[] = {
+ 0x55,
+ 0x04,
+ 0x00
+};
+
static const unsigned char SEQ_DISPON[] = {
0x29,
0x00,
@@ -115,8 +174,85 @@ static unsigned char SEQ_WRDISBV_CTL[] = {
0x00
};
+static unsigned char TRANS_BRIGHTNESS[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4,
+ 4, 5, 5, 6, 6, 7, 7, 8,
+ 8, 9, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 97, 98,
+ 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 131,
+ 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 146, 147, 148,
+ 149, 150, 151, 152, 153, 154, 155, 156,
+ 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 170, 171, 172, 173,
+ 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 192, 193, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206,
+ 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 244, 245, 246, 247, 248,
+ 249, 250, 251, 252, 253, 254, 255, 255,
+};
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+static void esd_reset_lcd(struct lcd_info *lcd)
+{
+ dev_info(&lcd->ld->dev, "++%s\n", __func__);
+ if (lcd_early_suspend)
+ lcd_early_suspend();
+ lcd->dsim->ops->suspend();
+
+ lcd->dsim->ops->resume();
+ if (lcd_late_resume)
+ lcd_late_resume();
+ dev_info(&lcd->ld->dev, "--%s\n", __func__);
+}
+
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->oled_detection_count, oled_det_level);
+ if (!oled_det_level)
+ esd_reset_lcd(lcd);
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
-static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+
+static int s6d6aa1_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
const unsigned char *wbuf;
@@ -141,7 +277,7 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
return 0;
}
-static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+static int _s6d6aa1_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
{
int ret = 0;
@@ -158,12 +294,12 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
return ret;
}
-static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+static int s6d6aa1_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
read_retry:
- ret = _s6e8ax0_read(lcd, addr, count, buf);
+ ret = _s6d6aa1_read(lcd, addr, count, buf);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n", __func__, retry_cnt);
@@ -180,23 +316,13 @@ static int get_backlight_level_from_brightness(int brightness)
{
int backlightlevel;
- /* brightness setting from platform is from 0 to 255
- * But in this driver, brightness is only supported from 0 to 24 */
+ backlightlevel = TRANS_BRIGHTNESS[brightness];
- switch (brightness) {
- case 0 ... 255:
- backlightlevel = brightness;
- break;
- default:
- backlightlevel = brightness;
- break;
- }
return backlightlevel;
}
static int update_brightness(struct lcd_info *lcd, u8 force)
{
- int ret;
u32 brightness;
mutex_lock(&lcd->bl_lock);
@@ -209,7 +335,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
lcd->current_bl = lcd->bl;
SEQ_WRDISBV_CTL[1] = lcd->bl;
- s6e8ax0_write(lcd, SEQ_WRDISBV_CTL, \
+ s6d6aa1_write(lcd, SEQ_WRDISBV_CTL, \
ARRAY_SIZE(SEQ_WRDISBV_CTL));
dev_info(&lcd->ld->dev, "brightness=%d, bl=%d\n", brightness, lcd->bl);
@@ -220,43 +346,52 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
return 0;
}
-static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+static int s6d6aa1_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
+ msleep(15);
+
+ s6d6aa1_write(lcd, SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
- msleep(200);
+ msleep(145);
- s6e8ax0_write(lcd, SEQ_DSCTL, ARRAY_SIZE(SEQ_DSCTL));
- s6e8ax0_write(lcd, SEQ_WRDISBV, ARRAY_SIZE(SEQ_WRDISBV));
- s6e8ax0_write(lcd, SEQ_WRCTRLD, ARRAY_SIZE(SEQ_WRCTRLD));
- s6e8ax0_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
+ s6d6aa1_write(lcd, SEQ_PASSWD1, ARRAY_SIZE(SEQ_PASSWD1));
+ s6d6aa1_write(lcd, SEQ_PASSWD2, ARRAY_SIZE(SEQ_PASSWD2));
+ s6d6aa1_write(lcd, SEQ_SONY_IP_SET1, ARRAY_SIZE(SEQ_SONY_IP_SET1));
+ s6d6aa1_write(lcd, SEQ_SONY_IP_SET2, ARRAY_SIZE(SEQ_SONY_IP_SET2));
+ s6d6aa1_write(lcd, SEQ_PGAMMACTL, ARRAY_SIZE(SEQ_PGAMMACTL));
+ s6d6aa1_write(lcd, SEQ_NGAMMACTL, ARRAY_SIZE(SEQ_NGAMMACTL));
+ s6d6aa1_write(lcd, SEQ_PASSWD1_DISABLE, ARRAY_SIZE(SEQ_PASSWD1_DISABLE));
+ s6d6aa1_write(lcd, SEQ_PASSWD2_DISABLE, ARRAY_SIZE(SEQ_PASSWD2_DISABLE));
+ s6d6aa1_write(lcd, SEQ_DSCTL, ARRAY_SIZE(SEQ_DSCTL));
+ s6d6aa1_write(lcd, SEQ_WRCTRLD, ARRAY_SIZE(SEQ_WRCTRLD));
+ s6d6aa1_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
return ret;
}
-static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+static int s6d6aa1_ldi_enable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPON, ARRAY_SIZE(SEQ_DISPON));
+ s6d6aa1_write(lcd, SEQ_DISPON, ARRAY_SIZE(SEQ_DISPON));
return ret;
}
-static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+static int s6d6aa1_ldi_disable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPOFF, ARRAY_SIZE(SEQ_DISPOFF));
- s6e8ax0_write(lcd, SEQ_SLPIN, ARRAY_SIZE(SEQ_SLPIN));
+ s6d6aa1_write(lcd, SEQ_DISPOFF, ARRAY_SIZE(SEQ_DISPOFF));
+ s6d6aa1_write(lcd, SEQ_SLPIN, ARRAY_SIZE(SEQ_SLPIN));
return ret;
}
-static int s6e8ax0_power_on(struct lcd_info *lcd)
+static int s6d6aa1_power_on(struct lcd_info *lcd)
{
int ret = 0;
struct lcd_platform_data *pd = NULL;
@@ -264,15 +399,14 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
/* dev_info(&lcd->ld->dev, "%s\n", __func__); */
- ret = s6e8ax0_ldi_init(lcd);
+ ret = s6d6aa1_ldi_init(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
goto err;
}
- msleep(120);
- ret = s6e8ax0_ldi_enable(lcd);
+ ret = s6d6aa1_ldi_enable(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
goto err;
@@ -285,7 +419,7 @@ err:
return ret;
}
-static int s6e8ax0_power_off(struct lcd_info *lcd)
+static int s6d6aa1_power_off(struct lcd_info *lcd)
{
int ret = 0;
@@ -293,21 +427,21 @@ static int s6e8ax0_power_off(struct lcd_info *lcd)
lcd->ldi_enable = 0;
- ret = s6e8ax0_ldi_disable(lcd);
+ ret = s6d6aa1_ldi_disable(lcd);
msleep(135);
return ret;
}
-static int s6e8ax0_power(struct lcd_info *lcd, int power)
+static int s6d6aa1_power(struct lcd_info *lcd, int power)
{
int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_on(lcd);
+ ret = s6d6aa1_power_on(lcd);
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_off(lcd);
+ ret = s6d6aa1_power_off(lcd);
if (!ret)
lcd->power = power;
@@ -315,7 +449,7 @@ static int s6e8ax0_power(struct lcd_info *lcd, int power)
return ret;
}
-static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+static int s6d6aa1_set_power(struct lcd_device *ld, int power)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -325,17 +459,27 @@ static int s6e8ax0_set_power(struct lcd_device *ld, int power)
return -EINVAL;
}
- return s6e8ax0_power(lcd, power);
+ return s6d6aa1_power(lcd, power);
+}
+
+ static int s6d6aa1_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
}
-static int s6e8ax0_get_power(struct lcd_device *ld)
+static int s6d6aa1_get_power(struct lcd_device *ld)
{
struct lcd_info *lcd = lcd_get_data(ld);
return lcd->power;
}
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6d6aa1_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
@@ -361,7 +505,7 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
return ret;
}
-static int s6e8ax0_get_brightness(struct backlight_device *bd)
+static int s6d6aa1_get_brightness(struct backlight_device *bd)
{
struct lcd_info *lcd = bl_get_data(bd);
@@ -369,28 +513,43 @@ static int s6e8ax0_get_brightness(struct backlight_device *bd)
}
static struct lcd_ops panel_lcd_ops = {
- .set_power = s6e8ax0_set_power,
- .get_power = s6e8ax0_get_power,
+ .set_power = s6d6aa1_set_power,
+ .get_power = s6d6aa1_get_power,
+ .check_fb = s6d6aa1_check_fb,
};
static const struct backlight_ops panel_backlight_ops = {
- .get_brightness = s6e8ax0_get_brightness,
- .update_status = s6e8ax0_set_brightness,
+ .get_brightness = s6d6aa1_get_brightness,
+ .update_status = s6d6aa1_set_brightness,
};
-static ssize_t power_reduce_show(struct device *dev,
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+
+ sprintf(temp, "JDI_ACX445BLN\n");
+
+ strcat(buf, temp);
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
char temp[3];
- sprintf(temp, "%d\n", lcd->acl_enable);
+ sprintf(temp, "%d\n", lcd->auto_brightness);
strcpy(buf, temp);
return strlen(buf);
}
-static ssize_t power_reduce_store(struct device *dev,
+static ssize_t auto_brightness_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
@@ -401,39 +560,21 @@ static ssize_t power_reduce_store(struct device *dev,
if (rc < 0)
return rc;
else {
- if (lcd->acl_enable != value) {
- dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
- mutex_lock(&lcd->bl_lock);
- lcd->acl_enable = value;
- if (lcd->ldi_enable)
- /*s6e8ax0_set_acl(lcd);*/
- mutex_unlock(&lcd->bl_lock);
- }
+ lcd->auto_brightness = value;
+ if (lcd->auto_brightness < 4)
+ s6d6aa1_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
+ else
+ s6d6aa1_write(lcd, SEQ_WRCABC_OUTDOOR, ARRAY_SIZE(SEQ_WRCABC_OUTDOOR));
}
return size;
}
-static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
-
-static ssize_t lcd_type_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- char temp[15];
-
- sprintf(temp, "SMD_AMS480GYXX\n");
-
- strcat(buf, temp);
-
- return strlen(buf);
-}
-
-static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
-
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
#ifdef CONFIG_HAS_EARLYSUSPEND
struct lcd_info *g_lcd;
-void s6e8ax0_early_suspend(void)
+void s6d6aa1_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
@@ -441,21 +582,33 @@ void s6e8ax0_early_suspend(void)
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+ s6d6aa1_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
-void s6e8ax0_late_resume(void)
+void s6d6aa1_late_resume(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
-
+ s6d6aa1_power(lcd, FB_BLANK_UNBLANK);
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
dev_info(&lcd->ld->dev, "-%s\n", __func__);
set_dsim_lcd_enabled(1);
@@ -464,20 +617,7 @@ void s6e8ax0_late_resume(void)
}
#endif
-#if 0
-static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
-{
- int ret = 0;
-
- ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
- if (!ret) {
- lcd->connected = 0;
- dev_info(&lcd->ld->dev, "panel is not connected well\n");
- }
-}
-#endif
-
-static int s6e8ax0_probe(struct device *dev)
+static int s6d6aa1_probe(struct device *dev)
{
int ret = 0;
struct lcd_info *lcd;
@@ -512,17 +652,15 @@ static int s6e8ax0_probe(struct device *dev)
lcd->bl = 0;
lcd->current_bl = lcd->bl;
- lcd->acl_enable = 0;
-
lcd->power = FB_BLANK_UNBLANK;
lcd->ldi_enable = 1;
lcd->connected = 1;
- ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
- ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
@@ -533,6 +671,23 @@ static int s6e8ax0_probe(struct device *dev)
dev_info(&lcd->ld->dev, "s6e8aa0 lcd panel driver has been probed.\n");
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = s6d6aa1_early_suspend;
+ lcd_late_resume = s6d6aa1_late_resume;
+
return 0;
out_free_backlight:
@@ -548,11 +703,11 @@ err_alloc:
return ret;
}
-static int __devexit s6e8ax0_remove(struct device *dev)
+static int __devexit s6d6aa1_remove(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6d6aa1_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
backlight_device_unregister(lcd->bd);
kfree(lcd);
@@ -561,35 +716,35 @@ static int __devexit s6e8ax0_remove(struct device *dev)
}
/* Power down all displays on reboot, poweroff or halt. */
-static void s6e8ax0_shutdown(struct device *dev)
+static void s6d6aa1_shutdown(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
dev_info(&lcd->ld->dev, "%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6d6aa1_power(lcd, FB_BLANK_POWERDOWN);
}
-static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+static struct mipi_lcd_driver s6d6aa1_mipi_driver = {
.name = "s6d6aa1",
- .probe = s6e8ax0_probe,
- .remove = __devexit_p(s6e8ax0_remove),
- .shutdown = s6e8ax0_shutdown,
+ .probe = s6d6aa1_probe,
+ .remove = __devexit_p(s6d6aa1_remove),
+ .shutdown = s6d6aa1_shutdown,
};
-static int s6e8ax0_init(void)
+static int s6d6aa1_init(void)
{
- return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+ return s5p_dsim_register_lcd_driver(&s6d6aa1_mipi_driver);
}
-static void s6e8ax0_exit(void)
+static void s6d6aa1_exit(void)
{
return;
}
-module_init(s6e8ax0_init);
-module_exit(s6e8ax0_exit);
+module_init(s6d6aa1_init);
+module_exit(s6d6aa1_exit);
-MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_DESCRIPTION("MIPI-DSI S6D6AA1:ACX445BLN SCLCD (720x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s6dr171.c b/drivers/video/samsung/s6dr171.c
index 167f658..868c006 100644
--- a/drivers/video/samsung/s6dr171.c
+++ b/drivers/video/samsung/s6dr171.c
@@ -79,7 +79,10 @@ struct lcd_info {
struct dsim_global *dsim;
};
-static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+static int s6dr171_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
const unsigned char *wbuf;
@@ -104,7 +107,7 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
return 0;
}
-static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+static int _s6dr171_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
{
int ret = 0;
@@ -121,12 +124,12 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
return ret;
}
-static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+static int s6dr171_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
read_retry:
- ret = _s6e8ax0_read(lcd, addr, count, buf);
+ ret = _s6dr171_read(lcd, addr, count, buf);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n", __func__, retry_cnt);
@@ -139,55 +142,55 @@ read_retry:
return ret;
}
-static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+static int s6dr171_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_1_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_1_KEY));
- s6e8ax0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
- s6e8ax0_write(lcd, SEQ_PWRSEQCTL, ARRAY_SIZE(SEQ_PWRSEQCTL));
- s6e8ax0_write(lcd, SEQ_DISPLAY_BRIGHTNESSS, ARRAY_SIZE(SEQ_DISPLAY_BRIGHTNESSS));
- s6e8ax0_write(lcd, SEQ_CONTROL_DISPLAY, ARRAY_SIZE(SEQ_CONTROL_DISPLAY));
- s6e8ax0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ s6dr171_write(lcd, SEQ_APPLY_LEVEL_1_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_1_KEY));
+ s6dr171_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6dr171_write(lcd, SEQ_PWRSEQCTL, ARRAY_SIZE(SEQ_PWRSEQCTL));
+ s6dr171_write(lcd, SEQ_DISPLAY_BRIGHTNESSS, ARRAY_SIZE(SEQ_DISPLAY_BRIGHTNESSS));
+ s6dr171_write(lcd, SEQ_CONTROL_DISPLAY, ARRAY_SIZE(SEQ_CONTROL_DISPLAY));
+ s6dr171_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
msleep(120);
- s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6dr171_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6dr171_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6dr171_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ s6dr171_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
msleep(20);
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE2, ARRAY_SIZE(SEQ_GAMMA_UPDATE2));
+ s6dr171_write(lcd, SEQ_GAMMA_UPDATE2, ARRAY_SIZE(SEQ_GAMMA_UPDATE2));
msleep(20);
- s6e8ax0_write(lcd, SEQ_ETC_SOURCE_CONTROL, ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
- s6e8ax0_write(lcd, SEQ_ETC_NVM_SETTING, ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
- s6e8ax0_write(lcd, SEQ_ETC_POWER_CONTROL, ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
+ s6dr171_write(lcd, SEQ_ETC_SOURCE_CONTROL, ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6dr171_write(lcd, SEQ_ETC_NVM_SETTING, ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
+ s6dr171_write(lcd, SEQ_ETC_POWER_CONTROL, ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
- s6e8ax0_write(lcd, SEQ_ELVSS_CONTROL, ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+ s6dr171_write(lcd, SEQ_ELVSS_CONTROL, ARRAY_SIZE(SEQ_ELVSS_CONTROL));
return ret;
}
-static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+static int s6dr171_ldi_enable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+ s6dr171_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
return ret;
}
-static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+static int s6dr171_ldi_disable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
- s6e8ax0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
+ s6dr171_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6dr171_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
return ret;
}
-static int s6e8ax0_power_on(struct lcd_info *lcd)
+static int s6dr171_power_on(struct lcd_info *lcd)
{
int ret = 0;
struct lcd_platform_data *pd = NULL;
@@ -195,7 +198,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
/* dev_info(&lcd->ld->dev, "%s\n", __func__); */
- ret = s6e8ax0_ldi_init(lcd);
+ ret = s6dr171_ldi_init(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
goto err;
@@ -203,7 +206,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
msleep(120);
- ret = s6e8ax0_ldi_enable(lcd);
+ ret = s6dr171_ldi_enable(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
goto err;
@@ -216,7 +219,7 @@ err:
return ret;
}
-static int s6e8ax0_power_off(struct lcd_info *lcd)
+static int s6dr171_power_off(struct lcd_info *lcd)
{
int ret = 0;
@@ -224,21 +227,21 @@ static int s6e8ax0_power_off(struct lcd_info *lcd)
lcd->ldi_enable = 0;
- ret = s6e8ax0_ldi_disable(lcd);
+ ret = s6dr171_ldi_disable(lcd);
msleep(135);
return ret;
}
-static int s6e8ax0_power(struct lcd_info *lcd, int power)
+static int s6dr171_power(struct lcd_info *lcd, int power)
{
int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_on(lcd);
+ ret = s6dr171_power_on(lcd);
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_off(lcd);
+ ret = s6dr171_power_off(lcd);
if (!ret)
lcd->power = power;
@@ -246,7 +249,7 @@ static int s6e8ax0_power(struct lcd_info *lcd, int power)
return ret;
}
-static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+static int s6dr171_set_power(struct lcd_device *ld, int power)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -256,17 +259,17 @@ static int s6e8ax0_set_power(struct lcd_device *ld, int power)
return -EINVAL;
}
- return s6e8ax0_power(lcd, power);
+ return s6dr171_power(lcd, power);
}
-static int s6e8ax0_get_power(struct lcd_device *ld)
+static int s6dr171_get_power(struct lcd_device *ld)
{
struct lcd_info *lcd = lcd_get_data(ld);
return lcd->power;
}
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6dr171_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
@@ -292,13 +295,13 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
return ret;
}
-static struct lcd_ops s6e8ax0_lcd_ops = {
- .set_power = s6e8ax0_set_power,
- .get_power = s6e8ax0_get_power,
+static struct lcd_ops s6dr171_lcd_ops = {
+ .set_power = s6dr171_set_power,
+ .get_power = s6dr171_get_power,
};
-static const struct backlight_ops s6e8ax0_backlight_ops = {
- .update_status = s6e8ax0_set_brightness,
+static const struct backlight_ops s6dr171_backlight_ops = {
+ .update_status = s6dr171_set_brightness,
};
static ssize_t power_reduce_show(struct device *dev,
@@ -329,7 +332,7 @@ static ssize_t power_reduce_store(struct device *dev,
mutex_lock(&lcd->bl_lock);
lcd->acl_enable = value;
/* if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd); */
+ s6dr171_set_acl(lcd); */
mutex_unlock(&lcd->bl_lock);
}
}
@@ -389,25 +392,25 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_
#ifdef CONFIG_HAS_EARLYSUSPEND
struct lcd_info *g_lcd;
-void s6e8ax0_early_suspend(void)
+void s6dr171_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
set_dsim_lcd_enabled(0);
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6dr171_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
-void s6e8ax0_late_resume(void)
+void s6dr171_late_resume(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
+ s6dr171_power(lcd, FB_BLANK_UNBLANK);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
set_dsim_lcd_enabled(1);
@@ -416,28 +419,28 @@ void s6e8ax0_late_resume(void)
}
#endif
-static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+static int s6dr171_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
{
int ret, i;
for (i = 0; i < 3; i++)
- ret = s6e8ax0_read(lcd, LDI_MTP_ADDR+i, LDI_MTP_LENGTH, mtp_data, 0);
+ ret = s6dr171_read(lcd, LDI_MTP_ADDR+i, LDI_MTP_LENGTH, mtp_data, 0);
return ret;
}
-static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
+static void s6dr171_read_id(struct lcd_info *lcd, u8 *buf)
{
int ret = 0;
- ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ ret = s6dr171_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
if (!ret) {
lcd->connected = 0;
dev_info(&lcd->ld->dev, "panel is not connected well\n");
}
}
-static int s6e8ax0_probe(struct device *dev)
+static int s6dr171_probe(struct device *dev)
{
int ret = 0;
struct lcd_info *lcd;
@@ -452,14 +455,14 @@ static int s6e8ax0_probe(struct device *dev)
g_lcd = lcd;
- lcd->ld = lcd_device_register("panel", dev, lcd, &s6e8ax0_lcd_ops);
+ lcd->ld = lcd_device_register("panel", dev, lcd, &s6dr171_lcd_ops);
if (IS_ERR(lcd->ld)) {
pr_err("failed to register lcd device\n");
ret = PTR_ERR(lcd->ld);
goto out_free_lcd;
}
- lcd->bd = backlight_device_register("panel", dev, lcd, &s6e8ax0_backlight_ops, NULL);
+ lcd->bd = backlight_device_register("panel", dev, lcd, &s6dr171_backlight_ops, NULL);
if (IS_ERR(lcd->bd)) {
pr_err("failed to register backlight device\n");
ret = PTR_ERR(lcd->bd);
@@ -498,18 +501,21 @@ static int s6e8ax0_probe(struct device *dev)
mutex_init(&lcd->lock);
mutex_init(&lcd->bl_lock);
- s6e8ax0_read_id(lcd, lcd->id);
+ s6dr171_read_id(lcd, lcd->id);
dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
dev_info(&lcd->ld->dev, "lcd panel driver has been probed.\n");
- ret = s6e8ax0_read_mtp(lcd, mtp_data);
+ ret = s6dr171_read_mtp(lcd, mtp_data);
if (!ret) {
printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
/*return -EPERM;*/
}
+ lcd_early_suspend = s6dr171_early_suspend;
+ lcd_late_resume = s6dr171_late_resume;
+
return 0;
out_free_backlight:
@@ -525,11 +531,11 @@ err_alloc:
return ret;
}
-static int __devexit s6e8ax0_remove(struct device *dev)
+static int __devexit s6dr171_remove(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6dr171_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
backlight_device_unregister(lcd->bd);
kfree(lcd);
@@ -538,34 +544,34 @@ static int __devexit s6e8ax0_remove(struct device *dev)
}
/* Power down all displays on reboot, poweroff or halt. */
-static void s6e8ax0_shutdown(struct device *dev)
+static void s6dr171_shutdown(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
dev_info(&lcd->ld->dev, "%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6dr171_power(lcd, FB_BLANK_POWERDOWN);
}
-static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+static struct mipi_lcd_driver s6dr171_mipi_driver = {
.name = "s6e8aa0",
- .probe = s6e8ax0_probe,
- .remove = __devexit_p(s6e8ax0_remove),
- .shutdown = s6e8ax0_shutdown,
+ .probe = s6dr171_probe,
+ .remove = __devexit_p(s6dr171_remove),
+ .shutdown = s6dr171_shutdown,
};
-static int s6e8ax0_init(void)
+static int s6dr171_init(void)
{
- return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+ return s5p_dsim_register_lcd_driver(&s6dr171_mipi_driver);
}
-static void s6e8ax0_exit(void)
+static void s6dr171_exit(void)
{
return;
}
-module_init(s6e8ax0_init);
-module_exit(s6e8ax0_exit);
+module_init(s6dr171_init);
+module_exit(s6dr171_exit);
-MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_DESCRIPTION("MIPI-DSI S6DR171:AMS480GZ01-0 (720x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s6e63m0_gamma_grande.h b/drivers/video/samsung/s6e63m0_gamma_grande.h
new file mode 100644
index 0000000..4692a78
--- /dev/null
+++ b/drivers/video/samsung/s6e63m0_gamma_grande.h
@@ -0,0 +1,229 @@
+#ifndef __S6E63M0_GAMMA_H__
+#define __S6E63M0_GAMMA_H__
+
+#include "s6e63m0_param.h"
+
+#define ACL_PARAM_SIZE ARRAY_SIZE(acl_cutoff_50)
+#define AID_PARAM_SIZE ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_500MBPS)
+
+static const unsigned char SEQ_PANEL_CONDITION_SET_500MBPS[] = {
+ 0xF8,
+ 0x19, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x7D, 0x10,
+ 0x27, 0x08, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x6E,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x23, 0x6E, 0xC0, 0xC1,
+ 0x01, 0x81, 0xC1, 0x00, 0xC3, 0xF6, 0xF6, 0xC1
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET_500MBPS_46[] = {
+ 0xF8,
+ 0x3D, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3C, 0x7D, 0x08,
+ 0x27, 0x7D, 0x3F, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08, 0x6E,
+ 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xC0, 0xC8,
+ 0x08, 0x48, 0xC1, 0x00, 0xC1, 0xFF, 0xFF, 0xC8
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET_480MBPS_46[] = {
+ 0xF8,
+ 0x3D, 0x32, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x39, 0x78, 0x08,
+ 0x26, 0x78, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08, 0x69,
+ 0x00, 0x00, 0x00, 0x02, 0x07, 0x07, 0x21, 0x21, 0xC0, 0xC8,
+ 0x08, 0x48, 0xC1, 0x00, 0xC1, 0xFF, 0xFF, 0xC8
+};
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xFA,
+ 0x01, 0x58, 0x1F, 0x63, 0xAC, 0xB4, 0x99, 0xAD, 0xBA, 0xA3,
+ 0xC0, 0xCB, 0xBB, 0x93, 0x9F, 0x8B, 0xAD, 0xB4, 0xA7, 0x00,
+ 0xBE, 0x00, 0xAB, 0x00, 0xE7
+};
+#endif
+static const unsigned char SEQ_GAMMA_CONDITION_SET_A1_SM2[] = {
+ 0xFA,
+ 0x01, 0x71, 0x31, 0x7B, 0xA4, 0xB6,
+ 0x95, 0xA9, 0xBC, 0xA2, 0xBB, 0xC9,
+ 0xB6, 0x91, 0xA3, 0x8B, 0xAD, 0xB6,
+ 0xA9, 0x00, 0xD6, 0x00, 0xBE, 0x00,
+ 0xFC,
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET_A2_SM2[] = {
+ 0xFA,
+ 0x01, 0x5F, 0x2E, 0x67, 0xAA, 0xC6,
+ 0xAC, 0xB0, 0xC8, 0xBB, 0xBE, 0xCB,
+ 0xBD, 0x97, 0xA5, 0x91, 0xAF, 0xB8,
+ 0xAB, 0x00, 0xC2, 0x00, 0xBA, 0x00, 0xE2,
+};
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
+ 0xF6,
+ 0x00, 0x02, 0x00
+};
+#endif
+
+static const unsigned char SEQ_ETC_PENTILE_CONTROL[] = {
+ 0xB6,
+ 0x0C, 0x02, 0x03, 0x32, 0xC0,
+ 0x44, 0x44, 0xC0, 0x00
+};
+
+static const unsigned char SEQ_ETC_PENTILE_CONTROL_46[] = {
+ 0xB6,
+ 0x0C, 0x02, 0x03, 0x32, 0xFF,
+ 0x44, 0x44, 0xC0, 0x00
+};
+
+static const unsigned char SEQ_ETC_NVM_SETTING[] = {
+ 0xD9,
+ 0x14, 0x40, 0x0C, 0xCB, 0xCE,
+ 0x6E, 0xC4, 0x07, 0xC0, 0x41,
+ 0xC1, 0x00, 0x60, 0x19
+};
+
+static const unsigned char SEQ_ETC_NVM_SETTING_46[] = {
+ 0xD9,
+ 0x14, 0x40, 0x0C, 0xCB, 0xCE,
+ 0x6E, 0xC4, 0x07, 0xC0, 0x41,
+ 0xD0, 0x00, 0x60, 0x19
+};
+
+static const unsigned char SEQ_ETC_POWER_CONTROL[] = {
+ 0xF4,
+ 0xCF, 0x0A, 0x15, 0x10, 0x19, 0x33, 0x02
+};
+
+static const unsigned char SEQ_ETC_POWER_CONTROL_46[] = {
+ 0xF4,
+ 0xCF, 0x0A, 0x12, 0x10, 0x1E, 0x33, 0x02
+};
+
+
+enum {
+ ACL_STATUS_0P = 0,
+ ACL_STATUS_20P,
+ ACL_STATUS_33P,
+ ACL_STATUS_40P,
+ ACL_STATUS_43P,
+ ACL_STATUS_45P,
+ ACL_STATUS_48P,
+ ACL_STATUS_50P,
+ ACL_STATUS_52P,
+ ACL_STATUS_53P,
+ ACL_STATUS_55P,
+ ACL_STATUS_MAX
+} ACL_STATUS;
+
+const unsigned char acl_cutoff_20[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x04, 0x07, 0x0A, 0x0D, 0x10,
+ 0x12, 0x15, 0x18, 0x1B, 0x1E
+};
+
+const unsigned char acl_cutoff_33[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x06, 0x0A, 0x0F, 0x14, 0x19,
+ 0x1D, 0x22, 0x27, 0x2B, 0x30
+};
+
+const unsigned char acl_cutoff_40[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x08, 0x0F, 0x15, 0x1C, 0x23,
+ 0x2A, 0x31, 0x37, 0x3E, 0x45
+};
+
+const unsigned char acl_cutoff_43[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x07, 0x0D, 0x14, 0x1A, 0x20,
+ 0x26, 0x2C, 0x33, 0x39, 0x3F
+};
+
+const unsigned char acl_cutoff_45[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x07, 0x0E, 0x14, 0x1B, 0x21,
+ 0x27, 0x2E, 0x34, 0x3B, 0x41
+};
+
+const unsigned char acl_cutoff_48[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x08, 0x0F, 0x17, 0x1E, 0x25,
+ 0x2C, 0x33, 0x3B, 0x42, 0x49
+};
+
+const unsigned char acl_cutoff_50[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x09, 0x10, 0x18, 0x1F, 0x27,
+ 0x2E, 0x36, 0x3D, 0x45, 0x4C
+};
+
+const unsigned char acl_cutoff_52[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x09, 0x11, 0x19, 0x21, 0x29,
+ 0x31, 0x39, 0x41, 0x49, 0x51
+};
+
+const unsigned char acl_cutoff_53[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x09, 0x11, 0x1A, 0x22, 0x2A,
+ 0x32, 0x3A, 0x43, 0x4B, 0x53
+};
+
+const unsigned char acl_cutoff_55[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x0A, 0x12, 0x1B, 0x23, 0x2C,
+ 0x35, 0x3D, 0x46, 0x4E, 0x57
+};
+
+const unsigned char *ACL_CUTOFF_TABLE[ACL_STATUS_MAX] = {
+ SEQ_ACL_OFF,
+ acl_cutoff_20,
+ acl_cutoff_33,
+ acl_cutoff_40,
+ acl_cutoff_43,
+ acl_cutoff_45,
+ acl_cutoff_48,
+ acl_cutoff_50,
+ acl_cutoff_52,
+ acl_cutoff_53,
+ acl_cutoff_55,
+};
+
+#endif /* __S6E63M0_GAMMA_H__ */
diff --git a/drivers/video/samsung/s6e63m0_gamma_l.h b/drivers/video/samsung/s6e63m0_gamma_l.h
new file mode 100644
index 0000000..8d57c5a
--- /dev/null
+++ b/drivers/video/samsung/s6e63m0_gamma_l.h
@@ -0,0 +1,311 @@
+#ifndef __S6E63M0_GAMMA_L_H__
+#define __S6E63M0_GAMMA_L_H__
+
+#include "s6e63m0_param.h"
+#ifdef CONFIG_AID_DIMMING
+#include "aid_s6e8aa0.h"
+#endif
+
+static const unsigned char gamma22_20[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xDF, 0x86, 0xF5,
+ 0xD5, 0xC7, 0xCF, 0xDF, 0xE0, 0xE0,
+ 0xC9, 0xC9, 0xCC, 0xD7, 0xD6, 0xD5,
+ 0x00, 0x68, 0x00, 0x68, 0x00, 0x75,
+};
+
+static const unsigned char gamma22_30[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xDF, 0x86, 0xF5,
+ 0xD5, 0xC7, 0xCF, 0xDF, 0xE0, 0xE0,
+ 0xC9, 0xC9, 0xCC, 0xD7, 0xD6, 0xD5,
+ 0x00, 0x68, 0x00, 0x68, 0x00, 0x75,
+};
+
+static const unsigned char gamma22_40[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xE5, 0xAA, 0xF2,
+ 0xD6, 0xCC, 0xCF, 0xE0, 0xE2, 0xE2,
+ 0xC8, 0xC9, 0xCA, 0xD2, 0xD2, 0xCF,
+ 0x00, 0x71, 0x00, 0x70, 0x00, 0x80,
+};
+
+static const unsigned char gamma22_50[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xE7, 0xBB, 0xEE,
+ 0xD6, 0xCE, 0xD0, 0xE0, 0xE3, 0xE4,
+ 0xC5, 0xC4, 0xC5, 0xD2, 0xD2, 0xCF,
+ 0x00, 0x78, 0x00, 0x78, 0x00, 0x88,
+};
+
+static const unsigned char gamma22_60[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xE9, 0xC4, 0xEB,
+ 0xD6, 0xD0, 0xD1, 0xE0, 0xE3, 0xE4,
+ 0xC3, 0xC2, 0xC2, 0xD2, 0xD1, 0xCF,
+ 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x8F,
+};
+
+static const unsigned char gamma22_70[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEA, 0xC9, 0xEA,
+ 0xD6, 0xD2, 0xD2, 0xDF, 0xE1, 0xE3,
+ 0xC2, 0xC1, 0xC0, 0xD1, 0xD0, 0xCE,
+ 0x00, 0x84, 0x00, 0x84, 0x00, 0x96,
+};
+
+static const unsigned char gamma22_80[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEB, 0xCC, 0xE9,
+ 0xD5, 0xD4, 0xD3, 0xDE, 0xE1, 0xE2,
+ 0xC2, 0xBF, 0xBF, 0xCF, 0xCF, 0xCC,
+ 0x00, 0x89, 0x00, 0x89, 0x00, 0x9C,
+};
+
+static const unsigned char gamma22_90[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEB, 0xD0, 0xE9,
+ 0xD4, 0xD5, 0xD4, 0xDF, 0xE0, 0xE1,
+ 0xC1, 0xBE, 0xBD, 0xCD, 0xCD, 0xCA,
+ 0x00, 0x8E, 0x00, 0x8F, 0x00, 0xA2,
+};
+
+static const unsigned char gamma22_100[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEA, 0xD2, 0xE7,
+ 0xD7, 0xD6, 0xD6, 0xDF, 0xDF, 0xE2,
+ 0xBF, 0xBD, 0xBC, 0xCD, 0xCD, 0xC9,
+ 0x00, 0x92, 0x00, 0x93, 0x00, 0xA7,
+};
+
+static const unsigned char gamma22_110[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEB, 0xD4, 0xE5,
+ 0xD6, 0xD6, 0xD7, 0xDE, 0xDF, 0xE0,
+ 0xBE, 0xBC, 0xBB, 0xCE, 0xCC, 0xC9,
+ 0x00, 0x96, 0x00, 0x97, 0x00, 0xAC,
+};
+
+static const unsigned char gamma22_120[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xD6, 0xE6,
+ 0xD6, 0xD7, 0xD8, 0xDE, 0xDE, 0xE0,
+ 0xBC, 0xBC, 0xB9, 0xCD, 0xCA, 0xC8,
+ 0x00, 0x9A, 0x00, 0x9C, 0x00, 0xB1,
+};
+
+static const unsigned char gamma22_130[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xD7, 0xE6,
+ 0xD3, 0xD8, 0xD7, 0xDE, 0xDD, 0xDF,
+ 0xBD, 0xBB, 0xB8, 0xCA, 0xC9, 0xC6,
+ 0x00, 0x9F, 0x00, 0xA0, 0x00, 0xB7,
+};
+
+static const unsigned char gamma22_140[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xD9, 0xE5,
+ 0xD4, 0xD8, 0xD9, 0xDE, 0xDD, 0xDF,
+ 0xBB, 0xB9, 0xB7, 0xCA, 0xC9, 0xC5,
+ 0x00, 0xA3, 0x00, 0xA4, 0x00, 0xBB,
+};
+
+static const unsigned char gamma22_150[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xDA, 0xE5,
+ 0xD4, 0xD8, 0xD9, 0xDD, 0xDD, 0xDD,
+ 0xBB, 0xB9, 0xB6, 0xC9, 0xC7, 0xC5,
+ 0x00, 0xA6, 0x00, 0xA8, 0x00, 0xBF,
+};
+
+static const unsigned char gamma22_160[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xDB, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDC, 0xDD, 0xDD,
+ 0xB9, 0xB8, 0xB4, 0xC9, 0xC6, 0xC4,
+ 0x00, 0xAA, 0x00, 0xAC, 0x00, 0xC4,
+};
+
+static const unsigned char gamma22_170[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xDC, 0xE5,
+ 0xD5, 0xD8, 0xD9, 0xDD, 0xDC, 0xDD,
+ 0xBA, 0xB7, 0xB5, 0xC7, 0xC6, 0xC3,
+ 0x00, 0xAD, 0x00, 0xAF, 0x00, 0xC7,
+};
+
+static const unsigned char gamma22_180[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+#ifdef CONFIG_AID_DIMMING
+static const unsigned char gamma22_182[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+static const unsigned char gamma22_184[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+static const unsigned char gamma22_186[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+static const unsigned char gamma22_188[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+#endif
+
+static const unsigned char gamma22_190[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xDE, 0xE6,
+ 0xD3, 0xD8, 0xD8, 0xDD, 0xDB, 0xDC,
+ 0xB9, 0xB6, 0xB4, 0xC5, 0xC4, 0xC0,
+ 0x00, 0xB4, 0x00, 0xB6, 0x00, 0xD0,
+};
+
+static const unsigned char gamma22_200[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xDF, 0xE6,
+ 0xD3, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA,
+ 0xB8, 0xB6, 0xB3, 0xC4, 0xC3, 0xC0,
+ 0x00, 0xB8, 0x00, 0xB9, 0x00, 0xD4,
+};
+
+static const unsigned char gamma22_210[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE0, 0xE5,
+ 0xD5, 0xD7, 0xD9, 0xDB, 0xDA, 0xDA,
+ 0xB7, 0xB5, 0xB1, 0xC4, 0xC2, 0xC0,
+ 0x00, 0xBA, 0x00, 0xBD, 0x00, 0xD7,
+};
+
+static const unsigned char gamma22_220[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE0, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDA, 0xDA, 0xD9,
+ 0xB7, 0xB4, 0xB1, 0xC2, 0xC2, 0xBE,
+ 0x00, 0xBE, 0x00, 0xC0, 0x00, 0xDC,
+};
+
+static const unsigned char gamma22_230[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE2, 0xE6,
+ 0xD3, 0xD6, 0xD8, 0xDC, 0xD9, 0xD9,
+ 0xB6, 0xB4, 0xB1, 0xC1, 0xC1, 0xBD,
+ 0x00, 0xC1, 0x00, 0xC3, 0x00, 0xDF,
+};
+
+static const unsigned char gamma22_240[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE2, 0xE6,
+ 0xD4, 0xD6, 0xD8, 0xDA, 0xDA, 0xDA,
+ 0xB6, 0xB3, 0xB0, 0xC1, 0xBF, 0xBC,
+ 0x00, 0xC4, 0x00, 0xC7, 0x00, 0xE3,
+};
+
+static const unsigned char gamma22_250[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE3, 0xE7,
+ 0xD4, 0xD6, 0xD8, 0xDB, 0xD9, 0xD9,
+ 0xB3, 0xB2, 0xAE, 0xC1, 0xC0, 0xBC,
+ 0x00, 0xC7, 0x00, 0xC9, 0x00, 0xE7,
+};
+
+static const unsigned char gamma22_260[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE4, 0xE7,
+ 0xD4, 0xD5, 0xD7, 0xDA, 0xD9, 0xD9,
+ 0xB3, 0xB2, 0xAD, 0xC1, 0xBE, 0xBC,
+ 0x00, 0xC9, 0x00, 0xCD, 0x00, 0xEA,
+};
+
+static const unsigned char gamma22_270[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE5, 0xE8,
+ 0xD3, 0xD5, 0xD5, 0xDB, 0xD9, 0xD9,
+ 0xB3, 0xB1, 0xAE, 0xBF, 0xBE, 0xBA,
+ 0x00, 0xCC, 0x00, 0xD0, 0x00, 0xEE,
+};
+
+static const unsigned char gamma22_280[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE5, 0xE6,
+ 0xD2, 0xD4, 0xD6, 0xDA, 0xD9, 0xD8,
+ 0xB3, 0xB1, 0xAD, 0xBF, 0xBD, 0xBA,
+ 0x00, 0xCF, 0x00, 0xD3, 0x00, 0xF1,
+};
+
+static const unsigned char gamma22_290[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE6, 0xE7,
+ 0xD2, 0xD4, 0xD5, 0xDB, 0xD8, 0xD8,
+ 0xB1, 0xB0, 0xAC, 0xBE, 0xBD, 0xB9,
+ 0x00, 0xD3, 0x00, 0xD6, 0x00, 0xF5,
+};
+
+static const unsigned char gamma22_300[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE6, 0xE7,
+ 0xD1, 0xD3, 0xD4, 0xDA, 0xD8, 0xD7,
+ 0xB1, 0xAF, 0xAB, 0xBD, 0xBB, 0xB8,
+ 0x00, 0xD6, 0x00, 0xDA, 0x00, 0xFA,
+};
+
+static const unsigned char *gamma22_table[GAMMA_MAX] = {
+#ifdef CONFIG_AID_DIMMING
+ gamma22_20,
+#endif
+ gamma22_30,
+ gamma22_40,
+ gamma22_50,
+ gamma22_60,
+ gamma22_70,
+ gamma22_80,
+ gamma22_90,
+ gamma22_100,
+ gamma22_110,
+ gamma22_120,
+ gamma22_130,
+ gamma22_140,
+ gamma22_150,
+ gamma22_160,
+ gamma22_170,
+ gamma22_180,
+#ifdef CONFIG_AID_DIMMING
+ gamma22_182,
+ gamma22_184,
+ gamma22_186,
+ gamma22_188,
+#endif
+ gamma22_190,
+ gamma22_200,
+ gamma22_210,
+ gamma22_220,
+ gamma22_230,
+ gamma22_240,
+ gamma22_250,
+ gamma22_300,
+};
+
+#endif /* __S6E63M0_GAMMA_L_H__ */
diff --git a/drivers/video/samsung/s6e63m0_param.h b/drivers/video/samsung/s6e63m0_param.h
new file mode 100644
index 0000000..c69ed45b
--- /dev/null
+++ b/drivers/video/samsung/s6e63m0_param.h
@@ -0,0 +1,375 @@
+#ifndef __S6E63M0_PARAM_H__
+#define __S6E63M0_PARAM_H__
+
+#define GAMMA_PARAM_SIZE 26
+#define ELVSS_PARAM_SIZE 3
+
+#define ELVSS_OFFSET_300 0x00
+#define ELVSS_OFFSET_290 0x01
+#define ELVSS_OFFSET_280 0x02
+#define ELVSS_OFFSET_270 0x03
+#define ELVSS_OFFSET_260 0x04
+#define ELVSS_OFFSET_250 0x05
+#define ELVSS_OFFSET_240 0x06
+#define ELVSS_OFFSET_230 0x06
+#define ELVSS_OFFSET_220 0x07
+#define ELVSS_OFFSET_210 0x08
+#define ELVSS_OFFSET_200 0x09
+#define ELVSS_OFFSET_190 0x05
+#define ELVSS_OFFSET_180 0x05
+#define ELVSS_OFFSET_170 0x06
+#define ELVSS_OFFSET_160 0x07
+#define ELVSS_OFFSET_150 0x08
+#define ELVSS_OFFSET_140 0x09
+#define ELVSS_OFFSET_130 0x0A
+#define ELVSS_OFFSET_120 0x0B
+#define ELVSS_OFFSET_110 0x0C
+#define ELVSS_OFFSET_100 0x0D
+#define ELVSS_OFFSET_090 0x0E
+#define ELVSS_OFFSET_080 0x0F
+#define ELVSS_OFFSET_070 0x10
+#define ELVSS_OFFSET_060 0x11
+#define ELVSS_OFFSET_050 0x12
+
+#if defined(CONFIG_MACH_Q1_BD)
+#define ELVSS_OFFSET_MAX ELVSS_OFFSET_300
+#define ELVSS_OFFSET_1 ELVSS_OFFSET_210
+#define ELVSS_OFFSET_2 ELVSS_OFFSET_100
+#define ELVSS_OFFSET_MIN ELVSS_OFFSET_060
+#else
+#define ELVSS_OFFSET_MAX ELVSS_OFFSET_300
+#define ELVSS_OFFSET_1 ELVSS_OFFSET_210
+#define ELVSS_OFFSET_2 ELVSS_OFFSET_1
+#define ELVSS_OFFSET_MIN ELVSS_OFFSET_050
+#endif
+
+#ifdef CONFIG_AID_DIMMING
+enum {
+ ELVSS_110 = 0,
+ ELVSS_120,
+ ELVSS_130,
+ ELVSS_140,
+ ELVSS_150,
+ ELVSS_160,
+ ELVSS_170,
+ ELVSS_180,
+ ELVSS_190,
+ ELVSS_200,
+ ELVSS_210,
+ ELVSS_220,
+ ELVSS_230,
+ ELVSS_240,
+ ELVSS_250,
+ ELVSS_260,
+ ELVSS_270,
+ ELVSS_280,
+ ELVSS_290,
+ ELVSS_300,
+ ELVSS_STATUS_MAX,
+};
+
+#else
+enum {
+ ELVSS_MIN = 0,
+ ELVSS_1,
+ ELVSS_2,
+ ELVSS_MAX,
+ ELVSS_STATUS_MAX,
+};
+#endif
+
+enum {
+ GAMMA_20CD,
+#ifdef CONFIG_AID_DIMMING
+ GAMMA_30CD,
+#else
+ GAMMA_30CD = GAMMA_20CD,
+#endif
+ GAMMA_40CD,
+ GAMMA_50CD,
+ GAMMA_60CD,
+ GAMMA_70CD,
+ GAMMA_80CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+#ifdef CONFIG_AID_DIMMING
+ GAMMA_182CD,
+ GAMMA_184CD,
+ GAMMA_186CD,
+ GAMMA_188CD,
+#endif
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_290CD,
+ GAMMA_300CD = GAMMA_290CD,
+ GAMMA_MAX
+};
+
+#if 0
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY[] = {
+ 0xFC,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_MTP_KEY_ENABLE[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_CONDITION_SET[] = {
+ 0xF2,
+ 0x80, 0x03, 0x0D
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xF7, 0x03,
+ 0x00
+};
+
+static const unsigned char SEQ_ELVSS_CONTROL[] = {
+ 0xB1,
+ 0x04, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_STANDBY_ON[] = {
+ 0x01,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_ACL_ON[] = {
+ 0xC0, 0x01,
+ 0x00
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+ 0x00
+};
+
+static const unsigned char SEQ_ELVSS_32[] = {
+ 0xB1,
+ 0x04, 0x9F
+};
+
+static const unsigned char SEQ_ELVSS_34[] = {
+ 0xB1,
+ 0x04, 0x9D
+};
+
+static const unsigned char SEQ_ELVSS_38[] = {
+ 0xB1,
+ 0x04, 0x99
+};
+
+static const unsigned char SEQ_ELVSS_47[] = {
+ 0xB1,
+ 0x04, 0x90
+};
+
+static const unsigned char *ELVSS_TABLE[] = {
+ SEQ_ELVSS_32,
+ SEQ_ELVSS_34,
+ SEQ_ELVSS_38,
+ SEQ_ELVSS_47,
+};
+#endif
+
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+static const unsigned char SEQ_SW_RESET[] = {
+ 0x01,
+ 0x00, 0x00
+};
+#endif
+
+static const unsigned char SEQ_APPLY_LEVEL2_KEY_ENABLE[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_MTP_KEY_ENABLE[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xFA,
+ 0x02, 0x18, 0x08, 0x24, 0x6B, 0x76, 0x57, 0xBD, 0xC3, 0xB5,
+ 0xB4, 0xBB, 0xAC, 0xC5, 0xC9, 0xC0, 0x00, 0xB7, 0x00, 0xAB,
+ 0x00, 0xCF,
+};
+
+const unsigned char SEQ_PANEL_CONDITION_SET[] = {
+ 0xF8,
+ 0x01, 0x27, 0x27, 0x07, 0x07, 0x54, 0x9F, 0x63, 0x86, 0x1A,
+ 0x33, 0x0D, 0x00, 0x00,
+};
+
+const unsigned char SEQ_DISPLAY_CONDITION_SET1[] = {
+ 0xF2,
+ 0x02, 0x03, 0x1C, 0x10, 0x10,
+};
+
+const unsigned char SEQ_DISPLAY_CONDITION_SET2[] = {
+ 0xF7,
+ 0x10, 0x00, 0x00,
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xFA, 0x03,
+};
+
+static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
+ 0xF6,
+ 0x00, 0x8E, 0x07,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B3h[] = {
+ 0xB3, 0x0C,
+};
+
+#if 0
+static const unsigned char SEQ_ETC_CONTROL_B5h[] = {
+ 0xB5,
+ 0x2C, 0x12, 0x0C, 0x0A, 0x10, 0x0E, 0x17, 0x13,
+ 0x1F, 0x1A, 0x2A, 0x24, 0x1F, 0x1B, 0x1A, 0x17,
+ 0x2B, 0x26, 0x22, 0x20, 0x3A, 0x34, 0x30, 0x2C,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1E, 0x1E,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B6h[] = {
+ 0xB6,
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B7h[] = {
+ 0xB7,
+ 0x2C, 0x12, 0x0C, 0x0A, 0x10, 0x0E, 0x17, 0x13,
+ 0x1F, 0x1A, 0x2A, 0x24, 0x1F, 0x1B, 0x1A, 0x17,
+ 0x2B, 0x26, 0x22, 0x20, 0x3A, 0x34, 0x30, 0x2C,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1E, 0x1E,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B8h[] = {
+ 0xB8,
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B9h[] = {
+ 0xB9,
+ 0x2C, 0x12, 0x0C, 0x0A, 0x10, 0x0E, 0x17, 0x13,
+ 0x1F, 0x1A, 0x2A, 0x24, 0x1F, 0x1B, 0x1A, 0x17,
+ 0x2B, 0x26, 0x22, 0x20, 0x3A, 0x34, 0x30, 0x2C,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1E, 0x1E,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_BAh[] = {
+ 0xBA,
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+};
+#endif
+
+const unsigned char SEQ_STANDBY_ON[] = {
+ 0x10,
+ 0x00, 0x00
+};
+
+const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+const unsigned char SEQ_ELVSS_SET[] = {
+ 0xB2,
+ 0x17, 0x17, 0x17, 0x17,
+};
+
+const unsigned char SEQ_ELVSS_ON[] = {
+ 0xB1, 0x0B,
+ 0x00,
+};
+
+
+static const unsigned char SEQ_ACL_ON[] = {
+ 0xC0, 0x01,
+ 0x00
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+ 0x00
+};
+
+static const unsigned char SEQ_ELVSS_32[] = {
+ 0xB1,
+ 0x04, 0x9F
+};
+
+static const unsigned char SEQ_ELVSS_34[] = {
+ 0xB1,
+ 0x04, 0x9D
+};
+
+static const unsigned char SEQ_ELVSS_38[] = {
+ 0xB1,
+ 0x04, 0x99
+};
+
+static const unsigned char SEQ_ELVSS_47[] = {
+ 0xB1,
+ 0x04, 0x90
+};
+
+static const unsigned char *ELVSS_TABLE[] = {
+ SEQ_ELVSS_32,
+ SEQ_ELVSS_34,
+ SEQ_ELVSS_38,
+ SEQ_ELVSS_47,
+};
+
+#endif /* __S6E63M0_PARAM_H__ */
diff --git a/drivers/video/samsung/s6e8aa0_gamma_q1.h b/drivers/video/samsung/s6e8aa0_gamma_q1.h
index 075f66e4..b0b5f0d 100644
--- a/drivers/video/samsung/s6e8aa0_gamma_q1.h
+++ b/drivers/video/samsung/s6e8aa0_gamma_q1.h
@@ -29,7 +29,6 @@ static const unsigned char SEQ_PANEL_CONDITION_SET[] = {
0x01, 0x81, 0xC1, 0x00, 0xC8, 0xC1, 0xD3, 0x01
};
-
static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
0xF6,
0x00, 0x02, 0x00
@@ -54,6 +53,11 @@ static const unsigned char SEQ_ELVSS_NVM_SETTING[] = {
0xD9, 0x00, 0x00, 0x00
};
+static const unsigned char SEQ_LTPS_DELAY[] = {
+ 0xFE,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x0B, 0x53, 0x3C
+};
static const unsigned char SEQ_ACL_CUTOFF_20[] = {
0xC1,
diff --git a/drivers/video/samsung/s6e8aa0_param.h b/drivers/video/samsung/s6e8aa0_param.h
index 3ac11ad..8db68a6 100644
--- a/drivers/video/samsung/s6e8aa0_param.h
+++ b/drivers/video/samsung/s6e8aa0_param.h
@@ -96,6 +96,12 @@ enum {
GAMMA_80CD,
GAMMA_90CD,
GAMMA_100CD,
+#ifdef CONFIG_AID_DIMMING
+ GAMMA_102CD,
+ GAMMA_104CD,
+ GAMMA_106CD,
+ GAMMA_108CD,
+#endif
GAMMA_110CD,
GAMMA_120CD,
GAMMA_130CD,
diff --git a/drivers/video/samsung/s6e8aa1.c b/drivers/video/samsung/s6e8aa1.c
new file mode 100644
index 0000000..82effe4
--- /dev/null
+++ b/drivers/video/samsung/s6e8aa1.c
@@ -0,0 +1,568 @@
+/* linux/drivers/video/samsung/s6e8aa1.c
+ *
+ * MIPI-DSI based AMS529HA01 AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.h>
+#include <plat/regs-dsim.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "s5p-dsim.h"
+#include "s3cfb.h"
+
+#include "s6e8aa1_param.h"
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_GAMMA_LEVEL 0
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+
+#define LDI_MTP_ADDR 0xCB
+#define LDI_MTP_LENGTH 63
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int cur_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+
+ unsigned char id[LDI_ID_LEN];
+
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+
+ unsigned int irq;
+ unsigned int connected;
+
+ struct dsim_global *dsim;
+};
+
+static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+{
+ int ret = 0;
+
+ if (!lcd->connected)
+ return ret;
+
+ mutex_lock(&lcd->lock);
+
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _s6e8ax0_read(lcd, addr, count, buf);
+ if (!ret) {
+ if (retry_cnt) {
+ printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto read_retry;
+ } else
+ printk(KERN_ERR "[ERROR:LCD] %s : 0x%02x read failed\n", __func__, addr);
+ }
+
+ return ret;
+}
+
+static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e8ax0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6e8ax0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(22);
+
+ s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6e8ax0_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e8ax0_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+
+ s6e8ax0_write(lcd, SEQ_ETC_SOURCE_CONTROL, ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e8ax0_write(lcd, SEQ_ETC_PENTILE_CONTROL, ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL));
+ s6e8ax0_write(lcd, SEQ_ELVSS_CONTROL, ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+ s6e8ax0_write(lcd, SEQ_ETC_NVM_SETTING, ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
+
+ return ret;
+}
+
+static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e8ax0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e8ax0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6e8ax0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
+
+ return ret;
+}
+
+static int s6e8ax0_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ /* dev_info(&lcd->ld->dev, "%s\n", __func__); */
+
+ ret = s6e8ax0_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = s6e8ax0_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ /* update_brightness(lcd, 1); */
+err:
+ return ret;
+}
+
+static int s6e8ax0_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = s6e8ax0_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int s6e8ax0_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = s6e8ax0_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = s6e8ax0_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(&lcd->ld->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return s6e8ax0_power(lcd, power);
+}
+
+static int s6e8ax0_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int s6e8ax0_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n", __func__, brightness); */
+
+ if (brightness < MIN_BRIGHTNESS ||
+ brightness > bd->props.max_brightness) {
+ dev_err(&bd->dev, "lcd brightness should be %d to %d. now %d\n",
+ MIN_BRIGHTNESS, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ /* ret = update_brightness(lcd, 0); */
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int s6e8ax0_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static struct lcd_ops s6e8ax0_lcd_ops = {
+ .set_power = s6e8ax0_set_power,
+ .get_power = s6e8ax0_get_power,
+ .check_fb = s6e8ax0_check_fb,
+};
+
+static const struct backlight_ops s6e8ax0_backlight_ops = {
+ .update_status = s6e8ax0_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ /* if (lcd->ldi_enable)
+ s6e8ax0_set_acl(lcd); */
+ mutex_unlock(&lcd->bl_lock);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "SMD_AMS480GZ01-0\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ /* if (lcd->ldi_enable)
+ update_brightness(lcd, 0); */
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+struct lcd_info *g_lcd;
+
+void s6e8ax0_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void s6e8ax0_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret, i;
+
+ for (i = 0; i < 3; i++)
+ ret = s6e8ax0_read(lcd, LDI_MTP_ADDR+i, LDI_MTP_LENGTH, mtp_data, 0);
+
+ return ret;
+}
+
+static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+static int s6e8ax0_probe(struct device *dev)
+{
+ int ret = 0;
+ struct lcd_info *lcd;
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+
+ lcd = kzalloc(sizeof(struct lcd_info), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ g_lcd = lcd;
+
+ lcd->ld = lcd_device_register("panel", dev, lcd, &s6e8ax0_lcd_ops);
+ if (IS_ERR(lcd->ld)) {
+ pr_err("failed to register lcd device\n");
+ ret = PTR_ERR(lcd->ld);
+ goto out_free_lcd;
+ }
+
+ lcd->bd = backlight_device_register("panel", dev, lcd, &s6e8ax0_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+
+ lcd->acl_enable = 0;
+ lcd->cur_acl = 0;
+
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ s6e8ax0_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ dev_info(&lcd->ld->dev, "lcd panel driver has been probed.\n");
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit s6e8ax0_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6e8ax0_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+ .name = "s6e8aa0",
+ .probe = s6e8ax0_probe,
+ .remove = __devexit_p(s6e8ax0_remove),
+ .shutdown = s6e8ax0_shutdown,
+};
+
+static int s6e8ax0_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+}
+
+static void s6e8ax0_exit(void)
+{
+ return;
+}
+
+module_init(s6e8ax0_init);
+module_exit(s6e8ax0_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s6e8aa1_param.h b/drivers/video/samsung/s6e8aa1_param.h
new file mode 100644
index 0000000..3232b88
--- /dev/null
+++ b/drivers/video/samsung/s6e8aa1_param.h
@@ -0,0 +1,74 @@
+#ifndef __S6E8AA1_PARAM_H__
+#define __S6E8AA1_PARAM_H__
+
+static const unsigned char SEQ_APPLY_MTP_KEY_ENABLE[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET[] = {
+ 0xF8,
+ 0x3D, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x7D, 0x08,
+ 0x27, 0x08, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x7D,
+ 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x66, 0xC0, 0xC1,
+ 0x01, 0x81, 0xC1, 0x00, 0xC1, 0xF6, 0xF6, 0xC1
+};
+
+static const unsigned char SEQ_DISPLAY_CONDITION_SET[] = {
+ 0xF2,
+ 0x80, 0x03, 0x0D
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xFA,
+ 0x01, 0x40, 0x32, 0x49, 0xC5, 0xBB, 0xB6, 0xBC, 0xC5, 0xC0,
+ 0xC9, 0xC9, 0xC5, 0xA0, 0x9F, 0x98, 0xB3, 0xB3, 0xAF, 0x00,
+ 0xD0, 0x00, 0xCF, 0x00, 0xE7
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xF7, 0x03,
+ 0x00
+};
+
+static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
+ 0xF6,
+ 0x00, 0x02, 0x00
+};
+
+static const unsigned char SEQ_ETC_PENTILE_CONTROL[] = {
+ 0xB6,
+ 0x0C, 0x02, 0x03, 0x32, 0xFF, 0x44, 0x44, 0xC0, 0x10
+};
+
+static const unsigned char SEQ_ELVSS_CONTROL[] = {
+ 0xB1,
+ 0x08, 0x95, 0x41, 0xC4
+};
+
+static const unsigned char SEQ_ETC_NVM_SETTING[] = {
+ 0xD9,
+ 0x14, 0x40, 0x0C, 0xCB, 0xCE, 0x6E, 0xC4, 0x07, 0x40
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_STANDBY_ON[] = {
+ 0x01,
+ 0x00, 0x00
+};
+
+#endif /* __S6E8AA1_PARAM_H__ */
diff --git a/drivers/video/samsung/s6evr02_param.h b/drivers/video/samsung/s6evr02_param.h
new file mode 100644
index 0000000..edc7a4e
--- /dev/null
+++ b/drivers/video/samsung/s6evr02_param.h
@@ -0,0 +1,351 @@
+#ifndef __S6EVR02_PARAM_H__
+#define __S6EVR02_PARAM_H__
+
+#define GAMMA_PARAM_SIZE 34
+#define ACL_PARAM_SIZE ARRAY_SIZE(acl_cutoff_33)
+#define ELVSS_PARAM_SIZE ARRAY_SIZE(elvss_control_set_20)
+#define AID_PARAM_SIZE ARRAY_SIZE(SEQ_AOR_CONTROL)
+
+enum {
+ GAMMA_20CD,
+ GAMMA_30CD,
+ GAMMA_40CD,
+ GAMMA_50CD,
+ GAMMA_60CD,
+ GAMMA_70CD,
+ GAMMA_80CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_102CD,
+ GAMMA_104CD,
+ GAMMA_106CD,
+ GAMMA_108CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+ GAMMA_182CD,
+ GAMMA_184CD,
+ GAMMA_186CD,
+ GAMMA_188CD,
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_300CD,
+ GAMMA_MAX
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY_DISABLE[] = {
+ 0xF0,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_3_KEY[] = {
+ 0xFC,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_3_KEY_DISABLE[] = {
+ 0xFC,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_SLEEP_IN[] = {
+ 0x10,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xCA,
+ 0x00, 0xFF, 0x01, 0x1C, 0x01, 0x2C, 0xDA, 0xD7, 0xDA, 0xD5,
+ 0xD2, 0xD6, 0xC1, 0xBC, 0xC2, 0xCA, 0xB9, 0xCB, 0xDC, 0xE5,
+ 0xDD, 0xDA, 0xD8, 0xDD, 0xBA, 0xA8, 0xC1, 0x6B, 0x20, 0xD7,
+ 0x02, 0x03, 0x02
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET_UB[] = {
+ 0xCA,
+ 0x01, 0x27, 0x01, 0x3D, 0x01, 0x47, 0xD1, 0xD7, 0xD1, 0xCA,
+ 0xCE, 0xCC, 0xC4, 0xB3, 0xB1, 0xA1, 0xB9, 0xB8, 0xA2, 0xCE,
+ 0xBA, 0xC8, 0xC9, 0xAD, 0x9B, 0x85, 0x53, 0x6A, 0x7E, 0xE3,
+ 0x09, 0x09, 0x0B
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xF7,
+ 0x03, 0x00
+};
+
+static const unsigned char SEQ_BRIGHTNESS_CONTROL_ON[] = {
+ 0x53,
+ 0x20, 0x00
+};
+
+static const unsigned char SEQ_AOR_CONTROL[] = {
+ 0x51,
+ 0xFF, 0x00
+};
+
+static const unsigned char SEQ_ELVSS_CONDITION_SET_UB[] = {
+ 0xB6,
+ 0x08, 0x07
+};
+
+static const unsigned char SEQ_AVC2_SET[] = {
+ 0xF4,
+ 0x6B, 0x18, 0x95, 0x02, 0x11, 0x8C, 0x77, 0x01, 0x01
+};
+
+static const unsigned char SEQ_ELVSS_CONDITION_SET[] = {
+ 0xB6,
+ 0x08, 0x07
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+
+enum {
+ ELVSS_STATUS_20,
+ ELVSS_STATUS_30,
+ ELVSS_STATUS_40,
+ ELVSS_STATUS_50,
+ ELVSS_STATUS_60,
+ ELVSS_STATUS_70,
+ ELVSS_STATUS_80,
+ ELVSS_STATUS_90,
+ ELVSS_STATUS_100,
+ ELVSS_STATUS_110,
+ ELVSS_STATUS_120,
+ ELVSS_STATUS_130,
+ ELVSS_STATUS_140,
+ ELVSS_STATUS_150,
+ ELVSS_STATUS_160,
+ ELVSS_STATUS_170,
+ ELVSS_STATUS_180,
+ ELVSS_STATUS_190,
+ ELVSS_STATUS_200,
+ ELVSS_STATUS_210,
+ ELVSS_STATUS_220,
+ ELVSS_STATUS_230,
+ ELVSS_STATUS_240,
+ ELVSS_STATUS_250,
+ ELVSS_STATUS_300,
+ ELVSS_STATUS_MAX
+};
+
+static const unsigned char elvss_control_set_20[] = {
+ 0xB6, 0x08,
+ 0x20
+};
+
+static const unsigned char elvss_control_set_30[] = {
+ 0xB6, 0x08,
+ 0x20
+};
+
+static const unsigned char elvss_control_set_40[] = {
+ 0xB6, 0x08,
+ 0x20
+};
+
+static const unsigned char elvss_control_set_50[] = {
+ 0xB6, 0x08,
+ 0x1F
+};
+
+static const unsigned char elvss_control_set_60[] = {
+ 0xB6, 0x08,
+ 0x1F
+};
+
+static const unsigned char elvss_control_set_70[] = {
+ 0xB6, 0x08,
+ 0x1F
+};
+
+static const unsigned char elvss_control_set_80[] = {
+ 0xB6, 0x08,
+ 0x1E
+};
+
+static const unsigned char elvss_control_set_90[] = {
+ 0xB6, 0x08,
+ 0x1E
+};
+
+static const unsigned char elvss_control_set_100[] = {
+ 0xB6, 0x08,
+ 0x1C
+};
+
+static const unsigned char elvss_control_set_110[] = {
+ 0xB6, 0x08,
+ 0x1B
+};
+
+static const unsigned char elvss_control_set_120[] = {
+ 0xB6, 0x08,
+ 0x19
+};
+
+static const unsigned char elvss_control_set_130[] = {
+ 0xB6, 0x08,
+ 0x17
+};
+
+static const unsigned char elvss_control_set_140[] = {
+ 0xB6, 0x08,
+ 0x16
+};
+
+static const unsigned char elvss_control_set_150[] = {
+ 0xB6, 0x08,
+ 0x14
+};
+
+static const unsigned char elvss_control_set_160[] = {
+ 0xB6, 0x08,
+ 0x12
+};
+
+static const unsigned char elvss_control_set_170[] = {
+ 0xB6, 0x08,
+ 0x10
+};
+
+static const unsigned char elvss_control_set_180[] = {
+ 0xB6, 0x08,
+ 0x0F
+};
+
+static const unsigned char elvss_control_set_190[] = {
+ 0xB6, 0x08,
+ 0x15
+};
+
+static const unsigned char elvss_control_set_200[] = {
+ 0xB6, 0x08,
+ 0x14
+};
+
+static const unsigned char elvss_control_set_210[] = {
+ 0xB6, 0x08,
+ 0x13
+};
+
+static const unsigned char elvss_control_set_220[] = {
+ 0xB6, 0x08,
+ 0x12
+};
+
+static const unsigned char elvss_control_set_230[] = {
+ 0xB6, 0x08,
+ 0x11
+};
+
+static const unsigned char elvss_control_set_240[] = {
+ 0xB6, 0x08,
+ 0x10
+};
+
+static const unsigned char elvss_control_set_250[] = {
+ 0xB6, 0x08,
+ 0x10
+};
+
+static const unsigned char elvss_control_set_300[] = {
+ 0xB6, 0x08,
+ 0x0B
+};
+
+
+static const unsigned char *ELVSS_CONTROL_TABLE[ELVSS_STATUS_MAX] = {
+ elvss_control_set_20,
+ elvss_control_set_30,
+ elvss_control_set_40,
+ elvss_control_set_50,
+ elvss_control_set_60,
+ elvss_control_set_70,
+ elvss_control_set_80,
+ elvss_control_set_90,
+ elvss_control_set_100,
+ elvss_control_set_110,
+ elvss_control_set_120,
+ elvss_control_set_130,
+ elvss_control_set_140,
+ elvss_control_set_150,
+ elvss_control_set_160,
+ elvss_control_set_170,
+ elvss_control_set_180,
+ elvss_control_set_190,
+ elvss_control_set_200,
+ elvss_control_set_210,
+ elvss_control_set_220,
+ elvss_control_set_230,
+ elvss_control_set_240,
+ elvss_control_set_250,
+ elvss_control_set_300
+};
+
+
+enum {
+ ACL_STATUS_0P = 0,
+ ACL_STATUS_33P,
+ ACL_STATUS_40P,
+ ACL_STATUS_50P,
+ ACL_STATUS_MAX
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0x55, 0x00,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_33[] = {
+ 0x55, 0x01,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_40[] = {
+ 0x55, 0x02,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_50[] = {
+ 0x55, 0x03,
+ 0x00
+};
+
+static const unsigned char *ACL_CUTOFF_TABLE[ACL_STATUS_MAX] = {
+ SEQ_ACL_OFF,
+ acl_cutoff_33,
+ acl_cutoff_40,
+ acl_cutoff_50,
+};
+#endif /* __S6EVR02_PARAM_H__ */
diff --git a/drivers/video/samsung/s6evr02_volt_tbl.h b/drivers/video/samsung/s6evr02_volt_tbl.h
new file mode 100644
index 0000000..0706964
--- /dev/null
+++ b/drivers/video/samsung/s6evr02_volt_tbl.h
@@ -0,0 +1,665 @@
+#ifndef __REF_VOLT_TABLE_H__
+#define __REF_VOLT_TABLE_H__
+
+u32 volt_table_vt[16] = {
+ 399769600, 394199040, 388628480, 383057920,
+ 377487360, 371851264, 366280704, 360710144,
+ 355139584, 349569024, 335609856, 330956800,
+ 326303744, 321650688, 316997632, 313327616,
+};
+
+u32 volt_table_v255[505] = {
+ 366300517, 365835669, 365370820, 364905972, 364441124, 363976275, 363511427, 363046579,
+ 362581730, 362116882, 361652033, 361187185, 360722337, 360257488, 359792640, 359327792,
+ 358862943, 358398095, 357933247, 357468398, 357003550, 356538701, 356073853, 355609005,
+ 355144156, 354679308, 354214460, 353749611, 353284763, 352819914, 352355066, 351890218,
+ 351425369, 350960521, 350495673, 350030824, 349565976, 349101127, 348636279, 348171431,
+ 347706582, 347241734, 346776886, 346312037, 345847189, 345382340, 344917492, 344452644,
+ 343987795, 343522947, 343058099, 342593250, 342128402, 341663553, 341198705, 340733857,
+ 340269008, 339804160, 339339312, 338874463, 338409615, 337944767, 337479918, 337015070,
+ 336550221, 336085373, 335620525, 335155676, 334690828, 334225980, 333761131, 333296283,
+ 332831434, 332366586, 331901738, 331436889, 330972041, 330507193, 330042344, 329577496,
+ 329112647, 328647799, 328182951, 327718102, 327253254, 326788406, 326323557, 325858709,
+ 325393860, 324929012, 324464164, 323999315, 323534467, 323069619, 322604770, 322139922,
+ 321675073, 321210225, 320745377, 320280528, 319815680, 319350832, 318885983, 318421135,
+ 317956287, 317491438, 317026590, 316561741, 316096893, 315632045, 315167196, 314702348,
+ 314237500, 313772651, 313307803, 312842954, 312378106, 311913258, 311448409, 310983561,
+ 310518713, 310053864, 309589016, 309124167, 308659319, 308194471, 307729622, 307264774,
+ 306799926, 306335077, 305870229, 305405380, 304940532, 304475684, 304010835, 303545987,
+ 303081139, 302616290, 302151442, 301686593, 301221745, 300756897, 300292048, 299827200,
+ 299362352, 298897503, 298432655, 297967807, 297502958, 297038110, 296573261, 296108413,
+ 295643565, 295178716, 294713868, 294249020, 293784171, 293319323, 292854474, 292389626,
+ 291924778, 291459929, 290995081, 290530233, 290065384, 289600536, 289135687, 288670839,
+ 288205991, 287741142, 287276294, 286811446, 286346597, 285881749, 285416900, 284952052,
+ 284487204, 284022355, 283557507, 283092659, 282627810, 282162962, 281698113, 281233265,
+ 280768417, 280303568, 279838720, 279373872, 278909023, 278444175, 277979327, 277514478,
+ 277049630, 276584781, 276119933, 275655085, 275190236, 274725388, 274260540, 273795691,
+ 273330843, 272865994, 272401146, 271936298, 271471449, 271006601, 270541753, 270076904,
+ 269612056, 269147207, 268682359, 268217511, 267752662, 267287814, 266822966, 266358117,
+ 265893269, 265428420, 264963572, 264498724, 264033875, 263569027, 263104179, 262639330,
+ 262174482, 261709633, 261244785, 260779937, 260315088, 259850240, 259385392, 258920543,
+ 258455695, 257990847, 257525998, 257061150, 256596301, 256131453, 255666605, 255201756,
+ 254736908, 254272060, 253807211, 253342363, 252877514, 252412666, 251947818, 251482969,
+ 251018121, 250553273, 250088424, 249623576, 249158727, 248693879, 248229031, 247764182,
+ 247299334, 246834486, 246369637, 245904789, 245439940, 244975092, 244510244, 244045395,
+ 243580547, 243115699, 242650850, 242186002, 241721153, 241256305, 240791457, 240326608,
+ 239861760, 239396912, 238932063, 238467215, 238002367, 237537518, 237072670, 236607821,
+ 236142973, 235678125, 235213276, 234748428, 234283580, 233818731, 233353883, 232889034,
+ 232424186, 231959338, 231494489, 231029641, 230564793, 230099944, 229635096, 229170247,
+ 228705399, 228240551, 227775702, 227310854, 226846006, 226381157, 225916309, 225451460,
+ 224986612, 224521764, 224056915, 223592067, 223127219, 222662370, 222197522, 221732673,
+ 221267825, 220802977, 220338128, 219873280, 219408432, 218943583, 218478735, 218013887,
+ 217549038, 217084190, 216619341, 216154493, 215689645, 215224796, 214759948, 214295100,
+ 213830251, 213365403, 212900554, 212435706, 211970858, 211506009, 211041161, 210576313,
+ 210111464, 209646616, 209181767, 208716919, 208252071, 207787222, 207322374, 206857526,
+ 206392677, 205927829, 205462980, 204998132, 204533284, 204068435, 203603587, 203138739,
+ 202673890, 202209042, 201744193, 201279345, 200814497, 200349648, 199884800, 199419952,
+ 198955103, 198490255, 198025407, 197560558, 197095710, 196630861, 196166013, 195701165,
+ 195236316, 194771468, 194306620, 193841771, 193376923, 192912074, 192447226, 191982378,
+ 191517529, 191052681, 190587833, 190122984, 189658136, 189193287, 188728439, 188263591,
+ 187798742, 187333894, 186869046, 186404197, 185939349, 185474500, 185009652, 184544804,
+ 184079955, 183615107, 183150259, 182685410, 182220562, 181755713, 181290865, 180826017,
+ 180361168, 179896320, 179431472, 178966623, 178501775, 178036927, 177572078, 177107230,
+ 176642381, 176177533, 175712685, 175247836, 174782988, 174318140, 173853291, 173388443,
+ 172923594, 172458746, 171993898, 171529049, 171064201, 170599353, 170134504, 169669656,
+ 169204807, 168739959, 168275111, 167810262, 167345414, 166880566, 166415717, 165950869,
+ 165486020, 165021172, 164556324, 164091475, 163626627, 163161779, 162696930, 162232082,
+ 161767233, 161302385, 160837537, 160372688, 159907840, 159442992, 158978143, 158513295,
+ 158048447, 157583598, 157118750, 156653901, 156189053, 155724205, 155259356, 154794508,
+ 154329660, 153864811, 153399963, 152935114, 152470266, 152005418, 151540569, 151075721,
+ 150610873, 150146024, 149681176, 149216327, 148751479, 148286631, 147821782, 147356934,
+ 146892086, 146427237, 145962389, 145497540, 145032692, 144567844, 144102995, 143638147,
+ 143173299, 142708450, 142243602, 141778753, 141313905, 140849057, 140384208, 139919360,
+ 139454512, 138989663, 138524815, 138059967, 137595118, 137130270, 136665421, 136200573,
+ 135735725, 135270876, 134806028, 134341180, 133876331, 133411483, 132946634, 132481786,
+ 132016938,
+};
+
+u32 volt_table_cv_64_dv_320[256] = {
+ 13104, 13308, 13513, 13718, 13923, 14127, 14332, 14537,
+ 14742, 14946, 15151, 15356, 15561, 15765, 15970, 16175,
+ 16380, 16585, 16789, 16994, 17199, 17404, 17608, 17813,
+ 18018, 18223, 18427, 18632, 18837, 19042, 19246, 19451,
+ 19656, 19861, 20065, 20270, 20475, 20680, 20884, 21089,
+ 21294, 21499, 21703, 21908, 22113, 22318, 22522, 22727,
+ 22932, 23137, 23341, 23546, 23751, 23956, 24160, 24365,
+ 24570, 24775, 24979, 25184, 25389, 25594, 25798, 26003,
+ 26208, 26413, 26617, 26822, 27027, 27232, 27436, 27641,
+ 27846, 28051, 28255, 28460, 28665, 28870, 29074, 29279,
+ 29484, 29689, 29893, 30098, 30303, 30508, 30712, 30917,
+ 31122, 31327, 31531, 31736, 31941, 32146, 32350, 32555,
+ 32760, 32965, 33170, 33374, 33579, 33784, 33989, 34193,
+ 34398, 34603, 34808, 35012, 35217, 35422, 35627, 35831,
+ 36036, 36241, 36446, 36650, 36855, 37060, 37265, 37469,
+ 37674, 37879, 38084, 38288, 38493, 38698, 38903, 39107,
+ 39312, 39517, 39722, 39926, 40131, 40336, 40541, 40745,
+ 40950, 41155, 41360, 41564, 41769, 41974, 42179, 42383,
+ 42588, 42793, 42998, 43202, 43407, 43612, 43817, 44021,
+ 44226, 44431, 44636, 44840, 45045, 45250, 45455, 45659,
+ 45864, 46069, 46274, 46478, 46683, 46888, 47093, 47297,
+ 47502, 47707, 47912, 48116, 48321, 48526, 48731, 48935,
+ 49140, 49345, 49550, 49755, 49959, 50164, 50369, 50574,
+ 50778, 50983, 51188, 51393, 51597, 51802, 52007, 52212,
+ 52416, 52621, 52826, 53031, 53235, 53440, 53645, 53850,
+ 54054, 54259, 54464, 54669, 54873, 55078, 55283, 55488,
+ 55692, 55897, 56102, 56307, 56511, 56716, 56921, 57126,
+ 57330, 57535, 57740, 57945, 58149, 58354, 58559, 58764,
+ 58968, 59173, 59378, 59583, 59787, 59992, 60197, 60402,
+ 60606, 60811, 61016, 61221, 61425, 61630, 61835, 62040,
+ 62244, 62449, 62654, 62859, 63063, 63268, 63473, 63678,
+ 63882, 64087, 64292, 64497, 64701, 64906, 65111, 65316
+};
+
+const u32 gamma_300_gra_table[256] = {
+ 0, 2, 7, 17, 32, 53, 78, 110,
+ 148, 191, 241, 298, 361, 430, 506, 589,
+ 679, 776, 880, 991, 1109, 1235, 1368, 1508,
+ 1657, 1812, 1975, 2147, 2325, 2512, 2706, 2909,
+ 3119, 3338, 3564, 3799, 4042, 4293, 4553, 4820,
+ 5096, 5381, 5674, 5975, 6285, 6604, 6931, 7267,
+ 7611, 7965, 8327, 8697, 9077, 9465, 9863, 10269,
+ 10684, 11109, 11542, 11984, 12436, 12896, 13366, 13845,
+ 14333, 14830, 15337, 15852, 16378, 16912, 17456, 18009,
+ 18572, 19144, 19726, 20317, 20918, 21528, 22148, 22778,
+ 23417, 24066, 24724, 25392, 26070, 26758, 27456, 28163,
+ 28880, 29607, 30344, 31090, 31847, 32613, 33390, 34176,
+ 34973, 35779, 36596, 37422, 38259, 39106, 39963, 40830,
+ 41707, 42594, 43492, 44399, 45317, 46246, 47184, 48133,
+ 49092, 50062, 51042, 52032, 53032, 54043, 55065, 56097,
+ 57139, 58192, 59255, 60329, 61413, 62508, 63613, 64729,
+ 65856, 66993, 68141, 69299, 70469, 71648, 72839, 74040,
+ 75252, 76475, 77708, 78952, 80207, 81473, 82750, 84037,
+ 85336, 86645, 87965, 89296, 90638, 91990, 93354, 94729,
+ 96114, 97511, 98919, 100337, 101767, 103208, 104659, 106122,
+ 107596, 109081, 110577, 112085, 113603, 115132, 116673, 118225,
+ 119788, 121362, 122948, 124544, 126152, 127772, 129402, 131044,
+ 132697, 134361, 136037, 137724, 139422, 141132, 142853, 144586,
+ 146330, 148085, 149852, 151630, 153419, 155220, 157033, 158857,
+ 160692, 162540, 164398, 166268, 168150, 170043, 171948, 173864,
+ 175792, 177731, 179683, 181645, 183620, 185606, 187603, 189613,
+ 191634, 193667, 195711, 197767, 199835, 201915, 204006, 206109,
+ 208224, 210351, 212489, 214640, 216802, 218976, 221161, 223359,
+ 225569, 227790, 230023, 232268, 234525, 236794, 239075, 241368,
+ 243672, 245989, 248318, 250658, 253011, 255375, 257752, 260141,
+ 262541, 264954, 267379, 269815, 272264, 274725, 277198, 279683,
+ 282180, 284689, 287211, 289744, 292290, 294848, 297418, 300000
+};
+
+const u32 gamma_control_set_21[] = {
+ 0, 9, 38, 89, 163, 260, 381, 526,
+ 697, 892, 1113, 1359, 1632, 1930, 2255, 2607,
+ 2985, 3391, 3823, 4283, 4770, 5284, 5826, 6396,
+ 6994, 7620, 8274, 8957, 9668, 10407, 11175, 11971,
+ 12797, 13651, 14534, 15446, 16388, 17358, 18358, 19387,
+ 20446, 21534, 22652, 23799, 24976, 26183, 27420, 28687,
+ 29983, 31310, 32667, 34054, 35471, 36919, 38397, 39905,
+ 41444, 43014, 44614, 46244, 47906, 49598, 51321, 53074,
+ 54859, 56674, 58521, 60399, 62307, 64247, 66218, 68220,
+ 70253, 72318, 74414, 76542, 78700, 80891, 83113, 85366,
+ 87651, 89968, 92316, 94696, 97108, 99551, 102027, 104534,
+ 107073, 109644, 112248, 114883, 117550, 120249, 122980, 125744,
+ 128540, 131367, 134228, 137120, 140045, 143002, 145991, 149013,
+ 152068, 155155, 158274, 161426, 164610, 167827, 171077, 174359,
+ 177674, 181022, 184403, 187816, 191262, 194741, 198253, 201797,
+ 205375, 208985, 212629, 216305, 220015, 223758, 227533, 231342,
+ 235184, 239059, 242967, 246909, 250883, 254891, 258932, 263007,
+ 267115, 271256, 275431, 279639, 283880, 288155, 292464, 296806,
+ 301181, 305590, 310033, 314509, 319019, 323562, 328139, 332750,
+ 337394, 342073, 346785, 351530, 356310, 361123, 365971, 370852,
+ 375767, 380715, 385698, 390715, 395766, 400851, 405969, 411122,
+ 416309, 421530, 426785, 432074, 437397, 442754, 448146, 453572,
+ 459032, 464526, 470054, 475617, 481214, 486845, 492511, 498211,
+ 503945, 509714, 515517, 521355, 527227, 533133, 539074, 545050,
+ 551060, 557104, 563183, 569297, 575445, 581628, 587845, 594097,
+ 600384, 606705, 613061, 619452, 625877, 632338, 638833, 645362,
+ 651927, 658526, 665161, 671830, 678533, 685272, 692046, 698854,
+ 705698, 712576, 719490, 726438, 733421, 740440, 747493, 754581,
+ 761705, 768863, 776057, 783286, 790550, 797848, 805183, 812552,
+ 819956, 827396, 834871, 842381, 849926, 857506, 865122, 872773,
+ 880460, 888181, 895938, 903731, 911558, 919421, 927320, 935254,
+ 943223, 951228, 959268, 967343, 975454, 983601, 991783, 1000000
+};
+
+const u32 gamma_control_set_213[] = {
+ 0, 8, 33, 78, 144, 231, 341, 473,
+ 628, 807, 1010, 1237, 1489, 1766, 2067, 2395,
+ 2747, 3126, 3531, 3962, 4419, 4903, 5413, 5951,
+ 6516, 7107, 7727, 8373, 9048, 9750, 10480, 11238,
+ 12024, 12839, 13682, 14553, 15453, 16381, 17339, 18325,
+ 19341, 20385, 21459, 22561, 23694, 24855, 26047, 27268,
+ 28518, 29798, 31109, 32449, 33819, 35219, 36650, 38111,
+ 39602, 41123, 42675, 44258, 45871, 47515, 49189, 50894,
+ 52630, 54397, 56196, 58025, 59885, 61776, 63699, 65653,
+ 67638, 69655, 71703, 73782, 75894, 78036, 80211, 82417,
+ 84655, 86925, 89227, 91560, 93926, 96324, 98754, 101216,
+ 103710, 106236, 108795, 111386, 114009, 116665, 119353, 122074,
+ 124827, 127613, 130432, 133283, 136167, 139083, 142033, 145015,
+ 148031, 151079, 154160, 157274, 160422, 163602, 166816, 170063,
+ 173343, 176656, 180002, 183382, 186795, 190242, 193722, 197236,
+ 200783, 204363, 207978, 211626, 215307, 219023, 222772, 226554,
+ 230371, 234221, 238106, 242024, 245976, 249962, 253982, 258037,
+ 262125, 266247, 270404, 274594, 278819, 283079, 287372, 291700,
+ 296062, 300458, 304889, 309354, 313854, 318388, 322957, 327560,
+ 332198, 336870, 341577, 346319, 351096, 355907, 360753, 365633,
+ 370549, 375499, 380484, 385505, 390560, 395650, 400775, 405935,
+ 411130, 416360, 421625, 426925, 432260, 437631, 443037, 448478,
+ 453954, 459466, 465012, 470594, 476212, 481865, 487553, 493277,
+ 499036, 504831, 510661, 516526, 522428, 528364, 534337, 540345,
+ 546388, 552468, 558583, 564733, 570920, 577142, 583400, 589694,
+ 596024, 602389, 608791, 615228, 621702, 628211, 634756, 641337,
+ 647955, 654608, 661297, 668023, 674785, 681582, 688416, 695286,
+ 702193, 709135, 716114, 723129, 730180, 737268, 744392, 751552,
+ 758749, 765982, 773251, 780557, 787900, 795279, 802694, 810146,
+ 817634, 825159, 832721, 840319, 847954, 855625, 863333, 871078,
+ 878860, 886678, 894533, 902425, 910353, 918319, 926321, 934360,
+ 942436, 950548, 958698, 966885, 975108, 983369, 991666, 1000000
+};
+
+const u32 gamma_control_set_215[] = {
+ 0, 7, 30, 72, 132, 214, 316, 440,
+ 586, 755, 947, 1162, 1401, 1664, 1951, 2263,
+ 2599, 2961, 3348, 3761, 4200, 4664, 5155, 5671,
+ 6215, 6785, 7382, 8006, 8657, 9335, 10041, 10774,
+ 11535, 12324, 13141, 13986, 14859, 15761, 16691, 17650,
+ 18637, 19653, 20698, 21772, 22876, 24008, 25170, 26361,
+ 27581, 28832, 30111, 31421, 32761, 34130, 35530, 36959,
+ 38419, 39909, 41430, 42981, 44562, 46175, 47817, 49491,
+ 51195, 52931, 54697, 56494, 58323, 60182, 62073, 63995,
+ 65949, 67934, 69950, 71998, 74078, 76190, 78333, 80508,
+ 82715, 84954, 87225, 89528, 91863, 94231, 96630, 99062,
+ 101526, 104023, 106552, 109114, 111708, 114335, 116994, 119687,
+ 122412, 125170, 127961, 130784, 133641, 136531, 139454, 142410,
+ 145399, 148422, 151477, 154566, 157689, 160845, 164034, 167257,
+ 170513, 173803, 177127, 180485, 183876, 187301, 190759, 194252,
+ 197779, 201339, 204934, 208562, 212225, 215922, 219653, 223418,
+ 227217, 231051, 234919, 238821, 242758, 246729, 250735, 254775,
+ 258850, 262959, 267103, 271282, 275496, 279744, 284027, 288345,
+ 292697, 297085, 301507, 305965, 310457, 314985, 319548, 324145,
+ 328778, 333446, 338150, 342888, 347662, 352471, 357316, 362195,
+ 367111, 372062, 377048, 382070, 387127, 392220, 397348, 402513,
+ 407713, 412948, 418220, 423527, 428870, 434248, 439663, 445114,
+ 450600, 456123, 461681, 467276, 472906, 478573, 484276, 490014,
+ 495790, 501601, 507448, 513332, 519252, 525209, 531201, 537231,
+ 543296, 549398, 555537, 561712, 567923, 574171, 580456, 586777,
+ 593135, 599529, 605961, 612429, 618933, 625475, 632053, 638668,
+ 645320, 652009, 658735, 665497, 672297, 679133, 686007, 692918,
+ 699865, 706850, 713872, 720931, 728027, 735161, 742331, 749539,
+ 756784, 764067, 771387, 778744, 786138, 793570, 801039, 808546,
+ 816090, 823672, 831291, 838947, 846642, 854374, 862143, 869950,
+ 877795, 885677, 893597, 901555, 909551, 917584, 925655, 933764,
+ 941911, 950096, 958318, 966579, 974877, 983214, 991588, 1000000
+};
+
+const u32 gamma_control_set_218[] = {
+ 0 , 6, 26, 63, 117, 190, 282, 395,
+ 528, 683, 859, 1057, 1278, 1522, 1788, 2078,
+ 2392, 2730, 3092, 3479, 3891, 4327, 4789, 5277,
+ 5789, 6328, 6893, 7484, 8102, 8746, 9417, 10114,
+ 10839, 11591, 12370, 13177, 14012, 14874, 15765, 16683,
+ 17630, 18605, 19608, 20640, 21701, 22791, 23909, 25057,
+ 26234, 27440, 28675, 29940, 31235, 32559, 33913, 35297,
+ 36711, 38155, 39630, 41134, 42669, 44235, 45831, 47458,
+ 49116, 50804, 52523, 54274, 56055, 57868, 59712, 61587,
+ 63494, 65432, 67402, 69403, 71436, 73501, 75598, 77727,
+ 79888, 82081, 84306, 86564, 88853, 91175, 93530, 95917,
+ 98337, 100789, 103275, 105792, 108343, 110927, 113544, 116193,
+ 118876, 121592, 124342, 127124, 129940, 132790, 135673, 138589,
+ 141539, 144523, 147540, 150592, 153677, 156795, 159948, 163135,
+ 166356, 169611, 172900, 176224, 179582, 182974, 186400, 189861,
+ 193356, 196886, 200451, 204050, 207684, 211352, 215056, 218794,
+ 222567, 226375, 230218, 234096, 238010, 241958, 245941, 249960,
+ 254014, 258104, 262228, 266389, 270584, 274815, 279082, 283384,
+ 287722, 292096, 296505, 300950, 305431, 309948, 314501, 319090,
+ 323714, 328375, 333072, 337805, 342574, 347380, 352221, 357099,
+ 362013, 366964, 371951, 376974, 382034, 387131, 392264, 397434,
+ 402640, 407883, 413163, 418480, 423833, 429223, 434651, 440115,
+ 445616, 451154, 456729, 462341, 467990, 473677, 479401, 485161,
+ 490960, 496795, 502668, 508578, 514526, 520511, 526533, 532593,
+ 538691, 544826, 550999, 557209, 563457, 569743, 576067, 582428,
+ 588828, 595265, 601740, 608253, 614804, 621393, 628020, 634685,
+ 641388, 648129, 654909, 661726, 668582, 675477, 682409, 689380,
+ 696389, 703437, 710523, 717647, 724810, 732011, 739251, 746530,
+ 753847, 761203, 768598, 776031, 783503, 791014, 798563, 806152,
+ 813779, 821445, 829150, 836894, 844677, 852499, 860360, 868261,
+ 876200, 884178, 892196, 900252, 908348, 916484, 924658, 932872,
+ 941125, 949417, 957749, 966121, 974531, 982982, 991471, 1000000
+};
+
+const u32 gamma_control_set_22[] = {
+ 0, 6, 24, 57, 108, 176, 262, 368,
+ 493, 639, 805, 993, 1202, 1434, 1687, 1964,
+ 2263, 2586, 2933, 3303, 3698, 4117, 4560, 5029,
+ 5522, 6041, 6585, 7156, 7752, 8374, 9022, 9697,
+ 10398, 11127, 11882, 12664, 13474, 14311, 15176, 16068,
+ 16989, 17937, 18913, 19918, 20952, 22013, 23104, 24223,
+ 25372, 26549, 27756, 28992, 30257, 31552, 32876, 34231,
+ 35615, 37029, 38473, 39948, 41452, 42988, 44553, 46149,
+ 47776, 49434, 51123, 52842, 54593, 56375, 58188, 60032,
+ 61908, 63815, 65754, 67725, 69728, 71762, 73828, 75927,
+ 78057, 80220, 82415, 84642, 86902, 89194, 91519, 93876,
+ 96267, 98690, 101146, 103635, 106157, 108712, 111300, 113921,
+ 116576, 119265, 121986, 124741, 127530, 130353, 133209, 136099,
+ 139023, 141981, 144973, 147999, 151059, 154153, 157281, 160444,
+ 163641, 166873, 170139, 173440, 176775, 180145, 183549, 186989,
+ 190463, 193973, 197517, 201096, 204711, 208360, 212045, 215765,
+ 219520, 223311, 227137, 230999, 234896, 238828, 242797, 246801,
+ 250841, 254916, 259028, 263175, 267359, 271578, 275833, 280125,
+ 284453, 288816, 293217, 297653, 302126, 306635, 311181, 315763,
+ 320382, 325037, 329730, 334458, 339224, 344026, 348865, 353741,
+ 358654, 363604, 368591, 373616, 378677, 383775, 388911, 394084,
+ 399294, 404541, 409826, 415149, 420508, 425906, 431341, 436813,
+ 442323, 447871, 453457, 459080, 464742, 470441, 476178, 481953,
+ 487766, 493617, 499506, 505433, 511398, 517402, 523444, 529524,
+ 535642, 541799, 547994, 554228, 560500, 566810, 573159, 579547,
+ 585973, 592439, 598942, 605485, 612066, 618686, 625345, 632043,
+ 638780, 645556, 652371, 659224, 666117, 673050, 680021, 687031,
+ 694081, 701170, 708298, 715466, 722673, 729919, 737205, 744531,
+ 751896, 759300, 766744, 774228, 781751, 789314, 796917, 804560,
+ 812242, 819964, 827726, 835528, 843370, 851252, 859174, 867136,
+ 875138, 883180, 891263, 899385, 907548, 915751, 923994, 932277,
+ 940601, 948965, 957370, 965815, 974301, 982827, 991393, 1000000
+};
+
+const u32 gamma_control_set_221[] = {
+ 0, 5, 23, 55, 103, 169, 252, 355,
+ 476, 618, 780, 962, 1166, 1392, 1639, 1909,
+ 2202, 2517, 2856, 3219, 3605, 4015, 4450, 4909,
+ 5393, 5902, 6437, 6997, 7582, 8194, 8831, 9495,
+ 10185, 10901, 11645, 12415, 13213, 14037, 14890, 15769,
+ 16677, 17612, 18575, 19567, 20587, 21635, 22712, 23817,
+ 24952, 26115, 27307, 28529, 29780, 31060, 32370, 33710,
+ 35079, 36478, 37908, 39367, 40857, 42377, 43928, 45509,
+ 47120, 48763, 50436, 52141, 53876, 55642, 57440, 59269,
+ 61130, 63022, 64946, 66901, 68889, 70908, 72959, 75042,
+ 77157, 79305, 81485, 83697, 85942, 88219, 90530, 92872,
+ 95248, 97656, 100098, 102572, 105080, 107621, 110195, 112802,
+ 115443, 118117, 120825, 123567, 126342, 129151, 131994, 134871,
+ 137782, 140727, 143706, 146719, 149766, 152848, 155964, 159115,
+ 162300, 165520, 168775, 172064, 175388, 178747, 182141, 185569,
+ 189033, 192532, 196066, 199635, 203240, 206880, 210555, 214266,
+ 218012, 221794, 225612, 229465, 233354, 237279, 241240, 245236,
+ 249269, 253338, 257442, 261583, 265760, 269974, 274223, 278509,
+ 282832, 287191, 291586, 296018, 300487, 304992, 309534, 314113,
+ 318729, 323381, 328071, 332797, 337561, 342362, 347199, 352074,
+ 356987, 361936, 366923, 371947, 377009, 382108, 387245, 392419,
+ 397631, 402881, 408168, 413493, 418856, 424257, 429695, 435172,
+ 440686, 446239, 451830, 457459, 463126, 468831, 474575, 480356,
+ 486177, 492035, 497932, 503868, 509842, 515854, 521906, 527996,
+ 534124, 540292, 546498, 552743, 559027, 565349, 571711, 578112,
+ 584552, 591030, 597548, 604106, 610702, 617337, 624012, 630726,
+ 637480, 644273, 651105, 657977, 664888, 671839, 678830, 685860,
+ 692930, 700039, 707189, 714378, 721607, 728876, 736184, 743533,
+ 750922, 758350, 765819, 773328, 780877, 788466, 796095, 803765,
+ 811475, 819225, 827015, 834846, 842717, 850629, 858582, 866574,
+ 874608, 882682, 890796, 898952, 907148, 915384, 923662, 931980,
+ 940339, 948740, 957181, 965662, 974185, 982749, 991354, 1000000
+};
+
+const u32 gamma_control_set_222[] = {
+ 0, 5, 22, 53, 99, 162, 243, 342,
+ 460, 597, 755, 932, 1131, 1351, 1592, 1856,
+ 2142, 2450, 2781, 3136, 3514, 3916, 4342, 4792,
+ 5267, 5767, 6292, 6841, 7417, 8017, 8644, 9297,
+ 9976, 10681, 11413, 12171, 12957, 13769, 14609, 15476,
+ 16371, 17293, 18243, 19222, 20228, 21263, 22326, 23418,
+ 24538, 25688, 26866, 28073, 29310, 30576, 31871, 33197,
+ 34551, 35936, 37351, 38795, 40270, 41775, 43311, 44877,
+ 46473, 48101, 49759, 51448, 53169, 54920, 56703, 58516,
+ 60362, 62239, 64147, 66088, 68060, 70064, 72100, 74168,
+ 76268, 78401, 80566, 82763, 84993, 87256, 89551, 91879,
+ 94240, 96634, 99061, 101521, 104014, 106541, 109100, 111694,
+ 114321, 116981, 119675, 122403, 125165, 127961, 130790, 133654,
+ 136551, 139483, 142450, 145450, 148485, 151555, 154659, 157797,
+ 160970, 164178, 167421, 170699, 174012, 177360, 180742, 184160,
+ 187614, 191102, 194626, 198185, 201780, 205410, 209076, 212778,
+ 216515, 220288, 224097, 227942, 231823, 235740, 239692, 243682,
+ 247707, 251768, 255866, 260001, 264171, 268379, 272623, 276903,
+ 281220, 285574, 289965, 294392, 298856, 303358, 307896, 312471,
+ 317084, 321734, 326421, 331145, 335906, 340705, 345541, 350415,
+ 355327, 360276, 365262, 370286, 375349, 380448, 385586, 390762,
+ 395975, 401227, 406516, 411844, 417210, 422614, 428056, 433537,
+ 439055, 444613, 450208, 455843, 461515, 467227, 472977, 478765,
+ 484593, 490459, 496364, 502307, 508290, 514312, 520372, 526472,
+ 532611, 538789, 545006, 551262, 557558, 563892, 570267, 576680,
+ 583133, 589626, 596158, 602729, 609341, 615992, 622682, 629412,
+ 636183, 642992, 649842, 656732, 663662, 670631, 677641, 684691,
+ 691781, 698911, 706081, 713291, 720542, 727833, 735165, 742537,
+ 749949, 757402, 764895, 772429, 780003, 787618, 795274, 802971,
+ 810708, 818486, 826305, 834165, 842065, 850007, 857989, 866013,
+ 874078, 882183, 890330, 898518, 906748, 915018, 923330, 931683,
+ 940078, 948514, 956991, 965510, 974070, 982672, 991315, 1000000
+};
+
+const u32 gamma_control_set_223[] = {
+ 0, 5, 21, 50, 95, 156, 234, 330,
+ 444, 578, 731, 904, 1097, 1311, 1547, 1804,
+ 2083, 2385, 2709, 3056, 3426, 3820, 4237, 4679,
+ 5144, 5635, 6150, 6689, 7255, 7845, 8461, 9103,
+ 9771, 10465, 11185, 11932, 12705, 13506, 14333, 15188,
+ 16070, 16980, 17917, 18883, 19876, 20897, 21947, 23025,
+ 24132, 25267, 26432, 27625, 28848, 30099, 31381, 32691,
+ 34031, 35402, 36802, 38231, 39692, 41182, 42703, 44254,
+ 45835, 47448, 49091, 50765, 52470, 54207, 55974, 57773,
+ 59603, 61465, 63359, 65284, 67241, 69230, 71251, 73304,
+ 75389, 77507, 79657, 81839, 84054, 86302, 88583, 90896,
+ 93243, 95622, 98034, 100480, 102959, 105471, 108017, 110596,
+ 113209, 115856, 118536, 121251, 123999, 126781, 129597, 132448,
+ 135332, 138251, 141205, 144193, 147215, 150272, 153364, 156490,
+ 159651, 162848, 166079, 169345, 172647, 175983, 179355, 182762,
+ 186205, 189683, 193196, 196746, 200330, 203951, 207607, 211300,
+ 215028, 218792, 222592, 226429, 230301, 234210, 238155, 242137,
+ 246155, 250209, 254300, 258428, 262592, 266793, 271031, 275306,
+ 279618, 283966, 288352, 292775, 297235, 301732, 306267, 310838,
+ 315448, 320094, 324779, 329500, 334260, 339057, 343891, 348764,
+ 353674, 358623, 363609, 368633, 373695, 378796, 383934, 389111,
+ 394326, 399580, 404871, 410202, 415570, 420977, 426423, 431908,
+ 437431, 442992, 448593, 454232, 459911, 465628, 471384, 477180,
+ 483014, 488887, 494800, 500752, 506743, 512774, 518843, 524953,
+ 531102, 537290, 543518, 549785, 556092, 562439, 568826, 575252,
+ 581718, 588224, 594770, 601356, 607982, 614649, 621355, 628101,
+ 634888, 641715, 648582, 655489, 662437, 669425, 676454, 683524,
+ 690633, 697784, 704975, 712207, 719479, 726793, 734147, 741542,
+ 748977, 756454, 763972, 771531, 779131, 786772, 794454, 802177,
+ 809942, 817748, 825595, 833483, 841413, 849385, 857398, 865452,
+ 873548, 881685, 889865, 898085, 906348, 914652, 922998, 931386,
+ 939816, 948288, 956801, 965357, 973955, 982595, 991276, 1000000
+};
+
+const u32 gamma_control_set_224[] = {
+ 0, 5, 20, 48, 91, 150, 226, 318,
+ 429, 559, 707, 876, 1064, 1273, 1503, 1754,
+ 2026, 2321, 2638, 2977, 3340, 3725, 4135, 4567,
+ 5024, 5505, 6011, 6541, 7096, 7676, 8282, 8913,
+ 9570, 10253, 10962, 11697, 12459, 13248, 14063, 14906,
+ 15775, 16672, 17597, 18549, 19530, 20538, 21574, 22639,
+ 23732, 24854, 26005, 27184, 28393, 29630, 30897, 32194,
+ 33520, 34875, 36261, 37676, 39121, 40597, 42103, 43639,
+ 45206, 46804, 48432, 50091, 51781, 53503, 55255, 57039,
+ 58854, 60701, 62580, 64490, 66432, 68406, 70412, 72450,
+ 74520, 76623, 78758, 80926, 83126, 85359, 87625, 89924,
+ 92256, 94621, 97019, 99450, 101915, 104413, 106944, 109510,
+ 112109, 114742, 117408, 120109, 122843, 125612, 128415, 131252,
+ 134124, 137030, 139971, 142946, 145956, 149000, 152080, 155194,
+ 158343, 161528, 164747, 168002, 171292, 174617, 177978, 181375,
+ 184806, 188274, 191777, 195316, 198891, 202502, 206149, 209832,
+ 213551, 217306, 221098, 224925, 228790, 232690, 236628, 240602,
+ 244612, 248659, 252744, 256864, 261022, 265217, 269449, 273718,
+ 278024, 282368, 286748, 291167, 295622, 300115, 304646, 309214,
+ 313820, 318463, 323145, 327864, 332621, 337416, 342249, 347120,
+ 352030, 356977, 361963, 366987, 372050, 377150, 382290, 387468,
+ 392684, 397939, 403233, 408566, 413937, 419347, 424796, 430285,
+ 435812, 441378, 446983, 452628, 458312, 464035, 469797, 475599,
+ 481440, 487321, 493241, 499201, 505201, 511240, 517319, 523438,
+ 529597, 535795, 542034, 548312, 554631, 560989, 567388, 573827,
+ 580307, 586826, 593386, 599987, 606627, 613309, 620030, 626793,
+ 633596, 640439, 647324, 654249, 661215, 668222, 675270, 682358,
+ 689488, 696659, 703871, 711124, 718418, 725753, 733130, 740548,
+ 748007, 755508, 763050, 770634, 778259, 785926, 793635, 801385,
+ 809177, 817010, 824886, 832803, 840762, 848763, 856806, 864891,
+ 873018, 881188, 889399, 897653, 905948, 914286, 922667, 931089,
+ 939555, 948062, 956612, 965205, 973840, 982517, 991238, 1000000
+};
+
+const u32 gamma_control_set_225[] = {
+ 0, 4, 19, 46, 88, 144, 217, 307,
+ 415, 540, 685, 849, 1032, 1235, 1460, 1705,
+ 1971, 2259, 2569, 2901, 3256, 3634, 4034, 4459,
+ 4907, 5379, 5875, 6396, 6941, 7511, 8107, 8727,
+ 9373, 10045, 10743, 11467, 12218, 12994, 13798, 14628,
+ 15486, 16370, 17283, 18222, 19190, 20185, 21208, 22259,
+ 23339, 24448, 25584, 26750, 27945, 29168, 30421, 31704,
+ 33015, 34357, 35728, 37129, 38559, 40020, 41512, 43033,
+ 44586, 46168, 47782, 49426, 51102, 52808, 54546, 56314,
+ 58115, 59947, 61810, 63705, 65632, 67591, 69583, 71606,
+ 73661, 75749, 77870, 80023, 82208, 84427, 86678, 88962,
+ 91279, 93630, 96014, 98431, 100881, 103365, 105883, 108434,
+ 111019, 113638, 116291, 118978, 121699, 124454, 127244, 130068,
+ 132926, 135819, 138747, 141710, 144707, 147739, 150806, 153909,
+ 157046, 160218, 163426, 166669, 169948, 173262, 176612, 179997,
+ 183419, 186876, 190369, 193898, 197462, 201063, 204701, 208374,
+ 212084, 215830, 219613, 223432, 227288, 231181, 235110, 239076,
+ 243079, 247119, 251196, 255311, 259462, 263650, 267876, 272139,
+ 276440, 280778, 285154, 289567, 294018, 298507, 303034, 307598,
+ 312200, 316841, 321519, 326236, 330991, 335784, 340615, 345485,
+ 350393, 355339, 360325, 365348, 370411, 375512, 380652, 385831,
+ 391049, 396306, 401601, 406936, 412310, 417723, 423176, 428668,
+ 434199, 439769, 445379, 451029, 456718, 462447, 468215, 474024,
+ 479872, 485760, 491687, 497655, 503663, 509711, 515799, 521927,
+ 528096, 534305, 540554, 546843, 553173, 559544, 565955, 572406,
+ 578899, 585432, 592005, 598620, 605275, 611971, 618709, 625487,
+ 632306, 639167, 646068, 653011, 659995, 667020, 674087, 681195,
+ 688345, 695536, 702768, 710042, 717358, 724715, 732115, 739556,
+ 747038, 754563, 762130, 769738, 777389, 785081, 792816, 800593,
+ 808412, 816273, 824177, 832123, 840111, 848142, 856215, 864331,
+ 872489, 880690, 888934, 897220, 905549, 913921, 922335, 930793,
+ 939293, 947836, 956423, 965052, 973724, 982440, 991199, 1000000
+};
+
+const u32 *GAMMA_CONTROL_TABLE[G_MAX] = {
+ gamma_control_set_21,
+ gamma_control_set_213,
+ gamma_control_set_215,
+ gamma_control_set_218,
+ gamma_control_set_22,
+ gamma_control_set_221,
+ gamma_control_set_222,
+ gamma_control_set_223,
+ gamma_control_set_224,
+ gamma_control_set_225
+};
+
+const struct str_flookup_table flookup_table[302] = {
+ { 0, 0}, { 1, 20},
+ { 20, 7}, { 27, 5},
+ { 32, 4}, { 36, 4},
+ { 40, 4}, { 44, 3},
+ { 47, 3}, { 50, 2},
+ { 52, 3}, { 55, 2},
+ { 57, 3}, { 60, 2},
+ { 62, 2}, { 64, 2},
+ { 66, 2}, { 68, 2},
+ { 70, 1}, { 71, 2},
+ { 73, 2}, { 75, 2},
+ { 77, 1}, { 78, 2},
+ { 80, 1}, { 81, 2},
+ { 83, 1}, { 84, 2},
+ { 86, 1}, { 87, 2},
+ { 89, 1}, { 90, 1},
+ { 91, 2}, { 93, 1},
+ { 94, 1}, { 95, 2},
+ { 97, 1}, { 98, 1},
+ { 99, 1}, {100, 1},
+ {101, 2}, {103, 1},
+ {104, 1}, {105, 1},
+ {106, 1}, {107, 1},
+ {108, 1}, {109, 1},
+ {110, 1}, {111, 1},
+ {112, 1}, {113, 1},
+ {114, 1}, {115, 1},
+ {116, 1}, {117, 1},
+ {118, 1}, {119, 1},
+ {120, 1}, {121, 1},
+ {122, 1}, {123, 1},
+ {124, 1}, {125, 1},
+ {126, 1}, {127, 1},
+ {128, 1}, {129, 1},
+ { 0, 0}, {130, 1},
+ {131, 1}, {132, 1},
+ {133, 1}, {134, 1},
+ { 0, 0}, {135, 1},
+ {136, 1}, {137, 1},
+ {138, 1}, {139, 1},
+ { 0, 0}, {140, 1},
+ {141, 1}, {142, 1},
+ { 0, 0}, {143, 1},
+ {144, 1}, {145, 1},
+ {146, 1}, { 0, 0},
+ {147, 1}, {148, 1},
+ {149, 1}, { 0, 0},
+ {150, 1}, {151, 1},
+ { 0, 0}, {152, 1},
+ {153, 1}, {154, 1},
+ { 0, 0}, {155, 1},
+ {156, 1}, { 0, 0},
+ {157, 1}, {158, 1},
+ { 0, 0}, {159, 1},
+ {160, 1}, { 0, 0},
+ {161, 1}, {162, 1},
+ { 0, 0}, {163, 1},
+ {164, 1}, { 0, 0},
+ {165, 1}, {166, 1},
+ { 0, 0}, {167, 1},
+ {168, 1}, { 0, 0},
+ {169, 1}, {170, 1},
+ { 0, 0}, {171, 1},
+ { 0, 0}, {172, 1},
+ {173, 1}, { 0, 0},
+ {174, 1}, { 0, 0},
+ {175, 1}, {176, 1},
+ { 0, 0}, {177, 1},
+ { 0, 0}, {178, 1},
+ {179, 1}, { 0, 0},
+ {180, 1}, { 0, 0},
+ {181, 1}, {182, 1},
+ { 0, 0}, {183, 1},
+ { 0, 0}, {184, 1},
+ { 0, 0}, {185, 1},
+ {186, 1}, { 0, 0},
+ {187, 1}, { 0, 0},
+ {188, 1}, { 0, 0},
+ {189, 1}, { 0, 0},
+ {190, 1}, {191, 1},
+ { 0, 0}, {192, 1},
+ { 0, 0}, {193, 1},
+ { 0, 0}, {194, 1},
+ { 0, 0}, {195, 1},
+ { 0, 0}, {196, 1},
+ { 0, 0}, {197, 1},
+ {198, 1}, { 0, 0},
+ {199, 1}, { 0, 0},
+ {200, 1}, { 0, 0},
+ {201, 1}, { 0, 0},
+ {202, 1}, { 0, 0},
+ {203, 1}, { 0, 0},
+ {204, 1}, { 0, 0},
+ {205, 1}, { 0, 0},
+ {206, 1}, { 0, 0},
+ {207, 1}, { 0, 0},
+ {208, 1}, { 0, 0},
+ {209, 1}, { 0, 0},
+ {210, 1}, { 0, 0},
+ {211, 1}, { 0, 0},
+ {212, 1}, { 0, 0},
+ {213, 1}, { 0, 0},
+ { 0, 0}, {214, 1},
+ { 0, 0}, {215, 1},
+ { 0, 0}, {216, 1},
+ { 0, 0}, {217, 1},
+ { 0, 0}, {218, 1},
+ { 0, 0}, {219, 1},
+ { 0, 0}, {220, 1},
+ { 0, 0}, {221, 1},
+ { 0, 0}, { 0, 0},
+ {222, 1}, { 0, 0},
+ {223, 1}, { 0, 0},
+ {224, 1}, { 0, 0},
+ {225, 1}, { 0, 0},
+ { 0, 0}, {226, 1},
+ { 0, 0}, {227, 1},
+ { 0, 0}, {228, 1},
+ { 0, 0}, {229, 1},
+ { 0, 0}, { 0, 0},
+ {230, 1}, { 0, 0},
+ {231, 1}, { 0, 0},
+ {232, 1}, { 0, 0},
+ {233, 1}, { 0, 0},
+ { 0, 0}, {234, 1},
+ { 0, 0}, {235, 1},
+ { 0, 0}, { 0, 0},
+ {236, 1}, { 0, 0},
+ {237, 1}, { 0, 0},
+ {238, 1}, { 0, 0},
+ { 0, 0}, {239, 1},
+ { 0, 0}, {240, 1},
+ { 0, 0}, {241, 1},
+ { 0, 0}, { 0, 0},
+ {242, 1}, { 0, 0},
+ {243, 1}, { 0, 0},
+ { 0, 0}, {244, 1},
+ { 0, 0}, {245, 1},
+ { 0, 0}, { 0, 0},
+ {246, 1}, { 0, 0},
+ {247, 1}, { 0, 0},
+ { 0, 0}, {248, 1},
+ { 0, 0}, {249, 1},
+ { 0, 0}, { 0, 0},
+ {250, 1}, { 0, 0},
+ {251, 1}, { 0, 0},
+ { 0, 0}, {252, 1},
+ { 0, 0}, {253, 1},
+ { 0, 0}, { 0, 0},
+ {254, 1}, { 0, 0},
+ { 0, 0}, {255, 1},
+};
+
+#endif
diff --git a/drivers/video/samsung/smart_dimming_ea8061.c b/drivers/video/samsung/smart_dimming_ea8061.c
new file mode 100644
index 0000000..7a9175c
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_ea8061.c
@@ -0,0 +1,918 @@
+/* linux/drivers/video/samsung/smartdimming.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+#include "smart_dimming_ea8061.h"
+#include "ea8061_volt_tbl.h"
+
+#define VALUE_DIM_1000 1000
+#define VT_255_div_1000 605000
+#define VREG_OUT_1000 6100
+#define VREG_OUT_1000_1024 6246400
+#define VT_255_calc_param (VT_255_div_1000 / VREG_OUT_1000)
+
+static const u8 range_table_count[IV_TABLE_MAX] = {
+ 3, 8, 12, 12, 16, 36, 64, 52, 52, 1
+};
+
+static const u32 table_radio[IV_TABLE_MAX] = {
+ 16384, 4138, 2763, 2763, 2080, 918, 516, 636, 636, 0
+};
+
+static const u32 dv_value[IV_MAX] = {
+ 0, 3, 11, 23, 35, 51, 87, 151, 203, 255
+};
+
+static const char color_name[3] = {'R', 'G', 'B'};
+
+static const u8 *offset_table[IV_TABLE_MAX] = {
+ NULL, /*V3*/
+ NULL, /*V11*/
+ NULL, /*V23*/
+ NULL, /*V23*/
+ NULL, /*V35*/
+ NULL, /*V51*/
+ NULL, /*V87*/
+ NULL, /*V151*/
+ NULL, /*V203*/
+ NULL /*V255*/
+};
+
+static const unsigned char gamma_300cd_00[] = {
+ 0x00, 0xE8, 0x00, 0xF7, 0x01, 0x03,
+ 0xDB, 0xDB, 0xDC, 0xD9, 0xD8, 0xDA, 0xCB, 0xC8, 0xCB,
+ 0xD4, 0xD3, 0xD7, 0xE6, 0xE6, 0xEA, 0xE2, 0xE4, 0xE5,
+ 0xCE, 0xC3, 0xCF, 0xB9, 0x9D, 0xDE, 0x01, 0x01, 0x00
+};
+
+static const unsigned char gamma_300cd_02[] = {
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x03, 0x02
+};
+
+static const unsigned char *gamma_300cd_list[GAMMA_300CD_MAX] = {
+ gamma_300cd_00,
+ gamma_300cd_00,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+};
+
+static const unsigned char gamma_id_list[GAMMA_300CD_MAX] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x25, 0x26,
+};
+
+static s16 s9_to_s16(s16 v)
+{
+ return (s16)(v << 7) >> 7;
+}
+
+static u32 calc_vt_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_vt[gamma] >> 16;
+
+ return ret;
+}
+
+static u32 calc_v3_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320 */
+ int ret = 0;
+ u32 v0 = VREG_OUT_1000, v11;
+ u32 ratio = 0;
+
+ /*vt = adjust_volt[rgb_index][AD_IVT];*/
+ v11 = adjust_volt[rgb_index][AD_IV11];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (v0 << 16) - ((v0-v11)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v11_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320*/
+ int ret = 0;
+ u32 vt, v23;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v23 = adjust_volt[rgb_index][AD_IV23];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v23)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v23_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v35;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v35 = adjust_volt[rgb_index][AD_IV35];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v35)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v35_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v51;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v51 = adjust_volt[rgb_index][AD_IV51];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v51)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v51_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v87;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v87 = adjust_volt[rgb_index][AD_IV87];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v87)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+
+}
+
+static u32 calc_v87_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v151;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v151 = adjust_volt[rgb_index][AD_IV151];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v151)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v151_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v203;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v203 = adjust_volt[rgb_index][AD_IV203];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v203)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v203_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v255;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v255 = adjust_volt[rgb_index][AD_IV255];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v255)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v255_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_v255[gamma] >> 16;
+
+ return ret;
+}
+
+u8 calc_voltage_table_ea8061(struct str_smart_dim *smart, const u8 *mtp)
+{
+ int c, i, j;
+#if defined(MTP_REVERSE)
+ int offset1 = 0;
+#endif
+ int offset = 0;
+ s16 t1, t2;
+ s16 adjust_mtp[CI_MAX][IV_MAX];
+ u8 range_index;
+ u8 table_index = 0;
+ u32 v1, v2;
+ u32 ratio;
+ u32(*calc_volt[IV_MAX])(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_volt,
+ calc_v3_volt,
+ calc_v11_volt,
+ calc_v23_volt,
+ calc_v35_volt,
+ calc_v51_volt,
+ calc_v87_volt,
+ calc_v151_volt,
+ calc_v203_volt,
+ calc_v255_volt,
+ };
+ u8 calc_seq[9] = { IV_VT, IV_203, IV_151, IV_87, IV_51, IV_35, IV_23, IV_11, IV_3};
+ u8 ad_seq[9] = {AD_IVT, AD_IV203, AD_IV151, AD_IV87, AD_IV51, AD_IV35, AD_IV23, AD_IV11, AD_IV3};
+
+ memset(adjust_mtp, 0, sizeof(adjust_mtp));
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ t2 = (smart->default_gamma[offset]<<8|smart->default_gamma[offset+1]) + t1;
+ smart->mtp[c][IV_255] = t1;
+ adjust_mtp[c][IV_255] = t2;
+ smart->adjust_volt[c][AD_IV255] = calc_volt[IV_255](t2, c, smart->adjust_volt);
+ /* for V0 All RGB Voltage Value is Reference Voltage */
+ smart->adjust_volt[c][AD_IVT] = VREG_OUT_1000;
+ }
+
+ for (i = IV_VT; i < IV_255; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i < IV_3) {
+ t1 = 0;
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ } else {
+ t1 = (s8)mtp[CI_MAX*(10-calc_seq[i])+c];
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ }
+ }
+ }
+
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i == 0)
+ smart->ve[table_index].v[c] = VREG_OUT_1000;
+ else
+ smart->ve[table_index].v[c] = smart->adjust_volt[c][i];
+ }
+ range_index = 0;
+
+ for (j = table_index+1; j < table_index+range_table_count[i]; j++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (smart->t_info[i].offset_table != NULL)
+ ratio = smart->t_info[i].offset_table[range_index] * smart->t_info[i].rv;
+ else
+ ratio = (range_table_count[i]-(range_index+1)) * smart->t_info[i].rv;
+
+ v1 = smart->adjust_volt[c][i+1] << 15;
+ v2 = (smart->adjust_volt[c][i] - smart->adjust_volt[c][i+1])*ratio;
+ smart->ve[j].v[c] = ((v1+v2) >> 15);
+ }
+ range_index++;
+ }
+ table_index = j;
+ }
+
+ for (i = 1; i < 3; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ smart->ve[i].v[c] = smart->ve[3].v[c]+((smart->ve[0].v[c]-smart->ve[3].v[c])*(3-i)/3);
+ }
+
+#if 0
+ printk(KERN_INFO "++++++++++++++++++++++++++++++ MTP VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : 0x%08x(%04d)", color_name[c], smart->mtp[c][i], smart->mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : 0x%08x(%04d)", color_name[c],
+ adjust_mtp[c][i], adjust_mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : %04dV", color_name[c], smart->adjust_volt[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++++++++++ VOLTAGE TABLE ++++++++++++++++++++++++++++++++++++++\n");
+ for (i = 0; i < 256; i++) {
+ printk("Gray Level : %03d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : %04dV", color_name[c], smart->ve[i].v[c]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+
+int init_table_info_ea8061(struct str_smart_dim *smart)
+{
+ int i;
+ int offset = 0;
+
+ for (i = 0; i < IV_TABLE_MAX; i++) {
+ smart->t_info[i].count = (u8)range_table_count[i];
+ smart->t_info[i].offset_table = offset_table[i];
+ smart->t_info[i].rv = table_radio[i];
+ offset += range_table_count[i];
+ }
+
+ smart->flooktbl = flookup_table;
+ smart->g300_gra_tbl = gamma_300_gra_table;
+ smart->gamma_table[G_21] = GAMMA_CONTROL_TABLE[G_21];
+ smart->gamma_table[G_213] = GAMMA_CONTROL_TABLE[G_213];
+ smart->gamma_table[G_215] = GAMMA_CONTROL_TABLE[G_215];
+ smart->gamma_table[G_218] = GAMMA_CONTROL_TABLE[G_218];
+ smart->gamma_table[G_22] = GAMMA_CONTROL_TABLE[G_22];
+ smart->gamma_table[G_221] = GAMMA_CONTROL_TABLE[G_221];
+ smart->gamma_table[G_222] = GAMMA_CONTROL_TABLE[G_222];
+ smart->gamma_table[G_223] = GAMMA_CONTROL_TABLE[G_223];
+ smart->gamma_table[G_224] = GAMMA_CONTROL_TABLE[G_224];
+ smart->gamma_table[G_225] = GAMMA_CONTROL_TABLE[G_225];
+
+ for (i = 0; i < GAMMA_300CD_MAX; i++) {
+ if (smart->panelid[2] == gamma_id_list[i])
+ break;
+ }
+
+ if (i >= GAMMA_300CD_MAX) {
+ printk(KERN_ERR "[SMART DIMMING-WARNING] %s Can't found default gamma table\n", __func__);
+ smart->default_gamma = gamma_300cd_list[GAMMA_300CD_MAX-1];
+ } else
+ smart->default_gamma = gamma_300cd_list[i];
+
+ return 0;
+}
+
+static u32 lookup_vtbl_idx(struct str_smart_dim *smart, u32 gamma)
+{
+ u32 lookup_index;
+ u16 table_count, table_index;
+ u32 gap, i;
+ u32 minimum = smart->g300_gra_tbl[255];
+ u32 candidate = 0;
+ u32 offset = 0;
+
+ lookup_index = (gamma/VALUE_DIM_1000)+1;
+ if (lookup_index > MAX_GRADATION) {
+ /*printk(KERN_ERR "ERROR Wrong input value LOOKUP INDEX : %d\n", lookup_index);*/
+ return 0;
+ }
+
+ if (smart->flooktbl[lookup_index].count) {
+ if (smart->flooktbl[lookup_index-1].count) {
+ table_index = smart->flooktbl[lookup_index-1].entry;
+ table_count = smart->flooktbl[lookup_index].count + smart->flooktbl[lookup_index-1].count;
+ } else {
+ table_index = smart->flooktbl[lookup_index].entry;
+ table_count = smart->flooktbl[lookup_index].count;
+ }
+ } else {
+ offset += 1;
+ while (!(smart->flooktbl[lookup_index+offset].count || smart->flooktbl[lookup_index-offset].count))
+ offset++;
+
+ if (smart->flooktbl[lookup_index-offset].count)
+ table_index = smart->flooktbl[lookup_index-offset].entry;
+ else
+ table_index = smart->flooktbl[lookup_index+offset].entry;
+
+ table_count = smart->flooktbl[lookup_index+offset].count + smart->flooktbl[lookup_index-offset].count;
+ }
+
+ for (i = 0; i < table_count; i++) {
+ if (gamma > smart->g300_gra_tbl[table_index])
+ gap = gamma - smart->g300_gra_tbl[table_index];
+ else
+ gap = smart->g300_gra_tbl[table_index] - gamma;
+
+ if (gap == 0) {
+ candidate = table_index;
+ break;
+ }
+
+ if (gap < minimum) {
+ minimum = gap;
+ candidate = table_index;
+ }
+ table_index++;
+ }
+
+#if 0
+ printk(KERN_INFO "cal : found index : %d\n", candidate);
+ printk(KERN_INFO "gamma : %d, found index : %d found gamma : %d\n",
+ gamma, candidate, smart->g300_gra_tbl[candidate]);
+#endif
+ return candidate;
+}
+
+static u32 calc_vt_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ return 0;
+}
+
+static u32 calc_v3_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 v0 = VREG_OUT_1000, v3, v11;
+ u32 ret;
+
+ /*v0 = dv[ci][IV_0];*/
+ v3 = dv[ci][IV_3];
+ v11 = dv[ci][IV_11];
+
+ t1 = (v0 - v3) << 10;
+ t2 = (v0 - v11) ? (v0 - v11) : (v0) ? v0 : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v11_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v11, v23;
+ u32 ret;
+
+ vt = adjust_volt[ci][AD_IVT];
+ v11 = dv[ci][IV_11];
+ v23 = dv[ci][IV_23];
+ t1 = (vt - v11) << 10;
+ t2 = (vt - v23) ? (vt - v23) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v23_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v23, v35;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v23 = dv[ci][IV_23];
+ v35 = dv[ci][IV_35];
+
+ t1 = (vt - v23) << 10;
+ t2 = (vt - v35) ? (vt - v35) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v35_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v35, v51;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v35 = dv[ci][IV_35];
+ v51 = dv[ci][IV_51];
+
+ t1 = (vt - v35) << 10;
+ t2 = (vt - v51) ? (vt - v51) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v51_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v51, v87;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v51 = dv[ci][IV_51];
+ v87 = dv[ci][IV_87];
+
+ t1 = (vt - v51) << 10;
+ t2 = (vt - v87) ? (vt - v87) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+
+static u32 calc_v87_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v87, v151;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v87 = dv[ci][IV_87];
+ v151 = dv[ci][IV_151];
+
+ t1 = (vt - v87) << 10;
+ t2 = (vt - v151) ? (vt - v151) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v151_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v203;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v151 = dv[ci][IV_151];
+ v203 = dv[ci][IV_203];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v203) ? (vt - v203) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v203_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v255;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][IV_VT];
+ v151 = dv[ci][IV_203];
+ v255 = dv[ci][IV_255];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v255) ? (vt - v255) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v255_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret;
+ u32 v255;
+ v255 = dv[ci][IV_255];
+
+ ret = (559 * 1000) - (VT_255_calc_param * v255);
+ ret = ret / 1000;
+
+ return ret;
+}
+
+u32 calc_gamma_table_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+
+memset(gamma, 0, sizeof(gamma));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_VT] = smart->ve[AD_IVT].v[c]; /* not use V1 calculate value*/
+#endif
+
+ for (i = IV_3 ; i < IV_MAX; i++) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv) / 1000;
+ lidx = lookup_vtbl_idx(smart, temp);
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ t1 = (s8)mtp[CI_MAX*(i + 1)+c];
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV_1 does not calculate value */
+ /* Do not use gamma value (IV_1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma[c][i];
+ }
+
+#if 0
+
+printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+}
+
+printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %3d, 0x%2x", color_name[c], gamma[c][i], gamma[c][i]);
+ printk("\n");
+}
+#endif
+return 0;
+}
+
+u32 calc_gamma_table_190_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_215_190;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_215_190[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_215_190, 0, sizeof(gamma_215_190));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_151) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-1;
+ } else if ((i == IV_203) || (i == IV_255)) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-2;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_215_190].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ t1 = (s8)mtp[CI_MAX*(i + 1)+c];
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_215_190[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_215_190[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_215_190[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_215_190[c][i], gamma_215_190[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+u32 calc_gamma_table_20_100_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_110;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_110[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_110, 0, sizeof(gamma_110));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_11) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_110 = lookup_vtbl_idx(smart, temp)-1;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_110 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_110].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ t1 = (s8)mtp[CI_MAX*(i + 1)+c];
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_210_110[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_110[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_110[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_110[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_110[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_110[c][i], gamma_210_110[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
diff --git a/drivers/video/samsung/smart_dimming_ea8061.h b/drivers/video/samsung/smart_dimming_ea8061.h
new file mode 100644
index 0000000..263c2e2
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_ea8061.h
@@ -0,0 +1,133 @@
+/* linux/drivers/video/samsung/smartdimming.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+
+#ifndef __SMART_DIMMING_H__
+#define __SMART_DIMMING_H__
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+
+#define MAX_GRADATION 300
+#define PANEL_ID_MAX 3
+#define GAMMA_300CD_MAX 9
+
+
+enum {
+ CI_RED = 0,
+ CI_GREEN = 1,
+ CI_BLUE = 2,
+ CI_MAX = 3,
+};
+
+
+enum {
+ IV_VT ,
+ IV_3 ,
+ IV_11 ,
+ IV_23 ,
+ IV_35 ,
+ IV_51,
+ IV_87 ,
+ IV_151,
+ IV_203,
+ IV_255,
+ IV_MAX,
+ IV_TABLE_MAX,
+};
+
+
+enum {
+ AD_IVT,
+ AD_IV3,
+ AD_IV11,
+ AD_IV23 ,
+ AD_IV35,
+ AD_IV51 ,
+ AD_IV87 ,
+ AD_IV151 ,
+ AD_IV203 ,
+ AD_IV255 ,
+ AD_IVMAX ,
+};
+
+
+enum {
+ G_21,
+ G_213,
+ G_215,
+ G_218,
+ G_22,
+ G_221,
+ G_222,
+ G_223,
+ G_224,
+ G_225,
+ G_MAX,
+};
+
+
+struct str_voltage_entry {
+ u32 v[CI_MAX];
+};
+
+
+struct str_table_info {
+ /* et : start gray value */
+ u8 st;
+ /* end gray value, st + count */
+ u8 et;
+ u8 count;
+ const u8 *offset_table;
+ /* rv : ratio value */
+ u32 rv;
+};
+
+
+struct str_flookup_table {
+ u16 entry;
+ u16 count;
+};
+
+
+struct str_smart_dim {
+ u8 panelid[PANEL_ID_MAX];
+ s16 mtp[CI_MAX][IV_MAX];
+ struct str_voltage_entry ve[256];
+ const u8 *default_gamma;
+ struct str_table_info t_info[IV_TABLE_MAX];
+ const struct str_flookup_table *flooktbl;
+ const u32 *g22_tbl;
+ const u32 *gamma_table[G_MAX];
+ const u32 *g300_gra_tbl;
+ u32 adjust_volt[CI_MAX][AD_IVMAX];
+};
+
+struct rgb_offset_info {
+ unsigned int candela_idx;
+ unsigned int gray;
+ unsigned int rgb;
+ int offset;
+};
+
+
+int init_table_info_ea8061(struct str_smart_dim *smart);
+u8 calc_voltage_table_ea8061(struct str_smart_dim *smart, const u8 *mtp);
+u32 calc_gamma_table_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_190_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_20_100_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+
+#endif
diff --git a/drivers/video/samsung/smart_dimming_s6evr02.c b/drivers/video/samsung/smart_dimming_s6evr02.c
new file mode 100644
index 0000000..9c0af0a
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_s6evr02.c
@@ -0,0 +1,948 @@
+/* linux/drivers/video/samsung/smartdimming.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+#include "smart_dimming_s6evr02.h"
+#include "s6evr02_volt_tbl.h"
+
+#define VALUE_DIM_1000 1000
+#define VT_255_div_1000 860000
+#define VREG_OUT_1000 6100
+#define VREG_OUT_1000_1024 6246400
+#define VT_255_calc_param (VT_255_div_1000 / VREG_OUT_1000)
+
+static const u8 range_table_count[IV_TABLE_MAX] = {
+ 3, 8, 12, 12, 16, 36, 64, 52, 52, 1
+};
+
+static const u32 table_radio[IV_TABLE_MAX] = {
+ 16384, 4138, 2763, 2763, 2080, 918, 516, 636, 636, 0
+};
+
+static const u32 dv_value[IV_MAX] = {
+ 0, 3, 11, 23, 35, 51, 87, 151, 203, 255
+};
+
+static const char color_name[3] = {'R', 'G', 'B'};
+
+static const u8 *offset_table[IV_TABLE_MAX] = {
+ NULL, /*V3*/
+ NULL, /*V11*/
+ NULL, /*V23*/
+ NULL, /*V23*/
+ NULL, /*V35*/
+ NULL, /*V51*/
+ NULL, /*V87*/
+ NULL, /*V151*/
+ NULL, /*V203*/
+ NULL /*V255*/
+};
+
+static const unsigned char gamma_300cd_80[] = {
+ 0x00, 0xFF, 0x01, 0x1C, 0x01, 0x2C,
+ 0xDA, 0xD7, 0xDA, 0xD5, 0xD2, 0xD6, 0xC1, 0xBC, 0xC2,
+ 0xCA, 0xB9, 0xCB, 0xDC, 0xE5, 0xDD, 0xDA, 0xD8, 0xDD,
+ 0xBA, 0xA8, 0xC1, 0x6B, 0x20, 0xD7, 0x02, 0x03, 0x02
+};
+
+static const unsigned char gamma_300cd_81[] = {
+ 0x00, 0xFF, 0x01, 0x1D, 0x01, 0x2D,
+ 0xDA, 0xD7, 0xDA, 0xD6, 0xD3, 0xD7, 0xC1, 0xBC, 0xC1,
+ 0xCB, 0xC6, 0xCC, 0xDC, 0xD9, 0xDD, 0xDA, 0xD8, 0xDE,
+ 0xBB, 0xAB, 0xC1, 0xC7, 0xBD, 0xE2, 0x02, 0x03, 0x02
+};
+
+static const unsigned char gamma_300cd_82[] = {
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x02, 0x03, 0x02
+};
+
+static const unsigned char *gamma_300cd_list[GAMMA_300CD_MAX] = {
+ gamma_300cd_80,
+ gamma_300cd_81,
+ gamma_300cd_82,
+ gamma_300cd_82,
+};
+
+static const unsigned char gamma_id_list[GAMMA_300CD_MAX] = {
+ 0x80, 0x81, 0x82, 0xA2
+};
+
+static s16 s9_to_s16(s16 v)
+{
+ return (s16)(v << 7) >> 7;
+}
+
+static u32 calc_vt_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_vt[gamma] >> 16;
+
+ return ret;
+}
+
+static u32 calc_v3_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320 */
+ int ret = 0;
+ u32 v0 = VREG_OUT_1000, v11;
+ u32 ratio = 0;
+
+ /*vt = adjust_volt[rgb_index][AD_IVT];*/
+ v11 = adjust_volt[rgb_index][AD_IV11];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (v0 << 16) - ((v0-v11)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v11_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320*/
+ int ret = 0;
+ u32 vt, v23;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v23 = adjust_volt[rgb_index][AD_IV23];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v23)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v23_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v35;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v35 = adjust_volt[rgb_index][AD_IV35];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v35)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v35_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v51;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v51 = adjust_volt[rgb_index][AD_IV51];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v51)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v51_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v87;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v87 = adjust_volt[rgb_index][AD_IV87];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v87)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+
+}
+
+static u32 calc_v87_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v151;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v151 = adjust_volt[rgb_index][AD_IV151];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v151)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v151_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v203;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v203 = adjust_volt[rgb_index][AD_IV203];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v203)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v203_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v255;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v255 = adjust_volt[rgb_index][AD_IV255];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v255)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v255_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_v255[gamma] >> 16;
+
+ return ret;
+}
+
+u8 calc_voltage_table(struct str_smart_dim *smart, const u8 *mtp)
+{
+ int c, i, j;
+#if defined(MTP_REVERSE)
+ int offset1 = 0;
+#endif
+ int offset = 0;
+ s16 t1, t2;
+ s16 adjust_mtp[CI_MAX][IV_MAX];
+ u8 range_index;
+ u8 table_index = 0;
+ u32 v1, v2;
+ u32 ratio;
+ u32(*calc_volt[IV_MAX])(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_volt,
+ calc_v3_volt,
+ calc_v11_volt,
+ calc_v23_volt,
+ calc_v35_volt,
+ calc_v51_volt,
+ calc_v87_volt,
+ calc_v151_volt,
+ calc_v203_volt,
+ calc_v255_volt,
+ };
+ u8 calc_seq[9] = { IV_VT, IV_203, IV_151, IV_87, IV_51, IV_35, IV_23, IV_11, IV_3};
+ u8 ad_seq[9] = {AD_IVT, AD_IV203, AD_IV151, AD_IV87, AD_IV51, AD_IV35, AD_IV23, AD_IV11, AD_IV3};
+
+ memset(adjust_mtp, 0, sizeof(adjust_mtp));
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+ t2 = (smart->default_gamma[offset]<<8|smart->default_gamma[offset+1]) + t1;
+ smart->mtp[c][IV_255] = t1;
+ adjust_mtp[c][IV_255] = t2;
+ smart->adjust_volt[c][AD_IV255] = calc_volt[IV_255](t2, c, smart->adjust_volt);
+ /* for V0 All RGB Voltage Value is Reference Voltage */
+ smart->adjust_volt[c][AD_IVT] = VREG_OUT_1000;
+ }
+
+ for (i = IV_VT; i < IV_255; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i < IV_3) {
+ t1 = 0;
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ } else {
+ if (mtp[CI_MAX*(10-calc_seq[i])+c] & 0x80)
+ t1 = (mtp[CI_MAX*(10-calc_seq[i])+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(10-calc_seq[i])+c] & 0x7f);
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ }
+ }
+ }
+
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i == 0)
+ smart->ve[table_index].v[c] = VREG_OUT_1000;
+ else
+ smart->ve[table_index].v[c] = smart->adjust_volt[c][i];
+ }
+ range_index = 0;
+
+ for (j = table_index+1; j < table_index+range_table_count[i]; j++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (smart->t_info[i].offset_table != NULL)
+ ratio = smart->t_info[i].offset_table[range_index] * smart->t_info[i].rv;
+ else
+ ratio = (range_table_count[i]-(range_index+1)) * smart->t_info[i].rv;
+
+ v1 = smart->adjust_volt[c][i+1] << 15;
+ v2 = (smart->adjust_volt[c][i] - smart->adjust_volt[c][i+1])*ratio;
+ smart->ve[j].v[c] = ((v1+v2) >> 15);
+ }
+ range_index++;
+ }
+ table_index = j;
+ }
+
+ for (i = 1; i < 3; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ smart->ve[i].v[c] = smart->ve[3].v[c]+((smart->ve[0].v[c]-smart->ve[3].v[c])*(3-i)/3);
+ }
+
+#if 0
+ printk(KERN_INFO "++++++++++++++++++++++++++++++ MTP VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : 0x%08x(%04d)", color_name[c], smart->mtp[c][i], smart->mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : 0x%08x(%04d)", color_name[c], adjust_mtp[c][i], adjust_mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], smart->adjust_volt[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++++++++++ VOLTAGE TABLE ++++++++++++++++++++++++++++++++++++++\n");
+ for (i = 0; i < 256; i++) {
+ printk("Gray Level : %03d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], smart->ve[i].v[c]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+
+int init_table_info(struct str_smart_dim *smart)
+{
+ int i;
+ int offset = 0;
+
+ for (i = 0; i < IV_TABLE_MAX; i++) {
+ smart->t_info[i].count = (u8)range_table_count[i];
+ smart->t_info[i].offset_table = offset_table[i];
+ smart->t_info[i].rv = table_radio[i];
+ offset += range_table_count[i];
+ }
+
+ smart->flooktbl = flookup_table;
+ smart->g300_gra_tbl = gamma_300_gra_table;
+ smart->gamma_table[G_21] = GAMMA_CONTROL_TABLE[G_21];
+ smart->gamma_table[G_213] = GAMMA_CONTROL_TABLE[G_213];
+ smart->gamma_table[G_215] = GAMMA_CONTROL_TABLE[G_215];
+ smart->gamma_table[G_218] = GAMMA_CONTROL_TABLE[G_218];
+ smart->gamma_table[G_22] = GAMMA_CONTROL_TABLE[G_22];
+ smart->gamma_table[G_221] = GAMMA_CONTROL_TABLE[G_221];
+ smart->gamma_table[G_222] = GAMMA_CONTROL_TABLE[G_222];
+ smart->gamma_table[G_223] = GAMMA_CONTROL_TABLE[G_223];
+ smart->gamma_table[G_224] = GAMMA_CONTROL_TABLE[G_224];
+ smart->gamma_table[G_225] = GAMMA_CONTROL_TABLE[G_225];
+
+ for (i = 0; i < GAMMA_300CD_MAX; i++) {
+ if (smart->panelid[2] == gamma_id_list[i])
+ break;
+ }
+
+ if (i >= GAMMA_300CD_MAX) {
+ printk(KERN_ERR "[SMART DIMMING-WARNING] %s Can't found default gamma table\n", __func__);
+ smart->default_gamma = gamma_300cd_list[GAMMA_300CD_MAX-1];
+ } else
+ smart->default_gamma = gamma_300cd_list[i];
+
+ return 0;
+}
+
+static u32 lookup_vtbl_idx(struct str_smart_dim *smart, u32 gamma)
+{
+ u32 lookup_index;
+ u16 table_count, table_index;
+ u32 gap, i;
+ u32 minimum = smart->g300_gra_tbl[255];
+ u32 candidate = 0;
+ u32 offset = 0;
+
+ lookup_index = (gamma/VALUE_DIM_1000)+1;
+ if (lookup_index > MAX_GRADATION) {
+ /*printk(KERN_ERR "ERROR Wrong input value LOOKUP INDEX : %d\n", lookup_index);*/
+ return 0;
+ }
+
+ if (smart->flooktbl[lookup_index].count) {
+ if (smart->flooktbl[lookup_index-1].count) {
+ table_index = smart->flooktbl[lookup_index-1].entry;
+ table_count = smart->flooktbl[lookup_index].count + smart->flooktbl[lookup_index-1].count;
+ } else {
+ table_index = smart->flooktbl[lookup_index].entry;
+ table_count = smart->flooktbl[lookup_index].count;
+ }
+ } else {
+ offset += 1;
+ while (!(smart->flooktbl[lookup_index+offset].count || smart->flooktbl[lookup_index-offset].count))
+ offset++;
+
+ if (smart->flooktbl[lookup_index-offset].count)
+ table_index = smart->flooktbl[lookup_index-offset].entry;
+ else
+ table_index = smart->flooktbl[lookup_index+offset].entry;
+
+ table_count = smart->flooktbl[lookup_index+offset].count + smart->flooktbl[lookup_index-offset].count;
+ }
+
+ for (i = 0; i < table_count; i++) {
+ if (gamma > smart->g300_gra_tbl[table_index])
+ gap = gamma - smart->g300_gra_tbl[table_index];
+ else
+ gap = smart->g300_gra_tbl[table_index] - gamma;
+
+ if (gap == 0) {
+ candidate = table_index;
+ break;
+ }
+
+ if (gap < minimum) {
+ minimum = gap;
+ candidate = table_index;
+ }
+ table_index++;
+ }
+
+#if 0
+ printk(KERN_INFO "cal : found index : %d\n", candidate);
+ printk(KERN_INFO "gamma : %d, found index : %d found gamma : %d\n",
+ gamma, candidate, smart->g300_gra_tbl[candidate]);
+#endif
+ return candidate;
+}
+
+static u32 calc_vt_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ return 0;
+}
+
+static u32 calc_v3_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 v0 = VREG_OUT_1000, v3, v11;
+ u32 ret;
+
+ /*v0 = dv[ci][IV_0];*/
+ v3 = dv[ci][IV_3];
+ v11 = dv[ci][IV_11];
+
+ t1 = (v0 - v3) << 10;
+ t2 = (v0 - v11) ? (v0 - v11) : (v0) ? v0 : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v11_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v11, v23;
+ u32 ret;
+
+ vt = adjust_volt[ci][AD_IVT];
+ v11 = dv[ci][IV_11];
+ v23 = dv[ci][IV_23];
+ t1 = (vt - v11) << 10;
+ t2 = (vt - v23) ? (vt - v23) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v23_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v23, v35;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v23 = dv[ci][IV_23];
+ v35 = dv[ci][IV_35];
+
+ t1 = (vt - v23) << 10;
+ t2 = (vt - v35) ? (vt - v35) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v35_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v35, v51;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v35 = dv[ci][IV_35];
+ v51 = dv[ci][IV_51];
+
+ t1 = (vt - v35) << 10;
+ t2 = (vt - v51) ? (vt - v51) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v51_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v51, v87;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v51 = dv[ci][IV_51];
+ v87 = dv[ci][IV_87];
+
+ t1 = (vt - v51) << 10;
+ t2 = (vt - v87) ? (vt - v87) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+
+static u32 calc_v87_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v87, v151;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v87 = dv[ci][IV_87];
+ v151 = dv[ci][IV_151];
+
+ t1 = (vt - v87) << 10;
+ t2 = (vt - v151) ? (vt - v151) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v151_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v203;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v151 = dv[ci][IV_151];
+ v203 = dv[ci][IV_203];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v203) ? (vt - v203) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (65 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v203_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v255;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][IV_VT];
+ v151 = dv[ci][IV_203];
+ v255 = dv[ci][IV_255];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v255) ? (vt - v255) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v255_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret;
+ u32 v255;
+ v255 = dv[ci][IV_255];
+
+ ret = (788 * 1000) - (141 * v255);
+ ret = ret / 1000;
+
+ return ret;
+}
+
+u32 calc_gamma_table(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+
+memset(gamma, 0, sizeof(gamma));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_VT] = smart->ve[AD_IVT].v[c]; /* not use V1 calculate value*/
+#endif
+
+ for (i = IV_3 ; i < IV_MAX; i++) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv) / 1000;
+ lidx = lookup_vtbl_idx(smart, temp);
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (mtp[CI_MAX*(i + 1)+c] & 0x80)
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f);
+
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV_1 does not calculate value */
+ /* Do not use gamma value (IV_1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %3d, 0x%2x", color_name[c], gamma[c][i], gamma[c][i]);
+ printk("\n");
+ }
+#endif
+return 0;
+}
+
+u32 calc_gamma_table_215_190(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_215_190;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_215_190[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_215_190, 0, sizeof(gamma_215_190));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_151) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-1;
+ } else if ((i == IV_203) || (i == IV_255)) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-2;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_215_190].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (mtp[CI_MAX*(i + 1)+c] & 0x80)
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f);
+
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_215_190[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_215_190[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_215_190[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_215_190[c][i], gamma_215_190[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+u32 calc_gamma_table_210_20_100(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_210_110;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_210_110[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_210_110, 0, sizeof(gamma_210_110));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_11) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_210_110 = lookup_vtbl_idx(smart, temp)-1;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_210_110 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_210_110].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (mtp[CI_MAX*(i + 1)+c] & 0x80)
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f);
+
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_210_110[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_210_110[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_210_110[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_210_110[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_210_110[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_210_110[c][i], gamma_210_110[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
diff --git a/drivers/video/samsung/smart_dimming_s6evr02.h b/drivers/video/samsung/smart_dimming_s6evr02.h
new file mode 100644
index 0000000..28fd3c0
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_s6evr02.h
@@ -0,0 +1,133 @@
+/* linux/drivers/video/samsung/smartdimming.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+
+#ifndef __SMART_DIMMING_H__
+#define __SMART_DIMMING_H__
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+
+#define MAX_GRADATION 300
+#define PANEL_ID_MAX 3
+#define GAMMA_300CD_MAX 4
+
+
+enum {
+ CI_RED = 0,
+ CI_GREEN = 1,
+ CI_BLUE = 2,
+ CI_MAX = 3,
+};
+
+
+enum {
+ IV_VT ,
+ IV_3 ,
+ IV_11 ,
+ IV_23 ,
+ IV_35 ,
+ IV_51,
+ IV_87 ,
+ IV_151,
+ IV_203,
+ IV_255,
+ IV_MAX,
+ IV_TABLE_MAX,
+};
+
+
+enum {
+ AD_IVT,
+ AD_IV3,
+ AD_IV11,
+ AD_IV23 ,
+ AD_IV35,
+ AD_IV51 ,
+ AD_IV87 ,
+ AD_IV151 ,
+ AD_IV203 ,
+ AD_IV255 ,
+ AD_IVMAX ,
+};
+
+
+enum {
+ G_21,
+ G_213,
+ G_215,
+ G_218,
+ G_22,
+ G_221,
+ G_222,
+ G_223,
+ G_224,
+ G_225,
+ G_MAX,
+};
+
+
+struct str_voltage_entry {
+ u32 v[CI_MAX];
+};
+
+
+struct str_table_info {
+ /* et : start gray value */
+ u8 st;
+ /* end gray value, st + count */
+ u8 et;
+ u8 count;
+ const u8 *offset_table;
+ /* rv : ratio value */
+ u32 rv;
+};
+
+
+struct str_flookup_table {
+ u16 entry;
+ u16 count;
+};
+
+
+struct str_smart_dim {
+ u8 panelid[PANEL_ID_MAX];
+ s16 mtp[CI_MAX][IV_MAX];
+ struct str_voltage_entry ve[256];
+ const u8 *default_gamma;
+ struct str_table_info t_info[IV_TABLE_MAX];
+ const struct str_flookup_table *flooktbl;
+ const u32 *g22_tbl;
+ const u32 *gamma_table[G_MAX];
+ const u32 *g300_gra_tbl;
+ u32 adjust_volt[CI_MAX][AD_IVMAX];
+};
+
+struct rgb_offset_info {
+ unsigned int candela_idx;
+ unsigned int gray;
+ unsigned int rgb;
+ int offset;
+};
+
+
+int init_table_info(struct str_smart_dim *smart);
+u8 calc_voltage_table(struct str_smart_dim *smart, const u8 *mtp);
+u32 calc_gamma_table(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_215_190(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_210_20_100(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+
+#endif