From 41f27c5716411e914a2fb8e7f843eef2d318dab6 Mon Sep 17 00:00:00 2001 From: Yahui Wang Date: Tue, 23 May 2017 09:21:41 +0800 Subject: [PATCH] msm: mdss: control avdd enable gpio when doing panel reset Avdd enable gpio maybe used for AMOLED panel to control avdd output. This gpio should be enabled/disabled when panel does unblank/blank once to avoid panel electric leakage. Change-Id: I18f0f6491f0ff97df5556e74a686a18b262708df Signed-off-by: Yahui Wang --- .../devicetree/bindings/fb/mdss-dsi.txt | 4 ++- drivers/video/fbdev/msm/mdss_dsi.c | 9 +++++ drivers/video/fbdev/msm/mdss_dsi.h | 2 ++ drivers/video/fbdev/msm/mdss_dsi_panel.c | 35 +++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt index 0d55389f3790..f28de379f84c 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt @@ -105,7 +105,9 @@ Optional properties: - qcom,platform-reset-gpio: Specifies the panel reset gpio. - qcom,platform-te-gpio: Specifies the gpio used for TE. - qcom,platform-bklight-en-gpio: Specifies the gpio used to enable display back-light -- qcom,platform-bklight-en-gpio-invert: Invert the gpio used to enable display back-light +- qcom,platform-bklight-en-gpio-invert: Boolean to invert the gpio used to enable display back-light +- qcom,platform-avdd-en-gpio: Specifies the gpio used to enable AMOLED AVDD +- qcom,platform-avdd-en-gpio-invert: Boolean to invert the gpio used to enable AMOLED AVDD - qcom,panel-mode-gpio: Specifies the GPIO to select video/command/single-port/dual-port mode of panel through gpio when it supports these modes. - pinctrl-names: List of names to assign mdss pin states defined in pinctrl device node diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index c7cac996e5c0..f4bbf8eeef11 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -4267,6 +4267,15 @@ static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev, of_property_read_bool(ctrl_pdev->dev.of_node, "qcom,platform-bklight-en-gpio-invert"); + ctrl_pdata->avdd_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, + "qcom,platform-avdd-en-gpio", 0); + if (!gpio_is_valid(ctrl_pdata->avdd_en_gpio)) + pr_info("%s: avdd_en gpio not specified\n", __func__); + + ctrl_pdata->avdd_en_gpio_invert = + of_property_read_bool(ctrl_pdev->dev.of_node, + "qcom,platform-avdd-en-gpio-invert"); + ctrl_pdata->rst_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-reset-gpio", 0); if (!gpio_is_valid(ctrl_pdata->rst_gpio)) diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 62d88f0af652..7fabd4944cbd 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -455,6 +455,8 @@ struct mdss_dsi_ctrl_pdata { int bklt_en_gpio; bool bklt_en_gpio_invert; bool bklt_en_gpio_state; + int avdd_en_gpio; + bool avdd_en_gpio_invert; 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 60012c71449c..695dbfa95e29 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -260,6 +260,15 @@ static int mdss_dsi_request_gpios(struct mdss_dsi_ctrl_pdata *ctrl_pdata) rc); goto rst_gpio_err; } + if (gpio_is_valid(ctrl_pdata->avdd_en_gpio)) { + rc = gpio_request(ctrl_pdata->avdd_en_gpio, + "avdd_enable"); + if (rc) { + pr_err("request avdd_en gpio failed, rc=%d\n", + rc); + goto avdd_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) { @@ -272,6 +281,9 @@ 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->avdd_en_gpio)) + gpio_free(ctrl_pdata->avdd_en_gpio); +avdd_en_gpio_err: gpio_free(ctrl_pdata->rst_gpio); rst_gpio_err: if (gpio_is_valid(ctrl_pdata->disp_en_gpio)) @@ -424,6 +436,21 @@ 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->avdd_en_gpio)) { + if (ctrl_pdata->avdd_en_gpio_invert) { + rc = gpio_direction_output( + ctrl_pdata->avdd_en_gpio, 0); + } else { + rc = gpio_direction_output( + ctrl_pdata->avdd_en_gpio, 1); + } + if (rc) { + pr_err("%s: unable to set dir for avdd_en gpio\n", + __func__); + goto exit; + } + } } if (gpio_is_valid(ctrl_pdata->lcd_mode_sel_gpio)) { @@ -452,6 +479,14 @@ 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->avdd_en_gpio)) { + if (ctrl_pdata->avdd_en_gpio_invert) + gpio_set_value((ctrl_pdata->avdd_en_gpio), 1); + else + gpio_set_value((ctrl_pdata->avdd_en_gpio), 0); + + gpio_free(ctrl_pdata->avdd_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);