From f683b188b35fddf23ddba08b61d4da3316bee123 Mon Sep 17 00:00:00 2001 From: Eve Redero Date: Thu, 16 Jan 2025 11:27:28 +0100 Subject: [PATCH] drivers: display: ssd1306: add power pin support Add a power pin toggling feature in ssd1306 driver Signed-off-by: Eve Redero --- drivers/display/ssd1306.c | 40 ++++++++++++++++++++++++++++++++-- drivers/display/ssd1306_regs.h | 1 + 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index d16e12bdc1b..8fe6a929313 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -43,6 +43,7 @@ struct ssd1306_config { union ssd1306_bus bus; struct gpio_dt_spec data_cmd; struct gpio_dt_spec reset; + struct gpio_dt_spec supply; ssd1306_bus_ready_fn bus_ready; ssd1306_write_bus_fn write_bus; ssd1306_bus_name_fn bus_name; @@ -226,19 +227,33 @@ static inline int ssd1306_set_iref_mode(const struct device *dev) static int ssd1306_resume(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_DISPLAY_ON, }; + /* Turn on supply if pin connected */ + if (config->supply.port) { + gpio_pin_set_dt(&config->supply, 1); + k_sleep(K_MSEC(SSD1306_SUPPLY_DELAY)); + } + return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } static int ssd1306_suspend(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { SSD1306_DISPLAY_OFF, }; + /* Turn off supply if pin connected */ + if (config->supply.port) { + gpio_pin_set_dt(&config->supply, 0); + k_sleep(K_MSEC(SSD1306_SUPPLY_DELAY)); + } + return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } @@ -408,6 +423,11 @@ static int ssd1306_init_device(const struct device *dev) }; data->pf = config->color_inversion ? PIXEL_FORMAT_MONO10 : PIXEL_FORMAT_MONO01; + /* Turn on supply if pin connected */ + if (config->supply.port) { + gpio_pin_set_dt(&config->supply, 1); + k_sleep(K_MSEC(SSD1306_SUPPLY_DELAY)); + } /* Reset if pin connected */ if (config->reset.port) { @@ -460,6 +480,7 @@ static int ssd1306_init_device(const struct device *dev) static int ssd1306_init(const struct device *dev) { const struct ssd1306_config *config = dev->config; + int ret; k_sleep(K_TIMEOUT_ABS_MS(config->ready_time_ms)); @@ -468,14 +489,28 @@ static int ssd1306_init(const struct device *dev) return -EINVAL; } - if (config->reset.port) { - int ret; + if (config->supply.port) { + ret = gpio_pin_configure_dt(&config->supply, + GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + return ret; + } + if (!gpio_is_ready_dt(&config->supply)) { + LOG_ERR("Supply GPIO device not ready"); + return -ENODEV; + } + } + if (config->reset.port) { ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE); if (ret < 0) { return ret; } + if (!gpio_is_ready_dt(&config->reset)) { + LOG_ERR("Reset GPIO device not ready"); + return -ENODEV; + } } if (ssd1306_init_device(dev)) { @@ -514,6 +549,7 @@ static DEVICE_API(display, ssd1306_driver_api) = { static struct ssd1306_data data##node_id; \ static const struct ssd1306_config config##node_id = { \ .reset = GPIO_DT_SPEC_GET_OR(node_id, reset_gpios, {0}), \ + .supply = GPIO_DT_SPEC_GET_OR(node_id, supply_gpios, {0}), \ .height = DT_PROP(node_id, height), \ .width = DT_PROP(node_id, width), \ .segment_offset = DT_PROP(node_id, segment_offset), \ diff --git a/drivers/display/ssd1306_regs.h b/drivers/display/ssd1306_regs.h index c2982c1fae6..87dc3b6ba5b 100644 --- a/drivers/display/ssd1306_regs.h +++ b/drivers/display/ssd1306_regs.h @@ -118,5 +118,6 @@ /* time constants in ms */ #define SSD1306_RESET_DELAY 1 +#define SSD1306_SUPPLY_DELAY 20 #endif