drivers: ssd16xx: add multi-instance support
Get rid of all DT_INST_PROP(0,...) and rework the driver to support multiple instances. Signed-off-by: Johann Fischer <johann.fischer@nordicsemi.no>
This commit is contained in:
parent
1c78447428
commit
a2e7e9a0e0
1 changed files with 248 additions and 149 deletions
|
@ -25,18 +25,9 @@ LOG_MODULE_REGISTER(ssd16xx);
|
|||
* SSD1673, SSD1608, SSD1681, ILI3897 compatible EPD controller driver.
|
||||
*/
|
||||
|
||||
#define EPD_PANEL_WIDTH DT_INST_PROP(0, width)
|
||||
#define EPD_PANEL_HEIGHT DT_INST_PROP(0, height)
|
||||
#define EPD_PANEL_NUMOF_COLUMS EPD_PANEL_WIDTH
|
||||
#define EPD_PANEL_NUMOF_ROWS_PER_PAGE 8
|
||||
#define EPD_PANEL_NUMOF_PAGES (EPD_PANEL_HEIGHT / \
|
||||
EPD_PANEL_NUMOF_ROWS_PER_PAGE)
|
||||
|
||||
#define SSD16XX_PANEL_FIRST_PAGE 0
|
||||
#define SSD16XX_PANEL_LAST_PAGE (EPD_PANEL_NUMOF_PAGES - 1)
|
||||
#define SSD16XX_PANEL_FIRST_GATE 0
|
||||
#define SSD16XX_PANEL_LAST_GATE (EPD_PANEL_NUMOF_COLUMS - 1)
|
||||
|
||||
#define SSD16XX_PIXELS_PER_BYTE 8
|
||||
#define SSD16XX_DEFAULT_TR_VALUE 25U
|
||||
#define SSD16XX_TR_SCALE_FACTOR 256U
|
||||
|
@ -46,25 +37,31 @@ struct ssd16xx_data {
|
|||
uint8_t update_cmd;
|
||||
};
|
||||
|
||||
struct ssd16xx_dt_array {
|
||||
uint8_t *data;
|
||||
uint8_t len;
|
||||
};
|
||||
|
||||
struct ssd16xx_config {
|
||||
struct spi_dt_spec bus;
|
||||
struct gpio_dt_spec dc_gpio;
|
||||
struct gpio_dt_spec busy_gpio;
|
||||
struct gpio_dt_spec reset_gpio;
|
||||
struct ssd16xx_dt_array lut_initial;
|
||||
struct ssd16xx_dt_array lut_default;
|
||||
struct ssd16xx_dt_array softstart;
|
||||
struct ssd16xx_dt_array gdv;
|
||||
struct ssd16xx_dt_array sdv;
|
||||
bool orientation;
|
||||
uint16_t height;
|
||||
uint16_t width;
|
||||
uint8_t vcom;
|
||||
uint8_t b_waveform;
|
||||
uint8_t tssv;
|
||||
uint8_t pp_width_bits;
|
||||
uint8_t pp_height_bits;
|
||||
};
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, lut_initial)
|
||||
static uint8_t ssd16xx_lut_initial[] = DT_INST_PROP(0, lut_initial);
|
||||
#endif
|
||||
#if DT_INST_NODE_HAS_PROP(0, lut_default)
|
||||
static uint8_t ssd16xx_lut_default[] = DT_INST_PROP(0, lut_default);
|
||||
#endif
|
||||
#if DT_INST_NODE_HAS_PROP(0, softstart)
|
||||
static uint8_t ssd16xx_softstart[] = DT_INST_PROP(0, softstart);
|
||||
#endif
|
||||
static uint8_t ssd16xx_gdv[] = DT_INST_PROP(0, gdv);
|
||||
static uint8_t ssd16xx_sdv[] = DT_INST_PROP(0, sdv);
|
||||
|
||||
static inline int ssd16xx_write_cmd(const struct device *dev, uint8_t cmd,
|
||||
uint8_t *data, size_t len)
|
||||
{
|
||||
|
@ -104,49 +101,63 @@ static inline void ssd16xx_busy_wait(const struct device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static inline size_t push_x_param(uint8_t *data, uint16_t x)
|
||||
static inline size_t push_x_param(const struct device *dev,
|
||||
uint8_t *data, uint16_t x)
|
||||
{
|
||||
#if DT_INST_PROP(0, pp_width_bits) == 8
|
||||
data[0] = (uint8_t)x;
|
||||
return 1;
|
||||
#elif DT_INST_PROP(0, pp_width_bits) == 16
|
||||
sys_put_le16(sys_cpu_to_le16(x), data);
|
||||
return 2;
|
||||
#else
|
||||
#error Unsupported pp_width_bits value for solomon,ssd16xxfb DTS instance 0
|
||||
#endif
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
|
||||
if (config->pp_width_bits == 8) {
|
||||
data[0] = (uint8_t)x;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (config->pp_width_bits == 16) {
|
||||
sys_put_le16(sys_cpu_to_le16(x), data);
|
||||
return 2;
|
||||
}
|
||||
|
||||
LOG_ERR("Unsupported pp_width_bits %u", config->pp_width_bits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline size_t push_y_param(uint8_t *data, uint16_t y)
|
||||
static inline size_t push_y_param(const struct device *dev,
|
||||
uint8_t *data, uint16_t y)
|
||||
{
|
||||
#if DT_INST_PROP(0, pp_height_bits) == 8
|
||||
data[0] = (uint8_t)y;
|
||||
return 1;
|
||||
#elif DT_INST_PROP(0, pp_height_bits) == 16
|
||||
sys_put_le16(sys_cpu_to_le16(y), data);
|
||||
return 2;
|
||||
#else
|
||||
#error Unsupported pp_height_bits value for solomon,ssd16xxfb DTS instance 0
|
||||
#endif
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
|
||||
if (config->pp_height_bits == 8) {
|
||||
data[0] = (uint8_t)y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (config->pp_height_bits == 16) {
|
||||
sys_put_le16(sys_cpu_to_le16(y), data);
|
||||
return 2;
|
||||
}
|
||||
|
||||
LOG_ERR("Unsupported pp_height_bitsa %u", config->pp_height_bits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline int ssd16xx_set_ram_param(const struct device *dev,
|
||||
uint16_t sx, uint16_t ex, uint16_t sy, uint16_t ey)
|
||||
uint16_t sx, uint16_t ex,
|
||||
uint16_t sy, uint16_t ey)
|
||||
{
|
||||
int err;
|
||||
uint8_t tmp[4];
|
||||
size_t len;
|
||||
|
||||
len = push_x_param(tmp, sx);
|
||||
len += push_x_param(tmp + len, ex);
|
||||
len = push_x_param(dev, tmp, sx);
|
||||
len += push_x_param(dev, tmp + len, ex);
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_RAM_XPOS_CTRL, tmp, len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
len = push_y_param(tmp, sy);
|
||||
len += push_y_param(tmp + len, ey);
|
||||
len = push_y_param(dev, tmp, sy);
|
||||
len += push_y_param(dev, tmp + len, ey);
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_RAM_YPOS_CTRL, tmp, len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
|
@ -162,26 +173,16 @@ static inline int ssd16xx_set_ram_ptr(const struct device *dev, uint16_t x,
|
|||
uint8_t tmp[2];
|
||||
size_t len;
|
||||
|
||||
len = push_x_param(tmp, x);
|
||||
len = push_x_param(dev, tmp, x);
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_RAM_XPOS_CNTR, tmp, len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
len = push_y_param(tmp, y);
|
||||
len = push_y_param(dev, tmp, y);
|
||||
return ssd16xx_write_cmd(dev, SSD16XX_CMD_RAM_YPOS_CNTR, tmp, len);
|
||||
}
|
||||
|
||||
static void ssd16xx_set_orientation_internall(struct ssd16xx_data *driver)
|
||||
|
||||
{
|
||||
#if DT_INST_PROP(0, orientation_flipped) == 1
|
||||
driver->scan_mode = SSD16XX_DATA_ENTRY_XIYDY;
|
||||
#else
|
||||
driver->scan_mode = SSD16XX_DATA_ENTRY_XDYIY;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ssd16xx_blanking_off(const struct device *dev)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
|
@ -211,6 +212,7 @@ static int ssd16xx_write(const struct device *dev, const uint16_t x,
|
|||
const struct display_buffer_descriptor *desc,
|
||||
const void *buf)
|
||||
{
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
struct ssd16xx_data *driver = dev->data;
|
||||
int err;
|
||||
size_t buf_len;
|
||||
|
@ -218,8 +220,8 @@ static int ssd16xx_write(const struct device *dev, const uint16_t x,
|
|||
uint16_t x_end;
|
||||
uint16_t y_start;
|
||||
uint16_t y_end;
|
||||
uint16_t panel_h = EPD_PANEL_HEIGHT -
|
||||
EPD_PANEL_HEIGHT % EPD_PANEL_NUMOF_ROWS_PER_PAGE;
|
||||
uint16_t panel_h = config->height -
|
||||
config->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE;
|
||||
|
||||
if (desc->pitch < desc->width) {
|
||||
LOG_ERR("Pitch is smaller than width");
|
||||
|
@ -242,7 +244,7 @@ static int ssd16xx_write(const struct device *dev, const uint16_t x,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((x + desc->width) > EPD_PANEL_WIDTH) {
|
||||
if ((x + desc->width) > config->width) {
|
||||
LOG_ERR("Buffer out of bounds (width)");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -336,10 +338,12 @@ static int ssd16xx_set_contrast(const struct device *dev, uint8_t contrast)
|
|||
static void ssd16xx_get_capabilities(const struct device *dev,
|
||||
struct display_capabilities *caps)
|
||||
{
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
|
||||
memset(caps, 0, sizeof(struct display_capabilities));
|
||||
caps->x_resolution = EPD_PANEL_WIDTH;
|
||||
caps->y_resolution = EPD_PANEL_HEIGHT -
|
||||
EPD_PANEL_HEIGHT % EPD_PANEL_NUMOF_ROWS_PER_PAGE;
|
||||
caps->x_resolution = config->width;
|
||||
caps->y_resolution = config->height -
|
||||
config->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE;
|
||||
caps->supported_pixel_formats = PIXEL_FORMAT_MONO10;
|
||||
caps->current_pixel_format = PIXEL_FORMAT_MONO10;
|
||||
caps->screen_info = SCREEN_INFO_MONO_VTILED |
|
||||
|
@ -370,16 +374,17 @@ static int ssd16xx_set_pixel_format(const struct device *dev,
|
|||
static int ssd16xx_clear_cntlr_mem(const struct device *dev, uint8_t ram_cmd,
|
||||
bool update)
|
||||
{
|
||||
uint8_t clear_page[EPD_PANEL_WIDTH];
|
||||
uint16_t panel_h = EPD_PANEL_HEIGHT /
|
||||
EPD_PANEL_NUMOF_ROWS_PER_PAGE;
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
uint16_t panel_h = config->height / EPD_PANEL_NUMOF_ROWS_PER_PAGE;
|
||||
uint16_t last_gate = config->width - 1;
|
||||
uint8_t scan_mode = SSD16XX_DATA_ENTRY_XIYDY;
|
||||
uint8_t clear_page[256]; /* User large array for now */
|
||||
|
||||
/*
|
||||
* Clear unusable memory area when the resolution of the panel is not
|
||||
* multiple of an octet.
|
||||
*/
|
||||
if (EPD_PANEL_HEIGHT % EPD_PANEL_NUMOF_ROWS_PER_PAGE) {
|
||||
if (config->height % EPD_PANEL_NUMOF_ROWS_PER_PAGE) {
|
||||
panel_h += 1;
|
||||
}
|
||||
|
||||
|
@ -389,13 +394,13 @@ static int ssd16xx_clear_cntlr_mem(const struct device *dev, uint8_t ram_cmd,
|
|||
|
||||
if (ssd16xx_set_ram_param(dev, SSD16XX_PANEL_FIRST_PAGE,
|
||||
panel_h - 1,
|
||||
SSD16XX_PANEL_LAST_GATE,
|
||||
last_gate,
|
||||
SSD16XX_PANEL_FIRST_GATE)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (ssd16xx_set_ram_ptr(dev, SSD16XX_PANEL_FIRST_PAGE,
|
||||
SSD16XX_PANEL_LAST_GATE)) {
|
||||
last_gate)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -415,112 +420,125 @@ static int ssd16xx_clear_cntlr_mem(const struct device *dev, uint8_t ram_cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int ssd16xx_load_ws_from_otp(const struct device *dev)
|
||||
static inline int ssd16xx_load_ws_from_otp_tssv(const struct device *dev)
|
||||
{
|
||||
struct ssd16xx_data *driver = dev->data;
|
||||
uint8_t tmp[2];
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
struct ssd16xx_data *data = dev->data;
|
||||
uint8_t tssv = config->tssv;
|
||||
int err;
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, tssv)
|
||||
/*
|
||||
* Controller has an integrated temperature sensor or external
|
||||
* temperature sensor is connected to the controller.
|
||||
*/
|
||||
LOG_INF("Select and load WS from OTP");
|
||||
|
||||
tmp[0] = DT_INST_PROP(0, tssv);
|
||||
if (ssd16xx_write_cmd(dev,
|
||||
SSD16XX_CMD_TSENSOR_SELECTION,
|
||||
tmp, 1)) {
|
||||
return -EIO;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_TSENSOR_SELECTION, &tssv, 1);
|
||||
if (err == 0) {
|
||||
data->update_cmd |= SSD16XX_CTRL2_LOAD_LUT |
|
||||
SSD16XX_CTRL2_LOAD_TEMPERATURE;
|
||||
}
|
||||
|
||||
driver->update_cmd |= SSD16XX_CTRL2_LOAD_LUT |
|
||||
SSD16XX_CTRL2_LOAD_TEMPERATURE;
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
static inline int ssd16xx_load_ws_from_otp(const struct device *dev)
|
||||
{
|
||||
int16_t t = (SSD16XX_DEFAULT_TR_VALUE * SSD16XX_TR_SCALE_FACTOR);
|
||||
struct ssd16xx_data *data = dev->data;
|
||||
uint8_t tmp[2];
|
||||
int err;
|
||||
|
||||
LOG_INF("Load default WS (25 degrees Celsius) from OTP");
|
||||
|
||||
tmp[0] = SSD16XX_CTRL2_ENABLE_CLK;
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_CTRL2,
|
||||
tmp, 1)) {
|
||||
return -EIO;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_CTRL2, tmp, 1);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_MASTER_ACTIVATION,
|
||||
NULL, 0)) {
|
||||
return -EIO;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_MASTER_ACTIVATION, NULL, 0);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
ssd16xx_busy_wait(dev);
|
||||
|
||||
/* Load temperature value */
|
||||
sys_put_be16(t, tmp);
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_TSENS_CTRL,
|
||||
tmp, 2)) {
|
||||
return -EIO;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_TSENS_CTRL, tmp, 2);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
tmp[0] = SSD16XX_CTRL2_DISABLE_CLK;
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_CTRL2,
|
||||
tmp, 1)) {
|
||||
return -EIO;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_CTRL2, tmp, 1);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_MASTER_ACTIVATION,
|
||||
NULL, 0)) {
|
||||
return -EIO;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_MASTER_ACTIVATION, NULL, 0);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
ssd16xx_busy_wait(dev);
|
||||
|
||||
driver->update_cmd |= SSD16XX_CTRL2_LOAD_LUT;
|
||||
data->update_cmd |= SSD16XX_CTRL2_LOAD_LUT;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ssd16xx_load_ws_initial(const struct device *dev)
|
||||
{
|
||||
#if DT_INST_NODE_HAS_PROP(0, lut_initial)
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_LUT,
|
||||
ssd16xx_lut_initial,
|
||||
sizeof(ssd16xx_lut_initial))) {
|
||||
return -EIO;
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
int err = 0;
|
||||
|
||||
if (config->lut_initial.len) {
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_LUT,
|
||||
config->lut_initial.data,
|
||||
config->lut_initial.len);
|
||||
|
||||
if (err == 0) {
|
||||
ssd16xx_busy_wait(dev);
|
||||
}
|
||||
} else {
|
||||
if (config->tssv) {
|
||||
err = ssd16xx_load_ws_from_otp_tssv(dev);
|
||||
} else {
|
||||
err = ssd16xx_load_ws_from_otp(dev);
|
||||
}
|
||||
}
|
||||
|
||||
ssd16xx_busy_wait(dev);
|
||||
#else
|
||||
ssd16xx_load_ws_from_otp(dev);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ssd16xx_load_ws_default(const struct device *dev)
|
||||
{
|
||||
#if DT_INST_NODE_HAS_PROP(0, lut_default)
|
||||
if (ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_LUT,
|
||||
ssd16xx_lut_default,
|
||||
sizeof(ssd16xx_lut_default))) {
|
||||
return -EIO;
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
int err = 0;
|
||||
|
||||
if (config->lut_default.len) {
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_UPDATE_LUT,
|
||||
config->lut_default.data,
|
||||
config->lut_default.len);
|
||||
|
||||
if (err == 0) {
|
||||
ssd16xx_busy_wait(dev);
|
||||
}
|
||||
}
|
||||
|
||||
ssd16xx_busy_wait(dev);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int ssd16xx_controller_init(const struct device *dev)
|
||||
{
|
||||
const struct ssd16xx_config *config = dev->config;
|
||||
struct ssd16xx_data *driver = dev->data;
|
||||
uint16_t last_gate = config->width - 1;
|
||||
int err;
|
||||
uint8_t tmp[3];
|
||||
size_t len;
|
||||
struct ssd16xx_data *driver = dev->data;
|
||||
|
||||
LOG_DBG("");
|
||||
|
||||
|
@ -536,34 +554,35 @@ static int ssd16xx_controller_init(const struct device *dev)
|
|||
}
|
||||
ssd16xx_busy_wait(dev);
|
||||
|
||||
len = push_y_param(tmp, SSD16XX_PANEL_LAST_GATE);
|
||||
len = push_y_param(dev, tmp, last_gate);
|
||||
tmp[len++] = 0U;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_GDO_CTRL, tmp, len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if DT_INST_NODE_HAS_PROP(0, softstart)
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_SOFTSTART,
|
||||
ssd16xx_softstart, sizeof(ssd16xx_softstart));
|
||||
if (err < 0) {
|
||||
return err;
|
||||
if (config->softstart.len) {
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_SOFTSTART,
|
||||
config->softstart.data,
|
||||
config->softstart.len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_GDV_CTRL, ssd16xx_gdv,
|
||||
sizeof(ssd16xx_gdv));
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_GDV_CTRL, config->gdv.data,
|
||||
config->gdv.len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_SDV_CTRL, ssd16xx_sdv,
|
||||
sizeof(ssd16xx_sdv));
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_SDV_CTRL, config->sdv.data,
|
||||
config->sdv.len);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
tmp[0] = DT_INST_PROP(0, vcom);
|
||||
tmp[0] = config->vcom;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_VCOM_VOLTAGE, tmp, 1);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
|
@ -581,13 +600,18 @@ static int ssd16xx_controller_init(const struct device *dev)
|
|||
return err;
|
||||
}
|
||||
|
||||
tmp[0] = DT_INST_PROP(0, border_waveform);
|
||||
tmp[0] = config->b_waveform;
|
||||
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_BWF_CTRL, tmp, 1);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
ssd16xx_set_orientation_internall(driver);
|
||||
if (config->orientation == 1) {
|
||||
driver->scan_mode = SSD16XX_DATA_ENTRY_XIYDY;
|
||||
} else {
|
||||
driver->scan_mode = SSD16XX_DATA_ENTRY_XDYIY;
|
||||
}
|
||||
|
||||
driver->update_cmd = (SSD16XX_CTRL2_ENABLE_CLK |
|
||||
SSD16XX_CTRL2_ENABLE_ANALOG |
|
||||
SSD16XX_CTRL2_TO_PATTERN |
|
||||
|
@ -655,16 +679,6 @@ static int ssd16xx_init(const struct device *dev)
|
|||
return ssd16xx_controller_init(dev);
|
||||
}
|
||||
|
||||
static const struct ssd16xx_config ssd16xx_config = {
|
||||
.bus = SPI_DT_SPEC_INST_GET(
|
||||
0, SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0),
|
||||
.reset_gpio = GPIO_DT_SPEC_INST_GET(0, reset_gpios),
|
||||
.dc_gpio = GPIO_DT_SPEC_INST_GET(0, dc_gpios),
|
||||
.busy_gpio = GPIO_DT_SPEC_INST_GET(0, busy_gpios),
|
||||
};
|
||||
|
||||
static struct ssd16xx_data ssd16xx_driver;
|
||||
|
||||
static struct display_driver_api ssd16xx_driver_api = {
|
||||
.blanking_on = ssd16xx_blanking_on,
|
||||
.blanking_off = ssd16xx_blanking_off,
|
||||
|
@ -678,7 +692,92 @@ static struct display_driver_api ssd16xx_driver_api = {
|
|||
.set_orientation = ssd16xx_set_orientation,
|
||||
};
|
||||
|
||||
#define LUT_INITIAL_DEFINE(n) \
|
||||
static uint8_t lut_initial_##n[] = DT_INST_PROP(n, lut_initial);
|
||||
#define LUT_DEFAULT_DEFINE(n) \
|
||||
static uint8_t lut_default_##n[] = DT_INST_PROP(n, lut_default);
|
||||
#define SOFTSTART_DEFINE(n) \
|
||||
static uint8_t softstart_##n[] = DT_INST_PROP(n, softstart);
|
||||
|
||||
DEVICE_DT_INST_DEFINE(0, ssd16xx_init, NULL, &ssd16xx_driver, &ssd16xx_config,
|
||||
POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY,
|
||||
&ssd16xx_driver_api);
|
||||
#define LUT_INITIAL_ASSIGN(n) \
|
||||
.lut_initial = { \
|
||||
.data = lut_initial_##n, \
|
||||
.len = sizeof(lut_initial_##n), \
|
||||
},
|
||||
|
||||
#define LUT_DEFAULT_ASSIGN(n) \
|
||||
.lut_default = { \
|
||||
.data = lut_default_##n, \
|
||||
.len = sizeof(lut_default_##n), \
|
||||
},
|
||||
|
||||
#define SOFTSTART_ASSIGN(n) \
|
||||
.softstart = { \
|
||||
.data = softstart_##n, \
|
||||
.len = sizeof(softstart_##n), \
|
||||
},
|
||||
|
||||
#define CMD_ARRAY_DEFINE(n) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, lut_initial), \
|
||||
(LUT_INITIAL_DEFINE(n)), \
|
||||
()) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, lut_default), \
|
||||
(LUT_DEFAULT_DEFINE(n)), \
|
||||
()) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, softstart), \
|
||||
(SOFTSTART_DEFINE(n)), \
|
||||
())
|
||||
|
||||
#define CMD_ARRAY_COND(n) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, lut_initial), \
|
||||
(LUT_INITIAL_ASSIGN(n)), \
|
||||
()) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, lut_default), \
|
||||
(LUT_DEFAULT_ASSIGN(n)), \
|
||||
()) \
|
||||
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, softstart), \
|
||||
(SOFTSTART_ASSIGN(n)), \
|
||||
())
|
||||
|
||||
#define SSD16XX_DEFINE(n) \
|
||||
static uint8_t gdv_##n[] = DT_INST_PROP(n, gdv); \
|
||||
static uint8_t sdv_##n[] = DT_INST_PROP(n, sdv); \
|
||||
\
|
||||
CMD_ARRAY_DEFINE(n) \
|
||||
\
|
||||
static const struct ssd16xx_config ssd16xx_cfg_##n = { \
|
||||
.bus = SPI_DT_SPEC_INST_GET(n, \
|
||||
SPI_OP_MODE_MASTER | SPI_WORD_SET(8), 0), \
|
||||
.reset_gpio = GPIO_DT_SPEC_INST_GET(n, reset_gpios), \
|
||||
.dc_gpio = GPIO_DT_SPEC_INST_GET(n, dc_gpios), \
|
||||
.busy_gpio = GPIO_DT_SPEC_INST_GET(n, busy_gpios), \
|
||||
.height = DT_INST_PROP(n, height), \
|
||||
.width = DT_INST_PROP(n, width), \
|
||||
.orientation = DT_INST_PROP(n, orientation_flipped), \
|
||||
.vcom = DT_INST_PROP(n, vcom), \
|
||||
.pp_width_bits = DT_INST_PROP(n, pp_width_bits), \
|
||||
.pp_height_bits = DT_INST_PROP(n, pp_height_bits), \
|
||||
.b_waveform = DT_INST_PROP(n, border_waveform), \
|
||||
.gdv = { \
|
||||
.data = gdv_##n, \
|
||||
.len = sizeof(gdv_##n), \
|
||||
}, \
|
||||
.sdv = { \
|
||||
.data = sdv_##n, \
|
||||
.len = sizeof(sdv_##n), \
|
||||
}, \
|
||||
.tssv = DT_INST_PROP_OR(n, tssv, 0), \
|
||||
CMD_ARRAY_COND(n) \
|
||||
}; \
|
||||
\
|
||||
static struct ssd16xx_data ssd16xx_data_##n; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, ssd16xx_init, NULL, \
|
||||
&ssd16xx_data_##n, \
|
||||
&ssd16xx_cfg_##n, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_DISPLAY_INIT_PRIORITY, \
|
||||
&ssd16xx_driver_api); \
|
||||
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(SSD16XX_DEFINE)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue