72f741fa892b9c270f9a1464f03645d6f6572a1b
[openwrt/staging/dedeckeh.git] / target / linux / bcm27xx / patches-5.10 / 950-0332-staging-fbtft-Add-support-for-display-variants.patch
1 From 809abb2cd0f810ee0a94add2e5a038c78825915d 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 | 16 ++++++++++++-
18 drivers/staging/fbtft/fbtft.h | 28 +++++++++++++++++-----
19 3 files changed, 74 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,8 @@
90 #include <linux/platform_device.h>
91 #include <linux/property.h>
92 #include <linux/spinlock.h>
93 +#include <linux/of.h>
94 +#include <linux/of_device.h>
95
96 #include <video/mipi_display.h>
97
98 @@ -1194,6 +1196,7 @@ static struct fbtft_platform_data *fbtft
99 * @display: Display properties
100 * @sdev: SPI device
101 * @pdev: Platform device
102 + * @dt_ids: Compatible string table
103 *
104 * Allocates, initializes and registers a framebuffer
105 *
106 @@ -1203,12 +1206,15 @@ static struct fbtft_platform_data *fbtft
107 */
108 int fbtft_probe_common(struct fbtft_display *display,
109 struct spi_device *sdev,
110 - struct platform_device *pdev)
111 + struct platform_device *pdev,
112 + const struct of_device_id *dt_ids)
113 {
114 struct device *dev;
115 struct fb_info *info;
116 struct fbtft_par *par;
117 struct fbtft_platform_data *pdata;
118 + const struct of_device_id *match;
119 + int (*variant)(struct fbtft_display *);
120 int ret;
121
122 if (sdev)
123 @@ -1224,6 +1230,14 @@ int fbtft_probe_common(struct fbtft_disp
124 pdata = fbtft_properties_read(dev);
125 if (IS_ERR(pdata))
126 return PTR_ERR(pdata);
127 + match = of_match_device(dt_ids, dev);
128 + if (match && match->data) {
129 + /* apply the variant */
130 + variant = match->data;
131 + ret = (*variant)(display);
132 + if (ret)
133 + return ret;
134 + }
135 }
136
137 info = fbtft_framebuffer_alloc(display, dev, pdata);
138 --- a/drivers/staging/fbtft/fbtft.h
139 +++ b/drivers/staging/fbtft/fbtft.h
140 @@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbt
141 void fbtft_unregister_backlight(struct fbtft_par *par);
142 int fbtft_init_display(struct fbtft_par *par);
143 int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
144 - struct platform_device *pdev);
145 + struct platform_device *pdev,
146 + const struct of_device_id *dt_ids);
147 int fbtft_remove_common(struct device *dev, struct fb_info *info);
148
149 /* fbtft-io.c */
150 @@ -272,11 +273,13 @@ void fbtft_write_reg8_bus9(struct fbtft_
151 void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
152 void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
153
154 -#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
155 +#define FBTFT_REGISTER_DRIVER_START(_display) \
156 + \
157 +static const struct of_device_id dt_ids[]; \
158 \
159 static int fbtft_driver_probe_spi(struct spi_device *spi) \
160 { \
161 - return fbtft_probe_common(_display, spi, NULL); \
162 + return fbtft_probe_common(_display, spi, NULL, dt_ids); \
163 } \
164 \
165 static int fbtft_driver_remove_spi(struct spi_device *spi) \
166 @@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struc
167 \
168 static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
169 { \
170 - return fbtft_probe_common(_display, NULL, pdev); \
171 + return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
172 } \
173 \
174 static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
175 @@ -298,8 +301,16 @@ static int fbtft_driver_remove_pdev(stru
176 return fbtft_remove_common(&pdev->dev, info); \
177 } \
178 \
179 -static const struct of_device_id dt_ids[] = { \
180 - { .compatible = _compatible }, \
181 +static const struct of_device_id dt_ids[] = {
182 +
183 +#define FBTFT_COMPATIBLE(_compatible) \
184 + { .compatible = _compatible },
185 +
186 +#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
187 + { .compatible = _compatible, .data = _variant },
188 +
189 +#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
190 + \
191 {}, \
192 }; \
193 \
194 @@ -344,6 +355,11 @@ static void __exit fbtft_driver_module_e
195 module_init(fbtft_driver_module_init); \
196 module_exit(fbtft_driver_module_exit);
197
198 +#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
199 + FBTFT_REGISTER_DRIVER_START(_display) \
200 + FBTFT_COMPATIBLE(_compatible) \
201 + FBTFT_REGISTER_DRIVER_END(_name, _display)
202 +
203 /* Debug macros */
204
205 /* shorthand debug levels */