7206bad51dba049b97ffc3df60930465379ea026
[openwrt/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0960-staging-fbtft-Add-support-for-display-variants.patch
1 From fe85ae40abf546bf592d171de942c17238103e52 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Tue, 1 Sep 2020 18:15:27 +0100
4 Subject: [PATCH] staging/fbtft: Add support for display variants
5
6 Display variants are intended as a replacement for the now-deleted
7 fbtft_device drivers. Drivers can register additional compatible
8 strings with a custom callback that can make the required changes
9 to the fbtft_display structure.
10
11 Start the ball rolling by adding adafruit18, adafruit18_green and
12 sainsmart18 displays.
13
14 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
15 ---
16 drivers/staging/fbtft/fb_st7735r.c | 38 +++++++++++++++++++++++++++++-
17 drivers/staging/fbtft/fbtft-core.c | 15 +++++++++++-
18 drivers/staging/fbtft/fbtft.h | 28 +++++++++++++++++-----
19 3 files changed, 73 insertions(+), 8 deletions(-)
20
21 --- a/drivers/staging/fbtft/fb_st7735r.c
22 +++ b/drivers/staging/fbtft/fb_st7735r.c
23 @@ -16,6 +16,10 @@
24 #define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
25 "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
26
27 +#define ADAFRUIT18_GAMMA \
28 + "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
29 + "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
30 +
31 static const s16 default_init_sequence[] = {
32 -1, MIPI_DCS_SOFT_RESET,
33 -2, 150, /* delay */
34 @@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_pa
35 write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
36 }
37
38 +static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
39 + int xs, int ys, int xe, int ye)
40 +{
41 + write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
42 + write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
43 + write_reg(par, 0x2C);
44 +}
45 +
46 #define MY BIT(7)
47 #define MX BIT(6)
48 #define MV BIT(5)
49 @@ -174,12 +186,36 @@ static struct fbtft_display display = {
50 },
51 };
52
53 -FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
54 +int variant_adafruit18(struct fbtft_display *display)
55 +{
56 + display->gamma = ADAFRUIT18_GAMMA;
57 + return 0;
58 +}
59 +
60 +int variant_adafruit18_green(struct fbtft_display *display)
61 +{
62 + display->gamma = ADAFRUIT18_GAMMA;
63 + display->fbtftops.set_addr_win = adafruit18_green_tab_set_addr_win;
64 + return 0;
65 +}
66 +
67 +FBTFT_REGISTER_DRIVER_START(&display)
68 +FBTFT_COMPATIBLE("sitronix,st7735r")
69 +FBTFT_COMPATIBLE("fbtft,sainsmart18")
70 +FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18", variant_adafruit18)
71 +FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18_green", variant_adafruit18_green)
72 +FBTFT_REGISTER_DRIVER_END(DRVNAME, &display);
73
74 MODULE_ALIAS("spi:" DRVNAME);
75 MODULE_ALIAS("platform:" DRVNAME);
76 MODULE_ALIAS("spi:st7735r");
77 MODULE_ALIAS("platform:st7735r");
78 +MODULE_ALIAS("spi:sainsmart18");
79 +MODULE_ALIAS("platform:sainsmart");
80 +MODULE_ALIAS("spi:adafruit18");
81 +MODULE_ALIAS("platform:adafruit18");
82 +MODULE_ALIAS("spi:adafruit18_green");
83 +MODULE_ALIAS("platform:adafruit18_green");
84
85 MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
86 MODULE_AUTHOR("Noralf Tronnes");
87 --- a/drivers/staging/fbtft/fbtft-core.c
88 +++ b/drivers/staging/fbtft/fbtft-core.c
89 @@ -24,6 +24,7 @@
90 #include <linux/platform_device.h>
91 #include <linux/spinlock.h>
92 #include <linux/of.h>
93 +#include <linux/of_device.h>
94 #include <video/mipi_display.h>
95
96 #include "fbtft.h"
97 @@ -1199,6 +1200,7 @@ static struct fbtft_platform_data *fbtft
98 * @display: Display properties
99 * @sdev: SPI device
100 * @pdev: Platform device
101 + * @dt_ids: Compatible string table
102 *
103 * Allocates, initializes and registers a framebuffer
104 *
105 @@ -1208,12 +1210,15 @@ static struct fbtft_platform_data *fbtft
106 */
107 int fbtft_probe_common(struct fbtft_display *display,
108 struct spi_device *sdev,
109 - struct platform_device *pdev)
110 + struct platform_device *pdev,
111 + const struct of_device_id *dt_ids)
112 {
113 struct device *dev;
114 struct fb_info *info;
115 struct fbtft_par *par;
116 struct fbtft_platform_data *pdata;
117 + const struct of_device_id *match;
118 + int (*variant)(struct fbtft_display *);
119 int ret;
120
121 if (sdev)
122 @@ -1229,6 +1234,14 @@ int fbtft_probe_common(struct fbtft_disp
123 pdata = fbtft_probe_dt(dev);
124 if (IS_ERR(pdata))
125 return PTR_ERR(pdata);
126 + match = of_match_device(dt_ids, dev);
127 + if (match && match->data) {
128 + /* apply the variant */
129 + variant = match->data;
130 + ret = (*variant)(display);
131 + if (ret)
132 + return ret;
133 + }
134 }
135
136 info = fbtft_framebuffer_alloc(display, dev, pdata);
137 --- a/drivers/staging/fbtft/fbtft.h
138 +++ b/drivers/staging/fbtft/fbtft.h
139 @@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbt
140 void fbtft_unregister_backlight(struct fbtft_par *par);
141 int fbtft_init_display(struct fbtft_par *par);
142 int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
143 - struct platform_device *pdev);
144 + struct platform_device *pdev,
145 + const struct of_device_id *dt_ids);
146 int fbtft_remove_common(struct device *dev, struct fb_info *info);
147
148 /* fbtft-io.c */
149 @@ -272,11 +273,13 @@ void fbtft_write_reg8_bus9(struct fbtft_
150 void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
151 void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
152
153 -#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
154 +#define FBTFT_REGISTER_DRIVER_START(_display) \
155 + \
156 +static const struct of_device_id dt_ids[]; \
157 \
158 static int fbtft_driver_probe_spi(struct spi_device *spi) \
159 { \
160 - return fbtft_probe_common(_display, spi, NULL); \
161 + return fbtft_probe_common(_display, spi, NULL, dt_ids); \
162 } \
163 \
164 static int fbtft_driver_remove_spi(struct spi_device *spi) \
165 @@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struc
166 \
167 static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
168 { \
169 - return fbtft_probe_common(_display, NULL, pdev); \
170 + return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
171 } \
172 \
173 static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
174 @@ -298,8 +301,16 @@ static int fbtft_driver_remove_pdev(stru
175 return fbtft_remove_common(&pdev->dev, info); \
176 } \
177 \
178 -static const struct of_device_id dt_ids[] = { \
179 - { .compatible = _compatible }, \
180 +static const struct of_device_id dt_ids[] = {
181 +
182 +#define FBTFT_COMPATIBLE(_compatible) \
183 + { .compatible = _compatible },
184 +
185 +#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
186 + { .compatible = _compatible, .data = _variant },
187 +
188 +#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
189 + \
190 {}, \
191 }; \
192 \
193 @@ -344,6 +355,11 @@ static void __exit fbtft_driver_module_e
194 module_init(fbtft_driver_module_init); \
195 module_exit(fbtft_driver_module_exit);
196
197 +#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
198 + FBTFT_REGISTER_DRIVER_START(_display) \
199 + FBTFT_COMPATIBLE(_compatible) \
200 + FBTFT_REGISTER_DRIVER_END(_name, _display)
201 +
202 /* Debug macros */
203
204 /* shorthand debug levels */