diff options
Diffstat (limited to 'drivers/video/omap2/displays')
-rw-r--r-- | drivers/video/omap2/displays/panel-s6e8aa0.c | 81 |
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, |