blob: 5bdb8edf28cc8f42c88d0eef7dba12a32a8ba66a [file] [log] [blame]
/*
* Copyright (c) 2023 Jamie McCrae
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT hit_hd44780
#include <string.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/auxdisplay.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(auxdisplay_hd44780, CONFIG_AUXDISPLAY_LOG_LEVEL);
#define AUXDISPLAY_HD44780_BACKLIGHT_MIN 0
#define AUXDISPLAY_HD44780_BACKLIGHT_MAX 1
#define AUXDISPLAY_HD44780_CUSTOM_CHARACTERS 8
#define AUXDISPLAY_HD44780_CUSTOM_CHARACTER_WIDTH 5
#define AUXDISPLAY_HD44780_CUSTOM_CHARACTER_HEIGHT 8
enum {
AUXDISPLAY_HD44780_MODE_4_BIT = 0,
AUXDISPLAY_HD44780_MODE_8_BIT = 1,
/* Reserved for internal driver use only */
AUXDISPLAY_HD44780_MODE_4_BIT_ONCE,
};
/* Display commands */
#define AUXDISPLAY_HD44780_CMD_CLEAR 0x01
#define AUXDISPLAY_HD44780_CMD_ENTRY_MODE 0x04
#define AUXDISPLAY_HD44780_CMD_DISPLAY_MODE 0x08
#define AUXDISPLAY_HD44780_CMD_CGRAM_SET 0x40
#define AUXDISPLAY_HD44780_CMD_POSITION_SET 0x80
#define AUXDISPLAY_HD44780_CMD_SETUP 0x20
#define AUXDISPLAY_HD44780_8_BIT_CONFIG 0x10
#define AUXDISPLAY_HD44780_2_LINE_CONFIG 0x08
#define AUXDISPLAY_HD44780_POSITION_BLINK_ENABLED 0x01
#define AUXDISPLAY_HD44780_CURSOR_ENABLED 0x02
#define AUXDISPLAY_HD44780_DISPLAY_ENABLED 0x04
#define AUXDISPLAY_HD44780_DISPLAY_SHIFT 0x01
#define AUXDISPLAY_HD44780_CURSOR_MOVE_RIGHT 0x02
struct auxdisplay_hd44780_data {
uint16_t character_x;
uint16_t character_y;
bool cursor_enabled;
bool position_blink_enabled;
uint8_t direction;
bool display_shift;
bool backlight_state;
};
struct auxdisplay_hd44780_config {
struct auxdisplay_capabilities capabilities;
struct gpio_dt_spec rs_gpio;
struct gpio_dt_spec rw_gpio;
struct gpio_dt_spec e_gpio;
struct gpio_dt_spec db_gpios[8];
struct gpio_dt_spec backlight_gpio;
uint8_t line_addresses[4];
uint16_t enable_line_rise_delay;
uint16_t enable_line_fall_delay;
uint16_t rs_line_delay;
uint16_t clear_delay;
uint16_t boot_delay;
};
static void auxdisplay_hd44780_set_entry_mode(const struct device *dev);
static void auxdisplay_hd44780_set_display_mode(const struct device *dev, bool enabled);
static int auxdisplay_hd44780_clear(const struct device *dev);
static void hd44780_pulse_enable_line(const struct device *dev)
{
const struct auxdisplay_hd44780_config *const config = dev->config;
gpio_pin_set_dt(&config->e_gpio, 1);
k_sleep(K_NSEC(config->enable_line_rise_delay));
gpio_pin_set_dt(&config->e_gpio, 0);
k_sleep(K_NSEC(config->enable_line_fall_delay));
}
static inline void hd44780_set_rs_rw_lines(const struct device *dev, bool rs, bool rw)
{
const struct auxdisplay_hd44780_config *const config = dev->config;
gpio_pin_set_dt(&config->rs_gpio, rs);
if (config->rw_gpio.port) {
gpio_pin_set_dt(&config->rw_gpio, rw);
}
k_sleep(K_NSEC(config->rs_line_delay));
}
static int hd44780_db_gpios_configure(const struct device *dev, uint8_t lsb_line,
gpio_flags_t flags)
{
const struct auxdisplay_hd44780_config *config = dev->config;
int rc;
for (int line = 7; line >= lsb_line; --line) {
rc = gpio_pin_configure_dt(&config->db_gpios[line], flags);
if (rc < 0) {
return rc;
}
}
return 0;
}
static void auxdisplay_hd44780_command(const struct device *dev, bool rs,
uint8_t cmd, uint8_t mode)
{
int rc;
const struct auxdisplay_hd44780_config *config = dev->config;
int8_t i = 7;
const int8_t lsb_line = (mode == AUXDISPLAY_HD44780_MODE_8_BIT) ? 0 : 4;
int8_t ncommands = (mode == AUXDISPLAY_HD44780_MODE_4_BIT) ? 2 : 1;
const bool check_busy_flag = (!config->rw_gpio.port ||
(mode == AUXDISPLAY_HD44780_MODE_4_BIT_ONCE)) ?
false : true;
if (check_busy_flag) {
bool busy;
rc = hd44780_db_gpios_configure(dev, lsb_line, GPIO_INPUT | GPIO_PULL_DOWN);
if (rc < 0) {
LOG_ERR("Configuration of db-gpios as inputs failed: %d", rc);
return;
}
hd44780_set_rs_rw_lines(dev, 0, 1);
do {
hd44780_pulse_enable_line(dev);
/* We don't care about the other pins. */
busy = gpio_pin_get_dt(&config->db_gpios[7]);
if (config->capabilities.mode == AUXDISPLAY_HD44780_MODE_4_BIT) {
/* In this mode we have to initiate two separate readbacks. */
hd44780_pulse_enable_line(dev);
}
} while (busy);
rc = hd44780_db_gpios_configure(dev, lsb_line, GPIO_OUTPUT);
if (rc < 0) {
LOG_ERR("Configuration of db-gpios as outputs failed: %d", rc);
return;
}
}
hd44780_set_rs_rw_lines(dev, rs, 0);
while (ncommands--) {
for (int8_t line = 7; line >= lsb_line; --line) {
gpio_pin_set_dt(&config->db_gpios[line], ((cmd & BIT(i)) ? 1 : 0));
--i;
}
hd44780_pulse_enable_line(dev);
}
if (!check_busy_flag) {
/* Sleep for a max execution time for a given instruction. */
uint16_t cmd_delay_us = (cmd == AUXDISPLAY_HD44780_CMD_CLEAR) ? 1520 : 37;
k_sleep(K_USEC(cmd_delay_us));
}
}
static void hd44780_ic_initialize(const struct device *dev)
{
const struct auxdisplay_hd44780_config *config = dev->config;
uint8_t cmd;
/*
* If proper power supply is used to power the HD44780, it initializes correctly
* on a reset condition all by itself. However, if the power supply is below
* its expectations (e.g. supplying it with some 3.3V Nucleo board),
* it won't initialize properly on its own, and the MCU has to carry out
* the initialization as listed in the reference manual.
* Since we cannot determine it properly in the runtime,
* always carry out the initialization procedure.
*/
cmd = AUXDISPLAY_HD44780_CMD_SETUP | AUXDISPLAY_HD44780_8_BIT_CONFIG;
auxdisplay_hd44780_command(dev, false, cmd, AUXDISPLAY_HD44780_MODE_4_BIT_ONCE);
k_sleep(K_USEC(4100));
auxdisplay_hd44780_command(dev, false, cmd, AUXDISPLAY_HD44780_MODE_4_BIT_ONCE);
k_sleep(K_USEC(100));
auxdisplay_hd44780_command(dev, false, cmd, AUXDISPLAY_HD44780_MODE_4_BIT_ONCE);
k_sleep(K_USEC(100));
if (config->capabilities.mode == AUXDISPLAY_HD44780_MODE_4_BIT) {
/* Put display into 4-bit mode */
cmd = AUXDISPLAY_HD44780_CMD_SETUP;
auxdisplay_hd44780_command(dev, false, cmd, AUXDISPLAY_HD44780_MODE_4_BIT_ONCE);
}
/* Configure display */
if (config->capabilities.rows > 1) {
cmd |= AUXDISPLAY_HD44780_2_LINE_CONFIG;
}
auxdisplay_hd44780_command(dev, false, cmd, config->capabilities.mode);
auxdisplay_hd44780_set_display_mode(dev, false);
auxdisplay_hd44780_clear(dev);
auxdisplay_hd44780_set_entry_mode(dev);
auxdisplay_hd44780_set_display_mode(dev, true);
}
static int auxdisplay_hd44780_init(const struct device *dev)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
int rc;
uint8_t i = 0;
if (config->capabilities.mode > AUXDISPLAY_HD44780_MODE_8_BIT) {
/* This index is reserved for internal driver usage */
LOG_ERR("HD44780 mode must be 4 or 8-bit");
return -EINVAL;
}
/* Configure and set GPIOs */
rc = gpio_pin_configure_dt(&config->rs_gpio, GPIO_OUTPUT);
if (rc < 0) {
LOG_ERR("Configuration of RS GPIO failed: %d", rc);
return rc;
}
rc = gpio_pin_configure_dt(&config->e_gpio, GPIO_OUTPUT);
if (rc < 0) {
LOG_ERR("Configuration of E GPIO failed: %d", rc);
return rc;
}
if (config->capabilities.mode == AUXDISPLAY_HD44780_MODE_4_BIT) {
i = 4;
}
while (i < 8) {
if (config->db_gpios[i].port) {
rc = gpio_pin_configure_dt(&config->db_gpios[i], GPIO_OUTPUT);
if (rc < 0) {
LOG_ERR("Configuration of DB%d GPIO failed: %d", i, rc);
return rc;
}
} else if (config->capabilities.mode == AUXDISPLAY_HD44780_MODE_4_BIT && i > 3) {
/* Required pin missing */
LOG_ERR("Required DB%d pin missing (DB4-DB7 needed for 4-bit mode)", i);
return -EINVAL;
} else if (config->capabilities.mode == AUXDISPLAY_HD44780_MODE_8_BIT) {
/* Required pin missing */
LOG_ERR("Required DB%d pin missing", i);
return -EINVAL;
}
++i;
}
if (config->rw_gpio.port) {
rc = gpio_pin_configure_dt(&config->rw_gpio, GPIO_OUTPUT);
if (rc < 0) {
LOG_ERR("Configuration of RW GPIO failed: %d", rc);
return rc;
}
}
if (config->backlight_gpio.port) {
rc = gpio_pin_configure_dt(&config->backlight_gpio, GPIO_OUTPUT);
if (rc < 0) {
LOG_ERR("Configuration of backlight GPIO failed: %d", rc);
return rc;
}
gpio_pin_set_dt(&config->backlight_gpio, 0);
}
data->character_x = 0;
data->character_y = 0;
data->backlight_state = false;
data->cursor_enabled = false;
data->position_blink_enabled = false;
data->direction = AUXDISPLAY_DIRECTION_RIGHT;
if (config->boot_delay != 0) {
/* Boot delay is set, wait for a period of time for the LCD to become ready to
* accept commands
*/
k_sleep(K_MSEC(config->boot_delay));
}
hd44780_ic_initialize(dev);
return 0;
}
static int auxdisplay_hd44780_capabilities_get(const struct device *dev,
struct auxdisplay_capabilities *capabilities)
{
const struct auxdisplay_hd44780_config *config = dev->config;
memcpy(capabilities, &config->capabilities, sizeof(struct auxdisplay_capabilities));
return 0;
}
static int auxdisplay_hd44780_clear(const struct device *dev)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
auxdisplay_hd44780_command(dev, false, AUXDISPLAY_HD44780_CMD_CLEAR,
config->capabilities.mode);
data->character_x = 0;
data->character_y = 0;
k_sleep(K_USEC(config->clear_delay));
return 0;
}
static void auxdisplay_hd44780_set_entry_mode(const struct device *dev)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
uint8_t cmd = AUXDISPLAY_HD44780_CMD_ENTRY_MODE;
if (data->direction == AUXDISPLAY_DIRECTION_RIGHT) {
cmd |= AUXDISPLAY_HD44780_CURSOR_MOVE_RIGHT;
}
if (data->display_shift) {
cmd |= AUXDISPLAY_HD44780_DISPLAY_SHIFT;
}
auxdisplay_hd44780_command(dev, false, cmd, config->capabilities.mode);
}
static void auxdisplay_hd44780_set_display_mode(const struct device *dev, bool enabled)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
uint8_t cmd = AUXDISPLAY_HD44780_CMD_DISPLAY_MODE;
if (data->cursor_enabled) {
cmd |= AUXDISPLAY_HD44780_CURSOR_ENABLED;
}
if (data->position_blink_enabled) {
cmd |= AUXDISPLAY_HD44780_POSITION_BLINK_ENABLED;
}
if (enabled) {
cmd |= AUXDISPLAY_HD44780_DISPLAY_ENABLED;
}
auxdisplay_hd44780_command(dev, false, cmd, config->capabilities.mode);
}
static int auxdisplay_hd44780_display_on(const struct device *dev)
{
auxdisplay_hd44780_set_display_mode(dev, true);
return 0;
}
static int auxdisplay_hd44780_display_off(const struct device *dev)
{
auxdisplay_hd44780_set_display_mode(dev, false);
return 0;
}
static int auxdisplay_hd44780_cursor_set_enabled(const struct device *dev, bool enabled)
{
struct auxdisplay_hd44780_data *data = dev->data;
data->cursor_enabled = enabled;
auxdisplay_hd44780_set_display_mode(dev, true);
return 0;
}
static int auxdisplay_hd44780_position_blinking_set_enabled(const struct device *dev, bool enabled)
{
struct auxdisplay_hd44780_data *data = dev->data;
data->position_blink_enabled = enabled;
auxdisplay_hd44780_set_display_mode(dev, true);
return 0;
}
static int auxdisplay_hd44780_cursor_shift_set(const struct device *dev, uint8_t direction,
bool display_shift)
{
struct auxdisplay_hd44780_data *data = dev->data;
if (display_shift) {
/* Not currently supported */
return -EINVAL;
}
data->direction = direction;
data->display_shift = (display_shift ? true : false);
auxdisplay_hd44780_set_entry_mode(dev);
return 0;
}
static int auxdisplay_hd44780_cursor_position_set(const struct device *dev,
enum auxdisplay_position type, int16_t x,
int16_t y)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
uint8_t cmd = AUXDISPLAY_HD44780_CMD_POSITION_SET;
if (type == AUXDISPLAY_POSITION_RELATIVE) {
x += (int16_t)data->character_x;
y += (int16_t)data->character_y;
} else if (type == AUXDISPLAY_POSITION_RELATIVE_DIRECTION) {
if (data->direction == AUXDISPLAY_DIRECTION_RIGHT) {
x += (int16_t)data->character_x;
y += (int16_t)data->character_y;
} else {
x -= (int16_t)data->character_x;
y -= (int16_t)data->character_y;
}
}
/* Check position is valid before applying */
if (x < 0 || y < 0) {
return -EINVAL;
} else if (x >= config->capabilities.columns || y >= config->capabilities.rows) {
return -EINVAL;
}
data->character_x = (uint16_t)x;
data->character_y = (uint16_t)y;
cmd |= config->line_addresses[data->character_y] + data->character_x;
auxdisplay_hd44780_command(dev, false, cmd, config->capabilities.mode);
return 0;
}
static int auxdisplay_hd44780_cursor_position_get(const struct device *dev, int16_t *x, int16_t *y)
{
struct auxdisplay_hd44780_data *data = dev->data;
*x = (int16_t)data->character_x;
*y = (int16_t)data->character_y;
return 0;
}
static int auxdisplay_hd44780_backlight_get(const struct device *dev, uint8_t *backlight)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
if (!config->backlight_gpio.port) {
return -ENOTSUP;
}
*backlight = (data->backlight_state == true ? 1 : 0);
return 0;
}
static int auxdisplay_hd44780_backlight_set(const struct device *dev, uint8_t backlight)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
if (!config->backlight_gpio.port) {
return -ENOTSUP;
}
data->backlight_state = (bool)backlight;
gpio_pin_set_dt(&config->backlight_gpio, (uint8_t)data->backlight_state);
return 0;
}
static int auxdisplay_hd44780_custom_character_set(const struct device *dev,
struct auxdisplay_character *character)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
uint8_t i = 0;
uint8_t cmd = AUXDISPLAY_HD44780_CMD_CGRAM_SET | (character->index << 3);
auxdisplay_hd44780_command(dev, false, cmd, config->capabilities.mode);
/* HD44780 accepts 5x8 font but needs 8x8 data to be sent, mask off top 3 bits
* for each line sent
*/
while (i < 8) {
uint8_t l = 0;
cmd = 0;
while (l < 5) {
if (character->data[(i * 5) + (4 - l)]) {
cmd |= BIT(l);
}
++l;
}
auxdisplay_hd44780_command(dev, true, cmd, config->capabilities.mode);
++i;
}
character->character_code = character->index;
/* Send last known address to switch back to DDRAM entry mode */
cmd = AUXDISPLAY_HD44780_CMD_POSITION_SET |
(config->line_addresses[data->character_y] +
data->character_x);
auxdisplay_hd44780_command(dev, false, cmd, config->capabilities.mode);
return 0;
}
static int auxdisplay_hd44780_write(const struct device *dev, const uint8_t *text, uint16_t len)
{
const struct auxdisplay_hd44780_config *config = dev->config;
struct auxdisplay_hd44780_data *data = dev->data;
uint16_t i = 0;
while (i < len) {
auxdisplay_hd44780_command(dev, true, text[i], config->capabilities.mode);
++i;
if (data->direction == AUXDISPLAY_DIRECTION_RIGHT) {
/* Increment */
++data->character_x;
if (data->character_x == config->capabilities.columns) {
data->character_x = 0;
++data->character_y;
if (data->character_y == config->capabilities.rows) {
data->character_y = 0;
}
/* Send command to set position */
uint8_t cmd = AUXDISPLAY_HD44780_CMD_POSITION_SET |
config->line_addresses[data->character_y];
auxdisplay_hd44780_command(dev, false, cmd,
config->capabilities.mode);
}
} else {
/* Decrement */
if (data->character_x == 0) {
data->character_x = config->capabilities.columns - 1;
if (data->character_y == 0) {
data->character_y = config->capabilities.rows - 1;
} else {
--data->character_y;
}
/* Send command to set position */
uint8_t cmd = AUXDISPLAY_HD44780_CMD_POSITION_SET |
(config->line_addresses[data->character_y] +
data->character_x);
auxdisplay_hd44780_command(dev, false, cmd,
config->capabilities.mode);
} else {
--data->character_x;
}
}
}
return 0;
}
static DEVICE_API(auxdisplay, auxdisplay_hd44780_auxdisplay_api) = {
.display_on = auxdisplay_hd44780_display_on,
.display_off = auxdisplay_hd44780_display_off,
.cursor_set_enabled = auxdisplay_hd44780_cursor_set_enabled,
.position_blinking_set_enabled = auxdisplay_hd44780_position_blinking_set_enabled,
.cursor_shift_set = auxdisplay_hd44780_cursor_shift_set,
.cursor_position_set = auxdisplay_hd44780_cursor_position_set,
.cursor_position_get = auxdisplay_hd44780_cursor_position_get,
.capabilities_get = auxdisplay_hd44780_capabilities_get,
.clear = auxdisplay_hd44780_clear,
.backlight_get = auxdisplay_hd44780_backlight_get,
.backlight_set = auxdisplay_hd44780_backlight_set,
.custom_character_set = auxdisplay_hd44780_custom_character_set,
.write = auxdisplay_hd44780_write,
};
/* Returns desired value if backlight is enabled, otherwise returns not supported value */
#define BACKLIGHT_CHECK(inst, value) \
COND_CODE_1(DT_PROP_HAS_IDX(DT_DRV_INST(inst), backlight_gpios, 0), (value), \
(AUXDISPLAY_LIGHT_NOT_SUPPORTED))
#define AUXDISPLAY_HD44780_DEVICE(inst) \
static struct auxdisplay_hd44780_data auxdisplay_hd44780_data_##inst; \
static const struct auxdisplay_hd44780_config auxdisplay_hd44780_config_##inst = { \
.capabilities = { \
.columns = DT_INST_PROP(inst, columns), \
.rows = DT_INST_PROP(inst, rows), \
.mode = DT_INST_ENUM_IDX(inst, mode), \
.brightness.minimum = AUXDISPLAY_LIGHT_NOT_SUPPORTED, \
.brightness.maximum = AUXDISPLAY_LIGHT_NOT_SUPPORTED, \
.backlight.minimum = BACKLIGHT_CHECK(inst, \
AUXDISPLAY_HD44780_BACKLIGHT_MIN), \
.backlight.maximum = BACKLIGHT_CHECK(inst, \
AUXDISPLAY_HD44780_BACKLIGHT_MAX), \
.custom_characters = AUXDISPLAY_HD44780_CUSTOM_CHARACTERS, \
.custom_character_width = AUXDISPLAY_HD44780_CUSTOM_CHARACTER_WIDTH, \
.custom_character_height = AUXDISPLAY_HD44780_CUSTOM_CHARACTER_HEIGHT, \
}, \
.rs_gpio = GPIO_DT_SPEC_INST_GET(inst, register_select_gpios), \
.rw_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, read_write_gpios, {0}), \
.e_gpio = GPIO_DT_SPEC_INST_GET(inst, enable_gpios), \
.db_gpios[0] = GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, data_bus_gpios, 0, {0}), \
.db_gpios[1] = GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, data_bus_gpios, 1, {0}), \
.db_gpios[2] = GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, data_bus_gpios, 2, {0}), \
.db_gpios[3] = GPIO_DT_SPEC_INST_GET_BY_IDX_OR(inst, data_bus_gpios, 3, {0}), \
.db_gpios[4] = GPIO_DT_SPEC_INST_GET_BY_IDX(inst, data_bus_gpios, 4), \
.db_gpios[5] = GPIO_DT_SPEC_INST_GET_BY_IDX(inst, data_bus_gpios, 5), \
.db_gpios[6] = GPIO_DT_SPEC_INST_GET_BY_IDX(inst, data_bus_gpios, 6), \
.db_gpios[7] = GPIO_DT_SPEC_INST_GET_BY_IDX(inst, data_bus_gpios, 7), \
.line_addresses[0] = DT_INST_PROP_BY_IDX(inst, line_addresses, 0), \
.line_addresses[1] = DT_INST_PROP_BY_IDX(inst, line_addresses, 1), \
.line_addresses[2] = DT_INST_PROP_BY_IDX(inst, line_addresses, 2), \
.line_addresses[3] = DT_INST_PROP_BY_IDX(inst, line_addresses, 3), \
.backlight_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, backlight_gpios, {0}), \
.enable_line_rise_delay = DT_INST_PROP(inst, enable_line_rise_delay_ns), \
.enable_line_fall_delay = DT_INST_PROP(inst, enable_line_fall_delay_ns), \
.rs_line_delay = DT_INST_PROP(inst, rs_line_delay_ns), \
.clear_delay = DT_INST_PROP(inst, clear_command_delay_us), \
.boot_delay = DT_INST_PROP(inst, boot_delay_ms), \
}; \
DEVICE_DT_INST_DEFINE(inst, \
&auxdisplay_hd44780_init, \
NULL, \
&auxdisplay_hd44780_data_##inst, \
&auxdisplay_hd44780_config_##inst, \
POST_KERNEL, \
CONFIG_AUXDISPLAY_INIT_PRIORITY, \
&auxdisplay_hd44780_auxdisplay_api);
DT_INST_FOREACH_STATUS_OKAY(AUXDISPLAY_HD44780_DEVICE)