/* * Copyright (c) 2020 Actions Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ #include #include "panel_st77903.h" #include "panel_device.h" /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ /********************** * STATIC VARIABLES **********************/ /********************** * MACROS **********************/ /********************** * FUNCTIONS **********************/ static void _panel_transmit(const struct device *dev, uint32_t cmd, const uint8_t *tx_data, size_t tx_count) { struct lcd_panel_data *data = dev->data; display_controller_write_config(data->lcdc_dev, ST77903_WR_CMD(cmd), tx_data, tx_count); } static inline void _panel_transmit_cmd(const struct device *dev, uint32_t cmd) { _panel_transmit(dev, cmd, NULL, 0); } static inline void _panel_transmit_p1(const struct device *dev, uint32_t cmd, uint8_t tx_data) { _panel_transmit(dev, cmd, &tx_data, 1); } static int _panel_init(const struct device *dev) { const struct lcd_panel_config *config = dev->config; _panel_transmit_p1(dev, 0xf0, 0xc3); _panel_transmit_p1(dev, 0xf0, 0x96); _panel_transmit_p1(dev, 0xf0, 0xa5); _panel_transmit_p1(dev, 0xe9, 0x20); const uint8_t data_0xe7[] = { 0x80, 0x77, 0x1f, 0xcc, }; _panel_transmit(dev, 0xe7, data_0xe7, sizeof(data_0xe7)); const uint8_t data_0xc1[] = { 0x77, 0x07, 0xc2, 0x07, }; _panel_transmit(dev, 0xc1, data_0xc1, sizeof(data_0xc1)); const uint8_t data_0xc2[] = { 0x77, 0x07, 0xc2, 0x07, }; _panel_transmit(dev, 0xc2, data_0xc2, sizeof(data_0xc2)); const uint8_t data_0xc3[] = { 0x22, 0x02, 0x22, 0x04, }; _panel_transmit(dev, 0xc3, data_0xc3, sizeof(data_0xc3)); const uint8_t data_0xc4[] = { 0x22, 0x02, 0x22, 0x04, }; _panel_transmit(dev, 0xc4, data_0xc4, sizeof(data_0xc4)); _panel_transmit_p1(dev, 0xc5, 0x71); const uint8_t data_0xe0[] = { 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f, }; _panel_transmit(dev, 0xe0, data_0xe0, sizeof(data_0xe0)); const uint8_t data_0xe1[] = { 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f, }; _panel_transmit(dev, 0xe1, data_0xe1, sizeof(data_0xe1)); const uint8_t data_0xe5[] = { 0xb2, 0xf5, 0xbd, 0x24, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, }; _panel_transmit(dev, 0xe5, data_0xe5, sizeof(data_0xe5)); const uint8_t data_0xe6[] = { 0xb2, 0xf5, 0xbd, 0x24, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, }; _panel_transmit(dev, 0xe6, data_0xe6, sizeof(data_0xe6)); const uint8_t data_0xec[] = { 0x40, 0x03, }; _panel_transmit(dev, 0xec, data_0xec, sizeof(data_0xec)); _panel_transmit_p1(dev, 0x36, 0x0c); if (config->videomode.pixel_format == PIXEL_FORMAT_BGR_565) { _panel_transmit_p1(dev, 0x3a, 0x05); } else { /* RGB_888 */ _panel_transmit_p1(dev, 0x3a, 0x07); } _panel_transmit_p1(dev, 0xb2, 0x00); _panel_transmit_p1(dev, 0xb3, 0x00); // ??? _panel_transmit_p1(dev, 0xb4, 0x00); /* Set VFP(8) and VBP(8) in idle mode */ const uint8_t data_0xb5[] = { 0x00, 0x08, 0x00, 0x8 }; _panel_transmit(dev, 0xb5, data_0xb5, sizeof(data_0xb5)); /* Resolution 400x400 */ const uint8_t data_0xb6[] = { 0xc7, 0x31, }; _panel_transmit(dev, 0xb6, data_0xb6, sizeof(data_0xb6)); const uint8_t data_0xa5[] = { 0x00, 0x00, 0x00, 0x00, 0x20, 0x15, 0x2a, 0x8a, 0x02 }; _panel_transmit(dev, 0xa5, data_0xa5, sizeof(data_0xa5)); const uint8_t data_0xa6[] = { 0x00, 0x00, 0x00, 0x00, 0x20, 0x15, 0x2a, 0x8a, 0x02 }; _panel_transmit(dev, 0xa6, data_0xa6, sizeof(data_0xa6)); const uint8_t data_0xba[] = { 0x0a, 0x5a, 0x23, 0x10, 0x25, 0x02, 0x00 }; _panel_transmit(dev, 0xba, data_0xba, sizeof(data_0xba)); const uint8_t data_0xbb[] = { 0x00, 0x30, 0x00, 0x29, 0x88, 0x87, 0x18, 0x00, }; _panel_transmit(dev, 0xbb, data_0xbb, sizeof(data_0xbb)); const uint8_t data_0xbc[] = { 0x00, 0x30, 0x00, 0x29, 0x88, 0x87, 0x18, 0x00, }; _panel_transmit(dev, 0xbc, data_0xbc, sizeof(data_0xbc)); const uint8_t data_0xbd[] = { 0xa1, 0xb2, 0x2b, 0x1a, 0x56, 0x43, 0x34, 0x65, 0xff, 0xff, 0x0f, }; _panel_transmit(dev, 0xbd, data_0xbd, sizeof(data_0xbd)); /* TE on */ _panel_transmit_p1(dev, 0x35, 0x00); _panel_transmit_cmd(dev, 0x21); //_panel_transmit_cmd(dev, 0x38); /* idle mode off */ _panel_transmit_cmd(dev, 0x11); /* Sleep Out */ k_msleep(120); _panel_transmit_cmd(dev, 0x29); /* Display On */ k_msleep(120); return 0; } static const struct lcd_panel_ops lcd_panel_ops = { .init = _panel_init, }; /* RGB-565 */ static uint8_t lcd_framebuffer_mem[CONFIG_PANEL_HOR_RES * CONFIG_PANEL_VER_RES * 2] __aligned(4); const struct lcd_panel_config lcd_panel_st77903_config = { .videoport = PANEL_VIDEO_PORT_INITIALIZER, .videomode = PANEL_VIDEO_MODE_INITIALIZER, .ops = &lcd_panel_ops, .fb_mem = lcd_framebuffer_mem, .cmd_ramwr = ST77903_WR_CMD(DDIC_CMD_VS), .cmd_hsync = ST77903_WR_CMD(DDIC_CMD_HS), .tw_reset = 10, .ts_reset = 120, };