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_hx8340bn.c (6010B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * FB driver for the HX8340BN LCD Controller
      4 *
      5 * This display uses 9-bit SPI: Data/Command bit + 8 data bits
      6 * For platforms that doesn't support 9-bit, the driver is capable
      7 * of emulating this using 8-bit transfer.
      8 * This is done by transferring eight 9-bit words in 9 bytes.
      9 *
     10 * Copyright (C) 2013 Noralf Tronnes
     11 */
     12
     13#include <linux/module.h>
     14#include <linux/kernel.h>
     15#include <linux/init.h>
     16#include <linux/vmalloc.h>
     17#include <linux/spi/spi.h>
     18#include <linux/delay.h>
     19#include <video/mipi_display.h>
     20
     21#include "fbtft.h"
     22
     23#define DRVNAME		"fb_hx8340bn"
     24#define WIDTH		176
     25#define HEIGHT		220
     26#define TXBUFLEN	(4 * PAGE_SIZE)
     27#define DEFAULT_GAMMA	"1 3 0E 5 0 2 09 0 6 1 7 1 0 2 2\n" \
     28			"3 3 17 8 4 7 05 7 6 0 3 1 6 0 0 "
     29
     30static bool emulate;
     31module_param(emulate, bool, 0000);
     32MODULE_PARM_DESC(emulate, "Force emulation in 9-bit mode");
     33
     34static int init_display(struct fbtft_par *par)
     35{
     36	par->fbtftops.reset(par);
     37
     38	/* BTL221722-276L startup sequence, from datasheet */
     39
     40	/*
     41	 * SETEXTCOM: Set extended command set (C1h)
     42	 * This command is used to set extended command set access enable.
     43	 * Enable: After command (C1h), must write: ffh,83h,40h
     44	 */
     45	write_reg(par, 0xC1, 0xFF, 0x83, 0x40);
     46
     47	/*
     48	 * Sleep out
     49	 * This command turns off sleep mode.
     50	 * In this mode the DC/DC converter is enabled, Internal oscillator
     51	 * is started, and panel scanning is started.
     52	 */
     53	write_reg(par, 0x11);
     54	mdelay(150);
     55
     56	/* Undoc'd register? */
     57	write_reg(par, 0xCA, 0x70, 0x00, 0xD9);
     58
     59	/*
     60	 * SETOSC: Set Internal Oscillator (B0h)
     61	 * This command is used to set internal oscillator related settings
     62	 *	OSC_EN: Enable internal oscillator
     63	 *	Internal oscillator frequency: 125% x 2.52MHz
     64	 */
     65	write_reg(par, 0xB0, 0x01, 0x11);
     66
     67	/* Drive ability setting */
     68	write_reg(par, 0xC9, 0x90, 0x49, 0x10, 0x28, 0x28, 0x10, 0x00, 0x06);
     69	mdelay(20);
     70
     71	/*
     72	 * SETPWCTR5: Set Power Control 5(B5h)
     73	 * This command is used to set VCOM Low and VCOM High Voltage
     74	 * VCOMH 0110101 :  3.925
     75	 * VCOML 0100000 : -1.700
     76	 * 45h=69  VCOMH: "VMH" + 5d   VCOML: "VMH" + 5d
     77	 */
     78	write_reg(par, 0xB5, 0x35, 0x20, 0x45);
     79
     80	/*
     81	 * SETPWCTR4: Set Power Control 4(B4h)
     82	 *	VRH[4:0]:	Specify the VREG1 voltage adjusting.
     83	 *			VREG1 voltage is for gamma voltage setting.
     84	 *	BT[2:0]:	Switch the output factor of step-up circuit 2
     85	 *			for VGH and VGL voltage generation.
     86	 */
     87	write_reg(par, 0xB4, 0x33, 0x25, 0x4C);
     88	mdelay(10);
     89
     90	/*
     91	 * Interface Pixel Format (3Ah)
     92	 * This command is used to define the format of RGB picture data,
     93	 * which is to be transfer via the system and RGB interface.
     94	 * RGB interface: 16 Bit/Pixel
     95	 */
     96	write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
     97
     98	/*
     99	 * Display on (29h)
    100	 * This command is used to recover from DISPLAY OFF mode.
    101	 * Output from the Frame Memory is enabled.
    102	 */
    103	write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
    104	mdelay(10);
    105
    106	return 0;
    107}
    108
    109static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
    110{
    111	write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS, 0x00, xs, 0x00, xe);
    112	write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS, 0x00, ys, 0x00, ye);
    113	write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
    114}
    115
    116static int set_var(struct fbtft_par *par)
    117{
    118	/* MADCTL - Memory data access control */
    119	/* RGB/BGR can be set with H/W pin SRGB and MADCTL BGR bit */
    120#define MY BIT(7)
    121#define MX BIT(6)
    122#define MV BIT(5)
    123	switch (par->info->var.rotate) {
    124	case 0:
    125		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, par->bgr << 3);
    126		break;
    127	case 270:
    128		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
    129			  MX | MV | (par->bgr << 3));
    130		break;
    131	case 180:
    132		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
    133			  MX | MY | (par->bgr << 3));
    134		break;
    135	case 90:
    136		write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
    137			  MY | MV | (par->bgr << 3));
    138		break;
    139	}
    140
    141	return 0;
    142}
    143
    144/*
    145 * Gamma Curve selection, GC (only GC0 can be customized):
    146 *   0 = 2.2, 1 = 1.8, 2 = 2.5, 3 = 1.0
    147 * Gamma string format:
    148 *   OP0 OP1 CP0 CP1 CP2 CP3 CP4 MP0 MP1 MP2 MP3 MP4 MP5 CGM0 CGM1
    149 *   ON0 ON1 CN0 CN1 CN2 CN3 CN4 MN0 MN1 MN2 MN3 MN4 MN5 XXXX  GC
    150 */
    151#define CURVE(num, idx)  curves[(num) * par->gamma.num_values + (idx)]
    152static int set_gamma(struct fbtft_par *par, u32 *curves)
    153{
    154	static const unsigned long mask[] = {
    155		0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x07, 0x07, 0x07,
    156		0x07, 0x07, 0x07, 0x03, 0x03, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f,
    157		0x0f, 0x1f, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00,
    158	};
    159	int i, j;
    160
    161	/* apply mask */
    162	for (i = 0; i < par->gamma.num_curves; i++)
    163		for (j = 0; j < par->gamma.num_values; j++)
    164			CURVE(i, j) &= mask[i * par->gamma.num_values + j];
    165
    166	/* Gamma Set (26h) */
    167	write_reg(par, MIPI_DCS_SET_GAMMA_CURVE, 1 << CURVE(1, 14));
    168
    169	if (CURVE(1, 14))
    170		return 0; /* only GC0 can be customized */
    171
    172	write_reg(par, 0xC2,
    173		  (CURVE(0, 8) << 4) | CURVE(0, 7),
    174		  (CURVE(0, 10) << 4) | CURVE(0, 9),
    175		  (CURVE(0, 12) << 4) | CURVE(0, 11),
    176		  CURVE(0, 2),
    177		  (CURVE(0, 4) << 4) | CURVE(0, 3),
    178		  CURVE(0, 5),
    179		  CURVE(0, 6),
    180		  (CURVE(0, 1) << 4) | CURVE(0, 0),
    181		  (CURVE(0, 14) << 2) | CURVE(0, 13));
    182
    183	write_reg(par, 0xC3,
    184		  (CURVE(1, 8) << 4) | CURVE(1, 7),
    185		  (CURVE(1, 10) << 4) | CURVE(1, 9),
    186		  (CURVE(1, 12) << 4) | CURVE(1, 11),
    187		  CURVE(1, 2),
    188		  (CURVE(1, 4) << 4) | CURVE(1, 3),
    189		  CURVE(1, 5),
    190		  CURVE(1, 6),
    191		  (CURVE(1, 1) << 4) | CURVE(1, 0));
    192
    193	mdelay(10);
    194
    195	return 0;
    196}
    197
    198#undef CURVE
    199
    200static struct fbtft_display display = {
    201	.regwidth = 8,
    202	.width = WIDTH,
    203	.height = HEIGHT,
    204	.txbuflen = TXBUFLEN,
    205	.gamma_num = 2,
    206	.gamma_len = 15,
    207	.gamma = DEFAULT_GAMMA,
    208	.fbtftops = {
    209		.init_display = init_display,
    210		.set_addr_win = set_addr_win,
    211		.set_var = set_var,
    212		.set_gamma = set_gamma,
    213	},
    214};
    215
    216FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", &display);
    217
    218MODULE_ALIAS("spi:" DRVNAME);
    219MODULE_ALIAS("platform:" DRVNAME);
    220MODULE_ALIAS("spi:hx8340bn");
    221MODULE_ALIAS("platform:hx8340bn");
    222
    223MODULE_DESCRIPTION("FB driver for the HX8340BN LCD Controller");
    224MODULE_AUTHOR("Noralf Tronnes");
    225MODULE_LICENSE("GPL");