ath79: add support for TP-LINK Archer C7 v4
[openwrt/staging/jogo.git] / target / linux / brcm2708 / patches-4.9 / 950-0085-rpi_display-add-backlight-driver-and-overlay.patch
1 From ae5ae9278768c3d096910705bfa9af85da20a8cf Mon Sep 17 00:00:00 2001
2 From: P33M <P33M@github.com>
3 Date: Wed, 21 Oct 2015 14:55:21 +0100
4 Subject: [PATCH] rpi_display: add backlight driver and overlay
5
6 Add a mailbox-driven backlight controller for the Raspberry Pi DSI
7 touchscreen display. Requires updated GPU firmware to recognise the
8 mailbox request.
9
10 Signed-off-by: Gordon Hollingworth <gordon@raspberrypi.org>
11 ---
12 drivers/video/backlight/Kconfig | 6 ++
13 drivers/video/backlight/Makefile | 1 +
14 drivers/video/backlight/rpi_backlight.c | 119 ++++++++++++++++++++++++++++++++
15 3 files changed, 126 insertions(+)
16 create mode 100644 drivers/video/backlight/rpi_backlight.c
17
18 --- a/drivers/video/backlight/Kconfig
19 +++ b/drivers/video/backlight/Kconfig
20 @@ -265,6 +265,12 @@ config BACKLIGHT_PWM
21 If you have a LCD backlight adjustable by PWM, say Y to enable
22 this driver.
23
24 +config BACKLIGHT_RPI
25 + tristate "Raspberry Pi display firmware driven backlight"
26 + help
27 + If you have the Raspberry Pi DSI touchscreen display, say Y to
28 + enable the mailbox-controlled backlight driver.
29 +
30 config BACKLIGHT_DA903X
31 tristate "Backlight Driver for DA9030/DA9034 using WLED"
32 depends on PMIC_DA903X
33 --- a/drivers/video/backlight/Makefile
34 +++ b/drivers/video/backlight/Makefile
35 @@ -50,6 +50,7 @@ obj-$(CONFIG_BACKLIGHT_PANDORA) += pand
36 obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
37 obj-$(CONFIG_BACKLIGHT_PM8941_WLED) += pm8941-wled.o
38 obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
39 +obj-$(CONFIG_BACKLIGHT_RPI) += rpi_backlight.o
40 obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
41 obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
42 obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
43 --- /dev/null
44 +++ b/drivers/video/backlight/rpi_backlight.c
45 @@ -0,0 +1,119 @@
46 +/*
47 + * rpi_bl.c - Backlight controller through VPU
48 + *
49 + * This program is free software; you can redistribute it and/or modify
50 + * it under the terms of the GNU General Public License version 2 as
51 + * published by the Free Software Foundation.
52 + */
53 +
54 +#include <linux/backlight.h>
55 +#include <linux/err.h>
56 +#include <linux/fb.h>
57 +#include <linux/gpio.h>
58 +#include <linux/init.h>
59 +#include <linux/kernel.h>
60 +#include <linux/module.h>
61 +#include <linux/of.h>
62 +#include <linux/of_gpio.h>
63 +#include <linux/platform_device.h>
64 +#include <linux/slab.h>
65 +#include <soc/bcm2835/raspberrypi-firmware.h>
66 +
67 +struct rpi_backlight {
68 + struct device *dev;
69 + struct device *fbdev;
70 + struct rpi_firmware *fw;
71 +};
72 +
73 +static int rpi_backlight_update_status(struct backlight_device *bl)
74 +{
75 + struct rpi_backlight *gbl = bl_get_data(bl);
76 + int brightness = bl->props.brightness;
77 + int ret;
78 +
79 + if (bl->props.power != FB_BLANK_UNBLANK ||
80 + bl->props.fb_blank != FB_BLANK_UNBLANK ||
81 + bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
82 + brightness = 0;
83 +
84 + ret = rpi_firmware_property(gbl->fw,
85 + RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT,
86 + &brightness, sizeof(brightness));
87 + if (ret) {
88 + dev_err(gbl->dev, "Failed to set brightness\n");
89 + return ret;
90 + }
91 +
92 + if (brightness < 0) {
93 + dev_err(gbl->dev, "Backlight change failed\n");
94 + return -EAGAIN;
95 + }
96 +
97 + return 0;
98 +}
99 +
100 +static const struct backlight_ops rpi_backlight_ops = {
101 + .options = BL_CORE_SUSPENDRESUME,
102 + .update_status = rpi_backlight_update_status,
103 +};
104 +
105 +static int rpi_backlight_probe(struct platform_device *pdev)
106 +{
107 + struct backlight_properties props;
108 + struct backlight_device *bl;
109 + struct rpi_backlight *gbl;
110 + struct device_node *fw_node;
111 +
112 + gbl = devm_kzalloc(&pdev->dev, sizeof(*gbl), GFP_KERNEL);
113 + if (gbl == NULL)
114 + return -ENOMEM;
115 +
116 + gbl->dev = &pdev->dev;
117 +
118 + fw_node = of_parse_phandle(pdev->dev.of_node, "firmware", 0);
119 + if (!fw_node) {
120 + dev_err(&pdev->dev, "Missing firmware node\n");
121 + return -ENOENT;
122 + }
123 +
124 + gbl->fw = rpi_firmware_get(fw_node);
125 + if (!gbl->fw)
126 + return -EPROBE_DEFER;
127 +
128 + memset(&props, 0, sizeof(props));
129 + props.type = BACKLIGHT_RAW;
130 + props.max_brightness = 255;
131 + bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev),
132 + &pdev->dev, gbl, &rpi_backlight_ops,
133 + &props);
134 + if (IS_ERR(bl)) {
135 + dev_err(&pdev->dev, "failed to register backlight\n");
136 + return PTR_ERR(bl);
137 + }
138 +
139 + bl->props.brightness = 255;
140 + backlight_update_status(bl);
141 +
142 + platform_set_drvdata(pdev, bl);
143 + return 0;
144 +}
145 +
146 +static const struct of_device_id rpi_backlight_of_match[] = {
147 + { .compatible = "raspberrypi,rpi-backlight" },
148 + { /* sentinel */ }
149 +};
150 +MODULE_DEVICE_TABLE(of, rpi_backlight_of_match);
151 +
152 +static struct platform_driver rpi_backlight_driver = {
153 + .driver = {
154 + .name = "rpi-backlight",
155 + .of_match_table = of_match_ptr(rpi_backlight_of_match),
156 + },
157 + .probe = rpi_backlight_probe,
158 +};
159 +
160 +module_platform_driver(rpi_backlight_driver);
161 +
162 +MODULE_AUTHOR("Gordon Hollingworth <gordon@raspberrypi.org>");
163 +MODULE_DESCRIPTION("Raspberry Pi mailbox based Backlight Driver");
164 +MODULE_LICENSE("GPL");