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 <tokita.hiroshi@gmail.com>
This commit is contained in:
TOKITA Hiroshi 2023-04-16 15:15:33 +09:00 committed by Martí Bolívar
parent 91d750ea94
commit 2f7e822705
7 changed files with 82 additions and 60 deletions

View file

@ -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

View file

@ -14,7 +14,7 @@
status = "okay";
sh1106_sh1106_128x64: ssd1306@3c {
compatible = "solomon,ssd1306fb";
compatible = "sinowealth,sh1106";
reg = <0x3c>;
width = <128>;
height = <64>;

View file

@ -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

View file

@ -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 <zephyr/logging/log.h>
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),
};

View file

@ -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"]

View file

@ -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.

View file

@ -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.