mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
ODROID-N2: fbtft ili9488 lcd module added.
Change-Id: I701bf93801c55f9e28395bc8ee7c9b88e6859a09
This commit is contained in:
@@ -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) */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user