drivers: ssd16xx: support to load default WS from OTP

Add support to load default WS from OTP.

Signed-off-by: Johann Fischer <j.fischer@phytec.de>
This commit is contained in:
Johann Fischer 2020-05-11 12:36:02 +02:00 committed by Carles Cufí
commit ac19e0f263
3 changed files with 107 additions and 28 deletions

View file

@ -54,6 +54,8 @@ LOG_MODULE_REGISTER(ssd16xx);
#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
struct ssd16xx_data {
struct device *reset;
@ -65,24 +67,21 @@ struct ssd16xx_data {
struct spi_cs_control cs_ctrl;
#endif
uint8_t scan_mode;
uint8_t update_cmd;
};
#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);
#if !DT_INST_NODE_HAS_PROP(0, lut_initial)
#error "No initial waveform look up table (LUT) selected!"
#endif
#if !DT_INST_NODE_HAS_PROP(0, lut_default)
#error "No default waveform look up table (LUT) selected!"
#endif
static inline int ssd16xx_write_cmd(struct ssd16xx_data *driver,
uint8_t cmd, uint8_t *data, size_t len)
{
@ -211,16 +210,10 @@ static int ssd16xx_blanking_on(const struct device *dev)
static int ssd16xx_update_display(const struct device *dev)
{
struct ssd16xx_data *driver = dev->driver_data;
uint8_t tmp;
int err;
tmp = (SSD16XX_CTRL2_ENABLE_CLK |
SSD16XX_CTRL2_ENABLE_ANALOG |
SSD16XX_CTRL2_TO_PATTERN |
SSD16XX_CTRL2_DISABLE_ANALOG |
SSD16XX_CTRL2_DISABLE_CLK);
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_CTRL2, &tmp,
sizeof(tmp));
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_CTRL2,
&driver->update_cmd, 1);
if (err < 0) {
return err;
}
@ -439,6 +432,89 @@ static int ssd16xx_clear_cntlr_mem(struct device *dev, uint8_t ram_cmd,
return 0;
}
static inline int ssd16xx_load_ws_from_otp(struct device *dev)
{
struct ssd16xx_data *driver = dev->driver_data;
int16_t t = (SSD16XX_DEFAULT_TR_VALUE * SSD16XX_TR_SCALE_FACTOR);
uint8_t tmp[2];
LOG_INF("Load default WS (25 degrees Celsius) from OTP");
tmp[0] = SSD16XX_CTRL2_ENABLE_CLK;
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_CTRL2,
tmp, 1)) {
return -EIO;
}
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_MASTER_ACTIVATION,
NULL, 0)) {
return -EIO;
}
ssd16xx_busy_wait(driver);
/* Load temperature value */
sys_put_be16(t, tmp);
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_TSENS_CTRL,
tmp, 2)) {
return -EIO;
}
tmp[0] = SSD16XX_CTRL2_DISABLE_CLK;
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_CTRL2,
tmp, 1)) {
return -EIO;
}
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_MASTER_ACTIVATION,
NULL, 0)) {
return -EIO;
}
ssd16xx_busy_wait(driver);
driver->update_cmd |= SSD16XX_CTRL2_LOAD_LUT;
return 0;
}
static int ssd16xx_load_ws_initial(struct device *dev)
{
#if DT_INST_NODE_HAS_PROP(0, lut_initial)
struct ssd16xx_data *driver = dev->driver_data;
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_LUT,
ssd16xx_lut_initial,
sizeof(ssd16xx_lut_initial))) {
return -EIO;
}
ssd16xx_busy_wait(driver);
#else
ssd16xx_load_ws_from_otp(dev);
#endif
return 0;
}
static int ssd16xx_load_ws_default(struct device *dev)
{
#if DT_INST_NODE_HAS_PROP(0, lut_default)
struct ssd16xx_data *driver = dev->driver_data;
if (ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_LUT,
ssd16xx_lut_default,
sizeof(ssd16xx_lut_default))) {
return -EIO;
}
ssd16xx_busy_wait(driver);
#endif
return 0;
}
static int ssd16xx_controller_init(struct device *dev)
{
int err;
@ -512,12 +588,14 @@ static int ssd16xx_controller_init(struct device *dev)
}
ssd16xx_set_orientation_internall(driver);
driver->update_cmd = (SSD16XX_CTRL2_ENABLE_CLK |
SSD16XX_CTRL2_ENABLE_ANALOG |
SSD16XX_CTRL2_TO_PATTERN |
SSD16XX_CTRL2_DISABLE_ANALOG |
SSD16XX_CTRL2_DISABLE_CLK);
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_LUT,
ssd16xx_lut_initial,
sizeof(ssd16xx_lut_initial));
if (err < 0) {
return err;
if (ssd16xx_load_ws_initial(dev)) {
return -EIO;
}
err = ssd16xx_clear_cntlr_mem(dev, SSD16XX_CMD_WRITE_RAM, true);
@ -535,11 +613,8 @@ static int ssd16xx_controller_init(struct device *dev)
ssd16xx_busy_wait(driver);
err = ssd16xx_write_cmd(driver, SSD16XX_CMD_UPDATE_LUT,
ssd16xx_lut_default,
sizeof(ssd16xx_lut_default));
if (err < 0) {
return err;
if (ssd16xx_load_ws_default(dev)) {
return -EIO;
}
return ssd16xx_clear_cntlr_mem(dev, SSD16XX_CMD_WRITE_RAM, true);

View file

@ -17,6 +17,7 @@
#define SSD16XX_CMD_SLEEP_MODE 0x10
#define SSD16XX_CMD_ENTRY_MODE 0x11
#define SSD16XX_CMD_SW_RESET 0x12
#define SSD16XX_CMD_TSENSOR_SELECTION 0x18
#define SSD16XX_CMD_TSENS_CTRL 0x1a
#define SSD16XX_CMD_MASTER_ACTIVATION 0x20
#define SSD16XX_CMD_UPDATE_CTRL1 0x21
@ -28,6 +29,7 @@
#define SSD16XX_CMD_PRGM_VCOM_OTP 0x2a
#define SSD16XX_CMD_VCOM_VOLTAGE 0x2c
#define SSD16XX_CMD_PRGM_WS_OTP 0x30
#define SSD16XX_CMD_LOAD_WS_OTP 0x31
#define SSD16XX_CMD_UPDATE_LUT 0x32
#define SSD16XX_CMD_PRGM_OTP_SELECTION 0x36
#define SSD16XX_CMD_OTP_SELECTION_CTRL 0x37
@ -59,6 +61,8 @@
/* Options for display update sequence */
#define SSD16XX_CTRL2_ENABLE_CLK 0x80
#define SSD16XX_CTRL2_ENABLE_ANALOG 0x40
#define SSD16XX_CTRL2_LOAD_TEMPERATURE 0x20
#define SSD16XX_CTRL2_LOAD_LUT 0x10
#define SSD16XX_CTRL2_TO_INITIAL 0x08
#define SSD16XX_CTRL2_TO_PATTERN 0x04
#define SSD16XX_CTRL2_DISABLE_ANALOG 0x02

View file

@ -87,8 +87,8 @@ properties:
lut-initial:
type: uint8-array
required: true
required: false
lut-default:
type: uint8-array
required: true
required: false