drm/tilcdc: panel: Add support for enable GPIO
authorEzequiel Garcia <ezequiel@vanguardiasur.com.ar>
Tue, 2 Sep 2014 12:51:22 +0000 (09:51 -0300)
committerDave Airlie <airlied@redhat.com>
Wed, 17 Sep 2014 00:55:27 +0000 (10:55 +1000)
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.

Tested-by: Darren Etheridge <detheridge@ti.com>
Tested-by: Johannes Pointner <johannes.pointner@br-automation.com>
Signed-off-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Documentation/devicetree/bindings/drm/tilcdc/panel.txt
drivers/gpu/drm/tilcdc/tilcdc_panel.c

index 10a06e826b4abd8c5d720cc59aafda285c91800e..4ab9e230090793b4fc11519ed00494f9fad93e1b 100644 (file)
@@ -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>;
index f2a5b23782fabef8d7232af864191fb6a6fe2039..7a0315855e90130d5eaa2f00e76750e59a68853f 100644 (file)
@@ -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;