Commit 303ec5da authored by forum_service's avatar forum_service Committed by carbon

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
parent ab451374
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include <linux/mtd/rawnand.h> #include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/jiffies.h>
#include "cvsnfc_common.h" #include "cvsnfc_common.h"
#include "cvsnfc_spi_ids.h" #include "cvsnfc_spi_ids.h"
#include "cvsnfc.h" #include "cvsnfc.h"
...@@ -463,8 +463,10 @@ static void cvsnfc_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl) ...@@ -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) static int cvsnfc_waitfunc(struct nand_chip *chip)
{ {
unsigned int regval; unsigned int regval;
unsigned int deadline = 0;
struct cvsnfc_host *host = nand_get_controller_data(chip); 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__); pr_debug("=>%s\n", __func__);
...@@ -474,9 +476,7 @@ static int cvsnfc_waitfunc(struct nand_chip *chip) ...@@ -474,9 +476,7 @@ static int cvsnfc_waitfunc(struct nand_chip *chip)
if (!(regval & STATUS_OIP_MASK)) if (!(regval & STATUS_OIP_MASK))
return NAND_STATUS_READY; return NAND_STATUS_READY;
udelay(1); } while (jiffies_to_msecs(jiffies - start_time) < max_erase_time);
/* maybe need to sure */
} while (deadline++ < (40 << 5));
pr_err("%s timeout.\n", __func__); pr_err("%s timeout.\n", __func__);
...@@ -487,15 +487,16 @@ static int cvsnfc_waitfunc(struct nand_chip *chip) ...@@ -487,15 +487,16 @@ static int cvsnfc_waitfunc(struct nand_chip *chip)
static int cvsnfc_dev_ready(struct nand_chip *chip) static int cvsnfc_dev_ready(struct nand_chip *chip)
{ {
unsigned int regval; unsigned int regval;
unsigned int deadline = 0;
struct cvsnfc_host *host = chip->priv; struct cvsnfc_host *host = chip->priv;
unsigned long start_time = jiffies;
/* 4ms */
unsigned long max_erase_time = 4 * 3;
do { do {
spi_feature_op(host, GET_OP, STATUS_ADDR, &regval); spi_feature_op(host, GET_OP, STATUS_ADDR, &regval);
if (!(regval & STATUS_OIP_MASK)) if (!(regval & STATUS_OIP_MASK))
return 1; return 1;
udelay(1); } while (jiffies_to_msecs(jiffies - start_time) < max_erase_time);
} while (deadline++ < (40 << 5));
pr_err("%s timeout.\n", __func__); pr_err("%s timeout.\n", __func__);
...@@ -785,15 +786,15 @@ static int parse_status_info(struct cvsnfc_host *host) ...@@ -785,15 +786,15 @@ static int parse_status_info(struct cvsnfc_host *host)
/* read SR */ /* read SR */
spi_feature_op(host, GET_OP, ecc_info->ecc_sr_addr, &ecc_status0); spi_feature_op(host, GET_OP, ecc_info->ecc_sr_addr, &ecc_status0);
if (((ecc_status0 & 0x30) >> 4) == 0) mask = GENMASK(ecc_info->ecc_bits - 1, 0);
status = (ecc_status0 >> ecc_info->ecc_bit_shift) & mask;
if (status == 0)
return 0; return 0;
if (((ecc_status0 & 0x30) >> 4) == ecc_info->uncorr_val) if (status == ecc_info->uncorr_val)
return -EBADMSG; return -EBADMSG;
mask = GENMASK(ecc_info->ecc_bits - 1, 0);
status = (ecc_status0 >> ecc_info->ecc_bit_shift) & mask;
if (ecc_info->ecc_sr_addr && !ecc_info->read_ecc_opcode && !ecc_info->ecc_mbf_addr) { if (ecc_info->ecc_sr_addr && !ecc_info->read_ecc_opcode && !ecc_info->ecc_mbf_addr) {
if (ecc_info->remap) { if (ecc_info->remap) {
corr_bit = ecc_info->remap[status] != 0xff ? ecc_info->remap[status] : 0; 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) ...@@ -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); spi_nand_read_eccsr(host, ecc_info->read_ecc_opcode, &ecc_status0);
corr_bit = (ecc_status0 >> ecc_info->ecc_bit_shift) & mask; 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; return corr_bit;
} }
...@@ -871,15 +872,7 @@ RETRY_READ_CMD: ...@@ -871,15 +872,7 @@ RETRY_READ_CMD:
} }
ret = parse_status_info(host); ret = parse_status_info(host);
if (ret < 0) { return ret;
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;
} }
__attribute__((unused)) __attribute__((unused))
......
...@@ -495,7 +495,7 @@ struct nand_ecc_info { ...@@ -495,7 +495,7 @@ struct nand_ecc_info {
uint8_t ecc_bits; uint8_t ecc_bits;
uint8_t ecc_bit_shift; uint8_t ecc_bit_shift;
uint8_t uncorr_val; uint8_t uncorr_val;
char *remap; short *remap;
}; };
struct spi_nand_driver { struct spi_nand_driver {
......
...@@ -60,7 +60,7 @@ static struct spi_nand_driver spi_nand_driver_toshiba = { ...@@ -60,7 +60,7 @@ static struct spi_nand_driver spi_nand_driver_toshiba = {
*/ */
/* only for 8 bit threshold */ /* 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 * ECCS1 ECCS0 Description
...@@ -70,7 +70,7 @@ char ECC_3bits_remap[8] = {0, 1, -1, 4, 0xff, 7, 0xff, 0xff }; ...@@ -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 * 1 1 Bit errors were detected and corrected,Bit errors count was equal
* to the threshold bit count (8 bits) * 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 * ECCS1 ECCS0 Description
...@@ -79,7 +79,8 @@ char ECC_XT26G11C[4] = {0, 1, -1, 8}; ...@@ -79,7 +79,8 @@ char ECC_XT26G11C[4] = {0, 1, -1, 8};
* 1 0 More than 4-bit error and not corrected. * 1 0 More than 4-bit error and not corrected.
* 1 1 Reserved * 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 * ECCS1 ECCS0 ECCSE1 ECCSE0 Description
...@@ -93,11 +94,62 @@ char ECC_2bits_remap[4] = {0, 1, -1, 0xff}; ...@@ -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 * ECCS0-ECCS1 is located in field 4-5 of addr of 0xC0
* ECCSE0-ECCSE1 is located in field 4-5 of addr of 0xF0 * 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}; short 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}; short 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_HYF2G_remap[4] = {0, 1, -1, 14};
struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = { 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", { .name = "F50L1G41LB",
...@@ -524,7 +576,7 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = { ...@@ -524,7 +576,7 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
.options = 0, .options = 0,
.id_len = 2, .id_len = 2,
.oobsize = SZ_64, .oobsize = SZ_64,
{ .strength_ds = 8, { .strength_ds = 4,
.step_ds = SZ_512 .step_ds = SZ_512
}, },
}, },
...@@ -535,7 +587,7 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = { ...@@ -535,7 +587,7 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
.ecc_bits = 2, .ecc_bits = 2,
.ecc_bit_shift = 4, .ecc_bit_shift = 4,
.uncorr_val = 0x2, .uncorr_val = 0x2,
.remap = ECC_GD_8bit_remap .remap = ECC_GD_4bit_remap
}, },
.driver = &spi_nand_driver_gd, .driver = &spi_nand_driver_gd,
.flags = 0 .flags = 0
...@@ -1220,6 +1272,84 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = { ...@@ -1220,6 +1272,84 @@ struct cvsnfc_chip_info nand_flash_cvitek_supported_ids[] = {
.flags = 0 .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 } { NULL }
}; };
......
...@@ -78,6 +78,10 @@ static const struct flash_info cvitek_parts[] = { ...@@ -78,6 +78,10 @@ static const struct flash_info cvitek_parts[] = {
SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP | SECT_4K |
SPI_NOR_4B_OPCODES) SPI_NOR_4B_OPCODES)
.fixups = &sr_bit1_qe_fixups }, .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, { "MT25QL256A", INFO6(0x20ba19, 0x104400, 64 * 1024, 512,
SECT_4K | USE_FSR | SPI_NOR_DUAL_READ | SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
SPI_NOR_QUAD_OP | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_FIX_DUMMY) SPI_NOR_QUAD_OP | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_FIX_DUMMY)
...@@ -163,6 +167,9 @@ static const struct flash_info cvitek_parts[] = { ...@@ -163,6 +167,9 @@ static const struct flash_info cvitek_parts[] = {
{ "FM25W128A", INFO(0xA12818, 0x0, 64 * 1024, 256, { "FM25W128A", INFO(0xA12818, 0x0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP) SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
.fixups = &sr_bit1_qe_fixups }, .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, { "BY25Q128AS", INFO(0x684018, 0x0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP) SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
.fixups = &sr_bit1_qe_fixups }, .fixups = &sr_bit1_qe_fixups },
...@@ -173,6 +180,9 @@ static const struct flash_info cvitek_parts[] = { ...@@ -173,6 +180,9 @@ static const struct flash_info cvitek_parts[] = {
{ "PY25Q128HA", INFO(0x852018, 0x0, 64 * 1024, 256, { "PY25Q128HA", INFO(0x852018, 0x0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP) SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
.fixups = &sr_bit1_qe_fixups }, .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, { "P25Q64SH", INFO(0x856017, 0x0, 64 * 1024, 128,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP) SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_OP)
.fixups = &sr_bit1_qe_fixups }, .fixups = &sr_bit1_qe_fixups },
......
...@@ -88,6 +88,16 @@ config FB_TFT_ILI9486 ...@@ -88,6 +88,16 @@ config FB_TFT_ILI9486
help help
Generic Framebuffer support for ILI9486 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 config FB_TFT_PCD8544
tristate "FB driver for the PCD8544 LCD Controller" tristate "FB driver for the PCD8544 LCD Controller"
depends on FB_TFT depends on FB_TFT
......
...@@ -17,6 +17,7 @@ obj-$(CONFIG_FB_TFT_ILI9340) += fb_ili9340.o ...@@ -17,6 +17,7 @@ obj-$(CONFIG_FB_TFT_ILI9340) += fb_ili9340.o
obj-$(CONFIG_FB_TFT_ILI9341) += fb_ili9341.o obj-$(CONFIG_FB_TFT_ILI9341) += fb_ili9341.o
obj-$(CONFIG_FB_TFT_ILI9481) += fb_ili9481.o obj-$(CONFIG_FB_TFT_ILI9481) += fb_ili9481.o
obj-$(CONFIG_FB_TFT_ILI9486) += fb_ili9486.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_PCD8544) += fb_pcd8544.o
obj-$(CONFIG_FB_TFT_RA8875) += fb_ra8875.o obj-$(CONFIG_FB_TFT_RA8875) += fb_ra8875.o
obj-$(CONFIG_FB_TFT_S6D02A1) += fb_s6d02a1.o obj-$(CONFIG_FB_TFT_S6D02A1) += fb_s6d02a1.o
......
// 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");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment