• 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_ncts.h"
10 
11 #define HDF_LOG_TAG hdmi_ncts_c
12 #define HDMI_NCTS_KHZ 1000
13 #define HDMI_NCTS_TMDS_PER_PIXEL 10
14 
15 #define HDMI_NCTS_INVALID_VALUE 0xffffffff
16 
17 /*
18  * see hdmi1.4 table 7-1, 7-2, 7-3.
19  * The exact relationship: 128 * fs = tmdsClock * N / CTS.
20  */
21 static struct HdmiAudioNCts g_audioNctsMap[] = {
22     { 32000, 25174, 4576, 28125 },
23     { 32000, 25200, 4096, 25200 },
24     { 32000, 27000, 4096, 27000 },
25     { 32000, 27027, 4096, 27027 },
26     { 32000, 54000, 4096, 54000 },
27     { 32000, 54054, 4096, 54054 },
28     { 32000, 74175, 11648, 210937},
29     { 32000, 74250, 4096, 74250 },
30     { 32000, 148351, 11648, 421875 },
31     { 32000, 148500, 4096, 148500 },
32     { 32000, 296703, 5824, 421875 },
33     { 32000, 297000, 3072, 222750 },
34     { 32000, 593406, 5824, 843750 },
35     { 32000, 594000, 3072, 445500 },
36     { 32000, 0,      4096, 0 },
37     { 44100, 25174, 7007, 31250 },
38     { 44100, 25200, 6272, 28000 },
39     { 44100, 27000, 6272, 30000 },
40     { 44100, 27027, 6272, 30030 },
41     { 44100, 54000, 6272, 60000 },
42     { 44100, 54054, 6272, 60060 },
43     { 44100, 74175, 17836, 234375 },
44     { 44100, 74250, 6272, 82500 },
45     { 44100, 148351, 8918, 234375 },
46     { 44100, 148500, 6272, 165000 },
47     { 44100, 296703, 4459, 234375 },
48     { 44100, 297000, 4704, 247500 },
49     { 44100, 593406, 8918, 937500 },
50     { 44100, 594000, 9408, 990000 },
51     { 44100, 0,      6272, 0 },
52     { 48000, 25174, 6864, 28125 },
53     { 48000, 25200, 6144, 25200 },
54     { 48000, 27000, 6144, 27000 },
55     { 48000, 27027, 6144, 27027 },
56     { 48000, 54000, 6144, 54000 },
57     { 48000, 54054, 6144, 54054 },
58     { 48000, 74175, 11648, 140625 },
59     { 48000, 74250, 6144, 74250 },
60     { 48000, 148351, 5824, 140625 },
61     { 48000, 148500, 6144, 148500 },
62     { 48000, 296703, 5824, 281250 },
63     { 48000, 297000, 5120, 247500 },
64     { 48000, 593406, 5824, 562500 },
65     { 48000, 594000, 6144, 594000 },
66     { 48000, 0,      6144, 0 }
67     };
68 
HdmiGetN(uint32_t sampleRate,uint32_t tmdsClock)69 uint32_t HdmiGetN(uint32_t sampleRate, uint32_t tmdsClock)
70 {
71     uint32_t i;
72 
73     for (i = 0; i < sizeof(g_audioNctsMap) / sizeof(g_audioNctsMap[0]); i++) {
74         if (g_audioNctsMap[i].sampleRate == sampleRate &&
75             g_audioNctsMap[i].tmdsClock == tmdsClock) {
76             return g_audioNctsMap[i].n;
77         }
78         if (g_audioNctsMap[i].sampleRate == sampleRate &&
79             g_audioNctsMap[i].tmdsClock >= (tmdsClock - HDMI_NCTS_TMDS_DEVIATION) &&
80             g_audioNctsMap[i].tmdsClock <= (tmdsClock + HDMI_NCTS_TMDS_DEVIATION)) {
81             return g_audioNctsMap[i].n;
82         }
83         if (g_audioNctsMap[i].sampleRate == sampleRate &&
84             g_audioNctsMap[i].tmdsClock == 0) {
85             return g_audioNctsMap[i].n;
86         }
87     }
88     return HDMI_NCTS_N_DEFAULT;
89 }
90 
HdmiGetCts(uint32_t sampleRate,uint32_t tmdsClock)91 uint32_t HdmiGetCts(uint32_t sampleRate, uint32_t tmdsClock)
92 {
93     uint32_t i;
94     uint32_t tmpN = HDMI_NCTS_INVALID_VALUE;
95     uint32_t tmpCts = HDMI_NCTS_INVALID_VALUE;
96 
97     for (i = 0; i < sizeof(g_audioNctsMap) / sizeof(g_audioNctsMap[0]); i++) {
98         if (g_audioNctsMap[i].sampleRate == sampleRate &&
99             g_audioNctsMap[i].tmdsClock == tmdsClock) {
100             tmpN = g_audioNctsMap[i].n;
101             tmpCts = g_audioNctsMap[i].cts;
102             break;
103         }
104         if (g_audioNctsMap[i].sampleRate == sampleRate &&
105             g_audioNctsMap[i].tmdsClock >= (tmdsClock - HDMI_NCTS_TMDS_DEVIATION) &&
106             g_audioNctsMap[i].tmdsClock <= (tmdsClock + HDMI_NCTS_TMDS_DEVIATION)) {
107             tmpN = g_audioNctsMap[i].n;
108             tmpCts = g_audioNctsMap[i].cts;
109             break;
110         }
111         if (g_audioNctsMap[i].sampleRate == sampleRate &&
112             g_audioNctsMap[i].tmdsClock == 0) {
113             tmpN = g_audioNctsMap[i].n;
114             tmpCts = g_audioNctsMap[i].cts;
115             break;
116         }
117     }
118 
119     if (tmpCts == 0 && sampleRate >= HDMI_NCTS_KHZ) {
120         tmpCts = (tmpN / HDMI_NCTS_FACTOR)  * tmdsClock * HDMI_NCTS_TMDS_PER_PIXEL / (sampleRate / HDMI_NCTS_KHZ);
121     } else if (tmpCts == HDMI_NCTS_INVALID_VALUE && sampleRate >= HDMI_NCTS_KHZ) {
122         tmpCts = (HDMI_NCTS_N_DEFAULT / HDMI_NCTS_FACTOR)  * tmdsClock * HDMI_NCTS_TMDS_PER_PIXEL /
123             (sampleRate / HDMI_NCTS_KHZ);
124     }
125     return tmpCts;
126 }
127