Gpanel driver: add support for ILI9481 LCD controller.

This commit is contained in:
Serge Vakulenko
2018-01-30 20:22:36 -08:00
parent 435d3c34cf
commit a5d7f4ea99
7 changed files with 163 additions and 40 deletions

View File

@@ -163,6 +163,7 @@ extern int gpanel_height;
extern void st7781_init_display(struct gpanel_hw *hw);
extern void nt35702_init_display(struct gpanel_hw *hw);
extern void ili9341_init_display(struct gpanel_hw *hw);
extern void ili9481_init_display(struct gpanel_hw *hw);
extern void s6d04h0_init_display(struct gpanel_hw *hw);
#endif /* KERNEL */

View File

@@ -67,7 +67,7 @@ static void set_window(int x0, int y0, int x1, int y1)
/*
* Draw a pixel.
*/
void ili9341_set_pixel(int x, int y, int color)
void ili_set_pixel(int x, int y, int color)
{
if (x < 0 || x >= gpanel_width || y < 0 || y >= gpanel_height)
return;
@@ -139,7 +139,7 @@ static void flood(int color, int npixels)
/*
* Switch the screen orientation.
*/
static void set_rotation(int rotation)
static void ili9341_set_rotation(int rotation)
{
write_command(ILI9341_Memory_Access_Control);
switch (rotation & 3) {
@@ -166,15 +166,58 @@ static void set_rotation(int rotation)
}
}
/*
* Switch the screen orientation.
*/
static void ili9481_set_rotation(int rotation)
{
write_command(ILI9341_Memory_Access_Control);
switch (rotation & 3) {
case 0: /* Portrait */
write_data(MADCTL_MX | MADCTL_BGR);
gpanel_width = 320;
gpanel_height = 480;
break;
case 1: /* Landscape */
write_data(MADCTL_MV | MADCTL_BGR);
gpanel_width = 480;
gpanel_height = 320;
break;
case 2: /* Upside down portrait */
write_data(MADCTL_MY | MADCTL_BGR);
gpanel_width = 320;
gpanel_height = 480;
break;
case 3: /* Upside down landscape */
write_data(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
gpanel_width = 480;
gpanel_height = 320;
break;
}
}
static void ili9341_resize(struct gpanel_hw *h, int width, int height)
{
gpanel_cs_active();
/* Switch screen orientaation. */
if (width > height)
set_rotation(1); /* Landscape */
ili9341_set_rotation(1); /* Landscape */
else if (width < height)
set_rotation(0); /* Portrait */
ili9341_set_rotation(0); /* Portrait */
gpanel_cs_idle();
}
static void ili9481_resize(struct gpanel_hw *h, int width, int height)
{
gpanel_cs_active();
/* Switch screen orientaation. */
if (width > height)
ili9481_set_rotation(1); /* Landscape */
else if (width < height)
ili9481_set_rotation(0); /* Portrait */
gpanel_cs_idle();
}
@@ -182,7 +225,7 @@ static void ili9341_resize(struct gpanel_hw *h, int width, int height)
/*
* Fill a rectangle with specified color.
*/
void ili9341_fill_rectangle(int x0, int y0, int x1, int y1, int color)
void ili_fill_rectangle(int x0, int y0, int x1, int y1, int color)
{
if (x0 < 0) x0 = 0;
if (y0 < 0) x0 = 0;
@@ -212,7 +255,7 @@ void ili9341_fill_rectangle(int x0, int y0, int x1, int y1, int color)
/*
* Fill a rectangle with user data.
*/
void ili9341_draw_image(int x, int y, int width, int height,
void ili_draw_image(int x, int y, int width, int height,
const unsigned short *data)
{
unsigned cnt = width * height;
@@ -231,7 +274,7 @@ void ili9341_draw_image(int x, int y, int width, int height,
/*
* Draw a glyph of one symbol.
*/
void ili9341_draw_glyph(const struct gpanel_font_t *font,
void ili_draw_glyph(const struct gpanel_font_t *font,
int color, int background, int x, int y, int width,
const unsigned short *bits)
{
@@ -277,7 +320,7 @@ void ili9341_draw_glyph(const struct gpanel_font_t *font,
bitmask <<= 1;
if (bitmask & 0x8000)
ili9341_set_pixel(x + w, y + h, color);
ili_set_pixel(x + w, y + h, color);
}
}
}
@@ -326,7 +369,7 @@ void ili9341_init_display(struct gpanel_hw *h)
write_command(ILI9341_Display_ON);
set_rotation(1); /* Landscape */
ili9341_set_rotation(1); /* Landscape */
gpanel_cs_idle();
/*
@@ -334,8 +377,82 @@ void ili9341_init_display(struct gpanel_hw *h)
*/
h->name = "Ilitek ILI9341";
h->resize = ili9341_resize;
h->set_pixel = ili9341_set_pixel;
h->fill_rectangle = ili9341_fill_rectangle;
h->draw_image = ili9341_draw_image;
h->draw_glyph = ili9341_draw_glyph;
h->set_pixel = ili_set_pixel;
h->fill_rectangle = ili_fill_rectangle;
h->draw_image = ili_draw_image;
h->draw_glyph = ili_draw_glyph;
}
/*
* Initialize the LCD controller.
* Fill the gpanel_hw descriptor.
*/
void ili9481_init_display(struct gpanel_hw *h)
{
/* Use a few NOPs to synchronize after the hard Reset. */
gpanel_cs_active();
write_command(ILI9341_No_Operation);
write_command(ILI9341_No_Operation);
write_command(ILI9341_No_Operation);
write_command(ILI9341_No_Operation);
write_command(ILI9341_Sleep_OUT);
udelay(150000);
write_command(ILI9341_NV_Memory_Write);
write_data(0x07);
write_data(0x42);
write_data(0x18);
write_command(ILI9341_NV_Memory_Protection_Key);
write_data(0x00);
write_data(0x07);
write_data(0x10);
write_command(ILI9341_NV_Memory_Status_Read);
write_data(0x01);
write_data(0x02);
write_command(ILI9341_Power_Control_1);
write_data(0x10);
write_data(0x3B);
write_data(0x00);
write_data(0x02);
write_data(0x11);
write_command(ILI9341_VCOM_Control_1);
write_data(0x03);
write_command(ILI9341_Memory_Access_Control);
write_data(0x0A);
write_command(ILI9341_Pixel_Format_Set);
write_data(0x55);
write_command(ILI9341_Column_Address_Set);
write_data(0x00);
write_data(0x00);
write_data(0x01);
write_data(0x3F);
write_command(ILI9341_Page_Address_Set);
write_data(0x00);
write_data(0x00);
write_data(0x01);
write_data(0xE0);
write_command(ILI9341_Display_ON);
ili9481_set_rotation(1); /* Landscape */
gpanel_cs_idle();
/*
* Fill the gpanel_hw descriptor.
*/
h->name = "Ilitek ILI9341";
h->resize = ili9481_resize;
h->set_pixel = ili_set_pixel;
h->fill_rectangle = ili_fill_rectangle;
h->draw_image = ili_draw_image;
h->draw_glyph = ili_draw_glyph;
}

View File

@@ -1,7 +1,7 @@
/*
* Display driver for NT35702 LCD controller.
* This controller is partially compatible with ILI9341 chip,
* so we can reuse most of ili9341_xxx() routines.
* so we can reuse most of ili_xxx() routines.
*
* Copyright (C) 2015 Serge Vakulenko <serge@vak.ru>
*
@@ -120,11 +120,11 @@
/*
* Reuse ILI9341 routines.
*/
extern void ili9341_set_pixel(int x, int y, int color);
extern void ili9341_fill_rectangle(int x0, int y0, int x1, int y1, int color);
extern void ili9341_draw_image(int x, int y, int width, int height,
extern void ili_set_pixel(int x, int y, int color);
extern void ili_fill_rectangle(int x0, int y0, int x1, int y1, int color);
extern void ili_draw_image(int x, int y, int width, int height,
const unsigned short *data);
extern void ili9341_draw_glyph(const struct gpanel_font_t *font,
extern void ili_draw_glyph(const struct gpanel_font_t *font,
int color, int background, int x, int y, int width,
const unsigned short *bits);
@@ -291,8 +291,8 @@ void nt35702_init_display(struct gpanel_hw *h)
*/
h->name = "Novatek NT35702";
h->resize = nt35702_resize;
h->set_pixel = ili9341_set_pixel;
h->fill_rectangle = ili9341_fill_rectangle;
h->draw_image = ili9341_draw_image;
h->draw_glyph = ili9341_draw_glyph;
h->set_pixel = ili_set_pixel;
h->fill_rectangle = ili_fill_rectangle;
h->draw_image = ili_draw_image;
h->draw_glyph = ili_draw_glyph;
}

View File

@@ -675,6 +675,11 @@ static int probe(config)
ili9341_init_display(&hw);
break;
case 0x012200:
/* Ilitek ILI9481. */
ili9481_init_display(&hw);
break;
case 0x388000:
/* Novatek NT35702. */
nt35702_init_display(&hw);

View File

@@ -69,8 +69,8 @@
#define ILI9341_VCOM_Control_1 0xC5
#define ILI9341_VCOM_Control_2 0xC7
#define ILI9341_NV_Memory_Write 0xD0
#define ILI9341_NV_Memory_Protection Key 0xD1
#define ILI9341_NV_Memory_Status Read 0xD2
#define ILI9341_NV_Memory_Protection_Key 0xD1
#define ILI9341_NV_Memory_Status_Read 0xD2
#define ILI9341_Read_ID4 0xD3
#define ILI9341_Positive_Gamma_Correction 0xE0
#define ILI9341_Negative_Gamma_Correction 0xE1

View File

@@ -68,16 +68,16 @@ device pwm
# TFT display driver with 8-bit parallel interface.
# Supported controllers: ST7781, ILI9341, NT35702
device gpanel
signal "LCD_RST" pin RB10
signal "LCD_CS" pin RB0
signal "LCD_RD" pin RB2
signal "LCD_RS" pin RB8
signal "LCD_WR" pin RB4
signal "LCD_D0" pin RA14
signal "LCD_D1" pin RD3
signal "LCD_D2" pin RE8
signal "LCD_D3" pin RD0
signal "LCD_D4" pin RF1
signal "LCD_D5" pin RD1
signal "LCD_D6" pin RD2
signal "LCD_D7" pin RE9
signal "LCD_RST" pin RB10 # arduino A4
signal "LCD_CS" pin RB0 # arduino A3
signal "LCD_RS" pin RB8 # arduino A2
signal "LCD_WR" pin RB4 # arduino A1
signal "LCD_RD" pin RB2 # arduino A0
signal "LCD_D2" pin RE8 # arduino D2
signal "LCD_D3" pin RD0 # arduino D3
signal "LCD_D4" pin RF1 # arduino D4
signal "LCD_D5" pin RD1 # arduino D5
signal "LCD_D6" pin RD2 # arduino D6
signal "LCD_D7" pin RE9 # arduino D7
signal "LCD_D0" pin RA14 # arduino D8
signal "LCD_D1" pin RD3 # arduino D9

View File

@@ -13,17 +13,17 @@ PARAM += -DGPIO6_ENABLED
PARAM += -DADC_ENABLED
PARAM += -DPWM_ENABLED
PARAM += -DGPANEL_ENABLED
PARAM += -DLCD_D1_PORT=TRISD -DLCD_D1_PIN=3
PARAM += -DLCD_D0_PORT=TRISA -DLCD_D0_PIN=14
PARAM += -DLCD_D7_PORT=TRISE -DLCD_D7_PIN=9
PARAM += -DLCD_D6_PORT=TRISD -DLCD_D6_PIN=2
PARAM += -DLCD_D5_PORT=TRISD -DLCD_D5_PIN=1
PARAM += -DLCD_D4_PORT=TRISF -DLCD_D4_PIN=1
PARAM += -DLCD_D3_PORT=TRISD -DLCD_D3_PIN=0
PARAM += -DLCD_D2_PORT=TRISE -DLCD_D2_PIN=8
PARAM += -DLCD_D1_PORT=TRISD -DLCD_D1_PIN=3
PARAM += -DLCD_D0_PORT=TRISA -DLCD_D0_PIN=14
PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=2
PARAM += -DLCD_WR_PORT=TRISB -DLCD_WR_PIN=4
PARAM += -DLCD_RS_PORT=TRISB -DLCD_RS_PIN=8
PARAM += -DLCD_RD_PORT=TRISB -DLCD_RD_PIN=2
PARAM += -DLCD_CS_PORT=TRISB -DLCD_CS_PIN=0
PARAM += -DLCD_RST_PORT=TRISB -DLCD_RST_PIN=10
PARAM += -DLED_DISK_PORT=TRISA -DLED_DISK_PIN=1