Commit c38162be authored by Linus Walleij's avatar Linus Walleij Committed by Tomi Valkeinen

video: ARM CLCD: backlight support for OF

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: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 1d1e56f4
...@@ -284,12 +284,14 @@ config FB_PM2_FIFO_DISCONNECT ...@@ -284,12 +284,14 @@ config FB_PM2_FIFO_DISCONNECT
config FB_ARMCLCD config FB_ARMCLCD
tristate "ARM PrimeCell PL110 support" tristate "ARM PrimeCell PL110 support"
depends on ARM || ARM64 || COMPILE_TEST 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_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
select FB_MODE_HELPERS if OF select FB_MODE_HELPERS if OF
select VIDEOMODE_HELPERS if OF select VIDEOMODE_HELPERS if OF
select BACKLIGHT_LCD_SUPPORT if OF
select BACKLIGHT_CLASS_DEVICE if OF
help help
This framebuffer device driver is for the ARM PrimeCell PL110 This framebuffer device driver is for the ARM PrimeCell PL110
Colour LCD controller. ARM PrimeCells provide the building Colour LCD controller. ARM PrimeCells provide the building
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_graph.h> #include <linux/of_graph.h>
#include <linux/backlight.h>
#include <video/display_timing.h> #include <video/display_timing.h>
#include <video/of_display_timing.h> #include <video/of_display_timing.h>
#include <video/videomode.h> #include <video/videomode.h>
...@@ -71,6 +72,11 @@ static void clcdfb_disable(struct clcd_fb *fb) ...@@ -71,6 +72,11 @@ static void clcdfb_disable(struct clcd_fb *fb)
if (fb->board->disable) if (fb->board->disable)
fb->board->disable(fb); 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); val = readl(fb->regs + fb->off_cntl);
if (val & CNTL_LCDPWR) { if (val & CNTL_LCDPWR) {
val &= ~CNTL_LCDPWR; val &= ~CNTL_LCDPWR;
...@@ -116,6 +122,14 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) ...@@ -116,6 +122,14 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
cntl |= CNTL_LCDPWR; cntl |= CNTL_LCDPWR;
writel(cntl, fb->regs + fb->off_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. * finally, enable the interface.
*/ */
...@@ -576,6 +590,28 @@ static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode) ...@@ -576,6 +590,28 @@ static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
mode->refresh); 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, static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
struct fb_videomode *mode) struct fb_videomode *mode)
{ {
...@@ -662,6 +698,10 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) ...@@ -662,6 +698,10 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
if (!endpoint) if (!endpoint)
return -ENODEV; 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); err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
if (err) if (err)
return err; return err;
......
...@@ -93,6 +93,8 @@ enum { ...@@ -93,6 +93,8 @@ enum {
CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB, CLCD_CAP_ALL = CLCD_CAP_BGR | CLCD_CAP_RGB,
}; };
struct backlight_device;
struct clcd_panel { struct clcd_panel {
struct fb_videomode mode; struct fb_videomode mode;
signed short width; /* width in mm */ signed short width; /* width in mm */
...@@ -105,6 +107,7 @@ struct clcd_panel { ...@@ -105,6 +107,7 @@ struct clcd_panel {
fixedtimings:1, fixedtimings:1,
grayscale:1; grayscale:1;
unsigned int connector; unsigned int connector;
struct backlight_device *backlight;
}; };
struct clcd_regs { struct clcd_regs {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment