1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "hdmi_hal_ncts.h"
20 #include "hdmi_hal_intf.h"
21 #include "hdmi_product_define.h"
22
23 #define NCTS_TMDS_DEVIATION 20
24 #define NCTS_INVALID_DATA 0xffffffff
25 #define NCTS_CALC_FACTOR 128
26 #define NCTS_N_DEFAULT 6144
27
28 static hdmi_audio_cts_n g_audio_cts_n[] = {
29 /* rate TMDS N CTS */
30 { 32000, 25174, 4576, 28125 },
31 { 32000, 25200, 4096, 25200 },
32 { 32000, 27000, 4096, 27000 },
33 { 32000, 27027, 4096, 27027 },
34 { 32000, 54000, 4096, 54000 },
35 { 32000, 54054, 4096, 54054 },
36 { 32000, 74175, 11648, 210937 },
37 { 32000, 74250, 4096, 74250 },
38 { 32000, 148351, 11648, 421875 },
39 { 32000, 148500, 4096, 148500 },
40 { 32000, 296703, 5824, 421875 },
41 { 32000, 297000, 3072, 222750 },
42 { 32000, 593406, 5824, 843750 },
43 { 32000, 594000, 3072, 445500 },
44 { 32000, 0, 4096, 0 },
45 { 44100, 25174, 7007, 31250 },
46 { 44100, 25200, 6272, 28000 },
47 { 44100, 27000, 6272, 30000 },
48 { 44100, 27027, 6272, 30030 },
49 { 44100, 54000, 6272, 60000 },
50 { 44100, 54054, 6272, 60060 },
51 { 44100, 74175, 17836, 234375 },
52 { 44100, 74250, 6272, 82500 },
53 { 44100, 148351, 8918, 234375 },
54 { 44100, 148500, 6272, 165000 },
55 { 44100, 296703, 4459, 234375 },
56 { 44100, 297000, 4704, 247500 },
57 { 44100, 593406, 8918, 937500 },
58 { 44100, 594000, 9408, 990000 },
59 { 44100, 0, 6272, 0 },
60 { 48000, 25174, 6864, 28125 },
61 { 48000, 25200, 6144, 25200 },
62 { 48000, 27000, 6144, 27000 },
63 { 48000, 27027, 6144, 27027 },
64 { 48000, 54000, 6144, 54000 },
65 { 48000, 54054, 6144, 54054 },
66 { 48000, 74175, 11648, 140625 },
67 { 48000, 74250, 6144, 74250 },
68 { 48000, 148351, 5824, 140625 },
69 { 48000, 148500, 6144, 148500 },
70 { 48000, 296703, 5824, 281250 },
71 { 48000, 297000, 5120, 247500 },
72 { 48000, 593406, 5824, 562500 },
73 { 48000, 594000, 6144, 594000 },
74 { 48000, 0, 6144, 0 }
75 };
76
hal_hdmi_n_value_get(hi_u32 sample_rate,hi_u32 tmds_clk)77 hi_u32 hal_hdmi_n_value_get(hi_u32 sample_rate, hi_u32 tmds_clk)
78 {
79 hi_u32 i;
80 hdmi_audio_cts_n *audio_cts_n = &g_audio_cts_n[0];
81 hi_u32 n_value = NCTS_N_DEFAULT;
82
83 for (i = 0; i < hdmi_array_size(g_audio_cts_n); i++, audio_cts_n++) {
84 if ((audio_cts_n->audio_smp_rate == sample_rate) && (audio_cts_n->tmds_clk == tmds_clk)) {
85 n_value = audio_cts_n->n_value;
86 break;
87 } else if ((audio_cts_n->audio_smp_rate == sample_rate) &&
88 (audio_cts_n->tmds_clk >= (tmds_clk - NCTS_TMDS_DEVIATION)) &&
89 (audio_cts_n->tmds_clk <= (tmds_clk + NCTS_TMDS_DEVIATION))) {
90 n_value = audio_cts_n->n_value;
91 break;
92 } else if ((audio_cts_n->audio_smp_rate == sample_rate) && (audio_cts_n->tmds_clk == 0)) {
93 n_value = audio_cts_n->n_value;
94 break;
95 }
96 }
97
98 return n_value;
99 }
100
hal_hdmi_cts_value_get(hi_u32 sample_rate,hi_u32 tmds_clk)101 hi_u32 hal_hdmi_cts_value_get(hi_u32 sample_rate, hi_u32 tmds_clk)
102 {
103 hi_u32 i;
104 hi_u32 tmp_cts = NCTS_INVALID_DATA;
105 hi_u32 tmp_n = NCTS_INVALID_DATA;
106 hdmi_audio_cts_n *audio_cts_n = &g_audio_cts_n[0];
107
108 for (i = 0; i < hdmi_array_size(g_audio_cts_n); i++, audio_cts_n++) {
109 if ((audio_cts_n->audio_smp_rate == sample_rate) && (audio_cts_n->tmds_clk == tmds_clk)) {
110 tmp_cts = audio_cts_n->cts_value;
111 tmp_n = audio_cts_n->n_value;
112 break;
113 } else if ((audio_cts_n->audio_smp_rate == sample_rate) &&
114 (audio_cts_n->tmds_clk >= (tmds_clk - NCTS_TMDS_DEVIATION)) &&
115 (audio_cts_n->tmds_clk <= (tmds_clk + NCTS_TMDS_DEVIATION))) {
116 tmp_cts = audio_cts_n->cts_value;
117 tmp_n = audio_cts_n->n_value;
118 break;
119 } else if ((audio_cts_n->audio_smp_rate == sample_rate) && (audio_cts_n->tmds_clk == 0)) {
120 tmp_cts = audio_cts_n->cts_value;
121 tmp_n = audio_cts_n->n_value;
122 break;
123 }
124 }
125
126 /*
127 * (n * tmds_clk)
128 * cts =-----------------
129 * (128 * samp_rate)
130 */
131 if ((tmp_cts == 0) && (sample_rate >= HDMI_HUNDRED)) {
132 tmp_cts = (tmp_n / NCTS_CALC_FACTOR) * tmds_clk * HDMI_DECIMAL / (sample_rate / HDMI_HUNDRED);
133 } else if ((tmp_cts == NCTS_INVALID_DATA) && (sample_rate >= HDMI_HUNDRED)) {
134 /* can't find, N default 48k samprate */
135 hdmi_warn("can't find cts! tmp_cts=%u,sample_rate=%u,tmds_clk=%u\n", tmp_cts, sample_rate, tmds_clk);
136 tmp_cts = (NCTS_N_DEFAULT / NCTS_CALC_FACTOR) * tmds_clk * HDMI_DECIMAL / (sample_rate / HDMI_HUNDRED);
137 }
138
139 return tmp_cts;
140 }
141
142