xref: /OK3568_Linux_fs/kernel/drivers/media/i2c/it66353/it66353_EQ.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * it66353 HDMI 3 in 1 out driver.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author: Kenneth.Hung@ite.com.tw
8*4882a593Smuzhiyun  *         Wangqiang Guo <kay.guo@rock-chips.com>
9*4882a593Smuzhiyun  * Version: IT66353_SAMPLE_1.08
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun #include "config.h"
13*4882a593Smuzhiyun #include "platform.h"
14*4882a593Smuzhiyun #include "debug.h"
15*4882a593Smuzhiyun #include "it66353_drv.h"
16*4882a593Smuzhiyun #include "it66353_EQ.h"
17*4882a593Smuzhiyun #include "it66353.h"
18*4882a593Smuzhiyun #include <linux/time.h>
19*4882a593Smuzhiyun #include <linux/timer.h>
20*4882a593Smuzhiyun #include <linux/kernel.h>
21*4882a593Smuzhiyun #include <linux/module.h>
22*4882a593Smuzhiyun #include <linux/delay.h>
23*4882a593Smuzhiyun #include <linux/printk.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define Channel_B 0
26*4882a593Smuzhiyun #define Channel_G 1
27*4882a593Smuzhiyun #define Channel_R 2
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define PR_ERR(...); 	{if (dbg_level >= 0) printk(__VA_ARGS__);}
30*4882a593Smuzhiyun #define PR_INFO(...);	{if (dbg_level >= 1) printk(__VA_ARGS__);}
31*4882a593Smuzhiyun #define PR_INFO2(...);	{if (dbg_level >= 2) printk(__VA_ARGS__);}
32*4882a593Smuzhiyun #define PR_AEQ(...);	{if (dbg_level >= 2) printk(__VA_ARGS__);}
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun const u8 it66353_rs_value[] =  {0x7F, 0x7E, 0x3F, 0x3E, 0x1F, 0x1E, 0x0F,
35*4882a593Smuzhiyun 			0x0E, 0x07, 0x06, 0x03, 0x02, 0x01, 0x00};
36*4882a593Smuzhiyun static u8 rs_try_idx[] = {7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13, 0};
37*4882a593Smuzhiyun static int dbg_level;
38*4882a593Smuzhiyun #if 0
39*4882a593Smuzhiyun static u8 _rx_is_h14_tmds_over_1G(void)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	return it66353_get_port_info1(it66353_gdev.vars.Rx_active_port, PI_PLL_HS1G);
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun #endif
44*4882a593Smuzhiyun 
it66353_rx_DFE_enable(u8 enable)45*4882a593Smuzhiyun void it66353_rx_DFE_enable(u8 enable)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	it66353_chgrxbank(3);
48*4882a593Smuzhiyun 	if (enable)
49*4882a593Smuzhiyun 		it66353_h2rxset(0x22, 0x40, 0x40); // Enable DFE
50*4882a593Smuzhiyun 	else
51*4882a593Smuzhiyun 		it66353_h2rxset(0x22, 0x40, 0x00); // Disable DFE
52*4882a593Smuzhiyun 	it66353_chgrxbank(0);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun 
it66353_rx_set_rs_3ch(u8 * rs_value)55*4882a593Smuzhiyun void it66353_rx_set_rs_3ch(u8 *rs_value)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun 	u8 rs[3];
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	if (rs_value) {
60*4882a593Smuzhiyun 		rs[0] = rs_value[0] | 0x80;
61*4882a593Smuzhiyun 		rs[1] = rs_value[1] | 0x80;
62*4882a593Smuzhiyun 		rs[2] = rs_value[2] | 0x80;
63*4882a593Smuzhiyun 		it66353_chgrxbank(3);
64*4882a593Smuzhiyun 		it66353_h2rxbwr(0x27, 3, rs);
65*4882a593Smuzhiyun 		rs[0] = 0xCC;
66*4882a593Smuzhiyun 		rs[1] = 0xCC;
67*4882a593Smuzhiyun 		rs[2] = 0xCC;
68*4882a593Smuzhiyun 		it66353_h2rxbrd(0x27, 3, rs);
69*4882a593Smuzhiyun 		it66353_chgrxbank(0);
70*4882a593Smuzhiyun 		// it66353_h2rxwr(0x0f, 0x00);
71*4882a593Smuzhiyun 	}
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun 
it66353_rx_set_rs(u8 ch,u8 rs_value)74*4882a593Smuzhiyun void it66353_rx_set_rs(u8 ch, u8 rs_value)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	rs_value |= 0x80;
77*4882a593Smuzhiyun 	it66353_chgrxbank(3);
78*4882a593Smuzhiyun 	it66353_h2rxwr(0x27 + ch, rs_value);
79*4882a593Smuzhiyun 	it66353_chgrxbank(0);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun #if 0
84*4882a593Smuzhiyun static u8 _rx_get_rs(u8 ch)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	u8 rs_value;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	it66353_chgrxbank(3);
89*4882a593Smuzhiyun 	rs_value = it66353_h2rxrd(0x27+ch);
90*4882a593Smuzhiyun 	it66353_chgrxbank(0);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	return rs_value;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun #endif
95*4882a593Smuzhiyun 
it66353_rx_clear_ced_err(void)96*4882a593Smuzhiyun void it66353_rx_clear_ced_err(void)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	// read CED Error from SAREQ CEDError Counter
99*4882a593Smuzhiyun 	it66353_h2rxset(0x3B, 0x08, 0x08);
100*4882a593Smuzhiyun 	it66353_chgrxbank(3);
101*4882a593Smuzhiyun 	it66353_h2rxset(0x55, 0x80, 0x00);
102*4882a593Smuzhiyun 	it66353_h2rxwr(0xe9, 0x80);
103*4882a593Smuzhiyun 	it66353_chgrxbank(0);
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
_rx_ced_err_recheck(void)106*4882a593Smuzhiyun static void _rx_ced_err_recheck(void)
107*4882a593Smuzhiyun {
108*4882a593Smuzhiyun 	u8 i;
109*4882a593Smuzhiyun 	u8 tmp;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	it66353_h2rxwr(0xB9, 0xFF);
112*4882a593Smuzhiyun 	it66353_h2rxwr(0xBE, 0xFF);
113*4882a593Smuzhiyun 	msleep(10);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	for (i = 0 ; i < 3 ; i++) {
116*4882a593Smuzhiyun 		if ((it66353_gdev.vars.RxCEDErrValid&(1 << i)) &&
117*4882a593Smuzhiyun 		    (it66353_gdev.vars.RxCEDErr[i] > 0x100)) {
118*4882a593Smuzhiyun 			if ((it66353_h2rxrd(0x19)&0x80)) {
119*4882a593Smuzhiyun 				tmp = it66353_h2rxrd(0xB9);
120*4882a593Smuzhiyun 				if (0 == (tmp & (0x03<<i)))
121*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[i] = 0;
122*4882a593Smuzhiyun 			}
123*4882a593Smuzhiyun 		}
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
it66353_rx_update_ced_err_from_hw(void)127*4882a593Smuzhiyun void it66353_rx_update_ced_err_from_hw(void)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	u8 symlock;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	if (it66353_rx_is_clock_stable()) {
132*4882a593Smuzhiyun 		symlock = it66353_h2rxrd(0x14);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 		if (0 == (symlock & 0x38)) {
135*4882a593Smuzhiyun 			it66353_gdev.vars.RxCEDErrValid = 0;
136*4882a593Smuzhiyun 		} else {
137*4882a593Smuzhiyun 			// read CED Error from SAREQ CEDError Counter
138*4882a593Smuzhiyun 			it66353_h2rxset(0x3B, 0x08, 0x08);
139*4882a593Smuzhiyun 			it66353_chgrxbank(3);
140*4882a593Smuzhiyun 			it66353_h2rxset(0x55, 0x80, 0x00);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 			if (symlock & 0x08) {
143*4882a593Smuzhiyun 				it66353_h2rxwr(0xe9, 0x00);
144*4882a593Smuzhiyun 				it66353_gdev.vars.RxCEDErr[0] = it66353_h2rxrd(0xEB);
145*4882a593Smuzhiyun 				// ced valid
146*4882a593Smuzhiyun 				if (it66353_gdev.vars.RxCEDErr[0] & 0x80) {
147*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[0] = it66353_gdev.vars.RxCEDErr[0] & 0x7F;
148*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[0] = (it66353_gdev.vars.RxCEDErr[0] << 8) +
149*4882a593Smuzhiyun 								it66353_h2rxrd(0xEA);
150*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErrValid = 1;
151*4882a593Smuzhiyun 				} else {
152*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErrValid = 0;
153*4882a593Smuzhiyun 				}
154*4882a593Smuzhiyun 			} else {
155*4882a593Smuzhiyun 				it66353_gdev.vars.RxCEDErrValid = 0;
156*4882a593Smuzhiyun 			}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 			if (symlock & 0x10) {
159*4882a593Smuzhiyun 				it66353_h2rxwr(0xe9, 0x20);
160*4882a593Smuzhiyun 				it66353_gdev.vars.RxCEDErr[1] = it66353_h2rxrd(0xEB);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 				if (it66353_gdev.vars.RxCEDErr[1] & 0x80) {
163*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[1] = it66353_gdev.vars.RxCEDErr[1] & 0x7F;
164*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[1] = (it66353_gdev.vars.RxCEDErr[1]<<8) +
165*4882a593Smuzhiyun 								it66353_h2rxrd(0xEA);
166*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErrValid |= 0x02;
167*4882a593Smuzhiyun 				} else {
168*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErrValid &= ~0x02;
169*4882a593Smuzhiyun 				}
170*4882a593Smuzhiyun 			} else {
171*4882a593Smuzhiyun 				it66353_gdev.vars.RxCEDErrValid &= ~0x02;
172*4882a593Smuzhiyun 			}
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 			if (symlock & 0x20) {
175*4882a593Smuzhiyun 				it66353_h2rxwr(0xe9, 0x40);
176*4882a593Smuzhiyun 				it66353_gdev.vars.RxCEDErr[2] = it66353_h2rxrd(0xEB);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 				if (it66353_gdev.vars.RxCEDErr[2] & 0x80) {
179*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[2] = it66353_gdev.vars.RxCEDErr[2] & 0x7F;
180*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErr[2] = (it66353_gdev.vars.RxCEDErr[2]<<8) +
181*4882a593Smuzhiyun 								it66353_h2rxrd(0xEA);
182*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErrValid |= 0x04;
183*4882a593Smuzhiyun 				} else {
184*4882a593Smuzhiyun 					it66353_gdev.vars.RxCEDErrValid &= ~0x04;
185*4882a593Smuzhiyun 				}
186*4882a593Smuzhiyun 			} else {
187*4882a593Smuzhiyun 				it66353_gdev.vars.RxCEDErrValid &= ~0x04;
188*4882a593Smuzhiyun 			}
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 			it66353_h2rxwr(0xe9, 0x80);
191*4882a593Smuzhiyun 
192*4882a593Smuzhiyun 			it66353_chgrxbank(0);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 			_rx_ced_err_recheck();
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 		}
197*4882a593Smuzhiyun 	} else {
198*4882a593Smuzhiyun 		it66353_gdev.vars.RxCEDErrValid = 0;
199*4882a593Smuzhiyun 	}
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun 
_rx_record_ced_err(void)202*4882a593Smuzhiyun static void _rx_record_ced_err(void)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	u8 i;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	if (it66353_gdev.EQ.ced_acc_count == 0) {
207*4882a593Smuzhiyun 		for (i = 0 ; i < 3 ; i++) {
208*4882a593Smuzhiyun 			it66353_gdev.EQ.ced_err_avg[i] = it66353_gdev.vars.RxCEDErr[i];
209*4882a593Smuzhiyun 			// it66353_gdev.EQ.ced_err_avg_prev[i] = 0x8888;
210*4882a593Smuzhiyun 		}
211*4882a593Smuzhiyun 	} else {
212*4882a593Smuzhiyun 		for (i = 0 ; i < 3 ; i++) {
213*4882a593Smuzhiyun 			it66353_gdev.EQ.ced_err_avg[i] = it66353_gdev.EQ.ced_err_avg[i] +
214*4882a593Smuzhiyun 						 it66353_gdev.vars.RxCEDErr[i];
215*4882a593Smuzhiyun 			it66353_gdev.EQ.ced_err_avg[i] >>= 1;
216*4882a593Smuzhiyun 		}
217*4882a593Smuzhiyun 	}
218*4882a593Smuzhiyun 	it66353_gdev.EQ.ced_acc_count++;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
it66353_rx_monitor_ced_err(void)221*4882a593Smuzhiyun u8 it66353_rx_monitor_ced_err(void)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	static u8 err_acc;
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	if (0 == it66353_rx_is_all_ch_symlock()) {
226*4882a593Smuzhiyun 		return 0;
227*4882a593Smuzhiyun 	}
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	_rx_record_ced_err();
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	if (it66353_gdev.vars.RxCEDErrValid) {
233*4882a593Smuzhiyun 		if ((it66353_gdev.vars.RxCEDErr[0] || it66353_gdev.vars.RxCEDErr[1] ||
234*4882a593Smuzhiyun 		    it66353_gdev.vars.RxCEDErr[2])) {
235*4882a593Smuzhiyun 			err_acc++;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 			if (err_acc > 10) {
238*4882a593Smuzhiyun 				err_acc = 0;
239*4882a593Smuzhiyun 				if ((it66353_gdev.vars.RxCEDErr[0] > 0x08 ||
240*4882a593Smuzhiyun 				     it66353_gdev.vars.RxCEDErr[1] > 0x08 ||
241*4882a593Smuzhiyun 				     it66353_gdev.vars.RxCEDErr[2] > 0x08)) {
242*4882a593Smuzhiyun 					// return 1, means too much CED
243*4882a593Smuzhiyun 					return 1;
244*4882a593Smuzhiyun 				}
245*4882a593Smuzhiyun 			}
246*4882a593Smuzhiyun 		} else {
247*4882a593Smuzhiyun 			err_acc = 0;
248*4882a593Smuzhiyun 		}
249*4882a593Smuzhiyun 	} else {
250*4882a593Smuzhiyun 		// no ced error value for reference
251*4882a593Smuzhiyun 		// do nothing about CED error
252*4882a593Smuzhiyun 	}
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	return 0;
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun 
it66353_rx_is_hdmi20(void)257*4882a593Smuzhiyun u8 it66353_rx_is_hdmi20(void)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun #if 1
260*4882a593Smuzhiyun 	return it66353_gdev.vars.clock_ratio;
261*4882a593Smuzhiyun #else
262*4882a593Smuzhiyun 	if (it66353_h2swrd(0x61 + it66353_gdev.vars.Rx_active_port * 3) & 0x40) {
263*4882a593Smuzhiyun 		return 1;
264*4882a593Smuzhiyun 	}
265*4882a593Smuzhiyun 	return 0;
266*4882a593Smuzhiyun #endif
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun #if EN_H14_SKEW
it66353_rx_skew_adj(u8 ch)270*4882a593Smuzhiyun void it66353_rx_skew_adj(u8 ch)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun 	static u8 idx[3] = {0};
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun 	it66353_chgrxbank(3);
275*4882a593Smuzhiyun 	it66353_h2rxset(0x2D, 0x1 << ch, 0x01 << ch);
276*4882a593Smuzhiyun 	switch (idx[ch]) {
277*4882a593Smuzhiyun 	case 0:
278*4882a593Smuzhiyun 		it66353_h2rxset(0x2C, 0x3 << ch, 0x02 << ch);
279*4882a593Smuzhiyun 		idx[ch] = 1;
280*4882a593Smuzhiyun 		break;
281*4882a593Smuzhiyun 	case 1:
282*4882a593Smuzhiyun 		it66353_h2rxset(0x2C, 0x3 << ch, 0x03 << ch);
283*4882a593Smuzhiyun 		idx[ch] = 2;
284*4882a593Smuzhiyun 		break;
285*4882a593Smuzhiyun 	case 2:
286*4882a593Smuzhiyun 		it66353_h2rxset(0x2C, 0x3 << ch, 0x00 << ch);
287*4882a593Smuzhiyun 		idx[ch] = 0;
288*4882a593Smuzhiyun 		break;
289*4882a593Smuzhiyun 	default:
290*4882a593Smuzhiyun 		idx[ch] = 0;
291*4882a593Smuzhiyun 		break;
292*4882a593Smuzhiyun 	}
293*4882a593Smuzhiyun 	it66353_chgrxbank(0);
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun #endif
297*4882a593Smuzhiyun 
it66353_eq_save_h20(void)298*4882a593Smuzhiyun void it66353_eq_save_h20(void)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun 	it66353_chgrxbank(3);
301*4882a593Smuzhiyun 	it66353_gdev.EQ.stored_RS_20[0] = it66353_h2rxrd(0x27);
302*4882a593Smuzhiyun 	it66353_gdev.EQ.stored_RS_20[1] = it66353_h2rxrd(0x28);
303*4882a593Smuzhiyun 	it66353_gdev.EQ.stored_RS_20[2] = it66353_h2rxrd(0x29);
304*4882a593Smuzhiyun 	it66353_chgrxbank(0);
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun 
it66353_eq_load_h20(void)307*4882a593Smuzhiyun void it66353_eq_load_h20(void)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun 	PR_INFO("enter it66353_eq_load_h20\r\n");
310*4882a593Smuzhiyun 	it66353_rx_set_rs_3ch(it66353_gdev.EQ.stored_RS_20);
311*4882a593Smuzhiyun 	it66353_aeq_set_DFE2(it66353_gdev.EQ.stored_RS_20[0], it66353_gdev.EQ.stored_RS_20[1],
312*4882a593Smuzhiyun 		      it66353_gdev.EQ.stored_RS_20[2]);
313*4882a593Smuzhiyun 	it66353_rx_DFE_enable(1);
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
it66353_eq_save_h14(void)316*4882a593Smuzhiyun void it66353_eq_save_h14(void)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun 	it66353_chgrxbank(3);
319*4882a593Smuzhiyun 	it66353_gdev.EQ.stored_RS_14[0] = it66353_h2rxrd(0x27);
320*4882a593Smuzhiyun 	it66353_gdev.EQ.stored_RS_14[1] = it66353_h2rxrd(0x28);
321*4882a593Smuzhiyun 	it66353_gdev.EQ.stored_RS_14[2] = it66353_h2rxrd(0x29);
322*4882a593Smuzhiyun 	it66353_chgrxbank(0);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun 
it66353_eq_load_h14(void)325*4882a593Smuzhiyun void it66353_eq_load_h14(void)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	PR_INFO("enter it66353_eq_load_h14\r\n");
328*4882a593Smuzhiyun 	it66353_rx_set_rs_3ch(it66353_gdev.EQ.stored_RS_14);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
it66353_eq_load_previous(void)331*4882a593Smuzhiyun void it66353_eq_load_previous(void)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun 	if (it66353_rx_is_hdmi20()) {
334*4882a593Smuzhiyun 		if (it66353_gdev.EQ.current_eq_mode == 0) {
335*4882a593Smuzhiyun 			it66353_gdev.EQ.current_eq_mode = 1;
336*4882a593Smuzhiyun 			it66353_eq_load_h20();
337*4882a593Smuzhiyun 		}
338*4882a593Smuzhiyun 	} else {
339*4882a593Smuzhiyun 		if (it66353_gdev.EQ.current_eq_mode == 1) {
340*4882a593Smuzhiyun 			it66353_gdev.EQ.current_eq_mode = 0;
341*4882a593Smuzhiyun 			it66353_eq_load_h14();
342*4882a593Smuzhiyun 		}
343*4882a593Smuzhiyun 	}
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun 
it66353_eq_load_default(void)346*4882a593Smuzhiyun void it66353_eq_load_default(void)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun 	it66353_rx_set_rs_3ch(it66353_gdev.opts.active_rx_opt->DefaultEQ);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	if (it66353_rx_is_hdmi20()) {
351*4882a593Smuzhiyun 		it66353_rx_DFE_enable(0);
352*4882a593Smuzhiyun 		// PR_INFO(("_eq_load_def_20\r\n"));
353*4882a593Smuzhiyun 	} else {
354*4882a593Smuzhiyun 		// PR_INFO(("_eq_load_def_14\r\n"));
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun 
_eq_find_rs_index(u8 EQ_Value)358*4882a593Smuzhiyun static u8 _eq_find_rs_index(u8 EQ_Value)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	u8 i = 0;
361*4882a593Smuzhiyun 	EQ_Value &= ~0x80;
362*4882a593Smuzhiyun 	for (i = 0; i < sizeof(it66353_rs_value); i++) {
363*4882a593Smuzhiyun 		if (it66353_rs_value[i] == EQ_Value)
364*4882a593Smuzhiyun 			return i;
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	PR_ERR("EQ %02X not found !!\r\n", EQ_Value);
368*4882a593Smuzhiyun 	return 4;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
it66353_eq_reset_txoe_ready(void)371*4882a593Smuzhiyun void it66353_eq_reset_txoe_ready(void)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	it66353_gdev.EQ.txoe_ready20 = 0;
374*4882a593Smuzhiyun 	it66353_gdev.EQ.txoe_ready14 = 0;
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun 
it66353_eq_set_txoe_ready(u8 ready)377*4882a593Smuzhiyun void it66353_eq_set_txoe_ready(u8 ready)
378*4882a593Smuzhiyun {
379*4882a593Smuzhiyun 	if (it66353_rx_is_hdmi20())
380*4882a593Smuzhiyun 		it66353_gdev.EQ.txoe_ready20 = ready;
381*4882a593Smuzhiyun 	else
382*4882a593Smuzhiyun 		it66353_gdev.EQ.txoe_ready14 = ready;
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	PR_INFO("set ready 14=%d 20=%d\r\n", it66353_gdev.EQ.txoe_ready14,
385*4882a593Smuzhiyun 		it66353_gdev.EQ.txoe_ready20);
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun 
it66353_eq_get_txoe_ready(void)388*4882a593Smuzhiyun u8 it66353_eq_get_txoe_ready(void)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	PR_INFO("get ready 14=%d 20=%d\r\n", it66353_gdev.EQ.txoe_ready14,
391*4882a593Smuzhiyun 		it66353_gdev.EQ.txoe_ready20);
392*4882a593Smuzhiyun 	if (it66353_rx_is_hdmi20()) {
393*4882a593Smuzhiyun 		return it66353_gdev.EQ.txoe_ready20;
394*4882a593Smuzhiyun 	} else {
395*4882a593Smuzhiyun 		return it66353_gdev.EQ.txoe_ready14;
396*4882a593Smuzhiyun 	}
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun 
it66353_eq_reset_state(void)399*4882a593Smuzhiyun void it66353_eq_reset_state(void)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	it66353_gdev.EQ.EQ_flag_20 = SysAEQ_RUN;
402*4882a593Smuzhiyun 	it66353_gdev.EQ.EQ_flag_14 = SysAEQ_RUN;
403*4882a593Smuzhiyun }
404*4882a593Smuzhiyun 
it66353_eq_set_state(u8 state)405*4882a593Smuzhiyun void it66353_eq_set_state(u8 state)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	if (it66353_rx_is_hdmi20()) {
408*4882a593Smuzhiyun 		it66353_gdev.EQ.EQ_flag_20 = state;
409*4882a593Smuzhiyun 	} else {
410*4882a593Smuzhiyun 		it66353_gdev.EQ.EQ_flag_14 = state;
411*4882a593Smuzhiyun 	}
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	PR_INFO("set eq flag 14=%d 20=%d\r\n", it66353_gdev.EQ.EQ_flag_14,
414*4882a593Smuzhiyun 		it66353_gdev.EQ.EQ_flag_20);
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun 
it66353_eq_get_state(void)417*4882a593Smuzhiyun u8 it66353_eq_get_state(void)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	PR_INFO("get eq flag 14=%d 20=%d\r\n", it66353_gdev.EQ.EQ_flag_14,
420*4882a593Smuzhiyun 		it66353_gdev.EQ.EQ_flag_20);
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (it66353_rx_is_hdmi20()) {
423*4882a593Smuzhiyun 		return it66353_gdev.EQ.EQ_flag_20;
424*4882a593Smuzhiyun 	} else {
425*4882a593Smuzhiyun 		return it66353_gdev.EQ.EQ_flag_14;
426*4882a593Smuzhiyun 	}
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun 
_aeq_ready_to_start(void)429*4882a593Smuzhiyun static u8 _aeq_ready_to_start(void)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun 	return it66353_rx_is_clock_stable();
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun 
it66353_aeq_diable_eq_trigger(void)434*4882a593Smuzhiyun void it66353_aeq_diable_eq_trigger(void)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun 	it66353_chgrxbank(3);
437*4882a593Smuzhiyun 	it66353_h2rxset(0x22, 0x04, 0x00);
438*4882a593Smuzhiyun 	it66353_chgrxbank(0);
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
_aeq_reset(void)441*4882a593Smuzhiyun static void _aeq_reset(void)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	it66353_aeq_diable_eq_trigger();
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun 	it66353_h2rxwr(0x07, 0xff);
446*4882a593Smuzhiyun 	it66353_h2rxwr(0x23, 0xB0);
447*4882a593Smuzhiyun 	msleep(10);
448*4882a593Smuzhiyun 	it66353_h2rxwr(0x23, 0xA0);
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun 
_aeq_get_DFE2(u8 ch,u8 rs_idx)451*4882a593Smuzhiyun static void _aeq_get_DFE2(u8 ch, u8 rs_idx)
452*4882a593Smuzhiyun {
453*4882a593Smuzhiyun 	u8 i;
454*4882a593Smuzhiyun 	u8 amp_a, amp_b, amp_c, amp_d;
455*4882a593Smuzhiyun 	u8 tap1_sign, tap1_value;
456*4882a593Smuzhiyun 	u8 tap2_sign, tap2_value;
457*4882a593Smuzhiyun 	u8 tap3_sign, tap3_value;
458*4882a593Smuzhiyun 	u8 dfe_a, dfe_b, dfe_c;
459*4882a593Smuzhiyun 	u8 reg37o, reg37;
460*4882a593Smuzhiyun 	u8 rec[4];
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun 	it66353_chgrxbank(3);
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun 	i = rs_idx;
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	it66353_h2rxset(0x36, 0x0F, i);
467*4882a593Smuzhiyun 	reg37o = it66353_h2rxrd(0x37) & (~0xC0);
468*4882a593Smuzhiyun 	PR_AEQ("RS=%02x DEF:\r\n", 0x80|it66353_rs_value[i]);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun 	for (ch = 0 ; ch < 3 ; ch++) {
471*4882a593Smuzhiyun 		// hdmirxset(0x37 ,0xC0 ,ch<<6);
472*4882a593Smuzhiyun 		reg37 = reg37o | (ch << 6);
473*4882a593Smuzhiyun 		it66353_h2rxwr(0x37, reg37);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun #if 0
476*4882a593Smuzhiyun 		amp_a = hdmirxrd(0x5d);
477*4882a593Smuzhiyun 		amp_b = hdmirxrd(0x5e);
478*4882a593Smuzhiyun 		amp_c = hdmirxrd(0x5f);
479*4882a593Smuzhiyun 		amp_d = hdmirxrd(0x60);
480*4882a593Smuzhiyun #else
481*4882a593Smuzhiyun 		it66353_h2rxbrd(0x5d, 4, rec);
482*4882a593Smuzhiyun 		amp_a = rec[0];
483*4882a593Smuzhiyun 		amp_b = rec[1];
484*4882a593Smuzhiyun 		amp_c = rec[2];
485*4882a593Smuzhiyun 		amp_d = rec[3];
486*4882a593Smuzhiyun #endif
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 		if (amp_a > amp_b) {
489*4882a593Smuzhiyun 			tap1_sign = 1;
490*4882a593Smuzhiyun 			tap1_value = (amp_a - amp_b) >> 1;
491*4882a593Smuzhiyun 		} else {
492*4882a593Smuzhiyun 			tap1_sign = 0;
493*4882a593Smuzhiyun 			tap1_value = (amp_b - amp_a) >> 1;
494*4882a593Smuzhiyun 		}
495*4882a593Smuzhiyun 
496*4882a593Smuzhiyun 		if (amp_a > amp_c) {
497*4882a593Smuzhiyun 			tap2_sign = 1;
498*4882a593Smuzhiyun 			tap2_value = (amp_a - amp_c) >> 1;
499*4882a593Smuzhiyun 		} else {
500*4882a593Smuzhiyun 			tap2_sign = 0;
501*4882a593Smuzhiyun 			tap2_value = (amp_c - amp_a) >> 1;
502*4882a593Smuzhiyun 		}
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 		if (amp_a > amp_d) {
505*4882a593Smuzhiyun 			tap3_sign = 1;
506*4882a593Smuzhiyun 			tap3_value = (amp_a - amp_d) >> 1;
507*4882a593Smuzhiyun 		} else {
508*4882a593Smuzhiyun 			tap3_sign = 0;
509*4882a593Smuzhiyun 			tap3_value = (amp_d - amp_a) >> 1;
510*4882a593Smuzhiyun 		}
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 		if (tap1_value > 0x1F)
513*4882a593Smuzhiyun 			tap1_value = 0x1F;
514*4882a593Smuzhiyun 		if (tap2_value > 0x0F)
515*4882a593Smuzhiyun 			tap2_value = 0x0F;
516*4882a593Smuzhiyun 		if (tap3_value > 0x07)
517*4882a593Smuzhiyun 			tap3_value = 0x07;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 		dfe_a = (0x40) + (tap1_sign << 5) + tap1_value;
520*4882a593Smuzhiyun 		dfe_b = (0x20) + (tap2_sign << 4) + tap2_value;
521*4882a593Smuzhiyun 		dfe_c = (0x10) + (tap3_sign << 3) + tap3_value;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 		it66353_gdev.EQ.DFE[i][ch][0] = dfe_a;
524*4882a593Smuzhiyun 		it66353_gdev.EQ.DFE[i][ch][1] = dfe_b;
525*4882a593Smuzhiyun 		it66353_gdev.EQ.DFE[i][ch][2] = dfe_c;
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 		PR_AEQ(" ch%d=%02X %02X %02X |", ch, dfe_a, dfe_b, dfe_c);
528*4882a593Smuzhiyun 	}
529*4882a593Smuzhiyun 	PR_AEQ("\r\n");
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	it66353_chgrxbank(0);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun 
it66353_aeq_set_DFE2(u8 EQ0,u8 EQ1,u8 EQ2)535*4882a593Smuzhiyun void it66353_aeq_set_DFE2(u8 EQ0, u8 EQ1, u8 EQ2)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun 	u8 dfe[9];
538*4882a593Smuzhiyun 	u8 i;
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	i = _eq_find_rs_index(EQ0);
541*4882a593Smuzhiyun 	_aeq_get_DFE2(0, i);
542*4882a593Smuzhiyun 	dfe[0] = it66353_gdev.EQ.DFE[i][Channel_B][0];
543*4882a593Smuzhiyun 	dfe[1] = it66353_gdev.EQ.DFE[i][Channel_B][1];
544*4882a593Smuzhiyun 	dfe[2] = it66353_gdev.EQ.DFE[i][Channel_B][2];
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 	i = _eq_find_rs_index(EQ1);
547*4882a593Smuzhiyun 	_aeq_get_DFE2(1, i);
548*4882a593Smuzhiyun 	dfe[3] = it66353_gdev.EQ.DFE[i][Channel_G][0];
549*4882a593Smuzhiyun 	dfe[4] = it66353_gdev.EQ.DFE[i][Channel_G][1];
550*4882a593Smuzhiyun 	dfe[5] = it66353_gdev.EQ.DFE[i][Channel_G][2];
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	i = _eq_find_rs_index(EQ2);
553*4882a593Smuzhiyun 	_aeq_get_DFE2(2, i);
554*4882a593Smuzhiyun 	dfe[6] = it66353_gdev.EQ.DFE[i][Channel_R][0];
555*4882a593Smuzhiyun 	dfe[7] = it66353_gdev.EQ.DFE[i][Channel_R][1];
556*4882a593Smuzhiyun 	dfe[8] = it66353_gdev.EQ.DFE[i][Channel_R][2];
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	it66353_chgrxbank(3);
559*4882a593Smuzhiyun 	it66353_h2rxbwr(0x4B, 9, dfe);
560*4882a593Smuzhiyun 	// it66353_h2rxbrd(0x4B, 9, dfe); // for recheck only
561*4882a593Smuzhiyun 	for (i = 0; i < 3; i++) {
562*4882a593Smuzhiyun 		PR_AEQ("DFE:CH%d=%02X %02X %02X\r\n",
563*4882a593Smuzhiyun 			i, dfe[0+i*3], dfe[1+i*3], dfe[2+i*3]);
564*4882a593Smuzhiyun 	}
565*4882a593Smuzhiyun 	it66353_chgrxbank(0);
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun 
_aeq_get_calc_rs(void)568*4882a593Smuzhiyun static void _aeq_get_calc_rs(void)
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun 	it66353_chgrxbank(3);
571*4882a593Smuzhiyun 	it66353_h2rxbrd(0xD5, 3, it66353_gdev.EQ.CalcRS);
572*4882a593Smuzhiyun 	it66353_chgrxbank(0);
573*4882a593Smuzhiyun 	PR_AEQ("AEQ RS=%02X %02X %02X\r\n",
574*4882a593Smuzhiyun 		it66353_gdev.EQ.CalcRS[0], it66353_gdev.EQ.CalcRS[1], it66353_gdev.EQ.CalcRS[2]);
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun #if 0
578*4882a593Smuzhiyun static void _aeq_trigger_EQ(void)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun 	_aeq_reset();
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun 	it66353_chgrxbank(3);
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	// if 1G~3G, need to force set CSEL to 110
585*4882a593Smuzhiyun 	if (_rx_is_h14_tmds_over_1G()) {
586*4882a593Smuzhiyun 		PR_AEQ("over 1G\r\n");
587*4882a593Smuzhiyun 		it66353_h2rxwr(0x20, 0x36);
588*4882a593Smuzhiyun 		it66353_h2rxwr(0x21, 0x0E);
589*4882a593Smuzhiyun 	} else {
590*4882a593Smuzhiyun 		PR_AEQ("under 1G\r\n");
591*4882a593Smuzhiyun 		it66353_h2rxwr(0x20, 0x1B);
592*4882a593Smuzhiyun 		it66353_h2rxwr(0x21, 0x03);
593*4882a593Smuzhiyun 	}
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	it66353_h2rxwr(0x26, 0x00);
596*4882a593Smuzhiyun 	it66353_h2rxwr(0x22, 0x38); // [5:3] AUTOAMP , AUTOEQ , EQPWDB
597*4882a593Smuzhiyun 	it66353_h2rxset(0x22, 0x04, 0x04); // Trigger EQ
598*4882a593Smuzhiyun 	msleep(1);
599*4882a593Smuzhiyun 	it66353_h2rxset(0x22, 0x04, 0x00); // Trigger EQ
600*4882a593Smuzhiyun 	it66353_chgrxbank(0);
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	it66353_gdev.EQ.AutoEQ_WaitTime = 0;
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun #endif
605*4882a593Smuzhiyun 
_aeq_trigger_SAREQ(void)606*4882a593Smuzhiyun static void _aeq_trigger_SAREQ(void)
607*4882a593Smuzhiyun {
608*4882a593Smuzhiyun 	// MUST disable EQTrg before EQRst
609*4882a593Smuzhiyun 	u8 def_opt = 1;
610*4882a593Smuzhiyun 
611*4882a593Smuzhiyun 	it66353_chgrxbank(3);
612*4882a593Smuzhiyun 	//  init CSC value
613*4882a593Smuzhiyun 	it66353_h2rxwr(0x20, 0x1B);
614*4882a593Smuzhiyun 	it66353_h2rxwr(0x21, 0x03);
615*4882a593Smuzhiyun 	it66353_h2rxset(0x20, 0x80, 0x00);	// disable CLKStb AutoEQTrg
616*4882a593Smuzhiyun 	it66353_h2rxwr(0x22, 0x00);	// disable [4] ENDFE, set [2] EQTrg low
617*4882a593Smuzhiyun 	it66353_chgrxbank(0);
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	_aeq_reset();
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	it66353_h2rxwr(0x3B, 0x03);	// Reg_CEDOPT[5:0]
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	it66353_chgrxbank(3);
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	it66353_h2rxwr(0x26, 0x00);
626*4882a593Smuzhiyun 	// it66353_h2rxwr(0x27, 0x1F);
627*4882a593Smuzhiyun 	// it66353_h2rxwr(0x28, 0x1F);
628*4882a593Smuzhiyun 	// it66353_h2rxwr(0x29, 0x1F);
629*4882a593Smuzhiyun 	it66353_h2rxset(0x27, 0x80, 0x00);
630*4882a593Smuzhiyun 	it66353_h2rxset(0x28, 0x80, 0x00);
631*4882a593Smuzhiyun 	it66353_h2rxset(0x29, 0x80, 0x00);
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 	it66353_h2rxset(0x2C, 0xC0, 0xC0);
634*4882a593Smuzhiyun 	// it66353_h2rxset(0x2D, 0xF0, 0x20);
635*4882a593Smuzhiyun 	it66353_h2rxset(0x2D, 0xF0, 0x20+(def_opt<<4)); // rsdfeopt=1
636*4882a593Smuzhiyun 	it66353_h2rxset(0x2D, 0x07, 0x00);
637*4882a593Smuzhiyun 	it66353_h2rxwr(0x30, 0x8C);
638*4882a593Smuzhiyun 
639*4882a593Smuzhiyun 	it66353_h2rxwr(0x31, 0xB0);		// AMPTime[7:0]
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	it66353_h2rxwr(0x32, 0x43);
642*4882a593Smuzhiyun 	it66353_h2rxwr(0x33, 0x47);
643*4882a593Smuzhiyun 	it66353_h2rxwr(0x34, 0x4B);
644*4882a593Smuzhiyun 	it66353_h2rxwr(0x35, 0x53);
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	it66353_h2rxset(0x36, 0xc0, 0x00);	// [7:6] AMPTime[9:8]
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	it66353_h2rxwr(0x37, 0x0B);		// [7:6] RecChannel, [4]: RSOnestage,
649*4882a593Smuzhiyun 						// [3] IgnoreOPT, [1:0] MacthNoSel
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	it66353_h2rxwr(0x38, 0xF2);		// [7:4] MonTime
652*4882a593Smuzhiyun 	/* [5] POLBOPT, [4] ADDPClrOPT, [3:0] CED Valid Threshold 0x0D */
653*4882a593Smuzhiyun 	it66353_h2rxwr(0x39, 0x04);
654*4882a593Smuzhiyun 	it66353_h2rxset(0x4A, 0x80, 0x00);
655*4882a593Smuzhiyun 	it66353_h2rxset(0x4B, 0x80, 0x00);
656*4882a593Smuzhiyun 	it66353_h2rxset(0x54, 0x80, 0x80);	// Reg_EN_PREEQ
657*4882a593Smuzhiyun 	it66353_h2rxset(0x54, 0x38, 0x38);
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 	it66353_h2rxwr(0x55, 0x40);		// RSM Threshold
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	// it66353_h2rxset(0x22, 0x04, 0x04);	// Trigger EQ
662*4882a593Smuzhiyun 	it66353_h2rxset(0x22, 0x44, 0x04+(def_opt<<6));	// Trigger EQ
663*4882a593Smuzhiyun 	it66353_chgrxbank(0);
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	it66353_gdev.EQ.AutoEQ_WaitTime = 0;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun 
_aeq_check_amp_and_rs_status(void)668*4882a593Smuzhiyun static void _aeq_check_amp_and_rs_status(void)
669*4882a593Smuzhiyun {
670*4882a593Smuzhiyun 	u8 i;
671*4882a593Smuzhiyun 	u8 reg63, reg6D;
672*4882a593Smuzhiyun 	u16 reg64, reg6E;
673*4882a593Smuzhiyun 	u16 amp_timeout;
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	it66353_gdev.EQ.DFE_Valid = 1;
676*4882a593Smuzhiyun 	it66353_gdev.EQ.RS_Valid = 1;
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 	it66353_chgrxbank(3);
679*4882a593Smuzhiyun 	for (i = 0; i < 3; i++) {
680*4882a593Smuzhiyun 		it66353_h2rxset(0x37, 0xC0, i<<6);
681*4882a593Smuzhiyun 		reg63 = it66353_h2rxrd(0x63);
682*4882a593Smuzhiyun 		reg64 = it66353_h2rxrd(0x64)&0x3F;
683*4882a593Smuzhiyun 		reg6D = it66353_h2rxrd(0x6D);
684*4882a593Smuzhiyun 		reg6E = it66353_h2rxrd(0x6E);
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 		it66353_gdev.EQ.RS_ValidMap[i] = (reg6E<<8) + reg6D;
687*4882a593Smuzhiyun 		amp_timeout = (reg64<<8) + reg63;
688*4882a593Smuzhiyun 
689*4882a593Smuzhiyun 		PR_AEQ("CH %d, AMP_TimeOut = 0x%04X \r\n", i, amp_timeout);
690*4882a593Smuzhiyun 		PR_AEQ("CH %d, RS_ValidMap = 0x%04X \r\n", i,
691*4882a593Smuzhiyun 			it66353_gdev.EQ.RS_ValidMap[i]);
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 		if (amp_timeout == 0x3FFF) {
694*4882a593Smuzhiyun 			it66353_gdev.EQ.DFE_Valid = 0;
695*4882a593Smuzhiyun 		}
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 		reg63 = it66353_h2rxrd(0x61);
698*4882a593Smuzhiyun 		reg64 = it66353_h2rxrd(0x62) & 0x3F;
699*4882a593Smuzhiyun 		amp_timeout = (reg64 << 8) + reg63;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 		PR_AEQ("CH %d, AMP_Done = 0x%04X \r\n", i, amp_timeout);
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 		if (it66353_gdev.EQ.RS_ValidMap[i] == 0x0000) {
704*4882a593Smuzhiyun 			it66353_gdev.EQ.RS_Valid = 0;
705*4882a593Smuzhiyun 		}
706*4882a593Smuzhiyun 	}
707*4882a593Smuzhiyun 	it66353_chgrxbank(0);
708*4882a593Smuzhiyun }
709*4882a593Smuzhiyun 
it66353_aeq_check_sareq_result(void)710*4882a593Smuzhiyun u8 it66353_aeq_check_sareq_result(void)
711*4882a593Smuzhiyun {
712*4882a593Smuzhiyun 	u8 tmp;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	tmp = it66353_h2rxrd(0x07);
715*4882a593Smuzhiyun 	if (tmp & (0x20 | 0x10)) {		// EQ fail | EQ Done
716*4882a593Smuzhiyun 		it66353_aeq_diable_eq_trigger();
717*4882a593Smuzhiyun 		_aeq_check_amp_and_rs_status();
718*4882a593Smuzhiyun 		if (tmp & 0x10) {
719*4882a593Smuzhiyun 			it66353_gdev.EQ.AutoEQ_Result = EQRES_SAREQ_DONE;
720*4882a593Smuzhiyun 		} else {
721*4882a593Smuzhiyun 			it66353_gdev.EQ.AutoEQ_Result = EQRES_SAREQ_FAIL;
722*4882a593Smuzhiyun 		}
723*4882a593Smuzhiyun 
724*4882a593Smuzhiyun 		return 1;
725*4882a593Smuzhiyun 	}
726*4882a593Smuzhiyun 	/*
727*4882a593Smuzhiyun 	 * else if (tmp & BIT5) {		// EQ fail
728*4882a593Smuzhiyun 	 *	it66353_aeq_diable_eq_trigger();
729*4882a593Smuzhiyun 	 *	_aeq_check_amp_and_rs_status();
730*4882a593Smuzhiyun 	 *	it66353_gdev.EQ.AutoEQ_Result = EQRES_SAREQ_FAIL;
731*4882a593Smuzhiyun 	 * }
732*4882a593Smuzhiyun 	 */
733*4882a593Smuzhiyun 	else {
734*4882a593Smuzhiyun 		it66353_gdev.EQ.AutoEQ_WaitTime++;
735*4882a593Smuzhiyun 		msleep(20);
736*4882a593Smuzhiyun 		if (it66353_gdev.EQ.AutoEQ_WaitTime > 30) {
737*4882a593Smuzhiyun 			it66353_gdev.EQ.AutoEQ_Result = EQRES_SAREQ_TIMEOUT;
738*4882a593Smuzhiyun 			return 1;
739*4882a593Smuzhiyun 		}
740*4882a593Smuzhiyun 	}
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 	return 0;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun #if 0
746*4882a593Smuzhiyun static u8 _aeq_check_h14eq_result(void)
747*4882a593Smuzhiyun {
748*4882a593Smuzhiyun 	u8 tmp;
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 	tmp = it66353_h2rxrd(0x07);
751*4882a593Smuzhiyun 	if (tmp & 0x40) {		// EQ Done
752*4882a593Smuzhiyun 		it66353_aeq_diable_eq_trigger();
753*4882a593Smuzhiyun 		PR_AEQ("AEQ 14, DONE\r\n");
754*4882a593Smuzhiyun 		return EQRES_H14EQ_DONE;
755*4882a593Smuzhiyun 	} else if (tmp & 0x80) {	// EQ fail
756*4882a593Smuzhiyun 		it66353_aeq_diable_eq_trigger();
757*4882a593Smuzhiyun 		PR_ERR("AEQ 14, FAIL\r\n");
758*4882a593Smuzhiyun 		return EQRES_H14EQ_FAIL;
759*4882a593Smuzhiyun 	} else {
760*4882a593Smuzhiyun 		msleep(25);
761*4882a593Smuzhiyun 		it66353_gdev.EQ.AutoEQ_WaitTime++;
762*4882a593Smuzhiyun 		if (it66353_gdev.EQ.AutoEQ_WaitTime > 100) {
763*4882a593Smuzhiyun 			it66353_gdev.EQ.AutoEQ_Result = EQRES_SAREQ_TIMEOUT;
764*4882a593Smuzhiyun 			PR_ERR("AEQ 14, TIMEOUT\r\n");
765*4882a593Smuzhiyun 			return EQRES_H14EQ_TIMEOUT;
766*4882a593Smuzhiyun 		} else {
767*4882a593Smuzhiyun 			// return EQRES_BUSY;
768*4882a593Smuzhiyun 		}
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	}
771*4882a593Smuzhiyun 	return EQRES_BUSY;
772*4882a593Smuzhiyun }
773*4882a593Smuzhiyun #endif
774*4882a593Smuzhiyun 
_meq_14(void)775*4882a593Smuzhiyun static u8 _meq_14(void)
776*4882a593Smuzhiyun {
777*4882a593Smuzhiyun 	u8 rs_idx;
778*4882a593Smuzhiyun 	static u8 ch_rs_idx[3];
779*4882a593Smuzhiyun 	u8 ch;
780*4882a593Smuzhiyun 	u8 ch_all_done;
781*4882a593Smuzhiyun 	u8 ch_done[3];
782*4882a593Smuzhiyun 	u8 res = EQRES_H14EQ_FAIL;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	ch_done[0] = 0;
785*4882a593Smuzhiyun 	ch_done[1] = 0;
786*4882a593Smuzhiyun 	ch_done[2] = 0;
787*4882a593Smuzhiyun 	ch_all_done = 0;
788*4882a593Smuzhiyun 	ch_rs_idx[0] = 0;
789*4882a593Smuzhiyun 	ch_rs_idx[1] = 0;
790*4882a593Smuzhiyun 	ch_rs_idx[2] = 0;
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	it66353_rx_clear_ced_err();
793*4882a593Smuzhiyun 	msleep(50);
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 
796*4882a593Smuzhiyun 	for (rs_idx = 0; rs_idx < 14; rs_idx++) {
797*4882a593Smuzhiyun 		if (0 == _aeq_ready_to_start()) {
798*4882a593Smuzhiyun 			PR_ERR("Cannot perform EQ adjust\r\n");
799*4882a593Smuzhiyun 			break;
800*4882a593Smuzhiyun 		}
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun 		it66353_rx_update_ced_err_from_hw();
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 		for (ch = 0; ch < 3; ch++) {
806*4882a593Smuzhiyun 			if (ch_done[ch]) {
807*4882a593Smuzhiyun 				// break;
808*4882a593Smuzhiyun 			}
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 			if (it66353_gdev.vars.RxCEDErrValid & (1 << ch)) {
811*4882a593Smuzhiyun 				if (it66353_gdev.vars.RxCEDErr[ch] < 0x01) {
812*4882a593Smuzhiyun 					ch_done[ch] = 1;
813*4882a593Smuzhiyun 					ch_all_done++;
814*4882a593Smuzhiyun 					PR_AEQ("RS good ch%d = %02X\r\n",
815*4882a593Smuzhiyun 						ch, it66353_rs_value[ch_rs_idx[ch]]);
816*4882a593Smuzhiyun 				} else {
817*4882a593Smuzhiyun 					ch_done[ch] = 0;
818*4882a593Smuzhiyun 					PR_AEQ("RS NG ch%d = %02X, err=%04X\r\n",
819*4882a593Smuzhiyun 						ch, it66353_rs_value[ch_rs_idx[ch]],
820*4882a593Smuzhiyun 						it66353_gdev.vars.RxCEDErr[ch]);
821*4882a593Smuzhiyun 				}
822*4882a593Smuzhiyun 			} else {
823*4882a593Smuzhiyun 				ch_done[ch] = 0;
824*4882a593Smuzhiyun 			}
825*4882a593Smuzhiyun 		}
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 		if (ch_done[0] && ch_done[1] && ch_done[2]) {
828*4882a593Smuzhiyun 			PR_AEQ("ch_all_done\r\n");
829*4882a593Smuzhiyun 			res = EQRES_H14EQ_DONE;
830*4882a593Smuzhiyun 			break;
831*4882a593Smuzhiyun 		}
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 		it66353_rx_clear_ced_err();
834*4882a593Smuzhiyun 		for (ch = 0; ch < 3; ch++) {
835*4882a593Smuzhiyun 			if (0 == ch_done[ch]) {
836*4882a593Smuzhiyun 				it66353_rx_set_rs(ch, it66353_rs_value[rs_try_idx[ch_rs_idx[ch]]]);
837*4882a593Smuzhiyun 				ch_rs_idx[ch]++;
838*4882a593Smuzhiyun 				if (ch_rs_idx[ch] >= 14) {
839*4882a593Smuzhiyun 					ch_rs_idx[ch] = 0;
840*4882a593Smuzhiyun 				}
841*4882a593Smuzhiyun 			}
842*4882a593Smuzhiyun 		}
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun 		msleep(100);
845*4882a593Smuzhiyun 	}
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	return res;
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 
it66353_auto_eq_adjust(void)851*4882a593Smuzhiyun bool it66353_auto_eq_adjust(void)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun 	u8 result;
854*4882a593Smuzhiyun 	u8 ret = false;
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	if (_aeq_ready_to_start()) {
857*4882a593Smuzhiyun 		it66353_h2swset(0xD4, 0x03, 0x01);	  // Set TXOE off
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 		if (it66353_gdev.vars.count_auto_eq_fail > 13) {
860*4882a593Smuzhiyun 			it66353_gdev.vars.count_auto_eq_fail = 0;
861*4882a593Smuzhiyun 			it66353_rx_caof_init(it66353_gdev.vars.Rx_active_port);
862*4882a593Smuzhiyun 		}
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 		if (it66353_rx_is_hdmi20()) {
865*4882a593Smuzhiyun 			it66353_gdev.EQ.current_eq_mode = EQ_MODE_H20;
866*4882a593Smuzhiyun 			it66353_gdev.EQ.RS_Valid = 0;
867*4882a593Smuzhiyun 			it66353_gdev.EQ.DFE_Valid = 0;
868*4882a593Smuzhiyun 			_aeq_trigger_SAREQ();
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun 			while (it66353_aeq_check_sareq_result() == 0) {
871*4882a593Smuzhiyun 				// auto EQ will wait about 400ms here
872*4882a593Smuzhiyun 			}
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 			if (it66353_gdev.EQ.DFE_Valid && it66353_gdev.EQ.RS_Valid) {
875*4882a593Smuzhiyun 				_aeq_get_calc_rs();
876*4882a593Smuzhiyun 				it66353_rx_set_rs_3ch(it66353_gdev.EQ.CalcRS);
877*4882a593Smuzhiyun 				it66353_aeq_set_DFE2(it66353_gdev.EQ.CalcRS[0],
878*4882a593Smuzhiyun 					      it66353_gdev.EQ.CalcRS[1],
879*4882a593Smuzhiyun 					      it66353_gdev.EQ.CalcRS[2]);
880*4882a593Smuzhiyun 				it66353_rx_DFE_enable(1);
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 				it66353_eq_save_h20();
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun 				ret = true;
885*4882a593Smuzhiyun 			} else {
886*4882a593Smuzhiyun 				it66353_chgrxbank(3);
887*4882a593Smuzhiyun 				it66353_h2rxset(0x27, 0x80, 0x80);
888*4882a593Smuzhiyun 				it66353_h2rxset(0x28, 0x80, 0x80);
889*4882a593Smuzhiyun 				it66353_h2rxset(0x29, 0x80, 0x80);
890*4882a593Smuzhiyun 				it66353_chgrxbank(0);
891*4882a593Smuzhiyun 			}
892*4882a593Smuzhiyun 		} else {
893*4882a593Smuzhiyun 			it66353_gdev.EQ.current_eq_mode = EQ_MODE_H14;
894*4882a593Smuzhiyun 
895*4882a593Smuzhiyun #if 0
896*4882a593Smuzhiyun 			_aeq_trigger_EQ();
897*4882a593Smuzhiyun 
898*4882a593Smuzhiyun 			result = _aeq_check_h14eq_result();
899*4882a593Smuzhiyun 			while (EQRES_BUSY == result) {
900*4882a593Smuzhiyun 				result = _aeq_check_h14eq_result();
901*4882a593Smuzhiyun 			}
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 			if (result == EQRES_H14EQ_DONE) {
904*4882a593Smuzhiyun 				_aeq_get_calc_rs();
905*4882a593Smuzhiyun 				it66353_rx_set_rs_3ch(it66353_gdev.EQ.CalcRS);
906*4882a593Smuzhiyun 			} else {
907*4882a593Smuzhiyun 				result = _meq_14();
908*4882a593Smuzhiyun 			}
909*4882a593Smuzhiyun #else
910*4882a593Smuzhiyun 			result = _meq_14();
911*4882a593Smuzhiyun #endif
912*4882a593Smuzhiyun 
913*4882a593Smuzhiyun 			if (result == EQRES_H14EQ_DONE) {
914*4882a593Smuzhiyun 				it66353_eq_save_h14();
915*4882a593Smuzhiyun 				ret = true;
916*4882a593Smuzhiyun 			}
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun 		}
919*4882a593Smuzhiyun 
920*4882a593Smuzhiyun 		it66353_h2swset(0xD4, 0x03, 0x00);	  // Set DRV_RST='1'
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 		if (ret) {
923*4882a593Smuzhiyun 			it66353_gdev.vars.count_auto_eq_fail = 0;
924*4882a593Smuzhiyun 		} else {
925*4882a593Smuzhiyun 			it66353_gdev.vars.count_auto_eq_fail++;
926*4882a593Smuzhiyun 			PR_ERR("EQ result NG %d\r\n", it66353_gdev.vars.count_auto_eq_fail);
927*4882a593Smuzhiyun 		}
928*4882a593Smuzhiyun 	} else {
929*4882a593Smuzhiyun 		PR_ERR("EQ adjust not available\r\n");
930*4882a593Smuzhiyun 	}
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun 	return ret;
933*4882a593Smuzhiyun }
934*4882a593Smuzhiyun 
935*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
936