cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fb_tls8204.c (3601B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * FB driver for the TLS8204 LCD Controller
      4 *
      5 * The display is monochrome and the video memory is RGB565.
      6 * Any pixel value except 0 turns the pixel on.
      7 *
      8 * Copyright (C) 2013 Noralf Tronnes
      9 * Copyright (C) 2014 Michael Hope (adapted for the TLS8204)
     10 */
     11
     12#include <linux/module.h>
     13#include <linux/kernel.h>
     14#include <linux/init.h>
     15#include <linux/gpio/consumer.h>
     16#include <linux/spi/spi.h>
     17#include <linux/delay.h>
     18
     19#include "fbtft.h"
     20
     21#define DRVNAME		"fb_tls8204"
     22#define WIDTH		84
     23#define HEIGHT		48
     24#define TXBUFLEN	WIDTH
     25
     26/* gamma is used to control contrast in this driver */
     27#define DEFAULT_GAMMA	"40"
     28
     29static unsigned int bs = 4;
     30module_param(bs, uint, 0000);
     31MODULE_PARM_DESC(bs, "BS[2:0] Bias voltage level: 0-7 (default: 4)");
     32
     33static int init_display(struct fbtft_par *par)
     34{
     35	par->fbtftops.reset(par);
     36
     37	/* Enter extended command mode */
     38	write_reg(par, 0x21);	/* 5:1  1
     39				 * 2:0  PD - Powerdown control: chip is active
     40				 * 1:0  V  - Entry mode: horizontal addressing
     41				 * 0:1  H  - Extended instruction set control:
     42				 *	     extended
     43				 */
     44
     45	/* H=1 Bias system */
     46	write_reg(par, 0x10 | (bs & 0x7));
     47				/* 4:1  1
     48				 * 3:0  0
     49				 * 2:x  BS2 - Bias System
     50				 * 1:x  BS1
     51				 * 0:x  BS0
     52				 */
     53
     54	/* Set the address of the first display line. */
     55	write_reg(par, 0x04 | (64 >> 6));
     56	write_reg(par, 0x40 | (64 & 0x3F));
     57
     58	/* Enter H=0 standard command mode */
     59	write_reg(par, 0x20);
     60
     61	/* H=0 Display control */
     62	write_reg(par, 0x08 | 4);
     63				/* 3:1  1
     64				 * 2:1  D - DE: 10=normal mode
     65				 * 1:0  0
     66				 * 0:0  E
     67				 */
     68
     69	return 0;
     70}
     71
     72static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
     73{
     74	/* H=0 Set X address of RAM */
     75	write_reg(par, 0x80);	/* 7:1  1
     76				 * 6-0: X[6:0] - 0x00
     77				 */
     78
     79	/* H=0 Set Y address of RAM */
     80	write_reg(par, 0x40);	/* 7:0  0
     81				 * 6:1  1
     82				 * 2-0: Y[2:0] - 0x0
     83				 */
     84}
     85
     86static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
     87{
     88	u16 *vmem16 = (u16 *)par->info->screen_buffer;
     89	int x, y, i;
     90	int ret = 0;
     91
     92	for (y = 0; y < HEIGHT / 8; y++) {
     93		u8 *buf = par->txbuf.buf;
     94		/* The display is 102x68 but the LCD is 84x48.
     95		 * Set the write pointer at the start of each row.
     96		 */
     97		gpiod_set_value(par->gpio.dc, 0);
     98		write_reg(par, 0x80 | 0);
     99		write_reg(par, 0x40 | y);
    100
    101		for (x = 0; x < WIDTH; x++) {
    102			u8 ch = 0;
    103
    104			for (i = 0; i < 8 * WIDTH; i += WIDTH) {
    105				ch >>= 1;
    106				if (vmem16[(y * 8 * WIDTH) + i + x])
    107					ch |= 0x80;
    108			}
    109			*buf++ = ch;
    110		}
    111		/* Write the row */
    112		gpiod_set_value(par->gpio.dc, 1);
    113		ret = par->fbtftops.write(par, par->txbuf.buf, WIDTH);
    114		if (ret < 0) {
    115			dev_err(par->info->device,
    116				"write failed and returned: %d\n", ret);
    117			break;
    118		}
    119	}
    120
    121	return ret;
    122}
    123
    124static int set_gamma(struct fbtft_par *par, u32 *curves)
    125{
    126	/* apply mask */
    127	curves[0] &= 0x7F;
    128
    129	write_reg(par, 0x21); /* turn on extended instruction set */
    130	write_reg(par, 0x80 | curves[0]);
    131	write_reg(par, 0x20); /* turn off extended instruction set */
    132
    133	return 0;
    134}
    135
    136static struct fbtft_display display = {
    137	.regwidth = 8,
    138	.width = WIDTH,
    139	.height = HEIGHT,
    140	.txbuflen = TXBUFLEN,
    141	.gamma_num = 1,
    142	.gamma_len = 1,
    143	.gamma = DEFAULT_GAMMA,
    144	.fbtftops = {
    145		.init_display = init_display,
    146		.set_addr_win = set_addr_win,
    147		.write_vmem = write_vmem,
    148		.set_gamma = set_gamma,
    149	},
    150	.backlight = 1,
    151};
    152
    153FBTFT_REGISTER_DRIVER(DRVNAME, "teralane,tls8204", &display);
    154
    155MODULE_ALIAS("spi:" DRVNAME);
    156MODULE_ALIAS("spi:tls8204");
    157
    158MODULE_DESCRIPTION("FB driver for the TLS8204 LCD Controller");
    159MODULE_AUTHOR("Michael Hope");
    160MODULE_LICENSE("GPL");