aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorMarty Fouts <mfouts@sta.samsung.com>2011-09-21 14:58:22 -0700
committerArve Hjønnevåg <arve@android.com>2011-09-22 20:46:47 -0700
commit54b2f802c3327d586961f482a34bda6f7d3b7d4f (patch)
treedb8c33cd2b8a99bb1c6e148dd8b6c4362b380339 /drivers/video
parent147679e0d8551adcaee94a91ade23c86d8ff1a4a (diff)
downloadkernel_samsung_tuna-54b2f802c3327d586961f482a34bda6f7d3b7d4f.zip
kernel_samsung_tuna-54b2f802c3327d586961f482a34bda6f7d3b7d4f.tar.gz
kernel_samsung_tuna-54b2f802c3327d586961f482a34bda6f7d3b7d4f.tar.bz2
OMAP: DSS: panel-s6e8aa0: Add smart dynamic elvss setting function.
change list. -. It is for reduce lcd power consumption. -. new panel only support this functionality. Change-Id: Ib7aa24d20bea6fbda5477ffcc9160b97e4aacff5 Signed-off-by: Marty Fouts <mfouts@sta.samsung.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/displays/panel-s6e8aa0.c81
1 files changed, 70 insertions, 11 deletions
diff --git a/drivers/video/omap2/displays/panel-s6e8aa0.c b/drivers/video/omap2/displays/panel-s6e8aa0.c
index 1c905fc..ca80d39 100644
--- a/drivers/video/omap2/displays/panel-s6e8aa0.c
+++ b/drivers/video/omap2/displays/panel-s6e8aa0.c
@@ -167,6 +167,8 @@ struct s6e8aa0_data {
unsigned int acl_cur;
bool acl_enable;
+ unsigned int elvss_cur_i;
+ u8 panel_id[3];
};
const u8 s6e8aa0_mtp_unlock[] = {
@@ -808,7 +810,7 @@ static void s6e8aa0_setup_gamma_regs(struct s6e8aa0_data *s6, u8 gamma_regs[],
}
}
-static int s6e8aa0_update_acl_set(struct omap_dss_device *dssdev)
+static void s6e8aa0_update_acl_set(struct omap_dss_device *dssdev)
{
struct s6e8aa0_data *s6 = dev_get_drvdata(&dssdev->dev);
struct panel_s6e8aa0_data *pdata = s6->pdata;
@@ -819,7 +821,7 @@ static int s6e8aa0_update_acl_set(struct omap_dss_device *dssdev)
/* Quietly return if you don't have a table */
if (!pdata->acl_table_size)
- return 0;
+ return;
max_cd = pdata->acl_table[pdata->acl_table_size - 1].cd;
@@ -851,13 +853,54 @@ static int s6e8aa0_update_acl_set(struct omap_dss_device *dssdev)
}
pr_debug("%s : cur_acl=%d, %d\n", __func__, s6->acl_cur,
s6->acl_enable);
- return 0;
+ return;
+}
+
+static void s6e8aa0_update_elvss(struct omap_dss_device *dssdev)
+{
+ struct s6e8aa0_data *s6 = dev_get_drvdata(&dssdev->dev);
+ struct panel_s6e8aa0_data *pdata = s6->pdata;
+ u8 elvss_cmd[3];
+ u8 elvss;
+ u8 limit = 0x9F;
+ unsigned int i;
+ unsigned int cd;
+ unsigned int max_cd = 0;
+
+ if (!pdata->elvss_table_size)
+ return;
+
+ elvss_cmd[0] = 0xB1;
+ elvss_cmd[1] = 0x04;
+
+ max_cd = pdata->elvss_table[pdata->elvss_table_size - 1].cd;
+ cd = s6->bl * max_cd / 255;
+
+ for (i = 0; i < pdata->elvss_table_size - 1; i++)
+ if (cd <= pdata->elvss_table[i].cd)
+ break;
+
+ if (i == s6->elvss_cur_i)
+ return;
+
+ s6->elvss_cur_i = i;
+
+ elvss = s6->panel_id[2] + pdata->elvss_table[i].elvss_val;
+
+ if (elvss > limit)
+ elvss = limit;
+
+ elvss_cmd[2] = elvss;
+
+ s6e8aa0_write_block(dssdev, elvss_cmd, sizeof(elvss_cmd));
+ pr_debug("%s - brightness : %d, cd : %d, elvss : %02x\n",
+ __func__, s6->bl, cd, elvss);
+ return;
}
static int s6e8aa0_update_brightness(struct omap_dss_device *dssdev)
{
struct s6e8aa0_data *s6 = dev_get_drvdata(&dssdev->dev);
- int ret = 0;
u8 gamma_regs[NUM_GAMMA_REGS + 2];
u8 dy_regs[3][NUM_DY_REGS + 1];
@@ -874,12 +917,9 @@ static int s6e8aa0_update_brightness(struct omap_dss_device *dssdev)
s6e8aa0_write_block_nosync(dssdev, dy_regs[2], sizeof(dy_regs[2]));
s6e8aa0_write_reg(dssdev, 0xF7, 0x01);
- ret = s6e8aa0_update_acl_set(dssdev);
- if (ret != 0) {
- pr_err("%s - s6e8aa0_update_acl_set() failed\n", __func__);
- return -1;
- }
- return ret;
+ s6e8aa0_update_acl_set(dssdev);
+ s6e8aa0_update_elvss(dssdev);
+ return 0;
}
static u64 s6e8aa0_voltage_lookup(struct s6e8aa0_data *s6, int c, u32 v)
@@ -1087,6 +1127,22 @@ static int mtp_reg_index(int c, int i)
return c * (V_COUNT + 1) + i;
}
+static void s6e8aa0_read_id_info(struct s6e8aa0_data *s6)
+{
+ struct omap_dss_device *dssdev = s6->dssdev;
+ int ret;
+ u8 cmd = 0xD1;
+
+ dsi_vc_set_max_rx_packet_size(dssdev, 1, 3);
+ ret = s6e8aa0_read_block(dssdev, cmd, s6->panel_id,
+ ARRAY_SIZE(s6->panel_id));
+ dsi_vc_set_max_rx_packet_size(dssdev, 1, 1);
+ if (ret < 0) {
+ pr_err("%s: Failed to read id data\n", __func__);
+ return;
+ }
+}
+
static void s6e8aa0_read_mtp_info(struct s6e8aa0_data *s6, int b)
{
int ret;
@@ -1503,6 +1559,7 @@ static int s6e8aa0_probe(struct omap_dss_device *dssdev)
s6->acl_enable = true;
s6->acl_cur = 0;
+ s6->elvss_cur_i = ~0;
ret = device_create_file(&dssdev->dev, &dev_attr_acl_set);
if (ret < 0) {
@@ -1545,6 +1602,7 @@ static void s6e8aa0_config(struct omap_dss_device *dssdev)
struct s6e8aa0_data *s6 = dev_get_drvdata(&dssdev->dev);
struct panel_s6e8aa0_data *pdata = s6->pdata;
if (!s6->brightness_table) {
+ s6e8aa0_read_id_info(s6);
s6e8aa0_read_mtp_info(s6, 0);
s6e8aa0_read_mtp_info(s6, 1);
s6e8aa0_adjust_brightness_from_mtp(s6);
@@ -1553,7 +1611,8 @@ static void s6e8aa0_config(struct omap_dss_device *dssdev)
s6e8aa0_write_sequence(dssdev, pdata->seq_display_set,
pdata->seq_display_set_size);
- s6->acl_cur = 0; /* make sure acl table gets written */
+ s6->acl_cur = 0; /* make sure acl table and elvss value gets written */
+ s6->elvss_cur_i = ~0;
s6e8aa0_update_brightness(dssdev);
s6e8aa0_write_sequence(dssdev, pdata->seq_etc_set,