mirror of https://gitee.com/openkylin/linux.git
staging: fbtft: fb_sh1106: use own implementation of write_register
The default implementation of write_register keeps DC low for the first byte only. SH1106 requires DC to be low for all bytes of a multi-byte command. To deal with this limitation we currently use a separate call to write_reg for each single command byte what is not really efficient. Therefore override the default implementation of write_register with an own one which keeps DC low for all bytes. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
18c6142168
commit
82472b8618
|
@ -27,17 +27,6 @@
|
||||||
#define WIDTH 128
|
#define WIDTH 128
|
||||||
#define HEIGHT 64
|
#define HEIGHT 64
|
||||||
|
|
||||||
/*
|
|
||||||
* write_reg() caveat:
|
|
||||||
*
|
|
||||||
* This doesn't work because D/C has to be LOW for both values:
|
|
||||||
* write_reg(par, val1, val2);
|
|
||||||
*
|
|
||||||
* Do it like this:
|
|
||||||
* write_reg(par, val1);
|
|
||||||
* write_reg(par, val2);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Init sequence based on the Adafruit SSD1306 Arduino library */
|
/* Init sequence based on the Adafruit SSD1306 Arduino library */
|
||||||
static int init_display(struct fbtft_par *par)
|
static int init_display(struct fbtft_par *par)
|
||||||
{
|
{
|
||||||
|
@ -59,16 +48,13 @@ static int init_display(struct fbtft_par *par)
|
||||||
write_reg(par, 0xAE);
|
write_reg(par, 0xAE);
|
||||||
|
|
||||||
/* Set Display Clock Divide Ratio/ Oscillator Frequency */
|
/* Set Display Clock Divide Ratio/ Oscillator Frequency */
|
||||||
write_reg(par, 0xD5);
|
write_reg(par, 0xD5, 0x80);
|
||||||
write_reg(par, 0x80);
|
|
||||||
|
|
||||||
/* Set Multiplex Ratio */
|
/* Set Multiplex Ratio */
|
||||||
write_reg(par, 0xA8);
|
write_reg(par, 0xA8, par->info->var.yres - 1);
|
||||||
write_reg(par, par->info->var.yres - 1);
|
|
||||||
|
|
||||||
/* Set Display Offset */
|
/* Set Display Offset */
|
||||||
write_reg(par, 0xD3);
|
write_reg(par, 0xD3, 0x00);
|
||||||
write_reg(par, 0x0);
|
|
||||||
|
|
||||||
/* Set Display Start Line */
|
/* Set Display Start Line */
|
||||||
write_reg(par, 0x40 | 0x0);
|
write_reg(par, 0x40 | 0x0);
|
||||||
|
@ -82,24 +68,21 @@ static int init_display(struct fbtft_par *par)
|
||||||
write_reg(par, 0xC8);
|
write_reg(par, 0xC8);
|
||||||
|
|
||||||
/* Set COM Pins Hardware Configuration */
|
/* Set COM Pins Hardware Configuration */
|
||||||
write_reg(par, 0xDA);
|
|
||||||
if (par->info->var.yres == 64)
|
if (par->info->var.yres == 64)
|
||||||
/* A[4]=1b, Alternative COM pin configuration */
|
/* A[4]=1b, Alternative COM pin configuration */
|
||||||
write_reg(par, 0x12);
|
write_reg(par, 0xDA, 0x12);
|
||||||
else if (par->info->var.yres == 48)
|
else if (par->info->var.yres == 48)
|
||||||
/* A[4]=1b, Alternative COM pin configuration */
|
/* A[4]=1b, Alternative COM pin configuration */
|
||||||
write_reg(par, 0x12);
|
write_reg(par, 0xDA, 0x12);
|
||||||
else
|
else
|
||||||
/* A[4]=0b, Sequential COM pin configuration */
|
/* A[4]=0b, Sequential COM pin configuration */
|
||||||
write_reg(par, 0x02);
|
write_reg(par, 0xDA, 0x02);
|
||||||
|
|
||||||
/* Set Pre-charge Period */
|
/* Set Pre-charge Period */
|
||||||
write_reg(par, 0xD9);
|
write_reg(par, 0xD9, 0xF1);
|
||||||
write_reg(par, 0xF1);
|
|
||||||
|
|
||||||
/* Set VCOMH Deselect Level */
|
/* Set VCOMH Deselect Level */
|
||||||
write_reg(par, 0xDB);
|
write_reg(par, 0xDB, 0x40);
|
||||||
write_reg(par, 0x40);
|
|
||||||
|
|
||||||
/* Set Display ON */
|
/* Set Display ON */
|
||||||
write_reg(par, 0xAF);
|
write_reg(par, 0xAF);
|
||||||
|
@ -130,8 +113,7 @@ static int set_gamma(struct fbtft_par *par, u32 *curves)
|
||||||
curves[0] &= 0xFF;
|
curves[0] &= 0xFF;
|
||||||
|
|
||||||
/* Set Contrast Control for BANK0 */
|
/* Set Contrast Control for BANK0 */
|
||||||
write_reg(par, 0x81);
|
write_reg(par, 0x81, curves[0]);
|
||||||
write_reg(par, curves[0]);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -148,11 +130,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
|
||||||
page_end = DIV_ROUND_UP(offset + len, 8 * 2 * xres);
|
page_end = DIV_ROUND_UP(offset + len, 8 * 2 * xres);
|
||||||
|
|
||||||
for (page = page_start; page < page_end; page++) {
|
for (page = page_start; page < page_end; page++) {
|
||||||
/* set page */
|
/* set page and set column to 2 because of vidmem width 132 */
|
||||||
write_reg(par, 0xb0 | page);
|
write_reg(par, 0xb0 | page, 0x00 | 2, 0x10 | 0);
|
||||||
/* set column to 2 to compensate for vidmem width 132 */
|
|
||||||
write_reg(par, 0x00 | 2);
|
|
||||||
write_reg(par, 0x10 | 0);
|
|
||||||
|
|
||||||
memset(buf, 0, xres);
|
memset(buf, 0, xres);
|
||||||
for (x = 0; x < xres; x++)
|
for (x = 0; x < xres; x++)
|
||||||
|
@ -173,6 +152,27 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void write_register(struct fbtft_par *par, int len, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
|
va_start(args, len);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
par->buf[i] = va_arg(args, unsigned int);
|
||||||
|
|
||||||
|
/* keep DC low for all command bytes to transfer */
|
||||||
|
gpio_set_value(par->gpio.dc, 0);
|
||||||
|
|
||||||
|
ret = par->fbtftops.write(par, par->buf, len);
|
||||||
|
if (ret < 0)
|
||||||
|
dev_err(par->info->device,
|
||||||
|
"write() failed and returned %d\n", ret);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
static struct fbtft_display display = {
|
static struct fbtft_display display = {
|
||||||
.regwidth = 8,
|
.regwidth = 8,
|
||||||
.width = WIDTH,
|
.width = WIDTH,
|
||||||
|
@ -184,6 +184,7 @@ static struct fbtft_display display = {
|
||||||
.gamma = "cd",
|
.gamma = "cd",
|
||||||
.fbtftops = {
|
.fbtftops = {
|
||||||
.write_vmem = write_vmem,
|
.write_vmem = write_vmem,
|
||||||
|
.write_register = write_register,
|
||||||
.init_display = init_display,
|
.init_display = init_display,
|
||||||
.set_addr_win = set_addr_win,
|
.set_addr_win = set_addr_win,
|
||||||
.blank = blank,
|
.blank = blank,
|
||||||
|
|
Loading…
Reference in New Issue