From a124eb9f9e364aa617fc7ee71cb72ede42d1f326 Mon Sep 17 00:00:00 2001 From: Darryldh Date: Tue, 3 Aug 2021 20:26:58 -0400 Subject: [PATCH] feat(display): IL0323 driver for EPD displays. * Basic driver, using the GD7965 driver as a basis, since the ICs are very similar. --- app/drivers/CMakeLists.txt | 3 +- app/drivers/Kconfig | 3 +- app/drivers/display/CMakeLists.txt | 4 + app/drivers/display/Kconfig | 4 + app/drivers/display/Kconfig.il0323 | 11 + app/drivers/display/il0323.c | 432 ++++++++++++++++++ app/drivers/display/il0323_regs.h | 81 ++++ .../bindings/display/gooddisplay,il0323.yaml | 61 +++ 8 files changed, 597 insertions(+), 2 deletions(-) create mode 100644 app/drivers/display/CMakeLists.txt create mode 100644 app/drivers/display/Kconfig create mode 100644 app/drivers/display/Kconfig.il0323 create mode 100644 app/drivers/display/il0323.c create mode 100644 app/drivers/display/il0323_regs.h create mode 100644 app/dts/bindings/display/gooddisplay,il0323.yaml diff --git a/app/drivers/CMakeLists.txt b/app/drivers/CMakeLists.txt index b47e87a2..c1625f2f 100644 --- a/app/drivers/CMakeLists.txt +++ b/app/drivers/CMakeLists.txt @@ -2,4 +2,5 @@ # SPDX-License-Identifier: MIT add_subdirectory(kscan) -add_subdirectory(sensor) \ No newline at end of file +add_subdirectory(sensor) +add_subdirectory(display) \ No newline at end of file diff --git a/app/drivers/Kconfig b/app/drivers/Kconfig index 7ad76992..5bcc522d 100644 --- a/app/drivers/Kconfig +++ b/app/drivers/Kconfig @@ -2,4 +2,5 @@ # SPDX-License-Identifier: MIT rsource "kscan/Kconfig" -rsource "sensor/Kconfig" \ No newline at end of file +rsource "sensor/Kconfig" +rsource "display/Kconfig" \ No newline at end of file diff --git a/app/drivers/display/CMakeLists.txt b/app/drivers/display/CMakeLists.txt new file mode 100644 index 00000000..13b97193 --- /dev/null +++ b/app/drivers/display/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +zephyr_sources_ifdef(CONFIG_IL0323 il0323.c) \ No newline at end of file diff --git a/app/drivers/display/Kconfig b/app/drivers/display/Kconfig new file mode 100644 index 00000000..efa064d4 --- /dev/null +++ b/app/drivers/display/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +rsource "Kconfig.il0323" \ No newline at end of file diff --git a/app/drivers/display/Kconfig.il0323 b/app/drivers/display/Kconfig.il0323 new file mode 100644 index 00000000..f39015ef --- /dev/null +++ b/app/drivers/display/Kconfig.il0323 @@ -0,0 +1,11 @@ +# Copyright (c) 2020 Phytec Messtechnik GmbH, Peter Johanson +# SPDX-License-Identifier: Apache-2.0 + +# IL0323 display controller configuration options + +config IL0323 + bool "IL0323 compatible display controller driver" + depends on SPI + depends on HEAP_MEM_POOL_SIZE != 0 + help + Enable driver for IL0323 compatible controller. \ No newline at end of file diff --git a/app/drivers/display/il0323.c b/app/drivers/display/il0323.c new file mode 100644 index 00000000..9ec8162f --- /dev/null +++ b/app/drivers/display/il0323.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2020 PHYTEC Messtechnik GmbHH, Peter Johanson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT gooddisplay_il0323 + +#include +#include +#include +#include +#include +#include +#include + +#include "il0323_regs.h" + +#include +LOG_MODULE_REGISTER(il0323, CONFIG_DISPLAY_LOG_LEVEL); + +/** + * IL0323 compatible EPD controller driver. + * + */ + +#define IL0323_SPI_FREQ DT_INST_PROP(0, spi_max_frequency) +#define IL0323_BUS_NAME DT_INST_BUS_LABEL(0) +#define IL0323_DC_PIN DT_INST_GPIO_PIN(0, dc_gpios) +#define IL0323_DC_FLAGS DT_INST_GPIO_FLAGS(0, dc_gpios) +#define IL0323_DC_CNTRL DT_INST_GPIO_LABEL(0, dc_gpios) +#define IL0323_CS_PIN DT_INST_SPI_DEV_CS_GPIOS_PIN(0) +#define IL0323_CS_FLAGS DT_INST_SPI_DEV_CS_GPIOS_FLAGS(0) +#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0) +#define IL0323_CS_CNTRL DT_INST_SPI_DEV_CS_GPIOS_LABEL(0) +#endif +#define IL0323_BUSY_PIN DT_INST_GPIO_PIN(0, busy_gpios) +#define IL0323_BUSY_CNTRL DT_INST_GPIO_LABEL(0, busy_gpios) +#define IL0323_BUSY_FLAGS DT_INST_GPIO_FLAGS(0, busy_gpios) +#define IL0323_RESET_PIN DT_INST_GPIO_PIN(0, reset_gpios) +#define IL0323_RESET_CNTRL DT_INST_GPIO_LABEL(0, reset_gpios) +#define IL0323_RESET_FLAGS DT_INST_GPIO_FLAGS(0, reset_gpios) + +#define EPD_PANEL_WIDTH DT_INST_PROP(0, width) +#define EPD_PANEL_HEIGHT DT_INST_PROP(0, height) +#define IL0323_PIXELS_PER_BYTE 8U + +/* Horizontally aligned page! */ +#define IL0323_NUMOF_PAGES (EPD_PANEL_WIDTH / IL0323_PIXELS_PER_BYTE) +#define IL0323_PANEL_FIRST_GATE 0U +#define IL0323_PANEL_LAST_GATE (EPD_PANEL_HEIGHT - 1) +#define IL0323_PANEL_FIRST_PAGE 0U +#define IL0323_PANEL_LAST_PAGE (IL0323_NUMOF_PAGES - 1) +#define IL0323_BUFFER_SIZE 1280 + +struct il0323_data { + const struct device *reset; + const struct device *dc; + const struct device *busy; + const struct device *spi_dev; + struct spi_config spi_config; +#if defined(IL0323_CS_CNTRL) + struct spi_cs_control cs_ctrl; +#endif +}; + +static uint8_t il0323_pwr[] = DT_INST_PROP(0, pwr); + +static uint8_t last_buffer[IL0323_BUFFER_SIZE]; +static bool blanking_on = true; + +static inline int il0323_write_cmd(struct il0323_data *driver, uint8_t cmd, uint8_t *data, + size_t len) { + struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)}; + struct spi_buf_set buf_set = {.buffers = &buf, .count = 1}; + + gpio_pin_set(driver->dc, IL0323_DC_PIN, 1); + if (spi_write(driver->spi_dev, &driver->spi_config, &buf_set)) { + return -EIO; + } + + if (data != NULL) { + buf.buf = data; + buf.len = len; + gpio_pin_set(driver->dc, IL0323_DC_PIN, 0); + if (spi_write(driver->spi_dev, &driver->spi_config, &buf_set)) { + return -EIO; + } + } + + return 0; +} + +static inline void il0323_busy_wait(struct il0323_data *driver) { + int pin = gpio_pin_get(driver->busy, IL0323_BUSY_PIN); + + while (pin > 0) { + __ASSERT(pin >= 0, "Failed to get pin level"); + // LOG_DBG("wait %u", pin); + k_msleep(IL0323_BUSY_DELAY); + pin = gpio_pin_get(driver->busy, IL0323_BUSY_PIN); + } +} + +static int il0323_update_display(const struct device *dev) { + struct il0323_data *driver = dev->data; + + LOG_DBG("Trigger update sequence"); + if (il0323_write_cmd(driver, IL0323_CMD_DRF, NULL, 0)) { + return -EIO; + } + + k_msleep(IL0323_BUSY_DELAY); + + return 0; +} + +static int il0323_blanking_off(const struct device *dev) { + struct il0323_data *driver = dev->data; + + if (blanking_on) { + /* Update EPD pannel in normal mode */ + il0323_busy_wait(driver); + if (il0323_update_display(dev)) { + return -EIO; + } + } + + blanking_on = false; + + return 0; +} + +static int il0323_blanking_on(const struct device *dev) { + blanking_on = true; + + return 0; +} + +static int il0323_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) { + struct il0323_data *driver = dev->data; + uint16_t x_end_idx = x + desc->width - 1; + uint16_t y_end_idx = y + desc->height - 1; + uint8_t ptl[IL0323_PTL_REG_LENGTH] = {0}; + size_t buf_len; + + LOG_DBG("x %u, y %u, height %u, width %u, pitch %u", x, y, desc->height, desc->width, + desc->pitch); + + buf_len = MIN(desc->buf_size, desc->height * desc->width / IL0323_PIXELS_PER_BYTE); + __ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width"); + __ASSERT(buf != NULL, "Buffer is not available"); + __ASSERT(buf_len != 0U, "Buffer of length zero"); + __ASSERT(!(desc->width % IL0323_PIXELS_PER_BYTE), "Buffer width not multiple of %d", + IL0323_PIXELS_PER_BYTE); + + LOG_DBG("buf_len %d", buf_len); + if ((y_end_idx > (EPD_PANEL_HEIGHT - 1)) || (x_end_idx > (EPD_PANEL_WIDTH - 1))) { + LOG_ERR("Position out of bounds"); + return -EINVAL; + } + + /* Setup Partial Window and enable Partial Mode */ + ptl[IL0323_PTL_HRST_IDX] = x; + ptl[IL0323_PTL_HRED_IDX] = x_end_idx; + ptl[IL0323_PTL_VRST_IDX] = y; + ptl[IL0323_PTL_VRED_IDX] = y_end_idx; + ptl[sizeof(ptl) - 1] = IL0323_PTL_PT_SCAN; + LOG_HEXDUMP_DBG(ptl, sizeof(ptl), "ptl"); + + il0323_busy_wait(driver); + if (il0323_write_cmd(driver, IL0323_CMD_PIN, NULL, 0)) { + return -EIO; + } + + if (il0323_write_cmd(driver, IL0323_CMD_PTL, ptl, sizeof(ptl))) { + return -EIO; + } + + if (il0323_write_cmd(driver, IL0323_CMD_DTM1, last_buffer, IL0323_BUFFER_SIZE)) { + return -EIO; + } + + if (il0323_write_cmd(driver, IL0323_CMD_DTM2, (uint8_t *)buf, buf_len)) { + return -EIO; + } + + memcpy(last_buffer, (uint8_t *)buf, IL0323_BUFFER_SIZE); + + /* Update partial window and disable Partial Mode */ + if (blanking_on == false) { + if (il0323_update_display(dev)) { + return -EIO; + } + } + + if (il0323_write_cmd(driver, IL0323_CMD_POUT, NULL, 0)) { + return -EIO; + } + + return 0; +} + +static int il0323_read(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, void *buf) { + LOG_ERR("not supported"); + return -ENOTSUP; +} + +static void *il0323_get_framebuffer(const struct device *dev) { + LOG_ERR("not supported"); + return NULL; +} + +static int il0323_set_brightness(const struct device *dev, const uint8_t brightness) { + LOG_WRN("not supported"); + return -ENOTSUP; +} + +static int il0323_set_contrast(const struct device *dev, uint8_t contrast) { + LOG_WRN("not supported"); + return -ENOTSUP; +} + +static void il0323_get_capabilities(const struct device *dev, struct display_capabilities *caps) { + memset(caps, 0, sizeof(struct display_capabilities)); + caps->x_resolution = EPD_PANEL_WIDTH; + caps->y_resolution = EPD_PANEL_HEIGHT; + caps->supported_pixel_formats = PIXEL_FORMAT_MONO10; + caps->current_pixel_format = PIXEL_FORMAT_MONO10; + caps->screen_info = SCREEN_INFO_MONO_MSB_FIRST | SCREEN_INFO_EPD; +} + +static int il0323_set_orientation(const struct device *dev, + const enum display_orientation orientation) { + LOG_ERR("Unsupported"); + return -ENOTSUP; +} + +static int il0323_set_pixel_format(const struct device *dev, const enum display_pixel_format pf) { + if (pf == PIXEL_FORMAT_MONO10) { + return 0; + } + + LOG_ERR("not supported"); + return -ENOTSUP; +} + +static int il0323_clear_and_write_buffer(const struct device *dev, uint8_t pattern, bool update) { + struct display_buffer_descriptor desc = { + .buf_size = IL0323_NUMOF_PAGES, + .width = EPD_PANEL_WIDTH, + .height = 1, + .pitch = EPD_PANEL_WIDTH, + }; + uint8_t *line; + + line = k_malloc(IL0323_NUMOF_PAGES); + if (line == NULL) { + return -ENOMEM; + } + + memset(line, pattern, IL0323_NUMOF_PAGES); + for (int i = 0; i < EPD_PANEL_HEIGHT; i++) { + il0323_write(dev, 0, i, &desc, line); + } + + k_free(line); + + if (update == true) { + if (il0323_update_display(dev)) { + return -EIO; + } + } + + return 0; +} + +static int il0323_controller_init(const struct device *dev) { + struct il0323_data *driver = dev->data; + uint8_t tmp[IL0323_TRES_REG_LENGTH]; + + LOG_DBG(""); + + gpio_pin_set(driver->reset, IL0323_RESET_PIN, 1); + k_msleep(IL0323_RESET_DELAY); + gpio_pin_set(driver->reset, IL0323_RESET_PIN, 0); + k_msleep(IL0323_RESET_DELAY); + il0323_busy_wait(driver); + + LOG_DBG("Initialize IL0323 controller"); + + if (il0323_write_cmd(driver, IL0323_CMD_PWR, il0323_pwr, sizeof(il0323_pwr))) { + return -EIO; + } + + /* Turn on: booster, controller, regulators, and sensor. */ + if (il0323_write_cmd(driver, IL0323_CMD_PON, NULL, 0)) { + return -EIO; + } + + k_msleep(IL0323_PON_DELAY); + il0323_busy_wait(driver); + + /* Pannel settings, KW mode */ + tmp[0] = IL0323_PSR_UD | IL0323_PSR_SHL | IL0323_PSR_SHD | IL0323_PSR_RST; +#if EPD_PANEL_WIDTH == 80 + +#if EPD_PANEL_HEIGHT == 128 + tmp[0] |= IL0323_PSR_RES_HEIGHT; +#endif /* panel height */ + +#else + tmp[0] |= IL0323_PSR_RES_WIDTH; +#if EPD_PANEL_HEIGHT == 96 + tmp[0] |= IL0323_PSR_RES_HEIGHT; +#else +#endif /* panel height */ + +#endif /* panel width */ + + LOG_HEXDUMP_DBG(tmp, 1, "PSR"); + if (il0323_write_cmd(driver, IL0323_CMD_PSR, tmp, 1)) { + return -EIO; + } + + /* Set panel resolution */ + tmp[IL0323_TRES_HRES_IDX] = EPD_PANEL_WIDTH; + tmp[IL0323_TRES_VRES_IDX] = EPD_PANEL_HEIGHT; + LOG_HEXDUMP_DBG(tmp, IL0323_TRES_REG_LENGTH, "TRES"); + if (il0323_write_cmd(driver, IL0323_CMD_TRES, tmp, IL0323_TRES_REG_LENGTH)) { + return -EIO; + } + + tmp[IL0323_CDI_CDI_IDX] = DT_INST_PROP(0, cdi); + LOG_HEXDUMP_DBG(tmp, IL0323_CDI_REG_LENGTH, "CDI"); + if (il0323_write_cmd(driver, IL0323_CMD_CDI, tmp, IL0323_CDI_REG_LENGTH)) { + return -EIO; + } + + tmp[0] = DT_INST_PROP(0, tcon); + if (il0323_write_cmd(driver, IL0323_CMD_TCON, tmp, 1)) { + return -EIO; + } + + /* Enable Auto Sequence */ + tmp[0] = IL0323_AUTO_PON_DRF_POF; + if (il0323_write_cmd(driver, IL0323_CMD_AUTO, tmp, 1)) { + return -EIO; + } + + if (il0323_clear_and_write_buffer(dev, 0xff, false)) { + return -1; + } + + return 0; +} + +static int il0323_init(const struct device *dev) { + struct il0323_data *driver = dev->data; + + LOG_DBG(""); + + driver->spi_dev = device_get_binding(IL0323_BUS_NAME); + if (driver->spi_dev == NULL) { + LOG_ERR("Could not get SPI device for IL0323"); + return -EIO; + } + + driver->spi_config.frequency = IL0323_SPI_FREQ; + driver->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8); + driver->spi_config.slave = DT_INST_REG_ADDR(0); + driver->spi_config.cs = NULL; + + driver->reset = device_get_binding(IL0323_RESET_CNTRL); + if (driver->reset == NULL) { + LOG_ERR("Could not get GPIO port for IL0323 reset"); + return -EIO; + } + + gpio_pin_configure(driver->reset, IL0323_RESET_PIN, GPIO_OUTPUT_INACTIVE | IL0323_RESET_FLAGS); + + driver->dc = device_get_binding(IL0323_DC_CNTRL); + if (driver->dc == NULL) { + LOG_ERR("Could not get GPIO port for IL0323 DC signal"); + return -EIO; + } + + gpio_pin_configure(driver->dc, IL0323_DC_PIN, GPIO_OUTPUT_INACTIVE | IL0323_DC_FLAGS); + + driver->busy = device_get_binding(IL0323_BUSY_CNTRL); + if (driver->busy == NULL) { + LOG_ERR("Could not get GPIO port for IL0323 busy signal"); + return -EIO; + } + + gpio_pin_configure(driver->busy, IL0323_BUSY_PIN, GPIO_INPUT | IL0323_BUSY_FLAGS); + +#if defined(IL0323_CS_CNTRL) + driver->cs_ctrl.gpio_dev = device_get_binding(IL0323_CS_CNTRL); + if (!driver->cs_ctrl.gpio_dev) { + LOG_ERR("Unable to get SPI GPIO CS device"); + return -EIO; + } + + driver->cs_ctrl.gpio_pin = IL0323_CS_PIN; + driver->cs_ctrl.gpio_dt_flags = IL0323_CS_FLAGS; + driver->cs_ctrl.delay = 0U; + driver->spi_config.cs = &driver->cs_ctrl; +#endif + + return il0323_controller_init(dev); +} + +static struct il0323_data il0323_driver; + +static struct display_driver_api il0323_driver_api = { + .blanking_on = il0323_blanking_on, + .blanking_off = il0323_blanking_off, + .write = il0323_write, + .read = il0323_read, + .get_framebuffer = il0323_get_framebuffer, + .set_brightness = il0323_set_brightness, + .set_contrast = il0323_set_contrast, + .get_capabilities = il0323_get_capabilities, + .set_pixel_format = il0323_set_pixel_format, + .set_orientation = il0323_set_orientation, +}; + +DEVICE_DT_INST_DEFINE(0, il0323_init, device_pm_control_nop, &il0323_driver, NULL, POST_KERNEL, + CONFIG_APPLICATION_INIT_PRIORITY, &il0323_driver_api); \ No newline at end of file diff --git a/app/drivers/display/il0323_regs.h b/app/drivers/display/il0323_regs.h new file mode 100644 index 00000000..3eb19755 --- /dev/null +++ b/app/drivers/display/il0323_regs.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020 PHYTEC Messtechnik GmbH, Peter Johanson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISPLAY_IL0323_REGS_H_ +#define ZEPHYR_DRIVERS_DISPLAY_IL0323_REGS_H_ + +#define IL0323_CMD_PSR 0x00 +#define IL0323_CMD_PWR 0x01 +#define IL0323_CMD_POF 0x02 +#define IL0323_CMD_PFS 0x03 +#define IL0323_CMD_PON 0x04 +#define IL0323_CMD_PMES 0x05 +#define IL0323_CMD_CPSET 0x06 +#define IL0323_CMD_DSLP 0x07 +#define IL0323_CMD_DTM1 0x10 +#define IL0323_CMD_DSP 0x11 +#define IL0323_CMD_DRF 0x12 +#define IL0323_CMD_DTM2 0x13 +#define IL0323_CMD_AUTO 0x17 +#define IL0323_CMD_LUTOPT 0x2A +#define IL0323_CMD_PLL 0x30 +#define IL0323_CMD_TSC 0x40 +#define IL0323_CMD_TSE 0x41 +#define IL0323_CMD_PBC 0x44 +#define IL0323_CMD_CDI 0x50 +#define IL0323_CMD_LPD 0x51 +#define IL0323_CMD_TCON 0x60 +#define IL0323_CMD_TRES 0x61 +#define IL0323_CMD_GSST 0x65 +#define IL0323_CMD_REV 0x70 +#define IL0323_CMD_FLG 0x71 +#define IL0323_CMD_CRC 0x72 +#define IL0323_CMD_AMV 0x80 +#define IL0323_CMD_VV 0x81 +#define IL0323_CMD_VDCS 0x82 +#define IL0323_CMD_PTL 0x90 +#define IL0323_CMD_PIN 0x91 +#define IL0323_CMD_POUT 0x92 +#define IL0323_CMD_PGM 0xA0 +#define IL0323_CMD_APG 0xA1 +#define IL0323_CMD_ROTP 0xA2 +#define IL0323_CMD_CCSET 0xE0 +#define IL0323_CMD_PWS 0xE3 +#define IL0323_CMD_LVSEL 0xE4 +#define IL0323_CMD_TSSET 0xE5 + +#define IL0323_PSR_RES_WIDTH BIT(7) +#define IL0323_PSR_RES_HEIGHT BIT(6) +#define IL0323_PSR_LUT_REG BIT(5) +#define IL0323_PSR_LUT_OTP BIT(4) +#define IL0323_PSR_UD BIT(3) +#define IL0323_PSR_SHL BIT(2) +#define IL0323_PSR_SHD BIT(1) +#define IL0323_PSR_RST BIT(0) + +#define IL0323_AUTO_PON_DRF_POF 0xA5 +#define IL0323_AUTO_PON_DRF_POF_DSLP 0xA7 + +#define IL0323_CDI_REG_LENGTH 1U +#define IL0323_CDI_CDI_IDX 0 + +#define IL0323_TRES_REG_LENGTH 2U +#define IL0323_TRES_HRES_IDX 0 +#define IL0323_TRES_VRES_IDX 1 + +#define IL0323_PTL_REG_LENGTH 5U +#define IL0323_PTL_HRST_IDX 0 +#define IL0323_PTL_HRED_IDX 1 +#define IL0323_PTL_VRST_IDX 2 +#define IL0323_PTL_VRED_IDX 3 +#define IL0323_PTL_PT_SCAN BIT(0) + +/* Time constants in ms */ +#define IL0323_RESET_DELAY 10U +#define IL0323_PON_DELAY 100U +#define IL0323_BUSY_DELAY 1U + +#endif /* ZEPHYR_DRIVERS_DISPLAY_IL0323_REGS_H_ */ \ No newline at end of file diff --git a/app/dts/bindings/display/gooddisplay,il0323.yaml b/app/dts/bindings/display/gooddisplay,il0323.yaml new file mode 100644 index 00000000..d4a9ac7d --- /dev/null +++ b/app/dts/bindings/display/gooddisplay,il0323.yaml @@ -0,0 +1,61 @@ +# Copyright (c) 2020, Phytec Messtechnik GmbH, Peter Johanson +# SPDX-License-Identifier: Apache-2.0 + +description: IL0323 EPD display controller + +compatible: "gooddisplay,il0323" + +include: spi-device.yaml + +properties: + height: + type: int + required: true + description: Height in pixel of the panel driven by the controller + + width: + type: int + required: true + description: Width in pixel of the panel driven by the controller + + reset-gpios: + type: phandle-array + required: true + description: RESET pin. + + The RESET pin of GD7965 is active low. + If connected directly the MCU pin should be configured + as active low. + + dc-gpios: + type: phandle-array + required: true + description: DC pin. + + The DC pin of GD7965 is active low (transmission command byte). + If connected directly the MCU pin should be configured + as active low. + + busy-gpios: + type: phandle-array + required: true + description: BUSY pin. + + The BUSY pin of GD7965 is active low. + If connected directly the MCU pin should be configured + as active low. + + pwr: + type: uint8-array + required: true + description: Power Setting (PWR) values + + cdi: + type: int + required: true + description: VCOM and data interval value + + tcon: + type: int + required: true + description: TCON setting value \ No newline at end of file