drivers: display: uc81xx: convert to MIPI DBI API
Convert UC81XX display to use MIPI DBI API, as this display uses a SPI 3/4 wire bus. In tree shields using this driver have also had their devicetrees updated to use the new MIPI DBI SPI driver Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
parent
25cdda10e1
commit
9fdaf43e79
6 changed files with 157 additions and 198 deletions
|
|
@ -8,87 +8,93 @@
|
|||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,display = &uc8176_waveshare_epaper_gdew042t2-p;
|
||||
zephyr,display = &uc8176_waveshare_epaper_gdew042t2_p;
|
||||
};
|
||||
};
|
||||
|
||||
&arduino_spi {
|
||||
/*
|
||||
* GoodDisplay GDEW042T2 with fast partial refresh. Based on
|
||||
* configuration from GoodDisplay's Arduino example.
|
||||
*/
|
||||
uc8176_waveshare_epaper_gdew042t2-p: uc8176@0 {
|
||||
compatible = "gooddisplay,gdew042t2", "ultrachip,uc8176";
|
||||
spi-max-frequency = <4000000>;
|
||||
reg = <0>;
|
||||
width = <400>;
|
||||
height = <300>;
|
||||
dc-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */
|
||||
mipi_dbi_waveshare_epaper_gdew042t2-p {
|
||||
compatible = "zephyr,mipi-dbi-spi";
|
||||
spi-dev = <&arduino_spi>;
|
||||
dc-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */
|
||||
reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
|
||||
busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
|
||||
write-only;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
softstart = [ 17 17 17 ];
|
||||
/*
|
||||
* GoodDisplay GDEW042T2 with fast partial refresh. Based on
|
||||
* configuration from GoodDisplay's Arduino example.
|
||||
*/
|
||||
uc8176_waveshare_epaper_gdew042t2_p: uc8176@0 {
|
||||
compatible = "gooddisplay,gdew042t2", "ultrachip,uc8176";
|
||||
mipi-max-frequency = <4000000>;
|
||||
reg = <0>;
|
||||
width = <400>;
|
||||
height = <300>;
|
||||
busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
|
||||
|
||||
full {
|
||||
cdi = <0x07>;
|
||||
};
|
||||
softstart = [ 17 17 17 ];
|
||||
|
||||
partial {
|
||||
pwr = [ 03 02 2b 2b ];
|
||||
cdi = <0x07>;
|
||||
pll = <0x3c>;
|
||||
vdcs = <0x08>;
|
||||
full {
|
||||
cdi = <0x07>;
|
||||
};
|
||||
|
||||
lutc = [
|
||||
00 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00
|
||||
];
|
||||
partial {
|
||||
pwr = [ 03 02 2b 2b ];
|
||||
cdi = <0x07>;
|
||||
pll = <0x3c>;
|
||||
vdcs = <0x08>;
|
||||
|
||||
lutww = [
|
||||
00 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
lutc = [
|
||||
00 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00
|
||||
];
|
||||
|
||||
lutkw = [
|
||||
20 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
lutww = [
|
||||
00 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
|
||||
lutwk = [
|
||||
10 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
lutkw = [
|
||||
20 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
|
||||
lutkk = [
|
||||
00 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
lutwk = [
|
||||
10 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
|
||||
lutkk = [
|
||||
00 01 0E 00 00 01
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
00 00 00 00 00 00
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,25 +9,31 @@
|
|||
chosen {
|
||||
zephyr,display = &uc8176_waveshare_epaper_gdew042t2;
|
||||
};
|
||||
};
|
||||
|
||||
&arduino_spi {
|
||||
uc8176_waveshare_epaper_gdew042t2: uc8176@0 {
|
||||
compatible = "gooddisplay,gdew042t2", "ultrachip,uc8176";
|
||||
spi-max-frequency = <4000000>;
|
||||
reg = <0>;
|
||||
width = <400>;
|
||||
height = <300>;
|
||||
dc-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */
|
||||
mipi_dbi_waveshare_epaper_gdew042t2 {
|
||||
compatible = "zephyr,mipi-dbi-spi";
|
||||
spi-dev = <&arduino_spi>;
|
||||
dc-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */
|
||||
reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
|
||||
busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
|
||||
write-only;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
softstart = [17 17 17];
|
||||
uc8176_waveshare_epaper_gdew042t2: uc8176@0 {
|
||||
compatible = "gooddisplay,gdew042t2", "ultrachip,uc8176";
|
||||
mipi-max-frequency = <4000000>;
|
||||
reg = <0>;
|
||||
width = <400>;
|
||||
height = <300>;
|
||||
busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
|
||||
|
||||
full {
|
||||
pwr = [03 00 26 26 09];
|
||||
cdi = <0xd7>;
|
||||
tcon = <0x22>;
|
||||
softstart = [17 17 17];
|
||||
|
||||
full {
|
||||
pwr = [03 00 26 26 09];
|
||||
cdi = <0xd7>;
|
||||
tcon = <0x22>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,25 +10,31 @@
|
|||
chosen {
|
||||
zephyr,display = &uc8179_waveshare_epaper_gdew075t7;
|
||||
};
|
||||
};
|
||||
|
||||
&arduino_spi {
|
||||
uc8179_waveshare_epaper_gdew075t7: uc8179@0 {
|
||||
compatible = "gooddisplay,gdew075t7", "ultrachip,uc8179";
|
||||
spi-max-frequency = <4000000>;
|
||||
reg = <0>;
|
||||
width = <800>;
|
||||
height = <480>;
|
||||
dc-gpios = <&arduino_header 15 GPIO_ACTIVE_LOW>; /* D9 */
|
||||
mipi_dbi_waveshare_epaper_gdew075t7 {
|
||||
compatible = "zephyr,mipi-dbi-spi";
|
||||
spi-dev = <&arduino_spi>;
|
||||
dc-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */
|
||||
reset-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */
|
||||
busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
|
||||
write-only;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
softstart = [17 17 17 17];
|
||||
uc8179_waveshare_epaper_gdew075t7: uc8179@0 {
|
||||
compatible = "gooddisplay,gdew075t7", "ultrachip,uc8179";
|
||||
mipi-max-frequency = <4000000>;
|
||||
reg = <0>;
|
||||
width = <800>;
|
||||
height = <480>;
|
||||
busy-gpios = <&arduino_header 13 GPIO_ACTIVE_LOW>; /* D7 */
|
||||
|
||||
full {
|
||||
pwr = [07 07 3f 3f];
|
||||
cdi = <07>;
|
||||
tcon = <0x22>;
|
||||
softstart = [17 17 17 17];
|
||||
|
||||
full {
|
||||
pwr = [07 07 3f 3f];
|
||||
cdi = <07>;
|
||||
tcon = <0x22>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ config UC81XX
|
|||
bool "UltraChip UC81xx compatible display controller driver"
|
||||
default y
|
||||
depends on DT_HAS_ULTRACHIP_UC8175_ENABLED || DT_HAS_ULTRACHIP_UC8176_ENABLED || DT_HAS_ULTRACHIP_UC8179_ENABLED
|
||||
select SPI
|
||||
select MIPI_DBI
|
||||
help
|
||||
Enable driver for UC81xx compatible controller.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Andreas Sandberg
|
||||
* Copyright (c) 2020 PHYTEC Messtechnik GmbH
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
|
@ -10,7 +11,7 @@
|
|||
#include <zephyr/init.h>
|
||||
#include <zephyr/drivers/display.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/spi.h>
|
||||
#include <zephyr/drivers/mipi_dbi.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#include "uc81xx_regs.h"
|
||||
|
|
@ -75,10 +76,9 @@ struct uc81xx_quirks {
|
|||
struct uc81xx_config {
|
||||
const struct uc81xx_quirks *quirks;
|
||||
|
||||
struct spi_dt_spec bus;
|
||||
struct gpio_dt_spec dc_gpio;
|
||||
const struct device *mipi_dev;
|
||||
const struct mipi_dbi_config dbi_config;
|
||||
struct gpio_dt_spec busy_gpio;
|
||||
struct gpio_dt_spec reset_gpio;
|
||||
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
|
|
@ -110,39 +110,13 @@ static inline int uc81xx_write_cmd(const struct device *dev, uint8_t cmd,
|
|||
const uint8_t *data, size_t len)
|
||||
{
|
||||
const struct uc81xx_config *config = dev->config;
|
||||
struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)};
|
||||
struct spi_buf_set buf_set = {.buffers = &buf, .count = 1};
|
||||
int err;
|
||||
|
||||
uc81xx_busy_wait(dev);
|
||||
|
||||
err = gpio_pin_set_dt(&config->dc_gpio, 1);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = spi_write_dt(&config->bus, &buf_set);
|
||||
if (err < 0) {
|
||||
goto spi_out;
|
||||
}
|
||||
|
||||
if (data != NULL) {
|
||||
buf.buf = (void *)data;
|
||||
buf.len = len;
|
||||
|
||||
err = gpio_pin_set_dt(&config->dc_gpio, 0);
|
||||
if (err < 0) {
|
||||
goto spi_out;
|
||||
}
|
||||
|
||||
err = spi_write_dt(&config->bus, &buf_set);
|
||||
if (err < 0) {
|
||||
goto spi_out;
|
||||
}
|
||||
}
|
||||
|
||||
spi_out:
|
||||
spi_release_dt(&config->bus);
|
||||
err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config,
|
||||
cmd, data, len);
|
||||
mipi_dbi_release(config->mipi_dev, &config->dbi_config);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -151,43 +125,42 @@ static inline int uc81xx_write_cmd_pattern(const struct device *dev,
|
|||
uint8_t pattern, size_t len)
|
||||
{
|
||||
const struct uc81xx_config *config = dev->config;
|
||||
struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)};
|
||||
struct spi_buf_set buf_set = {.buffers = &buf, .count = 1};
|
||||
struct display_buffer_descriptor mipi_desc;
|
||||
int err;
|
||||
uint8_t data[64];
|
||||
|
||||
uc81xx_busy_wait(dev);
|
||||
|
||||
err = gpio_pin_set_dt(&config->dc_gpio, 1);
|
||||
err = mipi_dbi_command_write(config->mipi_dev, &config->dbi_config,
|
||||
cmd, NULL, 0);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = spi_write_dt(&config->bus, &buf_set);
|
||||
if (err < 0) {
|
||||
goto spi_out;
|
||||
}
|
||||
|
||||
err = gpio_pin_set_dt(&config->dc_gpio, 0);
|
||||
if (err < 0) {
|
||||
goto spi_out;
|
||||
}
|
||||
/*
|
||||
* MIPI display write API requires a display buffer descriptor.
|
||||
* Create one that describes the buffer we are writing
|
||||
*/
|
||||
mipi_desc.height = 1;
|
||||
|
||||
memset(data, pattern, sizeof(data));
|
||||
while (len) {
|
||||
buf.buf = data;
|
||||
buf.len = MIN(len, sizeof(data));
|
||||
mipi_desc.buf_size = mipi_desc.width = mipi_desc.pitch =
|
||||
MIN(len, sizeof(data));
|
||||
|
||||
err = spi_write_dt(&config->bus, &buf_set);
|
||||
err = mipi_dbi_write_display(config->mipi_dev,
|
||||
&config->dbi_config,
|
||||
data, &mipi_desc,
|
||||
PIXEL_FORMAT_MONO10);
|
||||
if (err < 0) {
|
||||
goto spi_out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len -= buf.len;
|
||||
len -= mipi_desc.buf_size;
|
||||
}
|
||||
|
||||
spi_out:
|
||||
spi_release_dt(&config->bus);
|
||||
out:
|
||||
mipi_dbi_release(config->mipi_dev, &config->dbi_config);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -544,9 +517,7 @@ static int uc81xx_controller_init(const struct device *dev)
|
|||
const struct uc81xx_config *config = dev->config;
|
||||
struct uc81xx_data *data = dev->data;
|
||||
|
||||
gpio_pin_set_dt(&config->reset_gpio, 1);
|
||||
k_sleep(K_MSEC(UC81XX_RESET_DELAY));
|
||||
gpio_pin_set_dt(&config->reset_gpio, 0);
|
||||
mipi_dbi_reset(config->mipi_dev, UC81XX_RESET_DELAY);
|
||||
k_sleep(K_MSEC(UC81XX_RESET_DELAY));
|
||||
uc81xx_busy_wait(dev);
|
||||
|
||||
|
|
@ -570,26 +541,11 @@ static int uc81xx_init(const struct device *dev)
|
|||
|
||||
LOG_DBG("");
|
||||
|
||||
if (!spi_is_ready_dt(&config->bus)) {
|
||||
LOG_ERR("SPI bus %s not ready", config->bus.bus->name);
|
||||
if (!device_is_ready(config->mipi_dev)) {
|
||||
LOG_ERR("MIPI device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!gpio_is_ready_dt(&config->reset_gpio)) {
|
||||
LOG_ERR("Reset GPIO device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
|
||||
if (!gpio_is_ready_dt(&config->dc_gpio)) {
|
||||
LOG_ERR("DC GPIO device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpio_pin_configure_dt(&config->dc_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
|
||||
|
||||
if (!gpio_is_ready_dt(&config->busy_gpio)) {
|
||||
LOG_ERR("Busy GPIO device not ready");
|
||||
return -ENODEV;
|
||||
|
|
@ -816,12 +772,14 @@ static const struct display_driver_api uc81xx_driver_api = {
|
|||
\
|
||||
static const struct uc81xx_config uc81xx_cfg_ ## n = { \
|
||||
.quirks = quirks_ptr, \
|
||||
.bus = SPI_DT_SPEC_GET(n, \
|
||||
SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | \
|
||||
SPI_LOCK_ON, \
|
||||
0), \
|
||||
.reset_gpio = GPIO_DT_SPEC_GET(n, reset_gpios), \
|
||||
.dc_gpio = GPIO_DT_SPEC_GET(n, dc_gpios), \
|
||||
.mipi_dev = DEVICE_DT_GET(DT_PARENT(n)), \
|
||||
.dbi_config = { \
|
||||
.mode = MIPI_DBI_MODE_SPI_4WIRE, \
|
||||
.config = MIPI_DBI_SPI_CONFIG_DT(n, \
|
||||
SPI_OP_MODE_MASTER | \
|
||||
SPI_LOCK_ON | SPI_WORD_SET(8), \
|
||||
0), \
|
||||
}, \
|
||||
.busy_gpio = GPIO_DT_SPEC_GET(n, busy_gpios), \
|
||||
\
|
||||
.height = DT_PROP(n, height), \
|
||||
|
|
|
|||
|
|
@ -1,30 +1,13 @@
|
|||
# Copyright (c) 2022 Andreas Sandberg
|
||||
# Copyright (c) 2020, Phytec Messtechnik GmbH
|
||||
# Copyright 2024 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: UltraChip UC81xx EPD display controller common properties
|
||||
|
||||
include: [spi-device.yaml, display-controller.yaml]
|
||||
include: [mipi-dbi-spi-device.yaml, display-controller.yaml]
|
||||
|
||||
properties:
|
||||
reset-gpios:
|
||||
type: phandle-array
|
||||
required: true
|
||||
description: RESET pin.
|
||||
|
||||
The RESET pin of UC81xx 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 UC81xx 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
|
||||
|
|
|
|||
Loading…
Reference in a new issue