Skip to content

Commit db98854

Browse files
pelwellpopcornmix
authored andcommitted
staging/fbtft: Add support for display variants
Display variants are intended as a replacement for the now-deleted fbtft_device drivers. Drivers can register additional compatible strings with a custom callback that can make the required changes to the fbtft_display structure. Start the ball rolling by adding adafruit18, adafruit18_green and sainsmart18 displays. Signed-off-by: Phil Elwell <[email protected]>
1 parent 668155c commit db98854

File tree

3 files changed

+126
-40
lines changed

3 files changed

+126
-40
lines changed

drivers/staging/fbtft/fb_st7735r.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
1717
"0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
1818

19+
#define ADAFRUIT18_GAMMA \
20+
"02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
21+
"03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
22+
1923
static const s16 default_init_sequence[] = {
2024
-1, MIPI_DCS_SOFT_RESET,
2125
-2, 150, /* delay */
@@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
9498
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
9599
}
96100

101+
static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
102+
int xs, int ys, int xe, int ye)
103+
{
104+
write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
105+
write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
106+
write_reg(par, 0x2C);
107+
}
108+
97109
#define MY BIT(7)
98110
#define MX BIT(6)
99111
#define MV BIT(5)
@@ -174,12 +186,36 @@ static struct fbtft_display display = {
174186
},
175187
};
176188

177-
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
189+
static int variant_adafruit18(struct fbtft_display *display)
190+
{
191+
display->gamma = ADAFRUIT18_GAMMA;
192+
return 0;
193+
}
194+
195+
static int variant_adafruit18_green(struct fbtft_display *display)
196+
{
197+
display->gamma = ADAFRUIT18_GAMMA;
198+
display->fbtftops.set_addr_win = adafruit18_green_tab_set_addr_win;
199+
return 0;
200+
}
201+
202+
FBTFT_REGISTER_DRIVER_START(&display)
203+
FBTFT_COMPATIBLE("sitronix,st7735r")
204+
FBTFT_COMPATIBLE("fbtft,sainsmart18")
205+
FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18", variant_adafruit18)
206+
FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18_green", variant_adafruit18_green)
207+
FBTFT_REGISTER_DRIVER_END(DRVNAME, &display);
178208

179209
MODULE_ALIAS("spi:" DRVNAME);
180210
MODULE_ALIAS("platform:" DRVNAME);
181211
MODULE_ALIAS("spi:st7735r");
182212
MODULE_ALIAS("platform:st7735r");
213+
MODULE_ALIAS("spi:sainsmart18");
214+
MODULE_ALIAS("platform:sainsmart");
215+
MODULE_ALIAS("spi:adafruit18");
216+
MODULE_ALIAS("platform:adafruit18");
217+
MODULE_ALIAS("spi:adafruit18_green");
218+
MODULE_ALIAS("platform:adafruit18_green");
183219

184220
MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
185221
MODULE_AUTHOR("Noralf Tronnes");

drivers/staging/fbtft/fbtft-core.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <linux/platform_device.h>
2525
#include <linux/property.h>
2626
#include <linux/spinlock.h>
27+
#include <linux/of.h>
28+
#include <linux/of_device.h>
2729

2830
#include <video/mipi_display.h>
2931

@@ -1135,6 +1137,7 @@ static struct fbtft_platform_data *fbtft_properties_read(struct device *dev)
11351137
* @display: Display properties
11361138
* @sdev: SPI device
11371139
* @pdev: Platform device
1140+
* @dt_ids: Compatible string table
11381141
*
11391142
* Allocates, initializes and registers a framebuffer
11401143
*
@@ -1144,12 +1147,15 @@ static struct fbtft_platform_data *fbtft_properties_read(struct device *dev)
11441147
*/
11451148
int fbtft_probe_common(struct fbtft_display *display,
11461149
struct spi_device *sdev,
1147-
struct platform_device *pdev)
1150+
struct platform_device *pdev,
1151+
const struct of_device_id *dt_ids)
11481152
{
11491153
struct device *dev;
11501154
struct fb_info *info;
11511155
struct fbtft_par *par;
11521156
struct fbtft_platform_data *pdata;
1157+
const struct of_device_id *match;
1158+
int (*variant)(struct fbtft_display *);
11531159
int ret;
11541160

11551161
if (sdev)
@@ -1165,6 +1171,14 @@ int fbtft_probe_common(struct fbtft_display *display,
11651171
pdata = fbtft_properties_read(dev);
11661172
if (IS_ERR(pdata))
11671173
return PTR_ERR(pdata);
1174+
match = of_match_device(dt_ids, dev);
1175+
if (match && match->data) {
1176+
/* apply the variant */
1177+
variant = match->data;
1178+
ret = (*variant)(display);
1179+
if (ret)
1180+
return ret;
1181+
}
11681182
}
11691183

11701184
info = fbtft_framebuffer_alloc(display, dev, pdata);

drivers/staging/fbtft/fbtft.h

Lines changed: 74 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbtft_par *par);
251251
void fbtft_unregister_backlight(struct fbtft_par *par);
252252
int fbtft_init_display(struct fbtft_par *par);
253253
int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
254-
struct platform_device *pdev);
254+
struct platform_device *pdev,
255+
const struct of_device_id *dt_ids);
255256
void fbtft_remove_common(struct device *dev, struct fb_info *info);
256257

257258
/* fbtft-io.c */
@@ -272,42 +273,25 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...);
272273
void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
273274
void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
274275

275-
#define FBTFT_DT_TABLE(_compatible) \
276-
static const struct of_device_id dt_ids[] = { \
277-
{ .compatible = _compatible }, \
278-
{}, \
279-
}; \
280-
MODULE_DEVICE_TABLE(of, dt_ids);
281-
282-
#define FBTFT_SPI_DRIVER(_name, _compatible, _display, _spi_ids) \
283-
\
284-
static int fbtft_driver_probe_spi(struct spi_device *spi) \
285-
{ \
286-
return fbtft_probe_common(_display, spi, NULL); \
287-
} \
288-
\
289-
static void fbtft_driver_remove_spi(struct spi_device *spi) \
290-
{ \
291-
struct fb_info *info = spi_get_drvdata(spi); \
292-
\
293-
fbtft_remove_common(&spi->dev, info); \
294-
} \
295-
\
296-
static struct spi_driver fbtft_driver_spi_driver = { \
297-
.driver = { \
298-
.name = _name, \
299-
.of_match_table = dt_ids, \
300-
}, \
301-
.id_table = _spi_ids, \
302-
.probe = fbtft_driver_probe_spi, \
303-
.remove = fbtft_driver_remove_spi, \
304-
};
305-
306-
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
276+
#define FBTFT_REGISTER_DRIVER_START(_display) \
277+
\
278+
static const struct of_device_id dt_ids[]; \
279+
\
280+
static int fbtft_driver_probe_spi(struct spi_device *spi) \
281+
{ \
282+
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
283+
} \
284+
\
285+
static void fbtft_driver_remove_spi(struct spi_device *spi) \
286+
{ \
287+
struct fb_info *info = spi_get_drvdata(spi); \
288+
\
289+
fbtft_remove_common(&spi->dev, info); \
290+
} \
307291
\
308292
static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
309293
{ \
310-
return fbtft_probe_common(_display, NULL, pdev); \
294+
return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
311295
} \
312296
\
313297
static void fbtft_driver_remove_pdev(struct platform_device *pdev) \
@@ -317,9 +301,30 @@ static void fbtft_driver_remove_pdev(struct platform_device *pdev) \
317301
fbtft_remove_common(&pdev->dev, info); \
318302
} \
319303
\
320-
FBTFT_DT_TABLE(_compatible) \
304+
static const struct of_device_id dt_ids[] = {
305+
306+
#define FBTFT_COMPATIBLE(_compatible) \
307+
{ .compatible = _compatible },
308+
309+
#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
310+
{ .compatible = _compatible, .data = _variant },
311+
312+
#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
313+
\
314+
{}, \
315+
}; \
321316
\
322-
FBTFT_SPI_DRIVER(_name, _compatible, _display, NULL) \
317+
MODULE_DEVICE_TABLE(of, dt_ids); \
318+
\
319+
\
320+
static struct spi_driver fbtft_driver_spi_driver = { \
321+
.driver = { \
322+
.name = _name, \
323+
.of_match_table = dt_ids, \
324+
}, \
325+
.probe = fbtft_driver_probe_spi, \
326+
.remove = fbtft_driver_remove_spi, \
327+
}; \
323328
\
324329
static struct platform_driver fbtft_driver_platform_driver = { \
325330
.driver = { \
@@ -355,18 +360,49 @@ module_exit(fbtft_driver_module_exit);
355360

356361
#define FBTFT_REGISTER_SPI_DRIVER(_name, _comp_vend, _comp_dev, _display) \
357362
\
358-
FBTFT_DT_TABLE(_comp_vend "," _comp_dev) \
363+
static const struct of_device_id dt_ids[] = { \
364+
{ .compatible = _comp_vend "," _comp_dev }, \
365+
{}, \
366+
}; \
367+
\
368+
static int fbtft_driver_probe_spi(struct spi_device *spi) \
369+
{ \
370+
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
371+
} \
372+
\
373+
static void fbtft_driver_remove_spi(struct spi_device *spi) \
374+
{ \
375+
struct fb_info *info = spi_get_drvdata(spi); \
376+
\
377+
fbtft_remove_common(&spi->dev, info); \
378+
} \
379+
\
380+
MODULE_DEVICE_TABLE(of, dt_ids); \
359381
\
360382
static const struct spi_device_id spi_ids[] = { \
361383
{ .name = _comp_dev }, \
362384
{}, \
363385
}; \
386+
\
364387
MODULE_DEVICE_TABLE(spi, spi_ids); \
365388
\
366-
FBTFT_SPI_DRIVER(_name, _comp_vend "," _comp_dev, _display, spi_ids) \
389+
static struct spi_driver fbtft_driver_spi_driver = { \
390+
.driver = { \
391+
.name = _name, \
392+
.of_match_table = dt_ids, \
393+
}, \
394+
.id_table = spi_ids, \
395+
.probe = fbtft_driver_probe_spi, \
396+
.remove = fbtft_driver_remove_spi, \
397+
}; \
367398
\
368399
module_spi_driver(fbtft_driver_spi_driver);
369400

401+
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
402+
FBTFT_REGISTER_DRIVER_START(_display) \
403+
FBTFT_COMPATIBLE(_compatible) \
404+
FBTFT_REGISTER_DRIVER_END(_name, _display)
405+
370406
/* Debug macros */
371407

372408
/* shorthand debug levels */

0 commit comments

Comments
 (0)