@@ -66,6 +66,7 @@ struct ssd16xx_data {
6666 uint8_t scan_mode ;
6767 bool blanking_on ;
6868 enum ssd16xx_profile_type profile ;
69+ enum display_orientation orientation ;
6970};
7071
7172struct ssd16xx_dt_array {
@@ -100,7 +101,7 @@ struct ssd16xx_config {
100101
101102 const struct ssd16xx_profile * profiles [SSD16XX_NUM_PROFILES ];
102103
103- bool orientation ;
104+ uint16_t rotation ;
104105 uint16_t height ;
105106 uint16_t width ;
106107 uint8_t tssv ;
@@ -380,42 +381,73 @@ static int ssd16xx_set_window(const struct device *dev,
380381 return - ENOTSUP ;
381382 }
382383
383- if ((y + desc -> height ) > panel_h ) {
384- LOG_ERR ("Buffer out of bounds (height)" );
385- return - EINVAL ;
386- }
384+ if (data -> orientation == DISPLAY_ORIENTATION_NORMAL ||
385+ data -> orientation == DISPLAY_ORIENTATION_ROTATED_180 ) {
386+ if ((y + desc -> height ) > panel_h ) {
387+ LOG_ERR ("Buffer out of bounds (height)" );
388+ return - EINVAL ;
389+ }
387390
388- if ((x + desc -> width ) > config -> width ) {
389- LOG_ERR ("Buffer out of bounds (width)" );
390- return - EINVAL ;
391- }
391+ if ((x + desc -> width ) > config -> width ) {
392+ LOG_ERR ("Buffer out of bounds (width)" );
393+ return - EINVAL ;
394+ }
392395
393- if ((desc -> height % EPD_PANEL_NUMOF_ROWS_PER_PAGE ) != 0U ) {
394- LOG_ERR ("Buffer height not multiple of %d" ,
395- EPD_PANEL_NUMOF_ROWS_PER_PAGE );
396- return - EINVAL ;
397- }
396+ if ((desc -> height % EPD_PANEL_NUMOF_ROWS_PER_PAGE ) != 0U ) {
397+ LOG_ERR ("Buffer height not multiple of %d" , EPD_PANEL_NUMOF_ROWS_PER_PAGE );
398+ return - EINVAL ;
399+ }
398400
399- if ((y % EPD_PANEL_NUMOF_ROWS_PER_PAGE ) != 0U ) {
400- LOG_ERR ("Y coordinate not multiple of %d" ,
401- EPD_PANEL_NUMOF_ROWS_PER_PAGE );
402- return - EINVAL ;
401+ if ((y % EPD_PANEL_NUMOF_ROWS_PER_PAGE ) != 0U ) {
402+ LOG_ERR ("Y coordinate not multiple of %d" , EPD_PANEL_NUMOF_ROWS_PER_PAGE );
403+ return - EINVAL ;
404+ }
405+ } else {
406+ if ((y + desc -> height ) > config -> width ) {
407+ LOG_ERR ("Buffer out of bounds (height)" );
408+ return - EINVAL ;
409+ }
410+
411+ if ((x + desc -> width ) > panel_h ) {
412+ LOG_ERR ("Buffer out of bounds (width)" );
413+ return - EINVAL ;
414+ }
415+
416+ if ((desc -> width % SSD16XX_PIXELS_PER_BYTE ) != 0U ) {
417+ LOG_ERR ("Buffer width not multiple of %d" , SSD16XX_PIXELS_PER_BYTE );
418+ return - EINVAL ;
419+ }
420+
421+ if ((x % SSD16XX_PIXELS_PER_BYTE ) != 0U ) {
422+ LOG_ERR ("X coordinate not multiple of %d" , SSD16XX_PIXELS_PER_BYTE );
423+ return - EINVAL ;
424+ }
403425 }
404426
405- switch (data -> scan_mode ) {
406- case SSD16XX_DATA_ENTRY_XIYDY :
427+ switch (data -> orientation ) {
428+ case DISPLAY_ORIENTATION_NORMAL :
429+ x_start = (panel_h - 1 - y ) / SSD16XX_PIXELS_PER_BYTE ;
430+ x_end = (panel_h - 1 - (y + desc -> height - 1 )) / SSD16XX_PIXELS_PER_BYTE ;
431+ y_start = x ;
432+ y_end = (x + desc -> width - 1 );
433+ break ;
434+ case DISPLAY_ORIENTATION_ROTATED_90 :
435+ x_start = (panel_h - 1 - x ) / SSD16XX_PIXELS_PER_BYTE ;
436+ x_end = (panel_h - 1 - (x + desc -> width - 1 )) / SSD16XX_PIXELS_PER_BYTE ;
437+ y_start = (config -> width - 1 - y );
438+ y_end = (config -> width - 1 - (y + desc -> height - 1 ));
439+ break ;
440+ case DISPLAY_ORIENTATION_ROTATED_180 :
407441 x_start = y / SSD16XX_PIXELS_PER_BYTE ;
408442 x_end = (y + desc -> height - 1 ) / SSD16XX_PIXELS_PER_BYTE ;
409443 y_start = (x + desc -> width - 1 );
410444 y_end = x ;
411445 break ;
412-
413- case SSD16XX_DATA_ENTRY_XDYIY :
414- x_start = (panel_h - 1 - y ) / SSD16XX_PIXELS_PER_BYTE ;
415- x_end = (panel_h - 1 - (y + desc -> height - 1 )) /
416- SSD16XX_PIXELS_PER_BYTE ;
417- y_start = x ;
418- y_end = (x + desc -> width - 1 );
446+ case DISPLAY_ORIENTATION_ROTATED_270 :
447+ x_start = x / SSD16XX_PIXELS_PER_BYTE ;
448+ x_end = (x + desc -> width - 1 ) / SSD16XX_PIXELS_PER_BYTE ;
449+ y_start = y ;
450+ y_end = (y + desc -> height - 1 );
419451 break ;
420452 default :
421453 return - EINVAL ;
@@ -585,16 +617,22 @@ static void ssd16xx_get_capabilities(const struct device *dev,
585617 struct display_capabilities * caps )
586618{
587619 const struct ssd16xx_config * config = dev -> config ;
620+ struct ssd16xx_data * data = dev -> data ;
588621
589622 memset (caps , 0 , sizeof (struct display_capabilities ));
590623 caps -> x_resolution = config -> width ;
591624 caps -> y_resolution = config -> height -
592625 config -> height % EPD_PANEL_NUMOF_ROWS_PER_PAGE ;
593626 caps -> supported_pixel_formats = PIXEL_FORMAT_MONO10 ;
594627 caps -> current_pixel_format = PIXEL_FORMAT_MONO10 ;
595- caps -> screen_info = SCREEN_INFO_MONO_VTILED |
596- SCREEN_INFO_MONO_MSB_FIRST |
597- SCREEN_INFO_EPD ;
628+ caps -> screen_info = SCREEN_INFO_MONO_MSB_FIRST | SCREEN_INFO_EPD ;
629+
630+ if (data -> orientation == DISPLAY_ORIENTATION_NORMAL ||
631+ data -> orientation == DISPLAY_ORIENTATION_ROTATED_180 ) {
632+ caps -> screen_info |= SCREEN_INFO_MONO_VTILED ;
633+ }
634+
635+ caps -> current_orientation = data -> orientation ;
598636}
599637
600638static int ssd16xx_set_pixel_format (const struct device * dev ,
@@ -608,6 +646,32 @@ static int ssd16xx_set_pixel_format(const struct device *dev,
608646 return - ENOTSUP ;
609647}
610648
649+ static int ssd16xx_set_orientation (const struct device * dev ,
650+ const enum display_orientation orientation )
651+ {
652+ struct ssd16xx_data * data = dev -> data ;
653+ int err ;
654+
655+ if (orientation == DISPLAY_ORIENTATION_NORMAL ) {
656+ data -> scan_mode = SSD16XX_DATA_ENTRY_XDYIY ;
657+ } else if (orientation == DISPLAY_ORIENTATION_ROTATED_90 ) {
658+ data -> scan_mode = SSD16XX_DATA_ENTRY_XDYDX ;
659+ } else if (orientation == DISPLAY_ORIENTATION_ROTATED_180 ) {
660+ data -> scan_mode = SSD16XX_DATA_ENTRY_XIYDY ;
661+ } else if (orientation == DISPLAY_ORIENTATION_ROTATED_270 ) {
662+ data -> scan_mode = SSD16XX_DATA_ENTRY_XIYIX ;
663+ }
664+
665+ err = ssd16xx_write_uint8 (dev , SSD16XX_CMD_ENTRY_MODE , data -> scan_mode );
666+ if (err < 0 ) {
667+ return err ;
668+ }
669+
670+ data -> orientation = orientation ;
671+
672+ return 0 ;
673+ }
674+
611675static int ssd16xx_clear_cntlr_mem (const struct device * dev , uint8_t ram_cmd )
612676{
613677 const struct ssd16xx_config * config = dev -> config ;
@@ -840,6 +904,7 @@ static int ssd16xx_controller_init(const struct device *dev)
840904{
841905 const struct ssd16xx_config * config = dev -> config ;
842906 struct ssd16xx_data * data = dev -> data ;
907+ enum display_orientation orientation ;
843908 int err ;
844909
845910 LOG_DBG ("" );
@@ -860,12 +925,6 @@ static int ssd16xx_controller_init(const struct device *dev)
860925
861926 k_msleep (SSD16XX_RESET_DELAY );
862927
863- if (config -> orientation == 1 ) {
864- data -> scan_mode = SSD16XX_DATA_ENTRY_XIYDY ;
865- } else {
866- data -> scan_mode = SSD16XX_DATA_ENTRY_XDYIY ;
867- }
868-
869928 err = ssd16xx_set_profile (dev , SSD16XX_PROFILE_FULL );
870929 if (err < 0 ) {
871930 return err ;
@@ -881,6 +940,21 @@ static int ssd16xx_controller_init(const struct device *dev)
881940 return err ;
882941 }
883942
943+ if (config -> rotation == 0U ) {
944+ orientation = DISPLAY_ORIENTATION_NORMAL ;
945+ } else if (config -> rotation == 90U ) {
946+ orientation = DISPLAY_ORIENTATION_ROTATED_90 ;
947+ } else if (config -> rotation == 180U ) {
948+ orientation = DISPLAY_ORIENTATION_ROTATED_180 ;
949+ } else {
950+ orientation = DISPLAY_ORIENTATION_ROTATED_270 ;
951+ }
952+
953+ err = ssd16xx_set_orientation (dev , orientation );
954+ if (err < 0 ) {
955+ return err ;
956+ }
957+
884958 err = ssd16xx_update_display (dev );
885959 if (err < 0 ) {
886960 return err ;
@@ -954,6 +1028,7 @@ static struct display_driver_api ssd16xx_driver_api = {
9541028 .read = ssd16xx_read ,
9551029 .get_capabilities = ssd16xx_get_capabilities ,
9561030 .set_pixel_format = ssd16xx_set_pixel_format ,
1031+ .set_orientation = ssd16xx_set_orientation ,
9571032};
9581033
9591034#if DT_HAS_COMPAT_STATUS_OKAY (solomon_ssd1608 )
@@ -1070,7 +1145,7 @@ static struct ssd16xx_quirks quirks_solomon_ssd1681 = {
10701145 .quirks = quirks_ptr, \
10711146 .height = DT_PROP(n, height), \
10721147 .width = DT_PROP(n, width), \
1073- .orientation = DT_PROP(n, orientation_flipped), \
1148+ .rotation = DT_PROP(n, rotation), \
10741149 .tssv = DT_PROP_OR(n, tssv, 0), \
10751150 .softstart = SSD16XX_ASSIGN_ARRAY(n, softstart), \
10761151 .profiles = { \
0 commit comments