Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tilcdc: panel: Add support for enable GPIO

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>

authored by

Ezequiel Garcia and committed by
Dave Airlie
d898ce03 12778fc1

+34 -5
+2
Documentation/devicetree/bindings/drm/tilcdc/panel.txt
··· 20 20 21 21 Optional properties: 22 22 - backlight: phandle of the backlight device attached to the panel 23 + - enable-gpios: GPIO pin to enable or disable the panel 23 24 24 25 Recommended properties: 25 26 - pinctrl-names, pinctrl-0: the pincontrol settings to configure ··· 34 33 pinctrl-names = "default"; 35 34 pinctrl-0 = <&bone_lcd3_cape_lcd_pins>; 36 35 backlight = <&backlight>; 36 + enable-gpios = <&gpio3 19 0>; 37 37 38 38 panel-info { 39 39 ac-bias = <255>;
+32 -5
drivers/gpu/drm/tilcdc/tilcdc_panel.c
··· 18 18 #include <linux/pinctrl/pinmux.h> 19 19 #include <linux/pinctrl/consumer.h> 20 20 #include <linux/backlight.h> 21 + #include <linux/gpio/consumer.h> 21 22 #include <video/display_timing.h> 22 23 #include <video/of_display_timing.h> 23 24 #include <video/videomode.h> ··· 30 29 struct tilcdc_panel_info *info; 31 30 struct display_timings *timings; 32 31 struct backlight_device *backlight; 32 + struct gpio_desc *enable_gpio; 33 33 }; 34 34 #define to_panel_module(x) container_of(x, struct panel_module, base) 35 35 ··· 57 55 { 58 56 struct panel_encoder *panel_encoder = to_panel_encoder(encoder); 59 57 struct backlight_device *backlight = panel_encoder->mod->backlight; 58 + struct gpio_desc *gpio = panel_encoder->mod->enable_gpio; 60 59 61 - if (!backlight) 62 - return; 60 + if (backlight) { 61 + backlight->props.power = mode == DRM_MODE_DPMS_ON ? 62 + FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 63 + backlight_update_status(backlight); 64 + } 63 65 64 - backlight->props.power = mode == DRM_MODE_DPMS_ON 65 - ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 66 - backlight_update_status(backlight); 66 + if (gpio) 67 + gpiod_set_value_cansleep(gpio, 68 + mode == DRM_MODE_DPMS_ON ? 1 : 0); 67 69 } 68 70 69 71 static bool panel_encoder_mode_fixup(struct drm_encoder *encoder, ··· 375 369 dev_info(&pdev->dev, "found backlight\n"); 376 370 } 377 371 372 + panel_mod->enable_gpio = devm_gpiod_get(&pdev->dev, "enable"); 373 + if (IS_ERR(panel_mod->enable_gpio)) { 374 + ret = PTR_ERR(panel_mod->enable_gpio); 375 + if (ret != -ENOENT) { 376 + dev_err(&pdev->dev, "failed to request enable GPIO\n"); 377 + goto fail_backlight; 378 + } 379 + 380 + /* Optional GPIO is not here, continue silently. */ 381 + panel_mod->enable_gpio = NULL; 382 + } else { 383 + ret = gpiod_direction_output(panel_mod->enable_gpio, 0); 384 + if (ret < 0) { 385 + dev_err(&pdev->dev, "failed to setup GPIO\n"); 386 + goto fail_backlight; 387 + } 388 + dev_info(&pdev->dev, "found enable GPIO\n"); 389 + } 390 + 378 391 mod = &panel_mod->base; 379 392 pdev->dev.platform_data = mod; 380 393 ··· 426 401 427 402 fail_free: 428 403 tilcdc_module_cleanup(mod); 404 + 405 + fail_backlight: 429 406 if (panel_mod->backlight) 430 407 put_device(&panel_mod->backlight->dev); 431 408 return ret;