From 2f7e822705386b9569e44d25370b9c940abfb63f Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Sun, 16 Apr 2023 15:15:33 +0900 Subject: [PATCH] drivers: display: ssd1306: determin sh1106 by dts compatibility Determine sh1106 from the `compatibility` value instead of the SSD1306_CONTROLLER_TYPE setting. Change the settings in `boards/shields/ssd1306/sh1106_128x64.overlay` to follow this change. Remove the SSD1306_CONTROLLER_TYPE from its Kconfig.defconfig, and set the `compatibility` to `sinowealth,sh1106`. Signed-off-by: TOKITA Hiroshi --- boards/shields/ssd1306/Kconfig.defconfig | 4 - boards/shields/ssd1306/sh1106_128x64.overlay | 2 +- drivers/display/Kconfig.ssd1306 | 18 +--- drivers/display/ssd1306.c | 95 +++++++++++-------- .../display/sinowealth,sh1106-i2c.yaml | 8 ++ .../display/sinowealth,sh1106-spi.yaml | 14 +++ dts/bindings/vendor-prefixes.txt | 1 + 7 files changed, 82 insertions(+), 60 deletions(-) create mode 100644 dts/bindings/display/sinowealth,sh1106-i2c.yaml create mode 100644 dts/bindings/display/sinowealth,sh1106-spi.yaml diff --git a/boards/shields/ssd1306/Kconfig.defconfig b/boards/shields/ssd1306/Kconfig.defconfig index 960247d2f1d..3fc5d5a7c05 100644 --- a/boards/shields/ssd1306/Kconfig.defconfig +++ b/boards/shields/ssd1306/Kconfig.defconfig @@ -5,10 +5,6 @@ if SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X64_SPI || SHIELD_SSD1306_128X32 | if DISPLAY -choice SSD1306_CONTROLLER_TYPE - default SSD1306_SH1106_COMPATIBLE if SHIELD_SH1106_128X64 -endchoice - if LVGL config LV_Z_VDB_SIZE diff --git a/boards/shields/ssd1306/sh1106_128x64.overlay b/boards/shields/ssd1306/sh1106_128x64.overlay index 354b818cbd8..a9e4e0768ad 100644 --- a/boards/shields/ssd1306/sh1106_128x64.overlay +++ b/boards/shields/ssd1306/sh1106_128x64.overlay @@ -14,7 +14,7 @@ status = "okay"; sh1106_sh1106_128x64: ssd1306@3c { - compatible = "solomon,ssd1306fb"; + compatible = "sinowealth,sh1106"; reg = <0x3c>; width = <128>; height = <64>; diff --git a/drivers/display/Kconfig.ssd1306 b/drivers/display/Kconfig.ssd1306 index af7992b09b4..32f8b0e1423 100644 --- a/drivers/display/Kconfig.ssd1306 +++ b/drivers/display/Kconfig.ssd1306 @@ -6,9 +6,11 @@ menuconfig SSD1306 bool "SSD1306 display driver" default y - depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED + depends on DT_HAS_SOLOMON_SSD1306FB_ENABLED || DT_HAS_SINOWEALTH_SH1106_ENABLED select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),i2c) select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SOLOMON_SSD1306FB),spi) + select I2C if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),i2c) + select SPI if $(dt_compat_on_bus,$(DT_COMPAT_SINOWEALTH_SH1106),spi) help Enable driver for SSD1306 display driver. @@ -21,18 +23,4 @@ config SSD1306_DEFAULT_CONTRAST help SSD1306 default contrast. -choice SSD1306_CONTROLLER_TYPE - prompt "Display controller type" - default SSD1306_DEFAULT - help - Specify the type of the controller. - -config SSD1306_DEFAULT - bool "Default SSD1306 controller" - -config SSD1306_SH1106_COMPATIBLE - bool "SH1106 compatible mode" - -endchoice - endif # SSD1306 diff --git a/drivers/display/ssd1306.c b/drivers/display/ssd1306.c index f0b9fccd5d4..95457ff7865 100644 --- a/drivers/display/ssd1306.c +++ b/drivers/display/ssd1306.c @@ -4,7 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#if defined(CONFIG_DT_HAS_SOLOMON_SSD1306FB_ENABLED) #define DT_DRV_COMPAT solomon_ssd1306fb +#elif defined(CONFIG_DT_HAS_SINOWEALTH_SH1106_ENABLED) +#define DT_DRV_COMPAT sinowealth_sh1106 +#endif #include LOG_MODULE_REGISTER(ssd1306, CONFIG_DISPLAY_LOG_LEVEL); @@ -48,6 +52,7 @@ struct ssd1306_config { bool com_invdir; bool com_sequential; bool color_inversion; + bool sh1106_compatible; int ready_time_ms; }; @@ -155,15 +160,11 @@ static inline int ssd1306_set_hardware_config(const struct device *dev) static inline int ssd1306_set_charge_pump(const struct device *dev) { + const struct ssd1306_config *config = dev->config; uint8_t cmd_buf[] = { -#if defined(CONFIG_SSD1306_DEFAULT) - SSD1306_SET_CHARGE_PUMP_ON, - SSD1306_SET_CHARGE_PUMP_ON_ENABLED, -#endif -#if defined(CONFIG_SSD1306_SH1106_COMPATIBLE) - SH1106_SET_DCDC_MODE, - SH1106_SET_DCDC_ENABLED, -#endif + (config->sh1106_compatible ? SH1106_SET_DCDC_MODE : SSD1306_SET_CHARGE_PUMP_ON), + (config->sh1106_compatible ? SH1106_SET_DCDC_ENABLED + : SSD1306_SET_CHARGE_PUMP_ON_ENABLED), SSD1306_PANEL_PUMP_VOLTAGE, }; @@ -188,37 +189,10 @@ static int ssd1306_suspend(const struct device *dev) return ssd1306_write_bus(dev, cmd_buf, sizeof(cmd_buf), true); } -static int ssd1306_write(const struct device *dev, const uint16_t x, const uint16_t y, - const struct display_buffer_descriptor *desc, - const void *buf) +static int ssd1306_write_default(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf, + const size_t buf_len) { - size_t buf_len; - - if (desc->pitch < desc->width) { - LOG_ERR("Pitch is smaller then width"); - return -1; - } - - buf_len = MIN(desc->buf_size, desc->height * desc->width / 8); - if (buf == NULL || buf_len == 0U) { - LOG_ERR("Display buffer is not available"); - return -1; - } - - if (desc->pitch > desc->width) { - LOG_ERR("Unsupported mode"); - return -1; - } - - if ((y & 0x7) != 0U) { - LOG_ERR("Unsupported origin"); - return -1; - } - - LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", - x, y, desc->pitch, desc->width, desc->height, buf_len); - -#if defined(CONFIG_SSD1306_DEFAULT) uint8_t cmd_buf[] = { SSD1306_SET_MEM_ADDRESSING_MODE, SSD1306_ADDRESSING_MODE, @@ -236,8 +210,12 @@ static int ssd1306_write(const struct device *dev, const uint16_t x, const uint1 } return ssd1306_write_bus(dev, (uint8_t *)buf, buf_len, false); +} -#elif defined(CONFIG_SSD1306_SH1106_COMPATIBLE) +static int ssd1306_write_sh1106(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf, + const size_t buf_len) +{ const struct ssd1306_config *config = dev->config; uint8_t x_offset = x + config->segment_offset; uint8_t cmd_buf[] = { @@ -268,11 +246,47 @@ static int ssd1306_write(const struct device *dev, const uint16_t x, const uint1 return -1; } } -#endif return 0; } +static int ssd1306_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + const struct ssd1306_config *config = dev->config; + size_t buf_len; + + if (desc->pitch < desc->width) { + LOG_ERR("Pitch is smaller then width"); + return -1; + } + + buf_len = MIN(desc->buf_size, desc->height * desc->width / 8); + if (buf == NULL || buf_len == 0U) { + LOG_ERR("Display buffer is not available"); + return -1; + } + + if (desc->pitch > desc->width) { + LOG_ERR("Unsupported mode"); + return -1; + } + + if ((y & 0x7) != 0U) { + LOG_ERR("Unsupported origin"); + return -1; + } + + LOG_DBG("x %u, y %u, pitch %u, width %u, height %u, buf_len %u", x, y, desc->pitch, + desc->width, desc->height, buf_len); + + if (config->sh1106_compatible) { + return ssd1306_write_sh1106(dev, x, y, desc, buf, buf_len); + } + + return ssd1306_write_default(dev, x, y, desc, buf, buf_len); +} + static int ssd1306_read(const struct device *dev, const uint16_t x, const uint16_t y, const struct display_buffer_descriptor *desc, @@ -438,6 +452,7 @@ static const struct ssd1306_config ssd1306_config = { .com_sequential = DT_INST_PROP(0, com_sequential), .prechargep = DT_INST_PROP(0, prechargep), .color_inversion = DT_INST_PROP(0, inversion_on), + .sh1106_compatible = DT_NODE_HAS_COMPAT(0, sinowealth_sh1106), .ready_time_ms = DT_INST_PROP(0, ready_time_ms), }; diff --git a/dts/bindings/display/sinowealth,sh1106-i2c.yaml b/dts/bindings/display/sinowealth,sh1106-i2c.yaml new file mode 100644 index 00000000000..f476f838bbf --- /dev/null +++ b/dts/bindings/display/sinowealth,sh1106-i2c.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: SH1106 128x64 dot-matrix display controller on I2C bus + +compatible: "sinowealth,sh1106" + +include: ["solomon,ssd1306fb-common.yaml", "i2c-device.yaml"] diff --git a/dts/bindings/display/sinowealth,sh1106-spi.yaml b/dts/bindings/display/sinowealth,sh1106-spi.yaml new file mode 100644 index 00000000000..5fe3a2cf0f5 --- /dev/null +++ b/dts/bindings/display/sinowealth,sh1106-spi.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2023, TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: SH1106 128x64 dot-matrix display controller on SPI bus + +compatible: "sinowealth,sh1106" + +include: ["solomon,ssd1306fb-common.yaml", "spi-device.yaml"] + +properties: + data_cmd-gpios: + type: phandle-array + required: true + description: D/C# pin. diff --git a/dts/bindings/vendor-prefixes.txt b/dts/bindings/vendor-prefixes.txt index a2af2b9249a..4b2ab91c73e 100644 --- a/dts/bindings/vendor-prefixes.txt +++ b/dts/bindings/vendor-prefixes.txt @@ -563,6 +563,7 @@ simcom SIMCom Wireless Solutions Co., LTD simtek Cypress Semiconductor Corporation (Simtek Corporation) sinlinx Sinlinx Electronics Technology Co., LTD sinovoip SinoVoip Co., Ltd +sinowealth Sino Wealth Electronic Ltd sipeed Shenzhen Sipeed Technology Co., Ltd. sirf SiRF Technology, Inc. sis Silicon Integrated Systems Corp.