Skip to content

Commit d4f9cd1

Browse files
committed
drivers: ssd16xx: Remove SCREEN_INFO_DOUBLE_BUFFER cap
The SSD16xx driver used to use the SCREEN_INFO_DOUBLE_BUFFER flag to indicate to the LVGL integration that it needs writes to be performed twice. This was required because partial writes require both the old and new buffer to be written. This behavior is really an implementation detail and only applies to partial refresh. Do this buffer maintenance in the driver instead. Signed-off-by: Andreas Sandberg <[email protected]>
1 parent 4443510 commit d4f9cd1

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

drivers/display/ssd16xx.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static int ssd16xx_set_window(const struct device *dev,
361361
const struct display_buffer_descriptor *desc)
362362
{
363363
const struct ssd16xx_config *config = dev->config;
364-
struct ssd16xx_data *data = dev->data;
364+
const struct ssd16xx_data *data = dev->data;
365365
int err;
366366
uint16_t x_start;
367367
uint16_t x_end;
@@ -445,7 +445,11 @@ static int ssd16xx_write(const struct device *dev, const uint16_t x,
445445
const struct display_buffer_descriptor *desc,
446446
const void *buf)
447447
{
448+
const struct ssd16xx_config *config = dev->config;
448449
const struct ssd16xx_data *data = dev->data;
450+
const bool have_partial_refresh =
451+
config->profiles[SSD16XX_PROFILE_PARTIAL] != NULL;
452+
const bool partial_refresh = !data->blanking_on && have_partial_refresh;
449453
const size_t buf_len = MIN(desc->buf_size,
450454
desc->height * desc->width / 8);
451455
int err;
@@ -455,15 +459,13 @@ static int ssd16xx_write(const struct device *dev, const uint16_t x,
455459
return -EINVAL;
456460
}
457461

458-
if (!data->blanking_on) {
462+
if (partial_refresh) {
459463
/*
460-
* Blanking isn't on, so this is a partial
461-
* refresh. Request the partial profile. This
462-
* operation becomes a no-op if the profile is already
463-
* active.
464+
* Request the partial profile. This operation becomes
465+
* a no-op if the profile is already active.
464466
*/
465467
err = ssd16xx_set_profile(dev, SSD16XX_PROFILE_PARTIAL);
466-
if (err < 0 && err != -ENOENT) {
468+
if (err < 0) {
467469
return -EIO;
468470
}
469471
}
@@ -486,6 +488,35 @@ static int ssd16xx_write(const struct device *dev, const uint16_t x,
486488
}
487489
}
488490

491+
if (data->blanking_on && have_partial_refresh) {
492+
/*
493+
* We will trigger a full refresh when blanking is
494+
* turned off. The controller won't keep track of the
495+
* old frame buffer, which is needed to perform a
496+
* partial update, when this happens. Maintain the old
497+
* frame buffer manually here to make sure future
498+
* partial updates will work as expected.
499+
*/
500+
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_WRITE_RED_RAM,
501+
(uint8_t *)buf, buf_len);
502+
if (err < 0) {
503+
return err;
504+
}
505+
} else if (partial_refresh) {
506+
/*
507+
* We just performed a partial refresh. After the
508+
* refresh, the controller swaps the black/red buffers
509+
* containing the current and new image. We need to
510+
* perform a second write here to ensure that future
511+
* updates work on an up-to-date framebuffer.
512+
*/
513+
err = ssd16xx_write_cmd(dev, SSD16XX_CMD_WRITE_RAM,
514+
(uint8_t *)buf, buf_len);
515+
if (err < 0) {
516+
return err;
517+
}
518+
}
519+
489520
return 0;
490521
}
491522

@@ -582,8 +613,7 @@ static void ssd16xx_get_capabilities(const struct device *dev,
582613
caps->current_pixel_format = PIXEL_FORMAT_MONO10;
583614
caps->screen_info = SCREEN_INFO_MONO_VTILED |
584615
SCREEN_INFO_MONO_MSB_FIRST |
585-
SCREEN_INFO_EPD |
586-
SCREEN_INFO_DOUBLE_BUFFER;
616+
SCREEN_INFO_EPD;
587617
}
588618

589619
static int ssd16xx_set_orientation(const struct device *dev,

0 commit comments

Comments
 (0)