From b3e2e8e673fa0180ed48630e8a928d50875c8cc1 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 19 Feb 2021 10:25:01 +0000 Subject: [PATCH 0286/1085] staging: fbtft: Add minipitft13 variant The Adafruit Mini-PiTFT13 display needs offsets applying when rotated, so use the "variant" mechanism to select a custom set_addr_win method using a dedicated compatible string of "fbtft,minipitft13". See: https://github.com/raspberrypi/firmware/issues/1524 Signed-off-by: Phil Elwell --- drivers/staging/fbtft/fb_st7789v.c | 44 +++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -75,6 +75,11 @@ enum st7789v_command { static struct completion panel_te; /* completion for panel TE line */ static int irq_te; /* Linux IRQ for LCD TE line */ +static u32 col_offset = 0; +static u32 row_offset = 0; +static u8 col_hack_fix_offset = 0; +static short x_offset = 0; +static short y_offset = 0; static irqreturn_t panel_te_handler(int irq, void *data) { @@ -261,6 +266,22 @@ static int write_vmem(struct fbtft_par * return ret; } +static void minipitft13_set_addr_win(struct fbtft_par *par, int xs, int ys, + int xe, int ye) +{ + xs += x_offset; + xe += x_offset; + ys += y_offset; + ye += y_offset; + write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, + xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF); + + write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, + ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF); + + write_reg(par, MIPI_DCS_WRITE_MEMORY_START); +} + /** * set_var() - apply LCD properties like rotation and BGR mode * @@ -271,20 +292,32 @@ static int write_vmem(struct fbtft_par * static int set_var(struct fbtft_par *par) { u8 madctl_par = 0; + struct fbtft_display *display = &par->pdata->display; + u32 width = display->width; + u32 height = display->height; if (par->bgr) madctl_par |= MADCTL_BGR; switch (par->info->var.rotate) { case 0: + x_offset = 0; + y_offset = 0; break; case 90: madctl_par |= (MADCTL_MV | MADCTL_MY); + x_offset = (320 - height) - row_offset; + y_offset = (240 - width) - col_offset; break; case 180: madctl_par |= (MADCTL_MX | MADCTL_MY); + x_offset = (240 - width) - col_offset + col_hack_fix_offset; + // hack tweak to account for extra pixel width to make even + y_offset = (320 - height) - row_offset; break; case 270: madctl_par |= (MADCTL_MV | MADCTL_MX); + x_offset = row_offset; + y_offset = col_offset; break; default: return -EINVAL; @@ -382,7 +415,16 @@ static struct fbtft_display display = { }, }; -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("platform:" DRVNAME);