1 /*
2  * Copyright 2019-2020 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_display.h"
10 #include "fsl_rm68191.h"
11 
12 /*******************************************************************************
13  * Definitions
14  ******************************************************************************/
15 #define RM68191_DelayMs VIDEO_DelayMs
16 
17 typedef struct _rm68191_setting
18 {
19     const uint8_t *value;
20     uint8_t len;
21 } rm68191_setting_t;
22 
23 #define RM68191_MAKE_SETTING_ITEM(setting)  \
24     {                                       \
25         (setting), (uint8_t)sizeof(setting) \
26     }
27 
28 /*******************************************************************************
29  * Variables
30  ******************************************************************************/
31 static const uint8_t s_rm68191Cmd0[]  = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x03};
32 static const uint8_t s_rm68191Cmd1[]  = {0x90, 0x05, 0x16, 0x09, 0x03, 0xCD, 0x00, 0x00, 0x00, 0x00};
33 static const uint8_t s_rm68191Cmd2[]  = {0x91, 0x05, 0x16, 0x0B, 0x03, 0xCF, 0x00, 0x00, 0x00, 0x00};
34 static const uint8_t s_rm68191Cmd3[]  = {0x92, 0x40, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x8F, 0x00, 0x00, 0x04, 0x08};
35 static const uint8_t s_rm68191Cmd4[]  = {0x94, 0x00, 0x08, 0x0C, 0x03, 0xD1, 0x03, 0xD2, 0x0C};
36 static const uint8_t s_rm68191Cmd5[]  = {0x95, 0x40, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13,
37                                         0x00, 0x8F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08};
38 static const uint8_t s_rm68191Cmd6[]  = {0x99, 0x00, 0x00};
39 static const uint8_t s_rm68191Cmd7[]  = {0x9A, 0x80, 0x10, 0x03, 0xD5, 0x03, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x50};
40 static const uint8_t s_rm68191Cmd8[]  = {0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
41 static const uint8_t s_rm68191Cmd9[]  = {0x9C, 0x00, 0x00};
42 static const uint8_t s_rm68191Cmd10[] = {0x9D, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00};
43 static const uint8_t s_rm68191Cmd11[] = {0x9E, 0x00, 0x00};
44 static const uint8_t s_rm68191Cmd12[] = {0xA0, 0x84, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x08, 0x1F, 0x0A, 0x1F};
45 static const uint8_t s_rm68191Cmd13[] = {0xA1, 0x1F, 0x1F, 0x1F, 0x1F, 0x0C, 0x1F, 0x0E, 0x1F, 0x1F, 0x1F};
46 static const uint8_t s_rm68191Cmd14[] = {0xA2, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x02, 0x1F, 0x06, 0x1F};
47 static const uint8_t s_rm68191Cmd15[] = {0xA3, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
48 static const uint8_t s_rm68191Cmd16[] = {0xA4, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x07, 0x1F, 0x03, 0x1F, 0x0F};
49 static const uint8_t s_rm68191Cmd17[] = {0xA5, 0x1F, 0x0D, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0B, 0x1F, 0x09};
50 static const uint8_t s_rm68191Cmd18[] = {0xA6, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x01, 0x05};
51 static const uint8_t s_rm68191Cmd19[] = {0xA7, 0x03, 0x07, 0x1F, 0x1F, 0x1F, 0x1F, 0x0B, 0x1F, 0x09, 0x1F};
52 static const uint8_t s_rm68191Cmd20[] = {0xA8, 0x1F, 0x1F, 0x1F, 0x1F, 0x0F, 0x1F, 0x0D, 0x1F, 0x1F, 0x1F};
53 static const uint8_t s_rm68191Cmd21[] = {0xA9, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x1F, 0x01, 0x1F};
54 static const uint8_t s_rm68191Cmd22[] = {0xAA, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
55 static const uint8_t s_rm68191Cmd23[] = {0xAB, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x1F, 0x04, 0x1F, 0x0C};
56 static const uint8_t s_rm68191Cmd24[] = {0xAC, 0x1F, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x08, 0x1F, 0x0A};
57 static const uint8_t s_rm68191Cmd25[] = {0xAD, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x06, 0x02};
58 static const uint8_t s_rm68191Cmd26[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x02};
59 static const uint8_t s_rm68191Cmd27[] = {0xEA, 0x7D};
60 static const uint8_t s_rm68191Cmd28[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x00};
61 static const uint8_t s_rm68191Cmd29[] = {0xBC, 0x00, 0x00, 0x00};
62 static const uint8_t s_rm68191Cmd30[] = {0xB8, 0x01, 0xAF, 0x8F, 0x8F};
63 static const uint8_t s_rm68191Cmd31[] = {0xF0, 0x55, 0xAA, 0x52, 0x08, 0x01};
64 static const uint8_t s_rm68191Cmd32[] = {0xD1, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
65                                          0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
66 static const uint8_t s_rm68191Cmd33[] = {0xD2, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
67                                          0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
68 static const uint8_t s_rm68191Cmd34[] = {0xD3, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
69                                          0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
70 static const uint8_t s_rm68191Cmd35[] = {0xD4, 0x03, 0xE5, 0x03, 0xFF};
71 static const uint8_t s_rm68191Cmd36[] = {0xD5, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
72                                          0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
73 static const uint8_t s_rm68191Cmd37[] = {0xD6, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
74                                          0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
75 static const uint8_t s_rm68191Cmd38[] = {0xD7, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
76                                          0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
77 static const uint8_t s_rm68191Cmd39[] = {0xD8, 0x03, 0xE5, 0x03, 0xFF};
78 static const uint8_t s_rm68191Cmd40[] = {0xD9, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
79                                          0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
80 static const uint8_t s_rm68191Cmd41[] = {0xDD, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
81                                          0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
82 static const uint8_t s_rm68191Cmd42[] = {0xDE, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
83                                          0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
84 static const uint8_t s_rm68191Cmd43[] = {0xDF, 0x03, 0xE5, 0x03, 0xFF};
85 static const uint8_t s_rm68191Cmd44[] = {0xE0, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
86                                          0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
87 static const uint8_t s_rm68191Cmd45[] = {0xE1, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
88                                          0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
89 static const uint8_t s_rm68191Cmd46[] = {0xE2, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
90                                          0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
91 static const uint8_t s_rm68191Cmd47[] = {0xE3, 0x03, 0xE5, 0x03, 0xFF};
92 static const uint8_t s_rm68191Cmd48[] = {0xE4, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
93                                          0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
94 static const uint8_t s_rm68191Cmd49[] = {0xE5, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
95                                          0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
96 static const uint8_t s_rm68191Cmd50[] = {0xE6, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
97                                          0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
98 static const uint8_t s_rm68191Cmd51[] = {0xE7, 0x03, 0xE5, 0x03, 0xFF};
99 static const uint8_t s_rm68191Cmd52[] = {0xE8, 0x00, 0x00, 0x00, 0x26, 0x00, 0x5E, 0x00, 0x88,
100                                          0x00, 0xA8, 0x00, 0xDB, 0x01, 0x02, 0x01, 0x3D};
101 static const uint8_t s_rm68191Cmd53[] = {0xE9, 0x01, 0x67, 0x01, 0xA6, 0x01, 0xD3, 0x02, 0x16,
102                                          0x02, 0x49, 0x02, 0x4B, 0x02, 0x7B, 0x02, 0xB3};
103 static const uint8_t s_rm68191Cmd54[] = {0xEA, 0x02, 0xD9, 0x03, 0x0E, 0x03, 0x31, 0x03, 0x61,
104                                          0x03, 0x80, 0x03, 0xA5, 0x03, 0xBD, 0x03, 0xD2};
105 static const uint8_t s_rm68191Cmd55[] = {0xEB, 0x03, 0xE5, 0x03, 0xFF};
106 static const uint8_t s_rm68191Cmd56[] = {0xB0, 0x07, 0x07, 0x07};
107 static const uint8_t s_rm68191Cmd57[] = {0xB1, 0x07, 0x07, 0x07};
108 static const uint8_t s_rm68191Cmd58[] = {0xB3, 0x11, 0x11, 0x11};
109 static const uint8_t s_rm68191Cmd59[] = {0xB4, 0x09, 0x09, 0x09};
110 static const uint8_t s_rm68191Cmd60[] = {0xB6, 0x44, 0x44, 0x44};
111 static const uint8_t s_rm68191Cmd61[] = {0xB7, 0x34, 0x34, 0x34};
112 static const uint8_t s_rm68191Cmd62[] = {0xB9, 0x34, 0x34, 0x34};
113 static const uint8_t s_rm68191Cmd63[] = {0xBA, 0x14, 0x14, 0x14};
114 static const uint8_t s_rm68191Cmd64[] = {0xBC, 0x00, 0x98, 0x00};
115 static const uint8_t s_rm68191Cmd65[] = {0xBD, 0x00, 0x98, 0x00};
116 static const uint8_t s_rm68191Cmd66[] = {0xBE, 0x1D};
117 static const uint8_t s_rm68191Cmd67[] = {0x35, 0x00};
118 
119 static const rm68191_setting_t s_rm68191InitSetting[] = {
120     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd0),  RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd1),
121     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd2),  RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd3),
122     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd4),  RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd5),
123     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd6),  RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd7),
124     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd8),  RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd9),
125     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd10), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd11),
126     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd12), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd13),
127     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd14), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd15),
128     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd16), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd17),
129     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd18), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd19),
130     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd20), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd21),
131     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd22), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd23),
132     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd24), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd25),
133     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd26), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd27),
134     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd28), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd29),
135     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd30), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd31),
136     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd32), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd33),
137     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd34), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd35),
138     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd36), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd37),
139     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd38), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd39),
140     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd40), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd41),
141     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd42), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd43),
142     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd44), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd45),
143     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd46), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd47),
144     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd48), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd49),
145     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd50), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd51),
146     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd52), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd53),
147     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd54), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd55),
148     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd56), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd57),
149     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd58), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd59),
150     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd60), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd61),
151     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd62), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd63),
152     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd64), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd65),
153     RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd66), RM68191_MAKE_SETTING_ITEM(s_rm68191Cmd67),
154 };
155 
156 const display_operations_t rm68191_ops = {
157     .init   = RM68191_Init,
158     .deinit = RM68191_Deinit,
159     .start  = RM68191_Start,
160     .stop   = RM68191_Stop,
161 };
162 
163 /*******************************************************************************
164  * Code
165  ******************************************************************************/
166 
RM68191_Init(display_handle_t * handle,const display_config_t * config)167 status_t RM68191_Init(display_handle_t *handle, const display_config_t *config)
168 {
169     uint32_t i;
170     status_t status                    = kStatus_Success;
171     const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
172     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
173 
174     /* Only support 540 * 960 */
175     if (config->resolution != FSL_VIDEO_RESOLUTION(540, 960))
176     {
177         return kStatus_InvalidArgument;
178     }
179 
180     /* Power on. */
181     resource->pullPowerPin(true);
182     RM68191_DelayMs(1);
183 
184     /* Perform reset. */
185     resource->pullResetPin(false);
186     RM68191_DelayMs(1);
187     resource->pullResetPin(true);
188     RM68191_DelayMs(5);
189 
190     /* Set the LCM init settings. */
191     for (i = 0; i < ARRAY_SIZE(s_rm68191InitSetting); i++)
192     {
193         status = MIPI_DSI_DCS_Write(dsiDevice, s_rm68191InitSetting[i].value, (int32_t)s_rm68191InitSetting[i].len);
194 
195         if (kStatus_Success != status)
196         {
197             return status;
198         }
199     }
200 
201     /* Exit sleep mode */
202     status = MIPI_DSI_DCS_EnterSleepMode(dsiDevice, false);
203 
204     if (kStatus_Success != status)
205     {
206         return status;
207     }
208 
209     RM68191_DelayMs(200);
210 
211     /* Set display on. */
212     status = MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
213 
214     if (kStatus_Success != status)
215     {
216         return status;
217     }
218 
219     RM68191_DelayMs(200);
220 
221     return kStatus_Success;
222 }
223 
RM68191_Deinit(display_handle_t * handle)224 status_t RM68191_Deinit(display_handle_t *handle)
225 {
226     const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
227     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
228 
229     (void)MIPI_DSI_DCS_EnterSleepMode(dsiDevice, true);
230 
231     resource->pullResetPin(false);
232     resource->pullPowerPin(false);
233 
234     return kStatus_Success;
235 }
236 
RM68191_Start(display_handle_t * handle)237 status_t RM68191_Start(display_handle_t *handle)
238 {
239     const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
240     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
241 
242     return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, true);
243 }
244 
RM68191_Stop(display_handle_t * handle)245 status_t RM68191_Stop(display_handle_t *handle)
246 {
247     const rm68191_resource_t *resource = (const rm68191_resource_t *)(handle->resource);
248     mipi_dsi_device_t *dsiDevice       = resource->dsiDevice;
249 
250     return MIPI_DSI_DCS_SetDisplayOn(dsiDevice, false);
251 }
252