1 /*
2 * Copyright (c) 2023 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT renesas_smartbond_mipi_dbi
8
9 #include <zephyr/drivers/mipi_dbi.h>
10 #include <zephyr/drivers/pinctrl.h>
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/irq.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/device.h>
15 #include <zephyr/pm/device.h>
16 #include <zephyr/pm/policy.h>
17 #include <DA1469xAB.h>
18 #include <zephyr/drivers/clock_control.h>
19 #include <zephyr/drivers/clock_control/smartbond_clock_control.h>
20 #include <zephyr/drivers/display.h>
21 #include <zephyr/sys/util.h>
22 #include <zephyr/drivers/spi.h>
23 #include <da1469x_lcdc.h>
24 #include <da1469x_pd.h>
25
26 #include <zephyr/logging/log.h>
27 LOG_MODULE_REGISTER(smartbond_mipi_dbi, CONFIG_MIPI_DBI_LOG_LEVEL);
28
29 #define SMARTBOND_IRQN DT_INST_IRQN(0)
30 #define SMARTBOND_IRQ_PRIO DT_INST_IRQ(0, priority)
31
32 #define PINCTRL_STATE_READ PINCTRL_STATE_PRIV_START
33
34 #define MIPI_DBI_SMARTBOND_IS_READ_SUPPORTED \
35 DT_INST_NODE_HAS_PROP(0, spi_dev)
36
37 #define LCDC_SMARTBOND_CLK_DIV(_freq) \
38 ((32000000U % (_freq)) ? (96000000U / (_freq)) : (32000000U / (_freq)))
39
40 #define MIPI_DBI_SMARTBOND_IS_PLL_REQUIRED \
41 !!(32000000U % DT_PROP(DT_CHOSEN(zephyr_display), mipi_max_frequency))
42
43 #define MIPI_DBI_SMARTBOND_IS_TE_ENABLED \
44 DT_INST_PROP_OR(0, te_enable, 0)
45
46 #define MIPI_DBI_SMARTBOND_IS_DMA_PREFETCH_ENABLED \
47 DT_INST_ENUM_IDX_OR(0, dma_prefetch, 0)
48
49 #define MIPI_DBI_SMARTBOND_IS_RESET_AVAILABLE \
50 DT_INST_NODE_HAS_PROP(0, reset_gpios)
51
52 #define LCDC_LAYER0_OFFSETX_REG_SET_FIELD(_field, _var, _val) \
53 ((_var)) = \
54 ((_var) & ~(LCDC_LCDC_LAYER0_OFFSETX_REG_ ## _field ## _Msk)) | \
55 (((_var) << LCDC_LCDC_LAYER0_OFFSETX_REG_ ## _field ## _Pos) & \
56 LCDC_LCDC_LAYER0_OFFSETX_REG_ ## _field ## _Msk)
57
58 struct mipi_dbi_smartbond_data {
59 /* Provide mutual exclusion when a display operation is requested. */
60 struct k_sem device_sem;
61 /* Provide synchronization between task return and ISR firing */
62 struct k_sem sync_sem;
63 /* Flag indicating whether or not an underflow took place */
64 volatile bool underflow_flag;
65 /* Layer settings */
66 lcdc_smartbond_layer_cfg layer;
67 };
68
69 struct mipi_dbi_smartbond_config {
70 /* Reference to device instance's pinctrl configurations */
71 const struct pinctrl_dev_config *pcfg;
72 /* Reset GPIO */
73 const struct gpio_dt_spec reset;
74 /* Host controller's timing settings */
75 lcdc_smartbond_timing_cfg timing_cfg;
76 /* Background default color configuration */
77 lcdc_smartbond_bgcolor_cfg bgcolor_cfg;
78 };
79
80 /* Mark the device is progress and so it's not allowed to enter the sleep state. */
mipi_dbi_smartbond_pm_policy_state_lock_get(void)81 static inline void mipi_dbi_smartbond_pm_policy_state_lock_get(void)
82 {
83 /*
84 * Prevent the SoC from etering the normal sleep state as PDC does not support
85 * waking up the application core following LCDC events.
86 */
87 pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
88 }
89
90 /* Mark that device is inactive and so it's allowed to enter the sleep state */
mipi_dbi_smartbond_pm_policy_state_lock_put(void)91 static inline void mipi_dbi_smartbond_pm_policy_state_lock_put(void)
92 {
93 /* Allow the SoC to enter the nornmal sleep state once LCDC is inactive */
94 pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
95 }
96
97 /* Helper function to trigger the LCDC fetching data from frame buffer to the connected display */
mipi_dbi_smartbond_send_single_frame(const struct device * dev)98 static void mipi_dbi_smartbond_send_single_frame(const struct device *dev)
99 {
100 struct mipi_dbi_smartbond_data *data = dev->data;
101
102 #if MIPI_DBI_SMARTBOND_IS_TE_ENABLED
103 da1469x_lcdc_te_set_status(true, DT_INST_PROP_OR(0, te_polarity, false));
104 /*
105 * Wait for the TE signal to be asserted so display's refresh status can be synchronized
106 * with the current frame update.
107 */
108 k_sem_take(&data->sync_sem, K_FOREVER);
109 #endif
110
111 LCDC->LCDC_INTERRUPT_REG |= LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Msk;
112
113 /* Setting this bit will enable the host to start outputing pixel data */
114 LCDC->LCDC_MODE_REG |= LCDC_LCDC_MODE_REG_LCDC_SFRAME_UPD_Msk;
115
116 /* Wait for frame update to complete */
117 k_sem_take(&data->sync_sem, K_FOREVER);
118
119 if (data->underflow_flag) {
120 LOG_WRN("Underflow took place");
121 data->underflow_flag = false;
122 }
123 }
124
125 #if MIPI_DBI_SMARTBOND_IS_RESET_AVAILABLE
mipi_dbi_smartbond_reset(const struct device * dev,k_timeout_t delay)126 static int mipi_dbi_smartbond_reset(const struct device *dev, k_timeout_t delay)
127 {
128 const struct mipi_dbi_smartbond_config *config = dev->config;
129 int ret;
130
131 if (!gpio_is_ready_dt(&config->reset)) {
132 LOG_ERR("Reset signal not available");
133 return -ENODEV;
134 }
135
136 ret = gpio_pin_set_dt(&config->reset, 1);
137 if (ret < 0) {
138 LOG_ERR("Cannot drive reset signal");
139 return ret;
140 }
141 k_sleep(delay);
142
143 return gpio_pin_set_dt(&config->reset, 0);
144 }
145 #endif
146
147 /* Display pixel to output color format translation */
lcdc_smartbond_pixel_to_ocm(enum display_pixel_format pixfmt)148 static inline uint8_t lcdc_smartbond_pixel_to_ocm(enum display_pixel_format pixfmt)
149 {
150 switch (pixfmt) {
151 case PIXEL_FORMAT_RGB_565:
152 return (uint8_t)LCDC_SMARTBOND_OCM_RGB565;
153 case PIXEL_FORMAT_RGB_888:
154 return (uint8_t)LCDC_SMARTBOND_OCM_RGB888;
155 case PIXEL_FORMAT_MONO10:
156 return (uint8_t)LCDC_SMARTBOND_L0_L1;
157 default:
158 LOG_ERR("Unsupported pixel format");
159 return 0;
160 };
161 }
162
lcdc_smartbond_line_mode_translation(uint8_t mode)163 static inline uint8_t lcdc_smartbond_line_mode_translation(uint8_t mode)
164 {
165 switch (mode) {
166 case MIPI_DBI_MODE_SPI_3WIRE:
167 return (uint8_t)LCDC_SMARTBOND_MODE_SPI3;
168 case MIPI_DBI_MODE_SPI_4WIRE:
169 return (uint8_t)LCDC_SMARTBOND_MODE_SPI4;
170 default:
171 LOG_ERR("Unsupported SPI mode");
172 return 0;
173 }
174 }
175
lcdc_smartbond_pixel_to_lcm(enum display_pixel_format pixfmt)176 static inline uint8_t lcdc_smartbond_pixel_to_lcm(enum display_pixel_format pixfmt)
177 {
178 switch (pixfmt) {
179 case PIXEL_FORMAT_RGB_565:
180 return (uint8_t)LCDC_SMARTBOND_L0_RGB565;
181 case PIXEL_FORMAT_ARGB_8888:
182 return (uint8_t)LCDC_SMARTBOND_L0_ARGB8888;
183 default:
184 LOG_ERR("Unsupported pixel format");
185 return 0;
186 };
187 }
188
lcdc_smartbond_mipi_dbi_translation(const struct mipi_dbi_config * dbi_config,lcdc_smartbond_mipi_dbi_cfg * mipi_dbi_cfg,enum display_pixel_format pixfmt)189 static void lcdc_smartbond_mipi_dbi_translation(const struct mipi_dbi_config *dbi_config,
190 lcdc_smartbond_mipi_dbi_cfg *mipi_dbi_cfg,
191 enum display_pixel_format pixfmt)
192 {
193 mipi_dbi_cfg->cpha = dbi_config->config.operation & SPI_MODE_CPHA;
194 mipi_dbi_cfg->cpol = dbi_config->config.operation & SPI_MODE_CPOL;
195 mipi_dbi_cfg->cs_active_high = dbi_config->config.operation & SPI_CS_ACTIVE_HIGH;
196 mipi_dbi_cfg->line_mode = lcdc_smartbond_line_mode_translation(dbi_config->mode);
197 mipi_dbi_cfg->color_mode = lcdc_smartbond_pixel_to_ocm(pixfmt);
198 }
199
200 #if MIPI_DBI_SMARTBOND_IS_READ_SUPPORTED
mipi_dbi_smartbond_command_read(const struct device * dev,const struct mipi_dbi_config * dbi_config,uint8_t * cmd,size_t num_cmds,uint8_t * response,size_t len)201 static int mipi_dbi_smartbond_command_read(const struct device *dev,
202 const struct mipi_dbi_config *dbi_config,
203 uint8_t *cmd, size_t num_cmds,
204 uint8_t *response, size_t len)
205 {
206 struct mipi_dbi_smartbond_data *data = dev->data;
207 const struct mipi_dbi_smartbond_config *config = dev->config;
208 int ret = 0;
209 lcdc_smartbond_mipi_dbi_cfg mipi_dbi_cfg;
210
211 k_sem_take(&data->device_sem, K_FOREVER);
212
213 mipi_dbi_smartbond_pm_policy_state_lock_get();
214
215 /*
216 * Add an arbitrary valid color format to satisfy subroutine. The MIPI DBI command/data
217 * engine should not be affected.
218 */
219 lcdc_smartbond_mipi_dbi_translation(dbi_config, &mipi_dbi_cfg, PIXEL_FORMAT_RGB_565);
220 ret = da1469x_lcdc_mipi_dbi_interface_configure(&mipi_dbi_cfg);
221 if (ret < 0) {
222 goto _mipi_dbi_read_exit;
223 }
224
225 /* Check if the cmd/data engine is busy since the #CS line will be overruled. */
226 if (da1469x_lcdc_is_busy()) {
227 LOG_WRN("MIPI DBI host is busy");
228 ret = -EBUSY;
229 goto _mipi_dbi_read_exit;
230 }
231
232 /* Force CS line to low. Typically, command and data are bound in the same #CS assertion */
233 da1469x_lcdc_force_cs_line(true, mipi_dbi_cfg.cs_active_high);
234
235 da1469x_lcdc_send_cmd_data(true, cmd, num_cmds);
236
237 if (len) {
238 const struct device *spi_dev = DEVICE_DT_GET(DT_INST_PHANDLE(0, spi_dev));
239
240 struct spi_buf buffer = {
241 .buf = (void *)response,
242 .len = len,
243 };
244 struct spi_buf_set buf_set = {
245 .buffers = &buffer,
246 .count = 1,
247 };
248
249 if (!device_is_ready(spi_dev)) {
250 LOG_ERR("SPI device is not ready");
251 ret = -ENODEV;
252 goto _mipi_dbi_read_exit;
253 }
254
255 /* Overwrite CLK and enable DI lines. CS is driven forcefully. */
256 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_READ);
257 if (ret < 0) {
258 LOG_ERR("Could not apply MIPI DBI pins' SPI read state (%d)", ret);
259 goto _mipi_dbi_read_exit;
260 }
261
262 /* Get response */
263 ret = spi_read(spi_dev, &dbi_config->config, &buf_set);
264 if (ret < 0) {
265 LOG_ERR("Could not read data from SPI");
266 goto _mipi_dbi_read_exit;
267 }
268 }
269
270 _mipi_dbi_read_exit:
271
272 /* Restore #CS line */
273 da1469x_lcdc_force_cs_line(false, mipi_dbi_cfg.cs_active_high);
274
275 /* Make sure default LCDC pins are applied upon exit */
276 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
277 if (ret < 0) {
278 LOG_ERR("Could not apply MIPI DBI pins' default state (%d)", ret);
279 }
280
281 mipi_dbi_smartbond_pm_policy_state_lock_put();
282
283 k_sem_give(&data->device_sem);
284
285 return ret;
286 }
287 #endif
288
mipi_dbi_smartbond_command_write(const struct device * dev,const struct mipi_dbi_config * dbi_config,uint8_t cmd,const uint8_t * data_buf,size_t len)289 static int mipi_dbi_smartbond_command_write(const struct device *dev,
290 const struct mipi_dbi_config *dbi_config,
291 uint8_t cmd, const uint8_t *data_buf,
292 size_t len)
293 {
294 struct mipi_dbi_smartbond_data *data = dev->data;
295 int ret = 0;
296 lcdc_smartbond_mipi_dbi_cfg mipi_dbi_cfg;
297
298 k_sem_take(&data->device_sem, K_FOREVER);
299
300 mipi_dbi_smartbond_pm_policy_state_lock_get();
301
302 /*
303 * Add an arbitrary valid color format to satisfy subroutine. The MIPI DBI command/data
304 * engine should not be affected.
305 */
306 lcdc_smartbond_mipi_dbi_translation(dbi_config, &mipi_dbi_cfg, PIXEL_FORMAT_RGB_565);
307 ret = da1469x_lcdc_mipi_dbi_interface_configure(&mipi_dbi_cfg);
308 if (ret < 0) {
309 goto finish;
310 }
311
312 /* Command and accompanied data should be transmitted via the DBIB interface */
313 da1469x_lcdc_send_cmd_data(true, &cmd, 1);
314
315 if (len) {
316 /* Data should be transmitted via the DBIB interface */
317 da1469x_lcdc_send_cmd_data(false, data_buf, len);
318 }
319
320 finish:
321 mipi_dbi_smartbond_pm_policy_state_lock_put();
322
323 k_sem_give(&data->device_sem);
324
325 return ret;
326 }
327
mipi_dbi_smartbond_write_display(const struct device * dev,const struct mipi_dbi_config * dbi_config,const uint8_t * framebuf,struct display_buffer_descriptor * desc,enum display_pixel_format pixfmt)328 static int mipi_dbi_smartbond_write_display(const struct device *dev,
329 const struct mipi_dbi_config *dbi_config,
330 const uint8_t *framebuf,
331 struct display_buffer_descriptor *desc,
332 enum display_pixel_format pixfmt)
333 {
334 struct mipi_dbi_smartbond_data *data = dev->data;
335 const struct mipi_dbi_smartbond_config *config = dev->config;
336 lcdc_smartbond_layer_cfg *layer = &data->layer;
337 int ret = 0;
338 lcdc_smartbond_mipi_dbi_cfg mipi_dbi_cfg;
339 uint8_t layer_color = lcdc_smartbond_pixel_to_lcm(pixfmt);
340
341 if (desc->width * desc->height * (DISPLAY_BITS_PER_PIXEL(pixfmt) / BITS_PER_BYTE) !=
342 desc->buf_size) {
343 LOG_ERR("Incorrect buffer size for given width and height");
344 return -EINVAL;
345 }
346
347 k_sem_take(&data->device_sem, K_FOREVER);
348
349 mipi_dbi_smartbond_pm_policy_state_lock_get();
350
351 /*
352 * Mainly check if the frame generator is busy with a pending frame update (might happen
353 * when two frame updates take place one after the other and the display interface is
354 * quite slow). VSYNC interrupt line should be asserted when the last line is being
355 * outputed.
356 */
357 if (da1469x_lcdc_is_busy()) {
358 LOG_WRN("MIPI DBI host is busy");
359 ret = -EBUSY;
360 goto _mipi_dbi_write_exit;
361 }
362
363 lcdc_smartbond_mipi_dbi_translation(dbi_config, &mipi_dbi_cfg, pixfmt);
364 ret = da1469x_lcdc_mipi_dbi_interface_configure(&mipi_dbi_cfg);
365 if (ret < 0) {
366 goto _mipi_dbi_write_exit;
367 }
368
369 ret = da1469x_lcdc_timings_configure(desc->width, desc->height,
370 (lcdc_smartbond_timing_cfg *)&config->timing_cfg);
371 if (ret < 0) {
372 goto _mipi_dbi_write_exit;
373 }
374
375 LCDC_SMARTBOND_LAYER_CONFIG(layer, framebuf, 0, 0, desc->width, desc->height,
376 layer_color,
377 da1469x_lcdc_stride_calculation(layer_color, desc->width));
378 ret = da1469x_lcdc_layer_configure(layer);
379 if (ret < 0) {
380 goto _mipi_dbi_write_exit;
381 }
382
383 /* Trigger single frame update via the LCDC-DMA engine */
384 mipi_dbi_smartbond_send_single_frame(dev);
385
386 _mipi_dbi_write_exit:
387
388 mipi_dbi_smartbond_pm_policy_state_lock_put();
389
390 k_sem_give(&data->device_sem);
391
392 return ret;
393 }
394
mipi_dbi_smartbond_configure(const struct device * dev)395 static int mipi_dbi_smartbond_configure(const struct device *dev)
396 {
397 uint8_t clk_div =
398 LCDC_SMARTBOND_CLK_DIV(DT_PROP(DT_CHOSEN(zephyr_display), mipi_max_frequency));
399 const struct mipi_dbi_smartbond_config *config = dev->config;
400
401 /*
402 * First enable the controller so registers can be written. In serial interfaces
403 * clock divider is further divided by 2.
404 */
405 da1469x_lcdc_set_status(true, MIPI_DBI_SMARTBOND_IS_PLL_REQUIRED,
406 (clk_div >= 2 ? clk_div / 2 : clk_div));
407
408 if (!da1469x_lcdc_check_id()) {
409 LOG_ERR("Mismatching LCDC ID");
410 da1469x_lcdc_set_status(false, 0, 0);
411 return -EINVAL;
412 }
413
414 da1469x_lcdc_te_set_status(false, DT_INST_PROP_OR(0, te_polarity, false));
415
416 da1469x_lcdc_bgcolor_configure((lcdc_smartbond_bgcolor_cfg *)&config->bgcolor_cfg);
417
418 LCDC_LAYER0_OFFSETX_REG_SET_FIELD(LCDC_L0_DMA_PREFETCH,
419 LCDC->LCDC_LAYER0_OFFSETX_REG, MIPI_DBI_SMARTBOND_IS_DMA_PREFETCH_ENABLED);
420
421 return 0;
422 }
423
smartbond_mipi_dbi_isr(const void * arg)424 static void smartbond_mipi_dbi_isr(const void *arg)
425 {
426 struct mipi_dbi_smartbond_data *data = ((const struct device *)arg)->data;
427
428 /*
429 * Underflow sticky bit will remain high until cleared by writing
430 * any value to LCDC_INTERRUPT_REG.
431 */
432 data->underflow_flag = LCDC_STATUS_REG_GET_FIELD(LCDC_STICKY_UNDERFLOW);
433
434 /* Default interrupt mode is level triggering so interrupt should be cleared */
435 da1469x_lcdc_te_set_status(false, DT_INST_PROP_OR(0, te_polarity, false));
436
437 k_sem_give(&data->sync_sem);
438 }
439
mipi_dbi_smartbond_resume(const struct device * dev)440 static int mipi_dbi_smartbond_resume(const struct device *dev)
441 {
442 const struct mipi_dbi_smartbond_config *config = dev->config;
443 int ret;
444
445 /* Select default state */
446 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
447 if (ret < 0) {
448 LOG_ERR("Could not apply LCDC pins' default state (%d)", ret);
449 return -EIO;
450 }
451
452 #if MIPI_DBI_SMARTBOND_IS_PLL_REQUIRED
453 const struct device *clock_dev = DEVICE_DT_GET(DT_NODELABEL(osc));
454
455 if (!device_is_ready(clock_dev)) {
456 LOG_WRN("Clock device is not available; PLL cannot be used");
457 } else {
458 ret = z_smartbond_select_sys_clk(SMARTBOND_CLK_PLL96M);
459 if (ret < 0) {
460 LOG_WRN("Could not switch to PLL. Requested speed should not be achieved.");
461 }
462 }
463 #endif
464
465 return mipi_dbi_smartbond_configure(dev);
466 }
467
468 #if defined(CONFIG_PM_DEVICE)
mipi_dbi_smartbond_suspend(const struct device * dev)469 static int mipi_dbi_smartbond_suspend(const struct device *dev)
470 {
471 const struct mipi_dbi_smartbond_config *config = dev->config;
472 int ret;
473
474 /* Select sleep state; it's OK if settings fails for any reason. */
475 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
476 if (ret < 0) {
477 LOG_WRN("Could not apply MIPI DBI pins' sleep state");
478 }
479
480 /* Disable host controller to minimize power consumption. */
481 da1469x_lcdc_set_status(false, false, 0);
482
483 return 0;
484 }
485
mipi_dbi_smartbond_pm_action(const struct device * dev,enum pm_device_action action)486 static int mipi_dbi_smartbond_pm_action(const struct device *dev, enum pm_device_action action)
487 {
488 int ret = 0;
489
490 switch (action) {
491 case PM_DEVICE_ACTION_SUSPEND:
492 /* A non-zero value should not affect sleep */
493 (void)mipi_dbi_smartbond_suspend(dev);
494 break;
495 case PM_DEVICE_ACTION_RESUME:
496 /*
497 * The resume error code should not be taken into consideration
498 * by the PM subsystem.
499 */
500 ret = mipi_dbi_smartbond_resume(dev);
501 break;
502 default:
503 return -ENOTSUP;
504 }
505
506 return ret;
507 }
508 #endif
509
mipi_dbi_smartbond_init(const struct device * dev)510 static int mipi_dbi_smartbond_init(const struct device *dev)
511 {
512 __unused const struct mipi_dbi_smartbond_config *config = dev->config;
513 struct mipi_dbi_smartbond_data *data = dev->data;
514 int ret;
515
516 /* Device should be ready to be acquired */
517 k_sem_init(&data->device_sem, 1, 1);
518 /* Event should be signaled by LCDC ISR */
519 k_sem_init(&data->sync_sem, 0, 1);
520
521 #if MIPI_DBI_SMARTBOND_IS_RESET_AVAILABLE
522 if (gpio_is_ready_dt(&config->reset)) {
523 ret = gpio_pin_configure_dt(&config->reset, GPIO_OUTPUT_INACTIVE);
524 if (ret < 0) {
525 LOG_ERR("Could not configure reset line (%d)", ret);
526 return -EIO;
527 }
528 }
529 #endif
530
531 IRQ_CONNECT(SMARTBOND_IRQN, SMARTBOND_IRQ_PRIO, smartbond_mipi_dbi_isr,
532 DEVICE_DT_INST_GET(0), 0);
533
534 ret = mipi_dbi_smartbond_resume(dev);
535
536 return ret;
537 }
538
539 static DEVICE_API(mipi_dbi, mipi_dbi_smartbond_driver_api) = {
540 #if MIPI_DBI_SMARTBOND_IS_RESET_AVAILABLE
541 .reset = mipi_dbi_smartbond_reset,
542 #endif
543 .command_write = mipi_dbi_smartbond_command_write,
544 .write_display = mipi_dbi_smartbond_write_display,
545 #if MIPI_DBI_SMARTBOND_IS_READ_SUPPORTED
546 .command_read = mipi_dbi_smartbond_command_read,
547 #endif
548 };
549
550 #define SMARTBOND_MIPI_DBI_INIT(inst) \
551 PINCTRL_DT_INST_DEFINE(inst); \
552 \
553 static const struct mipi_dbi_smartbond_config mipi_dbi_smartbond_config_## inst = { \
554 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
555 .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}), \
556 .timing_cfg = { 0 }, \
557 .bgcolor_cfg = { 0xFF, 0xFF, 0xFF, 0 }, \
558 }; \
559 \
560 static struct mipi_dbi_smartbond_data mipi_dbi_smartbond_data_## inst; \
561 \
562 PM_DEVICE_DT_INST_DEFINE(inst, mipi_dbi_smartbond_pm_action); \
563 \
564 DEVICE_DT_INST_DEFINE(inst, mipi_dbi_smartbond_init, \
565 PM_DEVICE_DT_INST_GET(inst), \
566 &mipi_dbi_smartbond_data_## inst, \
567 &mipi_dbi_smartbond_config_## inst, \
568 POST_KERNEL, \
569 CONFIG_MIPI_DBI_INIT_PRIORITY, \
570 &mipi_dbi_smartbond_driver_api);
571
572 SMARTBOND_MIPI_DBI_INIT(0);
573