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
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.
11 Start the ball rolling by adding adafruit18, adafruit18_green and
14 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
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(-)
21 --- a/drivers/staging/fbtft/fb_st7735r.c
22 +++ b/drivers/staging/fbtft/fb_st7735r.c
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"
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"
31 static const s16 default_init_sequence[] = {
32 -1, MIPI_DCS_SOFT_RESET,
34 @@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_pa
35 write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
38 +static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
39 + int xs, int ys, int xe, int ye)
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);
49 @@ -174,12 +186,36 @@ static struct fbtft_display display = {
53 -FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
54 +int variant_adafruit18(struct fbtft_display *display)
56 + display->gamma = ADAFRUIT18_GAMMA;
60 +int variant_adafruit18_green(struct fbtft_display *display)
62 + display->gamma = ADAFRUIT18_GAMMA;
63 + display->fbtftops.set_addr_win = adafruit18_green_tab_set_addr_win;
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);
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");
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
90 #include <linux/platform_device.h>
91 #include <linux/spinlock.h>
93 +#include <linux/of_device.h>
94 #include <video/mipi_display.h>
97 @@ -1199,6 +1200,7 @@ static struct fbtft_platform_data *fbtft
98 * @display: Display properties
100 * @pdev: Platform device
101 + * @dt_ids: Compatible string table
103 * Allocates, initializes and registers a framebuffer
105 @@ -1208,12 +1210,15 @@ static struct fbtft_platform_data *fbtft
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)
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 *);
122 @@ -1229,6 +1234,14 @@ int fbtft_probe_common(struct fbtft_disp
123 pdata = fbtft_probe_dt(dev);
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);
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);
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, ...);
153 -#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
154 +#define FBTFT_REGISTER_DRIVER_START(_display) \
156 +static const struct of_device_id dt_ids[]; \
158 static int fbtft_driver_probe_spi(struct spi_device *spi) \
160 - return fbtft_probe_common(_display, spi, NULL); \
161 + return fbtft_probe_common(_display, spi, NULL, dt_ids); \
164 static int fbtft_driver_remove_spi(struct spi_device *spi) \
165 @@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struc
167 static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
169 - return fbtft_probe_common(_display, NULL, pdev); \
170 + return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
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); \
178 -static const struct of_device_id dt_ids[] = { \
179 - { .compatible = _compatible }, \
180 +static const struct of_device_id dt_ids[] = {
182 +#define FBTFT_COMPATIBLE(_compatible) \
183 + { .compatible = _compatible },
185 +#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
186 + { .compatible = _compatible, .data = _variant },
188 +#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
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);
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)
204 /* shorthand debug levels */