提交 d6c84cc6 编写于 作者: P Phil Elwell 提交者: Zheng Zengkai

staging/fbtft: Add support for display variants

raspberrypi inclusion
category: feature
bugzilla: 50432

--------------------------------

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: NPhil Elwell <phil@raspberrypi.com>
Signed-off-by: NFang Yafen <yafen@iscas.ac.cn>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 d80d2cef
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \ #define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
"0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10" "0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
#define ADAFRUIT18_GAMMA \
"02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \
"03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10"
static const s16 default_init_sequence[] = { static const s16 default_init_sequence[] = {
-1, MIPI_DCS_SOFT_RESET, -1, MIPI_DCS_SOFT_RESET,
-2, 150, /* delay */ -2, 150, /* delay */
...@@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye) ...@@ -94,6 +98,14 @@ static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
write_reg(par, MIPI_DCS_WRITE_MEMORY_START); write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
} }
static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par,
int xs, int ys, int xe, int ye)
{
write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2);
write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1);
write_reg(par, 0x2C);
}
#define MY BIT(7) #define MY BIT(7)
#define MX BIT(6) #define MX BIT(6)
#define MV BIT(5) #define MV BIT(5)
...@@ -174,12 +186,36 @@ static struct fbtft_display display = { ...@@ -174,12 +186,36 @@ static struct fbtft_display display = {
}, },
}; };
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display); int variant_adafruit18(struct fbtft_display *display)
{
display->gamma = ADAFRUIT18_GAMMA;
return 0;
}
int variant_adafruit18_green(struct fbtft_display *display)
{
display->gamma = ADAFRUIT18_GAMMA;
display->fbtftops.set_addr_win = adafruit18_green_tab_set_addr_win;
return 0;
}
FBTFT_REGISTER_DRIVER_START(&display)
FBTFT_COMPATIBLE("sitronix,st7735r")
FBTFT_COMPATIBLE("fbtft,sainsmart18")
FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18", variant_adafruit18)
FBTFT_VARIANT_COMPATIBLE("fbtft,adafruit18_green", variant_adafruit18_green)
FBTFT_REGISTER_DRIVER_END(DRVNAME, &display);
MODULE_ALIAS("spi:" DRVNAME); MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME); MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7735r"); MODULE_ALIAS("spi:st7735r");
MODULE_ALIAS("platform:st7735r"); MODULE_ALIAS("platform:st7735r");
MODULE_ALIAS("spi:sainsmart18");
MODULE_ALIAS("platform:sainsmart");
MODULE_ALIAS("spi:adafruit18");
MODULE_ALIAS("platform:adafruit18");
MODULE_ALIAS("spi:adafruit18_green");
MODULE_ALIAS("platform:adafruit18_green");
MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller"); MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
MODULE_AUTHOR("Noralf Tronnes"); MODULE_AUTHOR("Noralf Tronnes");
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <video/mipi_display.h> #include <video/mipi_display.h>
...@@ -1199,6 +1201,7 @@ static struct fbtft_platform_data *fbtft_properties_read(struct device *dev) ...@@ -1199,6 +1201,7 @@ static struct fbtft_platform_data *fbtft_properties_read(struct device *dev)
* @display: Display properties * @display: Display properties
* @sdev: SPI device * @sdev: SPI device
* @pdev: Platform device * @pdev: Platform device
* @dt_ids: Compatible string table
* *
* Allocates, initializes and registers a framebuffer * Allocates, initializes and registers a framebuffer
* *
...@@ -1208,12 +1211,15 @@ static struct fbtft_platform_data *fbtft_properties_read(struct device *dev) ...@@ -1208,12 +1211,15 @@ static struct fbtft_platform_data *fbtft_properties_read(struct device *dev)
*/ */
int fbtft_probe_common(struct fbtft_display *display, int fbtft_probe_common(struct fbtft_display *display,
struct spi_device *sdev, struct spi_device *sdev,
struct platform_device *pdev) struct platform_device *pdev,
const struct of_device_id *dt_ids)
{ {
struct device *dev; struct device *dev;
struct fb_info *info; struct fb_info *info;
struct fbtft_par *par; struct fbtft_par *par;
struct fbtft_platform_data *pdata; struct fbtft_platform_data *pdata;
const struct of_device_id *match;
int (*variant)(struct fbtft_display *);
int ret; int ret;
if (sdev) if (sdev)
...@@ -1229,6 +1235,14 @@ int fbtft_probe_common(struct fbtft_display *display, ...@@ -1229,6 +1235,14 @@ int fbtft_probe_common(struct fbtft_display *display,
pdata = fbtft_properties_read(dev); pdata = fbtft_properties_read(dev);
if (IS_ERR(pdata)) if (IS_ERR(pdata))
return PTR_ERR(pdata); return PTR_ERR(pdata);
match = of_match_device(dt_ids, dev);
if (match && match->data) {
/* apply the variant */
variant = match->data;
ret = (*variant)(display);
if (ret)
return ret;
}
} }
info = fbtft_framebuffer_alloc(display, dev, pdata); info = fbtft_framebuffer_alloc(display, dev, pdata);
......
...@@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbtft_par *par); ...@@ -251,7 +251,8 @@ void fbtft_register_backlight(struct fbtft_par *par);
void fbtft_unregister_backlight(struct fbtft_par *par); void fbtft_unregister_backlight(struct fbtft_par *par);
int fbtft_init_display(struct fbtft_par *par); int fbtft_init_display(struct fbtft_par *par);
int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev, int fbtft_probe_common(struct fbtft_display *display, struct spi_device *sdev,
struct platform_device *pdev); struct platform_device *pdev,
const struct of_device_id *dt_ids);
int fbtft_remove_common(struct device *dev, struct fb_info *info); int fbtft_remove_common(struct device *dev, struct fb_info *info);
/* fbtft-io.c */ /* fbtft-io.c */
...@@ -272,11 +273,13 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...); ...@@ -272,11 +273,13 @@ void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...);
void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...); void fbtft_write_reg16_bus8(struct fbtft_par *par, int len, ...);
void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...); void fbtft_write_reg16_bus16(struct fbtft_par *par, int len, ...);
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \ #define FBTFT_REGISTER_DRIVER_START(_display) \
\
static const struct of_device_id dt_ids[]; \
\ \
static int fbtft_driver_probe_spi(struct spi_device *spi) \ static int fbtft_driver_probe_spi(struct spi_device *spi) \
{ \ { \
return fbtft_probe_common(_display, spi, NULL); \ return fbtft_probe_common(_display, spi, NULL, dt_ids); \
} \ } \
\ \
static int fbtft_driver_remove_spi(struct spi_device *spi) \ static int fbtft_driver_remove_spi(struct spi_device *spi) \
...@@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struct spi_device *spi) \ ...@@ -288,7 +291,7 @@ static int fbtft_driver_remove_spi(struct spi_device *spi) \
\ \
static int fbtft_driver_probe_pdev(struct platform_device *pdev) \ static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
{ \ { \
return fbtft_probe_common(_display, NULL, pdev); \ return fbtft_probe_common(_display, NULL, pdev, dt_ids); \
} \ } \
\ \
static int fbtft_driver_remove_pdev(struct platform_device *pdev) \ static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
...@@ -298,8 +301,16 @@ static int fbtft_driver_remove_pdev(struct platform_device *pdev) \ ...@@ -298,8 +301,16 @@ static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
return fbtft_remove_common(&pdev->dev, info); \ return fbtft_remove_common(&pdev->dev, info); \
} \ } \
\ \
static const struct of_device_id dt_ids[] = { \ static const struct of_device_id dt_ids[] = {
{ .compatible = _compatible }, \
#define FBTFT_COMPATIBLE(_compatible) \
{ .compatible = _compatible },
#define FBTFT_VARIANT_COMPATIBLE(_compatible, _variant) \
{ .compatible = _compatible, .data = _variant },
#define FBTFT_REGISTER_DRIVER_END(_name, _display) \
\
{}, \ {}, \
}; \ }; \
\ \
...@@ -344,6 +355,11 @@ static void __exit fbtft_driver_module_exit(void) \ ...@@ -344,6 +355,11 @@ static void __exit fbtft_driver_module_exit(void) \
module_init(fbtft_driver_module_init); \ module_init(fbtft_driver_module_init); \
module_exit(fbtft_driver_module_exit); module_exit(fbtft_driver_module_exit);
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
FBTFT_REGISTER_DRIVER_START(_display) \
FBTFT_COMPATIBLE(_compatible) \
FBTFT_REGISTER_DRIVER_END(_name, _display)
/* Debug macros */ /* Debug macros */
/* shorthand debug levels */ /* shorthand debug levels */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册