aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/backlight/s6e8aa0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/backlight/s6e8aa0.c')
-rw-r--r--drivers/video/backlight/s6e8aa0.c339
1 files changed, 255 insertions, 84 deletions
diff --git a/drivers/video/backlight/s6e8aa0.c b/drivers/video/backlight/s6e8aa0.c
index c9b1184..2cc5466 100644
--- a/drivers/video/backlight/s6e8aa0.c
+++ b/drivers/video/backlight/s6e8aa0.c
@@ -4,6 +4,8 @@
*
* Inki Dae, <inki.dae@samsung.com>
* Donghwa Lee, <dh09.lee@samsung.com>
+ * Joongmock Shin <jmock.shin@samsung.com>
+ * Eunchul Kim <chulspro.kim@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -21,6 +23,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/lcd.h>
+#include <linux/lcd-property.h>
#include <linux/fb.h>
#include <linux/backlight.h>
#include <linux/regulator/consumer.h>
@@ -28,8 +31,13 @@
#include <video/mipi_display.h>
+#include <plat/cpu.h>
#include <plat/mipi_dsim2.h>
+#if defined(CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ) || defined(CONFIG_DISPFREQ_OPP)
+#include <linux/devfreq/exynos4_display.h>
+#endif
+
#include "s6e8aa0_gamma.h"
#ifdef CONFIG_BACKLIGHT_SMART_DIMMING
#include "smart_dimming.h"
@@ -43,10 +51,62 @@
#define MIN_BRIGHTNESS (0)
#define MAX_BRIGHTNESS (24)
+/* 1 */
+#define PANELCTL_SS_MASK (1 << 5)
+#define PANELCTL_SS_1_800 (0 << 5)
+#define PANELCTL_SS_800_1 (1 << 5)
+#define PANELCTL_GTCON_MASK (7 << 2)
+#define PANELCTL_GTCON_110 (6 << 2)
+#define PANELCTL_GTCON_111 (7 << 2)
+/* LTPS */
+/* 30 */
+#define PANELCTL_CLK1_CON_MASK (7 << 3)
+#define PANELCTL_CLK1_000 (0 << 3)
+#define PANELCTL_CLK1_001 (1 << 3)
+#define PANELCTL_CLK2_CON_MASK (7 << 0)
+#define PANELCTL_CLK2_000 (0 << 0)
+#define PANELCTL_CLK2_001 (1 << 0)
+/* 31 */
+#define PANELCTL_INT1_CON_MASK (7 << 3)
+#define PANELCTL_INT1_000 (0 << 3)
+#define PANELCTL_INT1_001 (1 << 3)
+#define PANELCTL_INT2_CON_MASK (7 << 0)
+#define PANELCTL_INT2_000 (0 << 0)
+#define PANELCTL_INT2_001 (1 << 0)
+/* 32 */
+#define PANELCTL_BICTL_CON_MASK (7 << 3)
+#define PANELCTL_BICTL_000 (0 << 3)
+#define PANELCTL_BICTL_001 (1 << 3)
+#define PANELCTL_BICTLB_CON_MASK (7 << 0)
+#define PANELCTL_BICTLB_000 (0 << 0)
+#define PANELCTL_BICTLB_001 (1 << 0)
+/* 36 */
+#define PANELCTL_EM_CLK1_CON_MASK (7 << 3)
+#define PANELCTL_EM_CLK1_110 (6 << 3)
+#define PANELCTL_EM_CLK1_111 (7 << 3)
+#define PANELCTL_EM_CLK1B_CON_MASK (7 << 0)
+#define PANELCTL_EM_CLK1B_110 (6 << 0)
+#define PANELCTL_EM_CLK1B_111 (7 << 0)
+/* 37 */
+#define PANELCTL_EM_CLK2_CON_MASK (7 << 3)
+#define PANELCTL_EM_CLK2_110 (6 << 3)
+#define PANELCTL_EM_CLK2_111 (7 << 3)
+#define PANELCTL_EM_CLK2B_CON_MASK (7 << 0)
+#define PANELCTL_EM_CLK2B_110 (6 << 0)
+#define PANELCTL_EM_CLK2B_111 (7 << 0)
+/* 38 */
+#define PANELCTL_EM_INT1_CON_MASK (7 << 3)
+#define PANELCTL_EM_INT1_000 (0 << 3)
+#define PANELCTL_EM_INT1_001 (1 << 3)
+#define PANELCTL_EM_INT2_CON_MASK (7 << 0)
+#define PANELCTL_EM_INT2_000 (0 << 0)
+#define PANELCTL_EM_INT2_001 (1 << 0)
+
#define VER_142 (0x8e) /* MACH_SLP_PQ */
#define VER_174 (0xae) /* MACH_SLP_PQ Dali */
#define VER_42 (0x2a) /* MACH_SLP_PQ_LTE */
#define VER_32 (0x20) /* MACH_SLP_PQ M0 B-Type */
+#define VER_96 (0x60) /* MACH_SLP_PQ Galaxy S3 */
#define VER_210 (0xd2) /* MACH_SLP_PQ M0 A-Type */
#define AID_DISABLE (0x4)
@@ -61,87 +121,64 @@
#define lcd_to_master(a) (a->dsim_dev->master)
#define lcd_to_master_ops(a) ((lcd_to_master(a))->master_ops)
-struct str_elvss {
- u8 reference;
- u8 limit;
-};
-
struct panel_model {
int ver;
char *name;
};
-enum {
- DSIM_NONE_STATE = 0,
- DSIM_RESUME_COMPLETE = 1,
- DSIM_FRAME_DONE = 2,
-};
-
struct s6e8aa0 {
struct device *dev;
- unsigned int id;
- unsigned int aid;
- unsigned int ver;
- unsigned int power;
- unsigned int current_brightness;
- unsigned int updated;
- unsigned int brightness;
- unsigned int resume_complete;
- unsigned int acl_enable;
- unsigned int cur_acl;
- unsigned int cur_addr;
-
- struct lcd_device *ld;
- struct backlight_device *bd;
-
+ struct lcd_device *ld;
+ struct backlight_device *bd;
struct mipi_dsim_lcd_device *dsim_dev;
struct lcd_platform_data *ddi_pd;
+ struct lcd_property *property;
- struct mutex lock;
- struct regulator *reg_vdd3;
- struct regulator *reg_vci;
+ struct regulator *reg_vdd3;
+ struct regulator *reg_vci;
+
+#if defined(CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ) || defined(CONFIG_DISPFREQ_OPP)
+ struct notifier_block nb_disp;
+#endif
+ struct mutex lock;
+
+ unsigned int id;
+ unsigned int aid;
+ unsigned int ver;
+ unsigned int power;
+ unsigned int acl_enable;
+ unsigned int cur_acl;
+ unsigned int cur_addr;
const struct panel_model *model;
- unsigned int model_count;
+ unsigned int model_count;
- bool enabled;
#ifdef CONFIG_BACKLIGHT_SMART_DIMMING
- unsigned int support_elvss;
- struct str_smart_dim smart_dim;
- struct str_elvss elvss;
- struct mutex bl_lock;
+ unsigned int support_elvss;
+ struct str_smart_dim smart_dim;
#endif
};
-struct s6e8aa0 *lcd_global;
-
-static void s6e8aa0_regulator_enable(struct s6e8aa0 *lcd)
+static void s6e8aa0_regulator_ctl(struct s6e8aa0 *lcd, bool enable)
{
+ dev_dbg(lcd->dev, "%s:enable[%d]\n", __func__, enable);
+
mutex_lock(&lcd->lock);
- if (!lcd->enabled) {
+
+ if (enable) {
if (lcd->reg_vdd3)
regulator_enable(lcd->reg_vdd3);
if (lcd->reg_vci)
regulator_enable(lcd->reg_vci);
-
- lcd->enabled = true;
- }
- mutex_unlock(&lcd->lock);
-}
-
-static void s6e8aa0_regulator_disable(struct s6e8aa0 *lcd)
-{
- mutex_lock(&lcd->lock);
- if (lcd->enabled) {
+ } else {
if (lcd->reg_vci)
regulator_disable(lcd->reg_vci);
if (lcd->reg_vdd3)
regulator_disable(lcd->reg_vdd3);
-
- lcd->enabled = false;
}
+
mutex_unlock(&lcd->lock);
}
@@ -178,9 +215,8 @@ static unsigned char s6e8aa0_apply_aid_panel_cond(unsigned int aid)
return ret;
}
-void s6e8aa0_panel_cond(int high_freq)
+static void s6e8aa0_panel_cond(struct s6e8aa0 *lcd, int high_freq)
{
- struct s6e8aa0 *lcd = lcd_global;
struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
unsigned char data_to_send_v42[] = {
0xf8, 0x01, 0x34, 0x00, 0x00, 0x00, 0x95, 0x00, 0x3c,
@@ -204,6 +240,13 @@ void s6e8aa0_panel_cond(int high_freq)
0x23, 0x6e, 0xc0, 0xc1, 0x01, 0x81, 0xc1, 0x00, 0xc3,
0xf6, 0xf6, 0xc1
};
+ unsigned char data_to_send_v96[] = {
+ 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, 0x37, 0xc0, 0xc1, 0x01, 0x81, 0xc1, 0x00, 0xc3,
+ 0xf6, 0xf6, 0xc1
+ };
unsigned char data_to_send_v210[] = {
0xf8, 0x3d, 0x32, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x39,
0x78, 0x08, 0x26, 0x78, 0x3c, 0x00, 0x00, 0x00, 0x20,
@@ -213,17 +256,92 @@ void s6e8aa0_panel_cond(int high_freq)
};
unsigned char *data_to_send;
unsigned int size;
+ struct lcd_property *property = lcd->property;
+ unsigned char cfg;
if (lcd->ver == VER_42) {
data_to_send = data_to_send_v42;
size = ARRAY_SIZE(data_to_send_v42);
- } else if (lcd->ver == VER_142 || lcd->ver == VER_174) {
+ } else if (lcd->ver == VER_142) {
+ data_to_send_v142[18] = s6e8aa0_apply_aid_panel_cond(lcd->aid);
+ data_to_send = data_to_send_v142;
+ if (property) {
+ if (property->flip & LCD_PROPERTY_FLIP_VERTICAL) {
+ /* GTCON */
+ cfg = data_to_send[1];
+ cfg &= ~(PANELCTL_GTCON_MASK);
+ cfg |= (PANELCTL_GTCON_110);
+ data_to_send[1] = cfg;
+ }
+
+ if (property->flip & LCD_PROPERTY_FLIP_HORIZONTAL) {
+ /* SS */
+ cfg = data_to_send[1];
+ cfg &= ~(PANELCTL_SS_MASK);
+ cfg |= (PANELCTL_SS_1_800);
+ data_to_send[1] = cfg;
+ }
+
+ if (property->flip & (LCD_PROPERTY_FLIP_VERTICAL |
+ LCD_PROPERTY_FLIP_HORIZONTAL)) {
+ /* CLK1,2_CON */
+ cfg = data_to_send[30];
+ cfg &= ~(PANELCTL_CLK1_CON_MASK |
+ PANELCTL_CLK2_CON_MASK);
+ cfg |= (PANELCTL_CLK1_000 | PANELCTL_CLK2_001);
+ data_to_send[30] = cfg;
+
+ /* INT1,2_CON */
+ cfg = data_to_send[31];
+ cfg &= ~(PANELCTL_INT1_CON_MASK |
+ PANELCTL_INT2_CON_MASK);
+ cfg |= (PANELCTL_INT1_000 | PANELCTL_INT2_001);
+ data_to_send[31] = cfg;
+
+ /* BICTL,B_CON */
+ cfg = data_to_send[32];
+ cfg &= ~(PANELCTL_BICTL_CON_MASK |
+ PANELCTL_BICTLB_CON_MASK);
+ cfg |= (PANELCTL_BICTL_000 |
+ PANELCTL_BICTLB_001);
+ data_to_send[32] = cfg;
+
+ /* EM_CLK1,1B_CON */
+ cfg = data_to_send[36];
+ cfg &= ~(PANELCTL_EM_CLK1_CON_MASK |
+ PANELCTL_EM_CLK1B_CON_MASK);
+ cfg |= (PANELCTL_EM_CLK1_110 |
+ PANELCTL_EM_CLK1B_110);
+ data_to_send[36] = cfg;
+
+ /* EM_CLK2,2B_CON */
+ cfg = data_to_send[37];
+ cfg &= ~(PANELCTL_EM_CLK2_CON_MASK |
+ PANELCTL_EM_CLK2B_CON_MASK);
+ cfg |= (PANELCTL_EM_CLK2_110 |
+ PANELCTL_EM_CLK2B_110);
+ data_to_send[37] = cfg;
+
+ /* EM_INT1,2_CON */
+ cfg = data_to_send[38];
+ cfg &= ~(PANELCTL_EM_INT1_CON_MASK |
+ PANELCTL_EM_INT2_CON_MASK);
+ cfg |= (PANELCTL_EM_INT1_000 |
+ PANELCTL_EM_INT2_001);
+ data_to_send[38] = cfg;
+ }
+ }
+ size = ARRAY_SIZE(data_to_send_v142);
+ } else if (lcd->ver == VER_174) {
data_to_send_v142[18] = s6e8aa0_apply_aid_panel_cond(lcd->aid);
data_to_send = data_to_send_v142;
size = ARRAY_SIZE(data_to_send_v142);
} else if (lcd->ver == VER_32) {
data_to_send = data_to_send_v32;
size = ARRAY_SIZE(data_to_send_v32);
+ } else if (lcd->ver == VER_96) {
+ data_to_send = data_to_send_v96;
+ size = ARRAY_SIZE(data_to_send_v96);
} else if (lcd->ver == VER_210) {
data_to_send = data_to_send_v210;
size = ARRAY_SIZE(data_to_send_v210);
@@ -270,7 +388,7 @@ static void s6e8aa0_etc_pentile_control(struct s6e8aa0 *lcd)
0x00
};
- if (lcd->ver == VER_32)
+ if (lcd->ver == VER_32 || lcd->ver == VER_96)
data_to_send[5] = 0xc0;
ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_LONG_WRITE,
@@ -306,7 +424,7 @@ static void s6e8aa0_etc_power_control(struct s6e8aa0 *lcd)
0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x1e, 0x33, 0x02
};
- if (lcd->ver == VER_32) {
+ if (lcd->ver == VER_32 || lcd->ver == VER_96) {
data_to_send[3] = 0x15;
data_to_send[5] = 0x19;
}
@@ -349,6 +467,8 @@ static void s6e8aa0_etc_elvss_control(struct s6e8aa0 *lcd)
static void s6e8aa0_elvss_nvm_set(struct s6e8aa0 *lcd)
{
struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+ struct backlight_device *bd = lcd->bd;
+ int brightness = bd->props.brightness;
unsigned char data_to_send[] = {
0xd9, 0x14, 0x40, 0x0c, 0xcb, 0xce, 0x6e, 0xc4, 0x0f,
0x40, 0x41, 0xd9, 0x00, 0x60, 0x19
@@ -358,11 +478,15 @@ static void s6e8aa0_elvss_nvm_set(struct s6e8aa0 *lcd)
if (lcd->ver == VER_32) {
data_to_send[8] = 0x07;
data_to_send[11] = 0xc1;
+ } else if (lcd->ver == VER_96) {
+ data_to_send[8] = 0x07;
+ data_to_send[9] = 0xc0;
+ data_to_send[11] = 0xc1;
} else if (lcd->ver == VER_210 || lcd->ver == VER_174) {
data_to_send[8] = 0x07;
data_to_send[11] = 0xd0;
} else {
- switch (lcd->brightness) {
+ switch (brightness) {
case 0 ... 6: /* 30cd ~ 100cd */
data_to_send[11] = 0xdf;
break;
@@ -428,19 +552,21 @@ static void s6e8aa0_acl_on(struct s6e8aa0 *lcd)
{
struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
ops->cmd_write(lcd_to_master(lcd),
- MIPI_DSI_DCS_SHORT_WRITE, 0xc0, 0x01);
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xc0, 0x01);
}
static void s6e8aa0_acl_off(struct s6e8aa0 *lcd)
{
struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
ops->cmd_write(lcd_to_master(lcd),
- MIPI_DSI_DCS_SHORT_WRITE, 0xc0, 0x00);
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xc0, 0x00);
}
static void s6e8aa0_acl_ctrl_set(struct s6e8aa0 *lcd)
{
struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
+ struct backlight_device *bd = lcd->bd;
+ int brightness = bd->props.brightness;
/* FIXME: !! must be review acl % value */
/* Full white 50% reducing setting */
const unsigned char cutoff_50[] = {
@@ -466,14 +592,14 @@ static void s6e8aa0_acl_ctrl_set(struct s6e8aa0 *lcd)
if (lcd->acl_enable) {
if (lcd->cur_acl == 0) {
- if (lcd->brightness == 0 || lcd->brightness == 1) {
+ if (brightness == 0 || brightness == 1) {
s6e8aa0_acl_off(lcd);
dev_dbg(&lcd->ld->dev,
"cur_acl=%d\n", lcd->cur_acl);
} else
s6e8aa0_acl_on(lcd);
}
- switch (lcd->brightness) {
+ switch (brightness) {
case 0 ... 1: /* 30cd */
s6e8aa0_acl_off(lcd);
lcd->cur_acl = 0;
@@ -570,7 +696,7 @@ unsigned int convert_brightness_to_gamma(int brightness)
return gamma_table[brightness] - 1;
}
-static int s6e8aa0_update_gamma_ctrl(struct s6e8aa0 *lcd, int brightness)
+static int s6e8aa0_gamma_ctrl(struct s6e8aa0 *lcd, int brightness)
{
struct mipi_dsim_master_ops *ops = lcd_to_master_ops(lcd);
@@ -597,22 +723,16 @@ static int s6e8aa0_update_gamma_ctrl(struct s6e8aa0 *lcd, int brightness)
ops->cmd_write(lcd_to_master(lcd), MIPI_DSI_DCS_SHORT_WRITE_PARAM,
0xf7, 0x03);
- lcd->brightness = brightness;
-
s6e8aa0_acl_ctrl_set(lcd);
return 0;
}
-static int s6e8aa0_gamma_ctrl(struct s6e8aa0 *lcd, int brightness)
-{
- s6e8aa0_update_gamma_ctrl(lcd, brightness);
-
- return 0;
-}
-
static int s6e8aa0_panel_init(struct s6e8aa0 *lcd)
{
+ struct backlight_device *bd = lcd->bd;
+ int brightness = bd->props.brightness;
+
s6e8aa0_apply_level_1_key(lcd);
if (system_rev == 3)
s6e8aa0_apply_level_2_key(lcd);
@@ -620,10 +740,10 @@ static int s6e8aa0_panel_init(struct s6e8aa0 *lcd)
s6e8aa0_sleep_out(lcd);
usleep_range(5000, 6000);
- s6e8aa0_panel_cond(1);
+ s6e8aa0_panel_cond(lcd, 1);
s6e8aa0_display_condition_set(lcd);
- s6e8aa0_gamma_ctrl(lcd, lcd->bd->props.brightness);
+ s6e8aa0_gamma_ctrl(lcd, brightness);
s6e8aa0_etc_source_control(lcd);
s6e8aa0_etc_pentile_control(lcd);
@@ -633,6 +753,7 @@ static int s6e8aa0_panel_init(struct s6e8aa0 *lcd)
/* if ID3 value is not 33h, branch private elvss mode */
mdelay(lcd->ddi_pd->power_on_delay);
+ dev_info(lcd->dev, "panel init sequence done.\n");
return 0;
}
@@ -712,7 +833,7 @@ static int s6e8aa0_set_brightness(struct backlight_device *bd)
int ret = 0, brightness = bd->props.brightness;
struct s6e8aa0 *lcd = bl_get_data(bd);
- if (!lcd->enabled) {
+ if (lcd->power == FB_BLANK_POWERDOWN) {
dev_err(lcd->dev,
"lcd off: brightness set failed.\n");
return -EINVAL;
@@ -802,9 +923,11 @@ static void s6e8aa0_power_on(struct mipi_dsim_lcd_device *dsim_dev,
{
struct s6e8aa0 *lcd = dev_get_drvdata(&dsim_dev->dev);
+ dev_dbg(lcd->dev, "%s:enable[%d]\n", __func__, enable);
+
if (enable) {
/* lcd power on */
- s6e8aa0_regulator_enable(lcd);
+ s6e8aa0_regulator_ctl(lcd, true);
mdelay(lcd->ddi_pd->reset_delay);
@@ -813,8 +936,10 @@ static void s6e8aa0_power_on(struct mipi_dsim_lcd_device *dsim_dev,
lcd->ddi_pd->reset(lcd->ld);
mdelay(5);
- } else
- s6e8aa0_regulator_disable(lcd);
+ } else {
+ /* lcd power off */
+ s6e8aa0_regulator_ctl(lcd, false);
+ }
}
@@ -924,10 +1049,14 @@ static int s6e8aa0_write_reg(struct s6e8aa0 *lcd, char *name)
return ret;
}
- if (fw->size < 2)
+ if (fw->size == 1)
ret = ops->cmd_write(lcd_to_master(lcd),
MIPI_DSI_DCS_SHORT_WRITE,
- (unsigned int)fw->data, fw->size);
+ (unsigned int)fw->data[0], 0);
+ else if (fw->size == 2)
+ ret = ops->cmd_write(lcd_to_master(lcd),
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM,
+ (unsigned int)fw->data[0], fw->data[1]);
else
ret = ops->cmd_write(lcd_to_master(lcd),
MIPI_DSI_DCS_LONG_WRITE,
@@ -1017,11 +1146,38 @@ static struct panel_model s6e8aa0_model[] = {
.ver = VER_32, /* MACH_SLP_PQ M0 B-Type */
.name = "SMD_AMS480GYXX-0",
}, {
+ .ver = VER_96, /* MACH_SLP_PQ Galaxy S3 */
+ .name = "SMD_AMS480GYXX-0",
+ }, {
.ver = VER_210, /* MACH_SLP_PQ M0 A-Type */
.name = "SMD_AMS465GS0x",
}
};
+#if defined(CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ) || defined(CONFIG_DISPFREQ_OPP)
+static int s6e8aa0_notifier_callback(struct notifier_block *this,
+ unsigned long event, void *_data)
+{
+ struct s6e8aa0 *lcd = container_of(this, struct s6e8aa0, nb_disp);
+
+ if (lcd->power == FB_BLANK_POWERDOWN)
+ return NOTIFY_DONE;
+
+ switch (event) {
+ case EXYNOS4_DISPLAY_LV_HF:
+ s6e8aa0_panel_cond(lcd, 1);
+ break;
+ case EXYNOS4_DISPLAY_LV_LF:
+ s6e8aa0_panel_cond(lcd, 0);
+ break;
+ default:
+ return NOTIFY_BAD;
+ }
+
+ return NOTIFY_DONE;
+}
+#endif
+
static int s6e8aa0_probe(struct mipi_dsim_lcd_device *dsim_dev)
{
struct s6e8aa0 *lcd;
@@ -1072,9 +1228,20 @@ static int s6e8aa0_probe(struct mipi_dsim_lcd_device *dsim_dev)
goto err_unregister_lcd;
}
+ if (lcd->ddi_pd)
+ lcd->property = lcd->ddi_pd->pdata;
+
+#if defined(CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ) || defined(CONFIG_DISPFREQ_OPP)
+ if (lcd->property && lcd->property->dynamic_refresh) {
+ lcd->nb_disp.notifier_call = s6e8aa0_notifier_callback;
+ ret = exynos4_display_register_client(&lcd->nb_disp);
+ if (ret < 0)
+ dev_warn(&lcd->ld->dev, "failed to register exynos-display notifier\n");
+ }
+#endif
+
lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
lcd->bd->props.brightness = MAX_BRIGHTNESS;
-
lcd->acl_enable = 1;
lcd->cur_acl = 0;
lcd->model = s6e8aa0_model;
@@ -1090,11 +1257,9 @@ static int s6e8aa0_probe(struct mipi_dsim_lcd_device *dsim_dev)
dev_set_drvdata(&dsim_dev->dev, lcd);
- s6e8aa0_regulator_enable(lcd);
+ s6e8aa0_regulator_ctl(lcd, true);
lcd->power = FB_BLANK_UNBLANK;
- lcd_global = lcd;
-
dev_info(lcd->dev, "probed s6e8aa0 panel driver(%s).\n",
dev_name(&lcd->ld->dev));
@@ -1121,9 +1286,13 @@ static void s6e8aa0_remove(struct mipi_dsim_lcd_device *dsim_dev)
lcd_device_unregister(lcd->ld);
regulator_put(lcd->reg_vci);
-
regulator_put(lcd->reg_vdd3);
+#if defined(CONFIG_ARM_EXYNOS4_DISPLAY_DEVFREQ) || defined(CONFIG_DISPFREQ_OPP)
+ if (lcd->property && lcd->property->dynamic_refresh)
+ exynos4_display_unregister_client(&lcd->nb_disp);
+#endif
+
kfree(lcd);
}
@@ -1183,5 +1352,7 @@ module_exit(s6e8aa0_exit);
MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
+MODULE_AUTHOR("Joongmock Shin <jmock.shin@samsung.com>");
+MODULE_AUTHOR("Eunchul Kim <chulspro.kim@samsung.com>");
MODULE_DESCRIPTION("MIPI-DSI based s6e8aa0 AMOLED LCD Panel Driver");
MODULE_LICENSE("GPL");