diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/components/video/display/it6263/fsl_it6263.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/components/video/display/it6263/fsl_it6263.c | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/video/display/it6263/fsl_it6263.c b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/it6263/fsl_it6263.c new file mode 100644 index 000000000..23e515498 --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/components/video/display/it6263/fsl_it6263.c | |||
@@ -0,0 +1,371 @@ | |||
1 | /* | ||
2 | * Copyright 2018, 2020 NXP | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * SPDX-License-Identifier: BSD-3-Clause | ||
6 | */ | ||
7 | |||
8 | #include "fsl_video_common.h" | ||
9 | #include "fsl_display.h" | ||
10 | #include "fsl_it6263.h" | ||
11 | |||
12 | /******************************************************************************* | ||
13 | * Definitions | ||
14 | ******************************************************************************/ | ||
15 | #define IT6263_LVDS_ID (0x66U / 2U) | ||
16 | |||
17 | #define IT6263_HDMI_VENDER_ID 0x01ca1376U | ||
18 | #define IT6263_LVDS_VENDER_ID 0x15ca6162U | ||
19 | |||
20 | #define IT6263_I2C_WriteReg(handle, addr, reg, value) \ | ||
21 | VIDEO_I2C_WriteReg(addr, kVIDEO_RegAddr8Bit, (reg), kVIDEO_RegWidth8Bit, (value), \ | ||
22 | ((const it6263_resource_t *)((handle)->resource))->i2cSendFunc) | ||
23 | |||
24 | #define IT6263_I2C_ReadReg(handle, addr, reg, value) \ | ||
25 | VIDEO_I2C_ReadReg(addr, kVIDEO_RegAddr8Bit, (reg), kVIDEO_RegWidth8Bit, (value), \ | ||
26 | ((const it6263_resource_t *)((handle)->resource))->i2cReceiveFunc) | ||
27 | |||
28 | #define IT6263_I2C_ModifyReg(handle, addr, reg, mask, value) \ | ||
29 | VIDEO_I2C_ModifyReg(addr, kVIDEO_RegAddr8Bit, (reg), kVIDEO_RegWidth8Bit, mask, (value), \ | ||
30 | ((const it6263_resource_t *)((handle)->resource))->i2cReceiveFunc, \ | ||
31 | ((const it6263_resource_t *)((handle)->resource))->i2cSendFunc) | ||
32 | |||
33 | #define IT6263_I2C_ReadRegs(handle, addr, reg, value, len) \ | ||
34 | VIDEO_I2C_ReadReg(addr, kVIDEO_RegAddr8Bit, (reg), (video_reg_width_t)len, (value), \ | ||
35 | ((const it6263_resource_t *)((handle)->resource))->i2cReceiveFunc) | ||
36 | |||
37 | #define IT6263_SET_LVDS_ID_REG 0x1DU | ||
38 | #define IT6263_ENABLE_LVDS_ID_REG 0x1EU | ||
39 | |||
40 | #define IT6263_HDMI_VENDER_ID_REG 0 | ||
41 | #define IT6263_LVDS_VENDER_ID_REG 0 | ||
42 | |||
43 | #define IT6263_LVDS_COLOR_DEPTH(x) ((x) << 0U) | ||
44 | #define IT6263_LVDS_COLOR_DEPTH_MASK (3U << 0U) | ||
45 | #define IT6263_LVDS_MAP(x) ((x) << 4U) | ||
46 | #define IT6263_LVDS_MAP_MASK (1U << 4U) | ||
47 | #define IT6263_LVDS_DUAL_MODE(x) ((x) << 7U) | ||
48 | #define IT6263_LVDS_DUAL_MODE_MASK (1U << 7U) | ||
49 | |||
50 | /* Color depth. */ | ||
51 | #define IT6263_LVDS_COLOR_6BIT IT6263_LVDS_COLOR_DEPTH(0U) | ||
52 | #define IT6263_LVDS_COLOR_8BIT IT6263_LVDS_COLOR_DEPTH(1U) | ||
53 | #define IT6263_LVDS_COLOR_10BIT IT6263_LVDS_COLOR_DEPTH(2U) | ||
54 | #define IT6263_LVDS_COLOR_12BIT IT6263_LVDS_COLOR_DEPTH(3U) | ||
55 | |||
56 | /* Pixel map. */ | ||
57 | #define IT6263_LVDS_JEIDA IT6263_LVDS_MAP(0U) | ||
58 | #define IT6263_LVDS_VESA IT6263_LVDS_MAP(1U) | ||
59 | |||
60 | /* Dual mode. */ | ||
61 | #define IT6263_LVDS_DISO IT6263_LVDS_DUAL_MODE(1U) /* Dual In / Single Out */ | ||
62 | #define IT6263_LVDS_DIRECT IT6263_LVDS_DUAL_MODE(0U) /* Single In / Single Out or Dual In / Dual Out */ | ||
63 | |||
64 | /* HDMI register 0x04. */ | ||
65 | #define HDMI_REG_SW_RST 0x04U | ||
66 | #define IT6263_HDMI_04_SOFTREFRST_MASK (1U << 5U) | ||
67 | #define IT6263_HDMI_04_SOFTARST_MASK (1U << 4U) | ||
68 | #define IT6263_HDMI_04_SOFTVRST_MASK (1U << 3U) | ||
69 | #define IT6263_HDMI_04_AUDRST_MASK (1U << 2U) | ||
70 | #define IT6263_HDMI_04_HDCPRST_MASK (1U << 0U) | ||
71 | #define IT6263_HDMI_04_ALLRST_MASK ((1U << 5U) | (1U << 4U) | (1U << 3U) | (1U << 2U) | (1U << 0U)) | ||
72 | |||
73 | /* HDMI register 0x61. */ | ||
74 | #define IT6263_HDMI_61_DRV_PWD_MASK (1U << 5U) | ||
75 | #define IT6263_HDMI_61_DRV_RST_MASK (1U << 4U) | ||
76 | |||
77 | /* HDMI register 0xC1. */ | ||
78 | #define IT6263_HDMI_C1_AVMUTE_MASK (1U << 0U) | ||
79 | |||
80 | /* HDMI register 0xC6. */ | ||
81 | #define IT6263_HDMI_C6_PKTGENCTRLRPT_MASK (1U << 1U) | ||
82 | #define IT6263_HDMI_C6_PKTGENCTRLEN_MASK (1U << 0U) | ||
83 | |||
84 | /* LVDS register 0x05. */ | ||
85 | #define IT6263_LVDS_05_SOFTREFRST_MASK (1U << 0U) | ||
86 | #define IT6263_LVDS_05_SOFTRST_MASK (1U << 1U) | ||
87 | |||
88 | #define IT6263_CHECK_RET(x) \ | ||
89 | do \ | ||
90 | { \ | ||
91 | status = (x); \ | ||
92 | if (kStatus_Success != status) \ | ||
93 | { \ | ||
94 | return status; \ | ||
95 | } \ | ||
96 | } while (false) | ||
97 | |||
98 | /******************************************************************************* | ||
99 | * Variables | ||
100 | ******************************************************************************/ | ||
101 | const display_operations_t it6263_ops = { | ||
102 | .init = IT6263_Init, | ||
103 | .deinit = IT6263_Deinit, | ||
104 | .start = IT6263_Start, | ||
105 | .stop = IT6263_Stop, | ||
106 | }; | ||
107 | |||
108 | /******************************************************************************* | ||
109 | * Code | ||
110 | ******************************************************************************/ | ||
111 | |||
112 | static void IT6263_HardwareReset(display_handle_t *handle) | ||
113 | { | ||
114 | const it6263_resource_t *resource = (const it6263_resource_t *)(handle->resource); | ||
115 | |||
116 | resource->pullResetPin(true); | ||
117 | |||
118 | VIDEO_DelayMs(1); | ||
119 | |||
120 | resource->pullResetPin(false); | ||
121 | |||
122 | VIDEO_DelayMs(40); | ||
123 | |||
124 | resource->pullResetPin(true); | ||
125 | |||
126 | VIDEO_DelayMs(10); | ||
127 | } | ||
128 | |||
129 | static status_t IT6263_LVDSReset(display_handle_t *handle) | ||
130 | { | ||
131 | status_t status; | ||
132 | |||
133 | /* Reset the AFE PLL. */ | ||
134 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x3C, 0x1, 0x0)); | ||
135 | VIDEO_DelayMs(1); | ||
136 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x3C, 0x1, 0x1)); | ||
137 | |||
138 | /* Reset the PCLK. */ | ||
139 | status = | ||
140 | IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x05, IT6263_LVDS_05_SOFTRST_MASK, IT6263_LVDS_05_SOFTRST_MASK); | ||
141 | if (kStatus_Success != status) | ||
142 | { | ||
143 | return status; | ||
144 | } | ||
145 | |||
146 | VIDEO_DelayMs(1); | ||
147 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x05, IT6263_LVDS_05_SOFTRST_MASK, 0)); | ||
148 | |||
149 | VIDEO_DelayMs(1); | ||
150 | |||
151 | return kStatus_Success; | ||
152 | } | ||
153 | |||
154 | static status_t IT6263_InitLVDS_ID(display_handle_t *handle) | ||
155 | { | ||
156 | status_t status; | ||
157 | |||
158 | uint8_t i2cAddr = (((const it6263_resource_t *)(handle->resource))->i2cAddr) / 2U; | ||
159 | |||
160 | status = IT6263_I2C_WriteReg(handle, i2cAddr, IT6263_SET_LVDS_ID_REG, IT6263_LVDS_ID * 2U); | ||
161 | |||
162 | if (kStatus_Success == status) | ||
163 | { | ||
164 | status = IT6263_I2C_WriteReg(handle, i2cAddr, IT6263_ENABLE_LVDS_ID_REG, 1); | ||
165 | } | ||
166 | |||
167 | return status; | ||
168 | } | ||
169 | |||
170 | static status_t IT6263_Identify(display_handle_t *handle) | ||
171 | { | ||
172 | status_t status; | ||
173 | uint32_t hdmiVendorID = 0U; | ||
174 | uint32_t lvdsVendorID = 0U; | ||
175 | |||
176 | uint8_t i2cAddr = (((const it6263_resource_t *)(handle->resource))->i2cAddr) / 2U; | ||
177 | |||
178 | status = IT6263_I2C_ReadRegs(handle, i2cAddr, IT6263_HDMI_VENDER_ID_REG, &hdmiVendorID, sizeof(hdmiVendorID)); | ||
179 | if (kStatus_Success != status) | ||
180 | { | ||
181 | return status; | ||
182 | } | ||
183 | |||
184 | status = | ||
185 | IT6263_I2C_ReadRegs(handle, IT6263_LVDS_ID, IT6263_LVDS_VENDER_ID_REG, &lvdsVendorID, sizeof(lvdsVendorID)); | ||
186 | if (kStatus_Success != status) | ||
187 | { | ||
188 | return status; | ||
189 | } | ||
190 | |||
191 | if ((hdmiVendorID != IT6263_HDMI_VENDER_ID) || (lvdsVendorID != IT6263_LVDS_VENDER_ID)) | ||
192 | { | ||
193 | return kStatus_Fail; | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | return kStatus_Success; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static status_t IT6263_InitLVDS(display_handle_t *handle) | ||
202 | { | ||
203 | status_t status; | ||
204 | uint8_t mask; | ||
205 | uint8_t val; | ||
206 | |||
207 | /* Configure LVDS. */ | ||
208 | mask = IT6263_LVDS_COLOR_DEPTH_MASK | IT6263_LVDS_MAP_MASK | IT6263_LVDS_DUAL_MODE_MASK; | ||
209 | val = IT6263_LVDS_COLOR_8BIT | IT6263_LVDS_JEIDA | IT6263_LVDS_DIRECT; | ||
210 | |||
211 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x2C, mask, val)); | ||
212 | |||
213 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x52, 0x02, 0x00)); | ||
214 | |||
215 | /* AFE */ | ||
216 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, IT6263_LVDS_ID, 0x3E, 0xAA)); | ||
217 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, IT6263_LVDS_ID, 0x3F, 0x02)); | ||
218 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, IT6263_LVDS_ID, 0x47, 0xAA)); | ||
219 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, IT6263_LVDS_ID, 0x48, 0x02)); | ||
220 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, IT6263_LVDS_ID, 0x4F, 0x11)); | ||
221 | |||
222 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, IT6263_LVDS_ID, 0x3C, 0x07, 0)); | ||
223 | |||
224 | return kStatus_Success; | ||
225 | } | ||
226 | |||
227 | status_t IT6263_Init(display_handle_t *handle, const display_config_t *config) | ||
228 | { | ||
229 | assert(handle); | ||
230 | |||
231 | status_t status; | ||
232 | |||
233 | uint8_t i2cAddr = ((const it6263_resource_t *)(handle->resource))->i2cAddr / 2U; | ||
234 | |||
235 | IT6263_HardwareReset(handle); | ||
236 | |||
237 | /* Software reset. */ | ||
238 | status = IT6263_I2C_WriteReg(handle, i2cAddr, 0x04, IT6263_HDMI_04_ALLRST_MASK); | ||
239 | if (kStatus_Success != status) | ||
240 | { | ||
241 | return status; | ||
242 | } | ||
243 | |||
244 | VIDEO_DelayMs(1); | ||
245 | |||
246 | status = IT6263_InitLVDS_ID(handle); | ||
247 | if (kStatus_Success != status) | ||
248 | { | ||
249 | return status; | ||
250 | } | ||
251 | |||
252 | status = IT6263_Identify(handle); | ||
253 | if (kStatus_Success != status) | ||
254 | { | ||
255 | return status; | ||
256 | } | ||
257 | |||
258 | IT6263_CHECK_RET(IT6263_LVDSReset(handle)); | ||
259 | |||
260 | IT6263_CHECK_RET(IT6263_InitLVDS(handle)); | ||
261 | |||
262 | /* | ||
263 | * Set color: | ||
264 | * 0 RGB | ||
265 | * 1 YUV422 | ||
266 | * 2 YUV444 | ||
267 | */ | ||
268 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0x70, 0x03U << 6U, 0)); | ||
269 | |||
270 | /* | ||
271 | * No color space conversion. | ||
272 | * 0: No conversion | ||
273 | * 1: RGB -> YUV | ||
274 | * 2: YUV -> RGB | ||
275 | */ | ||
276 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0x72, 0x03U << 0U, 0)); | ||
277 | |||
278 | /* | ||
279 | * HDMI color dpeth: | ||
280 | * 000 - color depth is not indicate (as 8bit) | ||
281 | * 100 - 8/8/8 bit color | ||
282 | * 101 - 10/10/10 bit color | ||
283 | * 110 - 12/12/12 bit color) | ||
284 | */ | ||
285 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0xC1, 0x07U << 4U, 0x04U << 0U)); | ||
286 | |||
287 | /* Select HDMI. */ | ||
288 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0xC0, 0x01)); | ||
289 | |||
290 | /* Set AFE */ | ||
291 | if (config->pixelClock_Hz > 80000000U) | ||
292 | { | ||
293 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0x62, 0x88)); | ||
294 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0x64, 0x84)); | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0x62, 0x18)); | ||
299 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0x64, 0x0C)); | ||
300 | } | ||
301 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0x63, 0x10)); | ||
302 | |||
303 | /* | ||
304 | * Output Color Mode | ||
305 | * 00 - RGB444 mode | ||
306 | * 01 - YCbCr422 mode | ||
307 | * 10 - YCbCr444 mode | ||
308 | */ | ||
309 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0x0F, 0x03U << 0U, 0x01U << 0U)); /* Bank 0 */ | ||
310 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0x58, 0x03U << 5U, 0x00U << 5U)); | ||
311 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0x0F, 0x03U << 0U, 0x00U << 0U)); /* Bank 1 */ | ||
312 | |||
313 | /* software video reset */ | ||
314 | status = IT6263_I2C_ModifyReg(handle, i2cAddr, 0x04, IT6263_HDMI_04_SOFTVRST_MASK, IT6263_HDMI_04_SOFTVRST_MASK); | ||
315 | if (kStatus_Success != status) | ||
316 | { | ||
317 | return status; | ||
318 | } | ||
319 | |||
320 | VIDEO_DelayMs(100); | ||
321 | |||
322 | return kStatus_Success; | ||
323 | } | ||
324 | |||
325 | status_t IT6263_Deinit(display_handle_t *handle) | ||
326 | { | ||
327 | const it6263_resource_t *resource = (const it6263_resource_t *)(handle->resource); | ||
328 | |||
329 | resource->pullResetPin(false); | ||
330 | |||
331 | return kStatus_Success; | ||
332 | } | ||
333 | |||
334 | status_t IT6263_Start(display_handle_t *handle) | ||
335 | { | ||
336 | status_t status; | ||
337 | |||
338 | uint8_t i2cAddr = ((const it6263_resource_t *)(handle->resource))->i2cAddr / 2U; | ||
339 | |||
340 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0x04, IT6263_HDMI_04_SOFTVRST_MASK, 0)); | ||
341 | IT6263_CHECK_RET(IT6263_I2C_WriteReg(handle, i2cAddr, 0x61, 0)); | ||
342 | IT6263_CHECK_RET(IT6263_I2C_ModifyReg(handle, i2cAddr, 0xC1, IT6263_HDMI_C1_AVMUTE_MASK, 0)); | ||
343 | return IT6263_I2C_WriteReg(handle, i2cAddr, 0xc6, | ||
344 | IT6263_HDMI_C6_PKTGENCTRLRPT_MASK | IT6263_HDMI_C6_PKTGENCTRLEN_MASK); | ||
345 | } | ||
346 | |||
347 | status_t IT6263_Stop(display_handle_t *handle) | ||
348 | { | ||
349 | status_t status; | ||
350 | uint8_t i2cAddr = ((const it6263_resource_t *)(handle->resource))->i2cAddr / 2U; | ||
351 | |||
352 | status = IT6263_I2C_ModifyReg(handle, i2cAddr, 0xC1, IT6263_HDMI_C1_AVMUTE_MASK, IT6263_HDMI_C1_AVMUTE_MASK); | ||
353 | |||
354 | if (kStatus_Success == status) | ||
355 | { | ||
356 | status = IT6263_I2C_WriteReg(handle, i2cAddr, 0xC6, 0); | ||
357 | } | ||
358 | |||
359 | if (kStatus_Success == status) | ||
360 | { | ||
361 | status = | ||
362 | IT6263_I2C_ModifyReg(handle, i2cAddr, 0x04, IT6263_HDMI_04_SOFTVRST_MASK, IT6263_HDMI_04_SOFTVRST_MASK); | ||
363 | } | ||
364 | |||
365 | if (kStatus_Success == status) | ||
366 | { | ||
367 | status = IT6263_I2C_WriteReg(handle, i2cAddr, 0x61, IT6263_HDMI_61_DRV_PWD_MASK | IT6263_HDMI_61_DRV_RST_MASK); | ||
368 | } | ||
369 | |||
370 | return status; | ||
371 | } | ||