Skip to content

Commit

Permalink
staging: fbtft: add support for ST7789V display controller
Browse files Browse the repository at this point in the history
This patch adds support for the Sitronix ST7789V display controller.
The controller is intended for small color displays with a resolution
of up to 320x240 pixels.

Signed-off-by: Dennis Menschel <menschel-d@posteo.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dennis Menschel authored and Greg Kroah-Hartman committed Oct 13, 2015
1 parent 56b3152 commit d4c402f
Show file tree
Hide file tree
Showing 3 changed files with 301 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/staging/fbtft/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ config FB_TFT_ST7735R
help
Generic Framebuffer support for ST7735R

config FB_TFT_ST7789V
tristate "FB driver for the ST7789V LCD Controller"
depends on FB_TFT
help
This enables generic framebuffer support for the Sitronix ST7789V
display controller. The controller is intended for small color
displays with a resolution of up to 320x240 pixels.

Say Y if you have such a display that utilizes this controller.

config FB_TFT_TINYLCD
tristate "FB driver for tinylcd.com display"
depends on FB_TFT
Expand Down
1 change: 1 addition & 0 deletions drivers/staging/fbtft/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ obj-$(CONFIG_FB_TFT_SSD1306) += fb_ssd1306.o
obj-$(CONFIG_FB_TFT_SSD1331) += fb_ssd1331.o
obj-$(CONFIG_FB_TFT_SSD1351) += fb_ssd1351.o
obj-$(CONFIG_FB_TFT_ST7735R) += fb_st7735r.o
obj-$(CONFIG_FB_TFT_ST7789V) += fb_st7789v.o
obj-$(CONFIG_FB_TFT_TINYLCD) += fb_tinylcd.o
obj-$(CONFIG_FB_TFT_TLS8204) += fb_tls8204.o
obj-$(CONFIG_FB_TFT_UC1611) += fb_uc1611.o
Expand Down
290 changes: 290 additions & 0 deletions drivers/staging/fbtft/fb_st7789v.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,290 @@
/*
* FB driver for the ST7789V LCD Controller
*
* Copyright (C) 2015 Dennis Menschel
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include "fbtft.h"

#define DRVNAME "fb_st7789v"

#define DEFAULT_GAMMA \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25\n" \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25"

/**
* enum st7789v_command - ST7789V display controller commands
*
* @SLPOUT: sleep out
* @DISPOFF: display off
* @DISPON: display on
* @CASET: column address set
* @RASET: row address set
* @RAMRW: memory write
* @MADCTL: memory data access control
* @COLMOD: interface pixel format
* @PORCTRL: porch setting
* @GCTRL: gate control
* @VCOMS: VCOM setting
* @VDVVRHEN: VDV and VRH command enable
* @VRHS: VRH set
* @VDVS: VDV set
* @VCMOFSET: VCOM offset set
* @PWCTRL1: power control 1
* @PVGAMCTRL: positive voltage gamma control
* @NVGAMCTRL: negative voltage gamma control
*
* The command names are the same as those found in the datasheet to ease
* looking up their semantics and usage.
*
* Note that the ST7789V display controller offers quite a few more commands
* which have been omitted from this list as they are not used at the moment.
*/
enum st7789v_command {
SLPOUT = 0x11,
DISPOFF = 0x28,
DISPON = 0x29,
CASET = 0x2A,
RASET = 0x2B,
RAMRW = 0x2C,
MADCTL = 0x36,
COLMOD = 0x3A,
PORCTRL = 0xB2,
GCTRL = 0xB7,
VCOMS = 0xBB,
VDVVRHEN = 0xC2,
VRHS = 0xC3,
VDVS = 0xC4,
VCMOFSET = 0xC5,
PWCTRL1 = 0xD0,
PVGAMCTRL = 0xE0,
NVGAMCTRL = 0xE1,
};

#define MADCTL_BGR BIT(3) /* bitmask for RGB/BGR order */
#define MADCTL_MV BIT(5) /* bitmask for page/column order */
#define MADCTL_MX BIT(6) /* bitmask for column address order */
#define MADCTL_MY BIT(7) /* bitmask for page address order */

/**
* default_init_sequence - default initialization sequence for ST7789V
*
* Most of the commands in this init sequence set their parameters to the
* same default values which are already in place after the display has been
* powered up. (The main exception to this rule is the pixel format which
* would default to 18 instead of 16 bit per pixel.)
* Nonetheless, this sequence can be used as a template for concrete
* displays which usually need some adjustments.
*/
static int default_init_sequence[] = {
/* turn off sleep mode */
-1, SLPOUT,
-2, 120,

/* set pixel format to RGB-565 */
-1, COLMOD, 0x05,

-1, PORCTRL, 0x08, 0x08, 0x00, 0x22, 0x22,

/*
* VGH = 13.26V
* VGL = -10.43V
*/
-1, GCTRL, 0x35,

/*
* VDV and VRH register values come from command write
* (instead of NVM)
*/
-1, VDVVRHEN, 0x01, 0xFF,

/*
* VAP = 4.1V + (VCOM + VCOM offset + 0.5 * VDV)
* VAN = -4.1V + (VCOM + VCOM offset + 0.5 * VDV)
*/
-1, VRHS, 0x0B,

/* VDV = 0V */
-1, VDVS, 0x20,

/* VCOM = 0.9V */
-1, VCOMS, 0x20,

/* VCOM offset = 0V */
-1, VCMOFSET, 0x20,

/*
* AVDD = 6.8V
* AVCL = -4.8V
* VDS = 2.3V
*/
-1, PWCTRL1, 0xA4, 0xA1,

-1, DISPON,

-3,
};

/**
* set_addr_win() - configure display area to use
*
* @par: FBTFT parameter object
* @xs: first active pixel of x-axis
* @ys: first active pixel of y-axis
* @xe: last active pixel of x-axis
* @ye: last active pixel of y-axis
*/
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
write_reg(par, CASET, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
write_reg(par, RASET, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
write_reg(par, RAMRW);
}

/**
* set_var() - apply LCD properties like rotation and BGR mode
*
* @par: FBTFT parameter object
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_var(struct fbtft_par *par)
{
u8 madctl_par = 0;

if (par->bgr)
madctl_par |= MADCTL_BGR;
switch (par->info->var.rotate) {
case 0:
break;
case 90:
madctl_par |= (MADCTL_MV | MADCTL_MY);
break;
case 180:
madctl_par |= (MADCTL_MX | MADCTL_MY);
break;
case 270:
madctl_par |= (MADCTL_MV | MADCTL_MX);
break;
default:
return -EINVAL;
}
write_reg(par, MADCTL, madctl_par);
return 0;
}

/**
* set_gamma() - set gamma curves
*
* @par: FBTFT parameter object
* @curves: gamma curves
*
* Before the gamma curves are applied, they are preprocessed with a bitmask
* to ensure syntactically correct input for the display controller.
* This implies that the curves input parameter might be changed by this
* function and that illegal gamma values are auto-corrected and not
* reported as errors.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_gamma(struct fbtft_par *par, unsigned long *curves)
{
int i;
int j;
int c; /* curve index offset */

/*
* Bitmasks for gamma curve command parameters.
* The masks are the same for both positive and negative voltage
* gamma curves.
*/
const u8 gamma_par_mask[] = {
0xFF, /* V63[3:0], V0[3:0]*/
0x3F, /* V1[5:0] */
0x3F, /* V2[5:0] */
0x1F, /* V4[4:0] */
0x1F, /* V6[4:0] */
0x3F, /* J0[1:0], V13[3:0] */
0x7F, /* V20[6:0] */
0x77, /* V36[2:0], V27[2:0] */
0x7F, /* V43[6:0] */
0x3F, /* J1[1:0], V50[3:0] */
0x1F, /* V57[4:0] */
0x1F, /* V59[4:0] */
0x3F, /* V61[5:0] */
0x3F, /* V62[5:0] */
};

for (i = 0; i < par->gamma.num_curves; i++) {
c = i * par->gamma.num_values;
for (j = 0; j < par->gamma.num_values; j++)
curves[c + j] &= gamma_par_mask[j];
write_reg(
par, PVGAMCTRL + i,
curves[c + 0], curves[c + 1], curves[c + 2],
curves[c + 3], curves[c + 4], curves[c + 5],
curves[c + 6], curves[c + 7], curves[c + 8],
curves[c + 9], curves[c + 10], curves[c + 11],
curves[c + 12], curves[c + 13]);
}
return 0;
}

/**
* blank() - blank the display
*
* @par: FBTFT parameter object
* @on: whether to enable or disable blanking the display
*
* Return: 0 on success, < 0 if error occurred.
*/
static int blank(struct fbtft_par *par, bool on)
{
if (on)
write_reg(par, DISPOFF);
else
write_reg(par, DISPON);
return 0;
}

static struct fbtft_display display = {
.regwidth = 8,
.width = 240,
.height = 320,
.init_sequence = default_init_sequence,
.gamma_num = 2,
.gamma_len = 14,
.gamma = DEFAULT_GAMMA,
.fbtftops = {
.set_addr_win = set_addr_win,
.set_var = set_var,
.set_gamma = set_gamma,
.blank = blank,
},
};

FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7789v", &display);

MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7789v");
MODULE_ALIAS("platform:st7789v");

MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
MODULE_AUTHOR("Dennis Menschel");
MODULE_LICENSE("GPL");

0 comments on commit d4c402f

Please sign in to comment.