1 /*
2 * Copyright (c) 2022 ITE.
3 * Copyright 2022 NXP
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_it6161.h"
9 #include "hdmi_tx.h"
10 #include "fsl_debug_console.h"
11
12 static RX_CAP RxCapability;
13 static uint8_t CommonBuff[128] = {0U};
14
15 static uint8_t bCSCMtx_RGB2YUV_ITU601_16_235[] = {0x00, 0x80, 0x00, 0xB2, 0x04, 0x65, 0x02, 0xE9, 0x00, 0x93, 0x3C,
16 0x18, 0x04, 0x55, 0x3F, 0x49, 0x3D, 0x9F, 0x3E, 0x18, 0x04};
17
18 static uint8_t bCSCMtx_RGB2YUV_ITU601_0_255[] = {0x10, 0x80, 0x10, 0x09, 0x04, 0x0E, 0x02, 0xC9, 0x00, 0x0F, 0x3D,
19 0x84, 0x03, 0x6D, 0x3F, 0xAB, 0x3D, 0xD1, 0x3E, 0x84, 0x03};
20
21 static uint8_t bCSCMtx_RGB2YUV_ITU709_16_235[] = {0x00, 0x80, 0x00, 0xB8, 0x05, 0xB4, 0x01, 0x94, 0x00, 0x4a, 0x3C,
22 0x17, 0x04, 0x9F, 0x3F, 0xD9, 0x3C, 0x10, 0x3F, 0x17, 0x04};
23
24 static uint8_t bCSCMtx_RGB2YUV_ITU709_0_255[] = {0x10, 0x80, 0x10, 0xEa, 0x04, 0x77, 0x01, 0x7F, 0x00, 0xD0, 0x3C,
25 0x83, 0x03, 0xAD, 0x3F, 0x4B, 0x3D, 0x32, 0x3F, 0x83, 0x03};
26
27 static uint8_t bCSCMtx_YUV2RGB_ITU601_16_235[] = {0x00, 0x00, 0x00, 0x00, 0x08, 0x6B, 0x3A, 0x50, 0x3D, 0x00, 0x08,
28 0xF5, 0x0A, 0x02, 0x00, 0x00, 0x08, 0xFD, 0x3F, 0xDA, 0x0D};
29
30 static uint8_t bCSCMtx_YUV2RGB_ITU601_0_255[] = {0x04, 0x00, 0xA7, 0x4F, 0x09, 0x81, 0x39, 0xDD, 0x3C, 0x4F, 0x09,
31 0xC4, 0x0C, 0x01, 0x00, 0x4F, 0x09, 0xFD, 0x3F, 0x1F, 0x10};
32
33 static uint8_t bCSCMtx_YUV2RGB_ITU709_16_235[] = {0x00, 0x00, 0x00, 0x00, 0x08, 0x55, 0x3C, 0x88, 0x3E, 0x00, 0x08,
34 0x51, 0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x84, 0x0E};
35
36 static uint8_t bCSCMtx_YUV2RGB_ITU709_0_255[] = {0x04, 0x00, 0xA7, 0x4F, 0x09, 0xBA, 0x3B, 0x4B, 0x3E, 0x4F, 0x09,
37 0x57, 0x0E, 0x02, 0x00, 0x4F, 0x09, 0xFE, 0x3F, 0xE8, 0x10};
38
HDMITX_LoadRegSetting(display_handle_t * handle,RegSetTable_t * table,uint32_t table_sz)39 void HDMITX_LoadRegSetting(display_handle_t *handle, RegSetTable_t *table, uint32_t table_sz)
40 {
41 uint32_t i;
42
43 for (i = 0U; i < table_sz / sizeof(RegSetTable_t); i++)
44 {
45 if (table[i].invAndMask == 0xFFU)
46 {
47 HDMITX_WriteI2C_Byte(handle, table[i].offset, table[i].OrMask);
48 }
49 else
50 {
51 HDMITX_SetI2C_Byte(handle, table[i].offset, table[i].invAndMask, table[i].OrMask);
52 }
53 }
54 }
55
HDMITX_DisableAudioOutput(display_handle_t * handle)56 static void HDMITX_DisableAudioOutput(display_handle_t *handle)
57 {
58 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (B_HDMITX_AUD_RST | B_TX_AREF_RST),
59 (B_HDMITX_AUD_RST | B_TX_AREF_RST));
60 HDMITX_SetI2C_Byte(handle, 0x0F, 0x10, 0x10);
61 }
62
HDMITX_VideoReset(display_handle_t * handle)63 void HDMITX_VideoReset(display_handle_t *handle)
64 {
65 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, B_HDMITX_VID_RST, B_HDMITX_VID_RST);
66 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, B_HDMITX_VID_RST, 0x00);
67 delay1ms(10);
68 }
69
HDMITX_ChangeBank(display_handle_t * handle,uint8_t value)70 static inline void HDMITX_ChangeBank(display_handle_t *handle, uint8_t value)
71 {
72 HDMITX_SetI2C_Byte(handle, 0x0F, 0x03, (uint32_t)value & 0x03U);
73 }
74
DumpHDMITXReg(display_handle_t * handle)75 static void DumpHDMITXReg(display_handle_t *handle)
76 {
77 #if (DEBUG_DUMP_HDMITX_REGISTER == 0x01U)
78 int i = 0, j = 0;
79 uint8_t ucData = 0U;
80
81 PRINTF(" ");
82 for (j = 0; j < 16; j++)
83 {
84 PRINTF(" %02X", j);
85 if ((j == 3) || (j == 7) || (j == 11))
86 {
87 PRINTF(" ");
88 }
89 }
90 PRINTF("\r\n -----------------------------------------------------\r\n");
91
92 HDMITX_ChangeBank(handle, 0);
93
94 for (i = 0; i < 0x100; i += 16)
95 {
96 PRINTF("[%3X] ", i);
97 for (j = 0; j < 16; j++)
98 {
99 if ((i + j) != 0x17)
100 {
101 HDMITX_ReadI2C_Byte(handle, (uint8_t)((i + j) & 0xFFU), &ucData);
102 PRINTF(" %02X", (int)ucData);
103 }
104 else
105 {
106 PRINTF(" XX", (int)ucData); // for DDC FIFO
107 }
108 if ((j == 3) || (j == 7) || (j == 11))
109 {
110 PRINTF(" -");
111 }
112 }
113 PRINTF("\r\n");
114 if ((i % 0x40) == 0x30)
115 {
116 PRINTF(" -----------------------------------------------------\r\n");
117 }
118 }
119 HDMITX_ChangeBank(handle, 1);
120 for (i = 0x130; i < 0x200; i += 16)
121 {
122 PRINTF("[%3X] ", i);
123 for (j = 0; j < 16; j++)
124 {
125 HDMITX_ReadI2C_Byte(handle, (uint8_t)((i + j) & 0xFF), &ucData);
126 PRINTF(" %02X", (int)ucData);
127 if ((j == 3) || (j == 7) || (j == 11))
128 {
129 PRINTF(" -");
130 }
131 }
132 PRINTF("\r\n");
133 if ((i % 0x40) == 0x20)
134 {
135 PRINTF(" -----------------------------------------------------\r\n");
136 }
137 }
138 PRINTF(" -----------------------------------------------------\r\n");
139 HDMITX_ChangeBank(handle, 0);
140 #endif
141 }
142
HDMITX_DisableVideoOutput(display_handle_t * handle)143 static void HDMITX_DisableVideoOutput(display_handle_t *handle)
144 {
145 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, B_HDMITX_VID_RST, B_HDMITX_VID_RST);
146 HDMITX_WriteI2C_Byte(handle, REG_TX_AFE_DRV_CTRL, B_TX_AFE_DRV_RST | B_TX_AFE_DRV_PWD);
147 HDMITX_SetI2C_Byte(handle, 0x62, 0x90, 0x00);
148 HDMITX_SetI2C_Byte(handle, 0x64, 0x89, 0x00);
149 }
150
HDMITX_GetSinkHpd(display_handle_t * handle)151 static inline bool HDMITX_GetSinkHpd(display_handle_t *handle)
152 {
153 uint8_t tx_sys_status = 0;
154
155 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_STATUS_REG0E, &tx_sys_status);
156
157 return (bool)(tx_sys_status & HDMI_TX_SYS_STATUS_REG0E_RHPDetect_MASK);
158 }
159
HDMITX_ClearDDCFIFO(display_handle_t * handle)160 static void HDMITX_ClearDDCFIFO(display_handle_t *handle)
161 {
162 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK);
163 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15, HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_DDC_FIFO_clear);
164 }
165
HDMITX_AbortDDC(display_handle_t * handle)166 static void HDMITX_AbortDDC(display_handle_t *handle)
167 {
168 uint8_t SWReset = 0U;
169 uint8_t uc = 0U, timeout = 0U, i = 0U;
170
171 // save the SW reset,DDC master,and CP Desire setting.
172 HDMITX_ReadI2C_Byte(handle, HDMI_TX_GENERAL_REG04, &SWReset);
173
174 HDMITX_WriteI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (uint32_t)SWReset | (uint32_t)B_TX_HDCP_RST_HDMITX);
175 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK);
176
177 for (i = 0; i < 2U; i++)
178 {
179 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15, HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_Abort_DDC_CMD);
180
181 for (timeout = 0; timeout < 200U; timeout++)
182 {
183 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG16, &uc);
184 if ((uc & HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_Done_MASK) != 0U)
185 {
186 break; // success
187 }
188 if ((uc & (HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_NoACK_MASK |
189 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_WaitBus_MASK |
190 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_ArbiLose_MASK)) != 0U)
191 {
192 break;
193 }
194 delay1ms(1); // delay 1 ms to stable.
195 }
196 }
197 }
198
getHDMITX_EDIDBytes(display_handle_t * handle,uint8_t * pData,uint8_t bSegment,uint8_t offset,uint16_t Count)199 static bool getHDMITX_EDIDBytes(
200 display_handle_t *handle, uint8_t *pData, uint8_t bSegment, uint8_t offset, uint16_t Count)
201 {
202 uint16_t RemainedCount = 0U, ReqCount = 0U;
203 uint8_t bCurrOffset = 0U;
204 uint16_t TimeOut = 0U;
205 uint8_t *pBuff = pData;
206 uint8_t ucdata = 0U;
207 uint8_t value = 0U;
208
209 if (pData == NULL)
210 {
211 return false;
212 }
213 HDMITX_ReadI2C_Byte(handle, HDMI_TX_INT_FLAGS_REG06, &value);
214 if ((value & HDMI_TX_INT_FLAGS_REG06_RInt_DDCBusHang_MASK) != 0U)
215 {
216 HDMITX_DEBUG_PRINTF("Called hdmitx_AboutDDC()\n");
217 HDMITX_AbortDDC(handle);
218 }
219
220 HDMITX_ClearDDCFIFO(handle);
221
222 RemainedCount = Count;
223 bCurrOffset = offset;
224
225 HDMITX_ChangeBank(handle, 0);
226
227 while (RemainedCount > 0U)
228 {
229 ReqCount = (RemainedCount > DDC_FIFO_MAXREQ) ? DDC_FIFO_MAXREQ : RemainedCount;
230 HDMITX_DEBUG_PRINTF("getHDMITX_EDIDBytes(): ReqCount = %d,bCurrOffset = %d\n", (int)ReqCount, (int)bCurrOffset);
231
232 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK);
233 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15, HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_DDC_FIFO_clear);
234
235 for (TimeOut = 0; TimeOut < 200U; TimeOut++)
236 {
237 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG16, &value);
238 if ((value & HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_Done_MASK) != 0U)
239 {
240 break;
241 }
242 HDMITX_ReadI2C_Byte(handle, HDMI_TX_INT_FLAGS_REG06, &ucdata);
243 if ((value & (HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_NoACK_MASK |
244 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_WaitBus_MASK |
245 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_ArbiLose_MASK)) != 0U ||
246 (ucdata & HDMI_TX_INT_FLAGS_REG06_RInt_DDCBusHang_MASK) != 0U)
247 {
248 HDMITX_DEBUG_PRINTF("Called hdmitx_AboutDDC()\n");
249 HDMITX_AbortDDC(handle);
250 return false;
251 }
252 }
253 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK);
254 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG11, HDMI_TX_DDC_EDID_ADDR); // for EDID ucdata get
255 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG12, bCurrOffset);
256 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG13, (uint8_t)ReqCount);
257 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG14, bSegment);
258 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15, HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_EDID_read);
259
260 bCurrOffset += (uint8_t)ReqCount;
261 RemainedCount -= ReqCount;
262
263 for (TimeOut = 250; TimeOut > 0U; TimeOut--)
264 {
265 delay1ms(1);
266 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG16, &ucdata);
267 if ((ucdata & HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_Done_MASK) != 0U)
268 {
269 break;
270 }
271 if ((ucdata & (HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_NoACK_MASK |
272 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_WaitBus_MASK |
273 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_ArbiLose_MASK)) != 0U)
274 {
275 HDMITX_DEBUG_PRINTF("getHDMITX_EDIDBytes(): DDC_STATUS = %02X,fail.\n", (int)ucdata);
276 return false;
277 }
278 }
279 if (TimeOut == 0U)
280 {
281 HDMITX_DEBUG_PRINTF("getHDMITX_EDIDBytes(): DDC TimeOut. \n", (int)ucdata);
282 return false;
283 }
284 do
285 {
286 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG17, pBuff);
287 pBuff++;
288 ReqCount--;
289 } while (ReqCount > 0U);
290 }
291 return true;
292 }
293
getHDMITX_EDIDBlock(display_handle_t * handle,int32_t EDIDBlockID,uint8_t * pEDIDData)294 static bool getHDMITX_EDIDBlock(display_handle_t *handle, int32_t EDIDBlockID, uint8_t *pEDIDData)
295 {
296 if (pEDIDData == NULL)
297 {
298 return false;
299 }
300 return getHDMITX_EDIDBytes(handle, pEDIDData, (uint8_t)EDIDBlockID / 2U, (uint8_t)((EDIDBlockID % 2) * 128), 128);
301 }
302
ParseCEAEDID(uint8_t * pCEAEDID)303 static bool ParseCEAEDID(uint8_t *pCEAEDID)
304
305 {
306 uint8_t offset = 0U, End = 0U;
307 uint8_t count = 0U;
308 uint8_t tag = 0U;
309 uint8_t i = 0U;
310
311 if (pCEAEDID[0] != 0x02U || pCEAEDID[1] != 0x03U)
312 {
313 return false; // not a CEA BLOCK.
314 }
315 End = pCEAEDID[2]; // CEA description.
316
317 RxCapability.VDOMode[0] = 0x00;
318 RxCapability.VDOMode[1] = 0x00;
319 RxCapability.VDOMode[2] = 0x00;
320 RxCapability.VDOMode[3] = 0x00;
321 RxCapability.VDOMode[4] = 0x00;
322 RxCapability.VDOMode[5] = 0x00;
323 RxCapability.VDOMode[6] = 0x00;
324 RxCapability.VDOMode[7] = 0x00;
325 RxCapability.PA[0] = 0x00;
326 RxCapability.PA[1] = 0x00;
327
328 RxCapability.VideoMode = pCEAEDID[3];
329
330 RxCapability.NativeVDOMode = 0xff;
331
332 for (offset = 4; offset < End;)
333 {
334 tag = pCEAEDID[offset] >> 5U;
335 count = pCEAEDID[offset] & 0x1fU;
336 switch (tag)
337 {
338 case 0x01: // Audio Data Block ;
339 RxCapability.AUDDesCount = count / 3U;
340 HDMITX_DEBUG_PRINTF("RxCapability.AUDDesCount = %d\n", (int)RxCapability.AUDDesCount);
341 offset++;
342 for (i = 0U; i < RxCapability.AUDDesCount && i < MAX_AUDDES_COUNT; i++)
343 {
344 RxCapability.AUDDes[i].uc[0] = pCEAEDID[offset + i * 3U];
345 RxCapability.AUDDes[i].uc[1] = pCEAEDID[offset + i * 3U + 1U];
346 RxCapability.AUDDes[i].uc[2] = pCEAEDID[offset + i * 3U + 2U];
347 }
348 offset += count;
349 break;
350
351 case 0x02: // Video Data Block ;
352 offset++;
353 for (i = 0U; i < count; i++)
354 {
355 uint8_t VIC = 0U;
356 RxCapability.NativeVDOMode = 0xff;
357
358 VIC = (uint8_t)(pCEAEDID[offset + i] & (~0x80U));
359 if (VIC < 64U)
360 {
361 RxCapability.VDOMode[VIC / 8U] |= (1U << (VIC % 8U));
362 HDMITX_DEBUG_PRINTF("VIC = %d, RxCapability.VDOMode[%d]=%02X\n", (int)VIC, (int)VIC / 8,
363 (int)RxCapability.VDOMode[VIC / 8]);
364 if (((pCEAEDID[offset + i] & 0x80U) != 0U) && (RxCapability.NativeVDOMode == 0xFFU))
365 {
366 RxCapability.NativeVDOMode = VIC;
367 HDMITX_DEBUG_PRINTF("native = %d\n", RxCapability.NativeVDOMode);
368 }
369 }
370 }
371 offset += count;
372 break;
373
374 case 0x03: // Vendor Specific Data Block ;
375 offset++;
376 RxCapability.IEEEOUI = (uint32_t)pCEAEDID[offset + 2U];
377 RxCapability.IEEEOUI <<= 8;
378 RxCapability.IEEEOUI += (uint32_t)pCEAEDID[offset + 1U];
379 RxCapability.IEEEOUI <<= 8;
380 RxCapability.IEEEOUI += (uint32_t)pCEAEDID[offset];
381 HDMITX_DEBUG_PRINTF("IEEEOUI = %02X %02X %02X %lx", (int)pCEAEDID[offset + 2],
382 (int)pCEAEDID[offset + 1], (int)pCEAEDID[offset], RxCapability.IEEEOUI);
383 if (RxCapability.IEEEOUI == 0x0C03U)
384 {
385 uint8_t nextoffset = 0U;
386
387 RxCapability.ValidHDMI = 1U;
388
389 RxCapability.PA[0] = pCEAEDID[offset + 3U];
390 RxCapability.PA[1] = pCEAEDID[offset + 4U];
391 if (count > 5U)
392 {
393 RxCapability.dc.uc = pCEAEDID[offset + 5U] & 0x70U;
394 }
395 if (count > 6U)
396 {
397 RxCapability.MaxTMDSClock = pCEAEDID[offset + 6U];
398 }
399 if (count > 7U)
400 {
401 nextoffset = 8;
402 if ((pCEAEDID[offset + 7U] & 0x80U) != 0U)
403 {
404 nextoffset += 2U;
405 } // latency
406 if ((pCEAEDID[offset + 7U] & 0x40U) != 0U)
407 {
408 nextoffset += 2U;
409 } // interlace latency
410 if ((pCEAEDID[offset + 7U] & 0x20U) != 0U)
411 {
412 HDMITX_DEBUG_PRINTF("next offset = %d", (int)nextoffset);
413 RxCapability.Valid3D = ((pCEAEDID[offset + nextoffset] & 0x80U) != 0U) ? 1U : 0U;
414 } // interlace latency
415 }
416 }
417 offset += count; // ignore the remaind.
418
419 break;
420
421 case 0x04: // Speaker Data Block ;
422 offset++;
423 RxCapability.SpeakerAllocBlk.uc[0] = pCEAEDID[offset];
424 RxCapability.SpeakerAllocBlk.uc[1] = pCEAEDID[offset + 1U];
425 RxCapability.SpeakerAllocBlk.uc[2] = pCEAEDID[offset + 2U];
426 offset += 3U;
427 break;
428 case 0x05: // VESA Data Block ;
429 offset += count + 1U;
430 break;
431 case 0x07: // Extended Data Block ;
432 offset += count + 1U; // ignore
433 break;
434 default:
435 offset += count + 1U; // ignore
436 break;
437 }
438 }
439 RxCapability.ValidCEA = 1;
440
441 return true;
442 }
443
ParseEDID(display_handle_t * handle)444 static uint8_t ParseEDID(display_handle_t *handle)
445 {
446 // collect the EDID ucdata of segment 0
447 unsigned char *EDID_Buf = NULL;
448 uint8_t CheckSum = 0U;
449 uint8_t BlockCount = 0U;
450 uint8_t err = 0U;
451 // uint8_t bValidCEA = false ;
452 uint8_t i = 0U;
453 uint8_t j = 0U;
454
455 EDID_Buf = CommonBuff;
456 RxCapability.ValidCEA = 0;
457 RxCapability.ValidHDMI = 0;
458 RxCapability.dc.uc = 0;
459 RxCapability.IEEEOUI = 0;
460 getHDMITX_EDIDBlock(handle, 0, EDID_Buf);
461
462 for (i = 0, CheckSum = 0; i < 128U; i++)
463 {
464 CheckSum += EDID_Buf[i];
465 CheckSum &= 0xFFU;
466 }
467 if (CheckSum != 0U)
468 {
469 return 0;
470 }
471 if (EDID_Buf[0] != 0x00U || EDID_Buf[1] != 0xFFU || EDID_Buf[2] != 0xFFU || EDID_Buf[3] != 0xFFU ||
472 EDID_Buf[4] != 0xFFU || EDID_Buf[5] != 0xFFU || EDID_Buf[6] != 0xFFU || EDID_Buf[7] != 0x00U)
473 {
474 return 0;
475 }
476
477 BlockCount = EDID_Buf[0x7E];
478
479 if (BlockCount == 0U)
480 {
481 return 1; // do nothing.
482 }
483 else if (BlockCount > 4U)
484 {
485 BlockCount = 4;
486 }
487 // read all segment for test
488 for (i = 1; i <= BlockCount; i++)
489 {
490 err = (uint8_t)getHDMITX_EDIDBlock(handle, (int32_t)i, EDID_Buf);
491
492 HDMITX_DEBUG_PRINTF("\r\n");
493 for (j = 0; j < 128U; j++)
494 {
495 HDMITX_DEBUG_PRINTF("%02X%c", (int)EDID_Buf[j], ' ');
496 if ((j & 7U) == 7U)
497 {
498 HDMITX_DEBUG_PRINTF("\r\n");
499 }
500 }
501
502 if (err != 0U)
503 {
504 if ((RxCapability.ValidHDMI == 0U) && EDID_Buf[0] == 0x2U && EDID_Buf[1] == 0x3U)
505 {
506 err = (uint8_t)ParseCEAEDID(EDID_Buf);
507 HDMITX_DEBUG_PRINTF("err = %s\n", err ? "SUCCESS" : "FAIL");
508 if (err != 0U)
509 {
510 HDMITX_DEBUG_PRINTF("RxCapability.IEEEOUI = %lx\n", RxCapability.IEEEOUI);
511 }
512 }
513 }
514 }
515 return err;
516 }
517
HDMITX_GetVideoState(display_handle_t * handle)518 static bool HDMITX_GetVideoState(display_handle_t *handle)
519 {
520 uint8_t value = 0U;
521
522 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_STATUS_REG0E, &value);
523
524 return (bool)(HDMI_TX_SYS_STATUS_REG0E_TxVidStable_MASK & value);
525 }
526
HDMITX_CalcRclk(display_handle_t * handle)527 static int32_t HDMITX_CalcRclk(display_handle_t *handle)
528 {
529 uint32_t i = 0;
530 uint32_t sum = 0, RCLKCNT = 0, TimeLoMax = 0, retry = 5;
531 uint8_t value = 0U;
532
533 /* Init CEC */
534 HDMITX_WriteI2C_Byte(handle, HDMI_TX_COLOR_SPACE_CONVERSION_REG8D,
535 (HDMI_TX_COLOR_SPACE_CONVERSION_REG8D_RegCECSlvAdr(HDMI_TX_CEC_SLAVE_ADDR) |
536 HDMI_TX_COLOR_SPACE_CONVERSION_REG8D_RegEnCRCLK_MASK));
537 delay1ms(10);
538
539 for (i = 0U; i < retry; i++)
540 {
541 HDMITX_CEC_WriteI2C_Byte(handle, 0x09, 1);
542 delay1ms(100);
543 HDMITX_CEC_WriteI2C_Byte(handle, 0x09, 0);
544 HDMITX_CEC_ReadI2C_Byte(handle, 0x47, &value);
545 RCLKCNT = (uint32_t)value;
546 RCLKCNT <<= 8U;
547 HDMITX_CEC_ReadI2C_Byte(handle, 0x46, &value);
548 RCLKCNT |= (uint32_t)value;
549 RCLKCNT <<= 8U;
550 HDMITX_CEC_ReadI2C_Byte(handle, 0x45, &value);
551 RCLKCNT |= (uint32_t)value;
552 sum += RCLKCNT;
553 }
554
555 sum /= retry;
556 RCLKCNT = sum / 1000U;
557 HDMITX_CEC_WriteI2C_Byte(handle, 0x0C, (RCLKCNT & 0xFFU));
558
559 /* Disable CEC */
560 HDMITX_SetI2C_Byte(handle, HDMI_TX_COLOR_SPACE_CONVERSION_REG8D,
561 HDMI_TX_COLOR_SPACE_CONVERSION_REG8D_RegEnCRCLK_MASK,
562 HDMI_TX_COLOR_SPACE_CONVERSION_REG8D_RegEnCRCLK(0x00U));
563
564 it6161.hdmi_tx.rclk = (sum << 4U) / 108U;
565 HDMITX_DEBUG_PRINTF("hdmi tx rclk = %d.%d MHz", it6161.hdmi_tx.rclk / 1000, it6161.hdmi_tx.rclk % 1000);
566
567 TimeLoMax = (sum << 4) / 10U; /* 10*TxRCLK; */
568 if (TimeLoMax > 0x3FFFFU)
569 {
570 TimeLoMax = 0x3FFFFU;
571 }
572 HDMITX_WriteI2C_Byte(handle, 0x47, (TimeLoMax & 0xFFU));
573 HDMITX_WriteI2C_Byte(handle, 0x48, ((TimeLoMax & 0xFF00U) >> 8U));
574 HDMITX_WriteI2C_Byte(handle, 0x49, 0x23);
575
576 return (int32_t)it6161.hdmi_tx.rclk;
577 }
578
HDMITX_CalcPclk(display_handle_t * handle)579 int32_t HDMITX_CalcPclk(display_handle_t *handle)
580 {
581 uint8_t uc = 0U, RCLKFreqSelRead = 0U;
582 int32_t div = 0, i = 0;
583 uint32_t sum = 0, count = 0;
584 uint32_t value = 0U;
585
586 HDMITX_ChangeBank(handle, 0);
587 HDMITX_ReadI2C_Byte(handle, 0x5D, &value);
588 RCLKFreqSelRead = (uint8_t)(value & 0x04U) >> 2U;
589 /* PCLK Count Pre-Test */
590 HDMITX_SetI2C_Byte(handle, 0xD7, 0xF0, 0x80);
591 delay1ms(1);
592 HDMITX_SetI2C_Byte(handle, 0xD7, 0x80, 0x00);
593
594 HDMITX_ReadI2C_Byte(handle, 0xD7, &value);
595 count = value & 0xFU;
596 count <<= 8U;
597 HDMITX_ReadI2C_Byte(handle, 0xD8, &value);
598 count |= value;
599
600 if (RCLKFreqSelRead != 0U)
601 {
602 count <<= 1U;
603 }
604
605 for (div = 7; div > 0; div--)
606 {
607 if (count < (1U << (uint32_t)(11 - div)))
608 {
609 break;
610 }
611 }
612
613 if (div < 0)
614 {
615 div = 0;
616 }
617
618 HDMITX_SetI2C_Byte(handle, 0xD7, 0x70, (uint32_t)div << 4U);
619
620 HDMITX_ReadI2C_Byte(handle, 0xD7, &value);
621 uc = (uint8_t)value & 0x7FU;
622 for (i = 0, sum = 0; i < 100; i++)
623 {
624 HDMITX_WriteI2C_Byte(handle, 0xD7, (uint32_t)uc | 0x80U);
625 delay1ms(1);
626 HDMITX_WriteI2C_Byte(handle, 0xD7, uc);
627
628 HDMITX_ReadI2C_Byte(handle, 0xD7, &value);
629 count = value & 0xFU;
630 count <<= 8U;
631 HDMITX_ReadI2C_Byte(handle, 0xD8, &value);
632 count |= value;
633 if (RCLKFreqSelRead != 0U)
634 {
635 count <<= 1U;
636 }
637 sum += count;
638 }
639 sum /= 100U;
640 count = sum;
641
642 it6161.hdmi_tx.pclk = it6161.hdmi_tx.rclk * 128U / count * 16U; /* 128*16=2048 */
643 it6161.hdmi_tx.pclk *= (uint32_t)(1U << (uint32_t)div);
644
645 HDMITX_DEBUG_PRINTF("hdmi tx pclk = %d.%d MHz", it6161.hdmi_tx.pclk / 1000, it6161.hdmi_tx.pclk % 1000);
646 return (int32_t)it6161.hdmi_tx.pclk;
647 }
648
HDMITX_GetDisplayMode(display_handle_t * handle)649 static void HDMITX_GetDisplayMode(display_handle_t *handle)
650 {
651 int32_t interlaced = 0;
652 uint32_t htotal = 0, hdes = 0, hdee = 0, hsyncw = 0, H2ndVRRise = 0;
653 uint32_t vtotal = 0, vdes = 0, vdee = 0, vdes2nd = 0, vdee2nd = 0;
654 uint32_t VRS2nd = 0;
655 uint8_t rega9 = 0;
656 uint8_t value = 0U;
657
658 HDMITX_CalcRclk(handle);
659 HDMITX_CalcPclk(handle);
660
661 /* enable video timing read back */
662 HDMITX_SetI2C_Byte(handle, 0xA8, 0x08, 0x08);
663 HDMITX_ReadI2C_Byte(handle, 0xa9, &value);
664 rega9 = value;
665 interlaced = (int32_t)((rega9 & 0x04U) >> 2U);
666
667 HDMITX_ReadI2C_Bytes(handle, 0x98, (uint8_t *)&htotal, 2);
668 htotal = htotal & 0x0FFFU;
669 HDMITX_ReadI2C_Bytes(handle, 0x90, (uint8_t *)&hdes, 2);
670 hdes = hdes & 0x0FFFU;
671 HDMITX_ReadI2C_Bytes(handle, 0x92, (uint8_t *)&hdee, 2);
672 hdee = hdee & 0x0FFFU;
673 HDMITX_ReadI2C_Bytes(handle, 0x94, (uint8_t *)&hsyncw, 2);
674 hsyncw = hsyncw & 0x0FFFU;
675
676 HDMITX_ReadI2C_Bytes(handle, 0xA6, (uint8_t *)&vtotal, 2);
677 vtotal = vtotal & 0x0FFFU;
678 HDMITX_ReadI2C_Bytes(handle, 0x9C, (uint8_t *)&vdes, 2);
679 vdes = vdes & 0x0FFFU;
680 HDMITX_ReadI2C_Bytes(handle, 0x9E, (uint8_t *)&vdee, 2);
681 vdee = vdee & 0x0FFFU;
682 if (interlaced != 0)
683 {
684 HDMITX_ReadI2C_Bytes(handle, 0xA2, (uint8_t *)&vdes2nd, 2);
685 vdes2nd &= 0x0FFFU;
686 HDMITX_ReadI2C_Bytes(handle, 0xA4, (uint8_t *)&vdee2nd, 2);
687 vdee2nd &= 0x0FFFU;
688 HDMITX_ReadI2C_Bytes(handle, 0xB1, (uint8_t *)&VRS2nd, 2);
689 VRS2nd &= 0x0FFFU;
690 HDMITX_ReadI2C_Bytes(handle, 0x96, (uint8_t *)&H2ndVRRise, 2);
691 H2ndVRRise &= 0x0FFFU;
692
693 #if HDMITX_DEBUG_PRINTF
694 uint32_t vsyncw2nd = 0, vdew2nd = 0, vfph2nd = 0, vbph2nd = 0;
695 uint8_t value = 0U;
696
697 HDMITX_ReadI2C_Byte(handle, 0xA1, &value);
698 vsyncw2nd = value;
699 vdew2nd = vdee2nd - vdes2nd;
700 vfph2nd = VRS2nd - vdee;
701 vbph2nd = vdes2nd - VRS2nd - vsyncw2nd;
702 HDMITX_DEBUG_PRINTF("vdew2nd = %d\n", vdew2nd);
703 HDMITX_DEBUG_PRINTF("vfph2nd = %d\n", vfph2nd);
704 HDMITX_DEBUG_PRINTF("vbph2nd = %d\n", vbph2nd);
705 HDMITX_DEBUG_PRINTF("VSyncW2nd = %d\n", vsyncw2nd);
706 HDMITX_DEBUG_PRINTF("H2ndVRRise = %d\n", H2ndVRRise);
707 #endif
708 }
709
710 /* disable video timing read back */
711 HDMITX_SetI2C_Byte(handle, 0xA8, 0x08, 0x00);
712 }
713
HDMITX_DisableAviInfoframe(display_handle_t * handle)714 static inline void HDMITX_DisableAviInfoframe(display_handle_t *handle)
715 {
716 HDMITX_ChangeBank(handle, 0);
717 HDMITX_WriteI2C_Byte(handle, HDMI_TX_HDMI_CONTROL_REGCD, 0x00);
718 }
719
HDMITX_EnableAviInfoframe(display_handle_t * handle)720 static inline void HDMITX_EnableAviInfoframe(display_handle_t *handle)
721 {
722 HDMITX_ChangeBank(handle, 0);
723 HDMITX_WriteI2C_Byte(
724 handle, HDMI_TX_HDMI_CONTROL_REGCD,
725 HDMI_TX_HDMI_CONTROL_REGCD_REGPktAVIInfoEn_MASK | HDMI_TX_HDMI_CONTROL_REGCD_REGPktAVIInfoRpt_MASK);
726 }
727
HDMI_AviInfoframeInit(struct hdmi_avi_infoframe * frame)728 void HDMI_AviInfoframeInit(struct hdmi_avi_infoframe *frame)
729 {
730 memset(frame, 0, sizeof(*frame));
731
732 frame->type = HDMI_INFOFRAME_TYPE_AVI;
733 frame->version = 2;
734 frame->length = HDMI_AVI_INFOFRAME_SIZE;
735 }
736
HDMI_SetupAviInfoframe(struct hdmi_avi_infoframe * frame)737 static int32_t HDMI_SetupAviInfoframe(struct hdmi_avi_infoframe *frame)
738 {
739 enum hdmi_picture_aspect picture_aspect = HDMI_PICTURE_ASPECT_NONE;
740 uint8_t vic = 0U;
741
742 if (frame == NULL)
743 {
744 return -1;
745 }
746 HDMI_AviInfoframeInit(frame);
747 frame->pixel_repeat = 0;
748
749 vic = 2;
750
751 frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
752
753 frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
754 frame->itc = 0;
755
756 picture_aspect = HDMI_PICTURE_ASPECT_4_3;
757
758 frame->video_code = vic;
759 frame->picture_aspect = picture_aspect;
760 frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
761 frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN;
762
763 return 0;
764 }
765
HDMI_InfoframeChecksum(void * buffer,int32_t size)766 uint8_t HDMI_InfoframeChecksum(void *buffer, int32_t size)
767 {
768 uint8_t csum = 0;
769 uint8_t *ptr = buffer;
770 int32_t i = 0;
771
772 /* compute checksum */
773 for (i = 0; i < size; i++)
774 {
775 csum += ptr[i];
776 }
777 return (uint8_t)(256U - csum);
778 }
779
HDMI_InfoframeSetChecksum(void * buffer,int32_t size)780 void HDMI_InfoframeSetChecksum(void *buffer, int32_t size)
781 {
782 uint8_t *ptr = buffer;
783
784 ptr[3] = HDMI_InfoframeChecksum(buffer, size);
785 }
786
HDMI_AviInfoframePack(struct hdmi_avi_infoframe * frame,void * buffer,int32_t size)787 int32_t HDMI_AviInfoframePack(struct hdmi_avi_infoframe *frame, void *buffer, int32_t size)
788 {
789 int32_t length = 0;
790 uint8_t *ptr = buffer;
791
792 if (frame->type != HDMI_INFOFRAME_TYPE_AVI || frame->version != 2U || frame->length != HDMI_AVI_INFOFRAME_SIZE)
793 {
794 return -1;
795 }
796 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
797
798 if (size < length)
799 {
800 return -1;
801 }
802
803 memset(buffer, 0, (uint32_t)size);
804
805 ptr[0] = (uint8_t)frame->type;
806 ptr[1] = frame->version;
807 ptr[2] = frame->length;
808 ptr[3] = 0; /* checksum */
809
810 /* start infoframe payload */
811 ptr += HDMI_INFOFRAME_HEADER_SIZE;
812
813 ptr[0] = (((uint8_t)frame->colorspace & 0x3U) << 5U) | ((uint8_t)frame->scan_mode & 0x3U);
814
815 /* Data byte 1, bit 4 has to be set if we provide the active format aspect ratio */
816 if (((uint8_t)(frame->active_aspect) & 0xFU) != 0U)
817 {
818 ptr[0] |= BIT(4);
819 }
820
821 /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
822 if ((bool)frame->top_bar || (bool)frame->bottom_bar)
823 {
824 ptr[0] |= BIT(3);
825 }
826
827 if ((bool)frame->left_bar || (bool)frame->right_bar)
828 {
829 ptr[0] |= BIT(2);
830 }
831
832 ptr[1] = (((uint8_t)frame->colorimetry & 0x3U) << 6U) | (((uint8_t)frame->picture_aspect & 0x3U) << 4U) |
833 ((uint8_t)frame->active_aspect & 0xFU);
834
835 ptr[2] = (((uint8_t)frame->extended_colorimetry & 0x7U) << 4U) |
836 (((uint8_t)frame->quantization_range & 0x3U) << 2U) | ((uint8_t)frame->nups & 0x3U);
837
838 if (frame->itc)
839 {
840 ptr[2] |= BIT(7);
841 }
842
843 ptr[3] = frame->video_code & 0x7FU;
844
845 ptr[4] = (((uint8_t)frame->ycc_quantization_range & 0x3U) << 6U) | (((uint8_t)frame->content_type & 0x3U) << 2U) |
846 ((uint8_t)frame->pixel_repeat & 0xFU);
847
848 ptr[5] = (uint8_t)(frame->top_bar & 0xFFU);
849 ptr[6] = (uint8_t)((frame->top_bar >> 8U) & 0xFFU);
850 ptr[7] = (uint8_t)(frame->bottom_bar & 0xFFU);
851 ptr[8] = (uint8_t)((frame->bottom_bar >> 8U) & 0xFFU);
852 ptr[9] = (uint8_t)(frame->left_bar & 0xFFU);
853 ptr[10] = (uint8_t)((frame->left_bar >> 8U) & 0xFFU);
854 ptr[11] = (uint8_t)(frame->right_bar & 0xFFU);
855 ptr[12] = (uint8_t)((frame->right_bar >> 8U) & 0xFFU);
856
857 HDMI_InfoframeSetChecksum(buffer, length);
858
859 return length;
860 }
861
HDMITX_AviInfoframeSet(display_handle_t * handle)862 static int32_t HDMITX_AviInfoframeSet(display_handle_t *handle)
863 {
864 struct hdmi_avi_infoframe *frame = &it6161.source_avi_infoframe;
865 uint8_t buf[32] = {0U}, i = 0U, *ptr = NULL;
866 int32_t ret = 0;
867
868 HDMITX_DEBUG_PRINTF("avinfo set\n");
869 HDMITX_DisableAviInfoframe(handle);
870
871 ret = HDMI_SetupAviInfoframe(frame);
872 if (ret != 0)
873 {
874 HDMITX_DEBUG_PRINTF("Failed to setup AVI infoframe: %d", ret);
875 return ret;
876 }
877 if ((it6161.hdmi_tx.output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_RGB444)
878 {
879 frame->colorspace = HDMI_COLORSPACE_RGB;
880 }
881 if ((it6161.hdmi_tx.output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_YUV444)
882 {
883 frame->colorspace = HDMI_COLORSPACE_YUV444;
884 }
885 if ((it6161.hdmi_tx.output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_YUV422)
886 {
887 frame->colorspace = HDMI_COLORSPACE_YUV422;
888 }
889 ret = HDMI_AviInfoframePack(&it6161.source_avi_infoframe, buf, (int32_t)sizeof(buf));
890 if (ret < 0)
891 {
892 HDMITX_DEBUG_PRINTF("Failed to pack AVI infoframe: %d", ret);
893 return ret;
894 }
895
896 /* fill PB */
897 HDMITX_ChangeBank(handle, 1);
898 ptr = buf + HDMI_INFOFRAME_HEADER_SIZE;
899 for (i = 0; i < it6161.source_avi_infoframe.length; i++)
900 {
901 HDMITX_WriteI2C_Byte(handle, (uint32_t)HDMI_TX_AVIINFO_DB1 + (uint32_t)i, ptr[i]);
902 }
903 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AVIINFO_SUM, buf[3]);
904
905 /* Enable */
906 HDMITX_EnableAviInfoframe(handle);
907
908 return 0;
909 }
910
HDMI_AudioInfoframePack(struct hdmi_audio_infoframe * frame,void * buffer,int32_t size)911 int32_t HDMI_AudioInfoframePack(struct hdmi_audio_infoframe *frame, void *buffer, int32_t size)
912 {
913 int32_t length = 0;
914 uint8_t channels = 0U;
915 uint8_t *ptr = buffer;
916
917 if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO || frame->version != 1U || frame->length != HDMI_AUDIO_INFOFRAME_SIZE)
918 {
919 return -1;
920 }
921
922 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
923 if (size < length)
924 {
925 return -1;
926 }
927
928 memset(buffer, 0, (uint32_t)size);
929
930 if (frame->channels >= 2U)
931 {
932 channels = frame->channels - 1U;
933 }
934 else
935 {
936 channels = 0;
937 }
938
939 ptr[0] = (uint8_t)frame->type;
940 ptr[1] = frame->version;
941 ptr[2] = frame->length;
942 ptr[3] = 0; /* checksum */
943
944 /* start infoframe payload */
945 ptr += HDMI_INFOFRAME_HEADER_SIZE;
946
947 ptr[0] = (((uint8_t)frame->coding_type & 0xFU) << 4U) | (channels & 0x7U);
948 ptr[1] = (((uint8_t)frame->sample_frequency & 0x7U) << 2U) | ((uint8_t)frame->sample_size & 0x3U);
949 ptr[2] = (uint8_t)frame->coding_type_ext & 0x1FU;
950 ptr[3] = (uint8_t)frame->channel_allocation;
951 ptr[4] = ((uint8_t)frame->level_shift_value & 0xFU) << 3U;
952
953 if (frame->downmix_inhibit)
954 {
955 ptr[4] |= BIT(7);
956 }
957
958 HDMI_InfoframeSetChecksum(buffer, length);
959
960 return length;
961 }
962
HDMITX_AudioInfoframeSet(display_handle_t * handle,uint8_t channels)963 static void HDMITX_AudioInfoframeSet(display_handle_t *handle, uint8_t channels)
964 {
965 struct hdmi_audio_infoframe frame;
966 uint8_t buf[16] = {0U};
967 int32_t ret = 0;
968
969 memset((void *)&frame, 0, sizeof(frame));
970 frame.channels = channels;
971 frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
972
973 ret = HDMI_AudioInfoframePack(&frame, buf, (int32_t)sizeof(buf));
974 if (ret < 0)
975 {
976 HDMITX_DEBUG_PRINTF("failed to pack audio infoframe: %d\n", ret);
977 return;
978 }
979
980 /* set audio Data byte */
981 HDMITX_ChangeBank(handle, 1);
982 HDMITX_WriteI2C_Byte(handle, HDMI_TX_PKT_AUDINFO_SUM, buf[3]);
983 HDMITX_WriteI2C_Byte(handle, HDMI_TX_PKT_AUDINFO_CC, buf[4]);
984 HDMITX_WriteI2C_Byte(handle, HDMI_TX_PKT_AUDINFO_SF, buf[5]);
985 HDMITX_WriteI2C_Byte(handle, HDMI_TX_PKT_AUDINFO_CA, buf[7]);
986 HDMITX_WriteI2C_Byte(handle, HDMI_TX_PKT_AUDINFO_DM_LSV, buf[8]);
987
988 /* Enable Audio info frame */
989 HDMITX_ChangeBank(handle, 0);
990 HDMITX_WriteI2C_Byte(
991 handle, HDMI_TX_HDMI_CONTROL_REGCE,
992 HDMI_TX_HDMI_CONTROL_REGCE_REGPktAudInfoEn_MASK | HDMI_TX_HDMI_CONTROL_REGCE_REGPktAudInfoRpt_MASK);
993 }
994
setHDMITX_ChStat(display_handle_t * handle,uint8_t ucIEC60958ChStat[])995 static void setHDMITX_ChStat(display_handle_t *handle, uint8_t ucIEC60958ChStat[])
996 {
997 uint8_t uc = 0U;
998
999 HDMITX_ChangeBank(handle, 1);
1000 uc = (ucIEC60958ChStat[0] << 1U) & 0x7CU;
1001 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_MODE, uc);
1002 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_CAT, ucIEC60958ChStat[1]);
1003 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_SRCNUM, (uint32_t)ucIEC60958ChStat[2] & 0xFU);
1004 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUD0CHST_CHTNUM, ((uint32_t)ucIEC60958ChStat[2] >> 4U) & 0xFU);
1005 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_CA_FS, ucIEC60958ChStat[3]);
1006 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_OFS_WL, ucIEC60958ChStat[4]);
1007 HDMITX_ChangeBank(handle, 0);
1008 }
1009
setHDMITX_LPCMAudio(display_handle_t * handle,uint8_t AudioSrcNum,uint8_t AudSWL,uint8_t bAudInterface)1010 static void setHDMITX_LPCMAudio(display_handle_t *handle, uint8_t AudioSrcNum, uint8_t AudSWL, uint8_t bAudInterface)
1011 {
1012 uint8_t AudioEnable = 0, AudioFormat = 0, bTDMSetting = 0U;
1013
1014 switch (AudSWL)
1015 {
1016 case 16:
1017 AudioEnable |= HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_16bits;
1018 break;
1019 case 18:
1020 AudioEnable |= HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_18bits;
1021 break;
1022 case 20:
1023 AudioEnable |= HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_20bits;
1024 break;
1025 case 24:
1026 default:
1027 AudioEnable |= HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits;
1028 break;
1029 }
1030 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1031 {
1032 AudioFormat &= (uint8_t)~0x40U; /* not full packet mode */
1033 AudioEnable |=
1034 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF | HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0;
1035 }
1036 else
1037 {
1038 AudioFormat |= 0x40U; /* full packet mode */
1039 switch (AudioSrcNum)
1040 {
1041 case 4:
1042 AudioEnable |= HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_3 |
1043 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_2 |
1044 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_1 |
1045 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0;
1046 break;
1047
1048 case 3:
1049 AudioEnable |= 2U | HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_1 |
1050 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0;
1051 break;
1052
1053 case 2:
1054 AudioEnable |= 1U | HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0;
1055 break;
1056
1057 case 1:
1058 default:
1059 AudioFormat &= (uint8_t)~0x40U;
1060 AudioEnable |= 0U;
1061 break;
1062 }
1063 }
1064 AudioFormat |= 0x01U;
1065 it6161.hdmi_tx.bAudioChannelEnable = AudioEnable;
1066
1067 HDMITX_ChangeBank(handle, 0);
1068 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, (uint32_t)AudioEnable & 0xF0U);
1069
1070 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE1, AudioFormat);
1071 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE2, 0xE4);
1072
1073 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1074 {
1075 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE3, HDMI_TX_AUDIO_CHANNEL_REGE3_REGChStSel_MASK);
1076 }
1077 else
1078 {
1079 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE3, 0);
1080 }
1081 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE4, 0x00);
1082 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, 0x00);
1083
1084 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1085 {
1086 uint8_t i = 0U, value = 0U;
1087
1088 HDMITX_SetI2C_Byte(handle, 0x5c, (1U << 6U), (1U << 6U));
1089 for (i = 0; i < 100U; i++)
1090 {
1091 HDMITX_ReadI2C_Byte(handle, HDMI_TX_CLOCK_CONTROL_REG5F, &value);
1092 if ((value & HDMI_TX_CLOCK_CONTROL_REG5F_OSFreqLock_MASK) != 0U)
1093 {
1094 break; /* stable clock. */
1095 }
1096 }
1097 }
1098 else
1099 {
1100 HDMITX_ReadI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, &bTDMSetting);
1101 if (bAudInterface == (uint8_t)AUDIO_IF_TDM)
1102 {
1103 bTDMSetting |= HDMI_TX_AUDIO_CHANNEL_REGE5_RegEnTDM_MASK;
1104 bTDMSetting &= 0x9FU;
1105 bTDMSetting |= (AudioSrcNum - 1U) << 5U;
1106 }
1107 else
1108 {
1109 bTDMSetting &= (uint8_t)~HDMI_TX_AUDIO_CHANNEL_REGE5_RegEnTDM_MASK;
1110 }
1111
1112 /* 1 channel NLPCM, no TDM mode. */
1113 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, bTDMSetting);
1114 }
1115 }
1116
setHDMITX_NLPCMAudio(display_handle_t * handle,uint8_t bAudInterface)1117 static void setHDMITX_NLPCMAudio(display_handle_t *handle, uint8_t bAudInterface)
1118 {
1119 uint8_t AudioEnable = 0U;
1120 uint8_t i = 0U, value = 0U;
1121
1122 /* NLPCM must use standard I2S mode. */
1123 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1124 {
1125 AudioEnable = HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits | HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF;
1126 }
1127 else
1128 {
1129 AudioEnable = HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits;
1130 }
1131
1132 HDMITX_ChangeBank(handle, 0);
1133 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, AudioEnable);
1134 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE1, 0x01);
1135 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE2, 0xE4);
1136 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE3, HDMI_TX_AUDIO_CHANNEL_REGE3_REGChStSel_MASK);
1137 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE4, 0x00);
1138 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, 0x00);
1139
1140 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1141 {
1142 for (i = 0; i < 100U; i++)
1143 {
1144 HDMITX_ReadI2C_Byte(handle, HDMI_TX_CLOCK_CONTROL_REG5F, &value);
1145 if ((value & HDMI_TX_CLOCK_CONTROL_REG5F_OSFreqLock_MASK) != 0U)
1146 {
1147 break;
1148 }
1149 }
1150 }
1151 else
1152 {
1153 HDMITX_ReadI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, &value);
1154 value &= (uint8_t)~HDMI_TX_AUDIO_CHANNEL_REGE5_RegEnTDM_MASK;
1155 /* 2 channel NLPCM, no TDM mode. */
1156 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, value);
1157 }
1158 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, (uint32_t)AudioEnable | 0U);
1159 }
1160
setHDMITX_HBRAudio(display_handle_t * handle,uint8_t bAudInterface)1161 static void setHDMITX_HBRAudio(display_handle_t *handle, uint8_t bAudInterface)
1162 {
1163 HDMITX_ChangeBank(handle, 0);
1164
1165 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE1, 0x47);
1166 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE2, 0xE4);
1167
1168 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1169 {
1170 HDMITX_WriteI2C_Byte(
1171 handle, HDMI_TX_AUDIO_CHANNEL_REGE0,
1172 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits | HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF);
1173 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE3, HDMI_TX_AUDIO_CHANNEL_REGE3_REGChStSel_MASK);
1174 }
1175 else
1176 {
1177 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits);
1178 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE3, 0);
1179 }
1180 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE4, 0x08);
1181 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, HDMI_TX_AUDIO_CHANNEL_REGE5_RegAudHBR_MASK);
1182
1183 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1184 {
1185 uint8_t i = 0U, value = 0U;
1186
1187 for (i = 0; i < 100U; i++)
1188 {
1189 HDMITX_ReadI2C_Byte(handle, HDMI_TX_CLOCK_CONTROL_REG5F, &value);
1190 if ((value & HDMI_TX_CLOCK_CONTROL_REG5F_OSFreqLock_MASK) != 0U)
1191 {
1192 break;
1193 }
1194 }
1195 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0,
1196 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits |
1197 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF |
1198 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0);
1199 }
1200 else
1201 {
1202 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0,
1203 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits | 3U |
1204 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_2 | 1U |
1205 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0);
1206 }
1207 HDMITX_SetI2C_Byte(handle, 0x5c, 1U << 6U, 0x00);
1208 HDMITX_ReadI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, &it6161.hdmi_tx.bAudioChannelEnable);
1209 }
1210
setHDMITX_DSDAudio(display_handle_t * handle)1211 static void setHDMITX_DSDAudio(display_handle_t *handle)
1212 {
1213 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE1, 0x41);
1214 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE2, 0xE4);
1215 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits);
1216 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE3, 0);
1217 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE4, 0x00);
1218 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, HDMI_TX_AUDIO_CHANNEL_REGE5_Reg1BAud_MASK);
1219
1220 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0,
1221 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSWL_24bits | 3U |
1222 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_2 |
1223 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_1 |
1224 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudioEn_Enable_Audio_Source_0);
1225 }
1226
setHDMITX_NCTS(display_handle_t * handle,uint8_t Fs)1227 static void setHDMITX_NCTS(display_handle_t *handle, uint8_t Fs)
1228 {
1229 uint32_t n = 0U, LastCTS = 0;
1230 bool HBR_mode = false;
1231 uint8_t value = 0U;
1232
1233 HDMITX_ReadI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE5, &value);
1234 if ((HDMI_TX_AUDIO_CHANNEL_REGE5_RegAudHBR_MASK & value) != 0U)
1235 {
1236 HBR_mode = true;
1237 }
1238 else
1239 {
1240 HBR_mode = false;
1241 }
1242
1243 switch (Fs)
1244 {
1245 case AUDFS_32KHz:
1246 n = 4096;
1247 break;
1248 case AUDFS_44p1KHz:
1249 n = 6272;
1250 break;
1251 case AUDFS_48KHz:
1252 n = 6144;
1253 break;
1254 case AUDFS_88p2KHz:
1255 n = 12544;
1256 break;
1257 case AUDFS_96KHz:
1258 n = 12288;
1259 break;
1260 case AUDFS_176p4KHz:
1261 n = 25088;
1262 break;
1263 case AUDFS_192KHz:
1264 n = 24576;
1265 break;
1266 case AUDFS_768KHz:
1267 n = 24576;
1268 break;
1269 default:
1270 n = 6144;
1271 break;
1272 }
1273
1274 HDMITX_ChangeBank(handle, 1);
1275 HDMITX_WriteI2C_Byte(handle, HDMI_TX_REGPktAudN0, n & 0xFFU);
1276 HDMITX_WriteI2C_Byte(handle, HDMI_TX_REGPktAudN1, (n >> 8U) & 0xFFU);
1277 HDMITX_WriteI2C_Byte(handle, HDMI_TX_REGPktAudN2, (n >> 16U) & 0xFU);
1278
1279 HDMITX_WriteI2C_Byte(handle, HDMI_TX_REGPktAudCTS0, LastCTS & 0xFFU);
1280 HDMITX_WriteI2C_Byte(handle, HDMI_TX_REGPktAudCTS1, (LastCTS >> 8U) & 0xFFU);
1281 HDMITX_WriteI2C_Byte(handle, HDMI_TX_REGPktAudCTS2, (LastCTS >> 16U) & 0xFU);
1282 HDMITX_ChangeBank(handle, 0);
1283
1284 HDMITX_WriteI2C_Byte(handle, 0xF8, 0xC3);
1285 HDMITX_WriteI2C_Byte(handle, 0xF8, 0xA5);
1286 /* D[1] = 0, HW auto count CTS */
1287 HDMITX_SetI2C_Byte(handle, HDMI_TX_HDMI_CONTROL_REGC5, HDMI_TX_HDMI_CONTROL_REGC5_REGPktAudNCTSSel_MASK, 0x00);
1288 HDMITX_WriteI2C_Byte(handle, 0xF8, 0xFF);
1289
1290 if (false == HBR_mode)
1291 {
1292 /* LPCM */
1293 uint8_t uData = 0U, value = 0U;
1294
1295 HDMITX_ChangeBank(handle, 1);
1296 Fs = AUDFS_768KHz;
1297 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_CA_FS, 0x00U | (uint32_t)Fs);
1298 /* OFS is the one's complement of FS */
1299 Fs = ~Fs;
1300
1301 HDMITX_ReadI2C_Byte(handle, HDMI_TX_AUDCHST_OFS_WL, &value);
1302 uData = (0x0fU & value);
1303 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDCHST_OFS_WL, ((uint32_t)Fs << 4U) | (uint32_t)uData);
1304 HDMITX_ChangeBank(handle, 0);
1305 }
1306 }
1307
HDMITX_EnableAudioOutput(display_handle_t * handle,uint8_t AudioType,uint8_t bAudInterface,uint32_t SampleFreq,uint8_t ChNum,uint8_t * pIEC60958ChStat)1308 static void HDMITX_EnableAudioOutput(display_handle_t *handle,
1309 uint8_t AudioType,
1310 uint8_t bAudInterface,
1311 uint32_t SampleFreq,
1312 uint8_t ChNum,
1313 uint8_t *pIEC60958ChStat)
1314 {
1315 static uint8_t ucIEC60958ChStat[5] = {0U};
1316 uint8_t Fs = {0U};
1317
1318 it6161.hdmi_tx.bAudioChannelEnable = 0;
1319 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (B_HDMITX_AUD_RST | B_TX_AREF_RST),
1320 (B_HDMITX_AUD_RST | B_TX_AREF_RST));
1321 HDMITX_WriteI2C_Byte(
1322 handle, HDMI_TX_CLOCK_CONTROL_REG58,
1323 HDMI_TX_CLOCK_CONTROL_REG58_REGAutoOSCLK_MASK | HDMI_TX_CLOCK_CONTROL_REG58_REGMCLKFreq_2x128Fs | 0x01U);
1324
1325 /* Power on the TxCLK (for CSC) */
1326 HDMITX_SetI2C_Byte(handle, 0x0F, 0x10, 0x00);
1327
1328 if (bAudInterface == (uint8_t)AUDIO_IF_SPDIF)
1329 {
1330 if (AudioType == (uint8_t)T_AUDIO_HBR)
1331 {
1332 HDMITX_WriteI2C_Byte(handle, HDMI_TX_CLOCK_CONTROL_REG58, 0x81);
1333 }
1334
1335 HDMITX_SetI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF,
1336 HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF);
1337 }
1338 else
1339 {
1340 HDMITX_SetI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, HDMI_TX_AUDIO_CHANNEL_REGE0_REGAudSel_SPDIF, 0x00);
1341 }
1342
1343 if (AudioType != T_AUDIO_DSD)
1344 {
1345 /* one bit audio have no channel status. */
1346 switch (SampleFreq)
1347 {
1348 case 44100L:
1349 Fs = AUDFS_44p1KHz;
1350 break;
1351 case 88200L:
1352 Fs = AUDFS_88p2KHz;
1353 break;
1354 case 176400L:
1355 Fs = AUDFS_176p4KHz;
1356 break;
1357 case 32000L:
1358 Fs = AUDFS_32KHz;
1359 break;
1360 case 48000L:
1361 Fs = AUDFS_48KHz;
1362 break;
1363 case 96000L:
1364 Fs = AUDFS_96KHz;
1365 break;
1366 case 192000L:
1367 Fs = AUDFS_192KHz;
1368 break;
1369 case 768000L:
1370 Fs = AUDFS_768KHz;
1371 break;
1372 default:
1373 SampleFreq = 48000L;
1374 Fs = AUDFS_48KHz;
1375 break;
1376 }
1377
1378 setHDMITX_NCTS(handle, Fs);
1379 if (pIEC60958ChStat == NULL)
1380 {
1381 ucIEC60958ChStat[0] = 0;
1382 ucIEC60958ChStat[1] = 0;
1383 ucIEC60958ChStat[2] = (ChNum + 1U) / 2U;
1384
1385 if (ucIEC60958ChStat[2] < 1U)
1386 {
1387 ucIEC60958ChStat[2] = 1;
1388 }
1389 else if (ucIEC60958ChStat[2] > 4U)
1390 {
1391 ucIEC60958ChStat[2] = 4;
1392 }
1393 ucIEC60958ChStat[3] = Fs;
1394 ucIEC60958ChStat[4] = (((~Fs) << 4U) & 0xF0U) | CHTSTS_SWCODE;
1395 pIEC60958ChStat = ucIEC60958ChStat;
1396 }
1397 }
1398 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (B_HDMITX_AUD_RST | B_TX_AREF_RST), B_TX_AREF_RST);
1399
1400 switch (AudioType)
1401 {
1402 case T_AUDIO_HBR:
1403 HDMITX_DEBUG_PRINTF("T_AUDIO_HBR\n");
1404 pIEC60958ChStat[0] |= 1U << 1U;
1405 pIEC60958ChStat[2] = 0;
1406 pIEC60958ChStat[3] &= 0xF0U;
1407 pIEC60958ChStat[3] |= AUDFS_768KHz;
1408 pIEC60958ChStat[4] |= (((~AUDFS_768KHz) << 4U) & 0xF0U) | 0xBU;
1409 setHDMITX_ChStat(handle, pIEC60958ChStat);
1410 setHDMITX_HBRAudio(handle, bAudInterface);
1411 break;
1412 case T_AUDIO_DSD:
1413 HDMITX_DEBUG_PRINTF("T_AUDIO_DSD\n");
1414 setHDMITX_DSDAudio(handle);
1415 break;
1416 case T_AUDIO_NLPCM:
1417 HDMITX_DEBUG_PRINTF("T_AUDIO_NLPCM\n");
1418 pIEC60958ChStat[0] |= 1U << 1U;
1419 setHDMITX_ChStat(handle, pIEC60958ChStat);
1420 setHDMITX_NLPCMAudio(handle, bAudInterface);
1421 break;
1422 case T_AUDIO_LPCM:
1423 HDMITX_DEBUG_PRINTF("T_AUDIO_LPCM\n");
1424 pIEC60958ChStat[0] &= (uint8_t) ~(1U << 1U);
1425
1426 setHDMITX_ChStat(handle, pIEC60958ChStat);
1427 setHDMITX_LPCMAudio(handle, (ChNum + 1U) / 2U, SUPPORT_AUDI_AudSWL, bAudInterface);
1428 break;
1429 }
1430 HDMITX_SetI2C_Byte(handle, HDMI_TX_INT_MASK_REG09, HDMI_TX_INT_MASK_REG09_REG_AudioOvFlw_MASK, 0x00);
1431 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AUDIO_CHANNEL_REGE0, it6161.hdmi_tx.bAudioChannelEnable);
1432
1433 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (B_HDMITX_AUD_RST | B_TX_AREF_RST), 0);
1434 }
1435
HDMITX_AudioProcess(display_handle_t * handle)1436 static void HDMITX_AudioProcess(display_handle_t *handle)
1437 {
1438 if (it6161.hdmi_tx.support_audio != 0U)
1439 {
1440 HDMITX_DEBUG_PRINTF("%s: %d, it6161.support_audio = 0x%x\n", __func__, __LINE__, it6161.hdmi_tx.support_audio);
1441 HDMITX_AudioInfoframeSet(handle, (uint8_t)it6161.hdmi_tx.output_channel);
1442 HDMITX_EnableAudioOutput(handle, it6161.hdmi_tx.input_audio_type, it6161.hdmi_tx.input_audio_interface,
1443 it6161.hdmi_tx.input_audio_sample_freq, it6161.hdmi_tx.output_channel, NULL);
1444 }
1445 }
1446
HDMITX_SetAvMute(display_handle_t * handle,uint8_t bEnable)1447 static void HDMITX_SetAvMute(display_handle_t *handle, uint8_t bEnable)
1448 {
1449 HDMITX_ChangeBank(handle, 0);
1450 HDMITX_SetI2C_Byte(handle, HDMI_TX_HDMI_CONTROL_REGC1, HDMI_TX_HDMI_CONTROL_REGC1_REGAVMute_MASK,
1451 bEnable != 0U ? HDMI_TX_HDMI_CONTROL_REGC1_REGAVMute_MASK : 0U);
1452 HDMITX_WriteI2C_Byte(
1453 handle, HDMI_TX_HDMI_CONTROL_REGC6,
1454 HDMI_TX_HDMI_CONTROL_REGC6_REGPktGenCtrlEn_MASK | HDMI_TX_HDMI_CONTROL_REGC6_REGPktGenCtrlRpt_MASK);
1455 }
1456
HDMITX_SetupPclkDiv2(display_handle_t * handle)1457 static void HDMITX_SetupPclkDiv2(display_handle_t *handle)
1458 {
1459 if (HDMI_TX_PCLK_DIV2)
1460 {
1461 HDMITX_DEBUG_PRINTF("PCLK Divided by 2 mode");
1462 HDMITX_SetI2C_Byte(handle, HDMI_TX_INPUT_DATA_FORMAT_REG70, HDMI_TX_INPUT_DATA_FORMAT_REG70_Reg_PCLKDiv2_MASK,
1463 HDMI_TX_INPUT_DATA_FORMAT_REG70_Reg_PCLKDiv2_MASK);
1464 }
1465 }
1466
1467 /*************************************************************************
1468 * Function: HDMITX_SetupCsc
1469 * Parameter: input_mode -
1470 * D[1:0] - Color Mode
1471 * D[4] - Colorimetry 0: ITU_BT601 1: ITU_BT709
1472 * D[5] - Quantization 0: 0_255 1: 16_235
1473 * D[6] - Up/Dn Filter 'Required'
1474 * 0: no up/down filter
1475 * 1: enable up/down filter when csc need.
1476 * D[7] - Dither Filter 'Required'
1477 * 0: no dither enabled.
1478 * 1: enable dither and dither free go "when required".
1479 * output_mode -
1480 * D[1:0] - Color mode.
1481 * Return: N/A
1482 * Remark: reg72~reg8D will be programmed depended the input with table
1483 * **********************************************************************/
HDMITX_SetupCsc(display_handle_t * handle)1484 static void HDMITX_SetupCsc(display_handle_t *handle)
1485 {
1486 uint32_t ucData = 0U, csc = 0, i = 0U;
1487 uint8_t filter = 0; /* filter is for Video CTRL DN_FREE_GO,EN_DITHER,and ENUDFILT */
1488 uint8_t input_mode = it6161.hdmi_tx.input_color_space;
1489 uint8_t output_mode = it6161.hdmi_tx.output_color_space;
1490 uint8_t *ptable = NULL;
1491
1492 /* (1) YUV422 in,RGB/YUV444 output (Output is 8-bit,input is 12-bit)
1493 * (2) YUV444/422 in,RGB output (CSC enable,and output is not YUV422)
1494 * (3) RGB in,YUV444 output (CSC enable,and output is not YUV422)
1495 *
1496 * YUV444/RGB24 <-> YUV422 need set up/down filter.
1497 */
1498 HDMITX_DEBUG_PRINTF("hdmi_tx_setup_csc(uint8_t input_mode = %x,uint8_t output_mode = %x)\n", (int)input_mode,
1499 (int)output_mode);
1500
1501 switch (input_mode & F_MODE_CLRMOD_MASK)
1502 {
1503 /* YUV444 INPUT */
1504 case F_MODE_YUV444:
1505 switch (output_mode & F_MODE_CLRMOD_MASK)
1506 {
1507 case F_MODE_YUV444:
1508 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_BYPASS;
1509 break;
1510 case F_MODE_YUV422:
1511 /* YUV444 to YUV422 need up/down filter for processing. */
1512 if ((input_mode & F_VIDMODE_EN_UDFILT) != 0U)
1513 {
1514 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_UDFILTER_MASK;
1515 }
1516 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_BYPASS;
1517 break;
1518 case F_MODE_RGB444:
1519 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_YUV2RGB;
1520 /* YUV444 to RGB24 need dither */
1521 if ((input_mode & F_VIDMODE_EN_DITHER) != 0U)
1522 {
1523 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_DITHER_MASK |
1524 HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_DNFREE_GO_MASK;
1525 }
1526 break;
1527 }
1528
1529 /* YUV422 INPUT */
1530 case F_MODE_YUV422:
1531 switch (output_mode & F_MODE_CLRMOD_MASK)
1532 {
1533 case F_MODE_YUV444:
1534 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_BYPASS;
1535 if ((input_mode & F_VIDMODE_EN_UDFILT) != 0U)
1536 {
1537 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_UDFILTER_MASK;
1538 }
1539 else if ((input_mode & F_VIDMODE_EN_DITHER) != 0U)
1540 {
1541 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_DITHER_MASK |
1542 HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_DNFREE_GO_MASK;
1543 }
1544 break;
1545 case F_MODE_YUV422:
1546 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_BYPASS;
1547 break;
1548 case F_MODE_RGB444:
1549 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_YUV2RGB;
1550 if ((input_mode & F_VIDMODE_EN_UDFILT) != 0U)
1551 {
1552 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_UDFILTER_MASK;
1553 }
1554 else if ((input_mode & F_VIDMODE_EN_DITHER) != 0U)
1555 {
1556 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_DITHER_MASK |
1557 HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_DNFREE_GO_MASK;
1558 }
1559 break;
1560 }
1561
1562 /* RGB444 INPUT */
1563 case F_MODE_RGB444:
1564 switch (output_mode & F_MODE_CLRMOD_MASK)
1565 {
1566 case F_MODE_YUV444:
1567 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_RGB2YUV;
1568 if ((input_mode & F_VIDMODE_EN_DITHER) != 0U)
1569 {
1570 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_DITHER_MASK |
1571 HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_DNFREE_GO_MASK;
1572 }
1573 break;
1574 case F_MODE_YUV422:
1575 if ((input_mode & F_VIDMODE_EN_UDFILT) != 0U)
1576 {
1577 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_UDFILTER_MASK;
1578 }
1579 else if ((input_mode & F_VIDMODE_EN_DITHER) != 0U)
1580 {
1581 filter |= HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_DITHER_MASK |
1582 HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_DNFREE_GO_MASK;
1583 }
1584 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_RGB2YUV;
1585 break;
1586 case F_MODE_RGB444:
1587 csc = HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_BYPASS;
1588 break;
1589 }
1590 }
1591
1592 /* set the CSC metrix registers by colorimetry and quantization */
1593 if (csc == HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_RGB2YUV)
1594 {
1595 switch (input_mode & (F_VIDMODE_ITU709 | F_VIDMODE_16_235))
1596 {
1597 case F_VIDMODE_ITU709 | F_VIDMODE_16_235:
1598 ptable = bCSCMtx_RGB2YUV_ITU709_16_235;
1599 break;
1600 case F_VIDMODE_ITU709 | F_VIDMODE_0_255:
1601 ptable = bCSCMtx_RGB2YUV_ITU709_0_255;
1602 break;
1603 case F_VIDMODE_ITU601 | F_VIDMODE_16_235:
1604 ptable = bCSCMtx_RGB2YUV_ITU601_16_235;
1605 break;
1606 case F_VIDMODE_ITU601 | F_VIDMODE_0_255:
1607 default:
1608 ptable = bCSCMtx_RGB2YUV_ITU601_0_255;
1609 break;
1610 }
1611 }
1612
1613 if (csc == HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_YUV2RGB)
1614 {
1615 switch (input_mode & (F_VIDMODE_ITU709 | F_VIDMODE_16_235))
1616 {
1617 case F_VIDMODE_ITU709 | F_VIDMODE_16_235:
1618 ptable = bCSCMtx_YUV2RGB_ITU709_16_235;
1619 break;
1620 case F_VIDMODE_ITU709 | F_VIDMODE_0_255:
1621 ptable = bCSCMtx_YUV2RGB_ITU709_0_255;
1622 break;
1623 case F_VIDMODE_ITU601 | F_VIDMODE_16_235:
1624 ptable = bCSCMtx_YUV2RGB_ITU601_16_235;
1625 break;
1626 case F_VIDMODE_ITU601 | F_VIDMODE_0_255:
1627 default:
1628 ptable = bCSCMtx_YUV2RGB_ITU601_0_255;
1629 break;
1630 }
1631 }
1632
1633 if (csc == HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_BYPASS)
1634 {
1635 HDMITX_SetI2C_Byte(handle, 0xF, 0x10, 0x10);
1636 }
1637 else
1638 {
1639 if (ptable != NULL)
1640 {
1641 for (i = 0; i < SIZEOF_CSCMTX; i++)
1642 {
1643 HDMITX_WriteI2C_Byte(handle, (uint32_t)HDMI_TX_COLOR_SPACE_CONVERSION_REG73 + (uint32_t)i, ptable[i]);
1644 }
1645 }
1646 HDMITX_SetI2C_Byte(handle, 0xF, 0x10, 0x00);
1647 }
1648
1649 HDMITX_ReadI2C_Byte(handle, HDMI_TX_INPUT_DATA_FORMAT_REG72, &ucData);
1650 ucData &=
1651 ~(HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_CSCSel_MASK | HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_DNFREE_GO_MASK |
1652 HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_DITHER_MASK | HDMI_TX_INPUT_DATA_FORMAT_REG72_Reg_EN_UDFILTER_MASK);
1653 ucData |= filter | csc;
1654
1655 HDMITX_WriteI2C_Byte(handle, HDMI_TX_INPUT_DATA_FORMAT_REG72, ucData);
1656 }
1657
HDMITX_SetupAfe(display_handle_t * handle,uint8_t level)1658 static void HDMITX_SetupAfe(display_handle_t *handle, uint8_t level)
1659 {
1660 HDMITX_WriteI2C_Byte(handle, REG_TX_AFE_DRV_CTRL, B_TX_AFE_DRV_RST);
1661 switch (level)
1662 {
1663 case PCLK_HIGH:
1664 HDMITX_SetI2C_Byte(handle, 0x62, 0x90, 0x80);
1665 HDMITX_SetI2C_Byte(handle, 0x64, 0x89, 0x80);
1666 HDMITX_SetI2C_Byte(handle, 0x68, 0x10, 0x00);
1667 HDMITX_SetI2C_Byte(handle, 0x66, 0x80, 0x80);
1668 break;
1669 default:
1670 HDMITX_SetI2C_Byte(handle, 0x62, 0x90, 0x10);
1671 HDMITX_SetI2C_Byte(handle, 0x64, 0x89, 0x09);
1672 HDMITX_SetI2C_Byte(handle, 0x68, 0x10, 0x10);
1673 break;
1674 }
1675 HDMITX_DEBUG_PRINTF("setup afe: %s", level ? "high" : "low");
1676 }
1677
1678 /* force abort DDC and reset DDC bus */
HDMITX_AbortDdc(display_handle_t * handle)1679 static void HDMITX_AbortDdc(display_handle_t *handle)
1680 {
1681 uint8_t sw_reset = 0U, retry = 2;
1682 uint8_t uc = 0U, timeout = 0U, i = 0U;
1683
1684 HDMITX_DEBUG_PRINTF("ddc abort\n");
1685 /* save the sw reset, ddc master and cp desire setting */
1686 HDMITX_ReadI2C_Byte(handle, HDMI_TX_GENERAL_REG04, &sw_reset);
1687
1688 HDMITX_WriteI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (uint32_t)sw_reset | (uint32_t)B_TX_HDCP_RST_HDMITX);
1689 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK);
1690
1691 /* do abort DDC */
1692 for (i = 0; i < retry; i++)
1693 {
1694 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15, HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_Abort_DDC_CMD);
1695 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15,
1696 HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_GenerateSCL_clock_pulse);
1697
1698 for (timeout = 0; timeout < 200U; timeout++)
1699 {
1700 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG16, &uc);
1701 if ((uc & HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_Done_MASK) != 0U)
1702 {
1703 break;
1704 }
1705
1706 if ((uc & (HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_NoACK_MASK |
1707 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_WaitBus_MASK |
1708 HDMI_TX_SYS_DDC_CTRL_REG16_RDDC_Status_ArbiLose_MASK)) != 0U)
1709 {
1710 HDMITX_DEBUG_PRINTF("HDMITX_AbortDdc Fail by reg16=%02X\n", (int)uc);
1711 break;
1712 }
1713 /* delay 1 ms to stable */
1714 delay1ms(1);
1715 }
1716 }
1717 }
1718
1719 /* DDC master will set to be host */
HDMITX_ClrDdcFifo(display_handle_t * handle)1720 static void HDMITX_ClrDdcFifo(display_handle_t *handle)
1721 {
1722 HDMITX_ChangeBank(handle, 0);
1723 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK);
1724 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG15, HDMI_TX_SYS_DDC_CTRL_REG15_RDDC_Req_DDC_FIFO_clear);
1725 HDMITX_SetI2C_Byte(handle, HDMI_TX_SYS_DDC_CTRL_REG10, HDMI_TX_SYS_DDC_CTRL_REG10_Reg_MasterSel_MASK, 0x00);
1726 }
1727
HDMITX_ClrInt(display_handle_t * handle,uint8_t Reg06,uint8_t Reg07,uint8_t Reg08,uint8_t RegEE)1728 static void HDMITX_ClrInt(display_handle_t *handle, uint8_t Reg06, uint8_t Reg07, uint8_t Reg08, uint8_t RegEE)
1729 {
1730 uint8_t intClear = 0U;
1731
1732 if ((Reg06 & HDMI_TX_INT_FLAGS_REG06_RInt_AudioOvFlwStus_MASK) != 0U)
1733 {
1734 HDMITX_DEBUG_PRINTF("HDMI_TX_INT_FLAGS_REG06_RInt_AudioOvFlwStus_MASK");
1735 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, (B_HDMITX_AUD_RST | B_TX_AREF_RST),
1736 (B_HDMITX_AUD_RST | B_TX_AREF_RST));
1737 HDMITX_SetI2C_Byte(handle, HDMI_TX_GENERAL_REG04, B_HDMITX_AUD_RST | B_TX_AREF_RST, 0x00);
1738 }
1739 else if ((Reg06 & HDMI_TX_INT_FLAGS_REG06_RInt_DDCFIFOErr_MASK) != 0U)
1740 {
1741 HDMITX_DEBUG_PRINTF("DDC FIFO Error");
1742 HDMITX_ClrDdcFifo(handle);
1743 }
1744 else if ((Reg06 & HDMI_TX_INT_FLAGS_REG06_RInt_DDCBusHang_MASK) != 0U)
1745 {
1746 HDMITX_DEBUG_PRINTF("DDC BUS HANG");
1747 HDMITX_AbortDdc(handle);
1748 }
1749
1750 /* clear ext interrupt */
1751 HDMITX_WriteI2C_Byte(handle, 0xEE, RegEE);
1752 HDMITX_WriteI2C_Byte(handle, HDMI_TX_INT_CLEAR_REG0C, 0xFF);
1753 HDMITX_WriteI2C_Byte(handle, HDMI_TX_INT_CLEAR_REG0D, 0xFF);
1754 /* write HDMI_TX_SYS_STATUS_REG0E_Reg_IntActDone_MASK '1' to trigger clear interrupt */
1755 HDMITX_ReadI2C_Byte(handle, HDMI_TX_SYS_STATUS_REG0E, &intClear);
1756 intClear |= HDMI_TX_SYS_STATUS_REG0E_Reg_AudCTSClr_MASK | HDMI_TX_SYS_STATUS_REG0E_Reg_IntActDone_MASK;
1757 HDMITX_WriteI2C_Byte(handle, HDMI_TX_SYS_STATUS_REG0E, intClear);
1758 }
1759
HDMITX_Reg06_Process(display_handle_t * handle,uint8_t Reg06)1760 void HDMITX_Reg06_Process(display_handle_t *handle, uint8_t Reg06)
1761 {
1762 if ((Reg06 & HDMI_TX_INT_FLAGS_REG06_RInt_HPDStus_MASK) != 0U)
1763 {
1764 if (HDMITX_GetSinkHpd(handle))
1765 {
1766 HDMITX_DEBUG_PRINTF("HDMI Cable Plug In");
1767 HDMITX_VideoReset(handle);
1768 ParseEDID(handle);
1769 it6161.hdmi_tx.hdmi_mode = RxCapability.VideoMode;
1770 }
1771 else
1772 {
1773 HDMITX_DEBUG_PRINTF("HDMI Cable Plug Out");
1774 HDMITX_DisableVideoOutput(handle);
1775 }
1776 }
1777 }
1778
HDMITX_FireAfe(display_handle_t * handle)1779 static void HDMITX_FireAfe(display_handle_t *handle)
1780 {
1781 HDMITX_ChangeBank(handle, 0x00U);
1782 HDMITX_WriteI2C_Byte(handle, REG_TX_AFE_DRV_CTRL, 0x00);
1783 }
1784
HDMITX_EnableVideoOutput(display_handle_t * handle,uint8_t level)1785 static void HDMITX_EnableVideoOutput(display_handle_t *handle, uint8_t level)
1786 {
1787 HDMITX_WriteI2C_Byte(handle, REG_TX_SW_RST, B_HDMITX_AUD_RST | B_TX_AREF_RST | B_TX_HDCP_RST_HDMITX);
1788 HDMITX_ChangeBank(handle, 1);
1789 HDMITX_WriteI2C_Byte(handle, HDMI_TX_AVIINFO_DB1, 0x00);
1790 HDMITX_ChangeBank(handle, 0);
1791
1792 if (it6161.hdmi_tx.hdmi_mode != 0U)
1793 {
1794 HDMITX_SetAvMute(handle, 1U);
1795 }
1796
1797 HDMITX_SetupPclkDiv2(handle);
1798 HDMITX_SetupCsc(handle);
1799 HDMITX_WriteI2C_Byte(handle, HDMI_TX_HDMI_CONTROL_REGC0,
1800 it6161.hdmi_tx.hdmi_mode != 0U ? HDMI_TX_HDMI_CONTROL_REGC0_REGHDMIMode_HDMI_MODE :
1801 HDMI_TX_HDMI_CONTROL_REGC0_REGHDMIMode_DVI_MODE);
1802 HDMITX_SetupAfe(handle, level);
1803 HDMITX_FireAfe(handle);
1804 }
1805
HDMITX_SetOutputProcess(display_handle_t * handle)1806 static void HDMITX_SetOutputProcess(display_handle_t *handle)
1807 {
1808 uint8_t level = 0U;
1809 uint32_t TMDSClock = 0U;
1810
1811 TMDSClock = it6161.hdmi_tx.pclk * 1000U * (it6161.source_avi_infoframe.pixel_repeat + 1U);
1812
1813 HDMITX_DEBUG_PRINTF(
1814 "%s: %d, TMDSClock = 0x%x, it6161.hdmi_tx.pclk = 0x%x, it6161.source_avi_infoframe.pixel_repeat = 0x%x\n",
1815 __func__, __LINE__, TMDSClock, it6161.hdmi_tx.pclk, it6161.source_avi_infoframe.pixel_repeat);
1816 HDMITX_DisableAudioOutput(handle);
1817 HDMITX_DisableAviInfoframe(handle);
1818
1819 if (TMDSClock > 80000000U)
1820 {
1821 level = (uint8_t)PCLK_HIGH;
1822 }
1823 else if (TMDSClock > 20000000U)
1824 {
1825 level = (uint8_t)PCLK_MEDIUM;
1826 }
1827 else
1828 {
1829 level = (uint8_t)PCLK_LOW;
1830 }
1831
1832 HDMITX_EnableVideoOutput(handle, level);
1833
1834 /* Power on the TxCLK (for CSC) */
1835 HDMITX_SetI2C_Byte(handle, 0x0F, 0x10, 0x00);
1836 if (it6161.hdmi_tx.hdmi_mode != 0U)
1837 {
1838 HDMITX_AviInfoframeSet(handle);
1839 HDMITX_AudioProcess(handle);
1840 }
1841
1842 HDMITX_SetAvMute(handle, 0U);
1843 }
1844
HDMITX_Reg08_Process(display_handle_t * handle,uint8_t Reg08)1845 void HDMITX_Reg08_Process(display_handle_t *handle, uint8_t Reg08)
1846 {
1847 if ((Reg08 & HDMI_TX_INT_FLAGS_REG08_RInt_VidStableStus_MASK) != 0U)
1848 {
1849 HDMITX_WriteI2C_Byte(handle, HDMI_TX_INT_FLAGS_REG08, Reg08);
1850 if (HDMITX_GetVideoState(handle))
1851 {
1852 HDMITX_GetDisplayMode(handle);
1853
1854 HDMITX_SetOutputProcess(handle);
1855 HDMITX_SetAvMute(handle, 0U);
1856 }
1857 }
1858 }
1859
HDMITX_RegEE_Process(display_handle_t * handle,uint8_t RegEE)1860 void HDMITX_RegEE_Process(display_handle_t *handle, uint8_t RegEE)
1861 {
1862 if (RegEE != 0x00U)
1863 {
1864 HDMITX_DEBUG_PRINTF("%s%s%s%s%s%s%s", (RegEE & 0x40) ? "video parameter change " : "",
1865 (RegEE & 0x20) ? "HDCP Pj check done " : "", (RegEE & 0x10) ? "HDCP Ri check done " : "",
1866 (RegEE & 0x8) ? "DDC bus hang " : "", (RegEE & 0x4) ? "Video input FIFO auto reset " : "",
1867 (RegEE & 0x2) ? "o audio input interrupt " : "",
1868 (RegEE & 0x1) ? "Audio decode error interrupt " : "");
1869 }
1870 }
1871
HDMITX_DevLoopProc(display_handle_t * handle)1872 void HDMITX_DevLoopProc(display_handle_t *handle)
1873 {
1874 uint8_t Reg06 = 0U, Reg07 = 0U, Reg08 = 0U, RegEE = 0U;
1875
1876 HDMITX_ReadI2C_Byte(handle, 0x06, &Reg06);
1877 HDMITX_ReadI2C_Byte(handle, 0x07, &Reg07);
1878 HDMITX_ReadI2C_Byte(handle, 0x08, &Reg08);
1879 HDMITX_ReadI2C_Byte(handle, 0xEE, &RegEE);
1880
1881 if ((Reg06 != 0U) || (Reg07 != 0U) || (Reg08 != 0U))
1882 {
1883 HDMITX_ClrInt(handle, Reg06, Reg07, Reg08, RegEE);
1884 }
1885 HDMITX_Reg06_Process(handle, Reg06);
1886 HDMITX_Reg08_Process(handle, Reg08);
1887 HDMITX_RegEE_Process(handle, RegEE);
1888 DumpHDMITXReg(handle);
1889 }
1890