1 /*
2 * Copyright 2024 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_display.h"
9 #include "fsl_rpi.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14 #define RPI_DelayMs VIDEO_DelayMs
15 #define RPI_PWRON_ADDR 0x85U
16 #define RPI_PORTB_ADDR 0x82U
17 #define RPI_PWM_ADDR 0x86U
18 /*******************************************************************************
19 * Variables
20 ******************************************************************************/
21 const display_operations_t rpi_ops = {
22 .init = RPI_Init,
23 .deinit = RPI_Deinit,
24 .start = RPI_Start,
25 .stop = RPI_Stop,
26 };
27
28 static const uint8_t s_rpiCmds[11][6] = {
29 {0x10U, 0x02U, 0x03U, 0x00U, 0x00U, 0x00U}, {0x64U, 0x01U, 0x05U, 0x00U, 0x00U, 0x00U},
30 {0x68U, 0x01U, 0x05U, 0x00U, 0x00U, 0x00U}, {0x44U, 0x01U, 0x00U, 0x00U, 0x00U, 0x00U},
31 {0x48U, 0x01U, 0x00U, 0x00U, 0x00U, 0x00U}, {0x14U, 0x01U, 0x03U, 0x00U, 0x00U, 0x00U},
32 {0x50U, 0x04U, 0x00U, 0x00U, 0x00U, 0x00U}, {0x20U, 0x04U, 0x50U, 0x01U, 0x10U, 0x00U},
33 {0x64U, 0x04U, 0x0fU, 0x04U, 0x00U, 0x00U}, {0x04U, 0x01U, 0x01U, 0x00U, 0x00U, 0x00U},
34 {0x04U, 0x02U, 0x01U, 0x00U, 0x00U, 0x00U}};
35 /*******************************************************************************
36 * Code
37 ******************************************************************************/
38
RPI_Init(display_handle_t * handle,const display_config_t * config)39 status_t RPI_Init(display_handle_t *handle, const display_config_t *config)
40 {
41 status_t status = kStatus_Success;
42 const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
43 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
44 uint8_t regVal = 0U;
45
46 /* Only support one set of resolution. */
47 if (config->resolution != FSL_VIDEO_RESOLUTION(800, 480))
48 {
49 return kStatus_InvalidArgument;
50 }
51
52 /* Reset panel. */
53 if (resource->writeRegister(RPI_PWRON_ADDR, 0x0U) != kStatus_Success)
54 {
55 return kStatus_Fail;
56 }
57 VIDEO_DelayMs(400);
58 if (resource->writeRegister(RPI_PWRON_ADDR, 0x1U) != kStatus_Success)
59 {
60 return kStatus_Fail;
61 }
62 VIDEO_DelayMs(400);
63
64 /* Wait for power on done. */
65 while ((regVal & 0x1U) == 0U)
66 {
67 if (resource->readStatus(RPI_PORTB_ADDR, ®Val) != kStatus_Success)
68 {
69 return kStatus_Fail;
70 }
71 }
72
73 /* Set backlight. */
74 if (resource->writeRegister(RPI_PWM_ADDR, 0x80U) != kStatus_Success)
75 {
76 return kStatus_Fail;
77 }
78
79 for (uint8_t i = 0; i < ARRAY_SIZE(s_rpiCmds); i++)
80 {
81 status = MIPI_DSI_GenericWrite(dsiDevice, s_rpiCmds[i], 6);
82
83 if (kStatus_Success != status)
84 {
85 break;
86 }
87
88 if ((i == 8U) || (i == 10U))
89 {
90 RPI_DelayMs(100);
91 }
92 }
93
94 return status;
95 }
96
RPI_Deinit(display_handle_t * handle)97 status_t RPI_Deinit(display_handle_t *handle)
98 {
99 const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
100 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
101
102 (void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
103
104 return kStatus_Success;
105 }
106
RPI_Start(display_handle_t * handle)107 status_t RPI_Start(display_handle_t *handle)
108 {
109 const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
110 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
111
112 return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
113 }
114
RPI_Stop(display_handle_t * handle)115 status_t RPI_Stop(display_handle_t *handle)
116 {
117 const rpi_resource_t *resource = (const rpi_resource_t *)(handle->resource);
118 mipi_dsi_device_t *dsiDevice = resource->dsiDevice;
119
120 return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
121 }
122