@@ -45,20 +45,20 @@ struct co5300_data {
4545 struct k_sem tear_effect_sem ;
4646};
4747
48- /* Organized in MIPI_CMD | SIZE OF MIPI PARAM | MIPI PARAM */
49- uint8_t lcm_init_cmds [] = { 0xFE , 0x1 , 0x20 ,
50- 0xF4 , 0x1 , 0x5A ,
51- 0xF5 , 0x1 , 0x59 ,
52- 0xFE , 0x1 , 0x40 ,
53- 0x96 , 0x1 , 0x00 ,
54- 0xC9 , 0x1 , 0x00 ,
55- 0xFE , 0x1 , 0x00 ,
56- 0x35 , 0x1 , 0x00 ,
57- 0x53 , 0x1 , 0x20 ,
58- 0x51 , 0x1 , 0xFF ,
59- 0x63 , 0x1 , 0xFF ,
60- 0x2A , 0x4 , 0x00 , 0x06 , 0x01 , 0xD7 ,
61- 0x2B , 0x4 , 0x00 , 0x00 , 0x01 , 0xD1 };
48+ /* Organized as MIPI_CMD | SIZE OF MIPI PARAM | MIPI PARAM */
49+ uint8_t lcm_init_cmds [] = { 0xFE , 0x1 , 0x20 ,
50+ 0xF4 , 0x1 , 0x5A ,
51+ 0xF5 , 0x1 , 0x59 ,
52+ 0xFE , 0x1 , 0x40 ,
53+ 0x96 , 0x1 , 0x00 ,
54+ 0xC9 , 0x1 , 0x00 ,
55+ 0xFE , 0x1 , 0x00 ,
56+ 0x35 , 0x1 , 0x00 ,
57+ 0x53 , 0x1 , 0x20 ,
58+ 0x51 , 0x1 , 0xFF ,
59+ 0x63 , 0x1 , 0xFF ,
60+ 0x2A , 0x4 , 0x00 , 0x06 , 0x01 , 0xD7 ,
61+ 0x2B , 0x4 , 0x00 , 0x00 , 0x01 , 0xD1 };
6262
6363static void co5300_tear_effect_isr_handler (const struct device * gpio_dev ,
6464 struct gpio_callback * cb , uint32_t pins )
@@ -91,7 +91,8 @@ static int co5300_blanking_off(const struct device *dev)
9191 }
9292}
9393
94- /* Helper to write framebuffer data to co5300 via MIPI interface. */
94+ #if 0
95+ /* Helper function to write framebuffer data to co5300 via MIPI interface. */
9596static int co5300_write_fb (const struct device * dev , bool first_write ,
9697 const uint8_t * src , const struct display_buffer_descriptor * desc )
9798{
@@ -136,9 +137,126 @@ static int co5300_write_fb(const struct device *dev, bool first_write,
136137 }
137138 return wlen ;
138139}
140+ #else
141+ /* Helper function to write framebuffer data to co5300 via MIPI interface. */
142+ static int co5300_write_fb (const struct device * dev , bool first_write ,
143+ const uint8_t * src , const struct display_buffer_descriptor * desc )
144+ {
145+ const struct co5300_config * config = dev -> config ;
146+ struct co5300_data * data = dev -> data ;
147+ ssize_t wlen ;
148+ struct mipi_dsi_msg msg = {0 };
149+ uint8_t * local_src = (uint8_t * )src ;
150+ uint32_t len = desc -> height * desc -> width * data -> bytes_per_pixel ;
151+ uint32_t len_sent = 0U ;
152+
153+ /* Note- we need to set custom flags on the DCS message,
154+ * so we bypass the mipi_dsi_dcs_write API
155+ */
156+ if (first_write ) {
157+ msg .cmd = MIPI_DCS_WRITE_MEMORY_START ;
158+ } else {
159+ msg .cmd = MIPI_DCS_WRITE_MEMORY_CONTINUE ;
160+ }
161+ msg .type = MIPI_DSI_DCS_LONG_WRITE ;
162+ msg .flags = MCUX_DSI_2L_FB_DATA ;
163+ msg .user_data = (void * )desc ;
164+
165+ while (len > 0 ) {
166+ msg .tx_len = len ;
167+ msg .tx_buf = local_src ;
168+ wlen = mipi_dsi_transfer (config -> mipi_dsi , config -> channel , & msg );
169+ if (wlen < 0 ) {
170+ return (int )wlen ;
171+ }
172+ /* Advance source pointer and decrement remaining */
173+ if (desc -> pitch > desc -> width ) {
174+ len_sent += wlen ;
175+ local_src += wlen + len_sent / (desc -> width * data -> bytes_per_pixel ) *
176+ ((desc -> pitch - desc -> width ) * data -> bytes_per_pixel );
177+ } else {
178+ local_src += wlen ;
179+ }
180+ len -= wlen ;
181+ /* All future commands should use WRITE_MEMORY_CONTINUE */
182+ msg .cmd = MIPI_DCS_WRITE_MEMORY_CONTINUE ;
183+ }
184+ return wlen ;
185+ }
186+ #endif
187+
188+
189+
190+ #if 0
191+ static int co5300_write (const struct device * dev ,
192+ const uint16_t x , const uint16_t y ,
193+ const struct display_buffer_descriptor * desc ,
194+ const void * buf )
195+ {
196+ const struct co5300_config * config = dev -> config ;
197+ struct co5300_data * data = dev -> data ;
198+ int ret ;
199+ uint16_t start , end ;
200+ const uint8_t * src ;
201+ bool first_cmd ;
202+ uint8_t param [4 ];
203+
204+ LOG_DBG ("W=%d, H=%d @%d,%d" , desc -> width , desc -> height , x , y );
205+
206+ /*
207+ * CO5300 runs in MIPI DBI mode. This means we can use command mode
208+ * to write to the video memory buffer on the CO5300 control IC,
209+ * and the IC will update the display automatically.
210+ */
211+
212+ /* Set column address of target area */
213+ /* First two bytes are starting X coordinate */
214+ start = x ;
215+ end = x + desc -> width - 1 ;
216+ sys_put_be16 (start , & param [0 ]);
217+ /* Second two bytes are ending X coordinate */
218+ sys_put_be16 (end , & param [2 ]);
219+ ret = mipi_dsi_dcs_write (config -> mipi_dsi , config -> channel ,
220+ MIPI_DCS_SET_COLUMN_ADDRESS , param ,
221+ sizeof (param ));
222+ if (ret < 0 ) {
223+ return ret ;
224+ }
225+
226+ /* Set page address of target area */
227+ /* First two bytes are starting Y coordinate */
228+ start = y ;
229+ end = y + desc -> height - 1 ;
230+ sys_put_be16 (start , & param [0 ]);
231+ /* Second two bytes are ending X coordinate */
232+ sys_put_be16 (end , & param [2 ]);
233+ ret = mipi_dsi_dcs_write (config -> mipi_dsi , config -> channel ,
234+ MIPI_DCS_SET_PAGE_ADDRESS , param ,
235+ sizeof (param ));
236+ if (ret < 0 ) {
237+ return ret ;
238+ }
139239
240+ /*
241+ * Now, write the framebuffer. If the tearing effect GPIO is present,
242+ * wait until the display controller issues an interrupt (which will
243+ * give to the TE semaphore) before sending the frame
244+ */
245+ if (config -> tear_effect_gpio .port != NULL ) {
246+ /* Block sleep state until next TE interrupt so we can send
247+ * frame during that interval
248+ */
249+ k_sem_take (& data -> tear_effect_sem , K_FOREVER );
250+ }
251+ src = buf ;
252+ first_cmd = true;
140253
254+ co5300_write_fb (dev , first_cmd , src , desc );
141255
256+ return 0 ;
257+
258+ }
259+ #else
142260static int co5300_write (const struct device * dev ,
143261 const uint16_t x , const uint16_t y ,
144262 const struct display_buffer_descriptor * desc ,
@@ -207,6 +325,7 @@ static int co5300_write(const struct device *dev,
207325 return 0 ;
208326
209327}
328+ #endif
210329
211330static int co5300_read (const struct device * dev ,
212331 const uint16_t x , const uint16_t y ,
@@ -235,6 +354,7 @@ static int co5300_set_contrast(const struct device *dev, uint8_t contrast)
235354 return 0 ;
236355}
237356
357+ #if 0
238358static void co5300_get_capabilities (const struct device * dev ,
239359 struct display_capabilities * capabilities )
240360{
@@ -261,7 +381,36 @@ static void co5300_get_capabilities(const struct device *dev,
261381 }
262382 capabilities -> current_orientation = DISPLAY_ORIENTATION_ROTATED_90 ;
263383}
384+ #else
385+ static void co5300_get_capabilities (const struct device * dev ,
386+ struct display_capabilities * capabilities )
387+ {
388+ const struct co5300_config * config = dev -> config ;
389+ const struct co5300_data * data = dev -> data ;
390+
391+ memset (capabilities , 0 , sizeof (struct display_capabilities ));
392+ capabilities -> x_resolution = config -> panel_width ;
393+ capabilities -> y_resolution = config -> panel_height ;
394+ capabilities -> supported_pixel_formats = PIXEL_FORMAT_RGB_565 |
395+ PIXEL_FORMAT_RGB_888 ;
264396
397+ switch (data -> pixel_format ) {
398+ case MIPI_DSI_PIXFMT_RGB565 :
399+ capabilities -> current_pixel_format = PIXEL_FORMAT_RGB_565 ;
400+ break ;
401+ case MIPI_DSI_PIXFMT_RGB888 :
402+ capabilities -> current_pixel_format = PIXEL_FORMAT_RGB_888 ;
403+ break ;
404+ default :
405+ LOG_WRN ("Unsupported display format" );
406+ /* Other display formats not implemented */
407+ break ;
408+ }
409+ capabilities -> current_orientation = DISPLAY_ORIENTATION_ROTATED_90 ;
410+ }
411+ #endif
412+
413+ #if 0
265414static int co5300_set_pixel_format (const struct device * dev ,
266415 const enum display_pixel_format pixel_format )
267416{
@@ -291,7 +440,49 @@ static int co5300_set_pixel_format(const struct device *dev,
291440 return 0 ;
292441
293442}
443+ #else
444+ static int co5300_set_pixel_format (const struct device * dev ,
445+ const enum display_pixel_format pixel_format )
446+ {
447+ const struct co5300_config * config = dev -> config ;
448+ struct co5300_data * data = dev -> data ;
449+ uint8_t param ;
450+
451+ switch (data -> pixel_format ) {
452+ case PIXEL_FORMAT_RGB_565 :
453+ data -> pixel_format = MIPI_DSI_PIXFMT_RGB565 ;
454+ param = MIPI_DCS_PIXEL_FORMAT_16BIT ;
455+ data -> bytes_per_pixel = 2 ;
456+ break ;
457+ case PIXEL_FORMAT_RGB_888 :
458+ data -> pixel_format = MIPI_DSI_PIXFMT_RGB888 ;
459+ param = MIPI_DCS_PIXEL_FORMAT_24BIT ;
460+ data -> bytes_per_pixel = 3 ;
461+ break ;
462+ default :
463+ /* Other display formats not implemented */
464+ return - ENOTSUP ;
465+ }
294466
467+ return mipi_dsi_dcs_write (config -> mipi_dsi , config -> channel ,
468+ MIPI_DCS_SET_PIXEL_FORMAT , & param , 1 );
469+
470+ return 0 ;
471+
472+ }
473+ #endif
474+
475+ #if 0
476+ static int co5300_set_orientation (const struct device * dev ,
477+ const enum display_orientation orientation )
478+ {
479+ if (orientation == DISPLAY_ORIENTATION_NORMAL ) {
480+ return 0 ;
481+ }
482+ LOG_ERR ("Changing display orientation not implemented" );
483+ return - ENOTSUP ;
484+ }
485+ #else
295486static int co5300_set_orientation (const struct device * dev ,
296487 const enum display_orientation orientation )
297488{
@@ -301,6 +492,7 @@ static int co5300_set_orientation(const struct device *dev,
301492 LOG_ERR ("Changing display orientation not implemented" );
302493 return - ENOTSUP ;
303494}
495+ #endif
304496
305497static int co5300_init (const struct device * dev )
306498{
@@ -401,20 +593,16 @@ static int co5300_init(const struct device *dev)
401593 return ret ;
402594 }
403595
404- /* Delay 50 ms before exiting sleep mode */
596+ /* Command the display to enter sleep mode */
405597 k_sleep (K_MSEC (50 ));
406-
407598 ret = mipi_dsi_dcs_write (config -> mipi_dsi , config -> channel ,
408599 MIPI_DCS_EXIT_SLEEP_MODE , NULL , 0 );
409-
410600 if (ret < 0 ) {
411601 return ret ;
412602 }
413- /*
414- * We must wait 5 ms after exiting sleep mode before sending additional
415- * commands. If we intend to enter sleep mode, we must delay
416- * 120 ms before sending that command. To be safe, delay 150ms
417- */
603+
604+
605+ /* Commands after the monitor is directed to go to sleep should be delayed 150ms */
418606 k_sleep (K_MSEC (150 ));
419607
420608 /* Setup backlight */
@@ -426,8 +614,8 @@ static int co5300_init(const struct device *dev)
426614 }
427615 }
428616
617+ /* Setup tear effect pin */
429618 if (config -> tear_effect_gpio .port != NULL ) {
430- /* Setup tear effect pin */
431619 ret = gpio_pin_configure_dt (& config -> tear_effect_gpio , GPIO_INPUT );
432620 if (ret < 0 ) {
433621 LOG_ERR ("Could not configure TE GPIO (%d)" , ret );
@@ -450,7 +638,7 @@ static int co5300_init(const struct device *dev)
450638 return ret ;
451639 }
452640
453- /* Setup tear effect pin semaphore */
641+ /* Setup semaphore for using the tear effect pin */
454642 k_sem_init (& data -> tear_effect_sem , 0 , 1 );
455643 }
456644
0 commit comments