Updated and fixed ST7789v driver
This commit is contained in:
parent
d49b6e9d95
commit
97a7d43e85
7 changed files with 221 additions and 43 deletions
|
|
@ -275,11 +275,6 @@ def is_kernel_upgrade_required(config = None):
|
||||||
config = pitft_config
|
config = pitft_config
|
||||||
if not config['kernel_upgrade']:
|
if not config['kernel_upgrade']:
|
||||||
return False
|
return False
|
||||||
module = config['kernel_module']
|
|
||||||
if shell.exists(f"/lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.ko.xz"):
|
|
||||||
return False
|
|
||||||
if shell.exists(f"/lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.ko"):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -309,11 +304,10 @@ def install_drivers():
|
||||||
shell.pushd("st7789_module")
|
shell.pushd("st7789_module")
|
||||||
if not shell.run_command("make"):
|
if not shell.run_command("make"):
|
||||||
warn_exit("Apt failed to compile ST7789V drivers!")
|
warn_exit("Apt failed to compile ST7789V drivers!")
|
||||||
shell.run_command(f"mv /lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.ko /lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.BACK")
|
shell.run_command(f"mv /lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.ko.xz /lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.BACK.xz")
|
||||||
shell.run_command(f"mv {module}.ko /lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.ko")
|
shell.run_command(f"xz -v2 {module}.ko")
|
||||||
|
shell.run_command(f"mv {module}.ko.xz /lib/modules/{shell.release()}/kernel/drivers/staging/fbtft/{module}.ko.xz")
|
||||||
shell.popd()
|
shell.popd()
|
||||||
|
|
||||||
# We may need to unzip the /lib/modules/6.1.19-v8+/kernel/drivers/staging/fbtft/fb_st7789v.ko.xz file
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_configtxt(rotation_override=None):
|
def update_configtxt(rotation_override=None):
|
||||||
|
|
@ -759,4 +753,5 @@ restart the script and choose a different orientation.""".format(rotation=pitftr
|
||||||
# Main function
|
# Main function
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
shell.require_root()
|
shell.require_root()
|
||||||
|
shell.check_kernel_userspace_mismatch()
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
pitft: pitft@0{
|
pitft: pitft@0{
|
||||||
compatible = "sitronix,st7789v";
|
compatible = "fbtft,minipitft13";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&pitft_pins>;
|
pinctrl-0 = <&pitft_pins>;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
pitft: pitft@0{
|
pitft: pitft@0{
|
||||||
compatible = "sitronix,st7789v";
|
compatible = "fbtft,minipitft13";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&pitft_pins>;
|
pinctrl-0 = <&pitft_pins>;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
|
||||||
pitft: pitft@0{
|
pitft: pitft@0{
|
||||||
compatible = "sitronix,st7789v";
|
compatible = "fbtft,minipitft13";
|
||||||
reg = <0>;
|
reg = <0>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&pitft_pins>;
|
pinctrl-0 = <&pitft_pins>;
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
fragment@3 {
|
fragment@3 {
|
||||||
target-path = "/";
|
target-path = "/";
|
||||||
__overlay__ {
|
__overlay__ {
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,13 @@
|
||||||
|
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <video/mipi_display.h>
|
#include <video/mipi_display.h>
|
||||||
|
|
||||||
#include "fbtft.h"
|
#include "fbtft.h"
|
||||||
|
|
@ -66,13 +70,68 @@ enum st7789v_command {
|
||||||
#define MADCTL_MX BIT(6) /* bitmask for column address order */
|
#define MADCTL_MX BIT(6) /* bitmask for column address order */
|
||||||
#define MADCTL_MY BIT(7) /* bitmask for page address order */
|
#define MADCTL_MY BIT(7) /* bitmask for page address order */
|
||||||
|
|
||||||
static u32 col1_offset = 0;
|
/* 60Hz for 16.6ms, configured as 2*16.6ms */
|
||||||
static u32 col2_offset = 0;
|
#define PANEL_TE_TIMEOUT_MS 33
|
||||||
static u32 row1_offset = 0;
|
|
||||||
static u32 row2_offset = 0;
|
static struct completion panel_te; /* completion for panel TE line */
|
||||||
|
static int irq_te; /* Linux IRQ for LCD TE line */
|
||||||
|
static u32 col_start_offset = 0;
|
||||||
|
static u32 col_end_offset = 0;
|
||||||
|
static u32 row_start_offset = 0;
|
||||||
|
static u32 row_end_offset = 0;
|
||||||
static short x_offset = 0;
|
static short x_offset = 0;
|
||||||
static short y_offset = 0;
|
static short y_offset = 0;
|
||||||
|
|
||||||
|
static irqreturn_t panel_te_handler(int irq, void *data)
|
||||||
|
{
|
||||||
|
complete(&panel_te);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_tearing_effect_line() - init tearing effect line.
|
||||||
|
* @par: FBTFT parameter object.
|
||||||
|
*
|
||||||
|
* Return: 0 on success, or a negative error code otherwise.
|
||||||
|
*/
|
||||||
|
static int init_tearing_effect_line(struct fbtft_par *par)
|
||||||
|
{
|
||||||
|
struct device *dev = par->info->device;
|
||||||
|
struct gpio_desc *te;
|
||||||
|
int rc, irq;
|
||||||
|
|
||||||
|
te = gpiod_get_optional(dev, "te", GPIOD_IN);
|
||||||
|
if (IS_ERR(te))
|
||||||
|
return dev_err_probe(dev, PTR_ERR(te), "Failed to request te GPIO\n");
|
||||||
|
|
||||||
|
/* if te is NULL, indicating no configuration, directly return success */
|
||||||
|
if (!te) {
|
||||||
|
irq_te = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
irq = gpiod_to_irq(te);
|
||||||
|
|
||||||
|
/* GPIO is locked as an IRQ, we may drop the reference */
|
||||||
|
gpiod_put(te);
|
||||||
|
|
||||||
|
if (irq < 0)
|
||||||
|
return irq;
|
||||||
|
|
||||||
|
irq_te = irq;
|
||||||
|
init_completion(&panel_te);
|
||||||
|
|
||||||
|
/* The effective state is high and lasts no more than 1000 microseconds */
|
||||||
|
rc = devm_request_irq(dev, irq_te, panel_te_handler,
|
||||||
|
IRQF_TRIGGER_RISING, "TE_GPIO", par);
|
||||||
|
if (rc)
|
||||||
|
return dev_err_probe(dev, rc, "TE IRQ request failed.\n");
|
||||||
|
|
||||||
|
disable_irq_nosync(irq_te);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_display() - initialize the display controller
|
* init_display() - initialize the display controller
|
||||||
*
|
*
|
||||||
|
|
@ -89,6 +148,14 @@ static short y_offset = 0;
|
||||||
*/
|
*/
|
||||||
static int init_display(struct fbtft_par *par)
|
static int init_display(struct fbtft_par *par)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
par->fbtftops.reset(par);
|
||||||
|
|
||||||
|
rc = init_tearing_effect_line(par);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* turn off sleep mode */
|
/* turn off sleep mode */
|
||||||
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
|
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
|
||||||
mdelay(120);
|
mdelay(120);
|
||||||
|
|
@ -144,6 +211,10 @@ static int init_display(struct fbtft_par *par)
|
||||||
*/
|
*/
|
||||||
write_reg(par, PWCTRL1, 0xA4, 0xA1);
|
write_reg(par, PWCTRL1, 0xA4, 0xA1);
|
||||||
|
|
||||||
|
/* TE line output is off by default when powering on */
|
||||||
|
if (irq_te)
|
||||||
|
write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00);
|
||||||
|
|
||||||
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
|
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
|
||||||
|
|
||||||
if (HSD20_IPS)
|
if (HSD20_IPS)
|
||||||
|
|
@ -152,7 +223,51 @@ static int init_display(struct fbtft_par *par)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void minipitft_set_addr_win(struct fbtft_par *par, int xs, int ys,
|
/*
|
||||||
|
* write_vmem() - write data to display.
|
||||||
|
* @par: FBTFT parameter object.
|
||||||
|
* @offset: offset from screen_buffer.
|
||||||
|
* @len: the length of data to be writte.
|
||||||
|
*
|
||||||
|
* Return: 0 on success, or a negative error code otherwise.
|
||||||
|
*/
|
||||||
|
static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
|
||||||
|
{
|
||||||
|
struct device *dev = par->info->device;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (irq_te) {
|
||||||
|
enable_irq(irq_te);
|
||||||
|
reinit_completion(&panel_te);
|
||||||
|
ret = wait_for_completion_timeout(&panel_te,
|
||||||
|
msecs_to_jiffies(PANEL_TE_TIMEOUT_MS));
|
||||||
|
if (ret == 0)
|
||||||
|
dev_err(dev, "wait panel TE timeout\n");
|
||||||
|
|
||||||
|
disable_irq(irq_te);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (par->pdata->display.buswidth) {
|
||||||
|
case 8:
|
||||||
|
ret = fbtft_write_vmem16_bus8(par, offset, len);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
ret = fbtft_write_vmem16_bus9(par, offset, len);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
ret = fbtft_write_vmem16_bus16(par, offset, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(dev, "Unsupported buswidth %d\n",
|
||||||
|
par->pdata->display.buswidth);
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void minipitft13_set_addr_win(struct fbtft_par *par, int xs, int ys,
|
||||||
int xe, int ye)
|
int xe, int ye)
|
||||||
{
|
{
|
||||||
xs += x_offset;
|
xs += x_offset;
|
||||||
|
|
@ -185,35 +300,36 @@ static int set_var(struct fbtft_par *par)
|
||||||
madctl_par |= MADCTL_BGR;
|
madctl_par |= MADCTL_BGR;
|
||||||
|
|
||||||
if (width < 240) {
|
if (width < 240) {
|
||||||
// Display is centered
|
// Smaller displays are centered
|
||||||
row1_offset = row2_offset = (int)((320 - height + 1) / 2);
|
row_start_offset = row_end_offset = (int)((320 - height + 1) / 2);
|
||||||
col1_offset = (int)((240 - width) / 2);
|
col_start_offset = (int)((240 - width) / 2);
|
||||||
col2_offset = (int)((240 - width + 1) / 2);
|
col_end_offset = (int)((240 - width + 1) / 2); // Account for extra pixel
|
||||||
} else {
|
} else {
|
||||||
row1_offset = 0;
|
// Larger displays are left-aligned
|
||||||
row2_offset = (320 - height);
|
row_start_offset = 0;
|
||||||
col1_offset = col2_offset = (240 - width);
|
row_end_offset = (320 - height);
|
||||||
|
col_start_offset = col_end_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (par->info->var.rotate) {
|
switch (par->info->var.rotate) {
|
||||||
case 0:
|
case 0:
|
||||||
x_offset = col1_offset;
|
x_offset = col_start_offset;
|
||||||
y_offset = row1_offset;
|
y_offset = row_start_offset;
|
||||||
break;
|
break;
|
||||||
case 90:
|
case 90:
|
||||||
madctl_par |= (MADCTL_MV | MADCTL_MY);
|
madctl_par |= (MADCTL_MV | MADCTL_MY);
|
||||||
x_offset = row1_offset;
|
x_offset = row_start_offset;
|
||||||
y_offset = col1_offset;
|
y_offset = col_start_offset;
|
||||||
break;
|
break;
|
||||||
case 180:
|
case 180:
|
||||||
madctl_par |= (MADCTL_MX | MADCTL_MY);
|
madctl_par |= (MADCTL_MX | MADCTL_MY);
|
||||||
x_offset = col2_offset;
|
x_offset = col_end_offset;
|
||||||
y_offset = row2_offset;
|
y_offset = row_end_offset;
|
||||||
break;
|
break;
|
||||||
case 270:
|
case 270:
|
||||||
madctl_par |= (MADCTL_MV | MADCTL_MX);
|
madctl_par |= (MADCTL_MV | MADCTL_MX);
|
||||||
x_offset = row2_offset;
|
x_offset = row_end_offset;
|
||||||
y_offset = col2_offset;
|
y_offset = col_end_offset;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -304,14 +420,23 @@ static struct fbtft_display display = {
|
||||||
.gamma = HSD20_IPS_GAMMA,
|
.gamma = HSD20_IPS_GAMMA,
|
||||||
.fbtftops = {
|
.fbtftops = {
|
||||||
.init_display = init_display,
|
.init_display = init_display,
|
||||||
|
.write_vmem = write_vmem,
|
||||||
.set_var = set_var,
|
.set_var = set_var,
|
||||||
.set_gamma = set_gamma,
|
.set_gamma = set_gamma,
|
||||||
.blank = blank,
|
.blank = blank,
|
||||||
.set_addr_win = minipitft_set_addr_win,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7789v", &display);
|
int variant_minipitft13(struct fbtft_display *display)
|
||||||
|
{
|
||||||
|
display->fbtftops.set_addr_win = minipitft13_set_addr_win;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FBTFT_REGISTER_DRIVER_START(&display)
|
||||||
|
FBTFT_COMPATIBLE("sitronix,st7789v")
|
||||||
|
FBTFT_VARIANT_COMPATIBLE("fbtft,minipitft13", variant_minipitft13)
|
||||||
|
FBTFT_REGISTER_DRIVER_END(DRVNAME, &display);
|
||||||
|
|
||||||
MODULE_ALIAS("spi:" DRVNAME);
|
MODULE_ALIAS("spi:" DRVNAME);
|
||||||
MODULE_ALIAS("platform:" DRVNAME);
|
MODULE_ALIAS("platform:" DRVNAME);
|
||||||
|
|
@ -320,4 +445,4 @@ MODULE_ALIAS("platform:st7789v");
|
||||||
|
|
||||||
MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
|
MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
|
||||||
MODULE_AUTHOR("Dennis Menschel");
|
MODULE_AUTHOR("Dennis Menschel");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
@ -240,7 +240,7 @@ struct fbtft_par {
|
||||||
int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc);
|
int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc);
|
||||||
__printf(5, 6)
|
__printf(5, 6)
|
||||||
void fbtft_dbg_hex(const struct device *dev, int groupsize,
|
void fbtft_dbg_hex(const struct device *dev, int groupsize,
|
||||||
void *buf, size_t len, const char *fmt, ...);
|
const void *buf, size_t len, const char *fmt, ...);
|
||||||
struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
|
struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
struct fbtft_platform_data *pdata);
|
struct fbtft_platform_data *pdata);
|
||||||
|
|
@ -253,7 +253,7 @@ 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);
|
const struct of_device_id *dt_ids);
|
||||||
int fbtft_remove_common(struct device *dev, struct fb_info *info);
|
void fbtft_remove_common(struct device *dev, struct fb_info *info);
|
||||||
|
|
||||||
/* fbtft-io.c */
|
/* fbtft-io.c */
|
||||||
int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len);
|
int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len);
|
||||||
|
|
@ -282,11 +282,11 @@ static int fbtft_driver_probe_spi(struct spi_device *spi) \
|
||||||
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
|
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static int fbtft_driver_remove_spi(struct spi_device *spi) \
|
static void fbtft_driver_remove_spi(struct spi_device *spi) \
|
||||||
{ \
|
{ \
|
||||||
struct fb_info *info = spi_get_drvdata(spi); \
|
struct fb_info *info = spi_get_drvdata(spi); \
|
||||||
\
|
\
|
||||||
return fbtft_remove_common(&spi->dev, info); \
|
fbtft_remove_common(&spi->dev, info); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
|
static int fbtft_driver_probe_pdev(struct platform_device *pdev) \
|
||||||
|
|
@ -298,7 +298,8 @@ static int fbtft_driver_remove_pdev(struct platform_device *pdev) \
|
||||||
{ \
|
{ \
|
||||||
struct fb_info *info = platform_get_drvdata(pdev); \
|
struct fb_info *info = platform_get_drvdata(pdev); \
|
||||||
\
|
\
|
||||||
return fbtft_remove_common(&pdev->dev, info); \
|
fbtft_remove_common(&pdev->dev, info); \
|
||||||
|
return 0; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static const struct of_device_id dt_ids[] = {
|
static const struct of_device_id dt_ids[] = {
|
||||||
|
|
@ -343,7 +344,10 @@ static int __init fbtft_driver_module_init(void) \
|
||||||
ret = spi_register_driver(&fbtft_driver_spi_driver); \
|
ret = spi_register_driver(&fbtft_driver_spi_driver); \
|
||||||
if (ret < 0) \
|
if (ret < 0) \
|
||||||
return ret; \
|
return ret; \
|
||||||
return platform_driver_register(&fbtft_driver_platform_driver); \
|
ret = platform_driver_register(&fbtft_driver_platform_driver); \
|
||||||
|
if (ret < 0) \
|
||||||
|
spi_unregister_driver(&fbtft_driver_spi_driver); \
|
||||||
|
return ret; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static void __exit fbtft_driver_module_exit(void) \
|
static void __exit fbtft_driver_module_exit(void) \
|
||||||
|
|
@ -355,6 +359,46 @@ 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_SPI_DRIVER(_name, _comp_vend, _comp_dev, _display) \
|
||||||
|
\
|
||||||
|
static const struct of_device_id dt_ids[] = { \
|
||||||
|
{ .compatible = _comp_vend "," _comp_dev }, \
|
||||||
|
{}, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
static int fbtft_driver_probe_spi(struct spi_device *spi) \
|
||||||
|
{ \
|
||||||
|
return fbtft_probe_common(_display, spi, NULL, dt_ids); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static void fbtft_driver_remove_spi(struct spi_device *spi) \
|
||||||
|
{ \
|
||||||
|
struct fb_info *info = spi_get_drvdata(spi); \
|
||||||
|
\
|
||||||
|
fbtft_remove_common(&spi->dev, info); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
MODULE_DEVICE_TABLE(of, dt_ids); \
|
||||||
|
\
|
||||||
|
static const struct spi_device_id spi_ids[] = { \
|
||||||
|
{ .name = _comp_dev }, \
|
||||||
|
{}, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
MODULE_DEVICE_TABLE(spi, spi_ids); \
|
||||||
|
\
|
||||||
|
static struct spi_driver fbtft_driver_spi_driver = { \
|
||||||
|
.driver = { \
|
||||||
|
.name = _name, \
|
||||||
|
.of_match_table = dt_ids, \
|
||||||
|
}, \
|
||||||
|
.id_table = spi_ids, \
|
||||||
|
.probe = fbtft_driver_probe_spi, \
|
||||||
|
.remove = fbtft_driver_remove_spi, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
module_spi_driver(fbtft_driver_spi_driver);
|
||||||
|
|
||||||
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
|
#define FBTFT_REGISTER_DRIVER(_name, _compatible, _display) \
|
||||||
FBTFT_REGISTER_DRIVER_START(_display) \
|
FBTFT_REGISTER_DRIVER_START(_display) \
|
||||||
FBTFT_COMPATIBLE(_compatible) \
|
FBTFT_COMPATIBLE(_compatible) \
|
||||||
|
|
@ -433,4 +477,4 @@ do { \
|
||||||
(num) * sizeof(type), format, ##arg); \
|
(num) * sizeof(type), format, ##arg); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif /* __LINUX_FBTFT_H */
|
#endif /* __LINUX_FBTFT_H */
|
||||||
14
st7789_module/reload.sh
Normal file
14
st7789_module/reload.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Unload
|
||||||
|
sudo dtoverlay -r drm-minipitft114
|
||||||
|
sudo modprobe -r fb_st7789v
|
||||||
|
sudo modprobe -r fbtft
|
||||||
|
|
||||||
|
# Compile
|
||||||
|
sudo make
|
||||||
|
|
||||||
|
# Load again
|
||||||
|
sudo modprobe fbtft
|
||||||
|
sudo insmod ./fb_st7789v.ko
|
||||||
|
sudo dtoverlay drm-minipitft114
|
||||||
Loading…
Reference in a new issue