diff options
-rw-r--r-- | drivers/video/fbdev/Kconfig | 4 | ||||
-rw-r--r-- | drivers/video/fbdev/amba-clcd.c | 40 | ||||
-rw-r--r-- | include/linux/amba/clcd.h | 3 |
3 files changed, 46 insertions, 1 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 88b008fb8a4e..9b9a76b82c04 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -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 diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 9b158869cb89..52a33d3926ac 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -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; diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h index e82e3ee2c54a..e64c1ccebb76 100644 --- a/include/linux/amba/clcd.h +++ b/include/linux/amba/clcd.h @@ -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 { |