Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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
+40 −0
Original line number Diff line number Diff line
@@ -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;
@@ -116,6 +122,14 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl)
	cntl |= CNTL_LCDPWR;
	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.
	 */
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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 {