ODROID-N2: fbtft ili9488 lcd module added.

Change-Id: I701bf93801c55f9e28395bc8ee7c9b88e6859a09
This commit is contained in:
charles.park
2018-12-31 12:01:01 +09:00
committed by Dongjin Kim
parent 555f2e78be
commit 0cde1de852
4 changed files with 177 additions and 0 deletions

View File

@@ -236,3 +236,60 @@ int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len)
return -1;
}
EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
union reg_bitfield {
unsigned int wvalue;
struct {
unsigned int db02: 1; /* GPIOX.0 */
unsigned int db00: 1; /* GPIOX.1 */
unsigned int db01: 1; /* GPIOX.2 */
unsigned int bit3: 1; /* GPIOX.3 */
unsigned int db07: 1; /* GPIOX.4 */
unsigned int bit5: 1; /* GPIOX.5 */
unsigned int bit6: 1; /* GPIOX.6 */
unsigned int db06: 1; /* GPIOX.7 */
unsigned int db05: 1; /* GPIOX.8 */
unsigned int db04: 1; /* GPIOX.9 */
unsigned int wr: 1; /* GPIOX.10 */
unsigned int db03: 1; /* GPIOX.11 */
/* GPIOX.12 ~ GPIOX.31 */
unsigned int bit12_bit31 : 20;
} bits;
};
int fbtft_write_reg_wr(struct fbtft_par *par, void *buf, size_t len)
{
u8 data;
union reg_bitfield dbus;
if (!par->reg_gpiox) {
pr_err("%s : ioremap gpio register fail!\n", __func__);
return 0;
}
dbus.wvalue = ioread32(par->reg_gpiox + OFFSET_GPIOX_IN);
while (len--) {
data = *buf;
dbus.bits.db00 = (data & 0x01) ? 1 : 0;
dbus.bits.db01 = (data & 0x02) ? 1 : 0;
dbus.bits.db02 = (data & 0x04) ? 1 : 0;
dbus.bits.db03 = (data & 0x08) ? 1 : 0;
dbus.bits.db04 = (data & 0x10) ? 1 : 0;
dbus.bits.db05 = (data & 0x20) ? 1 : 0;
dbus.bits.db06 = (data & 0x40) ? 1 : 0;
dbus.bits.db07 = (data & 0x80) ? 1 : 0;
/* Start writing by pulling down /WR */
dbus.bits.wr = 0;
iowrite32(dbus.wvalue, par->reg_gpiox + OFFSET_GPIOX_OUT);
dbus.bits.wr = 1;
iowrite32(dbus.wvalue, par->reg_gpiox + OFFSET_GPIOX_OUT);
buf++;
}
return 0;
}
#endif /* #if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) */

View File

@@ -241,8 +241,18 @@ struct fbtft_par {
ktime_t update_time;
bool bgr;
void *extra;
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
void __iomem *reg_gpiox;
#endif
};
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
#define ODROIDN2_GPIO_START 0xff634400
#define ODROIDN2_GPIOX_START (ODROIDN2_GPIO_START + 0x50)
#define OFFSET_GPIOX_OUT 0x0C
#define OFFSET_GPIOX_IN 0x10
#endif
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
#define write_reg(par, ...) \
@@ -272,6 +282,10 @@ int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len);
int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len);
int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len);
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
int fbtft_write_reg_wr(struct fbtft_par *par, void *buf, size_t len);
#endif
/* fbtft-bus.c */
int fbtft_write_vmem8_bus8(struct fbtft_par *par, size_t offset, size_t len);
int fbtft_write_vmem16_bus16(struct fbtft_par *par, size_t offset, size_t len);

View File

@@ -544,6 +544,24 @@ static struct fbtft_device_display displays[] = {
.release = fbtft_device_pdev_release,
.platform_data = &(struct fbtft_platform_data) {
.gpios = (const struct fbtft_gpio []) {
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
{ "reset", 479 }, /* GPX.3 */
{ "dc", 490 }, /* GPX.14 */
{ "wr", 486 }, /* GPX.10 */
{ "cs", 492 }, /* GPX.16 */
{ "db00", 477 }, /* GPX.1 */
{ "db01", 478 }, /* GPX.2 */
{ "db02", 476 }, /* GPX.0 */
{ "db03", 487 }, /* GPX.11 */
{ "db04", 485 }, /* GPX.9 */
{ "db05", 484 }, /* GPX.8 */
{ "db06", 483 }, /* GPX.7 */
{ "db07", 480 }, /* GPX.4 */
{ "led", 481 }, /* GPX.5 */
{},
#else
{ "reset", 17 },
{ "dc", 1 },
{ "wr", 0 },
@@ -558,6 +576,7 @@ static struct fbtft_device_display displays[] = {
{ "db07", 7 },
{ "led", 4 },
{},
#endif
},
},
}

View File

@@ -126,6 +126,24 @@ static int ssd1351_init[] = { -1, 0xfd, 0x12, -1, 0xfd, 0xb1, -1, 0xae, -1, 0xb3
-1, 0xab, 0x01, -1, 0xb1, 0x32, -1, 0xb4, 0xa0, 0xb5, 0x55, -1, 0xbb, 0x17, -1, 0xbe, 0x05,
-1, 0xc1, 0xc8, 0x80, 0xc8, -1, 0xc7, 0x0f, -1, 0xb6, 0x01, -1, 0xa6, -1, 0xaf, -3 };
static int ili9488_init[] = {
-1, 0xB0, 0x00,
-1, 0x11,
-2, 120,
-1, 0x3A, 0x55,
-1, 0xC2, 0x33,
-1, 0xC5, 0x00, 0x1E, 0x80,
-1, 0x36, 0x28,
-1, 0xB1, 0xB0,
-1, 0xE0, 0x00, 0x04, 0x0E, 0x08, 0x17, 0x0A, 0x40, 0x79, 0x4D, 0x07,
0x0E, 0x0A, 0x1A, 0x1D, 0x0F,
-1, 0xE1, 0x00, 0x1B, 0x1F, 0x02, 0x10, 0x05, 0x32, 0x34, 0x43, 0x02,
0x0A, 0x09, 0x33, 0x37, 0x0F,
-1, 0x11,
-1, 0x29,
-3
};
/**
* struct flexfb_lcd_controller - Describes the LCD controller properties
* @name: Model name of the chip
@@ -210,6 +228,13 @@ static const struct flexfb_lcd_controller flexfb_chip_table[] = {
.init_seq = ili9341_init,
.init_seq_sz = ARRAY_SIZE(ili9341_init),
},
{
.name = "ili9488",
.width = 320,
.height = 480,
.init_seq = ili9488_init,
.init_seq_sz = ARRAY_SIZE(ili9488_init),
},
{
.name = "ssd1289",
.width = 240,
@@ -229,6 +254,53 @@ static const struct flexfb_lcd_controller flexfb_chip_table[] = {
},
};
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
static void set_addr_win_odroid(struct fbtft_par *par,
int xs, int ys, int xe, int ye)
{
/* Column address */
write_reg(par, 0x2A, xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
/* Row address */
write_reg(par, 0x2B, ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
/* Memory write */
write_reg(par, 0x2C);
}
#define ODROID_TFT35_MACTL_MV 0x20
#define ODROID_TFT35_MACTL_MX 0x40
#define ODROID_TFT35_MACTL_MY 0x80
static int set_var_odroid(struct fbtft_par *par)
{
u8 val;
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par, "%s()\n", __func__);
switch (par->info->var.rotate) {
case 270:
val = ODROID_TFT35_MACTL_MV;
break;
case 180:
val = ODROID_TFT35_MACTL_MY;
break;
case 90:
val = ODROID_TFT35_MACTL_MV |
ODROID_TFT35_MACTL_MX |
ODROID_TFT35_MACTL_MY;
break;
default:
val = ODROID_TFT35_MACTL_MX;
break;
}
/* Memory Access Control */
write_reg(par, 0x36, val | (par->bgr << 3));
return 0;
}
#endif
/* ili9320, ili9325 */
static void flexfb_set_addr_win_1(struct fbtft_par *par,
int xs, int ys, int xe, int ye)
@@ -518,6 +590,17 @@ static int flexfb_probe_common(struct spi_device *sdev,
if (!nobacklight)
par->fbtftops.register_backlight = fbtft_register_backlight;
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
par->reg_gpiox = ioremap(ODROIDN2_GPIOX_START, 64);
if (!par->reg_gpiox) {
pr_err("%s : ioremap gpiox register error!\n", __func__);
} else {
par->fbtftops.write = fbtft_write_reg_wr;
par->fbtftops.set_addr_win = set_addr_win_odroid;
par->fbtftops.set_var = set_var_odroid;
}
#endif
ret = fbtft_register_framebuffer(info);
if (ret < 0)
goto out_release;
@@ -540,6 +623,10 @@ static int flexfb_remove_common(struct device *dev, struct fb_info *info)
if (par)
fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par, "%s()\n",
__func__);
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
if (par->reg_gpiox)
iounmap(par->reg_gpiox);
#endif
fbtft_unregister_framebuffer(info);
fbtft_framebuffer_release(info);