diff mbox

[8/8] drm/tilcdc: panel: Add support for enable GPIO

Message ID 1405088334-11215-9-git-send-email-ezequiel@vanguardiasur.com.ar (mailing list archive)
State New, archived
Headers show

Commit Message

Ezequiel Garcia July 11, 2014, 2:18 p.m. UTC
In order to support the "enable GPIO" available in many panel devices,
this commit adds a proper devicetree binding.

By providing an enable GPIO in the devicetree, the driver can now turn
off and on the panel device, and/or the backlight device. Both the
backlight and the GPIO are optional properties.

Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
---
 .../devicetree/bindings/drm/tilcdc/panel.txt       |  2 ++
 drivers/gpu/drm/tilcdc/tilcdc_panel.c              | 37 +++++++++++++++++++---
 2 files changed, 34 insertions(+), 5 deletions(-)

Comments

Ezequiel Garcia July 11, 2014, 5:38 p.m. UTC | #1
Hello Fabio,

On 11 Jul 12:08 PM, Fabio Estevam wrote:
> On Fri, Jul 11, 2014 at 11:18 AM, Ezequiel Garcia
> <ezequiel@vanguardiasur.com.ar> wrote:
> > In order to support the "enable GPIO" available in many panel devices,
> > this commit adds a proper devicetree binding.
> >
> > By providing an enable GPIO in the devicetree, the driver can now turn
> > off and on the panel device, and/or the backlight device. Both the
> > backlight and the GPIO are optional properties.
> > +       panel_mod->enable_gpio = devm_gpiod_get(&pdev->dev, "enable");
> > +       if (IS_ERR(panel_mod->enable_gpio)) {
> > +               ret = PTR_ERR(panel_mod->enable_gpio);
> > +               if (ret != -ENOENT) {
> 
> Shouldn't this be controlled by a regulator instead? What if the panel
> is powered from a PMIC output?

I'm not sure I understand how is that related. I have a New Heaven LCD panel
(NHD-4.3-480272EF-ATXL#-T) and it has a signal called "Display On/Off" that
I'm using to enable and disable the panel from a GPIO.

This is useful when switching the output from the panel to the HDMI for
instance, and turn off the display panel when the output goes to the HDMI.

Probably I'm missing something, I can't really see how regulators fit here.

Thanks!
diff mbox

Patch

diff --git a/Documentation/devicetree/bindings/drm/tilcdc/panel.txt b/Documentation/devicetree/bindings/drm/tilcdc/panel.txt
index 10a06e8..4ab9e23 100644
--- a/Documentation/devicetree/bindings/drm/tilcdc/panel.txt
+++ b/Documentation/devicetree/bindings/drm/tilcdc/panel.txt
@@ -20,6 +20,7 @@  Required properties:
 
 Optional properties:
 - backlight: phandle of the backlight device attached to the panel
+- enable-gpios: GPIO pin to enable or disable the panel
 
 Recommended properties:
  - pinctrl-names, pinctrl-0: the pincontrol settings to configure
@@ -33,6 +34,7 @@  Example:
 		pinctrl-names = "default";
 		pinctrl-0 = <&bone_lcd3_cape_lcd_pins>;
 		backlight = <&backlight>;
+		enable-gpios = <&gpio3 19 0>;
 
 		panel-info {
 			ac-bias           = <255>;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
index f2a5b23..7a03158 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c
@@ -18,6 +18,7 @@ 
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/backlight.h>
+#include <linux/gpio/consumer.h>
 #include <video/display_timing.h>
 #include <video/of_display_timing.h>
 #include <video/videomode.h>
@@ -29,6 +30,7 @@  struct panel_module {
 	struct tilcdc_panel_info *info;
 	struct display_timings *timings;
 	struct backlight_device *backlight;
+	struct gpio_desc *enable_gpio;
 };
 #define to_panel_module(x) container_of(x, struct panel_module, base)
 
@@ -55,13 +57,17 @@  static void panel_encoder_dpms(struct drm_encoder *encoder, int mode)
 {
 	struct panel_encoder *panel_encoder = to_panel_encoder(encoder);
 	struct backlight_device *backlight = panel_encoder->mod->backlight;
+	struct gpio_desc *gpio = panel_encoder->mod->enable_gpio;
 
-	if (!backlight)
-		return;
+	if (backlight) {
+		backlight->props.power = mode == DRM_MODE_DPMS_ON ?
+					 FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+		backlight_update_status(backlight);
+	}
 
-	backlight->props.power = mode == DRM_MODE_DPMS_ON
-				     ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
-	backlight_update_status(backlight);
+	if (gpio)
+		gpiod_set_value_cansleep(gpio,
+					 mode == DRM_MODE_DPMS_ON ? 1 : 0);
 }
 
 static bool panel_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -369,6 +375,25 @@  static int panel_probe(struct platform_device *pdev)
 		dev_info(&pdev->dev, "found backlight\n");
 	}
 
+	panel_mod->enable_gpio = devm_gpiod_get(&pdev->dev, "enable");
+	if (IS_ERR(panel_mod->enable_gpio)) {
+		ret = PTR_ERR(panel_mod->enable_gpio);
+		if (ret != -ENOENT) {
+			dev_err(&pdev->dev, "failed to request enable GPIO\n");
+			goto fail_backlight;
+		}
+
+		/* Optional GPIO is not here, continue silently. */
+		panel_mod->enable_gpio = NULL;
+	} else {
+		ret = gpiod_direction_output(panel_mod->enable_gpio, 0);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to setup GPIO\n");
+			goto fail_backlight;
+		}
+		dev_info(&pdev->dev, "found enable GPIO\n");
+	}
+
 	mod = &panel_mod->base;
 	pdev->dev.platform_data = mod;
 
@@ -401,6 +426,8 @@  fail_timings:
 
 fail_free:
 	tilcdc_module_cleanup(mod);
+
+fail_backlight:
 	if (panel_mod->backlight)
 		put_device(&panel_mod->backlight->dev);
 	return ret;