linux: version release v4.1.5
[flash]: add GSS01GSAK1/GSS02GSAK1 to support list [flash]: add FM25S01B/PY25Q64HA to support list [panel]: add new spi panel jd9853 Change-Id: Id52d6c3df02215564a4a923e63f973ad192610c9
This commit is contained in:
@ -11,7 +11,7 @@
|
||||
#include <linux/mtd/rawnand.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <linux/jiffies.h>
|
||||
#include "cvsnfc_common.h"
|
||||
#include "cvsnfc_spi_ids.h"
|
||||
#include "cvsnfc.h"
|
||||
@ -463,8 +463,10 @@ static void cvsnfc_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl)
|
||||
static int cvsnfc_waitfunc(struct nand_chip *chip)
|
||||
{
|
||||
unsigned int regval;
|
||||
unsigned int deadline = 0;
|
||||
struct cvsnfc_host *host = nand_get_controller_data(chip);
|
||||
unsigned long start_time = jiffies;
|
||||
/* 4ms */
|
||||
unsigned long max_erase_time = 4 * 3;
|
||||
|
||||
pr_debug("=>%s\n", __func__);
|
||||
|
||||
@ -474,9 +476,7 @@ static int cvsnfc_waitfunc(struct nand_chip *chip)
|
||||
if (!(regval & STATUS_OIP_MASK))
|
||||
return NAND_STATUS_READY;
|
||||
|
||||
udelay(1);
|
||||
/* maybe need to sure */
|
||||
} while (deadline++ < (40 << 5));
|
||||
} while (jiffies_to_msecs(jiffies - start_time) < max_erase_time);
|
||||
|
||||
pr_err("%s timeout.\n", __func__);
|
||||
|
||||
@ -487,15 +487,16 @@ static int cvsnfc_waitfunc(struct nand_chip *chip)
|
||||
static int cvsnfc_dev_ready(struct nand_chip *chip)
|
||||
{
|
||||
unsigned int regval;
|
||||
unsigned int deadline = 0;
|
||||
struct cvsnfc_host *host = chip->priv;
|
||||
unsigned long start_time = jiffies;
|
||||
/* 4ms */
|
||||
unsigned long max_erase_time = 4 * 3;
|
||||
|
||||
do {
|
||||
spi_feature_op(host, GET_OP, STATUS_ADDR, ®val);
|
||||
if (!(regval & STATUS_OIP_MASK))
|
||||
return 1;
|
||||
udelay(1);
|
||||
} while (deadline++ < (40 << 5));
|
||||
} while (jiffies_to_msecs(jiffies - start_time) < max_erase_time);
|
||||
|
||||
pr_err("%s timeout.\n", __func__);
|
||||
|
||||
@ -785,15 +786,15 @@ static int parse_status_info(struct cvsnfc_host *host)
|
||||
|
||||
/* read SR */
|
||||
spi_feature_op(host, GET_OP, ecc_info->ecc_sr_addr, &ecc_status0);
|
||||
if (((ecc_status0 & 0x30) >> 4) == 0)
|
||||
return 0;
|
||||
|
||||
if (((ecc_status0 & 0x30) >> 4) == ecc_info->uncorr_val)
|
||||
return -EBADMSG;
|
||||
|
||||
mask = GENMASK(ecc_info->ecc_bits - 1, 0);
|
||||
status = (ecc_status0 >> ecc_info->ecc_bit_shift) & mask;
|
||||
|
||||
if (status == 0)
|
||||
return 0;
|
||||
|
||||
if (status == ecc_info->uncorr_val)
|
||||
return -EBADMSG;
|
||||
|
||||
if (ecc_info->ecc_sr_addr && !ecc_info->read_ecc_opcode && !ecc_info->ecc_mbf_addr) {
|
||||
if (ecc_info->remap) {
|
||||
corr_bit = ecc_info->remap[status] != 0xff ? ecc_info->remap[status] : 0;
|
||||
@ -819,7 +820,7 @@ static int parse_status_info(struct cvsnfc_host *host)
|
||||
spi_nand_read_eccsr(host, ecc_info->read_ecc_opcode, &ecc_status0);
|
||||
corr_bit = (ecc_status0 >> ecc_info->ecc_bit_shift) & mask;
|
||||
}
|
||||
pr_info("ECC CORR, correct bits %u\n", corr_bit);
|
||||
//pr_info("ECC CORR, correct bits %u\n", corr_bit);
|
||||
return corr_bit;
|
||||
}
|
||||
|
||||
@ -871,15 +872,7 @@ RETRY_READ_CMD:
|
||||
}
|
||||
|
||||
ret = parse_status_info(host);
|
||||
if (ret < 0) {
|
||||
mtd->ecc_stats.failed++;
|
||||
pr_info("%s caddr 0x%x, r_raddr 0x%x, len %d\n", __func__, col_addr, r_col_addr, len);
|
||||
} else {
|
||||
mtd->ecc_stats.corrected += ret;
|
||||
max_bitflips = max_t(unsigned int, max_bitflips, ret);
|
||||
}
|
||||
|
||||
return max_bitflips;
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
|
||||
@ -495,7 +495,7 @@ struct nand_ecc_info {
|
||||
uint8_t ecc_bits;
|
||||
uint8_t ecc_bit_shift;
|
||||
uint8_t uncorr_val;
|
||||
char *remap;
|
||||
short *remap;
|
||||
};
|
||||
|
||||
struct spi_nand_driver {
|
||||
|
||||
@ -60,7 +60,7 @@ static struct spi_nand_driver spi_nand_driver_toshiba = {
|
||||
*/
|
||||
|
||||
/* only for 8 bit threshold */
|
||||
char ECC_3bits_remap[8] = {0, 1, -1, 4, 0xff, 7, 0xff, 0xff };
|
||||
short ECC_3bits_remap[8] = {0, 1, -1, 4, 0xff, 7, 0xff, 0xff };
|
||||
|
||||
/*
|
||||
* ECCS1 ECCS0 Description
|
||||
@ -70,7 +70,7 @@ char ECC_3bits_remap[8] = {0, 1, -1, 4, 0xff, 7, 0xff, 0xff };
|
||||
* 1 1 Bit errors were detected and corrected,Bit errors count was equal
|
||||
* to the threshold bit count (8 bits)
|
||||
*/
|
||||
char ECC_XT26G11C[4] = {0, 1, -1, 8};
|
||||
short ECC_XT26G11C[4] = {0, 1, -1, 8};
|
||||
|
||||
/*
|
||||
* ECCS1 ECCS0 Description
|
||||
@ -79,7 +79,8 @@ char ECC_XT26G11C[4] = {0, 1, -1, 8};
|
||||
* 1 0 More than 4-bit error and not corrected.
|
||||
* 1 1 Reserved
|
||||
*/
|
||||
char ECC_2bits_remap[4] = {0, 1, -1, 0xff};
|
||||
short ECC_2bits_remap[4] = {0, 1, -1, 0xff};
|
||||
short ECC_1bits_remap[4] = {0, 1, -1, -1};
|
||||
|
||||
/*
|
||||
* ECCS1 ECCS0 ECCSE1 ECCSE0 Description
|
||||
@ -93,11 +94,62 @@ char ECC_2bits_remap[4] = {0, 1, -1, 0xff};
|
||||
* ECCS0-ECCS1 is located in field 4-5 of addr of 0xC0
|
||||
* ECCSE0-ECCSE1 is located in field 4-5 of addr of 0xF0
|
||||
*/
|
||||
char ECC_GD_4bit_remap[16] = {0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff};
|
||||
char ECC_GD_8bit_remap[16] = {0, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0, 8, 8, 8, 8};
|
||||
char ECC_HYF2G_remap[4] = {0, 1, -1, 14};
|
||||
short ECC_GD_4bit_remap[16] = {0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff};
|
||||
short ECC_GD_8bit_remap[16] = {0, 0, 0, 0, 4, 5, 6, 7, 0, 0, 0, 0, 8, 8, 8, 8};
|
||||
short ECC_HYF2G_remap[4] = {0, 1, -1, 14};
|
||||
|
||||
struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
|
||||
{
|
||||
{ .name = "GSS01GSAK1",
|
||||
.id = {0x52, 0xba, 0x13},
|
||||
.pagesize = SZ_2K,
|
||||
.chipsize = SZ_128,
|
||||
.erasesize = SZ_128K,
|
||||
.options = 0,
|
||||
.id_len = 3,
|
||||
.oobsize = 64,
|
||||
{ .strength_ds = 4,
|
||||
.step_ds = 512
|
||||
},
|
||||
},
|
||||
|
||||
{ .ecc_sr_addr = 0xc0,
|
||||
.ecc_mbf_addr = 0,
|
||||
.read_ecc_opcode = 0,
|
||||
.ecc_bits = 2,
|
||||
.ecc_bit_shift = 4,
|
||||
.uncorr_val = 0x2,
|
||||
.remap = ECC_2bits_remap,
|
||||
},
|
||||
.driver = &spi_nand_driver_general,
|
||||
.flags = 0
|
||||
},
|
||||
|
||||
{
|
||||
{ .name = "GSS02GSAK1",
|
||||
.id = {0x52, 0xba, 0x23},
|
||||
.pagesize = SZ_2K,
|
||||
.chipsize = SZ_256,
|
||||
.erasesize = SZ_128K,
|
||||
.options = 0,
|
||||
.id_len = 3,
|
||||
.oobsize = 128,
|
||||
{ .strength_ds = 4,
|
||||
.step_ds = 512
|
||||
},
|
||||
},
|
||||
|
||||
{ .ecc_sr_addr = 0xc0,
|
||||
.ecc_mbf_addr = 0,
|
||||
.read_ecc_opcode = 0,
|
||||
.ecc_bits = 2,
|
||||
.ecc_bit_shift = 4,
|
||||
.uncorr_val = 0x2,
|
||||
.remap = ECC_2bits_remap,
|
||||
},
|
||||
.driver = &spi_nand_driver_general,
|
||||
.flags = 0
|
||||
},
|
||||
|
||||
{
|
||||
{ .name = "F50L1G41LB",
|
||||
@ -524,7 +576,7 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
|
||||
.options = 0,
|
||||
.id_len = 2,
|
||||
.oobsize = SZ_64,
|
||||
{ .strength_ds = 8,
|
||||
{ .strength_ds = 4,
|
||||
.step_ds = SZ_512
|
||||
},
|
||||
},
|
||||
@ -535,7 +587,7 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
|
||||
.ecc_bits = 2,
|
||||
.ecc_bit_shift = 4,
|
||||
.uncorr_val = 0x2,
|
||||
.remap = ECC_GD_8bit_remap
|
||||
.remap = ECC_GD_4bit_remap
|
||||
},
|
||||
.driver = &spi_nand_driver_gd,
|
||||
.flags = 0
|
||||
@ -1220,6 +1272,84 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
|
||||
.flags = 0
|
||||
},
|
||||
|
||||
{
|
||||
{ .name = "FM25S01A",
|
||||
.id = {0xA1, 0xE4},
|
||||
.pagesize = SZ_2K,
|
||||
.chipsize = SZ_128,
|
||||
.erasesize = SZ_128K,
|
||||
.options = 0,
|
||||
.id_len = 2,
|
||||
.oobsize = SZ_64,
|
||||
{ .strength_ds = 1,
|
||||
.step_ds = SZ_512
|
||||
},
|
||||
},
|
||||
|
||||
{ .ecc_sr_addr = 0xc0,
|
||||
.ecc_mbf_addr = 0x0,
|
||||
.read_ecc_opcode = 0,
|
||||
.ecc_bits = 2,
|
||||
.ecc_bit_shift = 4,
|
||||
.uncorr_val = 0x2,
|
||||
.remap = ECC_1bits_remap
|
||||
},
|
||||
.driver = &spi_nand_driver_gd,
|
||||
.flags = 0
|
||||
},
|
||||
|
||||
{
|
||||
{ .name = "FM25S02A",
|
||||
.id = {0xA1, 0xE5},
|
||||
.pagesize = SZ_2K,
|
||||
.chipsize = SZ_256,
|
||||
.erasesize = SZ_128K,
|
||||
.options = 0,
|
||||
.id_len = 2,
|
||||
.oobsize = SZ_64,
|
||||
{ .strength_ds = 1,
|
||||
.step_ds = SZ_512
|
||||
},
|
||||
},
|
||||
|
||||
{ .ecc_sr_addr = 0xc0,
|
||||
.ecc_mbf_addr = 0x0,
|
||||
.read_ecc_opcode = 0,
|
||||
.ecc_bits = 2,
|
||||
.ecc_bit_shift = 4,
|
||||
.uncorr_val = 0x2,
|
||||
.remap = ECC_1bits_remap
|
||||
},
|
||||
.driver = &spi_nand_driver_gd,
|
||||
.flags = 0
|
||||
},
|
||||
|
||||
{
|
||||
{ .name = "FM25S01B",
|
||||
.id = {0xA1, 0xD4},
|
||||
.pagesize = SZ_2K,
|
||||
.chipsize = SZ_128,
|
||||
.erasesize = SZ_128K,
|
||||
.options = 0,
|
||||
.id_len = 2,
|
||||
.oobsize = SZ_128,
|
||||
{ .strength_ds = 8,
|
||||
.step_ds = SZ_512
|
||||
},
|
||||
},
|
||||
|
||||
{ .ecc_sr_addr = 0xc0,
|
||||
.ecc_mbf_addr = 0x0,
|
||||
.read_ecc_opcode = 0,
|
||||
.ecc_bits = 3,
|
||||
.ecc_bit_shift = 4,
|
||||
.uncorr_val = 0x2,
|
||||
.remap = ECC_3bits_remap
|
||||
},
|
||||
.driver = &spi_nand_driver_gd,
|
||||
.flags = 0
|
||||
},
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
@ -78,6 +78,10 @@ static const struct flash_info cvitek_parts[] = {
|
||||
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP | SECT_4K |
|
||||
SPI_NOR_4B_OPCODES)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
{ "XM25QH256B", INFO(0x206019, 0x0, 64 * 1024, 512,
|
||||
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP | SECT_4K |
|
||||
SPI_NOR_4B_OPCODES)
|
||||
.fixups = &sr1_bit6_qe_fixups },
|
||||
{ "MT25QL256A", INFO6(0x20ba19, 0x104400, 64 * 1024, 512,
|
||||
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
|
||||
SPI_NOR_QUAD_OP | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_FIX_DUMMY)
|
||||
@ -163,6 +167,9 @@ static const struct flash_info cvitek_parts[] = {
|
||||
{ "FM25W128A", INFO(0xA12818, 0x0, 64 * 1024, 256,
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
{ "BY25Q64ES", INFO(0x684017, 0x0, 64 * 1024, 128,
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
{ "BY25Q128AS", INFO(0x684018, 0x0, 64 * 1024, 256,
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
@ -173,6 +180,9 @@ static const struct flash_info cvitek_parts[] = {
|
||||
{ "PY25Q128HA", INFO(0x852018, 0x0, 64 * 1024, 256,
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
{ "PY25Q64HA", INFO(0x852017, 0x0, 64 * 1024, 128,
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
{ "P25Q64SH", INFO(0x856017, 0x0, 64 * 1024, 128,
|
||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
|
||||
.fixups = &sr_bit1_qe_fixups },
|
||||
|
||||
@ -88,6 +88,16 @@ config FB_TFT_ILI9486
|
||||
help
|
||||
Generic Framebuffer support for ILI9486
|
||||
|
||||
config FB_TFT_JD9853
|
||||
tristate "FB driver for the JD9853 LCD Controller"
|
||||
depends on FB_TFT
|
||||
help
|
||||
This enables generic framebuffer support for the JADARD JD9853
|
||||
display controller. The controller is intended for small color
|
||||
displays with a resolution of up to 240x320 pixels.
|
||||
|
||||
Say Y if you have such a display that utilizes this controller.
|
||||
|
||||
config FB_TFT_PCD8544
|
||||
tristate "FB driver for the PCD8544 LCD Controller"
|
||||
depends on FB_TFT
|
||||
|
||||
@ -17,6 +17,7 @@ obj-$(CONFIG_FB_TFT_ILI9340) += fb_ili9340.o
|
||||
obj-$(CONFIG_FB_TFT_ILI9341) += fb_ili9341.o
|
||||
obj-$(CONFIG_FB_TFT_ILI9481) += fb_ili9481.o
|
||||
obj-$(CONFIG_FB_TFT_ILI9486) += fb_ili9486.o
|
||||
obj-$(CONFIG_FB_TFT_JD9853) += fb_jd9853.o
|
||||
obj-$(CONFIG_FB_TFT_PCD8544) += fb_pcd8544.o
|
||||
obj-$(CONFIG_FB_TFT_RA8875) += fb_ra8875.o
|
||||
obj-$(CONFIG_FB_TFT_S6D02A1) += fb_s6d02a1.o
|
||||
|
||||
208
linux_5.10/drivers/staging/fbtft/fb_jd9853.c
Normal file
208
linux_5.10/drivers/staging/fbtft/fb_jd9853.c
Normal file
@ -0,0 +1,208 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* FB driver for the JD9853 LCD display controller
|
||||
*
|
||||
* This display uses 9-bit SPI: Data/Command bit + 8 data bits
|
||||
* For platforms that doesn't support 9-bit, the driver is capable
|
||||
* of emulating this using 8-bit transfer.
|
||||
* This is done by transferring eight 9-bit words in 9 bytes.
|
||||
*
|
||||
* Copyright (C) 2013 Christian Vogelgsang
|
||||
* Based on adafruit22fb.c by Noralf Tronnes
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <video/mipi_display.h>
|
||||
|
||||
#include "fbtft.h"
|
||||
|
||||
#define DRVNAME "fb_jd9853"
|
||||
#define WIDTH 240
|
||||
#define HEIGHT 320
|
||||
#define TXBUFLEN (4 * PAGE_SIZE)
|
||||
#define DEFAULT_GAMMA "1F 1A 18 0A 0F 06 45 87 32 0A 07 02 07 05 00\n" \
|
||||
"00 25 27 05 10 09 3A 78 4D 05 18 0D 38 3A 1F"
|
||||
|
||||
static int init_display(struct fbtft_par *par)
|
||||
{
|
||||
par->fbtftops.reset(par);
|
||||
|
||||
if (par->gpio.cs)
|
||||
gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
|
||||
|
||||
// set password to access inhouse register
|
||||
write_reg(par, 0xDF, 0x98, 0x53);
|
||||
|
||||
//set command page
|
||||
//page 0 command
|
||||
write_reg(par, 0xDE, 0x00);
|
||||
|
||||
//Set VCOM voltage for normal scan direction
|
||||
//vcom=-0.3-0.025*value
|
||||
write_reg(par, 0xB2, 0x17);
|
||||
|
||||
// Set positive / negative voltage of Gamma power
|
||||
write_reg(par, 0xB7, 0x00, 0x30, 0x00, 0x58);
|
||||
|
||||
//Power mode and charge pump related setting
|
||||
write_reg(par, 0xBB, 0x4F, 0x9A, 0x55, 0x73, 0x6F, 0xF0);
|
||||
|
||||
// Set Source Output driving ability
|
||||
write_reg(par, 0xC0, 0x22, 0x22);
|
||||
|
||||
//Set Panel relate register
|
||||
//- - - SS_PANEL GS_PANEL REV_PANEL CFHR -
|
||||
//SS_Panel: Set Source scan output direction /1:S240-> S1 0:S1 -> S240
|
||||
//GS_Panel: Set Gate scan output direction /0:Top -> Bottom Scan (G1->G320) 1:Bottom -> Top Scan (G320 -> G1)
|
||||
//REV_Panel: Set the display of the same data on both normally-white
|
||||
//and normally-black panels. //0:Normal Black 1:Normal White
|
||||
//CFHR: Set color fliter horizontial alignment order /1:BGR 0:RGB
|
||||
write_reg(par, 0xC1, 0x01); //0x12
|
||||
|
||||
//Set Display Waveform Cycles of RGB Mode
|
||||
//- RGB_INV_PI[1:0] RGB_INV_I[1:0] IDLE_TYPE RGB_INV_NP[1:0]
|
||||
//RGB_INV_NP[1:0]: Set source dot inversion type at normal or partial mode /01:2-dot 10:Column 00:1-dot
|
||||
write_reg(par, 0xC3, 0x7D, 0x07, 0x14, 0x06, 0xC8, 0x71, 0x6C, 0x77);
|
||||
|
||||
// Timing control setting
|
||||
//- - - - VBFP_RATIO[1:0] TE_OPT[1:0]
|
||||
//- TE_DELAY[6:0]
|
||||
//LN[7:0] : Sets the gate line number to drive LCD panel.Gate line number = LN*2 / 320 Line
|
||||
//SLT_NP[7:0]:Sets the scan line time width. (4 x OSC) CLK / step.Note: fosc = 10MHz
|
||||
//- VFP_NP[6:0]
|
||||
//VFP_xx[7:0]: Vertical front porch number setting. / 0x0E=60Hz 0x4E=50Hz 7E=45Hz
|
||||
write_reg(par, 0xC4, 0x00, 0x00, 0xA0, 0x79, 0x0E, 0x0A, 0x16, 0x79,
|
||||
0x25, 0x0A, 0x16, 0x82);
|
||||
|
||||
//Set Red Gamma output voltage.This command is used to set postive /neagative volatge of source output
|
||||
write_reg(par, 0xC8, 0x3F, 0x34, 0x2B, 0x20, 0x2A, 0x2C, 0x24, 0x24,
|
||||
0x21, 0x22, 0x20, 0x15, 0x10, 0x0B, 0x06, 0x00, 0x3F,
|
||||
0x34, 0x2B, 0x20, 0x2A, 0x2C, 0x24, 0x24, 0x21, 0x22,
|
||||
0x20, 0x15, 0x10, 0x0B, 0x06, 0x00);
|
||||
//SET CGOUTx_L Signal Mapping, GS_Panel=0
|
||||
write_reg(par, 0xD0, 0x04, 0x06, 0x6B, 0x0F, 0x00);
|
||||
//RAMCTRL
|
||||
//- CR_OPTION SPI_2LAN_EN RP RM MLBIT_INV DM[1:0]
|
||||
//CR_OPTION: for data mapping.used with EPF[1:0]
|
||||
//SPI_2LAN_EN: Enable SPI 2 data lane when IM[3:0]=0101 //0=disable
|
||||
//RP : Enable DPI data path. 0=disable 1=enable
|
||||
//RM : select data path for GRAM. 1=data from DPI/DSI 0=data from 2C/3C command
|
||||
//MLBIT_INV: RGB data MSB/LSB reversal(only for MCU Interface RGB565,except QSPI)
|
||||
//DM[1:0]: select contol timing and display data path. 00=internal vs, hs ,de;Display Data Path=GRAM
|
||||
write_reg(par, 0xD7, 0x00, 0x30);
|
||||
|
||||
write_reg(par, 0xE6, 0x14);
|
||||
|
||||
//set command page 1 command
|
||||
write_reg(par, 0xDE, 0x01);
|
||||
|
||||
write_reg(par, 0xB7, 0x0C, 0x0C, 0x00, 0x33, 0x33);
|
||||
write_reg(par, 0xC1, 0x14, 0x15, 0xC0);
|
||||
write_reg(par, 0xC2, 0x06, 0x3A, 0xE7);
|
||||
write_reg(par, 0xC4, 0x72, 0x12);
|
||||
write_reg(par, 0xBE, 0x00);
|
||||
write_reg(par, 0xDE, 0x00);
|
||||
write_reg(par, 0x3A, 0x05);
|
||||
write_reg(par, 0x2A, 0x00, 0x00, 0x00, 0xEF);
|
||||
write_reg(par, 0x2B, 0x00, 0x00, 0x01, 0x3F);
|
||||
write_reg(par, 0x35, 0x00);
|
||||
write_reg(par, 0x11);
|
||||
mdelay(120);
|
||||
write_reg(par, 0x29);
|
||||
mdelay(20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
|
||||
{
|
||||
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
|
||||
(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
|
||||
|
||||
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
|
||||
(ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
|
||||
|
||||
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
|
||||
}
|
||||
|
||||
#define MEM_Y BIT(7) /* MY row address order */
|
||||
#define MEM_X BIT(6) /* MX column address order */
|
||||
#define MEM_V BIT(5) /* MV row / column exchange */
|
||||
#define MEM_L BIT(4) /* ML vertical refresh order */
|
||||
#define MEM_H BIT(2) /* MH horizontal refresh order */
|
||||
#define MEM_BGR (3) /* RGB-BGR Order */
|
||||
static int set_var(struct fbtft_par *par)
|
||||
{
|
||||
switch (par->info->var.rotate) {
|
||||
case 0:
|
||||
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
|
||||
MEM_X | (par->bgr << MEM_BGR));
|
||||
break;
|
||||
case 270:
|
||||
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
|
||||
MEM_V | MEM_L | (par->bgr << MEM_BGR));
|
||||
break;
|
||||
case 180:
|
||||
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
|
||||
MEM_Y | (par->bgr << MEM_BGR));
|
||||
break;
|
||||
case 90:
|
||||
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
|
||||
MEM_Y | MEM_X | MEM_V | (par->bgr << MEM_BGR));
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gamma string format:
|
||||
* Positive: Par1 Par2 [...] Par15
|
||||
* Negative: Par1 Par2 [...] Par15
|
||||
*/
|
||||
#define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)]
|
||||
static int set_gamma(struct fbtft_par *par, u32 *curves)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < par->gamma.num_curves; i++)
|
||||
write_reg(par, 0xE0 + i,
|
||||
CURVE(i, 0), CURVE(i, 1), CURVE(i, 2),
|
||||
CURVE(i, 3), CURVE(i, 4), CURVE(i, 5),
|
||||
CURVE(i, 6), CURVE(i, 7), CURVE(i, 8),
|
||||
CURVE(i, 9), CURVE(i, 10), CURVE(i, 11),
|
||||
CURVE(i, 12), CURVE(i, 13), CURVE(i, 14));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef CURVE
|
||||
|
||||
static struct fbtft_display display = {
|
||||
.regwidth = 8,
|
||||
.width = WIDTH,
|
||||
.height = HEIGHT,
|
||||
.txbuflen = TXBUFLEN,
|
||||
.gamma_num = 2,
|
||||
.gamma_len = 15,
|
||||
.gamma = DEFAULT_GAMMA,
|
||||
.fbtftops = {
|
||||
.init_display = init_display,
|
||||
.set_addr_win = set_addr_win,
|
||||
.set_var = set_var,
|
||||
.set_gamma = set_gamma,
|
||||
},
|
||||
};
|
||||
|
||||
FBTFT_REGISTER_DRIVER(DRVNAME, "jadard,jd9853", &display);
|
||||
|
||||
MODULE_ALIAS("spi:" DRVNAME);
|
||||
MODULE_ALIAS("platform:" DRVNAME);
|
||||
MODULE_ALIAS("spi:jd9853");
|
||||
MODULE_ALIAS("platform:jd9853");
|
||||
|
||||
MODULE_DESCRIPTION("FB driver for the JD9853 LCD display controller");
|
||||
MODULE_AUTHOR("Christian Vogelgsang");
|
||||
MODULE_LICENSE("GPL");
|
||||
Reference in New Issue
Block a user