• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hdmi_core.h"
10 #include "device_resource_if.h"
11 #include "hdf_log.h"
12 #include "hdmi_dispatch.h"
13 #include "osal_mem.h"
14 #include "osal_time.h"
15 #include "securec.h"
16 
17 #define HDF_LOG_TAG hdmi_core_c
18 
HdmiCntlrAllocDev(struct HdmiCntlr * cntlr)19 int32_t HdmiCntlrAllocDev(struct HdmiCntlr *cntlr)
20 {
21     struct HdmiDevice *dev = (struct HdmiDevice *)OsalMemCalloc(sizeof(struct HdmiDevice));
22 
23     if (dev == NULL) {
24         HDF_LOGE("Hdmi alloc dev fail");
25         return HDF_ERR_MALLOC_FAIL;
26     }
27 
28     dev->cntlr = cntlr;
29     cntlr->hdmi = dev;
30     return HDF_SUCCESS;
31 }
32 
HdmiCntlrFreeDev(struct HdmiCntlr * cntlr)33 void HdmiCntlrFreeDev(struct HdmiCntlr *cntlr)
34 {
35     if (cntlr == NULL || cntlr->hdmi == NULL) {
36         return;
37     }
38 
39     OsalMemFree(cntlr->hdmi);
40     cntlr->hdmi = NULL;
41 }
42 
HdmiCecInit(struct HdmiCntlr * cntlr)43 static void HdmiCecInit(struct HdmiCntlr *cntlr)
44 {
45     if (cntlr == NULL) {
46         return;
47     }
48     if (cntlr->cap.baseCap.bits.cec == 0) {
49         HDF_LOGD("not support cec");
50         return;
51     }
52 
53     if (cntlr->cec == NULL) {
54         cntlr->cec = (struct HdmiCec *)OsalMemCalloc(sizeof(struct HdmiCec));
55         if (cntlr->cec == NULL) {
56             HDF_LOGE("cec malloc fail");
57             return;
58         }
59     }
60     HDF_LOGE("HdmiCecInit, success.");
61     cntlr->cec->priv = (void *)cntlr;
62 }
63 
HdmiCecDeinit(struct HdmiCntlr * cntlr)64 static void HdmiCecDeinit(struct HdmiCntlr *cntlr)
65 {
66     if (cntlr == NULL) {
67         return;
68     }
69     if (cntlr->cec != NULL) {
70         OsalMemFree(cntlr->cec);
71         cntlr->cec = NULL;
72     }
73 }
74 
HdmiDdcInit(struct HdmiCntlr * cntlr)75 static void HdmiDdcInit(struct HdmiCntlr *cntlr)
76 {
77     int32_t ret;
78 
79     if (cntlr == NULL) {
80         HDF_LOGE("ddc init: param is invalid");
81         return;
82     }
83     cntlr->ddc.priv = (void *)cntlr;
84     if (cntlr->ddc.init == true) {
85         return;
86     }
87     ret = OsalMutexInit(&(cntlr->ddc.ddcMutex));
88     if (ret != HDF_SUCCESS) {
89         HDF_LOGE("HdmiDdcInit: mutex init fail!");
90         return;
91     }
92     HDF_LOGE("HdmiDdcInit, success.");
93     cntlr->ddc.init = true;
94 }
95 
HdmiDdcDeinit(struct HdmiCntlr * cntlr)96 static void HdmiDdcDeinit(struct HdmiCntlr *cntlr)
97 {
98     if (cntlr == NULL) {
99         HDF_LOGE("ddc init: param is invalid");
100         return;
101     }
102 
103     (void)OsalMutexDestroy(&(cntlr->ddc.ddcMutex));
104     if (memset_s(&(cntlr->ddc), sizeof(struct HdmiDdc), 0, sizeof(struct HdmiDdc)) != EOK) {
105         HDF_LOGE("deinit ddc, memset_s fail.");
106     }
107     cntlr->ddc.priv = NULL;
108     cntlr->ddc.init = false;
109 }
110 
HdmiFrlInit(struct HdmiCntlr * cntlr)111 static void HdmiFrlInit(struct HdmiCntlr *cntlr)
112 {
113     if (cntlr == NULL) {
114         return;
115     }
116     if (cntlr->cap.baseCap.bits.frl == 0) {
117         HDF_LOGD("not support frl");
118         return;
119     }
120 
121     if (cntlr->frl == NULL) {
122         cntlr->frl = (struct HdmiFrl *)OsalMemCalloc(sizeof(struct HdmiFrl));
123         if (cntlr->frl == NULL) {
124             HDF_LOGE("frl malloc fail");
125             return;
126         }
127     }
128     HDF_LOGE("HdmiFrlInit, success.");
129     cntlr->frl->priv = (void *)cntlr;
130 }
131 
HdmiFrlDeinit(struct HdmiCntlr * cntlr)132 static void HdmiFrlDeinit(struct HdmiCntlr *cntlr)
133 {
134     if (cntlr == NULL) {
135         return;
136     }
137     if (cntlr->frl != NULL) {
138         OsalMemFree(cntlr->frl);
139         cntlr->frl = NULL;
140     }
141 }
142 
HdmiHdcpInit(struct HdmiCntlr * cntlr)143 static void HdmiHdcpInit(struct HdmiCntlr *cntlr)
144 {
145     int32_t ret;
146 
147     if (cntlr == NULL) {
148         return;
149     }
150     if (cntlr->cap.baseCap.bits.hdcp == 0) {
151         HDF_LOGD("not support hdcp");
152         return;
153     }
154 
155     if (cntlr->hdcp == NULL) {
156         cntlr->hdcp = (struct HdmiHdcp *)OsalMemCalloc(sizeof(struct HdmiHdcp));
157         if (cntlr->hdcp == NULL) {
158             HDF_LOGE("hdcp malloc fail");
159             return;
160         }
161         ret = OsalMutexInit(&(cntlr->hdcp->hdcpMutex));
162         if (ret != HDF_SUCCESS) {
163             HDF_LOGE("HdmiHdcpInit: mutex init fail!");
164             return;
165         }
166     }
167     HDF_LOGE("HdmiHdcpInit, success.");
168     cntlr->hdcp->priv = (void *)cntlr;
169 }
170 
HdmiHdcpDeinit(struct HdmiCntlr * cntlr)171 static void HdmiHdcpDeinit(struct HdmiCntlr *cntlr)
172 {
173     if (cntlr == NULL) {
174         return;
175     }
176     if (cntlr->hdcp != NULL) {
177         HdmiHdcpClose(cntlr->hdcp);
178         OsalMemFree(cntlr->hdcp);
179         cntlr->hdcp = NULL;
180     }
181 }
182 
HdmiHdrInit(struct HdmiCntlr * cntlr)183 static void HdmiHdrInit(struct HdmiCntlr *cntlr)
184 {
185     if (cntlr == NULL) {
186         return;
187     }
188     if (cntlr->cap.baseCap.bits.hdr == 0) {
189         HDF_LOGD("not support hdr");
190         return;
191     }
192 
193     if (cntlr->hdr == NULL) {
194         cntlr->hdr = (struct HdmiHdr *)OsalMemCalloc(sizeof(struct HdmiHdr));
195         if (cntlr->hdr == NULL) {
196             HDF_LOGE("hdr malloc fail");
197             return;
198         }
199     }
200     HDF_LOGE("HdmiHdrInit, success.");
201     cntlr->hdr->priv = (void *)cntlr;
202 }
203 
HdmiHdrDeinit(struct HdmiCntlr * cntlr)204 static void HdmiHdrDeinit(struct HdmiCntlr *cntlr)
205 {
206     if (cntlr == NULL) {
207         return;
208     }
209     if (cntlr->hdr != NULL) {
210         OsalMemFree(cntlr->hdr);
211         cntlr->hdr = NULL;
212     }
213 }
214 
HdmiInfoFrameInit(struct HdmiCntlr * cntlr)215 static void HdmiInfoFrameInit(struct HdmiCntlr *cntlr)
216 {
217     if (cntlr == NULL) {
218         return;
219     }
220     HDF_LOGE("HdmiInfoFrameInit, success.");
221     cntlr->infoFrame.priv = (void *)cntlr;
222 }
223 
HdmiInfoFrameDeInit(struct HdmiCntlr * cntlr)224 static void HdmiInfoFrameDeInit(struct HdmiCntlr *cntlr)
225 {
226     if (cntlr == NULL) {
227         return;
228     }
229 
230     if (memset_s(&(cntlr->infoFrame), sizeof(struct HdmiInfoFrame), 0, sizeof(struct HdmiInfoFrame)) != EOK) {
231         HDF_LOGE("deinit infoFrame, memset_s fail.");
232     }
233     cntlr->infoFrame.priv = NULL;
234 }
235 
HdmiScdcInit(struct HdmiCntlr * cntlr)236 static void HdmiScdcInit(struct HdmiCntlr *cntlr)
237 {
238     if (cntlr == NULL) {
239         return;
240     }
241     if (cntlr->cap.baseCap.bits.scdc == 0) {
242         HDF_LOGD("not support scdc");
243         return;
244     }
245 
246     if (cntlr->scdc == NULL) {
247         cntlr->scdc = (struct HdmiScdc *)OsalMemCalloc(sizeof(struct HdmiScdc));
248         if (cntlr->scdc == NULL) {
249             HDF_LOGE("scdc malloc fail");
250             return;
251         }
252     }
253     HDF_LOGE("HdmiScdcInit, success.");
254     cntlr->scdc->priv = (void *)cntlr;
255 }
256 
HdmiScdcDeinit(struct HdmiCntlr * cntlr)257 static void HdmiScdcDeinit(struct HdmiCntlr *cntlr)
258 {
259     if (cntlr == NULL) {
260         return;
261     }
262     if (cntlr->scdc != NULL) {
263         OsalMemFree(cntlr->scdc);
264         cntlr->scdc = NULL;
265     }
266 }
267 
HdmiCntlrInit(struct HdmiCntlr * cntlr)268 static int32_t HdmiCntlrInit(struct HdmiCntlr *cntlr)
269 {
270     int32_t ret;
271 
272     if (cntlr == NULL) {
273         return HDF_ERR_INVALID_OBJECT;
274     }
275 
276     if (cntlr->hdfDevObj == NULL) {
277         HDF_LOGE("HdmiCntlrInit: no HdfDeviceObject attached!");
278         return HDF_ERR_INVALID_OBJECT;
279     }
280 
281     ret = OsalMutexInit(&cntlr->mutex);
282     if (ret != HDF_SUCCESS) {
283         HDF_LOGE("HdmiCntlrInit: mutex init fail!");
284         return ret;
285     }
286 
287     cntlr->msgQueue = PlatformQueueCreate(HdmiEventMsgHandleDefault, "PlatformHdmiWorkerThread", cntlr);
288     if (cntlr->msgQueue == NULL) {
289         HDF_LOGE("HdmiCntlrInit: failed to create msg queue!");
290         return HDF_PLT_ERR_OS_API;
291     }
292     ret = PlatformQueueStart(cntlr->msgQueue);
293     if (ret != HDF_SUCCESS) {
294         HDF_LOGE("HdmiCntlrInit: failed to start msg queue!");
295         PlatformQueueDestroy(cntlr->msgQueue);
296         return ret;
297     }
298 
299     cntlr->service.Dispatch = HdmiIoDispatch;
300     cntlr->hdfDevObj->service = &(cntlr->service);
301     cntlr->device.number = (int32_t)cntlr->deviceIndex;
302     cntlr->device.hdfDev = cntlr->hdfDevObj;
303     HdmiInfoFrameInit(cntlr);
304     HdmiDdcInit(cntlr);
305     return HDF_SUCCESS;
306 }
307 
HdmiCntlrUninit(struct HdmiCntlr * cntlr)308 static void HdmiCntlrUninit(struct HdmiCntlr *cntlr)
309 {
310     if (cntlr != NULL) {
311         HdmiInfoFrameDeInit(cntlr);
312         HdmiScdcDeinit(cntlr);
313         HdmiDdcDeinit(cntlr);
314         HdmiCecDeinit(cntlr);
315         HdmiFrlDeinit(cntlr);
316         HdmiHdcpDeinit(cntlr);
317         HdmiCntlrFreeDev(cntlr);
318         (void)OsalMutexDestroy(&cntlr->mutex);
319     }
320 }
321 
HdmiCntlrAdd(struct HdmiCntlr * cntlr)322 int32_t HdmiCntlrAdd(struct HdmiCntlr *cntlr)
323 {
324     int32_t ret;
325 
326     if (cntlr == NULL) {
327         return HDF_ERR_INVALID_OBJECT;
328     }
329 
330     ret = HdmiCntlrInit(cntlr);
331     if (ret != HDF_SUCCESS) {
332         return ret;
333     }
334 
335     cntlr->device.manager = PlatformManagerGet(PLATFORM_MODULE_HDMI);
336     ret = PlatformDeviceAdd(&cntlr->device);
337     if (ret != HDF_SUCCESS) {
338         HDF_LOGE("HdmiCntlrAdd: device add fail!");
339         HdmiCntlrUninit(cntlr);
340         return ret;
341     }
342     return HDF_SUCCESS;
343 }
344 
HdmiCntlrRemove(struct HdmiCntlr * cntlr)345 void HdmiCntlrRemove(struct HdmiCntlr *cntlr)
346 {
347     if (cntlr != NULL) {
348         HdmiCntlrUninit(cntlr);
349         PlatformDeviceDel(&cntlr->device);
350     }
351 }
352 
HdmiCntlrParseVideoCaps(struct HdmiCntlr * cntlr,struct DeviceResourceIface * drsOps,const struct DeviceResourceNode * node)353 static int32_t HdmiCntlrParseVideoCaps(
354     struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps, const struct DeviceResourceNode *node)
355 {
356     int32_t ret;
357 
358     ret = drsOps->GetUint32(node, "maxTmdsClock", &(cntlr->cap.maxTmdsClock), 0);
359     if (ret != HDF_SUCCESS) {
360         HDF_LOGE("HdmiCntlrParseVideoCaps: read maxTmdsClock fail!");
361         return ret;
362     }
363 
364     ret = drsOps->GetUint32(node, "defTmdsClock", &(cntlr->cap.defTmdsClock), 0);
365     if (ret != HDF_SUCCESS) {
366         HDF_LOGE("HdmiCntlrParseVideoCaps: read defTmdsClock fail!");
367         return ret;
368     }
369 
370     ret = drsOps->GetUint32(node, "maxFrlRate", &(cntlr->cap.maxFrlRate), 0);
371     if (ret != HDF_SUCCESS) {
372         HDF_LOGE("HdmiCntlrParseVideoCaps: read maxFrlRate fail!");
373         return ret;
374     }
375 
376     ret = drsOps->GetUint32(node, "videoTiming", &(cntlr->cap.videoTiming), 0);
377     if (ret != HDF_SUCCESS) {
378         HDF_LOGE("HdmiCntlrParseVideoCaps: read videoTiming fail!");
379         return ret;
380     }
381 
382     ret = drsOps->GetUint32(node, "quantization", &(cntlr->cap.quantization), 0);
383     if (ret != HDF_SUCCESS) {
384         HDF_LOGE("HdmiCntlrParseVideoCaps: read quantization fail!");
385         return ret;
386     }
387 
388     ret = drsOps->GetUint32(node, "colorSpace", &(cntlr->cap.colorSpace), 0);
389     if (ret != HDF_SUCCESS) {
390         HDF_LOGE("HdmiCntlrParseVideoCaps: read colorSpace fail!");
391         return ret;
392     }
393 
394     ret = drsOps->GetUint32(node, "colorimetry", &(cntlr->cap.colorimetry), 0);
395     if (ret != HDF_SUCCESS) {
396         HDF_LOGE("HdmiCntlrParseVideoCaps: read colorimetry fail!");
397         return ret;
398     }
399     return HDF_SUCCESS;
400 }
401 
HdmiCntlrParseAudioCaps(struct HdmiCntlr * cntlr,struct DeviceResourceIface * drsOps,const struct DeviceResourceNode * node)402 static int32_t HdmiCntlrParseAudioCaps(
403     struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps, const struct DeviceResourceNode *node)
404 {
405     int32_t ret;
406 
407     ret = drsOps->GetUint32(node, "audioIfType", &(cntlr->cap.audioIfType), 0);
408     if (ret != HDF_SUCCESS) {
409         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioIfType fail!");
410         return ret;
411     }
412     HDF_LOGD("HdmiCntlrParseAudioCaps: audioIfType = %d", cntlr->cap.audioIfType);
413 
414     ret = drsOps->GetUint32(node, "audioBitDepth", &(cntlr->cap.audioBitDepth), 0);
415     if (ret != HDF_SUCCESS) {
416         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioBitDepth fail!");
417         return ret;
418     }
419     HDF_LOGD("HdmiCntlrParseAudioCaps: audioBitDepth = %d", cntlr->cap.audioBitDepth);
420 
421     ret = drsOps->GetUint32(node, "audioSampleRate", &(cntlr->cap.audioSampleRate), 0);
422     if (ret != HDF_SUCCESS) {
423         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioSampleRate fail!");
424         return ret;
425     }
426     HDF_LOGD("HdmiCntlrParseAudioCaps: audioSampleRate = %d", cntlr->cap.audioSampleRate);
427 
428     ret = drsOps->GetUint32(node, "audioChannels", &(cntlr->cap.audioChannels), 0);
429     if (ret != HDF_SUCCESS) {
430         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioChannels fail!");
431         return ret;
432     }
433     HDF_LOGD("HdmiCntlrParseAudioCaps: audioChannels = %d", cntlr->cap.audioChannels);
434     return HDF_SUCCESS;
435 }
436 
HdmiCntlrParseHdrCaps(struct HdmiCntlr * cntlr,struct DeviceResourceIface * drsOps,const struct DeviceResourceNode * node)437 static int32_t HdmiCntlrParseHdrCaps(
438     struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps, const struct DeviceResourceNode *node)
439 {
440     int32_t ret;
441 
442     ret = drsOps->GetUint32(node, "hdrColorimetry", &(cntlr->cap.hdrColorimetry), 0);
443     if (ret != HDF_SUCCESS) {
444         HDF_LOGE("HdmiCntlrParseAudioCaps: read hdrColorimetry fail!");
445         return ret;
446     }
447     HDF_LOGD("HdmiCntlrParseAudioCaps: hdrColorimetry = %d", cntlr->cap.hdrColorimetry);
448 
449     ret = drsOps->GetUint32(node, "hdrUserMode", &(cntlr->cap.hdrUserMode), 0);
450     if (ret != HDF_SUCCESS) {
451         HDF_LOGE("HdmiCntlrParseAudioCaps: read hdrUserMode fail!");
452         return ret;
453     }
454     HDF_LOGD("HdmiCntlrParseAudioCaps: hdrUserMode = %d", cntlr->cap.hdrUserMode);
455     return HDF_SUCCESS;
456 }
457 
HdmiCntlrParse(struct HdmiCntlr * cntlr,struct HdfDeviceObject * obj)458 int32_t HdmiCntlrParse(struct HdmiCntlr *cntlr, struct HdfDeviceObject *obj)
459 {
460     const struct DeviceResourceNode *node = NULL;
461     struct DeviceResourceIface *drsOps = NULL;
462     int32_t ret;
463 
464     if (obj == NULL || cntlr == NULL) {
465         HDF_LOGE("HdmiCntlrParse: input param is NULL.");
466         return HDF_FAILURE;
467     }
468 
469     node = obj->property;
470     if (node == NULL) {
471         HDF_LOGE("HdmiCntlrParse: drs node is NULL.");
472         return HDF_FAILURE;
473     }
474     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
475     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
476         HDF_LOGE("HdmiCntlrParse: invalid drs ops fail!");
477         return HDF_FAILURE;
478     }
479 
480     ret = drsOps->GetUint32(node, "index", &(cntlr->deviceIndex), 0);
481     if (ret != HDF_SUCCESS) {
482         HDF_LOGE("HdmiCntlrParse: read hostId fail!");
483         return ret;
484     }
485 
486     ret = drsOps->GetUint32(node, "cap", &(cntlr->cap.baseCap.data), 0);
487     if (ret != HDF_SUCCESS) {
488         HDF_LOGE("HdmiCntlrParse: read baseCap fail!");
489         return ret;
490     }
491 
492     ret = HdmiCntlrParseVideoCaps(cntlr, drsOps, node);
493     if (ret != HDF_SUCCESS) {
494         HDF_LOGE("HdmiCntlrParse: read video caps fail!");
495         return ret;
496     }
497 
498     ret = HdmiCntlrParseAudioCaps(cntlr, drsOps, node);
499     if (ret != HDF_SUCCESS) {
500         HDF_LOGE("HdmiCntlrParse: read audio caps fail!");
501         return ret;
502     }
503 
504     ret = HdmiCntlrParseHdrCaps(cntlr, drsOps, node);
505     if (ret != HDF_SUCCESS) {
506         HDF_LOGE("HdmiCntlrParse: read hdr caps fail!");
507         return ret;
508     }
509     return HDF_SUCCESS;
510 }
511 
HdmiGetSinkCapability(struct HdmiDevice * hdmi)512 static struct HdmiSinkDeviceCapability *HdmiGetSinkCapability(struct HdmiDevice *hdmi)
513 {
514     if (hdmi == NULL) {
515         return NULL;
516     }
517 
518     if (hdmi->edid.edidPhase == false) {
519         return NULL;
520     }
521     return &(hdmi->edid.sinkCap);
522 }
523 
HdmiCntlrGetSinkEdid(struct HdmiCntlr * cntlr,uint8_t * buffer,uint32_t len)524 int32_t HdmiCntlrGetSinkEdid(struct HdmiCntlr *cntlr, uint8_t *buffer, uint32_t len)
525 {
526     int32_t ret;
527 
528     if (cntlr == NULL) {
529         return HDF_ERR_INVALID_OBJECT;
530     }
531     if (HdmiHpdStatusDelayGet(cntlr) == false) {
532         HDF_LOGE("no hdmi sink device");
533         HdmiCntlrFreeDev(cntlr);
534         return HDF_DEV_ERR_NO_DEVICE;
535     }
536     if (cntlr->hdmi != NULL) {
537         return HdmiEdidGetRaw(&(cntlr->hdmi->edid), buffer, len);
538     }
539 
540     ret = HdmiCntlrAllocDev(cntlr);
541     if (ret != HDF_SUCCESS) {
542         return ret;
543     }
544 
545     ret = HdmiEdidRawDataRead(&(cntlr->hdmi->edid), &(cntlr->ddc));
546     if (ret != HDF_SUCCESS) {
547         HdmiCntlrFreeDev(cntlr);
548         return ret;
549     }
550 
551     if (cntlr->hdmi->edid.edidPhase != true) {
552         (void)HdmiEdidPhase(&(cntlr->hdmi->edid));
553         cntlr->hdmi->edid.edidPhase = true;
554     }
555     return HdmiEdidGetRaw(&(cntlr->hdmi->edid), buffer, len);
556 }
557 
HdmiCntlrModeSelect(struct HdmiCntlr * cntlr)558 static void HdmiCntlrModeSelect(struct HdmiCntlr *cntlr)
559 {
560     enum HdmiTmdsModeType tmdsMode;
561     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
562     struct HdmiScdcScrambleCap scramble = {0};
563     struct HdmiScdcScrambleCap curScramble = {0};
564     int32_t ret;
565 
566     /* support FRL. */
567     if (HdmiFrlSupport(cntlr->frl) == true && cntlr->cap.baseCap.bits.frl > 0) {
568         return;
569     }
570 
571     if (cntlr->cap.baseCap.bits.scdc > 0) {
572         ret = HdmiScdcFillScrambleCap(cntlr->scdc, &scramble, &tmdsMode);
573         if (ret != HDF_SUCCESS) {
574             return;
575         }
576     } else {
577         tmdsMode = (commAttr->enableHdmi == true) ? HDMI_TMDS_MODE_HDMI_1_4 : HDMI_TMDS_MODE_DVI;
578     }
579 
580     cntlr->tmdsMode = tmdsMode;
581     HdmiCntlrTmdsModeSet(cntlr, tmdsMode);
582     HdmiCntlrReset(cntlr);
583 
584     if (cntlr->cap.baseCap.bits.scdc > 0 && HdmiEdidScdcSupport(cntlr->hdmi) == true) {
585         ret = HdmiScdcScrambleGet(cntlr->scdc, &curScramble);
586         if (ret != HDF_SUCCESS) {
587             return;
588         }
589         if (scramble.sinkScramble != curScramble.sinkScramble ||
590             scramble.sourceScramble != curScramble.sourceScramble ||
591             scramble.tmdsBitClockRatio40 != curScramble.tmdsBitClockRatio40) {
592             (void)HdmiScdcScrambleSet(cntlr->scdc, &scramble);
593         }
594     }
595 }
596 
HdmiCommonAttrInit(struct HdmiCntlr * cntlr)597 static void HdmiCommonAttrInit(struct HdmiCntlr *cntlr)
598 {
599     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
600 
601     commAttr->enableHdmi = true;
602     commAttr->enableVideo = true;
603     commAttr->enableAudio = true;
604     commAttr->audio = true;
605     commAttr->avi = true;
606     commAttr->hdcpMode = HDMI_HDCP_MODE_1_4;
607     commAttr->colorSpace = (enum HdmiColorSpace)cntlr->cap.colorSpace;
608     commAttr->quantization = (enum HdmiQuantizationRange)cntlr->cap.quantization;
609 }
610 
HdmiVideoAttrInit(struct HdmiCntlr * cntlr)611 static void HdmiVideoAttrInit(struct HdmiCntlr *cntlr)
612 {
613     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
614     bool colorimetry601;
615 
616     videoAttr->timing = (enum HdmiVideoTiming)cntlr->cap.videoTiming;
617     colorimetry601 = ((videoAttr->timing == HDMI_VIDEO_TIMING_720X480P60) ||
618         (videoAttr->timing == HDMI_VIDEO_TIMING_720X576P50) || (videoAttr->timing == HDMI_VIDEO_TIMING_1440X240P60) ||
619         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60) || (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) ||
620         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576P50) || (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I60));
621 
622     if (videoAttr->timing == HDMI_VIDEO_TIMING_640X480P60) {
623         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
624         videoAttr->aspect = HDMI_PICTURE_ASPECT_4_3;
625     } else if (colorimetry601 == true) {
626         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU601;
627         videoAttr->aspect = HDMI_PICTURE_ASPECT_4_3;
628     } else if (videoAttr->timing <= HDMI_VIDEO_TIMING_4096X2160P120 &&
629         videoAttr->timing >= HDMI_VIDEO_TIMING_4096X2160P24) {
630         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
631         videoAttr->aspect = HDMI_PICTURE_ASPECT_256_135;
632     } else {
633         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
634         videoAttr->aspect = HDMI_PICTURE_ASPECT_16_9;
635     }
636 
637     videoAttr->pixelRepeat = 1;
638     if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 || videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
639         videoAttr->pixelRepeat = 2; // 2 means the number of repetitions for each pixel
640     }
641 
642     if (videoAttr->timing <= HDMI_VIDEO_TIMING_640X480P60) {
643         videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
644     } else {
645         videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
646     }
647 
648     if (videoAttr->timing != HDMI_VIDEO_TIMING_NONE && videoAttr->timing != HDMI_VIDEO_TIMING_640X480P60) {
649         videoAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
650     } else {
651         videoAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
652     }
653 
654     videoAttr->_3dStruct = HDMI_VS_VIDEO_3D_BUTT;
655     videoAttr->activeAspect = HDMI_ACTIVE_FORMAT_ASPECT_PICTURE;
656 }
657 
HdmiAudioAttrInit(struct HdmiCntlr * cntlr)658 static void HdmiAudioAttrInit(struct HdmiCntlr *cntlr)
659 {
660     struct HdmiAudioAttr *audioAttr = &(cntlr->attr.audioAttr);
661 
662     audioAttr->ifType = (enum HdmiAudioInterfaceType)cntlr->cap.audioIfType;
663     audioAttr->bitDepth = (enum HdmiAudioBitDepth)cntlr->cap.audioBitDepth;
664     audioAttr->sampleRate = (enum HdmiSampleRate)cntlr->cap.audioSampleRate;
665     audioAttr->channels = (enum HdmiAudioFormatChannel)cntlr->cap.audioChannels;
666 }
667 
HdmiHdrAttrInit(struct HdmiCntlr * cntlr)668 static void HdmiHdrAttrInit(struct HdmiCntlr *cntlr)
669 {
670     struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
671 
672     hdrAttr->userMode = (enum HdmiHdrUserMode)cntlr->cap.hdrUserMode;
673     hdrAttr->colorimetry = (enum HdmiHdrColormetry)cntlr->cap.hdrColorimetry;
674 }
675 
HdmiAttrInit(struct HdmiCntlr * cntlr)676 static void HdmiAttrInit(struct HdmiCntlr *cntlr)
677 {
678     HdmiCommonAttrInit(cntlr);
679     HdmiVideoAttrInit(cntlr);
680     HdmiAudioAttrInit(cntlr);
681     HdmiHdrAttrInit(cntlr);
682 }
683 
HdmiCntlrOpen(struct HdmiCntlr * cntlr)684 int32_t HdmiCntlrOpen(struct HdmiCntlr *cntlr)
685 {
686     int32_t ret;
687 
688     if (cntlr == NULL) {
689         return HDF_ERR_INVALID_OBJECT;
690     }
691     HdmiInfoFrameInit(cntlr);
692     HdmiDdcInit(cntlr);
693     HdmiScdcInit(cntlr);
694     HdmiFrlInit(cntlr);
695     HdmiHdcpInit(cntlr);
696     HdmiCecInit(cntlr);
697     HdmiHdrInit(cntlr);
698     HdmiAttrInit(cntlr);
699     HdmiCntlrHardWareInit(cntlr);
700     /* HDCP on. */
701     if ((cntlr->cap.baseCap.data & HDMI_CAP_HDCP_MARK) > 0) {
702         ret = HdmiHdcpOpen(cntlr->hdcp);
703         if (ret != HDF_SUCCESS) {
704             HdmiHdcpClose(cntlr->hdcp);
705         }
706     }
707     cntlr->state |= HDMI_CNTLR_STATE_OPEN;
708     return HDF_SUCCESS;
709 }
710 
HdmiCntlrStart(struct HdmiCntlr * cntlr)711 int32_t HdmiCntlrStart(struct HdmiCntlr *cntlr)
712 {
713     if (cntlr == NULL || cntlr->ops == NULL) {
714         return HDF_ERR_INVALID_OBJECT;
715     }
716 
717     HdmiCntlrLowPowerSet(cntlr, false);
718     /* select mode */
719     HdmiCntlrModeSelect(cntlr);
720     HdmiCntlrAvmuteSet(cntlr, false);
721 
722     if (cntlr->cap.baseCap.bits.hdr > 0 && cntlr->cap.baseCap.bits.frl > 0) {
723         HdmiFrlEnable(cntlr->frl, true);
724     } else {
725         /* TMDS Transfer. */
726         if (cntlr->ops->phyOutputEnable != NULL) {
727             HdmiCntlrLock(cntlr);
728             cntlr->ops->phyOutputEnable(cntlr, true);
729             HdmiCntlrUnlock(cntlr);
730         }
731     }
732 
733     HdmiCntlrAudioPathEnable(cntlr, true);
734     HdmiCntlrBlackDataSet(cntlr, false);
735 
736     cntlr->state |= HDMI_CNTLR_STATE_START;
737     return HDF_SUCCESS;
738 }
739 
HdmiCntlrStop(struct HdmiCntlr * cntlr)740 int32_t HdmiCntlrStop(struct HdmiCntlr *cntlr)
741 {
742     if (cntlr == NULL || cntlr->ops == NULL) {
743         return HDF_ERR_INVALID_OBJECT;
744     }
745 
746     HdmiCntlrLock(cntlr);
747     if (cntlr->ops->audioPathEnable != NULL) {
748         cntlr->ops->audioPathEnable(cntlr, false);
749     }
750     if (cntlr->ops->avmuteSet != NULL) {
751         cntlr->ops->avmuteSet(cntlr, true);
752     }
753     if (cntlr->ops->blackDataSet != NULL) {
754         cntlr->ops->blackDataSet(cntlr, true);
755     }
756     HdmiFrlEnable(cntlr->frl, false);
757     if (cntlr->ops->phyOutputEnable != NULL) {
758         cntlr->ops->phyOutputEnable(cntlr, false);
759     }
760     HdmiCntlrUnlock(cntlr);
761 
762     HdmiCntlrLowPowerSet(cntlr, true);
763     cntlr->state = HDMI_CNTLR_STATE_STOP;
764     return HDF_SUCCESS;
765 }
766 
HdmiTmdsClockUpdate(struct HdmiVideoAttr * videoAttr,struct HdmiCommonAttr * commAttr)767 static void HdmiTmdsClockUpdate(struct HdmiVideoAttr *videoAttr, struct HdmiCommonAttr *commAttr)
768 {
769     /*
770      * Video at the default 24-bit color depth is carried at a TMDS clock rate equal to the pixel clock rate.
771      * YCBCB 4:2:0 video is carried at a TMDS clock rate equal to the 1/2 pixel clock rate.
772      */
773     if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR420) {
774         videoAttr->tmdsClock = HDMI_MULTIPLE_0P5(videoAttr->pixelClock);
775         return;
776     }
777 
778     /*
779      * The TMDS clock rate is ibcreased by the ratio of the pixel size to 24-bits:
780      * 24-bit mode: TMDS clock is 1.0 X pixel clock;
781      * 30-bit mode: TMDS clock is 1.25 X pixel clock;
782      * 36-bit mode: TMDS clock is 1.5 X pixel clock;
783      * 48-bit mode: TMDS clock is 2.0 X pixel clock;
784      */
785     videoAttr->tmdsClock = videoAttr->pixelClock;
786     if (commAttr->colorSpace != HDMI_COLOR_SPACE_YCBCR422) {
787         if (commAttr->deepColor == HDMI_DEEP_COLOR_30BITS) {
788             videoAttr->tmdsClock = HDMI_MULTIPLE_1P25(videoAttr->pixelClock);
789         } else if (commAttr->deepColor == HDMI_DEEP_COLOR_36BITS) {
790             videoAttr->tmdsClock = HDMI_MULTIPLE_1P5(videoAttr->pixelClock);
791         } else if (commAttr->deepColor == HDMI_DEEP_COLOR_48BITS) {
792             videoAttr->tmdsClock = HDMI_MULTIPLE_2P0(videoAttr->pixelClock);
793         }
794     } else {
795         if ((commAttr->deepColor != HDMI_DEEP_COLOR_OFF) && (commAttr->deepColor != HDMI_DEEP_COLOR_24BITS)) {
796             HDF_LOGD("Y422 foce deepcolor 8bit");
797             commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
798         }
799         if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 || videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
800             HDF_LOGD("Y422 is not support at pal and ntsc, force adapt to rgb!");
801             commAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
802         }
803     }
804 }
805 
HdmiYcbcr420FormatCheck(struct HdmiSinkDeviceCapability * sinkCap,struct HdmiVideoAttr * videoAttr)806 static bool HdmiYcbcr420FormatCheck(struct HdmiSinkDeviceCapability *sinkCap, struct HdmiVideoAttr *videoAttr)
807 {
808     uint32_t i;
809     enum HdmiVic vic;
810 
811     vic = HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, false);
812     if (vic == HDMI_VIC_NONE) {
813         HDF_LOGD("Y420 not have supported vic.");
814         return false;
815     }
816 
817     for (i = 0; i < sinkCap->y420Cap.SupportY420VicNum; i++) {
818         if (vic == sinkCap->y420Cap.SupportY420Format[i]) {
819             HDF_LOGD("Y420 supported vic is %d.", vic);
820             return true;
821         }
822     }
823 
824     for (i = 0; i < sinkCap->y420Cap.onlySupportY420VicNum; i++) {
825         if (vic == sinkCap->y420Cap.onlySupportY420Format[i]) {
826             HDF_LOGD("Y420 supported vic is %d.", vic);
827             return true;
828         }
829     }
830 
831     HDF_LOGD("Y420 have no supported vic.");
832     return false;
833 }
834 
HdmiColorSpaceCheck(struct HdmiCntlr * cntlr,struct HdmiSinkDeviceCapability * sinkCap,uint32_t maxTmdsClk)835 static int32_t HdmiColorSpaceCheck(
836     struct HdmiCntlr *cntlr, struct HdmiSinkDeviceCapability *sinkCap, uint32_t maxTmdsClk)
837 {
838     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
839     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
840     union HdmiCap *cap = &(cntlr->cap.baseCap);
841     bool supportColorSpace = false;
842 
843     if (videoAttr->pixelClock > maxTmdsClk && commAttr->colorSpace != HDMI_COLOR_SPACE_YCBCR420) {
844         return HDF_ERR_INVALID_PARAM;
845     }
846 
847     switch (commAttr->colorSpace) {
848         case HDMI_COLOR_SPACE_RGB:
849             supportColorSpace = true;
850             if ((sinkCap->colorSpace.rgb444 && cap->bits.rgb444) == false) {
851                 HDF_LOGD("sink or source not support RGB!");
852             }
853             break;
854         case HDMI_COLOR_SPACE_YCBCR422:
855             supportColorSpace = sinkCap->colorSpace.ycbcr422 && cap->bits.ycbcr422;
856             break;
857         case HDMI_COLOR_SPACE_YCBCR444:
858             supportColorSpace = sinkCap->colorSpace.ycbcr444 && cap->bits.ycbcr444;
859             break;
860         case HDMI_COLOR_SPACE_YCBCR420:
861             supportColorSpace = cap->bits.ycbcr420 && HdmiYcbcr420FormatCheck(sinkCap, videoAttr);
862             break;
863         default:
864             HDF_LOGE("unknow color_space = %u!\n", commAttr->colorSpace);
865             break;
866     }
867 
868     if (supportColorSpace != true) {
869         return HDF_ERR_INVALID_PARAM;
870     }
871     return HDF_SUCCESS;
872 }
873 
HdmiDeepColor10bitsCheck(const struct HdmiSinkDeviceCapability * sinkCap,const struct HdmiCommonAttr * commAttr,const union HdmiCap * cap,uint32_t * tmdsClock,bool * supportDeepColor)874 static void HdmiDeepColor10bitsCheck(const struct HdmiSinkDeviceCapability *sinkCap,
875     const struct HdmiCommonAttr *commAttr, const union HdmiCap *cap, uint32_t *tmdsClock, bool *supportDeepColor)
876 {
877     uint32_t tmpTmdsClk = *tmdsClock;
878 
879     switch (commAttr->colorSpace) {
880         case HDMI_COLOR_SPACE_RGB:
881             tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
882             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc30bit && cap->bits.deepColor10bits) ? true : false;
883             break;
884         case HDMI_COLOR_SPACE_YCBCR444:
885             tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
886             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc30bit && cap->bits.deepColor10bits &&
887                                     sinkCap->vsdbInfo.deepColor.dcY444) ?
888                 true :
889                 false;
890             break;
891         case HDMI_COLOR_SPACE_YCBCR420:
892             tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
893             *supportDeepColor = (sinkCap->hfVsdbInfo.dc.dc30bit && cap->bits.deepColor10bits) ? true : false;
894             break;
895         default:
896             /* Y422, ignore deepclr */
897             *supportDeepColor = true;
898             break;
899     }
900     *tmdsClock = tmpTmdsClk;
901 }
902 
HdmiDeepColor12bitsCheck(const struct HdmiSinkDeviceCapability * sinkCap,const struct HdmiCommonAttr * commAttr,const union HdmiCap * cap,uint32_t * tmdsClock,bool * supportDeepColor)903 static void HdmiDeepColor12bitsCheck(const struct HdmiSinkDeviceCapability *sinkCap,
904     const struct HdmiCommonAttr *commAttr, const union HdmiCap *cap, uint32_t *tmdsClock, bool *supportDeepColor)
905 {
906     uint32_t tmpTmdsClk = *tmdsClock;
907 
908     switch (commAttr->colorSpace) {
909         case HDMI_COLOR_SPACE_RGB:
910             tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
911             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc36bit && cap->bits.deepColor12bits) ? true : false;
912             break;
913         case HDMI_COLOR_SPACE_YCBCR444:
914             tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
915             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc36bit && cap->bits.deepColor12bits &&
916                                     sinkCap->vsdbInfo.deepColor.dcY444) ?
917                 true :
918                 false;
919             break;
920         case HDMI_COLOR_SPACE_YCBCR420:
921             tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
922             *supportDeepColor = (sinkCap->hfVsdbInfo.dc.dc36bit && cap->bits.deepColor12bits) ? true : false;
923             break;
924         default:
925             /* Y422, ignore deepclr */
926             *supportDeepColor = true;
927             break;
928     }
929     *tmdsClock = tmpTmdsClk;
930 }
931 
HdmiDeepColorCheck(struct HdmiCntlr * cntlr,struct HdmiSinkDeviceCapability * sinkCap,uint32_t maxTmdsClk)932 static int32_t HdmiDeepColorCheck(
933     struct HdmiCntlr *cntlr, struct HdmiSinkDeviceCapability *sinkCap, uint32_t maxTmdsClk)
934 {
935     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
936     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
937     union HdmiCap *cap = &(cntlr->cap.baseCap);
938     uint32_t tmdsClock = videoAttr->pixelClock;
939     bool supportDeepColor = false;
940 
941     if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR420) {
942         tmdsClock = HDMI_MULTIPLE_0P5(tmdsClock);
943     }
944 
945     switch (commAttr->deepColor) {
946         case HDMI_DEEP_COLOR_30BITS:
947             HdmiDeepColor10bitsCheck(sinkCap, commAttr, cap, &tmdsClock, &supportDeepColor);
948             break;
949         case HDMI_DEEP_COLOR_36BITS:
950             HdmiDeepColor12bitsCheck(sinkCap, commAttr, cap, &tmdsClock, &supportDeepColor);
951             break;
952         default:
953             commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
954             supportDeepColor = true;
955             break;
956     }
957 
958     if (supportDeepColor == false || tmdsClock > maxTmdsClk) {
959         return HDF_ERR_INVALID_PARAM;
960     }
961     videoAttr->tmdsClock = tmdsClock;
962     /* Y422 default 12bit output, deep_color force adapt to 8bit(24bit). */
963     if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR422) {
964         if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 || videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
965             HDF_LOGD("force change colorspace to RGB!");
966             commAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
967         }
968         if ((videoAttr->deepColor != HDMI_DEEP_COLOR_24BITS) && (videoAttr->deepColor != HDMI_DEEP_COLOR_OFF)) {
969             videoAttr->deepColor = HDMI_DEEP_COLOR_OFF;
970             HDF_LOGD("when Y422, deep_color not support 10/12bit!");
971         }
972     }
973     return HDF_SUCCESS;
974 }
975 
HdmiColorBitSelect(struct HdmiCntlr * cntlr)976 static int32_t HdmiColorBitSelect(struct HdmiCntlr *cntlr)
977 {
978     struct HdmiSinkDeviceCapability *sinkCap = NULL;
979     uint32_t maxTmdsClk = 0;
980 
981     /* DVI mode, must set RGB and DEEP_COLOR_OFF */
982     if (cntlr->attr.commAttr.enableHdmi == false) {
983         if (cntlr->attr.commAttr.colorSpace != HDMI_COLOR_SPACE_RGB) {
984             HDF_LOGE("DVI mode, the color space is not RGB!");
985             return HDF_ERR_INVALID_PARAM;
986         }
987         cntlr->attr.commAttr.deepColor = HDMI_DEEP_COLOR_OFF;
988         cntlr->attr.videoAttr.tmdsClock = cntlr->attr.videoAttr.pixelClock;
989         return HDF_SUCCESS;
990     }
991 
992     /* FRL mode. */
993     if (cntlr->cap.baseCap.bits.hdr > 0) {
994         HdmiTmdsClockUpdate(&(cntlr->attr.videoAttr), &(cntlr->attr.commAttr));
995         if (cntlr->attr.videoAttr.tmdsClock > HDMI_HDMI20_MAX_TMDS_RATE) {
996             HDF_LOGD("HDMI2.1, tmds clock exceed max.");
997             return HDF_SUCCESS;
998         }
999     }
1000 
1001     sinkCap = HdmiGetSinkCapability(cntlr->hdmi);
1002     if (sinkCap == NULL) {
1003         HdmiTmdsClockUpdate(&(cntlr->attr.videoAttr), &(cntlr->attr.commAttr));
1004         return HDF_SUCCESS;
1005     }
1006 
1007     if (sinkCap->maxTmdsClk == 0) {
1008         /* use default clock. */
1009         maxTmdsClk = cntlr->cap.defTmdsClock;
1010     } else {
1011         maxTmdsClk = (sinkCap->maxTmdsClk < cntlr->cap.maxTmdsClock) ? sinkCap->maxTmdsClk : cntlr->cap.maxTmdsClock;
1012     }
1013     /* MHz is converted to KHz */
1014     maxTmdsClk *= 1000;
1015 
1016     if (HdmiColorSpaceCheck(cntlr, sinkCap, maxTmdsClk) != HDF_SUCCESS) {
1017         return HDF_ERR_INVALID_PARAM;
1018     }
1019     if (HdmiDeepColorCheck(cntlr, sinkCap, maxTmdsClk) != HDF_SUCCESS) {
1020         return HDF_ERR_INVALID_PARAM;
1021     }
1022     return HDF_SUCCESS;
1023 }
1024 
HdmiAudioAttrHandle(struct HdmiCntlr * cntlr)1025 static int32_t HdmiAudioAttrHandle(struct HdmiCntlr *cntlr)
1026 {
1027     struct HdmiAudioConfigInfo audioCfg = {0};
1028     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
1029     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
1030     struct HdmiAudioAttr *audioAttr = &(cntlr->attr.audioAttr);
1031     int32_t ret;
1032 
1033     audioCfg.downSample = audioAttr->downSample;
1034     audioCfg.channels = audioAttr->channels;
1035     audioCfg.bitDepth = audioAttr->bitDepth;
1036     audioCfg.sampleRate = audioAttr->sampleRate;
1037     audioCfg.ifType = audioAttr->ifType;
1038     audioCfg.enable = (commAttr->enableAudio) && (commAttr->enableHdmi);
1039     audioCfg.tmdsClock = videoAttr->tmdsClock;
1040     audioCfg.pixelRepeat = videoAttr->pixelRepeat;
1041 
1042     HdmiCntlrAudioPathEnable(cntlr, false);
1043     HdmiCntlrAudioPathSet(cntlr, &audioCfg);
1044     ret = HdmiAudioInfoFrameSend(&(cntlr->infoFrame), ((commAttr->enableAudio) && (commAttr->audio)));
1045     HdmiCntlrAudioPathEnable(cntlr, true);
1046     return ret;
1047 }
1048 
HdmiHdrModeCheck(struct HdmiCommonAttr * commAttr,struct HdmiVideoAttr * videoAttr,const struct HdmiHdrAttr * hdrAttr)1049 static void HdmiHdrModeCheck(
1050     struct HdmiCommonAttr *commAttr, struct HdmiVideoAttr *videoAttr, const struct HdmiHdrAttr *hdrAttr)
1051 {
1052     switch (hdrAttr->userMode) {
1053         case HDMI_HDR_USERMODE_DOLBY:
1054             videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
1055             commAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
1056             videoAttr->tmdsClock = videoAttr->pixelClock;
1057             commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
1058             videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
1059             break;
1060         case HDMI_HDR_USERMODE_HDR10:
1061             if (hdrAttr->mode == HDMI_HDR_MODE_CEA_861_3) {
1062                 if (hdrAttr->colorimetry > HDMI_HDR_COLORIMETRY_EXTENDED) {
1063                     videoAttr->colorimetry = HDMI_COLORIMETRY_EXTENDED;
1064                     videoAttr->extColorimetry =
1065                         (enum HdmiExtendedColorimetry)(hdrAttr->colorimetry - HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601);
1066                 } else {
1067                     videoAttr->colorimetry = (enum HdmiColorimetry)(hdrAttr->colorimetry);
1068                     videoAttr->extColorimetry = HDMI_EXTENDED_COLORIMETRY_BUTT;
1069                 }
1070                 commAttr->xvyccMode = false;
1071             }
1072             break;
1073         default:
1074             break;
1075     }
1076 }
1077 
HdmiFillVideoAttrFromHardwareStatus(struct HdmiVideoAttr * videoAttr,const struct HdmiHardwareStatus * hwStatus,struct HdmiCommonAttr * commAttr)1078 static void HdmiFillVideoAttrFromHardwareStatus(
1079     struct HdmiVideoAttr *videoAttr, const struct HdmiHardwareStatus *hwStatus, struct HdmiCommonAttr *commAttr)
1080 {
1081     bool rgb;
1082     bool aspectIs256;
1083     uint8_t vic;
1084     enum HdmiVsVideoFormat format;
1085     enum Hdmi4kVic vic4k;
1086 
1087     rgb = ((hwStatus->videoStatus.rgb2Ycbcr) ||
1088         ((!hwStatus->videoStatus.ycbcr2Rgb) && (hwStatus->videoStatus.outColorSpace == HDMI_COLOR_SPACE_RGB)));
1089     videoAttr->colorSpace = (rgb == true) ? HDMI_COLOR_SPACE_RGB : HDMI_COLOR_SPACE_YCBCR444;
1090     /*
1091      * avi[0]: Packet Type = 0x82
1092      * avi[1]: Version = 0x02
1093      * avi[2]: BIT[7:5]: 0, BIT[4:0]: Length = 0x0D
1094      * avi[3]: CheckSum
1095      * avi[4]: BIT[7]: Reserved, BIT[6:5]: RGB or YCbCr indicator, BIT[4]: Active information present
1096      *         BIT[3:2]: Bar info data valid, BIT[1:0]: Scan information
1097      * avi[5]: BIT[7:6]: Colorimetry, BIT[5:4]: Picture aspect ratio, BIT[3:0]: Active format aspect ratio
1098      * avi[6]: BIT[7]: IT content, BIT[6:4]: Extended colorimetry, BIT[3:2]: Quantization range,
1099      *         BIT[1:0]: Non-uniform picture scaling
1100      * avi[7]: BIT[7]: Reserved, BIT[6:0]: Video format identification code
1101      * avi[8]: BIT[7:6]: YCC quantization range, BIT[5:4]: Content type, BIT[3:0]: Picture repetition factor
1102      * ...
1103      */
1104     if (hwStatus->infoFrameStatus.aviEnable) {
1105         vic = hwStatus->infoFrameStatus.avi[7];
1106         /*
1107          * when the timing is 4096*2160, the aspect ratio in AVI infoFrame is 0
1108          * (but the real aspect ratio is 256:135<0x04>, the video_code is 0)
1109          * vsif[0]: Packet Type = 0x81
1110          * vsif[1]: Version = 0x01
1111          * vsif[2]: BIT[7:5]: 0, Bit[4:0]: Length, defines the length of HDMI vendor specific infoFrame payload.
1112          * vsif[3]: Checksum.
1113          * vsif[4]--vsif[6]: 24bit IEEE Registration Identifier(0x000C03)(least significant byte first).
1114          * vsif[7]: BIT[7]: reserved for future, BIT[6:5]: HDMI_Video_Format, BIT[4:0]: reserved.
1115          * vsif[8]: HDMI_VIC, 0x04: 4K*2K @24Hz(SMPTE).
1116          */
1117         aspectIs256 = (((vic == 0) && (hwStatus->infoFrameStatus.vsif[8] == 0x04)) ||
1118             ((vic >= HDMI_VIC_4096X2160P25_256_135) && (vic <= HDMI_VIC_4096X2160P60_256_135)));
1119         videoAttr->aspect = (aspectIs256 == true) ? HDMI_PICTURE_ASPECT_256_135 :
1120             ((hwStatus->infoFrameStatus.avi[5] >> 4) & 0x3);                        /* 4'b, BIT[2:1] */
1121         videoAttr->activeAspect = hwStatus->infoFrameStatus.avi[5] & 0xf;
1122         videoAttr->colorimetry = (hwStatus->infoFrameStatus.avi[5] >> 6) & 0x3;     /* 6'b, BIT[2:1] */
1123         videoAttr->quantization = (hwStatus->infoFrameStatus.avi[6] >> 2) & 0x3;    /* 2'b, BIT[2:1] */
1124         videoAttr->extColorimetry = (hwStatus->infoFrameStatus.avi[6] >> 4) & 0x07; /* 4'b, BIT[3:1] */
1125         videoAttr->yccQuantization = (hwStatus->infoFrameStatus.avi[8] >> 6) & 0x3; /* 6'b, BIT[2:1] */
1126         videoAttr->pixelRepeat = (hwStatus->infoFrameStatus.avi[8] & 0xf) + 1;
1127         videoAttr->timing = HdmiCommonGetVideoTiming(vic, videoAttr->aspect);
1128         if ((!hwStatus->infoFrameStatus.vsifEnable) && (!vic)) {
1129             videoAttr->timing = HDMI_VIDEO_TIMING_NONE;
1130         }
1131         commAttr->quantization = (commAttr->colorSpace == HDMI_COLOR_SPACE_RGB) ?
1132             videoAttr->quantization : (videoAttr->yccQuantization + 1);
1133     }
1134 
1135     videoAttr->_3dStruct = HDMI_VS_VIDEO_3D_BUTT;
1136     if (hwStatus->infoFrameStatus.vsifEnable) {
1137         format = (hwStatus->infoFrameStatus.vsif[7] >> 5) & 0x3; /* 5'b, BIT[2:1] */
1138         if (format == HDMI_VS_VIDEO_FORMAT_4K) {
1139             vic4k = hwStatus->infoFrameStatus.vsif[8];
1140             videoAttr->timing = HdmiCommonGetVideo4kTiming(vic4k);
1141         } else if (format == HDMI_VS_VIDEO_FORMAT_3D) {
1142             videoAttr->_3dStruct = (hwStatus->infoFrameStatus.vsif[8] >> 4) & 0xf; /* 4'b, BIT[4:1] */
1143         }
1144     }
1145 }
1146 
HdmiFillCommonAttrFromHardwareStatus(struct HdmiCommonAttr * commAttr,const struct HdmiHardwareStatus * hwStatus,const struct HdmiAttr * attr)1147 static void HdmiFillCommonAttrFromHardwareStatus(
1148     struct HdmiCommonAttr *commAttr, const struct HdmiHardwareStatus *hwStatus, const struct HdmiAttr *attr)
1149 {
1150     bool dolby = false;
1151 
1152     switch (hwStatus->commonStatus.tmdsMode) {
1153         case HDMI_TMDS_MODE_HDMI_1_4:
1154         case HDMI_TMDS_MODE_HDMI_2_0:
1155             commAttr->enableHdmi = true;
1156             commAttr->enableVideo = true;
1157             break;
1158         case HDMI_TMDS_MODE_DVI:
1159             commAttr->enableHdmi = false;
1160             commAttr->enableVideo = true;
1161             break;
1162         default:
1163             commAttr->enableHdmi = false;
1164             commAttr->enableVideo = false;
1165             break;
1166     }
1167 
1168     commAttr->enableAudio = (hwStatus->audioStatus.enable && hwStatus->infoFrameStatus.audioEnable);
1169     commAttr->avi = hwStatus->infoFrameStatus.aviEnable;
1170     commAttr->audio = hwStatus->infoFrameStatus.audioEnable;
1171     commAttr->xvyccMode = hwStatus->infoFrameStatus.gdbEnable;
1172     commAttr->deepColor = HdmiCommonColorDepthConvertToDeepClolor(hwStatus->videoStatus.outBitDepth);
1173 
1174     /* color space is ycbcr444 when the hdr mode is dolby. */
1175     dolby = ((attr->hdrAttr.userMode == HDMI_HDR_USERMODE_DOLBY) && (!hwStatus->videoStatus.rgb2Ycbcr) &&
1176         (!hwStatus->videoStatus.ycbcr2Rgb) && (!hwStatus->videoStatus.ycbcr444422) &&
1177         (!hwStatus->videoStatus.ycbcr422420) && (!hwStatus->videoStatus.ycbcr422444) &&
1178         (!hwStatus->videoStatus.ycbcr420422));
1179     commAttr->colorSpace = (dolby == true) ? HDMI_COLOR_SPACE_YCBCR444 : hwStatus->videoStatus.outColorSpace;
1180 }
1181 
HdmiCommonAttrChanged(struct HdmiCommonAttr * curCommAttr,struct HdmiCommonAttr * commAttr)1182 static bool HdmiCommonAttrChanged(struct HdmiCommonAttr *curCommAttr, struct HdmiCommonAttr *commAttr)
1183 {
1184     bool change;
1185 
1186     change = (commAttr->enableHdmi != curCommAttr->enableHdmi) || (commAttr->colorSpace != curCommAttr->colorSpace) ||
1187         (commAttr->xvyccMode != curCommAttr->xvyccMode) || (commAttr->avi != curCommAttr->avi) ||
1188         (commAttr->quantization != curCommAttr->quantization);
1189 
1190     if (change == true) {
1191         return true;
1192     }
1193 
1194     if (((commAttr->deepColor == HDMI_DEEP_COLOR_OFF) || (commAttr->deepColor == HDMI_DEEP_COLOR_24BITS)) &&
1195         ((curCommAttr->deepColor == HDMI_DEEP_COLOR_OFF) || (curCommAttr->deepColor == HDMI_DEEP_COLOR_24BITS))) {
1196         HDF_LOGI("deep color not change: %u", curCommAttr->deepColor);
1197     } else if (commAttr->deepColor != curCommAttr->deepColor) {
1198         return true;
1199     }
1200     return false;
1201 }
1202 
HdmiVideoAttrChanged(struct HdmiVideoAttr * curVideoAttr,struct HdmiVideoAttr * videoAttr)1203 static bool HdmiVideoAttrChanged(struct HdmiVideoAttr *curVideoAttr, struct HdmiVideoAttr *videoAttr)
1204 {
1205     bool change;
1206 
1207     change = (videoAttr->timing != curVideoAttr->timing) || (videoAttr->colorSpace != curVideoAttr->colorSpace) ||
1208         (videoAttr->_3dStruct != curVideoAttr->_3dStruct) || (videoAttr->pixelRepeat != curVideoAttr->pixelRepeat) ||
1209         (videoAttr->colorimetry != curVideoAttr->colorimetry) ||
1210         (videoAttr->extColorimetry != curVideoAttr->extColorimetry) ||
1211         (videoAttr->quantization != curVideoAttr->quantization) ||
1212         (videoAttr->yccQuantization != curVideoAttr->yccQuantization) || (videoAttr->aspect != curVideoAttr->aspect);
1213     return change;
1214 }
1215 
HdmiVedioAttrHandle(struct HdmiCntlr * cntlr,struct HdmiHardwareStatus * hwStatus)1216 static int32_t HdmiVedioAttrHandle(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *hwStatus)
1217 {
1218     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
1219     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
1220     struct HdmiCommonAttr curCommAttr = {0};
1221     struct HdmiVideoAttr curVideoAttr = {0};
1222     int32_t ret;
1223 
1224     /* support HDR. */
1225     if (cntlr->cap.baseCap.bits.hdr > 0) {
1226         HdmiHdrModeCheck(commAttr, videoAttr, &(cntlr->attr.hdrAttr));
1227     }
1228 
1229     /* support FRL. */
1230     if (cntlr->cap.baseCap.bits.frl > 0) {
1231         ret = HdmiFrlModeSelect(cntlr->frl);
1232         if (ret != HDF_SUCCESS) {
1233             return ret;
1234         }
1235     }
1236 
1237     HdmiFillCommonAttrFromHardwareStatus(&curCommAttr, hwStatus, &(cntlr->attr));
1238     HdmiFillVideoAttrFromHardwareStatus(&curVideoAttr, hwStatus, &curCommAttr);
1239     if (HdmiCommonAttrChanged(&curCommAttr, commAttr) == false &&
1240         HdmiVideoAttrChanged(&curVideoAttr, videoAttr) == false && HdmiFrlModeChanged(cntlr->frl) == false) {
1241         HDF_LOGI("video and common attr is not changed.");
1242         return HDF_SUCCESS;
1243     }
1244 
1245     if (commAttr->enableVideo == true) {
1246         HdmiCntlrVideoPathSet(cntlr, videoAttr);
1247     }
1248 
1249     (void)HdmiAviInfoFrameSend(&(cntlr->infoFrame), (commAttr->enableHdmi && commAttr->avi));
1250     (void)HdmiVsInfoFrameSend(&(cntlr->infoFrame), commAttr->enableHdmi, commAttr->vsifDolby);
1251     /* the drm infoFrame is stop because software was reset in videopath, so re-enable it if the mode is HDR10. */
1252     if (cntlr->cap.baseCap.bits.hdr > 0) {
1253         if (cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_CEA_861_3) {
1254             (void)HdmiDrmInfoFrameSend(&(cntlr->infoFrame), false);
1255             (void)HdmiDrmInfoFrameSend(&(cntlr->infoFrame), true);
1256         }
1257     }
1258     return HDF_SUCCESS;
1259 }
1260 
HdmiAttrUpdate(struct HdmiCntlr * cntlr)1261 static void HdmiAttrUpdate(struct HdmiCntlr *cntlr)
1262 {
1263     struct HdmiHardwareStatus hwStatus = {0};
1264 
1265     if (HdmiColorBitSelect(cntlr) != HDF_SUCCESS) {
1266         HDF_LOGD("attr update: color bit select fail.");
1267         return;
1268     }
1269 
1270     if (cntlr->ops->hardWareStatusGet == NULL) {
1271         return;
1272     }
1273 
1274     HdmiCntlrLock(cntlr);
1275     cntlr->ops->hardWareStatusGet(cntlr, &hwStatus);
1276     HdmiCntlrUnlock(cntlr);
1277 
1278     if (HdmiAudioAttrHandle(cntlr) != HDF_SUCCESS) {
1279         HDF_LOGD("audio attr check fail");
1280         return;
1281     }
1282     if (HdmiVedioAttrHandle(cntlr, &hwStatus) != HDF_SUCCESS) {
1283         HDF_LOGD("vedio attr check fail");
1284     }
1285 }
1286 
HdmiCntlrDeepColorSet(struct HdmiCntlr * cntlr,enum HdmiDeepColor color)1287 int32_t HdmiCntlrDeepColorSet(struct HdmiCntlr *cntlr, enum HdmiDeepColor color)
1288 {
1289     if (cntlr == NULL || cntlr->ops == NULL) {
1290         return HDF_ERR_INVALID_OBJECT;
1291     }
1292 
1293     if (cntlr->attr.commAttr.colorSpace == HDMI_COLOR_SPACE_YCBCR422) {
1294         if (color != HDMI_DEEP_COLOR_24BITS && color != HDMI_DEEP_COLOR_OFF) {
1295             HDF_LOGE("not support deepcolor %u when colorspace is ycbcr422.", color);
1296             return HDF_ERR_INVALID_PARAM;
1297         }
1298     }
1299 
1300     /* if the current hdmi mode is dolby, deep color set is invalid. */
1301     if (cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_DOLBY_NORMAL ||
1302         cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_DOLBY_TUNNELING) {
1303         HDF_LOGD("don't change deepcolor when dolby mode is %u.", cntlr->attr.hdrAttr.mode);
1304         return HDF_ERR_NOT_SUPPORT;
1305     }
1306 
1307     cntlr->attr.commAttr.deepColor = color;
1308     HdmiCntlrAvmuteSet(cntlr, true);
1309     HdmiAttrUpdate(cntlr);
1310     HdmiCntlrAvmuteSet(cntlr, false);
1311     return HDF_SUCCESS;
1312 }
1313 
HdmiCntlrDeepColorGet(struct HdmiCntlr * cntlr,enum HdmiDeepColor * color)1314 int32_t HdmiCntlrDeepColorGet(struct HdmiCntlr *cntlr, enum HdmiDeepColor *color)
1315 {
1316     if (cntlr == NULL || cntlr->ops == NULL) {
1317         return HDF_ERR_INVALID_OBJECT;
1318     }
1319     if (color == NULL) {
1320         return HDF_ERR_INVALID_PARAM;
1321     }
1322 
1323     *color = cntlr->attr.commAttr.deepColor;
1324     return HDF_SUCCESS;
1325 }
1326 
HdmiCntlrSetVideoAttribute(struct HdmiCntlr * cntlr,const struct HdmiVideoAttr * attr)1327 int32_t HdmiCntlrSetVideoAttribute(struct HdmiCntlr *cntlr, const struct HdmiVideoAttr *attr)
1328 {
1329     struct HdmiHardwareStatus hwStatus = {0};
1330 
1331     if (cntlr == NULL || cntlr->ops == NULL) {
1332         return HDF_ERR_INVALID_OBJECT;
1333     }
1334     if (attr == NULL) {
1335         return HDF_ERR_INVALID_PARAM;
1336     }
1337 
1338     cntlr->attr.videoAttr = *attr;
1339 
1340     if (cntlr->ops->hardWareStatusGet == NULL) {
1341         return HDF_ERR_NOT_SUPPORT;
1342     }
1343 
1344     HdmiCntlrLock(cntlr);
1345     cntlr->ops->hardWareStatusGet(cntlr, &hwStatus);
1346     HdmiCntlrUnlock(cntlr);
1347     return HdmiVedioAttrHandle(cntlr, &hwStatus);
1348 }
1349 
HdmiCntlrSetAudioAttribute(struct HdmiCntlr * cntlr,const struct HdmiAudioAttr * attr)1350 int32_t HdmiCntlrSetAudioAttribute(struct HdmiCntlr *cntlr, const struct HdmiAudioAttr *attr)
1351 {
1352     if (cntlr == NULL || cntlr->ops == NULL) {
1353         return HDF_ERR_INVALID_OBJECT;
1354     }
1355     if (attr == NULL) {
1356         return HDF_ERR_INVALID_PARAM;
1357     }
1358 
1359     cntlr->attr.audioAttr = *attr;
1360     return HdmiAudioAttrHandle(cntlr);
1361 }
1362 
HdmiCntlrSetHdrAttribute(struct HdmiCntlr * cntlr,struct HdmiHdrAttr * attr)1363 int32_t HdmiCntlrSetHdrAttribute(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *attr)
1364 {
1365     if (cntlr == NULL || cntlr->ops == NULL) {
1366         return HDF_ERR_INVALID_OBJECT;
1367     }
1368     if (attr == NULL) {
1369         return HDF_ERR_INVALID_PARAM;
1370     }
1371 
1372     return HdmiHdrAttrHandle(cntlr->hdr, attr);
1373 }
1374 
HdmiCntlrInfoFrameGet(struct HdmiCntlr * cntlr,enum HdmiPacketType type,union HdmiInfoFrameInfo * frame)1375 int32_t HdmiCntlrInfoFrameGet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame)
1376 {
1377     if (cntlr == NULL) {
1378         return HDF_ERR_INVALID_OBJECT;
1379     }
1380     return HdmiInfoFrameGetInfo(&(cntlr->infoFrame), type, frame);
1381 }
1382 
HdmiCntlrInfoFrameSet(struct HdmiCntlr * cntlr,enum HdmiPacketType type,union HdmiInfoFrameInfo * frame)1383 int32_t HdmiCntlrInfoFrameSet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame)
1384 {
1385     if (cntlr == NULL || cntlr->ops == NULL) {
1386         return HDF_ERR_INVALID_OBJECT;
1387     }
1388     if (frame == NULL) {
1389         return HDF_ERR_INVALID_PARAM;
1390     }
1391     return HdmiInfoFrameSetInfo(&(cntlr->infoFrame), type, frame);
1392 }
1393 
HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdmiHpdCallbackInfo * callback)1394 int32_t HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdmiHpdCallbackInfo *callback)
1395 {
1396     if (cntlr == NULL) {
1397         return HDF_ERR_INVALID_OBJECT;
1398     }
1399     if (callback == NULL) {
1400         return HDF_ERR_INVALID_PARAM;
1401     }
1402 
1403     cntlr->event.callback.data = callback->data;
1404     cntlr->event.callback.callbackFunc = callback->callbackFunc;
1405     return HDF_SUCCESS;
1406 }
1407 
HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr * cntlr)1408 int32_t HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr *cntlr)
1409 {
1410     if (cntlr == NULL) {
1411         return HDF_ERR_INVALID_OBJECT;
1412     }
1413     cntlr->event.callback.data = NULL;
1414     cntlr->event.callback.callbackFunc = NULL;
1415     return HDF_SUCCESS;
1416 }
1417 
HdmiCntlrClose(struct HdmiCntlr * cntlr)1418 void HdmiCntlrClose(struct HdmiCntlr *cntlr)
1419 {
1420     if (cntlr == NULL || cntlr->ops == NULL) {
1421         return;
1422     }
1423 
1424     if ((cntlr->state & HDMI_CNTLR_STATE_START) > 0) {
1425         HdmiCntlrStop(cntlr);
1426     }
1427 
1428     HdmiInfoFrameDeInit(cntlr);
1429     HdmiDdcDeinit(cntlr);
1430     HdmiScdcDeinit(cntlr);
1431     HdmiFrlDeinit(cntlr);
1432     HdmiHdcpDeinit(cntlr);
1433     HdmiCecDeinit(cntlr);
1434     HdmiHdrDeinit(cntlr);
1435     cntlr->state = HDMI_CNTLR_STATE_CLOSE;
1436 }
1437