video: ARM CLCD: backlight support for OF
authorLinus Walleij <linus.walleij@linaro.org>
Thu, 16 Jun 2016 09:36:13 +0000 (11:36 +0200)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Thu, 11 Aug 2016 14:54:52 +0000 (17:54 +0300)
If the device is probed from device tree, we can support
backlight. This is used with some systems such as the
ST Microelectronics Nomadik.

We have to add HAS_IOMEM to the dependencies of CLCD since
the backlight class device will now be selected, and if it
gets selected on an arch that does not have IOMEM,
compilation will fail.

Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/video/fbdev/Kconfig
drivers/video/fbdev/amba-clcd.c
include/linux/amba/clcd.h

index 88b008f..9b9a76b 100644 (file)
@@ -284,12 +284,14 @@ config FB_PM2_FIFO_DISCONNECT
 config FB_ARMCLCD
        tristate "ARM PrimeCell PL110 support"
        depends on ARM || ARM64 || COMPILE_TEST
-       depends on FB && ARM_AMBA
+       depends on FB && ARM_AMBA && HAS_IOMEM
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        select FB_MODE_HELPERS if OF
        select VIDEOMODE_HELPERS if OF
+       select BACKLIGHT_LCD_SUPPORT if OF
+       select BACKLIGHT_CLASS_DEVICE if OF
        help
          This framebuffer device driver is for the ARM PrimeCell PL110
          Colour LCD controller.  ARM PrimeCells provide the building
index 9b15886..52a33d3 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_graph.h>
+#include <linux/backlight.h>
 #include <video/display_timing.h>
 #include <video/of_display_timing.h>
 #include <video/videomode.h>
@@ -71,6 +72,11 @@ static void clcdfb_disable(struct clcd_fb *fb)
        if (fb->board->disable)
                fb->board->disable(fb);
 
+       if (fb->panel->backlight) {
+               fb->panel->backlight->props.power = FB_BLANK_POWERDOWN;
+               backlight_update_status(fb->panel->backlight);
+       }
+
        val = readl(fb->regs + fb->off_cntl);
        if (val & CNTL_LCDPWR) {
                val &= ~CNTL_LCDPWR;
@@ -117,6 +123,14 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
        writel(cntl, fb->regs + fb->off_cntl);
 
        /*
+        * Turn on backlight
+        */
+       if (fb->panel->backlight) {
+               fb->panel->backlight->props.power = FB_BLANK_UNBLANK;
+               backlight_update_status(fb->panel->backlight);
+       }
+
+       /*
         * finally, enable the interface.
         */
        if (fb->board->enable)
@@ -576,6 +590,28 @@ static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
                        mode->refresh);
 }
 
+static int clcdfb_of_get_backlight(struct device_node *endpoint,
+                                  struct clcd_panel *clcd_panel)
+{
+       struct device_node *panel;
+       struct device_node *backlight;
+
+       panel = of_graph_get_remote_port_parent(endpoint);
+       if (!panel)
+               return -ENODEV;
+
+       /* Look up the optional backlight phandle */
+       backlight = of_parse_phandle(panel, "backlight", 0);
+       if (backlight) {
+               clcd_panel->backlight = of_find_backlight_by_node(backlight);
+               of_node_put(backlight);
+
+               if (!clcd_panel->backlight)
+                       return -EPROBE_DEFER;
+       }
+       return 0;
+}
+
 static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
                struct fb_videomode *mode)
 {
@@ -662,6 +698,10 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
        if (!endpoint)
                return -ENODEV;
 
+       err = clcdfb_of_get_backlight(endpoint, fb->panel);
+       if (err)
+               return err;
+
        err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
        if (err)
                return err;
index e82e3ee..e64c1cc 100644 (file)
@@ -93,6 +93,8 @@ enum {
        CLCD_CAP_ALL            = CLCD_CAP_BGR | CLCD_CAP_RGB,
 };
 
+struct backlight_device;
+
 struct clcd_panel {
        struct fb_videomode     mode;
        signed short            width;  /* width in mm */
@@ -105,6 +107,7 @@ struct clcd_panel {
                                fixedtimings:1,
                                grayscale:1;
        unsigned int            connector;
+       struct backlight_device *backlight;
 };
 
 struct clcd_regs {