From 0bb0cad9b6cf556b4202293545d78f8e68e23b5d Mon Sep 17 00:00:00 2001 From: Ashish Garg Date: Tue, 11 Apr 2017 12:19:38 +0530 Subject: [PATCH] msm: mdss: enable backlight gpio after commit is done Backlight gpio was enabled during panel power on. So backlight was turned on before commit was sent to the panel. Ensure backlight gpio is enabled only after the backlight level is set. Change-Id: I30a0a0cfc1c07761ae2b2bea8424d79e7e22ec42 Signed-off-by: Ashish Garg --- drivers/video/fbdev/msm/mdss_dsi.c | 3 + drivers/video/fbdev/msm/mdss_dsi.h | 1 + drivers/video/fbdev/msm/mdss_dsi_panel.c | 120 +++++++++++++++-------- 3 files changed, 82 insertions(+), 42 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 17722eac3006..2a559a70eed7 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -4269,6 +4269,9 @@ int dsi_panel_device_register(struct platform_device *ctrl_pdev, return rc; } + /* default state of gpio is false */ + ctrl_pdata->bklt_en_gpio_state = false; + pinfo->panel_max_fps = mdss_panel_get_framerate(pinfo); pinfo->panel_max_vtotal = mdss_panel_get_vtotal(pinfo); diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 2a76466abf3e..027156079573 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -452,6 +452,7 @@ struct mdss_dsi_ctrl_pdata { int disp_en_gpio; int bklt_en_gpio; bool bklt_en_gpio_invert; + bool bklt_en_gpio_state; int lcd_mode_sel_gpio; int bklt_ctrl; /* backlight ctrl */ bool pwm_pmi; diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 9faa1531c256..60012c71449c 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -260,16 +260,6 @@ static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) rc); goto rst_gpio_err; } - if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { - rc = gpio_request(ctrl_pdata->bklt_en_gpio, - "bklt_enable"); - if (rc) { - pr_err("request bklt gpio failed, rc=%d\n", - rc); - goto bklt_en_gpio_err; - } - } - if (gpio_is_valid(ctrl_pdata->lcd_mode_sel_gpio)) { rc = gpio_request(ctrl_pdata->lcd_mode_sel_gpio, "mode_sel"); if (rc) { @@ -282,9 +272,6 @@ static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) return rc; lcd_mode_sel_gpio_err: - if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) - gpio_free(ctrl_pdata->bklt_en_gpio); -bklt_en_gpio_err: gpio_free(ctrl_pdata->rst_gpio); rst_gpio_err: if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) @@ -293,6 +280,81 @@ disp_en_gpio_err: return rc; } +int mdss_dsi_bl_gpio_ctrl(struct mdss_panel_data *pdata, int enable) +{ + struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + int rc = 0, val = 0; + + if (pdata == NULL) { + pr_err("%s: Invalid input data\n", __func__); + return -EINVAL; + } + + ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, + panel_data); + if (ctrl_pdata == NULL) { + pr_err("%s: Invalid ctrl data\n", __func__); + return -EINVAL; + } + + /* if gpio is not valid */ + if (!gpio_is_valid(ctrl_pdata->bklt_en_gpio)) + return rc; + + pr_debug("%s: enable = %d\n", __func__, enable); + + /* + * if gpio state is false and enable (bl level) is + * non zero then toggle the gpio + */ + if (!ctrl_pdata->bklt_en_gpio_state && enable) { + rc = gpio_request(ctrl_pdata->bklt_en_gpio, "bklt_enable"); + if (rc) { + pr_err("request bklt gpio failed, rc=%d\n", rc); + goto free; + } + + if (ctrl_pdata->bklt_en_gpio_invert) + val = 0; + else + val = 1; + + rc = gpio_direction_output(ctrl_pdata->bklt_en_gpio, val); + if (rc) { + pr_err("%s: unable to set dir for bklt gpio val %d\n", + __func__, val); + goto free; + } + ctrl_pdata->bklt_en_gpio_state = true; + goto ret; + } else if (ctrl_pdata->bklt_en_gpio_state && !enable) { + /* + * if gpio state is true and enable (bl level) is + * zero then toggle the gpio + */ + if (ctrl_pdata->bklt_en_gpio_invert) + val = 1; + else + val = 0; + + rc = gpio_direction_output(ctrl_pdata->bklt_en_gpio, val); + if (rc) + pr_err("%s: unable to set dir for bklt gpio val %d\n", + __func__, val); + goto free; + } + + /* gpio state is true and bl level is non zero */ + goto ret; + +free: + pr_debug("%s: free bklt gpio\n", __func__); + ctrl_pdata->bklt_en_gpio_state = false; + gpio_free(ctrl_pdata->bklt_en_gpio); +ret: + return rc; +} + int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) { struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; @@ -362,26 +424,6 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) if (pdata->panel_info.rst_seq[++i]) usleep_range(pinfo->rst_seq[i] * 1000, pinfo->rst_seq[i] * 1000); } - - if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { - - if (ctrl_pdata->bklt_en_gpio_invert) { - rc = gpio_direction_output( - ctrl_pdata->bklt_en_gpio, 0); - gpio_set_value( - (ctrl_pdata->bklt_en_gpio), 0); - } else { - rc = gpio_direction_output( - ctrl_pdata->bklt_en_gpio, 1); - gpio_set_value( - (ctrl_pdata->bklt_en_gpio), 1); - } - if (rc) { - pr_err("%s: unable to set dir for bklt gpio\n", - __func__); - goto exit; - } - } } if (gpio_is_valid(ctrl_pdata->lcd_mode_sel_gpio)) { @@ -410,15 +452,6 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) pr_debug("%s: Reset panel done\n", __func__); } } else { - if (gpio_is_valid(ctrl_pdata->bklt_en_gpio)) { - - if (ctrl_pdata->bklt_en_gpio_invert) - gpio_set_value((ctrl_pdata->bklt_en_gpio), 1); - else - gpio_set_value((ctrl_pdata->bklt_en_gpio), 0); - - gpio_free(ctrl_pdata->bklt_en_gpio); - } if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) { gpio_set_value((ctrl_pdata->disp_en_gpio), 0); gpio_free(ctrl_pdata->disp_en_gpio); @@ -801,6 +834,9 @@ static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, if ((bl_level < pdata->panel_info.bl_min) && (bl_level != 0)) bl_level = pdata->panel_info.bl_min; + /* enable the backlight gpio if present */ + mdss_dsi_bl_gpio_ctrl(pdata, bl_level); + switch (ctrl_pdata->bklt_ctrl) { case BL_WLED: led_trigger_event(bl_led_trigger, bl_level);