From b219596cc126a6fd320e5239f7a84f1e1590ab12 Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Wed, 10 Apr 2024 08:43:40 -0500 Subject: [PATCH] drivers: mipi_dbi: Add controller driver for NXP FlexIO LCD Add a driver to support the NXP FlexIO LCD controller that uses 8080/6800 bus protocol. Signed-off-by: Mahesh Mahadevan --- drivers/mipi_dbi/CMakeLists.txt | 12 + drivers/mipi_dbi/Kconfig | 1 + drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif | 12 + drivers/mipi_dbi/mipi_dbi_nxp_flexio_lcdif.c | 485 ++++++++++++++++++ dts/arm/nxp/nxp_mcxn94x_common.dtsi | 12 + .../mipi-dbi/nxp,mipi-dbi-flexio-lcdif.yaml | 63 +++ 6 files changed, 585 insertions(+) create mode 100644 drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif create mode 100644 drivers/mipi_dbi/mipi_dbi_nxp_flexio_lcdif.c create mode 100644 dts/bindings/mipi-dbi/nxp,mipi-dbi-flexio-lcdif.yaml diff --git a/drivers/mipi_dbi/CMakeLists.txt b/drivers/mipi_dbi/CMakeLists.txt index fbcdc4d177b..5e9f475d151 100644 --- a/drivers/mipi_dbi/CMakeLists.txt +++ b/drivers/mipi_dbi/CMakeLists.txt @@ -5,3 +5,15 @@ zephyr_sources_ifdef(CONFIG_MIPI_DBI_SPI mipi_dbi_spi.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_SMARTBOND mipi_dbi_smartbond.c) zephyr_sources_ifdef(CONFIG_MIPI_DBI_NXP_LCDIC mipi_dbi_nxp_lcdic.c) +zephyr_sources_ifdef(CONFIG_MIPI_DBI_NXP_FLEXIO_LCDIF mipi_dbi_nxp_flexio_lcdif.c) +# Data bus width is used by the SDK driver and processes it as a compile time option +if(CONFIG_MIPI_DBI_NXP_FLEXIO_LCDIF) + dt_chosen(flexio0_lcd PROPERTY "zephyr,display") + dt_prop(data_bus_width PATH "${flexio0_lcd}" PROPERTY "mipi-mode") + # Values for mipi-mode property are defined inside dt-bindings/mipi_dbi/mipi_dbi.h. + # We pass a define to the SDK driver if we are using 8-bit mode. + if((data_bus_width EQUAL 8) OR (data_bus_width EQUAL 5)) + zephyr_compile_definitions(FLEXIO_MCULCD_DATA_BUS_WIDTH=8) + endif() + zephyr_compile_definitions(FLEXIO_MCULCD_LEGACY_GPIO_FUNC=0) +endif() diff --git a/drivers/mipi_dbi/Kconfig b/drivers/mipi_dbi/Kconfig index 16b7fc41c2d..51181ddd1e4 100644 --- a/drivers/mipi_dbi/Kconfig +++ b/drivers/mipi_dbi/Kconfig @@ -24,5 +24,6 @@ config MIPI_DBI_INIT_PRIORITY source "drivers/mipi_dbi/Kconfig.spi" source "drivers/mipi_dbi/Kconfig.smartbond" source "drivers/mipi_dbi/Kconfig.nxp_lcdic" +source "drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif" endif diff --git a/drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif b/drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif new file mode 100644 index 00000000000..ae4e2ad2d4b --- /dev/null +++ b/drivers/mipi_dbi/Kconfig.nxp_flexio_lcdif @@ -0,0 +1,12 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +config MIPI_DBI_NXP_FLEXIO_LCDIF + bool "MIPI DBI driver for NXP Flexio LCDIF" + default y + depends on DT_HAS_NXP_MIPI_DBI_FLEXIO_LCDIF_ENABLED + depends on CLOCK_CONTROL + select MCUX_FLEXIO + select DMA + help + Enable support for MIPI DBI driver for NXP FlexIO based LCDIF controller. diff --git a/drivers/mipi_dbi/mipi_dbi_nxp_flexio_lcdif.c b/drivers/mipi_dbi/mipi_dbi_nxp_flexio_lcdif.c new file mode 100644 index 00000000000..15156cc4fad --- /dev/null +++ b/drivers/mipi_dbi/mipi_dbi_nxp_flexio_lcdif.c @@ -0,0 +1,485 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nxp_mipi_dbi_flexio_lcdif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(display_mcux_flexio_lcdif, CONFIG_DISPLAY_LOG_LEVEL); + +struct stream { + const struct device *dma_dev; + uint32_t channel; /* stores the channel for dma */ + struct dma_config dma_cfg; + struct dma_block_config dma_blk_cfg; +}; + +struct mcux_flexio_lcdif_config { + FLEXIO_MCULCD_Type *flexio_lcd_dev; + const struct device *flexio_dev; + const struct pinctrl_dev_config *pincfg; + const struct nxp_flexio_child *child; + /* Reset GPIO */ + const struct gpio_dt_spec reset; + const struct gpio_dt_spec cs_gpio; + const struct gpio_dt_spec rs_gpio; + const struct gpio_dt_spec rdwr_gpio; +}; + +struct mcux_flexio_lcdif_data { + struct stream dma_tx; + struct k_sem transfer_done; + const struct mipi_dbi_config *active_cfg; + uint8_t data_bus_width; +}; + +static void flexio_lcdif_dma_callback(const struct device *dev, void *arg, + uint32_t channel, int status) +{ + const struct device *flexio_dev = (struct device *)arg; + struct mcux_flexio_lcdif_data *lcdif_data = flexio_dev->data; + const struct mcux_flexio_lcdif_config *config = flexio_dev->config; + FLEXIO_MCULCD_Type *flexio_lcd = config->flexio_lcd_dev; + + FLEXIO_MCULCD_EnableTxDMA(flexio_lcd, false); + + /* Now the data are in shifter, wait for the data send out from the shifter. */ + FLEXIO_MCULCD_WaitTransmitComplete(); + + /* Disable the TX shifter and the timer. */ + FLEXIO_MCULCD_ClearMultiBeatsWriteConfig(flexio_lcd); + + /* De-assert nCS. */ + FLEXIO_MCULCD_StopTransfer(flexio_lcd); + + k_sem_give(&lcdif_data->transfer_done); +} + + +static void flexio_lcdif_set_cs(bool set, void *param) +{ + const struct device *flexio_dev = (struct device *)param; + const struct mcux_flexio_lcdif_config *config = flexio_dev->config; + + gpio_pin_set_dt(&config->cs_gpio, (int)set); +} + +static void flexio_lcdif_set_rs(bool set, void *param) +{ + const struct device *flexio_dev = (struct device *)param; + const struct mcux_flexio_lcdif_config *config = flexio_dev->config; + + gpio_pin_set_dt(&config->rs_gpio, (int)set); +} + +static void flexio_lcdif_set_rd_wr(bool set, void *param) +{ + const struct device *flexio_dev = (struct device *)param; + const struct mcux_flexio_lcdif_config *config = flexio_dev->config; + + gpio_pin_set_dt(&config->rdwr_gpio, (int)set); +} + +static edma_modulo_t flexio_lcdif_get_edma_modulo(uint8_t shifterNum) +{ + edma_modulo_t ret = kEDMA_ModuloDisable; + + switch (shifterNum) { + case 1U: + ret = kEDMA_Modulo4bytes; + break; + case 2U: + ret = kEDMA_Modulo8bytes; + break; + case 4U: + ret = kEDMA_Modulo16bytes; + break; + case 8U: + ret = kEDMA_Modulo32bytes; + break; + default: + ret = kEDMA_ModuloDisable; + break; + } + + return ret; +} + +static void flexio_lcdif_write_data_array(FLEXIO_MCULCD_Type *base, + const void *data, + size_t size) +{ + assert(size > 0U); + + uint32_t i; + const uint8_t *data8Bit; + FLEXIO_Type *flexioBase = base->flexioBase; + + /* Assert the RS pin. */ + base->setRSPin(true, base->userData); + /* For 6800, de-assert the RDWR pin. */ + if (kFLEXIO_MCULCD_6800 == base->busType) { + base->setRDWRPin(false, base->userData); + } + + /* Configure the timer and TX shifter. */ + FLEXIO_MCULCD_SetSingleBeatWriteConfig(base); + + data8Bit = (const uint8_t *)data; + + for (i = 0; i < size; i++) { + flexioBase->SHIFTBUF[base->txShifterStartIndex] = data8Bit[i]; + + /* Wait for the data send out. */ + while (0U == ((1UL << base->timerIndex) & flexioBase->TIMSTAT)) { + } + + /* Clear the timer stat. */ + flexioBase->TIMSTAT = 1UL << base->timerIndex; + } + + /* Stop the timer and TX shifter. */ + FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base); +} + +static int mipi_dbi_flexio_lcdif_configure(const struct device *dev, + const struct mipi_dbi_config *dbi_config) +{ + const struct mcux_flexio_lcdif_config *config = dev->config; + struct mcux_flexio_lcdif_data *lcdif_data = dev->data; + flexio_mculcd_config_t flexioMcuLcdConfig; + int err; + uint32_t clock_freq; + uint32_t mipi_mode = dbi_config->mode; + status_t status; + + /* 9-bit mode is not supported by the SDK driver */ + if ((mipi_mode == MIPI_DBI_MODE_6800_BUS_9_BIT) || + (mipi_mode == MIPI_DBI_MODE_8080_BUS_9_BIT)) { + return -EINVAL; + } + + if (dbi_config == lcdif_data->active_cfg) { + return 0; + } + + err = gpio_pin_configure_dt(&config->cs_gpio, GPIO_OUTPUT_HIGH); + if (err) { + return err; + } + + err = gpio_pin_configure_dt(&config->rs_gpio, GPIO_OUTPUT_HIGH); + if (err) { + return err; + } + + if ((mipi_mode == MIPI_DBI_MODE_6800_BUS_16_BIT) || + (mipi_mode == MIPI_DBI_MODE_6800_BUS_8_BIT)) { + /* RDWR GPIO is only used in 68K mode */ + err = gpio_pin_configure_dt(&config->rdwr_gpio, GPIO_OUTPUT_HIGH); + if (err) { + return err; + } + config->flexio_lcd_dev->busType = kFLEXIO_MCULCD_6800; + } else { + config->flexio_lcd_dev->busType = kFLEXIO_MCULCD_8080; + } + + if ((mipi_mode == MIPI_DBI_MODE_6800_BUS_8_BIT) || + (mipi_mode == MIPI_DBI_MODE_8080_BUS_8_BIT)) { + lcdif_data->data_bus_width = 8; + } else { + lcdif_data->data_bus_width = 16; + } + + FLEXIO_MCULCD_GetDefaultConfig(&flexioMcuLcdConfig); + flexioMcuLcdConfig.baudRate_Bps = dbi_config->config.frequency * + lcdif_data->data_bus_width; + + if (nxp_flexio_get_rate(config->flexio_dev, &clock_freq)) { + return -EINVAL; + } + + nxp_flexio_lock(config->flexio_dev); + /* Resets the FlexIO module, then configures FlexIO MCULCD */ + status = FLEXIO_MCULCD_Init(config->flexio_lcd_dev, &flexioMcuLcdConfig, clock_freq); + nxp_flexio_unlock(config->flexio_dev); + + if (kStatus_Success != status) { + return -EINVAL; + } + + lcdif_data->active_cfg = dbi_config; + + return 0; +} + +static int mipi_dbi_flexio_ldcif_write_display(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + const uint8_t *framebuf, + struct display_buffer_descriptor *desc, + enum display_pixel_format pixfmt) +{ + const struct mcux_flexio_lcdif_config *config = dev->config; + struct mcux_flexio_lcdif_data *lcdif_data = dev->data; + FLEXIO_MCULCD_Type *flexio_lcd = config->flexio_lcd_dev; + struct dma_block_config *blk_cfg; + struct stream *stream = &lcdif_data->dma_tx; + uint8_t num_of_shifters = 0; + int ret; + + ARG_UNUSED(pixfmt); + + ret = mipi_dbi_flexio_lcdif_configure(dev, dbi_config); + if (ret) { + return ret; + } + + num_of_shifters = (flexio_lcd->txShifterEndIndex - flexio_lcd->txShifterStartIndex + 1); + + blk_cfg = &stream->dma_blk_cfg; + + /* Assert the nCS. */ + FLEXIO_MCULCD_StartTransfer(config->flexio_lcd_dev); + + /* prepare the block for this TX DMA channel */ + memset(blk_cfg, 0, sizeof(struct dma_block_config)); + + /* tx direction has memory as source and periph as dest. */ + blk_cfg->source_address = (uint32_t)framebuf; + + /* Destination is FLEXIO Shifters */ + blk_cfg->dest_address = FLEXIO_MCULCD_GetTxDataRegisterAddress(flexio_lcd); + blk_cfg->block_size = desc->buf_size; + /* Transfer in each DMA loop is based on the number of shifters used */ + stream->dma_cfg.source_burst_length = num_of_shifters * 4; + + stream->dma_cfg.head_block = &stream->dma_blk_cfg; + /* Give the client dev as arg, as the callback comes from the dma */ + stream->dma_cfg.user_data = (struct device *)dev; + + /* Set the source size in bytes */ + stream->dma_cfg.source_data_size = lcdif_data->data_bus_width / 8; + + /* Configure the DMA */ + dma_config(lcdif_data->dma_tx.dma_dev, lcdif_data->dma_tx.channel, &stream->dma_cfg); + + /* The DMA driver does not support setting this Modulo value which is required + * in case of the flexio module to form a circular chain between the Shift buffer + * in the FLEXIO module. + */ + EDMA_SetModulo(DMA0, lcdif_data->dma_tx.channel, kEDMA_ModuloDisable, + flexio_lcdif_get_edma_modulo(num_of_shifters)); + + /* For 6800, de-assert the RDWR pin. */ + if (kFLEXIO_MCULCD_6800 == flexio_lcd->busType) { + flexio_lcdif_set_rd_wr(false, (void *)dev); + } + + nxp_flexio_lock(config->flexio_dev); + FLEXIO_MCULCD_SetMultiBeatsWriteConfig(flexio_lcd); + FLEXIO_MCULCD_EnableTxDMA(flexio_lcd, true); + nxp_flexio_unlock(config->flexio_dev); + + /* Start the data transfer */ + dma_start(lcdif_data->dma_tx.dma_dev, lcdif_data->dma_tx.channel); + + /* Wait for transfer done. */ + k_sem_take(&lcdif_data->transfer_done, K_FOREVER); + + return 0; +} + +static int mipi_dbi_flexio_lcdif_command_write(const struct device *dev, + const struct mipi_dbi_config *dbi_config, + uint8_t cmd, const uint8_t *data_buf, + size_t len) +{ + const struct mcux_flexio_lcdif_config *config = dev->config; + FLEXIO_MCULCD_Type *flexio_lcd = config->flexio_lcd_dev; + int ret; + + ARG_UNUSED(dbi_config); + + ret = mipi_dbi_flexio_lcdif_configure(dev, dbi_config); + if (ret) { + return ret; + } + + FLEXIO_MCULCD_StartTransfer(flexio_lcd); + + nxp_flexio_lock(config->flexio_dev); + + FLEXIO_MCULCD_WriteCommandBlocking(flexio_lcd, cmd); + + if ((data_buf != NULL) && (len != 0)) { + flexio_lcdif_write_data_array(flexio_lcd, data_buf, len); + } + + nxp_flexio_unlock(config->flexio_dev); + + FLEXIO_MCULCD_StopTransfer(flexio_lcd); + + return kStatus_Success; + +} + +static int mipi_dbi_flexio_lcdif_reset(const struct device *dev, uint32_t delay) +{ + int err; + const struct mcux_flexio_lcdif_config *config = dev->config; + + /* Check if a reset port is provided to reset the LCD controller */ + if (config->reset.port == NULL) { + return 0; + } + + /* Reset the LCD controller. */ + err = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_HIGH); + if (err) { + return err; + } + + err = gpio_pin_set_dt(&config->reset, 0); + if (err < 0) { + return err; + } + + k_msleep(delay); + + err = gpio_pin_set_dt(&config->reset, 1); + if (err < 0) { + return err; + } + + LOG_DBG("%s device reset complete", dev->name); + + return 0; +} + +static int flexio_lcdif_init(const struct device *dev) +{ + const struct mcux_flexio_lcdif_config *config = dev->config; + struct mcux_flexio_lcdif_data *lcdif_data = dev->data; + int err; + uint8_t shifter_end = config->child->res.shifter_count - 1; + + if (!device_is_ready(lcdif_data->dma_tx.dma_dev)) { + LOG_ERR("%s device is not ready", lcdif_data->dma_tx.dma_dev->name); + return -ENODEV; + } + + err = nxp_flexio_child_attach(config->flexio_dev, config->child); + if (err < 0) { + return err; + } + + config->flexio_lcd_dev->txShifterStartIndex = config->child->res.shifter_index[0]; + config->flexio_lcd_dev->txShifterEndIndex = config->child->res.shifter_index[shifter_end]; + + config->flexio_lcd_dev->rxShifterStartIndex = config->flexio_lcd_dev->txShifterStartIndex; + config->flexio_lcd_dev->rxShifterEndIndex = config->flexio_lcd_dev->txShifterEndIndex; + + config->flexio_lcd_dev->timerIndex = config->child->res.timer_index[0]; + + if (config->flexio_lcd_dev->txShifterEndIndex != + config->flexio_lcd_dev->txShifterStartIndex + shifter_end) { + LOG_ERR("Shifters should be continuous"); + return -ENODEV; + } + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + return err; + } + + /* Pass the FlexIO LCD device as parameter to the function + * callbacks for setting GPIO signals. + */ + config->flexio_lcd_dev->userData = (void *)dev; + + + k_sem_init(&lcdif_data->transfer_done, 0, 1); + + LOG_DBG("%s device init complete", dev->name); + + return 0; +} + +static struct mipi_dbi_driver_api mipi_dbi_lcdif_driver_api = { + .reset = mipi_dbi_flexio_lcdif_reset, + .command_write = mipi_dbi_flexio_lcdif_command_write, + .write_display = mipi_dbi_flexio_ldcif_write_display, +}; + +#define MCUX_FLEXIO_LCDIF_DEVICE_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + \ + static FLEXIO_MCULCD_Type flexio_mculcd_##n = { \ + .flexioBase = (FLEXIO_Type *)DT_REG_ADDR(DT_INST_PARENT(n)), \ + .dataPinStartIndex = DT_INST_PROP(n, data_pin_start), \ + .ENWRPinIndex = DT_INST_PROP(n, enwr_pin), \ + .RDPinIndex = DT_INST_PROP_OR(n, rd_pin, 0), \ + .setCSPin = flexio_lcdif_set_cs, \ + .setRSPin = flexio_lcdif_set_rs, \ + .setRDWRPin = flexio_lcdif_set_rd_wr, \ + }; \ + \ + static uint8_t mcux_flexio_lcdif_shifters_##n[DT_INST_PROP(n, shifters_count)]; \ + static uint8_t mcux_flexio_lcdif_timers_##n[DT_INST_PROP(n, timers_count)]; \ + \ + static const struct nxp_flexio_child lcdif_child_##n = { \ + .isr = NULL, \ + .user_data = (void *)DEVICE_DT_INST_GET(n), \ + .res = { \ + .shifter_index = mcux_flexio_lcdif_shifters_##n, \ + .shifter_count = ARRAY_SIZE(mcux_flexio_lcdif_shifters_##n), \ + .timer_index = mcux_flexio_lcdif_timers_##n, \ + .timer_count = ARRAY_SIZE(mcux_flexio_lcdif_timers_##n), \ + } \ + }; \ + \ + struct mcux_flexio_lcdif_config mcux_flexio_lcdif_config_##n = { \ + .flexio_lcd_dev = &flexio_mculcd_##n, \ + .flexio_dev = DEVICE_DT_GET(DT_INST_PARENT(n)), \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + .child = &lcdif_child_##n, \ + .reset = GPIO_DT_SPEC_INST_GET(n, reset_gpios), \ + .cs_gpio = GPIO_DT_SPEC_INST_GET(n, cs_gpios), \ + .rs_gpio = GPIO_DT_SPEC_INST_GET(n, rs_gpios), \ + .rdwr_gpio = GPIO_DT_SPEC_INST_GET_OR(n, rdwr_gpios, {0}), \ + }; \ + struct mcux_flexio_lcdif_data mcux_flexio_lcdif_data_##n = { \ + .dma_tx = { \ + .dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, tx)), \ + .channel = DT_INST_DMAS_CELL_BY_NAME(n, tx, mux), \ + .dma_cfg = { \ + .channel_direction = MEMORY_TO_MEMORY, \ + .dma_callback = flexio_lcdif_dma_callback, \ + .dest_data_size = 4, \ + .block_count = 1, \ + .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, tx, source) \ + } \ + }, \ + }; \ + DEVICE_DT_INST_DEFINE(n, \ + &flexio_lcdif_init, \ + NULL, \ + &mcux_flexio_lcdif_data_##n, \ + &mcux_flexio_lcdif_config_##n, \ + POST_KERNEL, \ + CONFIG_MIPI_DBI_INIT_PRIORITY, \ + &mipi_dbi_lcdif_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(MCUX_FLEXIO_LCDIF_DEVICE_INIT) diff --git a/dts/arm/nxp/nxp_mcxn94x_common.dtsi b/dts/arm/nxp/nxp_mcxn94x_common.dtsi index 054ad3700d8..c14a6f2698e 100644 --- a/dts/arm/nxp/nxp_mcxn94x_common.dtsi +++ b/dts/arm/nxp/nxp_mcxn94x_common.dtsi @@ -904,6 +904,18 @@ clk-source = <1>; resolution = <32>; }; + + flexio0: flexio@105000 { + compatible = "nxp,flexio"; + reg = <0x105000 0x1000>; + status = "disabled"; + interrupts = <105 0>; + clocks = <&syscon MCUX_FLEXIO0_CLK>; + flexio0_lcd: flexio0-lcd { + compatible = "nxp,mipi-dbi-flexio-lcdif"; + status = "disabled"; + }; + }; }; &systick { diff --git a/dts/bindings/mipi-dbi/nxp,mipi-dbi-flexio-lcdif.yaml b/dts/bindings/mipi-dbi/nxp,mipi-dbi-flexio-lcdif.yaml new file mode 100644 index 00000000000..25851966505 --- /dev/null +++ b/dts/bindings/mipi-dbi/nxp,mipi-dbi-flexio-lcdif.yaml @@ -0,0 +1,63 @@ +# Copyright 2024 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP FlexIO LCD controller + +compatible: "nxp,mipi-dbi-flexio-lcdif" + +include: [mipi-dbi-controller.yaml, base.yaml, pinctrl-device.yaml] + +properties: + shifters-count: + type: int + required: true + description: | + Number of FlexIO shifters needed. + + timers-count: + type: int + required: true + description: | + Number of FlexIO timers needed. + + enwr-pin: + type: int + required: true + description: | + Pin select for WR(8080 mode), EN(6800 mode). + + rd-pin: + type: int + description: | + Pin select for RD(8080 mode), not used in 6800 mode. + + data-pin-start: + type: int + required: true + description: | + Start index of the data pin. + + cs-gpios: + type: phandle-array + required: true + description: | + CS Pin + GPIO to drive the CS pin. + + rs-gpios: + type: phandle-array + required: true + description: | + RS Pin + GPIO to drive the RS pin. + + rdwr-gpios: + type: phandle-array + description: | + RDWR Pin + GPIO to drive the RDWR pin. This is required for Motorola 68K bus. + + reset-gpios: + type: phandle-array + description: | + Reset GPIO pin.