xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/bridge/ite-it6161.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4  */
5 
6 #ifdef __linux__
7 //#include <linux/bits.h>
8 #include <linux/of_graph.h>
9 #include <linux/platform_device.h>
10 
11 #include <linux/delay.h>
12 #include <linux/device.h>
13 #include <linux/err.h>
14 #include <linux/extcon.h>
15 #include <linux/fs.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/i2c.h>
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regmap.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/types.h>
25 #include <linux/wait.h>
26 #include <drm/drm_mipi_dsi.h>
27 
28 #include <crypto/hash.h>
29 #include <crypto/sha.h>
30 
31 #include <drm/drm_atomic_helper.h>
32 #include <drm/drm_bridge.h>
33 #include <drm/drm_crtc.h>
34 #include <drm/drm_crtc_helper.h>
35 #include <drm/drm_dp_helper.h>
36 #include <drm/drm_edid.h>
37 #include <drm/drm_print.h>
38 #include <drm/drm_mipi_dsi.h>
39 #include <drm/drm_probe_helper.h>
40 
41 #include <sound/hdmi-codec.h>
42 #else
43 
44 #include "platform.h"
45 
46 #endif
47 #define IT6161_PRINT(fmt, ...)						\
48 	_DRM_PRINTK(, WARNING, fmt, ##__VA_ARGS__)
49 
50 static int ite_debug = 0;
51 
52 #define it6161_debug(fmt, ...) do {				\
53 		if (ite_debug)					\
54 			_DRM_PRINTK(, INFO, fmt, ##__VA_ARGS__); \
55 	} while (0)
56 
57 /* Vendor option */
58 #define AUDIO_SELECT I2S
59 #define AUDIO_TYPE LPCM
60 #define AUDIO_SAMPLE_RATE SAMPLE_RATE_48K
61 #define AUDIO_CHANNEL_COUNT 2
62 
63 /*
64  * 0: Standard I2S
65  * 1: 32bit I2S
66  */
67 #define I2S_INPUT_FORMAT 1
68 
69 /*
70  * 0: Left-justified
71  * 1: Right-justified
72  */
73 #define I2S_JUSTIFIED 0
74 
75 /*
76  * 0: Data delay 1T correspond to WS
77  * 1: No data delay correspond to WS
78  */
79 #define I2S_DATA_DELAY 0
80 
81 /*
82  * 0: Left channel
83  * 1: Right channel
84  */
85 #define I2S_WS_CHANNEL 0
86 
87 /*
88  * 0: MSB shift first
89  * 1: LSB shift first
90  */
91 #define I2S_DATA_SEQUENCE 0
92 
93 #define AUX_WAIT_TIMEOUT_MS 100
94 #define PIXEL_CLK_DELAY 1
95 #define PIXEL_CLK_INVERSE 0
96 #define ADJUST_PHASE_THRESHOLD 80000
97 #define MAX_PIXEL_CLK 95000
98 #define DEFAULT_DRV_HOLD 0
99 #define DEFAULT_PWR_ON 0
100 
101 enum hdmi_tx_mode {
102 	HDMI_TX_NONE,
103 	HDMI_TX_BY_PASS,
104 	HDMI_TX_ENABLE_DE_ONLY,
105 	HDMI_TX_ENABLE_PATTERN_GENERATOR,
106 };
107 
108 enum it6161_audio_select {
109 	I2S = 0,
110 	SPDIF,
111     TDM,
112 };
113 
114 enum it6161_audio_sample_rate {
115 	SAMPLE_RATE_24K = 0x6,
116 	SAMPLE_RATE_32K = 0x3,
117 	SAMPLE_RATE_48K = 0x2,
118 	SAMPLE_RATE_96K = 0xA,
119 	SAMPLE_RATE_192K = 0xE,
120 	SAMPLE_RATE_44_1K = 0x0,
121 	SAMPLE_RATE_88_2K = 0x8,
122 	SAMPLE_RATE_176_4K = 0xC,
123 };
124 
125 enum it6161_audio_type {
126 	LPCM = 0,
127 	NLPCM,
128 	DSS,
129 };
130 
131 enum it6161_audio_u32_length {
132 	u32_LENGTH_16BIT = 0,
133 	u32_LENGTH_18BIT,
134 	u32_LENGTH_20BIT,
135 	u32_LENGTH_24BIT,
136 };
137 
138 /*
139  * Audio Sample u32 Length
140  * u32_LENGTH_16BIT
141  * u32_LENGTH_18BIT
142  * u32_LENGTH_20BIT
143  * u32_LENGTH_24BIT
144  */
145 #define AUDIO_u32_LENGTH u32_LENGTH_24BIT
146 
147 enum it6161_active_level {
148     LOW,
149     HIGH,
150 };
151 
152 enum dsi_data_id {
153 	RGB_24b = 0x3E,
154 	RGB_30b = 0x0D,
155 	RGB_36b = 0x1D,
156 	RGB_18b = 0x1E,
157 	RGB_18b_L = 0x2E,
158 	YCbCr_16b = 0x2C,
159 	YCbCr_20b = 0x0C,
160 	YCbCr_24b = 0x1C,
161 };
162 
163 #include "ite_it6161_hdmi_tx.h"
164 #include "ite_it6161_mipi_rx.h"
165 
166 // for sample clock
167 #define AUDFS_22p05KHz  4
168 #define AUDFS_44p1KHz 0
169 #define AUDFS_88p2KHz 8
170 #define AUDFS_176p4KHz    12
171 
172 #define AUDFS_24KHz  6
173 #define AUDFS_48KHz  2
174 #define AUDFS_96KHz  10
175 #define AUDFS_192KHz 14
176 
177 #define AUDFS_768KHz 9
178 
179 #define AUDFS_32KHz  3
180 #define AUDFS_OTHER    1
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 // HDMI VTable
184 ////////////////////////////////////////////////////////////////////////////////
185 static HDMI_VTiming const s_VMTable[] = {
186     { 1,0,640,480,800,525,25175000L,0x89,16,96,48,10,2,33,PROG,Vneg,Hneg},//640x480@60Hz
187     { 2,0,720,480,858,525,27000000L,0x80,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@60Hz
188     { 3,0,720,480,858,525,27000000L,0x80,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@60Hz
189     { 4,0,1280,720,1650,750,74250000L,0x2E,110,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@60Hz
190     { 5,0,1920,540,2200,562,74250000L,0x2E,88,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@60Hz
191     { 6,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
192     { 7,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
193     { 8,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
194     { 9,1,720,240,858,262,13500000L,0x100,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
195     {10,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
196     {11,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@60Hz
197     {12,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
198     {13,2,720,240,858,262,54000000L,0x40,19,62,57,4,3,15,PROG,Vneg,Hneg},//720x480(I)@60Hz
199     {14,1,1440,480,1716,525,54000000L,0x40,32,124,120,9,6,30,PROG,Vneg,Hneg},//1440x480@60Hz
200     {15,1,1440,480,1716,525,54000000L,0x40,32,124,120,9,6,30,PROG,Vneg,Hneg},//1440x480@60Hz
201     {16,0,1920,1080,2200,1125,148500000L,0x17,88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@60Hz
202     {17,0,720,576,864,625,27000000L,0x80,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@50Hz
203     {18,0,720,576,864,625,27000000L,0x80,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@50Hz
204     {19,0,1280,720,1980,750,74250000L,0x2E,440,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@50Hz
205     {20,0,1920,540,2640,562,74250000L,0x2E,528,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@50Hz
206     {21,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
207     {22,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
208     {23,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
209     {24,1,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
210     {25,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
211     {26,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@50Hz
212     {27,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
213     {28,2,720,288,864,312,13500000L,0x100,12,63,69,2,3,19,PROG,Vneg,Hneg},//1440x288@50Hz
214     {29,1,1440,576,1728,625,54000000L,0x40,24,128,136,5,5,39,PROG,Vpos,Hneg},//1440x576@50Hz
215     {30,1,1440,576,1728,625,54000000L,0x40,24,128,136,5,5,39,PROG,Vpos,Hneg},//1440x576@50Hz
216     {31,0,1920,1080,2640,1125,148500000L,0x17,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@50Hz
217     {32,0,1920,1080,2750,1125,74250000L,0x2E,638,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@24Hz
218     {33,0,1920,1080,2640,1125,74250000L,0x2E,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@25Hz
219     {34,0,1920,1080,2200,1125,74250000L,0x2E,88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@30Hz
220     {35,2,2880,480,1716*2,525,108000000L,0x20,32*2,124*2,120*2,9,6,30,PROG,Vneg,Hneg},//2880x480@60Hz
221     {36,2,2880,480,1716*2,525,108000000L,0x20,32*2,124*2,120*2,9,6,30,PROG,Vneg,Hneg},//2880x480@60Hz
222     {37,1,2880,576,3456,625,108000000L,0x20,24*2,128*2,136*2,5,5,39,PROG,Vneg,Hneg},//2880x576@50Hz
223     {38,2,2880,576,3456,625,108000000L,0x20,24*2,128*2,136*2,5,5,39,PROG,Vneg,Hneg},//2880x576@50Hz
224     {39,0,1920,540,2304,625,72000000L,0x17,32,168,184,23,5,57,INTERLACE,Vneg,Hpos},//1920x1080@50Hz
225     // 100Hz
226     {40,0,1920,540,2640,562,148500000L,0x17,528,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@100Hz
227     {41,0,1280,720,1980,750,148500000L,0x17,440,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@100Hz
228     {42,0,720,576,864,625,   54000000L,0x40,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@100Hz
229     {43,0,720,576,864,625,   54000000L,0x40,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@100Hz
230     {44,1,720,288,864,312,   27000000L,0x80,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@100Hz
231     {45,1,720,288,864,312,   27000000L,0x80,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@100Hz
232     // 120Hz
233     {46,0,1920,540,2200,562,148500000L,0x17,88,44,148,2,5,15,INTERLACE,Vpos,Hpos},//1920x1080(I)@120Hz
234     {47,0,1280,720,1650,750,148500000L,0x17,110,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@120Hz
235     {48,0, 720,480, 858,525, 54000000L,0x40,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
236     {49,0, 720,480, 858,525, 54000000L,0x40,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
237     {50,1, 720,240, 858,262, 27000000L,0x80,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
238     {51,1, 720,240, 858,262, 27000000L,0x80,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
239 
240     // 200Hz
241     {52,0,720,576,864,625,108000000L,0x20,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@200Hz
242     {53,0,720,576,864,625,108000000L,0x20,12,64,68,5,5,39,PROG,Vneg,Hneg},//720x576@200Hz
243     {54,1,720,288,864,312, 54000000L,0x40,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@200Hz
244     {55,1,720,288,864,312, 54000000L,0x40,12,63,69,2,3,19,INTERLACE,Vneg,Hneg},//1440x576(I)@200Hz
245     // 240Hz
246     {56,0,720,480,858,525,108000000L,0x20,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
247     {57,0,720,480,858,525,108000000L,0x20,16,62,60,9,6,30,PROG,Vneg,Hneg},//720x480@120Hz
248     {58,1,720,240,858,262, 54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
249     {59,1,720,240,858,262, 54000000L,0x40,19,62,57,4,3,15,INTERLACE,Vneg,Hneg},//720x480(I)@120Hz
250     // 720p low resolution
251     {60,0,1280, 720,3300, 750, 59400000L,0x3A,1760,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@24Hz
252     {61,0,1280, 720,3960, 750, 74250000L,0x2E,2420,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@25Hz
253     {62,0,1280, 720,3300, 750, 74250000L,0x2E,1760,40,220,5,5,20,PROG,Vpos,Hpos},//1280x720@30Hz
254     // 1080p high refresh rate
255     {63,0,1920,1080,2200,1125,297000000L,0x0B, 88,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@120Hz
256     {64,0,1920,1080,2640,1125,297000000L,0x0B,528,44,148,4,5,36,PROG,Vpos,Hpos},//1920x1080@100Hz
257     // VESA mode
258     {0,0,640,350,832,445,31500000L,0x6D,32,64,96,32,3,60,PROG,Vneg,Hpos},// 640x350@85
259     {0,0,640,400,832,445,31500000L,0x6D,32,64,96,1,3,41,PROG,Vneg,Hneg},// 640x400@85
260     {0,0,832,624,1152,667,57283000L,0x3C,32,64,224,1,3,39,PROG,Vneg,Hneg},// 832x624@75Hz
261     {0,0,720,350,900,449,28322000L,0x7A,18,108,54,59,2,38,PROG,Vneg,Hneg},// 720x350@70Hz
262     {0,0,720,400,900,449,28322000L,0x7A,18,108,54,13,2,34,PROG,Vpos,Hneg},// 720x400@70Hz
263     {0,0,720,400,936,446,35500000L,0x61,36,72,108,1,3,42,PROG,Vpos,Hneg},// 720x400@85
264     {0,0,640,480,800,525,25175000L,0x89,16,96,48,10,2,33,PROG,Vneg,Hneg},// 640x480@60
265     {0,0,640,480,832,520,31500000L,0x6D,24,40,128,9,3,28,PROG,Vneg,Hneg},// 640x480@72
266     {0,0,640,480,840,500,31500000L,0x6D,16,64,120,1,3,16,PROG,Vneg,Hneg},// 640x480@75
267     {0,0,640,480,832,509,36000000L,0x60,56,56,80,1,3,25,PROG,Vneg,Hneg},// 640x480@85
268     {0,0,800,600,1024,625,36000000L,0x60,24,72,128,1,2,22,PROG,Vpos,Hpos},// 800x600@56
269     {0,0,800,600,1056,628,40000000L,0x56,40,128,88,1,4,23,PROG,Vpos,Hpos},// 800x600@60
270     {0,0,800,600,1040,666,50000000L,0x45,56,120,64,37,6,23,PROG,Vpos,Hpos},// 800x600@72
271     {0,0,800,600,1056,625,49500000L,0x45,16,80,160,1,3,21,PROG,Vpos,Hpos},// 800x600@75
272     {0,0,800,600,1048,631,56250000L,0x3D,32,64,152,1,3,27,PROG,Vpos,Hpos},// 800X600@85
273     {0,0,848,480,1088,517,33750000L,0x66,16,112,112,6,8,23,PROG,Vpos,Hpos},// 840X480@60
274     {0,0,1024,384,1264,408,44900000L,0x4C,8,176,56,0,4,20,INTERLACE,Vpos,Hpos},//1024x768(I)@87Hz
275     {0,0,1024,768,1344,806,65000000L,0x35,24,136,160,3,6,29,PROG,Vneg,Hneg},// 1024x768@60
276     {0,0,1024,768,1328,806,75000000L,0x2E,24,136,144,3,6,29,PROG,Vneg,Hneg},// 1024x768@70
277     {0,0,1024,768,1312,800,78750000L,0x2B,16,96,176,1,3,28,PROG,Vpos,Hpos},// 1024x768@75
278     {0,0,1024,768,1376,808,94500000L,0x24,48,96,208,1,3,36,PROG,Vpos,Hpos},// 1024x768@85
279     {0,0,1152,864,1600,900,108000000L,0x20,64,128,256,1,3,32,PROG,Vpos,Hpos},// 1152x864@75
280     {0,0,1280,768,1440,790,68250000L,0x32,48,32,80,3,7,12,PROG,Vneg,Hpos},// 1280x768@60-R
281     {0,0,1280,768,1664,798,79500000L,0x2B,64,128,192,3,7,20,PROG,Vpos,Hneg},// 1280x768@60
282     {0,0,1280,768,1696,805,102250000L,0x21,80,128,208,3,7,27,PROG,Vpos,Hneg},// 1280x768@75
283     {0,0,1280,768,1712,809,117500000L,0x1D,80,136,216,3,7,31,PROG,Vpos,Hneg},// 1280x768@85
284     {0,0,1280,800,1440, 823, 71000000L,0x31, 48, 32, 80,3,6,14,PROG,Vpos,Hneg},// 1280x800@60Hz
285     {0,0,1280,800,1680, 831, 83500000L,0x29, 72,128,200,3,6,22,PROG,Vpos,Hneg},// 1280x800@60Hz
286     {0,0,1280,800,1696, 838,106500000L,0x20, 80,128,208,3,6,29,PROG,Vpos,Hneg},// 1280x800@75Hz
287     {0,0,1280,800,1712, 843,122500000L,0x1C, 80,136,216,3,6,34,PROG,Vpos,Hneg},// 1280x800@85Hz
288 	{0,0,1280,960,1800,1000,108000000L,0x20,96,112,312,1,3,36,PROG,Vpos,Hpos},// 1280x960@60
289     {0,0,1280,960,1728,1011,148500000L,0x17,64,160,224,1,3,47,PROG,Vpos,Hpos},// 1280x960@85
290     {0,0,1280,1024,1688,1066,108000000L,0x20,48,112,248,1,3,38,PROG,Vpos,Hpos},// 1280x1024@60
291     {0,0,1280,1024,1688,1066,135000000L,0x19,16,144,248,1,3,38,PROG,Vpos,Hpos},// 1280x1024@75
292     {0,0,1280,1024,1728,1072,157500000L,0x15,64,160,224,1,3,44,PROG,Vpos,Hpos},// 1280X1024@85
293     {0,0,1360,768,1792,795,85500000L,0x28,64,112,256,3,6,18,PROG,Vpos,Hpos},// 1360X768@60
294     {0,0,1366,768,1792,798,85500000L,0x28, 70,143,213,3,3,24,PROG,Vpos,Hpos},// 1366X768@60
295     {0,0,1366,768,1500,800,72000000L,0x30, 14, 56, 64,1,3,28,PROG,Vpos,Hpos},// 1360X768@60
296     {0,0,1400,1050,1560,1080,101000000L,0x22,48,32,80,3,4,23,PROG,Vneg,Hpos},// 1400x768@60-R
297     {0,0,1400,1050,1864,1089,121750000L,0x1C,88,144,232,3,4,32,PROG,Vpos,Hneg},// 1400x768@60
298     {0,0,1400,1050,1896,1099,156000000L,0x16,104,144,248,3,4,42,PROG,Vpos,Hneg},// 1400x1050@75
299     {0,0,1400,1050,1912,1105,179500000L,0x13,104,152,256,3,4,48,PROG,Vpos,Hneg},// 1400x1050@85
300     {0,0,1440,900,1600,926,88750000L,0x26,48,32,80,3,6,17,PROG,Vneg,Hpos},// 1440x900@60-R
301     {0,0,1440,900,1904,934,106500000L,0x20,80,152,232,3,6,25,PROG,Vpos,Hneg},// 1440x900@60
302     {0,0,1440,900,1936,942,136750000L,0x19,96,152,248,3,6,33,PROG,Vpos,Hneg},// 1440x900@75
303     {0,0,1440,900,1952,948,157000000L,0x16,104,152,256,3,6,39,PROG,Vpos,Hneg},// 1440x900@85
304     {0,0,1600,1200,2160,1250,162000000L,0x15,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@60
305     {0,0,1600,1200,2160,1250,175500000L,0x13,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@65
306     {0,0,1600,1200,2160,1250,189000000L,0x12,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@70
307     {0,0,1600,1200,2160,1250,202500000L,0x11,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@75
308     {0,0,1600,1200,2160,1250,229500000L,0x0F,64,192,304,1,3,46,PROG,Vpos,Hpos},// 1600x1200@85
309     {0,0,1680,1050,1840,1080,119000000L,0x1D,48,32,80,3,6,21,PROG,Vneg,Hpos},// 1680x1050@60-R
310     {0,0,1680,1050,2240,1089,146250000L,0x17,104,176,280,3,6,30,PROG,Vpos,Hneg},// 1680x1050@60
311     {0,0,1680,1050,2272,1099,187000000L,0x12,120,176,296,3,6,40,PROG,Vpos,Hneg},// 1680x1050@75
312     {0,0,1680,1050,2288,1105,214750000L,0x10,128,176,304,3,6,46,PROG,Vpos,Hneg},// 1680x1050@85
313     {0,0,1792,1344,2448,1394,204750000L,0x10,128,200,328,1,3,46,PROG,Vpos,Hneg},// 1792x1344@60
314     {0,0,1792,1344,2456,1417,261000000L,0x0D,96,216,352,1,3,69,PROG,Vpos,Hneg},// 1792x1344@75
315     {0,0,1856,1392,2528,1439,218250000L,0x0F,96,224,352,1,3,43,PROG,Vpos,Hneg},// 1856x1392@60
316     {0,0,1856,1392,2560,1500,288000000L,0x0C,128,224,352,1,3,104,PROG,Vpos,Hneg},// 1856x1392@75
317     {0,0,1920,1200,2080,1235,154000000L,0x16,48,32,80,3,6,26,PROG,Vneg,Hpos},// 1920x1200@60-R
318     {0,0,1920,1200,2592,1245,193250000L,0x11,136,200,336,3,6,36,PROG,Vpos,Hneg},// 1920x1200@60
319     {0,0,1920,1200,2608,1255,245250000L,0x0E,136,208,344,3,6,46,PROG,Vpos,Hneg},// 1920x1200@75
320     {0,0,1920,1200,2624,1262,281250000L,0x0C,144,208,352,3,6,53,PROG,Vpos,Hneg},// 1920x1200@85
321     {0,0,1920,1440,2600,1500,234000000L,0x0E,128,208,344,1,3,56,PROG,Vpos,Hneg},// 1920x1440@60
322     {0,0,1920,1440,2640,1500,297000000L,0x0B,144,224,352,1,3,56,PROG,Vpos,Hneg},// 1920x1440@75
323 };
324 
325 #define DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a)))
326 
327 static bool bChangeMode = false ;
328 static unsigned char CommunBuff[128] ;
329 
330 static const u8 CA[] = { 0,0,0, 02, 0x3, 0x7, 0xB, 0xF, 0x1F } ;
331 
332 static u32 VideoPixelClock ;
333 static u8 pixelrep ; // no pixelrepeating
334 // static HDMI_Aspec aspec ;
335 // static HDMI_Colorimetry Colorimetry ;
336 
337 static u32 ulAudioSampleFS = INPUT_SAMPLE_FREQ_HZ;
338 // u8 bAudioSampleFreq = INPUT_SAMPLE_FREQ ;
339 static u8 bOutputAudioChannel = OUTPUT_CHANNEL;
340 static u8 bOutputAudioType=CNOFIG_INPUT_AUDIO_TYPE;
341 
342 #define MSCOUNT 1000
343 #define LOADING_UPDATE_TIMEOUT (3000/32)    // 3sec
344 
345 static HDMITXDEV hdmiTxDev[HDMITX_MAX_DEV_COUNT];
346 
347 /* configuration */
348 //#define ENABLE_HDCP
349 #define ENABLE_MIPI_RX_EXTERNAL_CLOCK false
350 #define MPLaneSwap FALSE
351 #define MPPNSwap FALSE /* TRUE: MTK , FALSE: Solomon */
352 #define MIPI_RX_LANE_COUNT 4 /* 1~4 */
353 
354 #define OUTPUT_COLOR_MODE F_MODE_RGB444 /* F_MODE_YUV444, F_MODE_YUV422, F_MODE_RGB444 */
355 #define HDMI_TX_MODE HDMI_TX_ENABLE_DE_ONLY /* HDMI_TX_NONE, HDMI_TX_BY_PASS, HDMI_TX_ENABLE_DE_ONLY, HDMI_TX_ENABLE_PATTERN_GENERATOR */
356 #define HDMI_TX_PATTERN_GENERATOR_FORMAT 16 /* support format 2, 4, 16*/
357 #define HDMI_TX_PATTERN_COLLOR_R 0x03
358 #define HDMI_TX_PATTERN_COLLOR_G 0x00
359 #define HDMI_TX_PATTERN_COLLOR_B 0x00
360 
361 /* vendor option */
362 #define EOTPSel 0 /* LM option 0~15 */
363 #define EnDeSkew TRUE
364 #define PPIDbgSel 12/* 0~15 */
365 #define RegIgnrNull 1
366 #define RegIgnrBlk 1
367 #define RegEnDummyECC 0
368 #define LMDbgSel 0 /* 0~7 */
369 #define EnContCK TRUE
370 #define HSSetNum 3
371 #define EnMBPM FALSE /* enable MIPI Bypass Mode */
372 
373 #if (EnMBPM == TRUE)
374 #define PREC_Update TRUE//int PREC_Update = FALSE;  // enable P-timing update
375 #define MREC_Update TRUE//int MREC_Update = FALSE;  // enable M-timing update
376 #define EnTBPM TRUE /* enable HDMITX Bypass Mode */
377 #else
378 #define PREC_Update FALSE//int PREC_Update = FALSE; // enable P-timing update
379 #define MREC_Update FALSE//int MREC_Update = FALSE; // enable M-timing update
380 #define EnTBPM FALSE /* enable HDMITX Bypass Mode */
381 #endif
382 
383 #define REGSELDEF FALSE
384 #define MPForceStb FALSE
385 #define EnHReSync FALSE
386 #define EnVReSync FALSE
387 #define EnFReSync FALSE
388 #define EnVREnh FALSE
389 #define EnVREnhSel 1 /* 0:Div2, 1:Div4, 2:Div8, 3:Div16, 4:Div32 */
390 #define EnMAvg TRUE
391 
392 #if (IC_VERSION == 0xC0)
393 #define SkipStg 4
394 #else
395 #define SkipStg 2
396 #endif
397 
398 #if (IC_VERSION == 0xC0)
399 #define PDREFCLK FALSE
400 #else
401 #define PDREFCLK TRUE
402 #endif
403 
404 #define PDREFCNT 0 /* when PDREFCLK=TRUE, 0:div2, 1:div4, 2:div8, 3:divg16 */
405 #define EnIntWakeU3 FALSE
406 #define EnIOIDDQ FALSE
407 #define EnStb2Rst FALSE
408 #define EnExtStdby FALSE
409 #define EnStandby FALSE
410 
411 #if (IC_VERSION == 0xC0)
412 #define MShift 4//int MShift = 5; // default: 0 //fmt2 fmt4 :4
413 #define PPSFFRdStg 0x04//int PPSFFRdStg = 0x10; //PPSFFRdStg(2:0)
414 #define RegAutoSync TRUE//int RegAutoSync = TRUE;//add sync falling //pet:D0 20200211
415 #else
416 #define MShift 5//int MShift = 5; // default: 0 //fmt2 fmt4 :4
417 #define PPSFFRdStg 0x10//int PPSFFRdStg = 0x10; //PPSFFRdStg(2:0)
418 #endif //#if (IC_VERSION == 0xC0)
419 
420 #define PShift 3
421 #define EnFFAutoRst TRUE
422 
423 #define RegEnSyncErr FALSE//int RegEnSyncErr = FALSE;
424 #define EnTxCRC TRUE//int EnTxCRC = TRUE;
425 #define TxCRCnum (0x20) //D0 20200211//(0x00)//TxCRCnum(6:0)//int TxCRCnum = 0x00; //TxCRCnum(6:0)
426 
427 #if (IC_VERSION == 0xC0)
428 #define InvMCLK TRUE //FALSE for solomon, if NonUFO, MCLK max = 140MHz with InvMCLK=TRUE
429 #else
430 #define InvMCLK FALSE //FALSE for solomon, if NonUFO, MCLK max = 140MHz with InvMCLK=TRUE
431 #endif
432 
433 #define InvPCLK FALSE
434 
435 #ifndef INV_INPUT_PCLK
436 #define PCLKINV 0
437 #else
438 #define PCLKINV B_TX_VDO_LATCH_EDGE
439 #endif
440 
441 #ifndef INV_INPUT_ACLK
442     #define InvAudCLK 0
443 #else
444     #define InvAudCLK B_TX_AUDFMT_FALL_EDGE_SAMPLE_WS
445 #endif
446 
447 // #define INIT_CLK_LOW
448 
449 #define TxChSwap 0
450 #define TxPNSwap 0
451 
452 #define NRTXRCLK 1//int NRTXRCLK = true;//it6161b0 option true:set TRCLK by self
453 #define RCLKFreqSel 1// int RCLKFreqSel = true; // false:  10MHz(div1),  true  : 20 MHz(OSSDIV2)
454 // #ifdef REDUCE_HDMITX_SRC_JITTER
455 	// #define ForceTxCLKStb true// int ForceTxCLKStb = false;  //true:define _hdmitx_jitter_
456 // #else
457 	#define ForceTxCLKStb true //20200220 C code set true-> false
458 // #endif //#ifdef REDUCE_HDMITX_SRC_JITTER
459 static const RegSetEntry HDMITX_Init_Table[] = {
460     {0x0F, 0x40, 0x00},
461 	//PLL Reset
462     {0x62, 0x08, 0x00}, // XP_RESETB
463     {0x64, 0x04, 0x00}, // IP_RESETB
464     {0x0F, 0x01, 0x00}, // bank 0 ;3
465     #ifdef INIT_CLK_LOW
466         {0x62, 0x90, 0x10},
467         {0x64, 0x89, 0x09},
468         {0x68, 0x10, 0x10},
469     #endif
470 
471 
472 
473     // {0xD1, 0x0E, 0x0C},
474     // {0x65, 0x03, 0x00},
475     // #ifdef NON_SEQUENTIAL_YCBCR422 // for ITE HDMIRX
476         // {0x71, 0xFC, 0x1C},
477     // #else
478         // {0x71, 0xFC, 0x18},
479     // #endif
480 
481     {0x8D, 0xFF, CEC_I2C_SLAVE_ADDR},//EnCEC
482     //{0x0F, 0x08, 0x08},
483 	{0xA9, 0x80, (EnTBPM<<7)},// hdmitxset(0xa9, 0xc0, (EnTBPM<<7) + (EnTxPatMux<<6))
484 	{0xBF, 0x80, (NRTXRCLK<<7)},//from c code hdmitxset(0xbf, 0x80, (NRTXRCLK<<7));
485 
486 	// Initial Value
487     {0xF8,0xFF,0xC3},
488     {0xF8,0xFF,0xA5},
489 	//{0x05,0x1E,0x0C},//hdmitxset(0x05, 0x1E, (ForceRxOn<<4)+(RCLKPDSel<<2)+(RCLKPDEn<<1));ForceRxOn:F,RCLKPDSel=3,RCLKPDSel=false
490 	{0xF4,0x0C,0x00},//hdmitxset(0xF4, 0x0C, DDCSpeed<<2);//DDC75K
491 	{0xF3,0x02,0x00},//hdmitxset(0xF3, 0x02, ForceVOut<<1);//ForceVOut:false
492     // {0x20, 0x80, 0x80},//TODO: check need or not?
493     // {0x37, 0x01, 0x00},//TODO: check need or not?
494     // {0x20, 0x80, 0x00},//TODO: check need or not?
495     {0xF8,0xFF,0xFF},
496 	{0x5A,0x0C,0x0C},//hdmitxset(0x5A, 0x0C, 0x0C);
497 	{0xD1,0x0A,((ForceTxCLKStb)<<3)+0x02},//hdmitxset(0xD1, 0x0A, (ForceTxCLKStb<<3)+0x02);   // High Sensitivity , modified by junjie force "CLK_stable"
498 	{0x5D,0x04,((RCLKFreqSel)<<2)},//hdmitxset(0x5D, 0x04, (RCLKFreqSel<<2));//int RCLKFreqSel = true; // false:  10MHz(div1),  true  : 20 MHz(OSSDIV2)
499 	{0x65,0x03,0x00},//hdmitxset(0x65, 0x03, RINGOSC);
500 	{0x71,0xF9,((0<<6)+(0<<5)+(1<<4)+(1<<3)+0)},//hdmitxset(0x71, 0xF9, (XPStableTime<<6)+(EnXPLockChk<<5)+(EnPLLBufRst<<4)+(EnFFAutoRst<<3)+ EnFFManualRst);
501 	{0xCF,0xFF,(0<<7)+(0<<6)+(0<<4)+(0<<2)+0},//hdmitxset(0xCF, 0xFF, (EnPktLimitGB<<7)+(EnPktBlankGB<<6)+(KeepOutGBSel<<4)+(PktLimitGBSel<<2)+PktBlankGBSel);
502 
503 	{0xd1,0x02,0x00},//hdmitxset(0xd1, 0x02, 0x00);//VidStbSen = false
504     // 2014/01/07 HW Request for ROSC stable
505 
506     // {0x5D,0x03,0x01},
507     //~2014/01/07
508 // #ifdef USE_IT66120
509     // {0x5A, 0x02, 0x00},
510     // {0xE2, 0xFF, 0xFF},
511 // #endif
512 
513     {0x59, 0xD0, (((2-1)<<6)+(0<<4))},//hdmitxset(0x59, 0xD0, ((ManuallPR-1)<<6)+(DisLockPR<<4));ManuallPR=2, DisLockPR = 0
514 	// {0x59, 0xD8, 0x40|PCLKINV},
515 	#if((TxChSwap == 1) || (TxPNSwap == 1))
516 	{0x6b,0xC0,((TxChSwap<<7)+ (TxPNSwap<<6))},// hdmitxset(0x6b, 0xC0,(TxChSwap<<7)+ (TxPNSwap<<6));
517 	{0x61,0x40,0x40},// hdmitxset(0x61, 0x40,0x40);
518 	#endif //#if((TxChSwap ==true) || (TxPNSwap ==true))
519 
520 
521 	{0xE1, 0x20, InvAudCLK},// Inverse Audio Latch Edge of IACLK
522 	{0xF5, 0x40, 0x00},//hdmitxset(0xF5,0x40,ForceTMDSStable<<6);
523 
524     {0x05, 0xC0, 0x40},// Setup INT Pin: Active Low & Open-Drain
525 
526     // {REG_TX_INT_MASK1, 0xFF, ~(B_TX_RXSEN_MASK|B_TX_HPD_MASK)},
527     // {REG_TX_INT_MASK2, 0xFF, ~(B_TX_KSVLISTCHK_MASK|B_TX_AUTH_DONE_MASK|B_TX_AUTH_FAIL_MASK)},
528     // {REG_TX_INT_MASK3, 0xFF, ~(B_TX_VIDSTABLE_MASK)},
529     {0x0C, 0xFF, 0xFF},
530     {0x0D, 0xFF, 0xFF},
531     {0x0E, 0x03, 0x03},// Clear all Interrupt
532 
533     {0x0C, 0xFF, 0x00},
534     {0x0D, 0xFF, 0x00},
535     {0x0E, 0x02, 0x00},
536     //{0x09, 0x03, 0x00}, // Enable HPD and RxSen Interrupt//remove for interrupt mode allen
537     {0x20,0x01,0x00}
538 };
539 
540 static const RegSetEntry HDMITX_DefaultVideo_Table[] = {
541 
542     ////////////////////////////////////////////////////
543     // Config default output format.
544     ////////////////////////////////////////////////////
545     {0x72, 0xff, 0x00},
546     {0x70, 0xff, 0x00},
547 #ifndef DEFAULT_INPUT_YCBCR
548 // GenCSC\RGB2YUV_ITU709_16_235.c
549     {0x72, 0xFF, 0x02},
550     {0x73, 0xFF, 0x00},
551     {0x74, 0xFF, 0x80},
552     {0x75, 0xFF, 0x00},
553     {0x76, 0xFF, 0xB8},
554     {0x77, 0xFF, 0x05},
555     {0x78, 0xFF, 0xB4},
556     {0x79, 0xFF, 0x01},
557     {0x7A, 0xFF, 0x93},
558     {0x7B, 0xFF, 0x00},
559     {0x7C, 0xFF, 0x49},
560     {0x7D, 0xFF, 0x3C},
561     {0x7E, 0xFF, 0x18},
562     {0x7F, 0xFF, 0x04},
563     {0x80, 0xFF, 0x9F},
564     {0x81, 0xFF, 0x3F},
565     {0x82, 0xFF, 0xD9},
566     {0x83, 0xFF, 0x3C},
567     {0x84, 0xFF, 0x10},
568     {0x85, 0xFF, 0x3F},
569     {0x86, 0xFF, 0x18},
570     {0x87, 0xFF, 0x04},
571 #else
572 // GenCSC\YUV2RGB_ITU709_16_235.c
573     {0x0F, 0x01, 0x00},
574     {0x72, 0xFF, 0x03},
575     {0x73, 0xFF, 0x00},
576     {0x74, 0xFF, 0x80},
577     {0x75, 0xFF, 0x00},
578     {0x76, 0xFF, 0x00},
579     {0x77, 0xFF, 0x08},
580     {0x78, 0xFF, 0x53},
581     {0x79, 0xFF, 0x3C},
582     {0x7A, 0xFF, 0x89},
583     {0x7B, 0xFF, 0x3E},
584     {0x7C, 0xFF, 0x00},
585     {0x7D, 0xFF, 0x08},
586     {0x7E, 0xFF, 0x51},
587     {0x7F, 0xFF, 0x0C},
588     {0x80, 0xFF, 0x00},
589     {0x81, 0xFF, 0x00},
590     {0x82, 0xFF, 0x00},
591     {0x83, 0xFF, 0x08},
592     {0x84, 0xFF, 0x00},
593     {0x85, 0xFF, 0x00},
594     {0x86, 0xFF, 0x87},
595     {0x87, 0xFF, 0x0E},
596 #endif
597     // 2012/12/20 added by Keming's suggestion test
598     {0x88, 0xF0, 0x00},
599 };
600 static const RegSetEntry HDMITX_SetHDMI_Table[] = {
601 
602     ////////////////////////////////////////////////////
603     // Config default HDMI Mode
604     ////////////////////////////////////////////////////
605     {0xC0, 0x01, 0x01},
606     {0xC1, 0x03, 0x03},
607     {0xC6, 0x03, 0x03}
608 };
609 
610 static const RegSetEntry HDMITX_SetDVI_Table[] = {
611 
612     ////////////////////////////////////////////////////
613     // Config default HDMI Mode
614     ////////////////////////////////////////////////////
615     {0x0F, 0x01, 0x01},
616     {0x58, 0xFF, 0x00},
617     {0x0F, 0x01, 0x00},
618     {0xC0, 0x01, 0x00},
619     {0xC1, 0x03, 0x02},
620     {0xC6, 0x03, 0x00}
621 };
622 
623 static const RegSetEntry HDMITX_DefaultAVIInfo_Table[] = {
624 
625     ////////////////////////////////////////////////////
626     // Config default avi infoframe
627     ////////////////////////////////////////////////////
628     {0x0F, 0x01, 0x01},
629     {0x58, 0xFF, 0x10},
630     {0x59, 0xFF, 0x08},
631     {0x5A, 0xFF, 0x00},
632     {0x5B, 0xFF, 0x00},
633     {0x5C, 0xFF, 0x00},
634     {0x5D, 0xFF, 0x57},
635     {0x5E, 0xFF, 0x00},
636     {0x5F, 0xFF, 0x00},
637     {0x60, 0xFF, 0x00},
638     {0x61, 0xFF, 0x00},
639     {0x62, 0xFF, 0x00},
640     {0x63, 0xFF, 0x00},
641     {0x64, 0xFF, 0x00},
642     {0x65, 0xFF, 0x00},
643     {0x0F, 0x01, 0x00},
644     {0xCD, 0x03, 0x03}
645 };
646 static const RegSetEntry HDMITX_DeaultAudioInfo_Table[] = {
647 
648     ////////////////////////////////////////////////////
649     // Config default audio infoframe
650     ////////////////////////////////////////////////////
651     {0x0F, 0x01, 0x01},
652     {0x68, 0xFF, 0x00},
653     {0x69, 0xFF, 0x00},
654     {0x6A, 0xFF, 0x00},
655     {0x6B, 0xFF, 0x00},
656     {0x6C, 0xFF, 0x00},
657     {0x6D, 0xFF, 0x71},
658     {0x0F, 0x01, 0x00},
659     {0xCE, 0x03, 0x03}
660 };
661 
662 static const RegSetEntry HDMITX_Aud_CHStatus_LPCM_20bit_48Khz[] =
663 {
664     {0x0F, 0x01, 0x01},
665     {0x33, 0xFF, 0x00},
666     {0x34, 0xFF, 0x18},
667     {0x35, 0xFF, 0x00},
668     {0x91, 0xFF, 0x00},
669     {0x92, 0xFF, 0x00},
670     {0x93, 0xFF, 0x01},
671     {0x94, 0xFF, 0x00},
672     {0x98, 0xFF, 0x02},
673     {0x99, 0xFF, 0xDA},
674     {0x0F, 0x01, 0x00}
675 } ;
676 
677 static const RegSetEntry HDMITX_AUD_SPDIF_2ch_24bit[] =
678 {
679     {0x0F, 0x11, 0x00},
680     {0x04, 0x14, 0x04},
681     {0xE0, 0xFF, 0xD1},
682     {0xE1, 0xFF, 0x01},
683     {0xE2, 0xFF, 0xE4},
684     {0xE3, 0xFF, 0x10},
685     {0xE4, 0xFF, 0x00},
686     {0xE5, 0xFF, 0x00},
687     {0x04, 0x14, 0x00}
688 } ;
689 
690 static const RegSetEntry HDMITX_AUD_I2S_2ch_24bit[] =
691 {
692     {0x0F, 0x11, 0x00},
693     {0x04, 0x14, 0x04},
694     {0xE0, 0xFF, 0xC1},
695     {0xE1, 0xFF, 0x01},
696 #ifdef USE_IT66120
697     {0x5A, 0x02, 0x00},
698     {0xE2, 0xFF, 0xFF},
699 #else
700     {0xE2, 0xFF, 0xE4},
701 #endif
702     {0xE3, 0xFF, 0x00},
703     {0xE4, 0xFF, 0x00},
704     {0xE5, 0xFF, 0x00},
705     {0x04, 0x14, 0x00}
706 } ;
707 
708 static const RegSetEntry HDMITX_DefaultAudio_Table[] = {
709 
710     ////////////////////////////////////////////////////
711     // Config default audio output format.
712     ////////////////////////////////////////////////////
713     {0x0F, 0x21, 0x00},
714     {0x04, 0x14, 0x04},
715     {0xE0, 0xFF, 0xC1},
716     {0xE1, 0xFF, 0x01},
717 #ifdef USE_IT66120
718     {0xE2, 0xFF, 0xFF},
719 #else
720     {0xE2, 0xFF, 0xE4},
721 #endif
722     {0xE3, 0xFF, 0x00},
723     {0xE4, 0xFF, 0x00},
724     {0xE5, 0xFF, 0x00},
725     {0x0F, 0x01, 0x01},
726     {0x33, 0xFF, 0x00},
727     {0x34, 0xFF, 0x18},
728     {0x35, 0xFF, 0x00},
729     {0x91, 0xFF, 0x00},
730     {0x92, 0xFF, 0x00},
731     {0x93, 0xFF, 0x01},
732     {0x94, 0xFF, 0x00},
733     {0x98, 0xFF, 0x02},
734     {0x99, 0xFF, 0xDB},
735     {0x0F, 0x01, 0x00},
736     {0x04, 0x14, 0x00}
737 } ;
738 
739 static const RegSetEntry HDMITX_PwrDown_Table[] = {
740 	{0x05, 0x60, 0x60},
741 	 {0xf8, 0xc3},
742      {0xf8, 0xa5},
743      {0xe8, 0x60},
744 	 {0xE0, 0x0F, 0x00},
745 	 // Enable GRCLK
746 	 // #if (IC_VERSION == 0xC0)
747      // {0x0F, 0x40, 0x00},
748 	 // #else
749 	 // {0x0F, 0x70, 0x70},// PwrDown RCLK , IACLK ,TXCLK
750 	 // #endif //#if (IC_VERSION == 0xC0)
751      // PLL Reset
752      {0x61, 0x10, 0x10},   // DRV_RST
753      {0x62, 0x08, 0x00},   // XP_RESETB
754      {0x64, 0x04, 0x00},   // IP_RESETB
755      {0x01, 0x00, 0x00}, // idle(100);
756 
757 	 {0x61, 0x60, 0x60},
758 
759 	 {0x70, 0xFF, 0x00},//hdmitxwr(0x70, 0x00);      // Select TXCLK power-down path
760      // PLL PwrDn
761      // {0x61, 0x20, 0x20},   // PwrDn DRV
762      // {0x62, 0x44, 0x44},   // PwrDn XPLL
763      // {0x64, 0x40, 0x40},   // PwrDn IPLL
764 
765      // HDMITX PwrDn
766      // {0x05, 0x01, 0x01},   // PwrDn PCLK
767      // {0xE0, 0x0F, 0x00},// hdmitxset(0xE0, 0x0F, 0x00);   // PwrDn GIACLK, IACLK
768      // {0x72, 0x03, 0x00},// hdmitxset(0x72, 0x03, 0x00);   // PwrDn GTxCLK (QCLK)
769      // {0x0F, 0x78, 0x78},   // PwrDn GRCLK
770 	 {0x0F, 0x70, 0x70}//Gate RCLK IACLK TXCLK
771 };
772 
773 static const RegSetEntry HDMITX_PwrOn_Table[] = {
774     {0x0F, 0x70, 0x00},   // // PwrOn RCLK , IACLK ,TXCLK
775 	// {0x0F, 0x78, 0x38},   // PwrOn GRCLK
776     // {0x05, 0x01, 0x00},   // PwrOn PCLK
777 
778     // PLL PwrOn
779     {0x61, 0x20, 0x00},   // PwrOn DRV
780     {0x62, 0x44, 0x00},   // PwrOn XPLL
781     {0x64, 0x40, 0x00},   // PwrOn IPLL
782 
783     // PLL Reset OFF
784     {0x61, 0x10, 0x00},   // DRV_RST
785     {0x62, 0x08, 0x08},   // XP_RESETB
786     {0x64, 0x04, 0x04}   // IP_RESETB
787     // {0x0F, 0x78, 0x08},   // PwrOn IACLK
788 };
789 
790 static const RegSetEntry hdmi_tx_pg_1080p60_table[] = {
791 // 1920x1080@60.00Hz VIC = 16
792 	{0x0F, 0xFF, 0x00},
793 	{0x90, 0xFF, 0x76},
794 	{0x91, 0xFF, 0x89},
795 	{0x92, 0xFF, 0xC0},
796 	{0x93, 0xFF, 0x40},
797 	{0x94, 0xFF, 0x80},
798 	{0x95, 0xFF, 0x00},
799 	{0x96, 0xFF, 0x2C},
800 	{0x97, 0xFF, 0x00},
801 	{0x98, 0xFF, 0x64},
802 	{0x99, 0xFF, 0x04},
803 	{0x9A, 0xFF, 0x28},
804 	{0x9B, 0xFF, 0x60},
805 	{0x9C, 0xFF, 0x40},
806 	{0x9D, 0xFF, 0xFF},
807 	{0x9E, 0xFF, 0xFF},
808 	{0x9F, 0xFF, 0xFF},
809 	{0xA0, 0xFF, 0x00},
810 	{0xA1, 0xFF, 0x50},
811 	{0xA2, 0xFF, 0xFF},
812 	{0xA3, 0xFF, 0xFF},
813 	{0xA4, 0xFF, 0x4C},
814 	{0xA5, 0xFF, 0x04},
815 	{0xA6, 0xFF, 0xF0},
816 	{0xB1, 0xFF, 0x00},
817 	{0xB2, 0xFF, 0x00},
818 	{0xA9, 0xFF, 0x70},
819 	{0xAA, 0xFF, 0x00},
820 	{0xAB, 0xFF, 0x00},
821 	{0xAC, 0xFF, 0x00},
822 	{0xAF, 0xFF, 0x00},
823 	{0xB0, 0xFF, 0x00}
824 };
825 
826 static const RegSetEntry hdmi_tx_pg_720p60_table[] = {
827 // PatGen\fmt4_PatGen.c
828 // 1280x720@60.00Hz VIC = 4
829     {0x0F, 0x01, 0x00},
830     {0x90, 0xFF, 0x16},
831     {0x91, 0xFF, 0x67},
832     {0x92, 0xFF, 0x04},
833     {0x93, 0xFF, 0x04},
834     {0x94, 0xFF, 0x61},
835     {0x95, 0xFF, 0x00},
836     {0x96, 0xFF, 0x28},
837     {0x97, 0xFF, 0x00},
838     {0x98, 0xFF, 0xED},
839     {0x99, 0xFF, 0x02},
840     {0x9A, 0xFF, 0x18},
841     {0x9B, 0xFF, 0xE8},
842     {0x9C, 0xFF, 0x20},
843     {0x9D, 0xFF, 0xFF},
844     {0x9E, 0xFF, 0xFF},
845     {0x9F, 0xFF, 0xFF},
846     {0xA0, 0xFF, 0x00},
847     {0xA1, 0xFF, 0x50},
848     {0xA2, 0xFF, 0xFF},
849     {0xA3, 0xFF, 0xFF},
850     {0xA4, 0xFF, 0x39},
851     {0xA5, 0xFF, 0x03},
852     {0xA6, 0xFF, 0xF0},
853     {0xB1, 0xFF, 0x00},
854     {0xB2, 0xFF, 0x00},
855 	{0xA9, 0xFF, 0x70},
856 	{0xAA, 0xFF, 0x00},
857 	{0xAB, 0xFF, 0x00},
858 	{0xAC, 0xFF, 0x00},
859 	{0xAF, 0xFF, 0x00},
860 	{0xB0, 0xFF, 0x00}
861 };
862 static const RegSetEntry hdmi_tx_pg_480p60_table[] = {
863 // PatGen\fmt2_PatGen.c
864 // 720x480@59.94Hz VIC = 2
865     {0x0F, 0x01, 0x00},
866     {0x90, 0xFF, 0x90},
867     {0x91, 0xFF, 0x35},
868     {0x92, 0xFF, 0x7A},
869     {0x93, 0xFF, 0x4A},
870     {0x94, 0xFF, 0x30},
871     {0x95, 0xFF, 0x00},
872     {0x96, 0xFF, 0x3E},
873     {0x97, 0xFF, 0x00},
874     {0x98, 0xFF, 0x0C},
875     {0x99, 0xFF, 0x02},
876     {0x9A, 0xFF, 0x23},
877     {0x9B, 0xFF, 0x03},
878     {0x9C, 0xFF, 0x20},
879     {0x9D, 0xFF, 0x30},
880     {0x9E, 0xFF, 0x10},
881     {0x9F, 0xFF, 0x42},
882     {0xA0, 0xFF, 0x00},
883     {0xA1, 0xFF, 0x60},
884     {0xA2, 0xFF, 0x0D},
885     {0xA3, 0xFF, 0x32},
886     {0xA4, 0xFF, 0xAC},
887     {0xA5, 0xFF, 0x01},
888     {0xA6, 0xFF, 0x10},
889     {0xB1, 0xFF, 0x00},
890     {0xB2, 0xFF, 0x00},
891     // {0xA9, 0xFF, 0x7F},
892 	{0xA9, 0xFF, 0x70},
893 	{0xAA, 0xFF, 0x00},
894 	{0xAB, 0xFF, 0x00},
895 	{0xAC, 0xFF, 0x00},
896 	{0xAF, 0xFF, 0x00},
897 	{0xB0, 0xFF, 0x00}
898 };
899 
900 #ifdef DETECT_VSYNC_CHG_IN_SAV
901 static bool EnSavVSync = false ;
902 #endif
903 
904 /* Period of hdcp checks (to ensure we're still authenticated) */
905 #define DRM_HDCP_CHECK_PERIOD_MS		(128 * 16)
906 #define DRM_HDCP2_CHECK_PERIOD_MS		500
907 
908 /* Shared lengths/masks between HDMI/DVI/DisplayPort */
909 #define DRM_HDCP_AN_LEN				8
910 #define DRM_HDCP_BSTATUS_LEN			2
911 #define DRM_HDCP_KSV_LEN			5
912 #define DRM_HDCP_RI_LEN				2
913 #define DRM_HDCP_V_PRIME_PART_LEN		4
914 #define DRM_HDCP_V_PRIME_NUM_PARTS		5
915 #define DRM_HDCP_NUM_DOWNSTREAM(x)		(x & 0x7f)
916 #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x)	(x & BIT(3))
917 #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x)		(x & BIT(7))
918 
919 /* Slave address for the HDCP registers in the receiver */
920 #define DRM_HDCP_DDC_ADDR			0x3A
921 
922 /* Value to use at the end of the SHA-1 bytestream used for repeaters */
923 #define DRM_HDCP_SHA1_TERMINATOR		0x80
924 
925 /* HDCP register offsets for HDMI/DVI devices */
926 #define DRM_HDCP_DDC_BKSV			0x00
927 #define DRM_HDCP_DDC_RI_PRIME			0x08
928 #define DRM_HDCP_DDC_AKSV			0x10
929 #define DRM_HDCP_DDC_AN				0x18
930 #define DRM_HDCP_DDC_V_PRIME(h)			(0x20 + h * 4)
931 #define DRM_HDCP_DDC_BCAPS			0x40
932 #define DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT	BIT(6)
933 #define DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY	BIT(5)
934 #define DRM_HDCP_DDC_BSTATUS			0x41
935 #define DRM_HDCP_DDC_KSV_FIFO			0x43
936 
937 #define MAX_HDCP_DOWN_STREAM_COUNT 10
938 #define HDCP_SHA1_FIFO_LEN (MAX_HDCP_DOWN_STREAM_COUNT * 5 + 10)
939 #define HDMI_TX_HDCP_RETRY 3
940 #define HDMI_TX_PCLK_DIV2 false
941 
942 #ifndef __linux__
943 
944 extern const struct drm_display_mode edid_cea_modes[];
945 
946 #endif
947 
948 struct it6161 {
949 	struct device *dev;
950 	struct drm_bridge bridge;
951 	struct i2c_client *i2c_mipi_rx;
952 	struct i2c_client *i2c_hdmi_tx;
953 	struct i2c_client *i2c_cec;
954 	struct edid *edid;
955 	struct drm_connector connector;
956 	struct mutex mode_lock;
957 	struct regmap *regmap_mipi_rx;
958 	struct regmap *regmap_hdmi_tx;
959 	struct regmap *regmap_cec;
960 	u32 it6161_addr_hdmi_tx;
961 	u32 it6161_addr_cec;
962 	struct device_node *host_node;
963 	struct mipi_dsi_device *dsi;
964 	struct completion wait_hdcp_event;
965 	struct completion wait_edid_complete;
966 	struct delayed_work hdcp_work;
967 	struct work_struct wait_hdcp_ksv_list;
968 	u8 hdmi_tx_hdcp_retry;
969 	/* kHz */
970 	u32 hdmi_tx_rclk;
971 	/* kHz */
972 	u32 hdmi_tx_pclk;
973 	/* kHz */
974 	u32 mipi_rx_mclk;
975 	/* kHz */
976 	u32 mipi_rx_rclk;
977 	/* kHz */
978 	u32 mipi_rx_pclk;
979 	struct drm_display_mode mipi_rx_p_display_mode;
980 	struct drm_display_mode hdmi_tx_display_mode;
981 	struct drm_display_mode source_display_mode;
982 	struct hdmi_avi_infoframe source_avi_infoframe;
983 	u32 vic;
984     u8 mipi_rx_lane_count;
985 	bool is_repeater;
986 	u8 hdcp_downstream_count;
987 	u8 bksv[DRM_HDCP_KSV_LEN];
988 	u8 sha1_transform_input[HDCP_SHA1_FIFO_LEN];
989 	u16 bstatus;
990 	bool enable_drv_hold;
991 	u8 hdmi_tx_output_color_space;
992 	u8 hdmi_tx_input_color_space;
993 	u8 hdmi_tx_mode;
994     u8 support_audio;
995 
996     u8 bOutputAudioMode;
997     u8 bAudioChannelSwap;
998     u8 bAudioChannelEnable;
999     u8 bAudFs ;
1000     u32 TMDSClock ;
1001     u32 RCLK ;
1002     #ifdef _SUPPORT_HDCP_REPEATER_
1003         HDMITX_HDCP_State TxHDCP_State ;
1004         u16 usHDCPTimeOut ;
1005         u16 Tx_BStatus ;
1006     #endif
1007     u8 bAuthenticated:1 ;
1008     bool hdmi_mode;
1009     u8 bAudInterface;
1010 
1011 	struct gpio_desc *reset_gpio;
1012 	struct gpio_desc *enable_gpio;
1013 	struct gpio_desc *test_gpio;
1014 
1015 	struct timer_list timer;
1016 	struct delayed_work	restart;
1017 };
1018 
1019 static struct it6161 *it6161;
1020 //static struct it6161 *it6161_dump;
1021 static struct drm_bridge *it6161_bridge;
1022 
1023 static const struct regmap_range it6161_mipi_rx_bridge_volatile_ranges[] = {
1024 	{ .range_min = 0, .range_max = 0xFF },
1025 };
1026 
1027 static const struct regmap_access_table it6161_mipi_rx_bridge_volatile_table = {
1028 	.yes_ranges = it6161_mipi_rx_bridge_volatile_ranges,
1029 	.n_yes_ranges = ARRAY_SIZE(it6161_mipi_rx_bridge_volatile_ranges),
1030 };
1031 
1032 static const struct regmap_config it6161_mipi_rx_bridge_regmap_config = {
1033 	.reg_bits = 8,
1034 	.val_bits = 8,
1035 	.volatile_table = &it6161_mipi_rx_bridge_volatile_table,
1036 	.cache_type = REGCACHE_NONE,
1037 };
1038 
1039 static const struct regmap_range it6161_hdmi_tx_bridge_volatile_ranges[] = {
1040 	{ .range_min = 0, .range_max = 0xFF },
1041 };
1042 
1043 static const struct regmap_access_table it6161_hdmi_tx_bridge_volatile_table = {
1044 	.yes_ranges = it6161_hdmi_tx_bridge_volatile_ranges,
1045 	.n_yes_ranges = ARRAY_SIZE(it6161_hdmi_tx_bridge_volatile_ranges),
1046 };
1047 
1048 static const struct regmap_config it6161_hdmi_tx_bridge_regmap_config = {
1049 	.reg_bits = 8,
1050 	.val_bits = 8,
1051 	.volatile_table = &it6161_hdmi_tx_bridge_volatile_table,
1052 	.cache_type = REGCACHE_NONE,
1053 };
1054 
1055 static const struct regmap_range it6161_cec_bridge_volatile_ranges[] = {
1056     { .range_min = 0, .range_max = 0xFF },
1057 };
1058 
1059 static const struct regmap_access_table it6161_cec_bridge_volatile_table = {
1060     .yes_ranges = it6161_cec_bridge_volatile_ranges,
1061     .n_yes_ranges = ARRAY_SIZE(it6161_cec_bridge_volatile_ranges),
1062 };
1063 
1064 static const struct regmap_config it6161_cec_bridge_regmap_config = {
1065     .reg_bits = 8,
1066     .val_bits = 8,
1067     .volatile_table = &it6161_cec_bridge_volatile_table,
1068     .cache_type = REGCACHE_NONE,
1069 };
1070 
it6161_mipi_rx_read(struct it6161 * it6161,unsigned int reg_addr)1071 static int it6161_mipi_rx_read(struct it6161 *it6161, unsigned int reg_addr)
1072 {
1073 	unsigned int value;
1074 	int err;
1075 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1076 
1077 	err = regmap_read(it6161->regmap_mipi_rx, reg_addr, &value);
1078 	if (err < 0) {
1079 		DRM_DEV_ERROR(dev, "mipi rx read failed reg[0x%x] err: %d", reg_addr,
1080 			      err);
1081 		return err;
1082 	}
1083 
1084 	return value;
1085 }
1086 
mipi_rx_read_word(struct it6161 * it6161,unsigned int reg)1087 static int mipi_rx_read_word(struct it6161 *it6161, unsigned int reg)
1088 {
1089 	int val_0, val_1;
1090 
1091 	val_0 = it6161_mipi_rx_read(it6161, reg);
1092 
1093 	if (val_0 < 0)
1094 		return val_0;
1095 
1096 	val_1 = it6161_mipi_rx_read(it6161, reg + 1);
1097 
1098 	if (val_1 < 0)
1099 		return val_1;
1100 
1101 	return (val_1 << 8) | val_0;
1102 }
1103 
it6161_mipi_rx_write(struct it6161 * it6161,unsigned int reg_addr,unsigned int reg_val)1104 static int it6161_mipi_rx_write(struct it6161 *it6161, unsigned int reg_addr,
1105 		      unsigned int reg_val)
1106 {
1107 	int err;
1108 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1109 
1110 	err = regmap_write(it6161->regmap_mipi_rx, reg_addr, reg_val);
1111 
1112 	if (err < 0) {
1113 		DRM_DEV_ERROR(dev, "mipi rx write failed reg[0x%x] = 0x%x err = %d",
1114 			      reg_addr, reg_val, err);
1115 		return err;
1116 	}
1117 
1118 	return 0;
1119 }
1120 
it6161_mipi_rx_set_bits(struct it6161 * it6161,unsigned int reg,unsigned int mask,unsigned int value)1121 static int it6161_mipi_rx_set_bits(struct it6161 *it6161, unsigned int reg,
1122 			 unsigned int mask, unsigned int value)
1123 {
1124 	int err;
1125 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1126 
1127 	err = regmap_update_bits(it6161->regmap_mipi_rx, reg, mask, value);
1128 	if (err < 0) {
1129 		DRM_DEV_ERROR(
1130 			dev, "mipi rx set reg[0x%x] = 0x%x mask = 0x%x failed err %d",
1131 			reg, value, mask, err);
1132 		return err;
1133 	}
1134 
1135 	return 0;
1136 }
1137 
1138 #if 0
1139 static void it6161_mipi_rx_dump(struct it6161 *it6161)
1140 {
1141 	unsigned int i, j;
1142 	u8 regs[16];
1143 	//struct device *dev = &it6161->i2c_mipi_rx->dev;
1144 
1145 	it6161_debug("mipi rx dump:");
1146 	for (i = 0; i <= 0xff; i += 16) {
1147 		for (j = 0; j < 16; j++)
1148 			regs[j] = it6161_mipi_rx_read(it6161, i + j);
1149 
1150 		it6161_debug("[0x%02x] = %16ph", i, regs);
1151 	}
1152 }
1153 #endif
1154 
it6161_hdmi_tx_read(struct it6161 * it6161,unsigned int reg_addr)1155 static int it6161_hdmi_tx_read(struct it6161 *it6161, unsigned int reg_addr)
1156 {
1157 	unsigned int value;
1158 	int err;
1159 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1160 
1161 	err = regmap_read(it6161->regmap_hdmi_tx, reg_addr, &value);
1162 	if (err < 0) {
1163 		DRM_DEV_ERROR(dev, "hdmi tx read failed reg[0x%x] err: %d", reg_addr,
1164 			      err);
1165 		return err;
1166 	}
1167 
1168 	return value;
1169 }
1170 
hdmi_tx_read_word(struct it6161 * it6161,unsigned int reg)1171 static int hdmi_tx_read_word(struct it6161 *it6161, unsigned int reg)
1172 {
1173 	int val_0, val_1;
1174 
1175 	val_0 = it6161_hdmi_tx_read(it6161, reg);
1176 
1177 	if (val_0 < 0)
1178 		return val_0;
1179 
1180 	val_1 = it6161_hdmi_tx_read(it6161, reg + 1);
1181 
1182 	if (val_1 < 0)
1183 		return val_1;
1184 
1185 	return (val_1 << 8) | val_0;
1186 }
1187 
1188 #ifdef HDCP
it6161_hdmi_tx_burst_read(struct it6161 * it6161,unsigned int reg_addr,void * buffer,size_t size)1189 static int it6161_hdmi_tx_burst_read(struct it6161 *it6161, unsigned int reg_addr, void *buffer, size_t size)
1190 {
1191 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1192 	int ret;
1193 
1194 	ret = regmap_bulk_read(it6161->regmap_hdmi_tx, reg_addr, buffer, size);
1195 	if (ret < 0)
1196 		DRM_DEV_ERROR(dev, "hdmi tx burst read failed reg[0x%x] ret: %d",
1197 			      reg_addr, ret);
1198 
1199 	return ret;
1200 }
1201 #endif
it6161_hdmi_tx_write(struct it6161 * it6161,unsigned int reg_addr,unsigned int reg_val)1202 static int it6161_hdmi_tx_write(struct it6161 *it6161, unsigned int reg_addr,
1203 				unsigned int reg_val)
1204 {
1205 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1206 	int err;
1207 
1208 	err = regmap_write(it6161->regmap_hdmi_tx, reg_addr, reg_val);
1209 
1210 	if (err < 0) {
1211 		DRM_DEV_ERROR(dev, "hdmi tx write failed reg[0x%x] = 0x%x err = %d",
1212 			      reg_addr, reg_val, err);
1213 		return err;
1214 	}
1215 
1216 	return 0;
1217 }
1218 
1219 #if 0
1220 static int hdmi_tx_burst_write(struct it6161 *it6161, unsigned int reg_addr,
1221 			       void *buffer, size_t size)
1222 {
1223 	struct device *dev = &it6161->i2c_hdmi_tx->dev;
1224 	int ret;
1225 
1226 	ret = regmap_bulk_write(it6161->regmap_hdmi_tx, reg_addr,
1227 				(u8 *)buffer, size);
1228 
1229 	if (ret < 0) {
1230 		DRM_DEV_ERROR(dev, "hdmi tx burst write failed reg[0x%x] ret = %d",
1231 			      reg_addr, ret);
1232 		return ret;
1233 	}
1234 
1235 	return ret;
1236 }
1237 #endif
1238 
it6161_hdmi_tx_set_bits(struct it6161 * it6161,unsigned int reg,unsigned int mask,unsigned int value)1239 static int it6161_hdmi_tx_set_bits(struct it6161 *it6161, unsigned int reg,
1240 			 unsigned int mask, unsigned int value)
1241 {
1242 	int err;
1243 	struct device *dev = &it6161->i2c_mipi_rx->dev;
1244 
1245 	err = regmap_update_bits(it6161->regmap_hdmi_tx, reg, mask, value);
1246 	if (err < 0) {
1247 		DRM_DEV_ERROR(
1248 			dev, "hdmi tx set reg[0x%x] = 0x%x mask = 0x%x failed err %d",
1249 			reg, value, mask, err);
1250 		return err;
1251 	}
1252 
1253 	return 0;
1254 }
1255 
it6161_hdmi_tx_change_bank(struct it6161 * it6161,int x)1256 static int inline it6161_hdmi_tx_change_bank(struct it6161 *it6161, int x)
1257 {
1258 	return it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, x & 0x03);
1259 }
1260 
1261 #if 0
1262 static void it6161_hdmi_tx_dump(struct it6161 *it6161, unsigned int bank)
1263 {
1264 	unsigned int i, j;
1265 	u8 regs[16];
1266 	//struct device *dev = &it6161->i2c_mipi_rx->dev;
1267 
1268 	it6161_debug("hdmi tx dump bank: %d", bank);
1269 	it6161_hdmi_tx_change_bank(it6161, bank);
1270 
1271 	for (i = 0; i <= 0xff; i += 16) {
1272 		for (j = 0; j < 16; j++)
1273 			regs[j] = it6161_hdmi_tx_read(it6161, i + j);
1274 
1275 		it6161_debug("[0x%02x] = %16ph", i, regs);
1276 	}
1277 }
1278 #endif
1279 
it6161_cec_read(struct it6161 * it6161,unsigned int reg_addr)1280 static int it6161_cec_read(struct it6161 *it6161, unsigned int reg_addr)
1281 {
1282     unsigned int value;
1283     int err;
1284     struct device *dev = &it6161->i2c_mipi_rx->dev;
1285 
1286     err = regmap_read(it6161->regmap_cec, reg_addr, &value);
1287     if (err < 0) {
1288         DRM_DEV_ERROR(dev, "cec read failed reg[0x%x] err: %d", reg_addr,
1289                   err);
1290         return err;
1291     }
1292 
1293     return value;
1294 }
1295 
it6161_cec_write(struct it6161 * it6161,unsigned int reg_addr,unsigned int reg_val)1296 static int it6161_cec_write(struct it6161 *it6161, unsigned int reg_addr,
1297               unsigned int reg_val)
1298 {
1299     int err;
1300     struct device *dev = &it6161->i2c_mipi_rx->dev;
1301 
1302     err = regmap_write(it6161->regmap_cec, reg_addr, reg_val);
1303 
1304     if (err < 0) {
1305         DRM_DEV_ERROR(dev, "cec write failed reg[0x%x] = 0x%x err = %d",
1306                   reg_addr, reg_val, err);
1307         return err;
1308     }
1309 
1310     return 0;
1311 }
1312 
1313 #if 0
1314 static int it6161_cec_set_bits(struct it6161 *it6161, unsigned int reg,
1315              unsigned int mask, unsigned int value)
1316 {
1317     int err;
1318     struct device *dev = &it6161->i2c_mipi_rx->dev;
1319 
1320     err = regmap_update_bits(it6161->regmap_cec, reg, mask, value);
1321     if (err < 0) {
1322         DRM_DEV_ERROR(
1323             dev, "cec set reg[0x%x] = 0x%x mask = 0x%x failed err %d",
1324             reg, value, mask, err);
1325         return err;
1326     }
1327 
1328     return 0;
1329 }
1330 #endif
1331 
connector_to_it6161(struct drm_connector * c)1332 static inline struct it6161 *connector_to_it6161(struct drm_connector *c)
1333 {
1334 	return container_of(c, struct it6161, connector);
1335 }
1336 
bridge_to_it6161(struct drm_bridge * bridge)1337 static inline struct it6161 *bridge_to_it6161(struct drm_bridge *bridge)
1338 {
1339 	return container_of(bridge, struct it6161, bridge);
1340 }
1341 
mipi_rx_logic_reset(struct it6161 * it6161)1342 static void mipi_rx_logic_reset(struct it6161 *it6161)
1343 {
1344     it6161_mipi_rx_set_bits(it6161, 0x05, 0x08, 0x08);
1345 }
1346 
mipi_rx_logic_reset_release(struct it6161 * it6161)1347 static void mipi_rx_logic_reset_release(struct it6161 *it6161)
1348 {
1349     it6161_mipi_rx_set_bits(it6161, 0x05, 0x08, 0x00);
1350 }
1351 
hdmi_tx_logic_reset(struct it6161 * it6161)1352 static void hdmi_tx_logic_reset(struct it6161 *it6161)
1353 {
1354     it6161_hdmi_tx_set_bits(it6161, 0x04, 0x20, 0x20);
1355 }
1356 
it6161_mipi_rx_int_mask_disable(struct it6161 * it6161)1357 static void it6161_mipi_rx_int_mask_disable(struct it6161 *it6161)
1358 {
1359     it6161_mipi_rx_set_bits(it6161, 0x0F, 0x03, 0x00);
1360     it6161_mipi_rx_write(it6161, 0x09, 0x00);
1361     it6161_mipi_rx_write(it6161, 0x0A, 0x00);
1362     it6161_mipi_rx_write(it6161, 0x0B, 0x00);
1363 }
1364 
it6161_mipi_rx_int_mask_enable(struct it6161 * it6161)1365 static void it6161_mipi_rx_int_mask_enable(struct it6161 *it6161)
1366 {
1367     it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1368     it6161_mipi_rx_write(it6161, 0x09, EnMBPM ? 0x11 : 0xBF);
1369     it6161_mipi_rx_write(it6161, 0x0A, 0xFF);
1370     it6161_mipi_rx_write(it6161, 0x0B, 0x3F);
1371 }
1372 
hdmi_tx_hdcp_int_mask_disable(struct it6161 * it6161)1373 static void hdmi_tx_hdcp_int_mask_disable(struct it6161 *it6161)
1374 {
1375 	it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1376 	it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK2, B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK, B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK);
1377 }
1378 
1379 #ifdef HDCP
hdmi_tx_hdcp_int_mask_enable(struct it6161 * it6161)1380 static void hdmi_tx_hdcp_int_mask_enable(struct it6161 *it6161)
1381 {
1382 	it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1383 	it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK2, B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK, ~(B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK));
1384 }
1385 #endif
1386 /*
1387 static void it6161_hdmi_tx_int_mask_disable(struct it6161 *it6161)
1388 {
1389     it6161_mipi_rx_set_bits(it6161, 0x0F, 0x03, 0x00);
1390     it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK1, 0xFF);
1391     it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK2, 0xFF);
1392     it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK3, 0xFF);
1393 }
1394 */
it6161_hdmi_tx_int_mask_enable(struct it6161 * it6161)1395 static void it6161_hdmi_tx_int_mask_enable(struct it6161 *it6161)
1396 {
1397     it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x03, 0x00);
1398     it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK1, ~(B_TX_AUDIO_OVFLW_MASK | B_TX_DDC_FIFO_ERR_MASK | B_TX_DDC_BUS_HANG_MASK | B_TX_HPD_MASK | B_TX_RXSEN_MASK));//0x7C);
1399     it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK2, ~(B_TX_AUTH_FAIL_MASK | B_TX_AUTH_DONE_MASK | B_TX_KSVLISTCHK_MASK | B_TX_PKT_VID_UNSTABLE_MASK));
1400     it6161_hdmi_tx_write(it6161, REG_TX_INT_MASK3, ~B_TX_VIDSTABLE_MASK);
1401 }
1402 
it6161_hdmi_tx_write_table(struct it6161 * it6161,const RegSetEntry table[],int size)1403 static void it6161_hdmi_tx_write_table(struct it6161 *it6161, const RegSetEntry table[], int size)
1404 {
1405 	int i ;
1406 
1407 	for (i = 0; i < size; i++) {
1408 		if (table[i].mask == 0 && table[i].value == 0) {
1409 			msleep(table[i].offset);
1410 		} else if (table[i].mask == 0xFF) {
1411 			it6161_hdmi_tx_write(it6161, table[i].offset,
1412 								 table[i].value);
1413 		} else {
1414 			it6161_hdmi_tx_set_bits(it6161, table[i].offset, table[i].mask,
1415 									table[i].value);
1416 		}
1417 	}
1418 }
1419 
hdmi_tx_enable_pattern_generator(struct it6161 * it6161)1420 static inline void hdmi_tx_enable_pattern_generator(struct it6161 *it6161)
1421 {
1422 	it6161_debug("enable pattern generator");
1423 	it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x01, 0x01);
1424 }
1425 
hdmi_tx_disable_pattern_generator(struct it6161 * it6161)1426 static inline void hdmi_tx_disable_pattern_generator(struct it6161 *it6161)
1427 {
1428 	it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x01, 0x00);
1429 }
1430 
hdmi_tx_pattern_generator_setup_color(struct it6161 * it6161)1431 static inline void hdmi_tx_pattern_generator_setup_color(struct it6161 *it6161)
1432 {
1433 	it6161_hdmi_tx_set_bits(it6161, 0xA9, 0x3F, (HDMI_TX_PATTERN_COLLOR_B << 4) | (HDMI_TX_PATTERN_COLLOR_G << 2) | HDMI_TX_PATTERN_COLLOR_R);
1434 }
1435 
hdmi_tx_setup_pattern_generator(struct it6161 * it6161)1436 static void hdmi_tx_setup_pattern_generator(struct it6161 *it6161)
1437 {
1438     switch (HDMI_TX_PATTERN_GENERATOR_FORMAT) {
1439 		case 2:
1440 		it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_480p60_table, sizeof(hdmi_tx_pg_480p60_table) / sizeof(RegSetEntry));
1441 		DRM_INFO("use 480p60 pattern");
1442 		break;
1443 
1444 		case 4:
1445 		it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_720p60_table, sizeof(hdmi_tx_pg_720p60_table) / sizeof(RegSetEntry));
1446 		DRM_INFO("use 720p60 pattern");
1447 		break;
1448 
1449 		case 16:
1450 		it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_1080p60_table, sizeof(hdmi_tx_pg_1080p60_table) / sizeof(RegSetEntry));
1451 		DRM_INFO("use 1080p60 pattern");
1452 		break;
1453 
1454 		default:
1455 		it6161_hdmi_tx_write_table(it6161, hdmi_tx_pg_1080p60_table, sizeof(hdmi_tx_pg_1080p60_table) / sizeof(RegSetEntry));
1456 		DRM_INFO("other format, will use 1080p60 pattern");
1457     }
1458 
1459     hdmi_tx_pattern_generator_setup_color(it6161);
1460 	hdmi_tx_enable_pattern_generator(it6161);
1461 }
1462 
show_display_mode(struct it6161 * it6161,struct drm_display_mode * display_mode,u8 select)1463 static void show_display_mode(struct it6161 *it6161, struct drm_display_mode *display_mode, u8 select)
1464 {
1465 	char *name[3] = { "source output", "it6161 hdmi tx receive", "mipi rx p receive" };
1466 
1467 	DRM_INFO("%s timing:", name[select]);
1468 	DRM_INFO("timing name:%s", display_mode->name);
1469 	DRM_INFO("clock = %dkHz", display_mode->clock);
1470 	DRM_INFO("htotal = %d", display_mode->htotal);
1471 	DRM_INFO("hactive = %d", display_mode->hdisplay);
1472 	DRM_INFO("hfront_porch = %d", display_mode->hsync_start - display_mode->hdisplay);
1473 	DRM_INFO("hsyncw = %d", display_mode->hsync_end - display_mode->hsync_start);
1474 	DRM_INFO("hback_porch = %d", display_mode->htotal - display_mode->hsync_end);
1475 
1476 	DRM_INFO("vtotal = %d", display_mode->vtotal);
1477 	DRM_INFO("vactive = %d", display_mode->vdisplay);
1478 	DRM_INFO("vfront_porch = %d", display_mode->vsync_start - display_mode->vdisplay);
1479 	DRM_INFO("vsyncw = %d", display_mode->vsync_end - display_mode->vsync_start);
1480 	DRM_INFO("vback_porch = %d", display_mode->vtotal - display_mode->vsync_end);
1481 	DRM_INFO("drm_display_mode flags = 0x%04x", display_mode->flags);
1482 
1483 }
1484 
it6161_set_interrupts_active_level(enum it6161_active_level level)1485 static void inline it6161_set_interrupts_active_level(enum it6161_active_level level)
1486 {
1487 	it6161_mipi_rx_set_bits(it6161, 0x0D, 0x02, level == HIGH ? 0x02 : 0x00);
1488 	it6161_hdmi_tx_set_bits(it6161, 0x05, 0xC0, level == HIGH ? 0x80 : 0x40);
1489 }
1490 
hdmi_tx_init(struct it6161 * it6161)1491 static void hdmi_tx_init(struct it6161 *it6161)
1492 {
1493     it6161_debug("init hdmi tx");
1494 
1495     it6161_hdmi_tx_write_table(it6161, HDMITX_Init_Table, ARRAY_SIZE(HDMITX_Init_Table));
1496     it6161_hdmi_tx_write_table(it6161, HDMITX_PwrOn_Table, ARRAY_SIZE(HDMITX_PwrOn_Table));
1497     it6161_hdmi_tx_write_table(it6161, HDMITX_DefaultVideo_Table, ARRAY_SIZE(HDMITX_DefaultVideo_Table));
1498     it6161_hdmi_tx_write_table(it6161, HDMITX_SetHDMI_Table, ARRAY_SIZE(HDMITX_SetHDMI_Table));
1499     it6161_hdmi_tx_write_table(it6161, HDMITX_DefaultAVIInfo_Table, ARRAY_SIZE(HDMITX_DefaultAVIInfo_Table));
1500     it6161_hdmi_tx_write_table(it6161, HDMITX_DeaultAudioInfo_Table, ARRAY_SIZE(HDMITX_DeaultAudioInfo_Table));
1501     it6161_hdmi_tx_write_table(it6161, HDMITX_Aud_CHStatus_LPCM_20bit_48Khz, ARRAY_SIZE(HDMITX_Aud_CHStatus_LPCM_20bit_48Khz));
1502     it6161_hdmi_tx_write_table(it6161, HDMITX_AUD_SPDIF_2ch_24bit, ARRAY_SIZE(HDMITX_AUD_SPDIF_2ch_24bit));
1503 
1504 #ifdef SUPPORT_CEC
1505     it6161_hdmi_tx_change_bank(it6161, 0);
1506     it6161_hdmi_tx_set_bits(it6161, 0x8D, 0x01, 0x01);//it6161_hdmi_tx_write(it6161,  0xf, 0 ); //pet
1507 
1508     Initial_Ext_Int1();
1509     HDMITX_CEC_Init();
1510 #endif // SUPPORT_CEC
1511 }
1512 
mipi_rx_get_m_video_stable(struct it6161 * it6161)1513 static bool mipi_rx_get_m_video_stable(struct it6161 *it6161)
1514 {
1515 	return !!(it6161_mipi_rx_read(it6161, 0x0D) & 0x10);
1516 }
1517 
mipi_rx_get_p_video_stable(struct it6161 * it6161)1518 static bool mipi_rx_get_p_video_stable(struct it6161 *it6161)
1519 {
1520 	return !!(it6161_mipi_rx_read(it6161, 0x0D) & 0x20);
1521 }
1522 
mipi_rx_setup_polarity(struct it6161 * it6161)1523 static void mipi_rx_setup_polarity(struct it6161 *it6161)
1524 {
1525 	struct drm_display_mode *display_mode = &it6161->source_display_mode;
1526 	u8 polarity;
1527 
1528 	polarity = ((display_mode->flags & DRM_MODE_FLAG_PHSYNC) == DRM_MODE_FLAG_PHSYNC) ? 0x01 : 0x00;
1529 	polarity |= ((display_mode->flags & DRM_MODE_FLAG_PVSYNC) == DRM_MODE_FLAG_PVSYNC) ? 0x02 : 0x00;
1530 
1531 	it6161_mipi_rx_set_bits(it6161, 0x4E, 0x03, polarity);
1532 }
1533 
mipi_rx_afe_configuration(struct it6161 * it6161,u8 data_id)1534 static void mipi_rx_afe_configuration(struct it6161 *it6161, u8 data_id)
1535 {
1536     //struct device *dev = &it6161->i2c_mipi_rx->dev;
1537     u8 MPLaneNum = (it6161->mipi_rx_lane_count - 1);
1538 
1539     it6161_debug("afe configuration data_id:0x%02x", data_id);
1540 
1541     if (data_id == RGB_18b) {
1542         if( MPLaneNum==3 ) {
1543             // if( EnMPx1PCLK )
1544                 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x02); // MPPCLKSel = 1; // 4-lane : MCLK = 1/1 PCLK
1545             // else
1546             // {
1547                 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x02); // MPPCLKSel = 1; // 4-lane : MCLK = 1/1 PCLK
1548                 DRM_INFO("Solomon is impossible TXPLL= 9/2 PCLK !!! \n");
1549                 DRM_INFO("MCLK=3/4PCLK Change to MCLK=PCLK ...\n");
1550             // }
1551         } else if( MPLaneNum==1 ) {
1552             // if( EnMPx1PCLK )
1553                 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x05); // MPPCLKSel = 6; // 2-lane : MCLK = 1/1 PCLK
1554             // else
1555             // {
1556                 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x05); // MPPCLKSel = 6; // 2-lane : MCLK = 1/1 PCLK
1557                 DRM_INFO("IT6121 is impossible RXPLL= 2/9 PCLK !!! \n");
1558                 DRM_INFO("MCLK=3/4PCLK Change to MCLK=PCLK ...\n");
1559             // }
1560         } else if( MPLaneNum==0 ) {
1561             // if( EnMPx1PCLK )
1562                 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x0b);// MPPCLKSel = 7; // 1-lane : MCLK = 1/1 PCLK
1563             // else
1564                 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x08); // MPPCLKSel = 8; // 1-lane : MCLK = 3/4 PCLK
1565         }
1566     } else {
1567         if( MPLaneNum==3 ) {
1568         // if( EnMPx1PCLK )
1569             // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x03);// MPPCLKSel = 0; // 4-lane : MCLK = 1/1 PCLK
1570         // else
1571             it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x02);// MPPCLKSel = 1; // 4-lane : MCLK = 3/4 PCLK
1572         } else if( MPLaneNum==1 ) {
1573             // if( EnMPx1PCLK )
1574                 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x07); // MPPCLKSel = 2; // 2-lane : MCLK = 1/1 PCLK
1575             // else
1576                 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x05); // MPPCLKSel = 3; // 2-lane : MCLK = 3/4 PCLK
1577         } else if( MPLaneNum==0 ) {
1578             // if( EnMPx1PCLK )
1579                 // it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x0f);// MPPCLKSel = 4; // 1-lane : MCLK = 1/1 PCLK
1580             // else
1581                 it6161_mipi_rx_set_bits(it6161, 0x80, 0x1F, 0x0b); // MPPCLKSel = 5; // 1-lane : MCLK = 3/4 PCLK
1582         }
1583     }
1584 }
1585 
mipi_rx_configuration(struct it6161 * it6161)1586 static void mipi_rx_configuration(struct it6161 *it6161)
1587 {
1588     //struct device *dev = &it6161->i2c_mipi_rx->dev;
1589     u8 mipi_lane_config = (it6161->mipi_rx_lane_count - 1);
1590 
1591 	//20200211 D0
1592 	it6161_mipi_rx_set_bits(it6161, 0x10, 0x0F, 0x0F);
1593 	msleep(1);//idle(100);
1594 	it6161_mipi_rx_set_bits(it6161, 0x10, 0x0F, 0x00);
1595 
1596 	// MPRX Software Reset
1597 	// it6161_mipi_rx_set_bits(it6161, 0x05, 0x07, 0x07);
1598 	// msleep(1);
1599 	// it6161_mipi_rx_set_bits(it6161, 0x05, 0x08, 0x08);
1600 	mipi_rx_logic_reset(it6161);
1601 	msleep(1);
1602 	mipi_rx_logic_reset_release(it6161);
1603 
1604 	it6161_mipi_rx_int_mask_disable(it6161);
1605 
1606 	/* setup INT pin: active low */
1607 	it6161_mipi_rx_set_bits(it6161, 0x0d, 0x02, 0x00);
1608 
1609 	it6161_mipi_rx_set_bits(it6161, 0x0C, 0x0F, (MPLaneSwap<<3) + (MPPNSwap<<2) + mipi_lane_config);
1610 
1611 	it6161_mipi_rx_set_bits(it6161, 0x11, 0x3F, (EnIOIDDQ<<5)+(EnStb2Rst<<4)+(EnExtStdby<<3)+(EnStandby<<2)+(InvPCLK<<1)+InvMCLK);
1612 	it6161_mipi_rx_set_bits(it6161, 0x12, 0x03, (PDREFCNT<<1)+PDREFCLK);
1613 
1614 	it6161_mipi_rx_set_bits(it6161, 0x18, 0xf7, (RegEnSyncErr<<7)+(SkipStg<<4)+HSSetNum);
1615 	it6161_mipi_rx_set_bits(it6161, 0x19, 0xf3, (PPIDbgSel<<4)+(EnContCK<<1)+EnDeSkew);
1616 	it6161_mipi_rx_set_bits(it6161, 0x20, 0xf7, (EOTPSel<<4)+(RegEnDummyECC<<2)+(RegIgnrBlk<<1)+RegIgnrNull);
1617 	it6161_mipi_rx_set_bits(it6161, 0x21, 0x07, LMDbgSel);
1618 
1619 	// it6161_mipi_rx_set_bits(it6161, 0x44, 0x38, (MREC_Update<<5)+(PREC_Update<<4)+(REGSELDEF<<3));
1620 	it6161_mipi_rx_set_bits(it6161, 0x44, 0x3a, (MREC_Update<<5)+(PREC_Update<<4)+(REGSELDEF<<3)+(RegAutoSync<<1));//D0 20200211
1621 	it6161_mipi_rx_set_bits(it6161, 0x4B, 0x1f, (EnFReSync<<4)+(EnVREnh<<3)+EnVREnhSel);
1622 	it6161_mipi_rx_write(it6161, 0x4C, PPSFFRdStg);
1623 	it6161_mipi_rx_set_bits(it6161, 0x4D, 0x01, (PPSFFRdStg>>8)&0x01);
1624 	it6161_mipi_rx_set_bits(it6161, 0x4E, 0x0C, (EnVReSync<<3)+(EnHReSync<<2));
1625 	it6161_mipi_rx_set_bits(it6161, 0x4F, 0x03, EnFFAutoRst);
1626 
1627 	//it6161_mipi_rx_write(it6161, 0x27, MPVidType);
1628 	it6161_mipi_rx_set_bits(it6161, 0x70, 0x01, EnMAvg);
1629 	it6161_mipi_rx_write(it6161, 0x72, MShift);
1630 	it6161_mipi_rx_write(it6161, 0x73, PShift);
1631 	it6161_mipi_rx_set_bits(it6161, 0x80, 0x20, ENABLE_MIPI_RX_EXTERNAL_CLOCK << 5);
1632 	it6161_mipi_rx_write(it6161, 0x21, 0x00); //debug sel
1633 	//	 it6161_mipi_rx_set_bits(it6161, 0x84, 0x70, 0x70);	// max swing
1634 	// 	 it6161_mipi_rx_set_bits(it6161, 0x84, 0x70, 0x40);	// def swing
1635 	it6161_mipi_rx_set_bits(it6161, 0x84, 0x70, 0x00);	// min swing
1636 
1637 	it6161_mipi_rx_set_bits(it6161, 0xA0, 0x01, EnMBPM);
1638 
1639     /* enable auto detect format */
1640     it6161_mipi_rx_set_bits(it6161, 0x21, 0x08, 0x08);
1641 
1642 
1643 	// if( REGSELDEF == true )
1644 	// {
1645 		// DRM_INFO("REGSELDEF MODE !!! ...\n");
1646 		// PHFP = 0x10;
1647 		// PHSW = 0x3e;
1648 		// PHBP = 0x3c;
1649 		// it6161_mipi_rx_write(it6161, 0x30, PHFP);					// HFP
1650 		// it6161_mipi_rx_write(it6161, 0x31, 0x80+((PHFP&0x3F00)>>8));
1651 		// it6161_mipi_rx_write(it6161, 0x32, PHSW);					// HBP
1652 		// it6161_mipi_rx_write(it6161, 0x33, 0x80+((PHSW&0x3F00)>>8));
1653 		// it6161_mipi_rx_write(it6161, 0x34, PHBP);					// HBP
1654 		// it6161_mipi_rx_write(it6161, 0x35, 0x80+((PHFP&0x3F00)>>8));
1655 	// }
1656 
1657 	it6161_mipi_rx_set_bits(it6161, 0x70, 0x01, EnMAvg);
1658 
1659 	it6161_mipi_rx_set_bits(it6161, 0x05, 0x02, 0x02);  // Video Clock Domain Reset
1660 
1661 	if( EnMBPM ) {
1662 		//HSW = pSetVTiming->HSyncWidth;
1663 		//VSW = pSetVTiming->VSyncWidth;
1664 
1665 		it6161_mipi_rx_write(it6161, 0xA1, 0x00);	// HRS offset
1666 		it6161_mipi_rx_write(it6161, 0xA2, 0x00);	// VRS offset
1667 
1668 		// it6161_mipi_rx_write(it6161, 0xA3, 44);//HSW);	// HSW
1669 		// it6161_mipi_rx_write(it6161, 0xA5, 5);//VSW);	// VSW
1670 			it6161_mipi_rx_write(it6161, 0xA3, 0x08);//0x10);	// HSW
1671 			it6161_mipi_rx_write(it6161, 0xA5, 0x04);	// VSw
1672 
1673 		// it6161_hdmi_tx_set_bits(it6161, 0xa9, 0xc0, (EnTBPM<<7)/* + (EnTxPatMux<<6)*/);
1674 		// it6161_hdmi_tx_set_bits(it6161, 0xbf, 0x80, (NRTXRCLK<<7));
1675 	}
1676 	if( MPForceStb == true ){
1677 		// mprxwr(0x30, HFP);					// HSP
1678 		// mprxwr(0x31, 0x80+((HFP&0x3F00)>>8));
1679 		// mprxwr(0x32, HSW);					// HSW
1680 		// mprxwr(0x33, 0x80+((HSW&0x3F00)>>8));
1681 		// mprxwr(0x34, HBP&0xFF);				// HBP
1682 		// mprxwr(0x35, 0x80+((HBP&0x3F00)>>8));
1683 		// mprxwr(0x36, HDEW&0xFF);				// HDEW
1684 		// mprxwr(0x37, 0x80+((HDEW&0x3F00)>>8));
1685 		// mprxwr(0x38, HVR2nd&0xFF);			// HVR2nd
1686 		// mprxwr(0x39, 0x80+((HVR2nd&0x3F00)>>8));
1687 
1688 		// mprxwr(0x3A, VFP);					// VSP
1689 		// mprxwr(0x3B, 0x80+((VFP&0x3F00)>>8));
1690 		// mprxwr(0x3C, VSW);					// VSW
1691 		// mprxwr(0x3D, 0x80+((VSW&0x3F00)>>8));
1692 		// mprxwr(0x3E, VBP&0xFF);				// VBP
1693 		// mprxwr(0x3F, 0x80+((VBP&0x3F00)>>8));
1694 		// mprxwr(0x40, VDEW&0xFF);				// VDEW
1695 		// mprxwr(0x41, 0x80+((VDEW&0x3F00)>>8));
1696 		// mprxwr(0x42, VFP2nd&0xFF);			// VFP2nd
1697 		// mprxwr(0x43, 0x80+((VFP2nd&0x3F00)>>8));
1698 
1699 		// mprxset(0x4e, 0x03, 0xC0+(VPol<<1)+HPol);
1700 	}
1701 	else
1702 	{
1703 		if( REGSELDEF == false ) {
1704 			it6161_mipi_rx_set_bits(it6161, 0x31, 0x80, 0x00);
1705 			it6161_mipi_rx_set_bits(it6161, 0x33, 0x80, 0x00);
1706 			it6161_mipi_rx_set_bits(it6161, 0x35, 0x80, 0x00);
1707 			it6161_mipi_rx_set_bits(it6161, 0x37, 0x80, 0x00);
1708 			it6161_mipi_rx_set_bits(it6161, 0x39, 0x80, 0x00);
1709 			it6161_mipi_rx_set_bits(it6161, 0x3A, 0x80, 0x00);
1710 			it6161_mipi_rx_set_bits(it6161, 0x3C, 0x80, 0x00);
1711 			it6161_mipi_rx_set_bits(it6161, 0x3E, 0x80, 0x00);
1712 			it6161_mipi_rx_set_bits(it6161, 0x41, 0x80, 0x00);
1713 			it6161_mipi_rx_set_bits(it6161, 0x43, 0x80, 0x00);
1714 		}
1715 
1716 		// mprxset(0x4e, 0x03, 0x00+(VPol<<1)+HPol);
1717 	}
1718 }
1719 
mipi_rx_init(struct it6161 * it6161)1720 static void mipi_rx_init(struct it6161 *it6161)
1721 {
1722     //struct device *dev = &it6161->i2c_mipi_rx->dev;
1723 
1724     it6161_debug("init mpip rx");
1725     mipi_rx_configuration(it6161);
1726     it6161_mipi_rx_set_bits(it6161, 0x05, 0x03, 0x00);  // Enable MPRX clock domain
1727 }
1728 
hdmi_tx_video_reset(struct it6161 * it6161)1729 static void hdmi_tx_video_reset(struct it6161 *it6161)
1730 {
1731     //struct device *dev = &it6161->i2c_mipi_rx->dev;
1732 
1733     it6161_debug("%s reg04:0x%02x reg05:0x%02x reg6:0x%02x reg07:0x%02x reg08:0x%02x reg0e:0x%02x", __func__, it6161_hdmi_tx_read(it6161, 0x04), it6161_hdmi_tx_read(it6161, 0x05), it6161_hdmi_tx_read(it6161, 0x06), it6161_hdmi_tx_read(it6161, 0x07), it6161_hdmi_tx_read(it6161, 0x08), it6161_hdmi_tx_read(it6161, 0x0e));
1734 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_VID_RST, B_HDMITX_VID_RST);
1735 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_VID_RST, 0x00);
1736     msleep(10);
1737 }
1738 /*
1739 static void hdmi_tx_audio_fifo_reset(struct it6161 *it6161)
1740 {
1741 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST, B_HDMITX_AUD_RST);
1742 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST, 0x00);
1743 }
1744 */
1745 /* DDC master will set to be host */
1746 
it6161_hdmi_tx_clear_ddc_fifo(struct it6161 * it6161)1747 static void it6161_hdmi_tx_clear_ddc_fifo(struct it6161 *it6161)
1748 {
1749 	it6161_hdmi_tx_change_bank(it6161, 0);
1750 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
1751 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_FIFO_CLR);
1752 	it6161_hdmi_tx_set_bits(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERHOST, 0x00);
1753 }
1754 
1755 #ifdef HDCP
it6161_hdmi_tx_generate_ddc_sclk(struct it6161 * it6161)1756 static void it6161_hdmi_tx_generate_ddc_sclk(struct it6161 *it6161)
1757 {
1758     it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST);
1759     it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD,CMD_GEN_SCLCLK);
1760 }
1761 #endif
hdmi_tx_generate_blank_timing(struct it6161 * it6161)1762 static void hdmi_tx_generate_blank_timing(struct it6161 *it6161)
1763 {
1764 	struct drm_display_mode *display_mode = &it6161->source_display_mode;
1765 	bool force_hdmi_tx_clock_stable = true, force_hdmi_tx_video_stable = true, hdmi_tx_by_pass_mode = false, de_generation = false, enable_de_only = true;
1766 	u8 polarity;
1767 	u16 hsync_start, hsync_end, vsync_start, vsync_end, htotal, hde_start, vtotal;
1768 	u16 vsync_start_2nd = 0, vsync_end_2nd = 0, vsync_rising_at_h_2nd;
1769 
1770 	it6161_debug("start %s", __func__);
1771 	polarity = ((display_mode->flags & DRM_MODE_FLAG_PHSYNC) == DRM_MODE_FLAG_PHSYNC) ? 0x02 : 0x00;
1772 	polarity |= ((display_mode->flags & DRM_MODE_FLAG_PVSYNC) == DRM_MODE_FLAG_PVSYNC) ? 0x04 : 0x00;
1773 
1774 	hsync_start = display_mode->hsync_start - display_mode->hdisplay - 1;
1775 	hsync_end = hsync_start + display_mode->hsync_end - display_mode->hsync_start;
1776 	vsync_rising_at_h_2nd = hsync_start + display_mode->htotal / 2;
1777 	hde_start = display_mode->htotal - display_mode->hsync_start;
1778 
1779 	it6161_hdmi_tx_set_bits(it6161, 0xD1, 0x0C, force_hdmi_tx_clock_stable << 3 | force_hdmi_tx_video_stable << 2);
1780 	it6161_hdmi_tx_set_bits(it6161, 0xA9, 0x80, hdmi_tx_by_pass_mode << 7);
1781 	it6161_hdmi_tx_set_bits(it6161, 0x90, 0x01, de_generation);
1782 	it6161_hdmi_tx_write(it6161, 0x91, vsync_rising_at_h_2nd >> 4);
1783 	it6161_hdmi_tx_set_bits(it6161, 0x90, 0xF0, (vsync_rising_at_h_2nd & 0x00F) << 4);
1784 	it6161_hdmi_tx_set_bits(it6161, 0x90, 0x06, polarity);
1785 	it6161_hdmi_tx_write(it6161, 0x95, (u8)hsync_start);
1786 	it6161_hdmi_tx_write(it6161, 0x96, (u8)hsync_end);
1787 	it6161_hdmi_tx_write(it6161, 0x97, (hsync_end & 0x0F00) >> 4 | hsync_start >> 8);
1788 
1789 	vsync_start = display_mode->vsync_start - display_mode->vdisplay;
1790 	vsync_end = display_mode->vsync_end - display_mode->vdisplay;
1791 
1792 	if ((display_mode->flags & DRM_MODE_FLAG_INTERLACE) != DRM_MODE_FLAG_INTERLACE) {
1793 		vsync_start_2nd = 0x0FFF;
1794 		vsync_end_2nd = 0x3F;
1795 		vtotal = display_mode->vtotal - 1;
1796 		it6161_hdmi_tx_set_bits(it6161, 0xA5, 0x10, 0x00);
1797 	} else {
1798 		vtotal = display_mode->vtotal * 2;
1799 		it6161_hdmi_tx_set_bits(it6161, 0xA5, 0x10, 0x10);
1800 	}
1801 	it6161_hdmi_tx_write(it6161, 0xA0, (u8)vsync_start);
1802 	it6161_hdmi_tx_write(it6161, 0xA1, (vsync_end & 0x0F) << 4 | vsync_start >> 8);
1803 	it6161_hdmi_tx_write(it6161, 0xA2, (u8)vsync_start_2nd);
1804 	it6161_hdmi_tx_write(it6161, 0xA6, (vsync_end_2nd & 0xF0) | vsync_end >> 4);
1805 	it6161_hdmi_tx_write(it6161, 0xA3, (vsync_end_2nd & 0x0F) << 4 | vsync_start_2nd >> 8);
1806 	it6161_hdmi_tx_write(it6161, 0xA4, vsync_rising_at_h_2nd);
1807 	it6161_hdmi_tx_set_bits(it6161, 0xB1, 0x51, (hsync_end & 0x1000) >> 6 | (hsync_start & 0x1000) >> 8 | hde_start >> 12);
1808 	it6161_hdmi_tx_set_bits(it6161, 0xA5, 0x2F, enable_de_only << 5 | vsync_rising_at_h_2nd >> 8);
1809 	it6161_hdmi_tx_set_bits(it6161, 0xB2, 0x05, (vsync_rising_at_h_2nd & 0x1000) >> 10 | (vsync_rising_at_h_2nd & 0x1000) >> 12);
1810 
1811 	htotal = display_mode->htotal - 1;
1812 	it6161_hdmi_tx_set_bits(it6161, 0x90, 0xF0, (htotal & 0x0F) << 4);
1813 	it6161_hdmi_tx_write(it6161, 0x91, (htotal & 0x0FF0) >> 4);
1814 	it6161_hdmi_tx_set_bits(it6161, 0xB2, 0x01, (htotal & 0x1000) >> 12);
1815 	it6161_hdmi_tx_write(it6161, 0x98, vtotal & 0x0FF);
1816 	it6161_hdmi_tx_write(it6161, 0x99, (vtotal & 0xF00) >> 8);
1817 }
1818 
1819 /* force abort DDC and reset DDC bus */
1820 
it6161_hdmi_tx_abort_ddc(struct it6161 * it6161)1821 static void it6161_hdmi_tx_abort_ddc(struct it6161 *it6161)
1822 {
1823 	u8 cp_desire, sw_reset, ddc_master, retry = 2;
1824 	u8 uc, timeout, i;
1825 
1826 	it6161_debug("%s", __func__);
1827 	/* save the sw reset, ddc master and cp desire setting */
1828 	sw_reset = it6161_hdmi_tx_read(it6161, REG_TX_SW_RST);
1829 	cp_desire = it6161_hdmi_tx_read(it6161, REG_TX_HDCP_DESIRE);
1830 	ddc_master = it6161_hdmi_tx_read(it6161, REG_TX_DDC_MASTER_CTRL);
1831 
1832 	// it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE,CPDesire&(~B_TX_CPDESIRE)); // @emily change order
1833 	it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, sw_reset | B_TX_HDCP_RST_HDMITX);         // @emily change order
1834 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
1835 
1836 	/* do abort DDC */
1837 	for (i = 0; i < retry; i++) {
1838 		it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_DDC_ABORT);
1839 		it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_GEN_SCLCLK);//hdmitxwr(0x15, 0x0A); //it6161A0   // Generate SCL Clock
1840 
1841 		for (timeout = 0; timeout < 200; timeout++) {
1842 			uc = it6161_hdmi_tx_read(it6161, REG_TX_DDC_STATUS);
1843 			if (uc&B_TX_DDC_DONE)
1844 				break ;
1845 
1846 			if (uc & (B_TX_DDC_NOACK | B_TX_DDC_WAITBUS | B_TX_DDC_ARBILOSE)) {
1847 				DRM_INFO("it6161_hdmi_tx_abort_ddc Fail by reg16=%02X\n",(int)uc);//pet
1848 				break ;
1849 			}
1850 			/* delay 1 ms to stable */
1851 			msleep(1);
1852 		}
1853 	}
1854 }
1855 
hdmi_tx_get_video_state(struct it6161 * it6161)1856 static bool hdmi_tx_get_video_state(struct it6161 *it6161)
1857 {
1858 	return !!(B_TXVIDSTABLE & it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS));
1859 }
1860 
hdmi_tx_get_sink_hpd(struct it6161 * it6161)1861 static bool inline hdmi_tx_get_sink_hpd(struct it6161 *it6161)
1862 {
1863     return !!(it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS) & B_TX_HPDETECT);
1864 }
1865 
it6161_ddc_op_finished(struct it6161 * it6161)1866 static bool it6161_ddc_op_finished(struct it6161 *it6161)
1867 {
1868     int reg16 = it6161_hdmi_tx_read(it6161, REG_TX_DDC_STATUS);
1869 
1870     if (reg16 < 0)
1871         return false;
1872 
1873     return (reg16 & B_TX_DDC_DONE) == B_TX_DDC_DONE;
1874 }
1875 
it6161_ddc_wait(struct it6161 * it6161)1876 static int it6161_ddc_wait(struct it6161 *it6161)
1877 {
1878     int status;
1879     unsigned long timeout;
1880     //struct device *dev = &it6161->client->dev;
1881 
1882     timeout = jiffies + msecs_to_jiffies(AUX_WAIT_TIMEOUT_MS) + 1;
1883 
1884     while (!it6161_ddc_op_finished(it6161)) {
1885         if (time_after(jiffies, timeout)) {
1886             DRM_INFO("Timed out waiting AUX to finish");
1887             return -ETIMEDOUT;
1888         }
1889         usleep_range(1000, 2000);
1890     }
1891 
1892     status = it6161_hdmi_tx_read(it6161, REG_TX_DDC_STATUS);
1893     if (status < 0) {
1894         DRM_INFO("Failed to read DDC channel: 0x%02x", status);
1895         return status;
1896     }
1897 
1898     if(status & B_TX_DDC_DONE) {
1899         return 0;
1900     } else {
1901         DRM_INFO("DDC error: 0x%02x", status);
1902         return -EIO;
1903     }
1904 }
1905 
hdmi_tx_ddc_operation(struct it6161 * it6161,u8 addr,u8 offset,u8 size,u8 segment,u8 cmd)1906 static void hdmi_tx_ddc_operation(struct it6161 *it6161, u8 addr, u8 offset, u8 size, u8 segment, u8 cmd)
1907 {
1908 	size = min(size, (u8)DDC_FIFO_MAXREQ);
1909 	it6161_hdmi_tx_change_bank(it6161, 0);
1910 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
1911 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER, addr);
1912 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF, offset);
1913 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT, size);
1914 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_EDIDSEG, segment);
1915 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, cmd);
1916 }
1917 
1918 //////////////////////////////////////////////////////////////////////
1919 // Function: it6161_ddc_get_edid_operation
1920 // Parameter: buffer - the pointer of buffer to receive EDID ucdata.
1921 //            segment - the segment of EDID readback.
1922 //            offset - the offset of EDID ucdata in the segment. in byte.
1923 //            size - the read back bytes count,cannot exceed 32
1924 // Return: ER_SUCCESS if successfully getting EDID. ER_FAIL otherwise.
1925 // Remark: function for read EDID ucdata from reciever.
1926 // Side-Effect: DDC master will set to be HOST. DDC FIFO will be used and dirty.
1927 //////////////////////////////////////////////////////////////////////
1928 
it6161_ddc_get_edid_operation(struct it6161 * it6161,u8 * buffer,u8 segment,u8 offset,int size)1929 static int it6161_ddc_get_edid_operation(struct it6161 *it6161, u8 *buffer, u8 segment, u8 offset, int size)
1930 {
1931 	u8 status, i;
1932 
1933 	if(!buffer)
1934 		return -ENOMEM;
1935 
1936 	if(it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1) & B_TX_INT_DDC_BUS_HANG) {
1937 		DRM_INFO("Called it6161_hdmi_tx_abort_ddc()");
1938 		it6161_hdmi_tx_abort_ddc(it6161);
1939 	}
1940 
1941 	it6161_hdmi_tx_clear_ddc_fifo(it6161);
1942 	status = it6161_ddc_wait(it6161);
1943 
1944 	if (status < 0)
1945 		goto error;
1946 
1947 	hdmi_tx_ddc_operation(it6161, DDC_EDID_ADDRESS, offset, size, segment, CMD_EDID_READ);
1948 	status = it6161_ddc_wait(it6161);
1949 
1950 	if (status < 0)
1951 		goto error;
1952 
1953 	for (i = 0; i < size; i++) {
1954 		status = it6161_hdmi_tx_read(it6161, REG_TX_DDC_READFIFO);
1955 
1956 		if (status < 0)
1957 			goto error;
1958 
1959 		buffer[i] = status;
1960 	}
1961 
1962 	return i;
1963 
1964 error:
1965 	return status;
1966 }
1967 
it6161_get_edid_block(void * data,u8 * buf,unsigned int block_num,size_t len)1968 static int it6161_get_edid_block(void *data, u8 *buf, unsigned int block_num,
1969                                                 size_t len)
1970 {
1971     struct it6161 *it6161 = data;
1972     u8 offset, ret, step = 8;
1973 
1974     step = min(step, (u8)DDC_FIFO_MAXREQ);
1975     DRM_INFO("[%s] edid block number:%d read step:%d", __func__, block_num, step);
1976 
1977     for (offset = 0; offset < len; offset += step) {
1978         ret = it6161_ddc_get_edid_operation(it6161, buf + offset, block_num / 2, (block_num % 2) * EDID_LENGTH + offset, step);
1979 
1980         if(ret < 0)
1981             return ret;
1982 #ifdef __linux__
1983         DRM_INFO("[0x%02x]: %*ph", offset, step, buf + offset);
1984 #else
1985         DRM_INFO("[0x%02x]:", offset);
1986 
1987         for (ret = 0; ret < step; ret++)
1988             printf(" 0x%02x", (buf + offset)[ret]);
1989         printf("\n\r");
1990 #endif
1991     }
1992     return 0;
1993 }
1994 
hdmi_tx_set_capability_from_edid_parse(struct it6161 * it6161)1995 static void hdmi_tx_set_capability_from_edid_parse(struct it6161 *it6161)
1996 {
1997 	struct drm_display_info *info = &it6161->connector.display_info;
1998 
1999 	it6161->hdmi_mode = drm_detect_hdmi_monitor(it6161->edid);
2000 	it6161->support_audio = drm_detect_monitor_audio(it6161->edid);
2001 	if (it6161->hdmi_tx_output_color_space == F_MODE_YUV444) {
2002 		if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) != DRM_COLOR_FORMAT_YCRCB444) {
2003 			it6161->hdmi_tx_output_color_space &= ~F_MODE_CLRMOD_MASK;
2004 			it6161->hdmi_tx_output_color_space |= F_MODE_RGB444;
2005 		}
2006 	}
2007 
2008 	if (it6161->hdmi_tx_output_color_space == F_MODE_YUV422) {
2009 		if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) != DRM_COLOR_FORMAT_YCRCB422) {
2010 			it6161->hdmi_tx_output_color_space &= ~F_MODE_CLRMOD_MASK;
2011 			it6161->hdmi_tx_output_color_space |= F_MODE_RGB444;
2012 		}
2013 	}
2014 	DRM_INFO("%s mode, monitor %ssupport audio, outputcolormode:%d color_formats:0x%08x color_depth:%d",
2015 		it6161->hdmi_mode ? "HDMI" : "DVI", it6161->support_audio ? "" : "not ", it6161->hdmi_tx_output_color_space, info->color_formats, info->bpc);
2016 
2017 	if ((info->color_formats & DRM_COLOR_FORMAT_RGB444) == DRM_COLOR_FORMAT_RGB444)
2018 		DRM_INFO("support RGB444 output");
2019 	if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB444) == DRM_COLOR_FORMAT_YCRCB444)
2020 		DRM_INFO("support YUV444 output");
2021 	if ((info->color_formats & DRM_COLOR_FORMAT_YCRCB422) == DRM_COLOR_FORMAT_YCRCB422)
2022 		DRM_INFO("support YUV422 output");
2023 }
2024 
it6161_variable_config(struct it6161 * it6161)2025 static void it6161_variable_config(struct it6161 *it6161)
2026 {
2027     it6161->hdmi_tx_hdcp_retry = HDMI_TX_HDCP_RETRY;
2028     it6161->hdmi_tx_mode = HDMI_TX_MODE;
2029     it6161->mipi_rx_lane_count = MIPI_RX_LANE_COUNT;
2030 }
2031 
2032 #ifdef __linux__
2033 
it6161_get_modes(struct drm_connector * connector)2034 static int it6161_get_modes(struct drm_connector *connector)
2035 {
2036  	struct it6161 *it6161 = connector_to_it6161(connector);
2037  	int err, num_modes = 0, i, retry = 3;
2038 	struct device *dev = &it6161->i2c_mipi_rx->dev;
2039 
2040 	it6161_debug("%s start", __func__);
2041 
2042 	if (it6161->edid)
2043 		return drm_add_edid_modes(connector, it6161->edid);
2044 	mutex_lock(&it6161->mode_lock);
2045 	reinit_completion(&it6161->wait_edid_complete);
2046 
2047 	for (i = 0; i < retry; i++) {
2048 		it6161->edid =
2049 		drm_do_get_edid(&it6161->connector, it6161_get_edid_block, it6161);
2050 
2051 		if (it6161->edid)
2052 			break;
2053 	}
2054 	if (!it6161->edid) {
2055 		DRM_DEV_ERROR(dev, "Failed to read EDID");
2056 		goto unlock;
2057 	}
2058 
2059 	err = drm_connector_update_edid_property(connector, it6161->edid);
2060 	if (err) {
2061 		DRM_DEV_ERROR(dev, "Failed to update EDID property: %d", err);
2062 		goto unlock;
2063 	}
2064 
2065 	num_modes = drm_add_edid_modes(connector, it6161->edid);
2066 
2067 unlock:
2068 	complete(&it6161->wait_edid_complete);
2069 	DRM_INFO("edid mode number:%d", num_modes);
2070 	mutex_unlock(&it6161->mode_lock);
2071 
2072 	return num_modes;
2073 }
2074 
2075  static const struct drm_connector_helper_funcs it6161_connector_helper_funcs = {
2076  	.get_modes = it6161_get_modes,
2077  };
2078 
it6161_detect(struct drm_connector * connector,bool force)2079 static enum drm_connector_status it6161_detect(struct drm_connector *connector,
2080 					       bool force)
2081 {
2082 	struct it6161 *it6161 = connector_to_it6161(connector);
2083 	enum drm_connector_status status = connector_status_disconnected;
2084 	bool hpd = hdmi_tx_get_sink_hpd(it6161);
2085 
2086 	DRM_INFO("hpd:%s", hpd ? "high" : "low");
2087 	//mutex_lock(&it6161->mode_lock);
2088 
2089 	if (hpd) {
2090 		it6161_variable_config(it6161);
2091 		status = connector_status_connected;
2092 	}
2093 
2094 	it6161_set_interrupts_active_level(HIGH);
2095 	it6161_mipi_rx_int_mask_enable(it6161);
2096 	it6161_hdmi_tx_int_mask_enable(it6161);
2097 
2098 	//mutex_lock(&it6161->mode_lock);
2099 	return status;
2100 }
2101 
2102 static const struct drm_connector_funcs it6161_connector_funcs = {
2103 	.fill_modes = drm_helper_probe_single_connector_modes,
2104 	.detect = it6161_detect,
2105 	.destroy = drm_connector_cleanup,
2106 	.reset = drm_atomic_helper_connector_reset,
2107 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
2108 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
2109 };
2110 
it6161_attach_dsi(struct it6161 * it6161)2111 static int it6161_attach_dsi(struct it6161 *it6161)
2112 {
2113     struct mipi_dsi_host *host;
2114     struct mipi_dsi_device *dsi;
2115     int ret = 0;
2116     const struct mipi_dsi_device_info info = { .type = "it6161",
2117                          };
2118 
2119     host = of_find_mipi_dsi_host_by_node(it6161->host_node);
2120     if (!host) {
2121         DRM_INFO("it6161 failed to find dsi host\n");
2122         return -EPROBE_DEFER;
2123     }
2124 
2125     dsi = mipi_dsi_device_register_full(host, &info);
2126     if (IS_ERR(dsi)) {
2127         DRM_INFO("it6161 failed to create dsi device\n");
2128         ret = PTR_ERR(dsi);
2129         goto err_dsi_device;
2130     }
2131 
2132     it6161->dsi = dsi;
2133 
2134     dsi->lanes = 4;
2135     dsi->format = MIPI_DSI_FMT_RGB888;
2136     dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
2137               MIPI_DSI_MODE_EOT_PACKET | MIPI_DSI_MODE_VIDEO_HSE;
2138 
2139     ret = mipi_dsi_attach(dsi);
2140     if (ret < 0) {
2141         DRM_INFO("it6161 failed to attach dsi to host\n");
2142         goto err_dsi_attach;
2143     }
2144 
2145     return 0;
2146 
2147 err_dsi_attach:
2148     mipi_dsi_device_unregister(dsi);
2149 err_dsi_device:
2150     return ret;
2151 }
2152 
it6161_bridge_attach(struct drm_bridge * bridge,enum drm_bridge_attach_flags flags)2153 static int it6161_bridge_attach(struct drm_bridge *bridge,
2154 				enum drm_bridge_attach_flags flags)
2155 {
2156 	struct it6161 *it6161 = bridge_to_it6161(bridge);
2157 	struct device *dev;
2158 	int err;
2159 
2160 	dev = &it6161->i2c_mipi_rx->dev;
2161 	if (!bridge->encoder) {
2162 		DRM_DEV_ERROR(dev, "Parent encoder object not found");
2163 		return -ENODEV;
2164 	}
2165 
2166 	err = drm_connector_init(bridge->dev, &it6161->connector,
2167 				 &it6161_connector_funcs,
2168 				 DRM_MODE_CONNECTOR_HDMIA);
2169 	if (err < 0) {
2170 		DRM_DEV_ERROR(dev, "Failed to initialize connector: %d", err);
2171 		return err;
2172 	}
2173 
2174 	drm_connector_helper_add(&it6161->connector,
2175 				 &it6161_connector_helper_funcs);
2176 
2177 	it6161->connector.polled = DRM_CONNECTOR_POLL_HPD;
2178 
2179 	err = drm_connector_attach_encoder(&it6161->connector, bridge->encoder);
2180 	if (err < 0) {
2181 		DRM_DEV_ERROR(dev, "Failed to link up connector to encoder: %d",
2182 			      err);
2183 		goto cleanup_connector;
2184 	}
2185 
2186     	DRM_INFO("%s, ret:%d", __func__, it6161_attach_dsi(it6161));
2187 
2188 	err = drm_connector_register(&it6161->connector);
2189 	if (err < 0) {
2190 		DRM_DEV_ERROR(dev, "Failed to register connector: %d", err);
2191 		goto cleanup_connector;
2192 	}
2193 	it6161_debug("%s finish", __func__);
2194 
2195 	return 0;
2196 
2197 // unregister_connector:
2198 // 	drm_connector_unregister(&it6161->connector);
2199 cleanup_connector:
2200 	drm_connector_cleanup(&it6161->connector);
2201 	return err;
2202 }
2203 
it6161_detach_dsi(struct it6161 * it6161)2204 static void it6161_detach_dsi(struct it6161 *it6161)
2205 {
2206 	mipi_dsi_detach(it6161->dsi);
2207 	mipi_dsi_device_unregister(it6161->dsi);
2208 }
2209 
it6161_bridge_detach(struct drm_bridge * bridge)2210 static void it6161_bridge_detach(struct drm_bridge *bridge)
2211 {
2212 	struct it6161 *it6161 = bridge_to_it6161(bridge);
2213 
2214 	drm_connector_unregister(&it6161->connector);
2215 	drm_connector_cleanup(&it6161->connector);
2216 	it6161_detach_dsi(it6161);
2217 }
2218 
2219 static enum drm_mode_status
it6161_bridge_mode_valid(struct drm_bridge * bridge,const struct drm_display_info * info,const struct drm_display_mode * mode)2220 it6161_bridge_mode_valid(struct drm_bridge *bridge,
2221 								const struct drm_display_info *info,
2222 								const struct drm_display_mode *mode)
2223 {
2224 	//struct it6161 *it6161 = bridge_to_it6161(bridge);
2225 
2226 	// if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2227 	// 	return MODE_NO_INTERLACE;
2228 	it6161_debug("%s\n", __func__);
2229 	// /* Max 1200p at 5.4 Ghz, one lane */
2230 	// if (mode->clock > MAX_PIXEL_CLK)
2231 	// 	return MODE_CLOCK_HIGH;
2232 
2233 	if (mode->clock == 27027)
2234 		return MODE_BAD;
2235 
2236 	if (mode->clock > 165000)
2237 		return MODE_CLOCK_HIGH;
2238 
2239 	//DRM_INFO("%s end", __func__);
2240 
2241 	return MODE_OK;
2242 }
2243 
2244 // static int it6161_send_video_infoframe(struct it6161 *it6161,
2245 // 				       struct hdmi_avi_infoframe *frame)
2246 // {
2247 // 	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
2248 // 	int err;
2249 // 	struct device *dev = &it6161->i2c_mipi_rx->dev;
2250 
2251 // 	err = hdmi_avi_infoframe_pack(frame, buffer, sizeof(buffer));
2252 // 	if (err < 0) {
2253 // 		DRM_DEV_ERROR(dev, "Failed to pack AVI infoframe: %d\n", err);
2254 // 		return err;
2255 // 	}
2256 
2257 // 	err = dptx_set_bits(it6161, 0xE8, 0x01, 0x00);
2258 // 	if (err)
2259 // 		return err;
2260 
2261 // 	err = regmap_bulk_write(it6161->regmap_mipi_rx, 0xE9,
2262 // 				buffer + HDMI_INFOFRAME_HEADER_SIZE,
2263 // 				frame->length);
2264 // 	if (err)
2265 // 		return err;
2266 
2267 // 	err = dptx_set_bits(it6161, 0xE8, 0x01, 0x01);
2268 // 	if (err)
2269 // 		return err;
2270 
2271 // 	return 0;
2272 // }
2273 
it6161_bridge_mode_set(struct drm_bridge * bridge,const struct drm_display_mode * mode,const struct drm_display_mode * adjusted_mode)2274 static void it6161_bridge_mode_set(struct drm_bridge *bridge,
2275 				   const struct drm_display_mode *mode,
2276 				   const struct drm_display_mode *adjusted_mode)
2277 {
2278 	struct it6161 *it6161 = bridge_to_it6161(bridge);
2279 	struct device *dev = &it6161->i2c_mipi_rx->dev;
2280 	struct drm_display_mode *display_mode = &it6161->source_display_mode;
2281 	int err;
2282 
2283 	mutex_lock(&it6161->mode_lock);
2284 	err = drm_hdmi_avi_infoframe_from_display_mode(&it6161->source_avi_infoframe, &it6161->connector,
2285 						       mode);
2286 	if (err) {
2287 		DRM_DEV_ERROR(dev, "Failed to setup AVI infoframe: %d", err);
2288 		goto unlock;
2289 	}
2290 
2291 	//it6161->hdmi_tx_display_mode.base.id = adjusted_mode->base.id;
2292 	strlcpy(it6161->hdmi_tx_display_mode.name, adjusted_mode->name,
2293 		DRM_DISPLAY_MODE_LEN);
2294 	it6161->hdmi_tx_display_mode.type = adjusted_mode->type;
2295 	it6161->hdmi_tx_display_mode.flags = adjusted_mode->flags;
2296 	//err = it6161_send_video_infoframe(it6161, &frame);
2297 	strlcpy(display_mode->name, adjusted_mode->name,
2298 		DRM_DISPLAY_MODE_LEN);
2299 	display_mode->clock = mode->clock;
2300 	display_mode->hdisplay = mode->hdisplay;
2301 	display_mode->hsync_start = mode->hsync_start;
2302 	display_mode->hsync_end = mode->hsync_end;
2303 	display_mode->htotal = mode->htotal;
2304 	display_mode->vdisplay = mode->vdisplay;
2305 	display_mode->vsync_start = mode->vsync_start;
2306 	display_mode->vsync_end = mode->vsync_end;
2307 	display_mode->vtotal = mode->vtotal;
2308 	display_mode->flags = mode->flags;
2309 	it6161->vic = it6161->source_avi_infoframe.video_code;
2310 	DRM_INFO("config display mode clk: %d\n", display_mode->clock);
2311 	DRM_INFO("config display mode hdisplay: %d\n", display_mode->hdisplay);
2312 	DRM_INFO("config display mode hsync_start: %d\n", display_mode->hsync_start);
2313 	DRM_INFO("config display mode hsync_end: %d\n", display_mode->hsync_end);
2314 	DRM_INFO("config display mode htotal: %d\n", display_mode->htotal);
2315 	DRM_INFO("config display mode vdisplay: %d\n", display_mode->vdisplay);
2316 	DRM_INFO("config display mode vsync_start: %d\n", display_mode->vsync_start);
2317 	DRM_INFO("config display mode vsync_end: %d\n", display_mode->vsync_end);
2318 	DRM_INFO("config display mode vtotal: %d\n", display_mode->vtotal);
2319 
2320 	if (err)
2321 		DRM_DEV_ERROR(dev, "Failed to send AVI infoframe: %d", err);
2322 
2323 unlock:
2324 	mutex_unlock(&it6161->mode_lock);
2325 }
2326 
it6161_bridge_enable(struct drm_bridge * bridge)2327 static void it6161_bridge_enable(struct drm_bridge *bridge)
2328 {
2329 	struct it6161 *it6161 = bridge_to_it6161(bridge);
2330 	it6161_bridge = bridge;
2331 
2332 	it6161_debug("%s start", __func__);
2333 	mipi_rx_init(it6161);//allen
2334 	hdmi_tx_init(it6161);//allen
2335 	it6161_set_interrupts_active_level(HIGH);
2336 	it6161_mipi_rx_int_mask_enable(it6161);
2337 	it6161_hdmi_tx_int_mask_enable(it6161);
2338 
2339 	it6161_debug("%s start restart delayed work\n", __func__);
2340 	schedule_delayed_work(&it6161->restart, msecs_to_jiffies(2000));
2341 
2342 	//if (enable_de_only)
2343 	//			hdmi_tx_generate_blank_timing(it6161);
2344 
2345 	//hdmi_tx_video_reset(it6161);
2346 	// if (!it6161->enable_drv_hold) {
2347 	// 	it6161_int_mask_on(it6161);
2348 	// 	dptx_sys_chg(it6161, SYS_HPD);
2349 	// }
2350 }
2351 
it6161_bridge_disable(struct drm_bridge * bridge)2352 static void it6161_bridge_disable(struct drm_bridge *bridge)
2353 {
2354 	struct it6161 *it6161 = bridge_to_it6161(bridge);
2355 
2356 	it6161_debug("%s start", __func__);//----TODO
2357 	mipi_rx_logic_reset(it6161);
2358 	hdmi_tx_logic_reset(it6161);
2359 	it6161_set_interrupts_active_level(HIGH);
2360 	it6161_mipi_rx_int_mask_enable(it6161);
2361 	it6161_hdmi_tx_int_mask_enable(it6161);//---
2362 	//kfree(it6161->edid);
2363 	//it6161->edid = NULL;
2364 }
2365 
2366 static const struct drm_bridge_funcs it6161_bridge_funcs = {
2367 	.attach = it6161_bridge_attach,
2368 	.detach = it6161_bridge_detach,
2369 	.mode_valid = it6161_bridge_mode_valid,
2370 	.mode_set = it6161_bridge_mode_set,
2371 	.enable = it6161_bridge_enable,// set NULL for old linux version
2372 	.disable = it6161_bridge_disable,
2373 };
2374 
2375 #endif
2376 
2377 #define InitCEC() it6161_hdmi_tx_write(it6161, 0x8D, (CEC_I2C_SLAVE_ADDR|0x01))//HDMITX_SetI2C_Byte(0x8D, 0x01, 0x01)//HDMITX_SetI2C_Byte(0x0F, 0x08, 0x00)
2378 #define DisableCEC() it6161_hdmi_tx_set_bits(it6161, 0x8D, 0x01, 0x00)//HDMITX_SetI2C_Byte(0x0F, 0x08, 0x08)
2379 
it6161_check_device_ready(struct it6161 * it6161)2380 static bool it6161_check_device_ready(struct it6161 *it6161)
2381 {
2382     u8 Vendor_ID[2], Device_ID[2];
2383 
2384     Vendor_ID[0] = it6161_mipi_rx_read(it6161, 0x00);
2385     Vendor_ID[1] = it6161_mipi_rx_read(it6161, 0x01);
2386     Device_ID[0] = it6161_mipi_rx_read(it6161, 0x02);
2387     Device_ID[1] = it6161_mipi_rx_read(it6161, 0x03);
2388     // Version_ID = MIPIRX_ReadI2C_Byte(0x04);
2389     if (Vendor_ID[0] == 0x54 && Vendor_ID[1] == 0x49 && Device_ID[0] == 0x61 && Device_ID[1] == 0x61)
2390     {
2391         DRM_INFO("Find 6161 revision: 0x%2x", (u32)it6161_mipi_rx_read(it6161, 0x04));
2392         return true;
2393     }
2394     DRM_INFO("find it6161 Fail");
2395     return false;
2396 }
2397 
hdmi_tx_calc_rclk(struct it6161 * it6161)2398 static u32 hdmi_tx_calc_rclk(struct it6161 *it6161)//in c code: cal_txrclk
2399 {
2400 	// u8 uc ;
2401 	int i ;
2402 	long sum = 0, RCLKCNT, TimeLoMax, retry = 5;
2403 
2404 	InitCEC();
2405 	// it6161_hdmi_tx_write(it6161, 0x8D, (CEC_I2C_SLAVE_ADDR|0x01));// Enable CRCLK
2406 	msleep(10);
2407 
2408 	for (i = 0; i < retry; i++) {
2409 		// uc = it6161_cec_read(it6161, 0x09) & 0xFE ;
2410 		it6161_cec_write(it6161, 0x09, 1);
2411 		msleep(100);
2412 		it6161_cec_write(it6161, 0x09, 0);
2413 		RCLKCNT = it6161_cec_read(it6161, 0x47);
2414 		RCLKCNT <<= 8 ;
2415 		RCLKCNT |= it6161_cec_read(it6161, 0x46);
2416 		RCLKCNT <<= 8 ;
2417 		RCLKCNT |= it6161_cec_read(it6161, 0x45);
2418 		// DRM_INFO1(("RCLK = %d\n",RCLKCNT) );
2419 		sum += RCLKCNT ;
2420 	}
2421 	sum /= retry;
2422 	RCLKCNT = sum/1000;
2423 	it6161_cec_write(it6161, 0x0C, (RCLKCNT & 0xFF));
2424 
2425 	DisableCEC();
2426 
2427 //	it6161->hdmi_tx_rclk = (sum << 4) / 108;//actually nxp platform msleep(100) is 108ms
2428 	it6161->hdmi_tx_rclk = (sum << 4) / 104;//actually nxp platform msleep(100) is 108ms
2429 	DRM_INFO("hdmi tx rclk = %d.%dMHz", it6161->hdmi_tx_rclk / 1000, it6161->hdmi_tx_rclk % 1000);
2430 
2431 	TimeLoMax = (sum << 4)/10;//10*TxRCLK;
2432 
2433      // add HDCP TimeLomax over-flow protection
2434      if(TimeLoMax>0x3FFFF)
2435          TimeLoMax = 0x3FFFF;
2436 
2437      DRM_INFO("TimeLoMax=%08lx\n", TimeLoMax);
2438      it6161_hdmi_tx_write(it6161, 0x47, (TimeLoMax&0xFF));
2439      it6161_hdmi_tx_write(it6161, 0x48, ((TimeLoMax&0xFF00)>>8));
2440      it6161_hdmi_tx_set_bits(it6161, 0x49, 0x03, ((TimeLoMax&0x30000)>>16));
2441 
2442      return it6161->hdmi_tx_rclk;
2443 }
2444 
hdmi_tx_calc_pclk(struct it6161 * it6161)2445 static u32 hdmi_tx_calc_pclk(struct it6161 *it6161) //c code void cal_txclk( void )
2446 {
2447 	u8 uc, RCLKFreqSelRead;
2448 	int div, i;
2449 	u32 sum , count;
2450 
2451 	it6161_hdmi_tx_change_bank(it6161, 0);
2452 	// uc = it6161_hdmi_tx_read(it6161, 0x5F) & 0x80 ;
2453 
2454 	// if( ! uc )
2455 	// {
2456 	    // return 0 ;
2457 	// }
2458 	RCLKFreqSelRead = (it6161_hdmi_tx_read(it6161, 0x5D) & 0x04)>>2;//hdmitxset(0x5D, 0x04, (RCLKFreqSel<<2));
2459 	/* PCLK Count Pre-Test */
2460 	it6161_hdmi_tx_set_bits(it6161, 0xD7, 0xF0, 0x80);
2461 	msleep(1);
2462 	it6161_hdmi_tx_set_bits(it6161, 0xD7, 0x80, 0x00);
2463 
2464 	count = it6161_hdmi_tx_read(it6161, 0xD7) & 0xF ;
2465 	count <<= 8 ;
2466 	count |= it6161_hdmi_tx_read(it6161, 0xD8);
2467 
2468 	if (RCLKFreqSelRead)
2469 		count <<= 1;
2470 
2471 	for ( div = 7 ; div > 0 ; div-- ) {
2472 		if (count < (1<<(11-div)))
2473 			break ;
2474 	}
2475 
2476 	if (div < 0)
2477 	{
2478 		div = 0;
2479 	}
2480 
2481 	it6161_hdmi_tx_set_bits(it6161, 0xD7, 0x70, div<<4);
2482 
2483 	uc = it6161_hdmi_tx_read(it6161, 0xD7) & 0x7F ;
2484 	for( i = 0 , sum = 0 ; i < 100 ; i ++ )
2485 	{
2486 		it6161_hdmi_tx_write(it6161, 0xD7, uc|0x80) ;
2487 		msleep(1);
2488 		it6161_hdmi_tx_write(it6161, 0xD7, uc) ;
2489 
2490 		count = it6161_hdmi_tx_read(it6161, 0xD7) & 0xF ;
2491 		count <<= 8 ;
2492 		count |= it6161_hdmi_tx_read(it6161, 0xD8);
2493 		if (RCLKFreqSelRead)
2494 		{
2495 			count <<= 1;
2496 		}
2497 		sum += count;
2498 	}
2499 	sum /= 100;
2500 	count = sum;
2501 
2502 	it6161->hdmi_tx_pclk = it6161->hdmi_tx_rclk * 128 / count * 16 ;//128*16=2048
2503 	it6161->hdmi_tx_pclk *= (1<<div);
2504 
2505 	// if( it6161_hdmi_tx_read(it6161, 0x70) & 0x10 )
2506 	// {
2507 		// it6161->hdmi_tx_pclk /= 2 ;
2508 	// }
2509 
2510 	DRM_INFO("hdmi tx pclk = %d.%dMHz", it6161->hdmi_tx_pclk / 1000, it6161->hdmi_tx_pclk % 1000);
2511 	return it6161->hdmi_tx_pclk;
2512 }
2513 
hdmi_tx_get_display_mode(struct it6161 * it6161)2514 static void hdmi_tx_get_display_mode(struct it6161 *it6161)
2515 {
2516 	struct drm_display_mode *display_mode = &it6161->hdmi_tx_display_mode;
2517 	u32 hsyncpol, vsyncpol, interlaced;
2518 	u32 htotal, hdes, hdee, hsyncw, hactive, hfront_porch, H2ndVRRise;
2519 	u32 vtotal, vdes, vdee, vsyncw, vactive, vfront_porch, vdes2nd, vdee2nd, vsyncw2nd, VRS2nd;
2520 	u32 vdew2nd, vfph2nd, vbph2nd;
2521 	u8 rega9;
2522 
2523 	hdmi_tx_calc_rclk(it6161);
2524 	hdmi_tx_calc_pclk(it6161);
2525 
2526 	/* enable video timing read back */
2527 	it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x08, 0x08);
2528 
2529 	rega9 = it6161_hdmi_tx_read(it6161, 0xa9);
2530 
2531 	hsyncpol = rega9 & 0x01;
2532 	vsyncpol = (rega9 & 0x02) >> 1;
2533 	interlaced = (rega9 & 0x04) >> 2;
2534 
2535 	htotal = hdmi_tx_read_word(it6161, 0x98) & 0x0FFF;
2536 	hdes = hdmi_tx_read_word(it6161, 0x90) & 0x0FFF;
2537 	hdee = hdmi_tx_read_word(it6161, 0x92) & 0x0FFF;
2538 	hsyncw = hdmi_tx_read_word(it6161, 0x94) & 0x0FFF;
2539 	hactive = hdee - hdes;
2540 	hfront_porch = htotal - hdee;
2541 
2542 	vtotal = hdmi_tx_read_word(it6161, 0xA6) & 0x0FFF;
2543 	vdes = hdmi_tx_read_word(it6161, 0x9C) & 0x0FFF;
2544 	vdee = hdmi_tx_read_word(it6161, 0x9E) & 0x0FFF;
2545 	vsyncw = it6161_hdmi_tx_read(it6161, 0xA0);
2546 	vactive = vdee - vdes;
2547 	vfront_porch = (interlaced == 0x01) ? (vtotal / 2 - vdee) : (vtotal - vdee);
2548 
2549 	display_mode->clock = it6161->hdmi_tx_pclk;
2550 	display_mode->hdisplay = hactive;
2551 	display_mode->hsync_start = hactive + hfront_porch;
2552 	display_mode->hsync_end = hactive + hfront_porch + hsyncw;
2553 	display_mode->htotal = htotal;
2554 	display_mode->vdisplay = vactive;
2555 	display_mode->vsync_start = vactive + vfront_porch;
2556 	display_mode->vsync_end = vactive + vfront_porch + vsyncw;
2557 	display_mode->vtotal = vtotal;
2558 	display_mode->flags = ((hsyncpol == 0x01) ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC) |
2559 			      ((vsyncpol == 0x01) ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC) |
2560 			      ((interlaced == 0x01) ? DRM_MODE_FLAG_INTERLACE : 0x00);
2561 
2562 	if (interlaced) {
2563 		vdes2nd = hdmi_tx_read_word(it6161, 0xA2) & 0x0FFF;
2564 		vdee2nd = hdmi_tx_read_word(it6161, 0xA4) & 0x0FFF;
2565 		VRS2nd = hdmi_tx_read_word(it6161, 0xB1) & 0x0FFF;
2566 		vsyncw2nd = it6161_hdmi_tx_read(it6161, 0xA1);
2567 		H2ndVRRise = hdmi_tx_read_word(it6161, 0x96) & 0x0FFF;
2568 		vdew2nd = vdee2nd-vdes2nd;
2569 		vfph2nd = VRS2nd-vdee;
2570 		vbph2nd = vdes2nd-VRS2nd-vsyncw2nd;
2571 		DRM_INFO("vdew2nd    = %d\n", vdew2nd);
2572 		DRM_INFO("vfph2nd    = %d\n", vfph2nd);
2573 		DRM_INFO("VSyncW2nd  = %d\n", vsyncw2nd);
2574 		DRM_INFO("vbph2nd    = %d\n", vbph2nd);
2575 		DRM_INFO("H2ndVRRise = %d\n", H2ndVRRise);
2576 	}
2577 
2578 	/* disable video timing read back */
2579 	it6161_hdmi_tx_set_bits(it6161, 0xA8, 0x08, 0x00);
2580 }
2581 
it6161_hdmi_tx_set_av_mute(struct it6161 * it6161,u8 bEnable)2582 static void it6161_hdmi_tx_set_av_mute(struct it6161 *it6161, u8 bEnable)
2583 {
2584     it6161_hdmi_tx_change_bank(it6161, 0);
2585     it6161_hdmi_tx_set_bits(it6161, REG_TX_GCP,B_TX_SETAVMUTE, bEnable?B_TX_SETAVMUTE:0 );
2586     it6161_hdmi_tx_write(it6161, REG_TX_PKT_GENERAL_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT);
2587 }
2588 
2589 #ifdef HDCP
2590 #ifdef SUPPORT_SHA
2591 static u8 SHABuff[64] ;
2592 static u8 V[20] ;
2593 static u8 KSVList[32] ;
2594 static u8 Vr[20] ;
2595 static u8 M0[8] ;
2596 #endif
2597 
hdmi_tx_hdcp_auth_status(struct it6161 * it6161)2598 static bool hdmi_tx_hdcp_auth_status(struct it6161 *it6161)
2599 {
2600 	return !!(it6161_hdmi_tx_read(it6161, REG_TX_AUTH_STAT) & B_TX_AUTH_DONE);
2601 }
2602 
hdmi_tx_hdcp_get_auth_done(struct it6161 * it6161)2603 static bool hdmi_tx_hdcp_get_auth_done(struct it6161 *it6161)
2604 {
2605 	return hdmiTxDev[0].bAuthenticated;
2606 }
2607 
hdmi_tx_hdcp_clear_auth_interrupt(struct it6161 * it6161)2608 static void hdmi_tx_hdcp_clear_auth_interrupt(struct it6161 *it6161)
2609 {
2610 	it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK2, B_TX_KSVLISTCHK_MASK | B_TX_AUTH_DONE_MASK | B_TX_AUTH_FAIL_MASK, 0x00);
2611 	it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0, B_TX_CLR_AUTH_FAIL | B_TX_CLR_AUTH_DONE | B_TX_CLR_KSVLISTCHK);
2612 	it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1, 0x00);
2613 	it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS, B_TX_INTACTDONE);
2614 }
2615 
hdmi_tx_hdcp_reset_auth(struct it6161 * it6161)2616 static void hdmi_tx_hdcp_reset_auth(struct it6161 *it6161)
2617 {
2618 	it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
2619 	it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE, 0x00);
2620 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_TX_HDCP_RST_HDMITX, B_TX_HDCP_RST_HDMITX);
2621 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
2622 	it6161_hdmi_tx_clear_ddc_fifo(it6161);
2623 	it6161_hdmi_tx_abort_ddc(it6161);
2624 }
2625 
2626 /* write anything to reg21 to enable HDCP authentication by HW */
2627 
hdmi_tx_hdcp_auth_fire(struct it6161 * it6161)2628 static void hdmi_tx_hdcp_auth_fire(struct it6161 *it6161)
2629 {
2630 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHDCP); // MASTERHDCP,no need command but fire.
2631 	it6161_hdmi_tx_write(it6161, REG_TX_AUTHFIRE, 0x01);
2632 }
2633 
2634 /*
2635  * Start the Cipher to free run for random number. When stop
2636  * An is ready in Reg30
2637  */
2638 
hdmi_tx_hdcp_start_an_cipher(struct it6161 * it6161)2639 static void hdmi_tx_hdcp_start_an_cipher(struct it6161 *it6161)
2640 {
2641 	it6161_hdmi_tx_write(it6161, REG_TX_AN_GENERATE, B_TX_START_CIPHER_GEN);
2642 }
2643 
2644 /* Stop the Cipher,and An is ready in Reg30 */
2645 
hdmi_tx_hdcp_stop_an_cipher(struct it6161 * it6161)2646 static void hdmi_tx_hdcp_stop_an_cipher(struct it6161 *it6161)
2647 {
2648 	it6161_hdmi_tx_write(it6161, REG_TX_AN_GENERATE, B_TX_STOP_CIPHER_GEN);
2649 }
2650 
2651 /*
2652  * start An ciper random run at first,then stop it. Software can get
2653  * An in reg30~reg38,the write to reg28~2F
2654  */
2655 
hdmi_tx_hdcp_generate_an(struct it6161 * it6161)2656 static void hdmi_tx_hdcp_generate_an(struct it6161 *it6161)
2657 {
2658 	u8 an[DRM_HDCP_AN_LEN], i;
2659 
2660 	hdmi_tx_hdcp_start_an_cipher(it6161);
2661 	usleep_range(2000, 3000);
2662 	hdmi_tx_hdcp_stop_an_cipher(it6161);
2663 	it6161_hdmi_tx_change_bank(it6161, 0);
2664 	/* new An is ready in reg30 */
2665 	it6161_hdmi_tx_burst_read(it6161, REG_TX_AN_GEN, an, DRM_HDCP_AN_LEN);
2666 
2667 	for (i = 0; i < DRM_HDCP_AN_LEN; i++)
2668 		it6161_hdmi_tx_write(it6161, REG_TX_AN + i, an[i]);
2669 }
2670 
2671 /*
2672  * Parameter: pBCaps - pointer of byte to get BCaps.
2673  *            pBStatus - pointer of two bytes to get BStatus
2674  * Return: ER_SUCCESS if successfully got BCaps and BStatus.
2675  * Remark: get B status and capability from HDCP reciever via DDC bus.
2676  */
2677 
hdmi_tx_get_hdcp_bcaps_bstatus(struct it6161 * it6161,u8 * pBCaps,u16 * pBStatus)2678 static SYS_STATUS hdmi_tx_get_hdcp_bcaps_bstatus(struct it6161 *it6161, u8 *pBCaps, u16 *pBStatus)
2679 {
2680 	int ucdata;
2681 
2682 	it6161_hdmi_tx_change_bank(it6161, 0);
2683 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL,B_TX_MASTERDDC|B_TX_MASTERHOST);
2684 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER,DDC_HDCP_ADDRESS);
2685 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF,0x40); // BCaps offset
2686 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT,3);
2687 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD);
2688 
2689 	ucdata = it6161_ddc_wait(it6161);
2690 
2691 	if (ucdata < 0) {
2692 		DRM_INFO("get bcaps/bstatus failed");
2693 		return ER_FAIL;
2694 	}
2695 
2696 #if 1
2697 	ucdata = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT + 1);
2698 	*pBStatus = (u16)ucdata;
2699 	*pBStatus <<= 8;
2700 	ucdata = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT);
2701 	*pBStatus |= ((u16)ucdata & 0xFF);
2702 	*pBCaps = it6161_hdmi_tx_read(it6161, REG_TX_BCAP);
2703 #else
2704     *pBCaps = it6161_hdmi_tx_read(it6161, 0x17);
2705     *pBStatus = it6161_hdmi_tx_read(it6161, 0x17) & 0xFF ;
2706     *pBStatus |= (int)(it6161_hdmi_tx_read(it6161, 0x17)&0xFF)<<8;
2707     DRM_INFO("hdmi_tx_get_hdcp_bcaps_bstatus(): ucdata = %02X\n",(int)it6161_hdmi_tx_read(it6161, 0x16));
2708 #endif
2709 #ifdef _SUPPORT_HDCP_REPEATER_
2710 	TxBstatus = *pBStatus;
2711 #endif
2712 	return ER_SUCCESS;
2713 }
2714 
2715 /* Get bksv from HDCP sink */
2716 
hdmi_tx_hdcp_get_bksv(struct it6161 * it6161,u8 * bksv,size_t size)2717 static int hdmi_tx_hdcp_get_bksv(struct it6161 *it6161, u8 *bksv, size_t size)
2718 {
2719 	int ret;
2720 #ifdef _SUPPORT_HDMI_REPEATER_
2721 	int timeout;
2722 #endif
2723 
2724 	hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_BKSV, size, 0x00, CMD_DDC_SEQ_BURSTREAD);
2725 
2726 	ret = it6161_ddc_wait(it6161);
2727 
2728 	if (ret < 0) {
2729 		DRM_INFO("ddc get bksv failed");
2730 		return ret;
2731 	}
2732 
2733 	ret = it6161_hdmi_tx_burst_read(it6161, REG_TX_BKSV, bksv, size);
2734 
2735 	if (ret < 0)
2736 		DRM_INFO("i2c get bksv failed");
2737 
2738 	return ret;
2739 
2740 #ifdef _SUPPORT_HDMI_REPEATER_
2741 	for (timeout = 0; timeout < 5; timeout++)
2742 		KSVList[timeout] = *(bksv+timeout);
2743 #endif
2744 }
2745 
countbit(u8 b)2746 static u8 countbit(u8 b)
2747 {
2748 	u8 i, count ;
2749 
2750 	for (i = 0, count = 0; i < 8; i++) {
2751 		if (b & (1 << i))
2752 			count++;
2753 	}
2754 
2755 	return count;
2756 }
2757 
hdmitx_hdcp_CancelRepeaterAuthenticate(struct it6161 * it6161)2758 static void hdmitx_hdcp_CancelRepeaterAuthenticate(struct it6161 *it6161)
2759 {
2760 	it6161_debug("hdmitx_hdcp_CancelRepeaterAuthenticate");
2761 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERDDC | B_TX_MASTERHOST);
2762 	it6161_hdmi_tx_abort_ddc(it6161);
2763 	it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, B_TX_LISTFAIL | B_TX_LISTDONE);
2764 	it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
2765 	hdmi_tx_hdcp_clear_auth_interrupt(it6161);
2766 }
2767 
hdmitx_hdcp_ResumeRepeaterAuthenticate(struct it6161 * it6161)2768 static void hdmitx_hdcp_ResumeRepeaterAuthenticate(struct it6161 *it6161)
2769 {
2770 	it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE);
2771 	it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
2772 	it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERHDCP);
2773 }
2774 
2775 #define WCOUNT 17
2776 u32    VH[5];
2777 u32    w[WCOUNT];
2778 
2779 #define rol(x,y)(((x)<< (y))| (((u32)x)>> (32-y)))
2780 
SHATransform(u32 * h)2781 static void SHATransform(u32 * h)
2782 {
2783     int t;
2784     u32 tmp;
2785 
2786     h[0]=0x67452301;
2787     h[1]=0xefcdab89;
2788     h[2]=0x98badcfe;
2789     h[3]=0x10325476;
2790     h[4]=0xc3d2e1f0;
2791 
2792     for (t=0; t < 20; t++){
2793         if(t>=16)
2794         {
2795             tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2796             w[(t)% WCOUNT]=rol(tmp,1);
2797         }
2798         DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2799 
2800         tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[3] & ~h[1]))+ h[4] + w[(t)% WCOUNT] + 0x5a827999;
2801         DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2802 
2803         h[4]=h[3];
2804         h[3]=h[2];
2805         h[2]=rol(h[1],30);
2806         h[1]=h[0];
2807         h[0]=tmp;
2808 
2809     }
2810     for (t=20; t < 40; t++){
2811         tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2812         w[(t)% WCOUNT]=rol(tmp,1);
2813         DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2814         tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0x6ed9eba1;
2815         DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2816         h[4]=h[3];
2817         h[3]=h[2];
2818         h[2]=rol(h[1],30);
2819         h[1]=h[0];
2820         h[0]=tmp;
2821     }
2822     for (t=40; t < 60; t++){
2823         tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2824         w[(t)% WCOUNT]=rol(tmp,1);
2825         DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2826         tmp=rol(h[0],5)+ ((h[1] & h[2])| (h[1] & h[3])| (h[2] & h[3]))+ h[4] + w[(t)% WCOUNT] + 0x8f1bbcdc;
2827         DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2828         h[4]=h[3];
2829         h[3]=h[2];
2830         h[2]=rol(h[1],30);
2831         h[1]=h[0];
2832         h[0]=tmp;
2833     }
2834     for (t=60; t < 80; t++)
2835     {
2836         tmp=w[(t - 3)% WCOUNT] ^ w[(t - 8)% WCOUNT] ^ w[(t - 14)% WCOUNT] ^ w[(t - 16)% WCOUNT];
2837         w[(t)% WCOUNT]=rol(tmp,1);
2838         DRM_INFO("w[%d]=%08X\n",t,w[(t)% WCOUNT]);
2839         tmp=rol(h[0],5)+ (h[1] ^ h[2] ^ h[3])+ h[4] + w[(t)% WCOUNT] + 0xca62c1d6;
2840         DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2841         h[4]=h[3];
2842         h[3]=h[2];
2843         h[2]=rol(h[1],30);
2844         h[1]=h[0];
2845         h[0]=tmp;
2846     }
2847     DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2848     h[0] +=0x67452301;
2849     h[1] +=0xefcdab89;
2850     h[2] +=0x98badcfe;
2851     h[3] +=0x10325476;
2852     h[4] +=0xc3d2e1f0;
2853 
2854     DRM_INFO("%08X %08X %08X %08X %08X\n",h[0],h[1],h[2],h[3],h[4]);
2855 }
2856 
SHA_Simple(void * p,u32 len,u8 * output)2857 static void SHA_Simple(void *p,u32 len,u8 *output)
2858 {
2859     // SHA_State s;
2860     u32 i,t;
2861     u32 c;
2862     u8 *pBuff=p;
2863 
2864     for(i=0;i < len;i++)
2865     {
2866         t=i/4;
2867         if(i%4==0)
2868         {
2869             w[t]=0;
2870         }
2871         c=pBuff[i];
2872         c <<=(3-(i%4))*8;
2873         w[t] |=c;
2874         DRM_INFO("pBuff[%d]=%02X,c=%08X,w[%d]=%08X\n",(int)i,(int)pBuff[i],c,(int)t,w[t]);
2875     }
2876     t=i/4;
2877     if(i%4==0)
2878     {
2879         w[t]=0;
2880     }
2881     //c=0x80 << ((3-i%4)*24);
2882     c=0x80;
2883     c <<=((3-i%4)*8);
2884     w[t]|=c;t++;
2885     for(; t < 15;t++)
2886     {
2887         w[t]=0;
2888     }
2889     w[15]=len*8;
2890 
2891     for(i = 0; i < 16; i++)
2892     {
2893         DRM_INFO("w[%d] = %08X\n",i,w[i]);
2894     }
2895     SHATransform(VH);
2896 
2897     for(i=0;i < 5;i++)
2898     {
2899         output[i*4+3]=(u8)((VH[i]>>24)&0xFF);
2900         output[i*4+2]=(u8)((VH[i]>>16)&0xFF);
2901         output[i*4+1]=(u8)((VH[i]>>8)&0xFF);
2902         output[i*4+0]=(u8)(VH[i]&0xFF);
2903     }
2904 }
2905 
2906 #ifdef SUPPORT_SHA
2907 
hdmitx_hdcp_CheckSHA(u8 pM0[],u16 BStatus,u8 pKSVList[],int cDownStream,u8 Vr[])2908 static SYS_STATUS hdmitx_hdcp_CheckSHA(u8 pM0[],u16 BStatus,u8 pKSVList[],int cDownStream,u8 Vr[])
2909 {
2910     int i,n ;
2911 
2912     for(i = 0 ; i < cDownStream*5 ; i++)
2913     {
2914         SHABuff[i] = pKSVList[i] ;
2915     }
2916     SHABuff[i++] = BStatus & 0xFF ;
2917     SHABuff[i++] = (BStatus>>8) & 0xFF ;
2918     for(n = 0 ; n < 8 ; n++,i++)
2919     {
2920         SHABuff[i] = pM0[n] ;
2921     }
2922     n = i ;
2923     // SHABuff[i++] = 0x80 ; // end mask
2924     for(; i < 64 ; i++)
2925     {
2926         SHABuff[i] = 0 ;
2927     }
2928     // n = cDownStream * 5 + 2 /* for BStatus */ + 8 /* for M0 */ ;
2929     // n *= 8 ;
2930     // SHABuff[62] = (n>>8) & 0xff ;
2931     // SHABuff[63] = (n>>8) & 0xff ;
2932 /*
2933     for(i = 0 ; i < 64 ; i++)
2934     {
2935         if(i % 16 == 0)
2936         {
2937             DRM_INFO("SHA[]: ");
2938         }
2939         DRM_INFO(" %02X",SHABuff[i]);
2940         if((i%16)==15)
2941         {
2942             DRM_INFO("\n");
2943         }
2944     }
2945     */
2946     SHA_Simple(SHABuff,n,V);
2947     for(i = 0 ; i < 20 ; i++)
2948     {
2949         if(V[i] != Vr[i])
2950         {
2951             DRM_INFO("V[] =");
2952             for(i = 0 ; i < 20 ; i++)
2953             {
2954                 DRM_INFO(" %02X",(int)V[i]);
2955             }
2956             DRM_INFO("\nVr[] =");
2957             for(i = 0 ; i < 20 ; i++)
2958             {
2959                 DRM_INFO(" %02X",(int)Vr[i]);
2960             }
2961             return ER_FAIL ;
2962         }
2963     }
2964     return ER_SUCCESS ;
2965 }
2966 
2967 #endif // SUPPORT_SHA
2968 
hdmi_tx_hdcp_get_ksv_list(struct it6161 * it6161,u8 * pKSVList,u8 cDownStream)2969 static SYS_STATUS hdmi_tx_hdcp_get_ksv_list(struct it6161 *it6161, u8 *pKSVList,u8 cDownStream)
2970 {
2971     u8 timeout = 100, ucdata;
2972 
2973     if( cDownStream == 0 )
2974     {
2975         return ER_SUCCESS ;
2976     }
2977     if( /* cDownStream == 0 || */ pKSVList == NULL)
2978     {
2979         return ER_FAIL ;
2980     }
2981     it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL, B_TX_MASTERHOST);
2982     it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER, 0x74);
2983     it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF, 0x43);
2984     it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT, cDownStream * 5);
2985     it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD, CMD_DDC_SEQ_BURSTREAD);
2986 
2987     ucdata = it6161_ddc_wait(it6161);
2988 
2989     if (ucdata < 0)
2990     {
2991         return ER_FAIL ;
2992     }
2993     DRM_INFO("hdmi_tx_hdcp_get_ksv_list(): KSV");
2994     for(timeout = 0 ; timeout < cDownStream * 5 ; timeout++)
2995     {
2996         pKSVList[timeout] = it6161_hdmi_tx_read(it6161, REG_TX_DDC_READFIFO);
2997 		#ifdef _SUPPORT_HDCP_REPEATER_
2998 		KSVList[timeout] = pKSVList[timeout];
2999         DRM_INFO(" %x",(int)pKSVList[timeout]);
3000         DRM_INFO(" %02X",(int)pKSVList[timeout]);
3001 		#endif
3002     }
3003 
3004     return ER_SUCCESS ;
3005 }
3006 
hdmitx_hdcp_GetVr(struct it6161 * it6161,u8 * pVr)3007 static SYS_STATUS hdmitx_hdcp_GetVr(struct it6161 *it6161, u8 *pVr)
3008 {
3009     u8 timeout, ucdata;
3010 
3011     if(pVr == NULL)
3012     {
3013         return ER_FAIL ;
3014     }
3015     it6161_hdmi_tx_write(it6161, REG_TX_DDC_MASTER_CTRL,B_TX_MASTERHOST);
3016     it6161_hdmi_tx_write(it6161, REG_TX_DDC_HEADER,0x74);
3017     it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQOFF,0x20);
3018     it6161_hdmi_tx_write(it6161, REG_TX_DDC_REQCOUNT,20);
3019     it6161_hdmi_tx_write(it6161, REG_TX_DDC_CMD,CMD_DDC_SEQ_BURSTREAD);
3020 
3021     ucdata = it6161_ddc_wait(it6161);
3022     if (ucdata < 0)
3023     {
3024         DRM_INFO("hdmitx_hdcp_GetVr(): DDC fail by timeout.\n");
3025         return ER_FAIL ;
3026     }
3027     it6161_hdmi_tx_change_bank(it6161, 0);
3028 
3029     for(timeout = 0 ; timeout < 5 ; timeout++)
3030     {
3031         it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL ,timeout);
3032         pVr[timeout*4]  = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE1);
3033         pVr[timeout*4+1] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE2);
3034         pVr[timeout*4+2] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE3);
3035         pVr[timeout*4+3] = (u32)it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE4);
3036 //        DRM_INFO("V' = %02X %02X %02X %02X\n",(int)pVr[timeout*4],(int)pVr[timeout*4+1],(int)pVr[timeout*4+2],(int)pVr[timeout*4+3]);
3037     }
3038     return ER_SUCCESS ;
3039 }
3040 
hdmitx_hdcp_GetM0(struct it6161 * it6161,u8 * pM0)3041 static SYS_STATUS hdmitx_hdcp_GetM0(struct it6161 *it6161, u8 *pM0)
3042 {
3043     int i ;
3044 
3045     if(!pM0)
3046     {
3047         return ER_FAIL ;
3048     }
3049     it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,5); // read m0[31:0] from reg51~reg54
3050     pM0[0] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE1);
3051     pM0[1] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE2);
3052     pM0[2] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE3);
3053     pM0[3] = it6161_hdmi_tx_read(it6161, REG_TX_SHA_RD_BYTE4);
3054     it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,0); // read m0[39:32] from reg55
3055     pM0[4] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3056     it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,1); // read m0[47:40] from reg55
3057     pM0[5] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3058     it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,2); // read m0[55:48] from reg55
3059     pM0[6] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3060     it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL,3); // read m0[63:56] from reg55
3061     pM0[7] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3062 
3063     DRM_INFO("M[] =");
3064     for(i = 0 ; i < 8 ; i++)
3065     {
3066         DRM_INFO("0x%02x,",(int)pM0[i]);
3067     }
3068     DRM_INFO("\n");
3069     return ER_SUCCESS ;
3070 }
3071 
3072 #ifdef _SUPPORT_HDCP_REPEATER_
3073 
TxHDCP_chg(HDMITX_HDCP_State state)3074 static void TxHDCP_chg(HDMITX_HDCP_State state)
3075 {
3076     if( state == hdmiTxDev[0].TxHDCP_State )
3077     {
3078         return ;
3079     }
3080     DRM_INFO("TxHDCP %d -> %d\n",hdmiTxDev[0].TxHDCP_State,state);
3081     hdmiTxDev[0].TxHDCP_State = state ;
3082 
3083     switch(state)
3084     {
3085     case TxHDCP_Off:
3086         hdmiTxDev[0].bAuthenticated=false;
3087         hdmiTxDev[0].usHDCPTimeOut = 0 ;
3088         hdmi_tx_hdcp_reset_auth(it6161);
3089         break;
3090 
3091     case TxHDCP_AuthRestart:
3092         hdmiTxDev[0].bAuthenticated = false ;
3093         hdmi_tx_hdcp_reset_auth(it6161);
3094         hdmiTxDev[0].usHDCPTimeOut = 5 ;
3095         break;
3096 
3097     case TxHDCP_AuthStart:
3098         hdmi_tx_hdcp_reset_auth(it6161);
3099         hdmiTxDev[0].bAuthenticated = false ;
3100         hdmiTxDev[0].usHDCPTimeOut = 80 ;
3101         break;
3102 
3103     case TxHDCP_Receiver:
3104         hdmiTxDev[0].usHDCPTimeOut = 250 ; // set the count as the 5000ms/interval
3105         break;
3106 
3107     case TxHDCP_Repeater:
3108         hdmiTxDev[0].usHDCPTimeOut = 250 ; // set the count as the 5000ms/interval
3109         break;
3110 
3111     case TxHDCP_CheckFIFORDY:
3112 
3113         hdmiTxDev[0].usHDCPTimeOut = 300 ; // set the count as the 6000ms/interval
3114         break;
3115 
3116     case TxHDCP_VerifyRevocationList:
3117         break;
3118 
3119 
3120     case TxHDCP_AuthFail:
3121         hdmi_tx_hdcp_reset_auth(it6161);
3122         hdmiTxDev[0].bAuthenticated = false ;
3123         break;
3124 
3125     case TxHDCP_RepeaterFail:
3126         hdmitx_hdcp_CancelRepeaterAuthenticate(it6161);
3127         hdmi_tx_hdcp_reset_auth(it6161);
3128         hdmiTxDev[0].bAuthenticated = false ;
3129         break;
3130 
3131     case TxHDCP_RepeaterSuccess:
3132         hdmitx_hdcp_ResumeRepeaterAuthenticate(it6161);
3133     case TxHDCP_Authenticated:
3134         it6161_hdmi_tx_set_av_mute(it6161, false) ;
3135         hdmiTxDev[0].bAuthenticated = true ;
3136         break;
3137 
3138     }
3139 }
3140 
TxHDCP_fsm()3141 static void TxHDCP_fsm()
3142 {
3143     u8 ucdata ;
3144     int i ;
3145 
3146     static u8 BCaps ;
3147     static u16 BStatus ;
3148     static u8 cDownStream ;// this value will be use in the function....
3149     static u8 bksv[5] ;
3150 
3151 
3152     switch(hdmiTxDev[0].TxHDCP_State)
3153     {
3154     case TxHDCP_Off:
3155         break;
3156 
3157     case TxHDCP_AuthRestart:
3158         if(hdmiTxDev[0].usHDCPTimeOut>0)
3159         {
3160             hdmiTxDev[0].usHDCPTimeOut -- ;
3161         }
3162         if( hdmiTxDev[0].usHDCPTimeOut == 0 )
3163         {
3164             TxHDCP_chg(TxHDCP_AuthStart) ;
3165         }
3166         break;
3167 
3168     case TxHDCP_AuthStart:
3169         cDownStream = 0 ;
3170         it6161_hdmi_tx_change_bank(it6161, 0);
3171         if(hdmiTxDev[0].usHDCPTimeOut>0)
3172         {
3173             hdmiTxDev[0].usHDCPTimeOut -- ;
3174             ucdata = it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)& (B_TX_HPDETECT|B_TX_RXSENDETECT);
3175 
3176         	if(ucdata != (B_TX_HPDETECT|B_TX_RXSENDETECT))
3177         	{
3178         	    // if no Rx sense, do not start authentication.
3179         	    // Eventhough start it, cannot work.
3180         	    return ;
3181         	}
3182 
3183             if(hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus) != ER_SUCCESS)
3184             {
3185                 DRM_INFO("hdmi_tx_get_hdcp_bcaps_bstatus fail.\n");
3186                 return;
3187             }
3188             // wait for HDMI State
3189 
3190             if(B_TX_HDMI_MODE == (it6161_hdmi_tx_read(it6161, REG_TX_HDMI_MODE) & B_TX_HDMI_MODE ))
3191             {
3192                 if((BStatus & B_TX_CAP_HDMI_MODE)!=B_TX_CAP_HDMI_MODE)
3193                 {
3194                     return;
3195                 }
3196             }
3197             else
3198             {
3199                 if((BStatus & B_TX_CAP_HDMI_MODE)==B_TX_CAP_HDMI_MODE)
3200                 {
3201                     return ;
3202                 }
3203             }
3204 
3205         }
3206         else
3207         {
3208             TxHDCP_chg(TxHDCP_AuthRestart) ;
3209         }
3210 
3211     	DRM_INFO("BCAPS = %x BSTATUS = %X\n", (int)BCaps, BStatus);
3212         hdmi_tx_hdcp_get_bksv(it6161, bksv, ARRAY_SIZE(bksv));
3213         DRM_INFO("bksv %X %X %X %X %X\n",(int)bksv[0],(int)bksv[1],(int)bksv[2],(int)bksv[3],(int)bksv[4]);
3214 
3215         for(i = 0, ucdata = 0 ; i < 5 ; i ++)
3216         {
3217             ucdata += countbit(bksv[i]);
3218         }
3219         if( ucdata != 20 )
3220         {
3221             DRM_INFO("countbit error\n");
3222             TxHDCP_chg(TxHDCP_AuthFail) ;
3223             return ;
3224 
3225         }
3226 
3227         it6161_hdmi_tx_change_bank(it6161, 0); // switch bank action should start on direct register writting of each function.
3228 
3229         it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_TX_HDCP_RST_HDMITX, 0x00);
3230 
3231         it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE,8|B_TX_CPDESIRE);
3232         hdmi_tx_hdcp_clear_auth_interrupt(it6161);
3233 
3234         hdmi_tx_hdcp_generate_an(it6161);
3235         it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL,0);
3236         hdmiTxDev[0].bAuthenticated = false ;
3237 
3238         it6161_hdmi_tx_clear_ddc_fifo(it6161);
3239         hdmi_tx_hdcp_auth_fire(it6161);
3240         hdmiTxDev[0].Tx_BStatus = BStatus ;
3241         if(BCaps & B_TX_CAP_HDMI_REPEATER)
3242         {
3243             TxHDCP_chg(TxHDCP_Repeater) ;
3244         }
3245         else
3246         {
3247 
3248             for(i = 0; i < 5 ; i ++)
3249             {
3250                 KSVList[i] = bksv[i] ;
3251             }
3252             TxHDCP_chg(TxHDCP_Receiver) ;
3253         }
3254         break;
3255 
3256     case TxHDCP_Receiver:
3257 
3258         if(hdmiTxDev[0].usHDCPTimeOut >0)
3259         {
3260             hdmiTxDev[0].usHDCPTimeOut -- ;
3261         }
3262 
3263         if(hdmiTxDev[0].usHDCPTimeOut==0)
3264         {
3265             TxHDCP_chg(TxHDCP_AuthFail) ;
3266             return ;
3267         }
3268         else
3269         {
3270             DRM_INFO("[Fsm] Receiver: usHDCPTimeOut = %d\n",hdmiTxDev[0].usHDCPTimeOut);
3271             ucdata = it6161_hdmi_tx_read(it6161, REG_TX_AUTH_STAT);
3272             DRM_INFO("[Fsm] Receiver: ucdata = %X, BStatus = %X\n",ucdata,BStatus);
3273 
3274             if(ucdata & B_TX_AUTH_DONE)
3275             {
3276                 //BStatus += 0x101 ;
3277             	IT680X_DownStream_AuthDoneCallback(bksv, BStatus);
3278                 TxHDCP_chg(TxHDCP_Authenticated) ;
3279                 break ;
3280             }
3281         }
3282         break;
3283 
3284     case TxHDCP_Repeater:
3285         if(hdmiTxDev[0].usHDCPTimeOut >0)
3286         {
3287             hdmiTxDev[0].usHDCPTimeOut -- ;
3288         }
3289 
3290         if(hdmiTxDev[0].usHDCPTimeOut==0)
3291         {
3292             TxHDCP_chg(TxHDCP_AuthFail) ;
3293             return ;
3294         }
3295         break;
3296 
3297     case TxHDCP_CheckFIFORDY:
3298         if(hdmiTxDev[0].usHDCPTimeOut >0)
3299         {
3300             hdmiTxDev[0].usHDCPTimeOut -- ;
3301         }
3302 
3303         if(hdmiTxDev[0].usHDCPTimeOut==0)
3304         {
3305             TxHDCP_chg(TxHDCP_RepeaterFail) ;
3306             return ;
3307         }
3308 
3309         if(hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus) == ER_FAIL)
3310         {
3311             DRM_INFO("Get BCaps fail\n");
3312             break ;  // get fail, again.
3313         }
3314 
3315 
3316         if(BCaps & B_TX_CAP_KSV_FIFO_RDY)
3317         {
3318             DRM_INFO("FIFO Ready\n");
3319 
3320 
3321             it6161_hdmi_tx_clear_ddc_fifo(it6161);
3322             it6161_hdmi_tx_generate_ddc_sclk(it6161);
3323             hdmiTxDev[0].Tx_BStatus = BStatus ;
3324             cDownStream=(BStatus & M_TX_DOWNSTREAM_COUNT);
3325             //+++++++++++++++++++++++++++++++++++++
3326             DRM_INFO("Downstream=%X \n",cDownStream);
3327 
3328             if( cDownStream > (MAX_REPEATER_DOWNSTREAM_COUNT-1))
3329             {
3330                 hdmiTxDev[0].Tx_BStatus |= B_TX_DOWNSTREAM_OVER ;
3331             }
3332             if( cDownStream > (MAX_REPEATER_DOWNSTREAM_COUNT-1) ||
3333                 BStatus & (B_TX_MAX_CASCADE_EXCEEDED|B_TX_DOWNSTREAM_OVER))
3334             {
3335                 DRM_INFO("Invalid Down stream count,fail\n");
3336 
3337                 // RxAuthSetBStatus(B_DOWNSTREAM_OVER|B_MAX_CASCADE_EXCEEDED);    //for ALLION HDCP 3C-2-06
3338                 // ForceKSVFIFOReady(B_DOWNSTREAM_OVER|B_MAX_CASCADE_EXCEEDED) ;
3339                 IT680X_DownStream_AuthDoneCallback(KSVList, 0xFFF);
3340                 TxHDCP_chg(TxHDCP_RepeaterFail);
3341                 break;
3342             }
3343 
3344              TxHDCP_chg(TxHDCP_VerifyRevocationList) ;
3345              break ;
3346         }
3347 
3348         break;
3349 
3350     case TxHDCP_VerifyRevocationList:
3351 
3352     #ifdef SUPPORT_SHA
3353         DRM_INFO("TxHDCP_VerifyRevocationList: cDownStream = %d",cDownStream);
3354         if(hdmi_tx_hdcp_get_ksv_list(it6161, KSVList,cDownStream) == ER_FAIL)
3355         {
3356         	DRM_INFO("hdmitx_hdcp_Repeater_Fail 2\n");
3357             TxHDCP_chg(TxHDCP_RepeaterFail);
3358             break;
3359         }
3360 
3361         if(hdmitx_hdcp_GetVr(it6161, Vr) == ER_FAIL)
3362         {
3363         	DRM_INFO("hdmitx_hdcp_Repeater_Fail 3\n");
3364             TxHDCP_chg(TxHDCP_RepeaterFail);
3365             break;
3366         }
3367         if(hdmitx_hdcp_GetM0(it6161, M0) == ER_FAIL)
3368         {
3369         	DRM_INFO("hdmitx_hdcp_Repeater_Fail 4\n");
3370             TxHDCP_chg(TxHDCP_RepeaterFail);
3371             break;
3372         }
3373         // do check SHA
3374         if(hdmitx_hdcp_CheckSHA(M0,BStatus,KSVList,cDownStream,Vr) == ER_FAIL)
3375         {
3376         	DRM_INFO("hdmitx_hdcp_Repeater_Fail 5\n");
3377             TxHDCP_chg(TxHDCP_RepeaterFail);
3378             break;
3379         }
3380     #endif // SUPPORT_SHA
3381         // checkSHA success, append the bksv to KSV List
3382         for(i = 0; i < 5 ; i ++)
3383         {
3384             KSVList[cDownStream*5+i] = bksv[i] ;
3385         }
3386 
3387         for( i = 0 ; i < ((cDownStream+1)*5) ; i ++ )
3388         {
3389             DRM_INFO("KSVLIST[%d] = %X\n",i,KSVList[i]);
3390         }
3391 
3392         //BStatus += 0x101 ;
3393     	IT680X_DownStream_AuthDoneCallback(KSVList, BStatus);
3394 
3395         TxHDCP_chg(TxHDCP_RepeaterSuccess) ;
3396         break;
3397 
3398 
3399     case TxHDCP_Authenticated:
3400         break;
3401 
3402     case TxHDCP_AuthFail:
3403         // force revoke the KSVList
3404         // IT680X_DownStream_AuthDoneCallback(KSVList, 0xFFF);
3405         TxHDCP_chg(TxHDCP_AuthRestart);
3406         break;
3407 
3408     case TxHDCP_RepeaterFail:
3409         TxHDCP_chg(TxHDCP_AuthFail);
3410         break;
3411 
3412     case TxHDCP_RepeaterSuccess:
3413         TxHDCP_chg(TxHDCP_Authenticated);
3414         break;
3415 
3416     }
3417 }
3418 
3419 #else
3420 
3421 //////////////////////////////////////////////////////////////////////
3422 // Function: hdmi_tx_hdcp_auth_process_Repeater
3423 // Parameter: BCaps and BStatus
3424 // Return: ER_SUCCESS if success,if AUTH_FAIL interrupt status,return fail.
3425 // Remark:
3426 // Side-Effect: as Authentication
3427 //////////////////////////////////////////////////////////////////////
3428 #ifdef HDCP
hdmi_tx_hdcp_auth_process_Repeater(struct it6161 * it6161)3429 static SYS_STATUS hdmi_tx_hdcp_auth_process_Repeater(struct it6161 *it6161)
3430 {
3431     u8 uc ,ii;
3432     // u8 revoked ;
3433     // int i ;
3434     u8 cDownStream ;
3435 
3436     u8 BCaps;
3437     u16 BStatus ;
3438     u16 timeout ;
3439 
3440     DRM_INFO("Authentication for repeater\n");
3441     // emily add for test,abort HDCP
3442     // 2007/10/01 marked by jj_tseng@chipadvanced.com
3443     // it6161_hdmi_tx_write(it6161, 0x20,0x00);
3444     // it6161_hdmi_tx_write(it6161, 0x04,0x01);
3445     // it6161_hdmi_tx_write(it6161, 0x10,0x01);
3446     // it6161_hdmi_tx_write(it6161, 0x15,0x0F);
3447     // msleep(100);
3448     // it6161_hdmi_tx_write(it6161, 0x04,0x00);
3449     // it6161_hdmi_tx_write(it6161, 0x10,0x00);
3450     // it6161_hdmi_tx_write(it6161, 0x20,0x01);
3451     // msleep(100);
3452     // test07 = it6161_hdmi_tx_read(it6161, 0x7);
3453     // test06 = it6161_hdmi_tx_read(it6161, 0x6);
3454     // test08 = it6161_hdmi_tx_read(it6161, 0x8);
3455     //~jj_tseng@chipadvanced.com
3456     // end emily add for test
3457     //////////////////////////////////////
3458     // Authenticate Fired
3459     //////////////////////////////////////
3460 
3461     hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus);
3462     msleep(2);
3463     if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3464     {
3465         DRM_INFO("HPD Before Fire Auth\n");
3466         goto hdmitx_hdcp_Repeater_Fail ;
3467     }
3468     hdmi_tx_hdcp_auth_fire(it6161);
3469     //msleep(550); // emily add for test
3470     for(ii=0;ii<55;ii++)    //msleep(550); // emily add for test
3471     {
3472         if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3473         {
3474             goto hdmitx_hdcp_Repeater_Fail ;
3475         }
3476         msleep(10);
3477     }
3478     for(timeout = /*250*6*/10 ; timeout > 0 ; timeout --)
3479     {
3480         DRM_INFO("timeout = %d wait part 1\n",timeout);
3481         if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3482         {
3483             DRM_INFO("HPD at wait part 1\n");
3484             goto hdmitx_hdcp_Repeater_Fail ;
3485         }
3486         uc = it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1);
3487         if(uc & B_TX_INT_DDC_BUS_HANG)
3488         {
3489             DRM_INFO("DDC Bus hang\n");
3490             goto hdmitx_hdcp_Repeater_Fail ;
3491         }
3492         uc = it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT2);
3493 
3494         if(uc & B_TX_INT_AUTH_FAIL)
3495         {
3496             /*
3497             it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0,B_TX_CLR_AUTH_FAIL);
3498             it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1,0);
3499             it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,B_TX_INTACTDONE);
3500             it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,0);
3501             */
3502             DRM_INFO("hdmi_tx_hdcp_auth_process_Repeater(): B_TX_INT_AUTH_FAIL.\n");
3503             goto hdmitx_hdcp_Repeater_Fail ;
3504         }
3505         // emily add for test
3506         // test =(it6161_hdmi_tx_read(it6161, 0x7)&0x4)>>2 ;
3507         if(uc & B_TX_INT_KSVLIST_CHK)
3508         {
3509             it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0,B_TX_CLR_KSVLISTCHK);
3510             it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1,0);
3511             it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,B_TX_INTACTDONE);
3512             it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS,0);
3513             DRM_INFO("B_TX_INT_KSVLIST_CHK\n");
3514             break ;
3515         }
3516         msleep(5);
3517     }
3518     if(timeout == 0)
3519     {
3520         DRM_INFO("Time out for wait KSV List checking interrupt\n");
3521         goto hdmitx_hdcp_Repeater_Fail ;
3522     }
3523     ///////////////////////////////////////
3524     // clear KSVList check interrupt.
3525     ///////////////////////////////////////
3526 
3527     for(timeout = 500 ; timeout > 0 ; timeout --)
3528     {
3529         DRM_INFO("timeout=%d at wait FIFO ready\n",timeout);
3530         if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3531         {
3532             DRM_INFO("HPD at wait FIFO ready\n");
3533             goto hdmitx_hdcp_Repeater_Fail ;
3534         }
3535         if(hdmi_tx_get_hdcp_bcaps_bstatus(it6161, &BCaps,&BStatus) == ER_FAIL)
3536         {
3537             DRM_INFO("Get BCaps fail\n");
3538             goto hdmitx_hdcp_Repeater_Fail ;
3539         }
3540         if(BCaps & B_TX_CAP_KSV_FIFO_RDY)
3541         {
3542              DRM_INFO("FIFO Ready\n");
3543              break ;
3544         }
3545         msleep(5);
3546 
3547     }
3548     if(timeout == 0)
3549     {
3550         DRM_INFO("Get KSV FIFO ready timeout\n");
3551         goto hdmitx_hdcp_Repeater_Fail ;
3552     }
3553     DRM_INFO("Wait timeout = %d\n",timeout);
3554 
3555     it6161_hdmi_tx_clear_ddc_fifo(it6161);
3556     it6161_hdmi_tx_generate_ddc_sclk(it6161);
3557     cDownStream =  (BStatus & M_TX_DOWNSTREAM_COUNT);
3558 
3559     if(/*cDownStream == 0 ||*/ cDownStream > 6 || BStatus & (B_TX_MAX_CASCADE_EXCEEDED|B_TX_DOWNSTREAM_OVER))
3560     {
3561         DRM_INFO("Invalid Down stream count,fail\n");
3562         goto hdmitx_hdcp_Repeater_Fail ;
3563     }
3564 #ifdef SUPPORT_SHA
3565     if(hdmi_tx_hdcp_get_ksv_list(it6161, KSVList,cDownStream) == ER_FAIL)
3566     {
3567         goto hdmitx_hdcp_Repeater_Fail ;
3568     }
3569 #if 0
3570     for(i = 0 ; i < cDownStream ; i++)
3571     {
3572         revoked=false ; uc = 0 ;
3573         for( timeout = 0 ; timeout < 5 ; timeout++ )
3574         {
3575             // check bit count
3576             uc += countbit(KSVList[i*5+timeout]);
3577         }
3578         if( uc != 20 ) revoked = true ;
3579 
3580         if(revoked)
3581         {
3582             DRM_INFO("KSVFIFO[%d] = %02X %02X %02X %02X %02X is revoked\n",i,(int)KSVList[i*5],(int)KSVList[i*5+1],(int)KSVList[i*5+2],(int)KSVList[i*5+3],(int)KSVList[i*5+4]);
3583              goto hdmitx_hdcp_Repeater_Fail ;
3584         }
3585     }
3586 #endif
3587 
3588     if(hdmitx_hdcp_GetVr(it6161, Vr) == ER_FAIL)
3589     {
3590         goto hdmitx_hdcp_Repeater_Fail ;
3591     }
3592     if(hdmitx_hdcp_GetM0(it6161, M0) == ER_FAIL)
3593     {
3594         goto hdmitx_hdcp_Repeater_Fail ;
3595     }
3596     // do check SHA
3597     if(hdmitx_hdcp_CheckSHA(M0,BStatus,KSVList,cDownStream,Vr) == ER_FAIL)
3598     {
3599         goto hdmitx_hdcp_Repeater_Fail ;
3600     }
3601     if((B_TX_INT_HPD_PLUG|B_TX_INT_RX_SENSE)&it6161_hdmi_tx_read(it6161, REG_TX_INT_STAT1))
3602     {
3603         DRM_INFO("HPD at Final\n");
3604         goto hdmitx_hdcp_Repeater_Fail ;
3605     }
3606 #endif // SUPPORT_SHA
3607 
3608     hdmitx_hdcp_ResumeRepeaterAuthenticate(it6161);
3609     hdmiTxDev[0].bAuthenticated = true ;
3610     return ER_SUCCESS ;
3611 
3612 hdmitx_hdcp_Repeater_Fail:
3613     hdmitx_hdcp_CancelRepeaterAuthenticate(it6161);
3614     return ER_FAIL ;
3615 }
3616 #endif
3617 #if 0
3618 static int hdmi_tx_hdcp_get_m0(struct it6161 *it6161, u8 *m0)
3619 {
3620     int ret, i;
3621 
3622 	if(!m0)
3623 		return -ENOMEM;
3624 
3625 	/* read m0[31:0] from reg51~reg54 */
3626 	it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL, 5);
3627 	ret = it6161_hdmi_tx_burst_read(it6161, REG_TX_SHA_RD_BYTE1, m0, 4);
3628 
3629 	if (ret < 0) {
3630 		DRM_INFO("i2c read m0 failed");
3631 		return ret;
3632 	}
3633 
3634 	/* read m0[39 + i * 8 : 32 + i * 8] from reg55 */
3635 	for (i = 0; i < 4; i++) {
3636 		it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL, i);
3637 		m0[4 + i] = it6161_hdmi_tx_read(it6161, REG_TX_AKSV_RD_BYTE5);
3638 	}
3639 
3640 	return ret;
3641 }
3642 #endif
3643 
hdmi_tx_hdcp_get_bcaps(struct it6161 * it6161)3644 static int hdmi_tx_hdcp_get_bcaps(struct it6161 *it6161)
3645 {
3646 	int ret;
3647 
3648 	hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_BCAPS, 0x01, 0x00, CMD_DDC_SEQ_BURSTREAD);
3649 	ret = it6161_ddc_wait(it6161);
3650 
3651 	if (ret < 0) {
3652 		DRM_INFO("ddc get bcaps failed");
3653 		return ret;
3654 	}
3655 
3656 	ret = it6161_hdmi_tx_read(it6161, REG_TX_BCAP);
3657 
3658 	if (ret < 0) {
3659 		DRM_INFO("i2c get bcaps failed");
3660 		return ret;
3661 	}
3662 
3663 	return ret;
3664 }
3665 
hdmi_tx_hdcp_get_bstatus(struct it6161 * it6161)3666 static int hdmi_tx_hdcp_get_bstatus(struct it6161 *it6161)
3667 {
3668 	int ret, bstatus;
3669 
3670 	hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_BSTATUS, 0x02, 0x00, CMD_DDC_SEQ_BURSTREAD);
3671 	ret = it6161_ddc_wait(it6161);
3672 
3673 	if (ret < 0) {
3674 		DRM_INFO("ddc get bstatus failed");
3675 		return ret;
3676 	}
3677 
3678 	ret = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT);
3679 
3680 	if (ret < 0) {
3681 		DRM_INFO("i2c get bstatus failed");
3682 		return ret;
3683 	}
3684 
3685 	bstatus = ret;
3686 
3687 	ret = it6161_hdmi_tx_read(it6161, REG_TX_BSTAT + 1);
3688 
3689 	if (ret < 0) {
3690 		DRM_INFO("i2c get bstatus failed");
3691 		return ret;
3692 	}
3693 
3694 	bstatus |= ret << 8;
3695 
3696 	return bstatus;
3697 }
3698 
3699 #if 0
3700 static void hdmi_tx_hdcp_show_ksv_list(struct it6161 *it6161, u8 *ksvlist)
3701 {
3702 	u8 i;
3703 
3704 	for (i = 0; i < it6161->hdcp_downstream_count; i++, ksvlist += DRM_HDCP_KSV_LEN)
3705 		DRM_INFO("device%d ksv:0x %*ph", i, DRM_HDCP_KSV_LEN, ksvlist);
3706 }
3707 
3708 static int hdmi_tx_hdcp_get_ksv_list1(struct it6161 *it6161, u8 *ksvlist, size_t size)
3709 {
3710 	int i, ret;
3711 
3712 	hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_KSV_FIFO, size, 0x00, CMD_DDC_SEQ_BURSTREAD);
3713 	ret = it6161_ddc_wait(it6161);
3714 
3715 	if (ret < 0) {
3716 		DRM_INFO("ddc get ksv list failed");
3717 		return ret;
3718 	}
3719 
3720 	for (i = 0; i < size; i++) {
3721 		ret = it6161_hdmi_tx_read(it6161, REG_TX_DDC_READFIFO);
3722 
3723 		if (ret < 0) {
3724 			DRM_INFO("i2c get ksv list failed");
3725 			return ret;
3726 		}
3727 
3728 		ksvlist[i] = ret;
3729 	}
3730 
3731 	return 0;
3732 }
3733 
3734 static int hdmi_tx_hdcp_get_v_prime(struct it6161 *it6161, u8 *v_prime, size_t size)
3735 {
3736 	int i, ret;
3737 
3738 	hdmi_tx_ddc_operation(it6161, DDC_HDCP_ADDRESS, DRM_HDCP_DDC_V_PRIME(0), size, 0x00, CMD_DDC_SEQ_BURSTREAD);
3739 	ret = it6161_ddc_wait(it6161);
3740 
3741 	if (ret < 0) {
3742 		DRM_INFO("ddc get v prime failed");
3743 		return ret;
3744 	}
3745 
3746 	for(i = 0 ; i < DRM_HDCP_V_PRIME_NUM_PARTS ; i++) {
3747 		it6161_hdmi_tx_write(it6161, REG_TX_SHA_SEL ,i);
3748 		ret = it6161_hdmi_tx_burst_read(it6161, REG_TX_SHA_RD_BYTE1, v_prime, DRM_HDCP_V_PRIME_PART_LEN);
3749 		if (ret < 0) {
3750 			DRM_INFO("i2c get v prime failed");
3751 			return ret;
3752 		}
3753 
3754 		v_prime += DRM_HDCP_V_PRIME_PART_LEN;
3755 	}
3756 
3757 	return 0;
3758 }
3759 
3760 static int hdmi_tx_setup_sha1_input(struct it6161 *it6161, u8 *ksvlist, u8 *sha1_input)
3761 {
3762 	u8 i, m0[8], msg_count = 0;
3763 
3764 	hdmi_tx_hdcp_get_m0(it6161, m0);
3765 
3766 	for (i = 0; i < it6161->hdcp_downstream_count * DRM_HDCP_KSV_LEN; i++)
3767 		sha1_input[i] = ksvlist[i];
3768 
3769 	msg_count += i;
3770 	sha1_input[msg_count++] = (u8)it6161->bstatus;
3771 	sha1_input[msg_count++] = (u8)(it6161->bstatus >> 8);
3772 	i = 0;
3773 
3774 	while (i < ARRAY_SIZE(m0))
3775 		sha1_input[msg_count++] = m0[i++];
3776 
3777 	return msg_count;
3778 }
3779 
3780 static int it6161_sha1_digest(struct it6161 *it6161, u8 *sha1_input,
3781 			      unsigned int size, u8 *output_av)
3782 {
3783 	struct shash_desc *desc;
3784 	struct crypto_shash *tfm;
3785 	int err;
3786 	struct device *dev = &it6161->i2c_mipi_rx->dev;
3787 
3788 	tfm = crypto_alloc_shash("sha1", 0, 0);
3789 	if (IS_ERR(tfm)) {
3790 		DRM_DEV_ERROR(dev, "crypto_alloc_shash sha1 failed");
3791 		return PTR_ERR(tfm);
3792 	}
3793 	desc = kzalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
3794 	if (!desc) {
3795 		crypto_free_shash(tfm);
3796 		return -ENOMEM;
3797 	}
3798 
3799 	desc->tfm = tfm;
3800 	err = crypto_shash_digest(desc, sha1_input, size, output_av);
3801 	if (err)
3802 		DRM_DEV_ERROR(dev, "crypto_shash_digest sha1 failed");
3803 
3804 	crypto_free_shash(tfm);
3805 	kfree(desc);
3806 	return err;
3807 }
3808 
3809 static bool hdmi_tX_hdcp_compare_sha1_v_prime_v(struct it6161 *it6161, u8 *v_array, u8 *v_prime_array)
3810 {
3811 	int i, j;
3812 
3813 	u8 (*v)[DRM_HDCP_V_PRIME_PART_LEN] = (u8 (*)[DRM_HDCP_V_PRIME_PART_LEN])v_array;
3814 	u8 (*v_prime)[DRM_HDCP_V_PRIME_PART_LEN] = (u8 (*)[DRM_HDCP_V_PRIME_PART_LEN])v_prime_array;
3815 
3816 	for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) {
3817 		for (j = 0; j < DRM_HDCP_V_PRIME_PART_LEN; j++) {
3818 			if (v[i][j] !=
3819 			    v_prime[i][DRM_HDCP_V_PRIME_PART_LEN - 1- j])
3820 				return false;
3821 		}
3822 	}
3823 
3824 	return true;
3825 }
3826 
3827 static void hdmi_tx_hdcp_auth_part2_process(struct work_struct *work)
3828 {
3829 	struct it6161 *it6161 = container_of(work, struct it6161,
3830 					     wait_hdcp_ksv_list);
3831 	int timeout = 5000, ret, i;
3832 	//u8 bcaps, ksvlist[DRM_HDCP_KSV_LEN * it6161->hdcp_downstream_count], *tmp;
3833 	u8 bcaps, ksvlist[DRM_HDCP_KSV_LEN], *tmp;
3834 	u8 v[DRM_HDCP_V_PRIME_NUM_PARTS][DRM_HDCP_V_PRIME_PART_LEN], v_prime[DRM_HDCP_V_PRIME_NUM_PARTS][DRM_HDCP_V_PRIME_PART_LEN];
3835 
3836 	while (timeout > 0) {
3837 		if (!hdmi_tx_get_sink_hpd(it6161))
3838 			return;
3839 
3840 		ret = hdmi_tx_hdcp_get_bcaps(it6161);
3841 
3842 		if (ret < 0)
3843 			return;
3844 
3845 		bcaps = ret;
3846 		if (!!(bcaps & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY)) {
3847 			DRM_INFO("ksv list fifo ready");
3848 			break;
3849 		}
3850 		usleep_range(1000, 2000);
3851 	}
3852 
3853 	if (timeout <= 0) {
3854 		DRM_INFO("wait ksv list ready timeout");
3855 		return;
3856 	}
3857 
3858 	ret = hdmi_tx_hdcp_get_ksv_list1(it6161, ksvlist, ARRAY_SIZE(ksvlist));
3859 
3860 	if (ret != 0)
3861 		return;
3862 
3863 	hdmi_tx_hdcp_show_ksv_list(it6161, ksvlist);
3864 	ret = hdmi_tx_setup_sha1_input(it6161, ksvlist, it6161->sha1_transform_input);
3865 	DRM_INFO("sha1 msg_count :%d \nsha1_input:0x %*ph", ret, ret, it6161->sha1_transform_input);
3866 	ret = it6161_sha1_digest(it6161, it6161->sha1_transform_input, ret, (u8 *)v);
3867 	if (ret != 0)
3868 		return;
3869 
3870 	tmp = (u8 *)v;
3871 	for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++, tmp += DRM_HDCP_V_PRIME_PART_LEN)
3872 		DRM_INFO("v:0x %*ph", DRM_HDCP_V_PRIME_PART_LEN, tmp);
3873 
3874 	ret = hdmi_tx_hdcp_get_v_prime(it6161, (u8 *)v_prime, sizeof(v_prime));
3875 
3876 	if (ret != 0)
3877 		return;
3878 
3879 	tmp = (u8 *)v_prime;
3880 	for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++, tmp += DRM_HDCP_V_PRIME_PART_LEN)
3881 		DRM_INFO("v_prime:0x %*ph", DRM_HDCP_V_PRIME_PART_LEN, tmp);
3882 
3883 	ret = hdmi_tX_hdcp_compare_sha1_v_prime_v(it6161, (u8 *)v, (u8 *)v_prime);
3884 	DRM_INFO("sha1 check result: %s", ret ? "pass" : "failed");
3885 
3886 	if (ret) {
3887 		it6161_hdmi_tx_set_bits(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE , B_TX_LISTDONE);
3888 	} else {
3889 		it6161_hdmi_tx_set_bits(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE | B_TX_LISTFAIL, B_TX_LISTDONE | B_TX_LISTFAIL);
3890 	}
3891 	it6161_hdmi_tx_set_bits(it6161, REG_TX_LISTCTRL, B_TX_LISTDONE | B_TX_LISTFAIL, 0x00);
3892 }
3893 #endif
3894 
hdmi_tx_hdcp_enable_auth_part1(struct it6161 * it6161)3895 static bool hdmi_tx_hdcp_enable_auth_part1(struct it6161 *it6161)
3896 {
3897 	int ret;
3898 	u8 i, count = 0;
3899 
3900 	ret = hdmi_tx_hdcp_get_bksv(it6161, it6161->bksv, (int)ARRAY_SIZE(it6161->bksv));
3901 	if (ret < 0)
3902 		return hdmiTxDev[0].bAuthenticated;
3903 	DRM_INFO("bksv: 0x %*ph", (int)ARRAY_SIZE(it6161->bksv), it6161->bksv);
3904 
3905 	for (i = 0; i < ARRAY_SIZE(it6161->bksv); i++)
3906 		count += countbit(it6161->bksv[i]);
3907 
3908 	if (count != 20) {
3909 		DRM_INFO("not a valid bksv");
3910 		return hdmiTxDev[0].bAuthenticated;
3911 	}
3912 
3913 	if ((it6161->bksv[4] == 0x93) &&
3914 		(it6161->bksv[3] == 0x43) &&
3915 		(it6161->bksv[2] == 0x5C) &&
3916 		(it6161->bksv[1] == 0xDE) &&
3917 		(it6161->bksv[0] == 0x23)) {
3918 		DRM_INFO("Revoked bksv");
3919 		return hdmiTxDev[0].bAuthenticated ;
3920 	}
3921 
3922 	it6161_hdmi_tx_write(it6161, REG_TX_HDCP_DESIRE, 0x08 | B_TX_CPDESIRE);
3923 	hdmi_tx_hdcp_generate_an(it6161);
3924 	hdmi_tx_hdcp_auth_fire(it6161);
3925 
3926 	return true;
3927 }
3928 
hdmi_tx_hdcp_auth_process(struct it6161 * it6161)3929 static bool hdmi_tx_hdcp_auth_process(struct it6161 *it6161)
3930 {
3931 	u8 bcaps;
3932 	u16 i, retry = 3;
3933 	int ret;
3934 
3935 	/* Authenticate should be called after AFE setup up */
3936 
3937 	DRM_INFO("start");
3938 	hdmiTxDev[0].bAuthenticated = false ;
3939 	it6161->hdmi_tx_hdcp_retry--;
3940 	hdmi_tx_hdcp_reset_auth(it6161);
3941 	it6161_hdmi_tx_change_bank(it6161, 0);
3942 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_TX_HDCP_RST_HDMITX, 0x00);
3943 	it6161_hdmi_tx_write(it6161, REG_TX_LISTCTRL, 0x00);
3944 	it6161_hdmi_tx_clear_ddc_fifo(it6161);
3945 	hdmi_tx_hdcp_int_mask_enable(it6161);
3946 
3947 	for (i = 0; i < retry; i++) {
3948 		ret = hdmi_tx_hdcp_get_bstatus(it6161);
3949 		if(ret < 0)
3950 			continue;
3951 		it6161->bstatus = (u16)ret;
3952 
3953 		ret = hdmi_tx_hdcp_get_bcaps(it6161);
3954 		if (ret < 0)
3955 			continue;
3956 		bcaps = ret;
3957 		break;
3958 	}
3959 
3960 	if (i == retry)
3961 		return hdmiTxDev[0].bAuthenticated;
3962 
3963 	DRM_INFO("bcaps: 0x%02x, bstatus: 0x%04x, hdmi_mode: %d", bcaps, it6161->bstatus,
3964 		 it6161->bstatus & B_TX_CAP_HDMI_MODE);
3965 	it6161->is_repeater = !!(bcaps & DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT);
3966 	DRM_INFO("downstream is hdcp %s", it6161->is_repeater ? "repeater" : "receiver");
3967 	if (it6161->is_repeater) {
3968 		it6161->hdcp_downstream_count = (u8)DRM_HDCP_NUM_DOWNSTREAM(it6161->bstatus);
3969 		DRM_INFO("down stream Count %d", it6161->hdcp_downstream_count);
3970 		if (it6161->hdcp_downstream_count > 6) {
3971 			DRM_INFO("over maximum supported number 6");
3972 			return hdmiTxDev[0].bAuthenticated;
3973 		}
3974 	}
3975 
3976 	ret = hdmi_tx_hdcp_enable_auth_part1(it6161);
3977 
3978 	if (!ret)
3979 		return ret;
3980 
3981 	if (!it6161->is_repeater) {
3982 		ret = wait_for_completion_timeout(&it6161->wait_hdcp_event, msecs_to_jiffies(1000));
3983 		DRM_INFO("completion:%d", ret);
3984 		if (ret == 0)
3985 			DRM_INFO("hdcp-receiver: timeout");
3986 
3987 		return hdmiTxDev[0].bAuthenticated;
3988 	}
3989 	return hdmiTxDev[0].bAuthenticated;
3990 }
3991 #endif
3992 
hdmitx_hdcp_ResumeAuthentication(struct it6161 * it6161)3993 static void hdmitx_hdcp_ResumeAuthentication(struct it6161 *it6161)
3994 {
3995     it6161_hdmi_tx_set_av_mute(it6161, true);
3996     if(hdmi_tx_hdcp_auth_process(it6161) == ER_SUCCESS)
3997     {
3998     }
3999     it6161_hdmi_tx_set_av_mute(it6161, false);
4000 }
4001 
hdmi_tx_hdcp_work(struct work_struct * work)4002 static void hdmi_tx_hdcp_work(struct work_struct *work)
4003 {
4004 	struct it6161 *it6161 = container_of(work, struct it6161,
4005 					     hdcp_work.work);
4006 	//struct device *dev = &it6161->i2c_hdmi_tx->dev;
4007 	bool ret, sink_hpd = hdmi_tx_get_sink_hpd(it6161), video_state = hdmi_tx_get_video_state(it6161);
4008 
4009 	if (it6161->hdmi_tx_hdcp_retry <= 0 || !sink_hpd || !video_state) {
4010 		DRM_INFO("hdcp_retry:%d sink_hpd:%d video_stable_state:%d", it6161->hdmi_tx_hdcp_retry, sink_hpd, video_state);
4011 		return;
4012 	}
4013 
4014 	ret = hdmi_tx_hdcp_auth_process(it6161);
4015 	if (it6161->is_repeater) {
4016 		DRM_INFO("is repeater and wait for ksv list interrupt");
4017 		return;
4018 	}
4019 
4020 	DRM_INFO("hdcp_auth_process %s", ret ? "pass" : "failed");
4021 }
4022 
hdmi_tx_enable_hdcp(struct it6161 * it6161)4023 static void hdmi_tx_enable_hdcp(struct it6161 *it6161)
4024 {
4025 	struct device *dev = &it6161->i2c_hdmi_tx->dev;
4026 
4027 	DRM_DEV_DEBUG_DRIVER(dev, "start");
4028 	queue_delayed_work(system_wq, &it6161->hdcp_work,
4029 			   msecs_to_jiffies(500));
4030 }
4031 #endif
4032 
getHDMITX_LinkStatus()4033 static bool getHDMITX_LinkStatus()
4034 {
4035 it6161_debug("%s reg0E:0x%02x reg0x61:0x%02x", __func__, it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS), it6161_hdmi_tx_read(it6161, REG_TX_AFE_DRV_CTRL));//allen
4036     if(B_TX_RXSENDETECT & it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)) {
4037         if(0==it6161_hdmi_tx_read(it6161, REG_TX_AFE_DRV_CTRL))
4038         {
4039             //DRM_INFO("getHDMITX_LinkStatus()!!\n");
4040             return true;
4041         }
4042     }
4043     DRM_INFO("GetTMDS not Ready()!!\n");
4044 
4045     return false;
4046 }
4047 
4048 // static void HDMITX_PowerDown()
4049 // {
4050 //     it6161_hdmi_tx_write_table(it6161, HDMITX_PwrDown_Table, ARRAY_SIZE(HDMITX_PwrDown_Table));
4051 // }
4052 
hdmi_tx_setup_pclk_div2(struct it6161 * it6161)4053 static void hdmi_tx_setup_pclk_div2(struct it6161 *it6161)
4054 {
4055 	if (HDMI_TX_PCLK_DIV2) {
4056 		DRM_INFO("PCLK Divided by 2 mode");
4057 		it6161_hdmi_tx_set_bits(it6161, REG_TX_INPUT_MODE, B_TX_PCLKDIV2, B_TX_PCLKDIV2);
4058     }
4059 }
4060 
4061 //////////////////////////////////////////////////////////////////////
4062 // Function: hdmi_tx_setup_csc
4063 // Parameter: input_mode -
4064 //             D[1:0] - Color Mode
4065 //             D[4] - Colorimetry 0: ITU_BT601 1: ITU_BT709
4066 //             D[5] - Quantization 0: 0_255 1: 16_235
4067 //             D[6] - Up/Dn Filter 'Required'
4068 //                    0: no up/down filter
4069 //                    1: enable up/down filter when csc need.
4070 //             D[7] - Dither Filter 'Required'
4071 //                    0: no dither enabled.
4072 //                    1: enable dither and dither free go "when required".
4073 //            output_mode -
4074 //             D[1:0] - Color mode.
4075 // Return: N/A
4076 // Remark: reg72~reg8D will be programmed depended the input with table.
4077 // Side-Effect:
4078 //////////////////////////////////////////////////////////////////////
4079 
hdmi_tx_setup_csc(struct it6161 * it6161)4080 static void hdmi_tx_setup_csc(struct it6161 *it6161)
4081 {
4082     u8 ucData, csc = 0, i, filter = 0; // filter is for Video CTRL DN_FREE_GO,EN_DITHER,and ENUDFILT
4083     u8 input_mode = it6161->hdmi_tx_input_color_space;
4084     u8 output_mode = it6161->hdmi_tx_output_color_space;
4085 
4086     // (1) YUV422 in,RGB/YUV444 output (Output is 8-bit,input is 12-bit)
4087     // (2) YUV444/422  in,RGB output (CSC enable,and output is not YUV422)
4088     // (3) RGB in,YUV444 output   (CSC enable,and output is not YUV422)
4089     //
4090     // YUV444/RGB24 <-> YUV422 need set up/down filter.
4091     DRM_INFO("hdmi_tx_setup_csc(u8 input_mode = %x,u8 output_mode = %x)\n", (int)input_mode, (int)output_mode);
4092     switch(input_mode&F_MODE_CLRMOD_MASK)
4093     {
4094     #ifdef SUPPORT_INPUTYUV444
4095     case F_MODE_YUV444:
4096         DRM_INFO("Input mode is YUV444 ");
4097         switch(output_mode&F_MODE_CLRMOD_MASK)
4098         {
4099         case F_MODE_YUV444:
4100             DRM_INFO("Output mode is YUV444\n");
4101             csc = B_HDMITX_CSC_BYPASS ;
4102             break ;
4103 
4104         case F_MODE_YUV422:
4105             DRM_INFO("Output mode is YUV422\n");
4106             if(input_mode & F_VIDMODE_EN_UDFILT) // YUV444 to YUV422 need up/down filter for processing.
4107             {
4108                 filter |= B_TX_EN_UDFILTER ;
4109             }
4110             csc = B_HDMITX_CSC_BYPASS ;
4111             break ;
4112         case F_MODE_RGB444:
4113             DRM_INFO("Output mode is RGB24\n");
4114             csc = B_HDMITX_CSC_YUV2RGB ;
4115             if(input_mode & F_VIDMODE_EN_DITHER) // YUV444 to RGB24 need dither
4116             {
4117                 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4118             }
4119             break ;
4120         }
4121         break ;
4122     #endif
4123 
4124     #ifdef SUPPORT_INPUTYUV422
4125     case F_MODE_YUV422:
4126         DRM_INFO("Input mode is YUV422\n");
4127         switch(output_mode&F_MODE_CLRMOD_MASK)
4128         {
4129         case F_MODE_YUV444:
4130             DRM_INFO("Output mode is YUV444\n");
4131             csc = B_HDMITX_CSC_BYPASS ;
4132             if(input_mode & F_VIDMODE_EN_UDFILT) // YUV422 to YUV444 need up filter
4133             {
4134                 filter |= B_TX_EN_UDFILTER ;
4135             }
4136             if(input_mode & F_VIDMODE_EN_DITHER) // YUV422 to YUV444 need dither
4137             {
4138                 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4139             }
4140             break ;
4141         case F_MODE_YUV422:
4142             DRM_INFO("Output mode is YUV422\n");
4143             csc = B_HDMITX_CSC_BYPASS ;
4144 
4145             break ;
4146 
4147         case F_MODE_RGB444:
4148             DRM_INFO("Output mode is RGB24\n");
4149             csc = B_HDMITX_CSC_YUV2RGB ;
4150             if(input_mode & F_VIDMODE_EN_UDFILT) // YUV422 to RGB24 need up/dn filter.
4151             {
4152                 filter |= B_TX_EN_UDFILTER ;
4153             }
4154             if(input_mode & F_VIDMODE_EN_DITHER) // YUV422 to RGB24 need dither
4155             {
4156                 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4157             }
4158             break ;
4159         }
4160         break ;
4161     #endif
4162 
4163     #ifdef SUPPORT_INPUTRGB
4164     case F_MODE_RGB444:
4165         DRM_INFO("Input mode is RGB24\n");
4166         switch(output_mode&F_MODE_CLRMOD_MASK)
4167         {
4168         case F_MODE_YUV444:
4169             DRM_INFO("Output mode is YUV444\n");
4170             csc = B_HDMITX_CSC_RGB2YUV ;
4171 
4172             if(input_mode & F_VIDMODE_EN_DITHER) // RGB24 to YUV444 need dither
4173             {
4174                 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4175             }
4176             break ;
4177 
4178         case F_MODE_YUV422:
4179             DRM_INFO("Output mode is YUV422\n");
4180             if(input_mode & F_VIDMODE_EN_UDFILT) // RGB24 to YUV422 need down filter.
4181             {
4182                 filter |= B_TX_EN_UDFILTER ;
4183             }
4184             if(input_mode & F_VIDMODE_EN_DITHER) // RGB24 to YUV422 need dither
4185             {
4186                 filter |= B_TX_EN_DITHER | B_TX_DNFREE_GO ;
4187             }
4188             csc = B_HDMITX_CSC_RGB2YUV ;
4189             break ;
4190 
4191         case F_MODE_RGB444:
4192             DRM_INFO("Output mode is RGB24\n");
4193             csc = B_HDMITX_CSC_BYPASS ;
4194             break ;
4195         }
4196         break ;
4197     #endif
4198     }
4199 #ifndef DISABLE_HDMITX_CSC
4200 
4201     #ifdef SUPPORT_INPUTRGB
4202     // set the CSC metrix registers by colorimetry and quantization
4203     if(csc == B_HDMITX_CSC_RGB2YUV)
4204     {
4205         DRM_INFO("CSC = RGB2YUV %x ",csc);
4206         switch(input_mode&(F_VIDMODE_ITU709|F_VIDMODE_16_235))
4207         {
4208         case F_VIDMODE_ITU709|F_VIDMODE_16_235:
4209             DRM_INFO("ITU709 16-235 ");
4210             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_16_235[i]);}
4211             break ;
4212         case F_VIDMODE_ITU709|F_VIDMODE_0_255:
4213             DRM_INFO("ITU709 0-255 ");
4214             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU709_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU709_0_255[i]);}
4215             break ;
4216         case F_VIDMODE_ITU601|F_VIDMODE_16_235:
4217             DRM_INFO("ITU601 16-235 ");
4218             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_16_235[i]);}
4219             break ;
4220         case F_VIDMODE_ITU601|F_VIDMODE_0_255:
4221         default:
4222             DRM_INFO("ITU601 0-255 ");
4223             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_RGB2YUV_ITU601_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_RGB2YUV_ITU601_0_255[i]);}
4224             break ;
4225         }
4226     }
4227     #endif
4228 
4229     #ifdef SUPPORT_INPUTYUV
4230     if (csc == B_HDMITX_CSC_YUV2RGB)
4231     {
4232         DRM_INFO("CSC = YUV2RGB %x ",csc);
4233 
4234         switch(input_mode&(F_VIDMODE_ITU709|F_VIDMODE_16_235))
4235         {
4236         case F_VIDMODE_ITU709|F_VIDMODE_16_235:
4237             DRM_INFO("ITU709 16-235 ");
4238             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_16_235[i]);}
4239             break ;
4240         case F_VIDMODE_ITU709|F_VIDMODE_0_255:
4241             DRM_INFO("ITU709 0-255 ");
4242             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU709_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU709_0_255[i]);}
4243             break ;
4244         case F_VIDMODE_ITU601|F_VIDMODE_16_235:
4245             DRM_INFO("ITU601 16-235 ");
4246             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_16_235[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_16_235[i]);}
4247             break ;
4248         case F_VIDMODE_ITU601|F_VIDMODE_0_255:
4249         default:
4250             DRM_INFO("ITU601 0-255 ");
4251             for( i = 0 ; i < SIZEOF_CSCMTX ; i++ ){ it6161_hdmi_tx_write(it6161, REG_TX_CSC_YOFF+i,bCSCMtx_YUV2RGB_ITU601_0_255[i]) ; DRM_INFO("reg%02X <- %02X\n",(int)(i+REG_TX_CSC_YOFF),(int)bCSCMtx_YUV2RGB_ITU601_0_255[i]);}
4252             break ;
4253         }
4254     }
4255     #endif
4256 #else// DISABLE_HDMITX_CSC
4257     csc = B_HDMITX_CSC_BYPASS ;
4258 #endif// DISABLE_HDMITX_CSC
4259 
4260     if( csc == B_HDMITX_CSC_BYPASS )
4261     {
4262         it6161_hdmi_tx_set_bits(it6161, 0xF, 0x10, 0x10);
4263     }
4264     else
4265     {
4266         it6161_hdmi_tx_set_bits(it6161, 0xF, 0x10, 0x00);
4267     }
4268     ucData = it6161_hdmi_tx_read(it6161, REG_TX_CSC_CTRL) & ~(M_TX_CSC_SEL|B_TX_DNFREE_GO|B_TX_EN_DITHER|B_TX_EN_UDFILTER);
4269     ucData |= filter|csc ;
4270 
4271     it6161_hdmi_tx_write(it6161, REG_TX_CSC_CTRL,ucData);
4272 }
4273 
4274 // Parameter: VIDEOPCLKLEVEL level
4275 //            PCLK_LOW - for 13.5MHz (for mode less than 1080p)
4276 //            PCLK MEDIUM - for 25MHz~74MHz
4277 //            PCLK HIGH - PCLK > 80Hz (for 1080p mode or above)
4278 // Remark: set reg62~reg65 depended on HighFreqMode
4279 //         reg61 have to be programmed at last and after video stable input.
4280 
hdmi_tx_setup_afe(struct it6161 * it6161,VIDEOPCLKLEVEL level)4281 static void hdmi_tx_setup_afe(struct it6161 *it6161, VIDEOPCLKLEVEL level)
4282 {
4283 
4284     it6161_hdmi_tx_write(it6161, REG_TX_AFE_DRV_CTRL, B_TX_AFE_DRV_RST);
4285     switch(level)
4286     {
4287         case PCLK_HIGH:
4288             it6161_hdmi_tx_set_bits(it6161, 0x62, 0x90, 0x80);
4289             it6161_hdmi_tx_set_bits(it6161, 0x64, 0x89, 0x80);
4290             it6161_hdmi_tx_set_bits(it6161, 0x68, 0x10, 0x00);
4291             it6161_hdmi_tx_set_bits(it6161, 0x66, 0x80, 0x80);//hdmitxset(0x66, 0x80, 0x80);// mark fix 6017
4292             break ;
4293         default:
4294             it6161_hdmi_tx_set_bits(it6161, 0x62, 0x90, 0x10);
4295             it6161_hdmi_tx_set_bits(it6161, 0x64, 0x89, 0x09);
4296             it6161_hdmi_tx_set_bits(it6161, 0x68, 0x10, 0x10);
4297             break ;
4298     }
4299 	DRM_INFO("setup afe: %s", level ? "high" : "low");
4300 #ifdef REDUCE_HDMITX_SRC_JITTER
4301     //it6161_hdmi_tx_set_bits(it6161, 0x64, 0x01, 0x00); //pet: TODO need check
4302     // it6161_hdmi_tx_set_bits(it6161, 0x6A, 0xFF, 0xFF);
4303 
4304     // 2019/02/15 modified by jjtseng,
4305     // Dr. Liu:
4306     // it6161 �b�� Solomon mipi TX (�Ψ�Ljitter �ܤj��source��), �Х[�H�U�]�w
4307     // reg[6A]=0x5D
4308     // Note: Register 6A  is REG_XP_TEST[7:0], its eye and jitter CTS report please see attached file
4309     //
4310     // it6161 �b�� ite mipi TX (�Ψ�Ljitter OK��source��), keep
4311     // [6A]=0x00 (default setting)
4312 
4313     it6161_hdmi_tx_set_bits(it6161, 0x6A, 0xFF, 0x5D);
4314 #endif
4315 }
4316 
4317 // Remark: write reg61 with 0x04
4318 //         When program reg61 with 0x04,then audio and video circuit work.
4319 
hdmi_tx_fire_afe(struct it6161 * it6161)4320 static void hdmi_tx_fire_afe(struct it6161 *it6161)
4321 {
4322     it6161_hdmi_tx_change_bank(it6161, 0x00);
4323     it6161_hdmi_tx_write(it6161, REG_TX_AFE_DRV_CTRL, 0x00);
4324 }
4325 
4326 //////////////////////////////////////////////////////////////////////
4327 // utility function for main..
4328 //////////////////////////////////////////////////////////////////////
4329 
4330 // #ifndef DISABLE_HDMITX_CSC
4331 //     #if (defined (SUPPORT_OUTPUTYUV)) && (defined (SUPPORT_INPUTRGB))
4332 //         extern const u8 bCSCMtx_RGB2YUV_ITU601_16_235[] ;
4333 //         extern const u8 bCSCMtx_RGB2YUV_ITU601_0_255[] ;
4334 //         extern const u8 bCSCMtx_RGB2YUV_ITU709_16_235[] ;
4335 //         extern const u8 bCSCMtx_RGB2YUV_ITU709_0_255[] ;
4336 //     #endif
4337 
4338 //     #if (defined (SUPPORT_OUTPUTRGB)) && (defined (SUPPORT_INPUTYUV))
4339 //         extern const u8 bCSCMtx_YUV2RGB_ITU601_16_235[] ;
4340 //         extern const u8 bCSCMtx_YUV2RGB_ITU601_0_255[] ;
4341 //         extern const u8 bCSCMtx_YUV2RGB_ITU709_16_235[] ;
4342 //         extern const u8 bCSCMtx_YUV2RGB_ITU709_0_255[] ;
4343 
4344 //     #endif
4345 // #endif// DISABLE_HDMITX_CSC
4346 
4347 
hdmi_tx_disable_video_output(struct it6161 * it6161)4348 static void hdmi_tx_disable_video_output(struct it6161 *it6161)
4349 {
4350 	it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_VID_RST, B_HDMITX_VID_RST);
4351 	it6161_hdmi_tx_write(it6161, REG_TX_AFE_DRV_CTRL,B_TX_AFE_DRV_RST|B_TX_AFE_DRV_PWD);
4352 	it6161_hdmi_tx_set_bits(it6161, 0x62, 0x90, 0x00);
4353 	it6161_hdmi_tx_set_bits(it6161, 0x64, 0x89, 0x00);
4354 }
4355 
hdmi_tx_enable_video_output(struct it6161 * it6161,VIDEOPCLKLEVEL level)4356 static void hdmi_tx_enable_video_output(struct it6161 *it6161, VIDEOPCLKLEVEL level)
4357 {
4358 	it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST | B_TX_AREF_RST | B_TX_HDCP_RST_HDMITX);
4359 	it6161_hdmi_tx_change_bank(it6161, 1);
4360 	it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB1, 0x00);
4361 	it6161_hdmi_tx_change_bank(it6161, 0);
4362 
4363 	if(it6161->hdmi_mode)
4364 		it6161_hdmi_tx_set_av_mute(it6161, true);
4365 
4366 	hdmi_tx_setup_pclk_div2(it6161);
4367 	hdmi_tx_setup_csc(it6161);
4368 	it6161_hdmi_tx_write(it6161, REG_TX_HDMI_MODE, it6161->hdmi_mode ? B_TX_HDMI_MODE : B_TX_DVI_MODE);
4369 	hdmi_tx_setup_afe(it6161, level);
4370 	hdmi_tx_fire_afe(it6161);
4371 }
4372 
4373 static u8 AudioDelayCnt=0;
4374 static u8 LastRefaudfreqnum=0;
4375 static bool bForceCTS = false;
4376 
setHDMITX_ChStat(struct it6161 * it6161,u8 ucIEC60958ChStat[])4377 static void setHDMITX_ChStat(struct it6161 *it6161, u8 ucIEC60958ChStat[])
4378 {
4379     u8 uc ;
4380 
4381     it6161_hdmi_tx_change_bank(it6161, 1);
4382     uc = (ucIEC60958ChStat[0] <<1)& 0x7C ;
4383     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_MODE,uc);
4384     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CAT,ucIEC60958ChStat[1]); // 192, audio CATEGORY
4385     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_SRCNUM,ucIEC60958ChStat[2]&0xF);
4386     it6161_hdmi_tx_write(it6161, REG_TX_AUD0CHST_CHTNUM,(ucIEC60958ChStat[2]>>4)&0xF);
4387     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CA_FS,ucIEC60958ChStat[3]); // choose clock
4388     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_OFS_WL,ucIEC60958ChStat[4]);
4389     it6161_hdmi_tx_change_bank(it6161, 0);
4390 }
4391 /*
4392 void setHDMITX_UpdateChStatFs(u32 Fs)
4393 {
4394     u8 uc ;
4395 
4396     /////////////////////////////////////
4397     // Fs should be the following value.
4398     // #define AUDFS_22p05KHz  4
4399     // #define AUDFS_44p1KHz 0
4400     // #define AUDFS_88p2KHz 8
4401     // #define AUDFS_176p4KHz    12
4402     //
4403     // #define AUDFS_24KHz  6
4404     // #define AUDFS_48KHz  2
4405     // #define AUDFS_96KHz  10
4406     // #define AUDFS_192KHz 14
4407     //
4408     // #define AUDFS_768KHz 9
4409     //
4410     // #define AUDFS_32KHz  3
4411     // #define AUDFS_OTHER    1
4412     /////////////////////////////////////
4413 
4414     it6161_hdmi_tx_change_bank(it6161, 1);
4415     uc = it6161_hdmi_tx_read(it6161, REG_TX_AUDCHST_CA_FS); // choose clock
4416     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CA_FS,uc); // choose clock
4417     uc &= 0xF0 ;
4418     uc |= (Fs&0xF);
4419 
4420     uc = it6161_hdmi_tx_read(it6161, REG_TX_AUDCHST_OFS_WL);
4421     uc &= 0xF ;
4422     uc |= ((~Fs) << 4)&0xF0 ;
4423     it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_OFS_WL,uc);
4424 
4425     it6161_hdmi_tx_change_bank(it6161, 0);
4426 }
4427 */
setHDMITX_LPCMAudio(u8 AudioSrcNum,u8 AudSWL,u8 bAudInterface)4428 static void setHDMITX_LPCMAudio(u8 AudioSrcNum, u8 AudSWL, u8 bAudInterface /*I2S/SPDIF/TDM*/)
4429 {
4430 
4431     u8 AudioEnable, AudioFormat ;
4432     u8 bTDMSetting ;
4433     AudioEnable = 0 ;
4434     AudioFormat = hdmiTxDev[0].bOutputAudioMode ;
4435 
4436     switch(AudSWL)
4437     {
4438     case 16:
4439         AudioEnable |= M_TX_AUD_16BIT ;
4440         break ;
4441     case 18:
4442         AudioEnable |= M_TX_AUD_18BIT ;
4443         break ;
4444     case 20:
4445         AudioEnable |= M_TX_AUD_20BIT ;
4446         break ;
4447     case 24:
4448     default:
4449         AudioEnable |= M_TX_AUD_24BIT ;
4450         break ;
4451     }
4452     if( bAudInterface == SPDIF )
4453     {
4454         AudioFormat &= ~0x40 ;
4455         AudioEnable |= B_TX_AUD_SPDIF|B_TX_AUD_EN_I2S0 ;
4456     }
4457     else
4458     {
4459         AudioFormat |= 0x40 ;
4460         switch(AudioSrcNum)
4461         {
4462         case 4:
4463             AudioEnable |= B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ;
4464             break ;
4465 
4466         case 3:
4467             AudioEnable |= B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ;
4468             break ;
4469 
4470         case 2:
4471             AudioEnable |= B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0 ;
4472             break ;
4473 
4474         case 1:
4475         default:
4476             AudioFormat &= ~0x40 ;
4477             AudioEnable |= B_TX_AUD_EN_I2S0 ;
4478             break ;
4479 
4480         }
4481     }
4482     AudioFormat|=0x01;//mingchih add
4483     hdmiTxDev[0].bAudioChannelEnable=AudioEnable;
4484 
4485     it6161_hdmi_tx_change_bank(it6161, 0);
4486     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0,AudioEnable&0xF0);
4487 
4488     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,AudioFormat); // regE1 bOutputAudioMode should be loaded from ROM image.
4489 #ifdef USE_IT66120
4490     it6161_hdmi_tx_set_bits(it6161, 0x5A,0x02, 0x00);
4491     if( bAudInterface == SPDIF )
4492     {
4493         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4494     }
4495     else
4496     {
4497         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xFF); // default mapping.
4498     }
4499 #else
4500     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4501 #endif
4502 
4503 #ifdef USE_SPDIF_CHSTAT
4504     if( bAudInterface == SPDIF )
4505     {
4506         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL);
4507     }
4508     else
4509     {
4510         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4511     }
4512 #else // not USE_SPDIF_CHSTAT
4513     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4514 #endif // USE_SPDIF_CHSTAT
4515 
4516     it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x00);
4517     it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ;
4518 
4519     if( bAudInterface == SPDIF )
4520     {
4521         u8 i ;
4522         it6161_hdmi_tx_set_bits(it6161, 0x5c,(1<<6), (1<<6));
4523         for( i = 0 ; i < 100 ; i++ )
4524         {
4525             if(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK)
4526             {
4527                 break ; // stable clock.
4528             }
4529         }
4530     }
4531     else
4532     {
4533         bTDMSetting = it6161_hdmi_tx_read(it6161, REG_TX_AUD_HDAUDIO) ;
4534         if( bAudInterface == TDM )
4535         {
4536             bTDMSetting |= B_TX_TDM ;
4537             bTDMSetting &= 0x9F ;
4538             bTDMSetting |= (AudioSrcNum-1)<< 5;
4539         }
4540         else
4541         {
4542             bTDMSetting &= ~B_TX_TDM ;
4543         }
4544         it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO, bTDMSetting) ; // 2 channel NLPCM, no TDM mode.
4545     }
4546 }
4547 
setHDMITX_NLPCMAudio(u8 bAudInterface)4548 static void setHDMITX_NLPCMAudio(u8 bAudInterface /*I2S/SPDIF/TDM*/) // no Source Num, no I2S.
4549 {
4550     u8 AudioEnable, AudioFormat ;
4551     u8 i ;
4552 
4553     AudioFormat = 0x01 ; // NLPCM must use standard I2S mode.
4554     if( bAudInterface == SPDIF )
4555     {
4556         AudioEnable = M_TX_AUD_24BIT|B_TX_AUD_SPDIF;
4557     }
4558     else
4559     {
4560         AudioEnable = M_TX_AUD_24BIT;
4561     }
4562 
4563     it6161_hdmi_tx_change_bank(it6161, 0);
4564     // it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF);
4565     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, AudioEnable);
4566     //it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST|B_TX_AREF_RST, 0x00);
4567 
4568     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,0x01); // regE1 bOutputAudioMode should be loaded from ROM image.
4569 #ifdef USE_IT66120
4570     if( bAudInterface == SPDIF )
4571     {
4572         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4573     }
4574     else
4575     {
4576         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xFF); // default mapping.
4577     }
4578 #else
4579     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4580 #endif
4581 
4582 #ifdef USE_SPDIF_CHSTAT
4583     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL);
4584 #else // not USE_SPDIF_CHSTAT
4585     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4586 #endif // USE_SPDIF_CHSTAT
4587 
4588     it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x00);
4589     it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,0x00); // regE5 = 0 ;
4590 
4591     if( bAudInterface == SPDIF )
4592     {
4593         for( i = 0 ; i < 100 ; i++ )
4594         {
4595             if(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK)
4596             {
4597                 break ; // stable clock.
4598             }
4599         }
4600     }
4601     else
4602     {
4603         i = it6161_hdmi_tx_read(it6161, REG_TX_AUD_HDAUDIO) ;
4604         i &= ~B_TX_TDM ;
4605         it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO, i) ; // 2 channel NLPCM, no TDM mode.
4606     }
4607     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, AudioEnable|B_TX_AUD_EN_I2S0);
4608 }
4609 
setHDMITX_HBRAudio(u8 bAudInterface)4610 static void setHDMITX_HBRAudio(u8 bAudInterface /*I2S/SPDIF/TDM*/)
4611 {
4612     // u8 rst;
4613     it6161_hdmi_tx_change_bank(it6161, 0);
4614 
4615     // rst = it6161_hdmi_tx_read(it6161, REG_TX_SW_RST);
4616 	// rst &= ~(B_HDMITX_AUD_RST|B_TX_AREF_RST);
4617 
4618     // it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst | B_HDMITX_AUD_RST );
4619 
4620     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,0x47); // regE1 bOutputAudioMode should be loaded from ROM image.
4621 #ifdef USE_IT66120
4622     if( bAudInterface == SPDIF )
4623     {
4624         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4625     }
4626     else
4627     {
4628         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xFF); // default mapping.
4629     }
4630 #else
4631     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4632 #endif
4633 
4634     if( bAudInterface == SPDIF )
4635     {
4636         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF);
4637         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,B_TX_CHSTSEL);
4638     }
4639     else
4640     {
4641         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT);
4642         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4643     }
4644     it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x08);
4645     it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,B_TX_HBR); // regE5 = 0 ;
4646 
4647     //uc = it6161_hdmi_tx_read(it6161, REG_TX_CLK_CTRL1);
4648     //uc &= ~M_TX_AUD_DIV ;
4649     //it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL1, uc);
4650 
4651     if( bAudInterface == SPDIF )
4652     {
4653         u8 i ;
4654         for( i = 0 ; i < 100 ; i++ )
4655         {
4656             if(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2) & B_TX_OSF_LOCK)
4657             {
4658                 break ; // stable clock.
4659             }
4660         }
4661         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_SPDIF|B_TX_AUD_EN_SPDIF);
4662     }
4663     else
4664     {
4665         it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0);
4666     }
4667     it6161_hdmi_tx_set_bits(it6161, 0x5c, BIT(6), 0x00);
4668     hdmiTxDev[0].bAudioChannelEnable=it6161_hdmi_tx_read(it6161, REG_TX_AUDIO_CTRL0);
4669     // it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst  );
4670 }
4671 
setHDMITX_DSDAudio()4672 static void setHDMITX_DSDAudio()
4673 {
4674     // to be continue
4675     // u8 rst;
4676     // rst = it6161_hdmi_tx_read(it6161, REG_TX_SW_RST);
4677 
4678     //it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst | (B_HDMITX_AUD_RST|B_TX_AREF_RST) );
4679 
4680     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL1,0x41); // regE1 bOutputAudioMode should be loaded from ROM image.
4681     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
4682 
4683     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT);
4684     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL3,0);
4685 
4686     it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0x00);
4687     it6161_hdmi_tx_write(it6161, REG_TX_AUD_HDAUDIO,B_TX_DSD); // regE5 = 0 ;
4688     //it6161_hdmi_tx_write(it6161, REG_TX_SW_RST, rst & ~(B_HDMITX_AUD_RST|B_TX_AREF_RST) );
4689 
4690     //uc = it6161_hdmi_tx_read(it6161, REG_TX_CLK_CTRL1);
4691     //uc &= ~M_TX_AUD_DIV ;
4692     //it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL1, uc);
4693 
4694     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, M_TX_AUD_24BIT|B_TX_AUD_EN_I2S3|B_TX_AUD_EN_I2S2|B_TX_AUD_EN_I2S1|B_TX_AUD_EN_I2S0);
4695 }
4696 
HDMITX_DisableAudioOutput(struct it6161 * it6161)4697 static void HDMITX_DisableAudioOutput(struct it6161 *it6161)
4698 {
4699     //u8 uc = (it6161_hdmi_tx_read(it6161, REG_TX_SW_RST) | (B_HDMITX_AUD_RST | B_TX_AREF_RST));
4700     //it6161_hdmi_tx_write(it6161, REG_TX_SW_RST,uc);
4701     AudioDelayCnt=AudioOutDelayCnt;
4702     LastRefaudfreqnum=0;
4703     it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, (B_HDMITX_AUD_RST | B_TX_AREF_RST), (B_HDMITX_AUD_RST | B_TX_AREF_RST) );
4704     it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x10, 0x10 );
4705 }
4706 
HDMITX_EnableAudioOutput(struct it6161 * it6161,u8 AudioType,u8 bAudInterface,u32 SampleFreq,u8 ChNum,u8 * pIEC60958ChStat,u32 TMDSClock)4707 static void HDMITX_EnableAudioOutput(struct it6161 *it6161, u8 AudioType, u8 bAudInterface /*I2S/SPDIF/TDM*/,  u32 SampleFreq,  u8 ChNum, u8 *pIEC60958ChStat, u32 TMDSClock)
4708 {
4709     static u8 ucIEC60958ChStat[5] ;
4710 
4711     u8 Fs ;
4712     AudioDelayCnt=36;
4713     LastRefaudfreqnum=0;
4714     hdmiTxDev[0].TMDSClock=TMDSClock;
4715     hdmiTxDev[0].bAudioChannelEnable=0;
4716     hdmiTxDev[0].bAudInterface=bAudInterface;
4717 
4718     //DRM_INFO1(("HDMITX_EnableAudioOutput(%02X, %s, %d, %d, %p, %d);\n",
4719     //    AudioType, bSPDIF?"SPDIF":"I2S",SampleFreq, ChNum, pIEC60958ChStat, TMDSClock
4720     //    ));
4721 
4722     it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST | B_TX_AREF_RST), (B_HDMITX_AUD_RST | B_TX_AREF_RST));
4723     it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL0,B_TX_AUTO_OVER_SAMPLING_CLOCK|B_TX_EXT_256FS|0x01);
4724 
4725     it6161_hdmi_tx_set_bits(it6161, 0x0F, 0x10, 0x00 ); // power on the ACLK
4726 
4727     if(bAudInterface == SPDIF)
4728     {
4729         if(AudioType==T_AUDIO_HBR)
4730         {
4731             it6161_hdmi_tx_write(it6161, REG_TX_CLK_CTRL0,0x81);
4732         }
4733         it6161_hdmi_tx_set_bits(it6161, REG_TX_AUDIO_CTRL0,B_TX_AUD_SPDIF, B_TX_AUD_SPDIF);
4734     }
4735     else
4736     {
4737         it6161_hdmi_tx_set_bits(it6161, REG_TX_AUDIO_CTRL0, B_TX_AUD_SPDIF, 0x00);
4738     }
4739     if( AudioType != T_AUDIO_DSD)
4740     {
4741         // one bit audio have no channel status.
4742         switch(SampleFreq)
4743         {
4744         case  44100L: Fs =  AUDFS_44p1KHz ; break ;
4745         case  88200L: Fs =  AUDFS_88p2KHz ; break ;
4746         case 176400L: Fs = AUDFS_176p4KHz ; break ;
4747         case  32000L: Fs =    AUDFS_32KHz ; break ;
4748         case  48000L: Fs =    AUDFS_48KHz ; break ;
4749         case  96000L: Fs =    AUDFS_96KHz ; break ;
4750         case 192000L: Fs =   AUDFS_192KHz ; break ;
4751         case 768000L: Fs =   AUDFS_768KHz ; break ;
4752         default:
4753             SampleFreq = 48000L ;
4754             Fs =    AUDFS_48KHz ;
4755             break ; // default, set Fs = 48KHz.
4756         }
4757     #ifdef SUPPORT_AUDIO_MONITOR
4758         hdmiTxDev[0].bAudFs=Fs;// AUDFS_OTHER;
4759     #else
4760         hdmiTxDev[0].bAudFs=Fs;
4761     #endif
4762         setHDMITX_NCTS(hdmiTxDev[0].bAudFs);
4763         if( pIEC60958ChStat == NULL )
4764         {
4765             ucIEC60958ChStat[0] = 0 ;
4766             ucIEC60958ChStat[1] = 0 ;
4767             ucIEC60958ChStat[2] = (ChNum+1)/2 ;
4768 
4769             if(ucIEC60958ChStat[2]<1)
4770             {
4771                 ucIEC60958ChStat[2] = 1 ;
4772             }
4773             else if( ucIEC60958ChStat[2] >4 )
4774             {
4775                 ucIEC60958ChStat[2] = 4 ;
4776             }
4777             ucIEC60958ChStat[3] = Fs ;
4778             ucIEC60958ChStat[4] = (((~Fs)<<4) & 0xF0) | CHTSTS_SWCODE ; // Fs | 24bit u32 length
4779             pIEC60958ChStat = ucIEC60958ChStat ;
4780         }
4781     }
4782     it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),B_TX_AREF_RST);
4783 
4784     switch(AudioType)
4785     {
4786     case T_AUDIO_HBR:
4787         DRM_INFO("T_AUDIO_HBR\n");
4788         pIEC60958ChStat[0] |= 1<<1 ;
4789         pIEC60958ChStat[2] = 0;
4790         pIEC60958ChStat[3] &= 0xF0 ;
4791         pIEC60958ChStat[3] |= AUDFS_768KHz ;
4792         pIEC60958ChStat[4] |= (((~AUDFS_768KHz)<<4) & 0xF0)| 0xB ;
4793         setHDMITX_ChStat(it6161, pIEC60958ChStat);
4794         setHDMITX_HBRAudio(bAudInterface);
4795 
4796         break ;
4797     case T_AUDIO_DSD:
4798         DRM_INFO("T_AUDIO_DSD\n");
4799         setHDMITX_DSDAudio();
4800         break ;
4801     case T_AUDIO_NLPCM:
4802         DRM_INFO("T_AUDIO_NLPCM\n");
4803         pIEC60958ChStat[0] |= 1<<1 ;
4804         setHDMITX_ChStat(it6161, pIEC60958ChStat);
4805         setHDMITX_NLPCMAudio(bAudInterface);
4806         break ;
4807     case T_AUDIO_LPCM:
4808         DRM_INFO("T_AUDIO_LPCM\n");
4809         pIEC60958ChStat[0] &= ~(1<<1);
4810 
4811         setHDMITX_ChStat(it6161, pIEC60958ChStat);
4812         setHDMITX_LPCMAudio((ChNum+1)/2, SUPPORT_AUDI_AudSWL, bAudInterface);
4813         // can add auto adjust
4814         break ;
4815     }
4816     it6161_hdmi_tx_set_bits(it6161, REG_TX_INT_MASK1, B_TX_AUDIO_OVFLW_MASK, 0x00);
4817     it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, hdmiTxDev[0].bAudioChannelEnable);
4818 
4819     it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST),0);
4820 }
4821 #ifdef SUPPORT_AUDIO_MONITOR
hdmitx_AutoAdjustAudio()4822 void hdmitx_AutoAdjustAudio()
4823 {
4824     u32 SampleFreq,cTMDSClock ;
4825     u32 N ;
4826     u32 aCTS=0;
4827     u8 fs, uc,LoopCnt=10;
4828     if(bForceCTS)
4829     {
4830         it6161_hdmi_tx_change_bank(it6161, 0);
4831         it6161_hdmi_tx_write(it6161, 0xF8, 0xC3);
4832         it6161_hdmi_tx_write(it6161, 0xF8, 0xA5);
4833         it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, B_TX_SW_CTS, 0x00); // D[1] = 0, HW auto count CTS
4834         it6161_hdmi_tx_write(it6161, 0xF8, 0xFF);
4835     }
4836     //msleep(50);
4837     it6161_hdmi_tx_change_bank(it6161, 1);
4838     N = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudN2)&0xF) << 16 ;
4839     N |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudN1)) <<8 ;
4840     N |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudN0));
4841 
4842     while(LoopCnt--)
4843     {   u32 TempCTS=0;
4844         aCTS = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt2)) << 12 ;
4845         aCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt1)) <<4 ;
4846         aCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt0)&0xf0)>>4  ;
4847         if(aCTS==TempCTS)
4848         {break;}
4849         TempCTS=aCTS;
4850     }
4851     it6161_hdmi_tx_change_bank(it6161, 0);
4852     if( aCTS == 0)
4853     {
4854         DRM_INFO("aCTS== 0");
4855         return;
4856     }
4857     uc = it6161_hdmi_tx_read(it6161, REG_TX_GCP);
4858 
4859     cTMDSClock = hdmiTxDev[0].TMDSClock ;
4860     //TMDSClock=GetInputPclk();
4861     DRM_INFO("PCLK = %u0,000\n",(u32)(cTMDSClock/10000));
4862     switch(uc & 0x70)
4863     {
4864     case 0x50:
4865         cTMDSClock *= 5 ;
4866         cTMDSClock /= 4 ;
4867         break ;
4868     case 0x60:
4869         cTMDSClock *= 3 ;
4870         cTMDSClock /= 2 ;
4871     }
4872     SampleFreq = cTMDSClock/aCTS ;
4873     SampleFreq *= N ;
4874     SampleFreq /= 128 ;
4875     //SampleFreq=48000;
4876 
4877     DRM_INFO("SampleFreq = %u0\n",(u32)(SampleFreq/10));
4878     if( SampleFreq>31000L && SampleFreq<=38050L ){fs = AUDFS_32KHz ;}
4879     else if (SampleFreq < 46550L )  {fs = AUDFS_44p1KHz ;}//46050
4880     else if (SampleFreq < 68100L )  {fs = AUDFS_48KHz ;}
4881     else if (SampleFreq < 92100L )  {fs = AUDFS_88p2KHz ;}
4882     else if (SampleFreq < 136200L ) {fs = AUDFS_96KHz ;}
4883     else if (SampleFreq < 184200L ) {fs = AUDFS_176p4KHz ;}
4884     else if (SampleFreq < 240200L ) {fs = AUDFS_192KHz ;}
4885     else if (SampleFreq < 800000L ) {fs = AUDFS_768KHz ;}
4886     else
4887     {
4888         fs = AUDFS_OTHER;
4889         DRM_INFO("fs = AUDFS_OTHER\n");
4890     }
4891     if(hdmiTxDev[0].bAudFs != fs)
4892     {
4893         hdmiTxDev[0].bAudFs=fs;
4894         setHDMITX_NCTS(hdmiTxDev[0].bAudFs); // set N, CTS by new generated clock.
4895         //CurrCTS=0;
4896         return;
4897     }
4898     return;
4899 }
4900 
hdmitx_IsAudioChang()4901 bool hdmitx_IsAudioChang()
4902 {
4903     //u32 pCTS=0;
4904     u8 FreDiff=0,Refaudfreqnum;
4905 
4906     //it6161_hdmi_tx_change_bank(it6161, 1);
4907     //pCTS = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt2)) << 12 ;
4908     //pCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt1)) <<4 ;
4909     //pCTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt0)&0xf0)>>4  ;
4910     //it6161_hdmi_tx_change_bank(it6161, 0);
4911     it6161_hdmi_tx_change_bank(it6161, 0);
4912     Refaudfreqnum=it6161_hdmi_tx_read(it6161, 0x60);
4913     //"Refaudfreqnum=%X    pCTS= %u",(u32)Refaudfreqnum,(u32)(pCTS/10000)));
4914     //if((pCTS%10000)<1000)DRM_INFO("0");
4915     //if((pCTS%10000)<100)DRM_INFO("0");
4916     //if((pCTS%10000)<10)DRM_INFO("0");
4917     //DRM_INFO("%u\n",(u32)(pCTS%10000));
4918     if((1<<4)&it6161_hdmi_tx_read(it6161, 0x5f))
4919     {
4920         //printf("=======XXXXXXXXXXX=========\n");
4921         return false;
4922     }
4923     if(LastRefaudfreqnum>Refaudfreqnum)
4924         {FreDiff=LastRefaudfreqnum-Refaudfreqnum;}
4925     else
4926         {FreDiff=Refaudfreqnum-LastRefaudfreqnum;}
4927     LastRefaudfreqnum=Refaudfreqnum;
4928     if(3<FreDiff)
4929     {
4930         DRM_INFO("Aduio FreDiff=%d\n",(int)FreDiff);
4931         it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL,(1<<5), (1<<5));
4932         it6161_hdmi_tx_set_bits(it6161, REG_TX_AUDIO_CTRL0, 0x0F, 0x00);
4933         return true;
4934     }
4935     else
4936     {
4937         return false;
4938     }
4939 }
4940 /*
4941 void setHDMITX_AudioChannelEnable(bool EnableAudio_b)
4942 {
4943     static bool AudioOutStatus=false;
4944     if(EnableAudio_b)
4945     {
4946         if(AudioDelayCnt==0)
4947         {
4948             //if(hdmiTxDev[0].bAuthenticated==false)
4949             //{
4950         #ifdef SUPPORT_AUDIO_MONITOR
4951             if(hdmitx_IsAudioChang())
4952             {
4953                 hdmitx_AutoAdjustAudio();
4954         #else
4955             if(AudioOutStatus==false)
4956             {
4957                 setHDMITX_NCTS(hdmiTxDev[0].bAudFs);
4958         #endif
4959                 it6161_hdmi_tx_write(it6161, REG_TX_AUD_SRCVALID_FLAT,0);
4960                 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL,(1<<5), (1<<5));
4961                 it6161_hdmi_tx_write(it6161, REG_TX_AUDIO_CTRL0, hdmiTxDev[0].bAudioChannelEnable);
4962                 //it6161_hdmi_tx_set_bits(it6161, 0x59,(1<<2), (1<<2));  //for test
4963                 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, 0x3C, 0x00);
4964                 it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, 1<<5, 0x00);
4965                 printf("Audio Out Enable\n");
4966         #ifndef SUPPORT_AUDIO_MONITOR
4967                 AudioOutStatus=true;
4968         #endif
4969             }
4970         }
4971         else
4972         {
4973             AudioOutStatus=false;
4974             if(0==(it6161_hdmi_tx_read(it6161, REG_TX_CLK_STATUS2)&0x10))
4975             {
4976                 AudioDelayCnt--;
4977             }
4978             else
4979             {
4980                 AudioDelayCnt=AudioOutDelayCnt;
4981             }
4982         }
4983     }
4984     else
4985     {
4986        // CurrCTS=0;
4987     }
4988 }*/
4989 #endif //#ifdef SUPPORT_AUDIO_MONITOR
4990 //////////////////////////////////////////////////////////////////////
4991 // Function: setHDMITX_NCTS
4992 // Parameter: PCLK - video clock in Hz.
4993 //            Fs - Encoded audio sample rate
4994 //                          AUDFS_22p05KHz  4
4995 //                          AUDFS_44p1KHz 0
4996 //                          AUDFS_88p2KHz 8
4997 //                          AUDFS_176p4KHz    12
4998 //
4999 //                          AUDFS_24KHz  6
5000 //                          AUDFS_48KHz  2
5001 //                          AUDFS_96KHz  10
5002 //                          AUDFS_192KHz 14
5003 //
5004 //                          AUDFS_768KHz 9
5005 //
5006 //                          AUDFS_32KHz  3
5007 //                          AUDFS_OTHER    1
5008 // Return: ER_SUCCESS if success
5009 // Remark: set N value,the CTS will be auto generated by HW.
5010 // Side-Effect: register bank will reset to bank 0.
5011 //////////////////////////////////////////////////////////////////////
5012 
setHDMITX_NCTS(u8 Fs)5013 static void setHDMITX_NCTS(u8 Fs)
5014 {
5015     u32 n;
5016     u8 LoopCnt=255,CTSStableCnt=0;
5017     u32 diff;
5018     u32 CTS=0,LastCTS=0;
5019     bool HBR_mode;
5020     // u8 aVIC;
5021 
5022     if(B_TX_HBR & it6161_hdmi_tx_read(it6161, REG_TX_AUD_HDAUDIO))
5023     {
5024         HBR_mode=true;
5025     }
5026     else
5027     {
5028         HBR_mode=false;
5029     }
5030     switch(Fs)
5031     {
5032     case AUDFS_32KHz: n = 4096; break;
5033     case AUDFS_44p1KHz: n = 6272; break;
5034     case AUDFS_48KHz: n = 6144; break;
5035     case AUDFS_88p2KHz: n = 12544; break;
5036     case AUDFS_96KHz: n = 12288; break;
5037     case AUDFS_176p4KHz: n = 25088; break;
5038     case AUDFS_192KHz: n = 24576; break;
5039     case AUDFS_768KHz: n = 24576; break ;
5040     default: n = 6144;
5041     }
5042     // tr_printf((" n = %d\n",n));
5043     it6161_hdmi_tx_change_bank(it6161, 1);
5044     it6161_hdmi_tx_write(it6161, REGPktAudN0,(u8)((n)&0xFF));
5045     it6161_hdmi_tx_write(it6161, REGPktAudN1,(u8)((n>>8)&0xFF));
5046     it6161_hdmi_tx_write(it6161, REGPktAudN2,(u8)((n>>16)&0xF));
5047 
5048     if(bForceCTS)
5049     {
5050         u32 SumCTS=0;
5051         while(LoopCnt--)
5052         {
5053             msleep(30);
5054             CTS = ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt2)) << 12 ;
5055             CTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt1)) <<4 ;
5056             CTS |= ((u32)it6161_hdmi_tx_read(it6161, REGPktAudCTSCnt0)&0xf0)>>4  ;
5057             if( CTS == 0)
5058             {
5059                 continue;
5060             }
5061             else
5062             {
5063                 if(LastCTS>CTS )
5064                     {diff=LastCTS-CTS;}
5065                 else
5066                     {diff=CTS-LastCTS;}
5067                 //DRM_INFO("LastCTS= %u%u",(u32)(LastCTS/10000),(u32)(LastCTS%10000));
5068                 //DRM_INFO("       CTS= %u%u\n",(u32)(CTS/10000),(u32)(CTS%10000));
5069                 LastCTS=CTS;
5070                 if(5>diff)
5071                 {
5072                     CTSStableCnt++;
5073                     SumCTS+=CTS;
5074                 }
5075                 else
5076                 {
5077                     CTSStableCnt=0;
5078                     SumCTS=0;
5079                     continue;
5080                 }
5081                 if(CTSStableCnt>=32)
5082                 {
5083                     LastCTS=(SumCTS>>5);
5084                     break;
5085                 }
5086             }
5087         }
5088     }
5089     it6161_hdmi_tx_write(it6161, REGPktAudCTS0,(u8)((LastCTS)&0xFF));
5090     it6161_hdmi_tx_write(it6161, REGPktAudCTS1,(u8)((LastCTS>>8)&0xFF));
5091     it6161_hdmi_tx_write(it6161, REGPktAudCTS2,(u8)((LastCTS>>16)&0xF));
5092     it6161_hdmi_tx_change_bank(it6161, 0);
5093 #ifdef Force_CTS
5094     bForceCTS = true;
5095 #endif
5096     it6161_hdmi_tx_write(it6161, 0xF8, 0xC3);
5097     it6161_hdmi_tx_write(it6161, 0xF8, 0xA5);
5098     if(bForceCTS)
5099     {
5100         it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL,B_TX_SW_CTS, B_TX_SW_CTS); // D[1] = 0, HW auto count CTS
5101     }
5102     else
5103     {
5104         it6161_hdmi_tx_set_bits(it6161, REG_TX_PKT_SINGLE_CTRL, B_TX_SW_CTS, 0x00); // D[1] = 0, HW auto count CTS
5105     }
5106     it6161_hdmi_tx_write(it6161, 0xF8, 0xFF);
5107 
5108     if(false==HBR_mode) //LPCM
5109     {
5110         u8 uData;
5111         it6161_hdmi_tx_change_bank(it6161, 1);
5112         Fs = AUDFS_768KHz ;
5113         it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_CA_FS,0x00|Fs);
5114         Fs = ~Fs ; // OFS is the one's complement of FS
5115         uData = (0x0f&it6161_hdmi_tx_read(it6161, REG_TX_AUDCHST_OFS_WL));
5116         it6161_hdmi_tx_write(it6161, REG_TX_AUDCHST_OFS_WL,(Fs<<4)|uData);
5117         it6161_hdmi_tx_change_bank(it6161, 0);
5118     }
5119 }
5120 
5121 //////////////////////////////////////////////////////////////////////
5122 // Function: hdmitx_SetAudioInfoFrame()
5123 // Parameter: pAudioInfoFrame - the pointer to HDMI Audio Infoframe ucData
5124 // Return: N/A
5125 // Remark: Fill the Audio InfoFrame ucData,and count checksum,then fill into
5126 //         Audio InfoFrame registers.
5127 // Side-Effect: N/A
5128 //////////////////////////////////////////////////////////////////////
5129 
hdmitx_SetAudioInfoFrame(struct it6161 * it6161,Audio_InfoFrame * pAudioInfoFrame)5130 static SYS_STATUS hdmitx_SetAudioInfoFrame(struct it6161 *it6161, Audio_InfoFrame *pAudioInfoFrame)
5131 {
5132     u8 checksum ;
5133 
5134     if(!pAudioInfoFrame)
5135     {
5136         return ER_FAIL ;
5137     }
5138     it6161_hdmi_tx_change_bank(it6161, 1);
5139     checksum = 0x100-(AUDIO_INFOFRAME_VER+AUDIO_INFOFRAME_TYPE+AUDIO_INFOFRAME_LEN );
5140     it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_CC,pAudioInfoFrame->pktbyte.AUD_DB[0]);
5141     checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_CC); checksum &= 0xFF ;
5142     it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_SF,pAudioInfoFrame->pktbyte.AUD_DB[1]);
5143     checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_SF); checksum &= 0xFF ;
5144     it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_CA,pAudioInfoFrame->pktbyte.AUD_DB[3]);
5145     checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_CA); checksum &= 0xFF ;
5146     it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_DM_LSV,pAudioInfoFrame->pktbyte.AUD_DB[4]);
5147     checksum -= it6161_hdmi_tx_read(it6161, REG_TX_PKT_AUDINFO_DM_LSV); checksum &= 0xFF ;
5148 
5149     it6161_hdmi_tx_write(it6161, REG_TX_PKT_AUDINFO_SUM,checksum);
5150 
5151     it6161_hdmi_tx_change_bank(it6161, 0);
5152     hdmitx_ENABLE_AUD_INFOFRM_PKT();
5153     return ER_SUCCESS ;
5154 }
5155 
5156 //////////////////////////////////////////////////////////////////////
5157 // Function: hdmitx_SetAVIInfoFrame()
5158 // Parameter: pAVIInfoFrame - the pointer to HDMI AVI Infoframe ucData
5159 // Return: N/A
5160 // Remark: Fill the AVI InfoFrame ucData,and count checksum,then fill into
5161 //         AVI InfoFrame registers.
5162 // Side-Effect: N/A
5163 //////////////////////////////////////////////////////////////////////
5164 #if 0
5165 static SYS_STATUS hdmitx_SetAVIInfoFrame(struct it6161 *it6161, AVI_InfoFrame *pAVIInfoFrame)
5166 {
5167     int i ;
5168     u8 checksum ;
5169 
5170     if(!pAVIInfoFrame)
5171     {
5172         return ER_FAIL ;
5173     }
5174     it6161_hdmi_tx_change_bank(it6161, 1);
5175     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB1,pAVIInfoFrame->pktbyte.AVI_DB[0]);
5176     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB2,pAVIInfoFrame->pktbyte.AVI_DB[1]);
5177     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB3,pAVIInfoFrame->pktbyte.AVI_DB[2]);
5178     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB4,pAVIInfoFrame->pktbyte.AVI_DB[3]);
5179     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB5,pAVIInfoFrame->pktbyte.AVI_DB[4]);
5180     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB6,pAVIInfoFrame->pktbyte.AVI_DB[5]);
5181     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB7,pAVIInfoFrame->pktbyte.AVI_DB[6]);
5182     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB8,pAVIInfoFrame->pktbyte.AVI_DB[7]);
5183     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB9,pAVIInfoFrame->pktbyte.AVI_DB[8]);
5184     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB10,pAVIInfoFrame->pktbyte.AVI_DB[9]);
5185     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB11,pAVIInfoFrame->pktbyte.AVI_DB[10]);
5186     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB12,pAVIInfoFrame->pktbyte.AVI_DB[11]);
5187     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB13,pAVIInfoFrame->pktbyte.AVI_DB[12]);
5188     for(i = 0,checksum = 0; i < 13 ; i++)
5189     {
5190         checksum -= pAVIInfoFrame->pktbyte.AVI_DB[i] ;
5191     }
5192     /*
5193     DRM_INFO("SetAVIInfo(): ");
5194     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB1));
5195     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB2));
5196     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB3));
5197     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB4));
5198     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB5));
5199     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB6));
5200     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB7));
5201     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB8));
5202     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB9));
5203     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB10));
5204     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB11));
5205     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB12));
5206     DRM_INFO("%02X ",(int)it6161_hdmi_tx_read(it6161, REG_TX_AVIINFO_DB13));
5207     DRM_INFO("\n");
5208     */
5209     checksum -= AVI_INFOFRAME_VER+AVI_INFOFRAME_TYPE+AVI_INFOFRAME_LEN ;
5210     it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_SUM,checksum);
5211 
5212     it6161_hdmi_tx_change_bank(it6161, 0);
5213     hdmitx_ENABLE_AVI_INFOFRM_PKT();
5214     return ER_SUCCESS ;
5215 }
5216 #endif
hdmitx_SetVSIInfoFrame(struct it6161 * it6161,VendorSpecific_InfoFrame * pVSIInfoFrame)5217 static SYS_STATUS hdmitx_SetVSIInfoFrame(struct it6161 *it6161, VendorSpecific_InfoFrame *pVSIInfoFrame)
5218 {
5219     u8 ucData=0 ;
5220 
5221     if(!pVSIInfoFrame)
5222     {
5223         return ER_FAIL ;
5224     }
5225 
5226     it6161_hdmi_tx_change_bank(it6161, 1);
5227     it6161_hdmi_tx_write(it6161, 0x80,pVSIInfoFrame->pktbyte.VS_DB[3]);
5228     it6161_hdmi_tx_write(it6161, 0x81,pVSIInfoFrame->pktbyte.VS_DB[4]);
5229 
5230     ucData -= pVSIInfoFrame->pktbyte.VS_DB[3] ;
5231     ucData -= pVSIInfoFrame->pktbyte.VS_DB[4] ;
5232 
5233     if(  pVSIInfoFrame->pktbyte.VS_DB[4] & (1<<7 ))
5234     {
5235         ucData -= pVSIInfoFrame->pktbyte.VS_DB[5] ;
5236         it6161_hdmi_tx_write(it6161, 0x82,pVSIInfoFrame->pktbyte.VS_DB[5]);
5237         ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 6 + 0x0C + 0x03 ;
5238     }
5239     else
5240     {
5241         ucData -= VENDORSPEC_INFOFRAME_TYPE + VENDORSPEC_INFOFRAME_VER + 5 + 0x0C + 0x03 ;
5242     }
5243 
5244     pVSIInfoFrame->pktbyte.CheckSum=ucData;
5245 
5246     it6161_hdmi_tx_write(it6161, 0x83,pVSIInfoFrame->pktbyte.CheckSum);
5247     it6161_hdmi_tx_change_bank(it6161, 0);
5248     it6161_hdmi_tx_write(it6161, REG_TX_3D_INFO_CTRL,B_TX_ENABLE_PKT|B_TX_REPEAT_PKT);
5249     return ER_SUCCESS ;
5250 }
5251 
HDMITX_EnableVSInfoFrame(struct it6161 * it6161,u8 bEnable,u8 * pVSInfoFrame)5252 static bool HDMITX_EnableVSInfoFrame(struct it6161 *it6161, u8 bEnable,u8 *pVSInfoFrame)
5253 {
5254     if(!bEnable)
5255     {
5256         hdmitx_DISABLE_VSDB_PKT();
5257         return true ;
5258     }
5259     if(hdmitx_SetVSIInfoFrame(it6161, (VendorSpecific_InfoFrame *)pVSInfoFrame) == ER_SUCCESS)
5260     {
5261         return true ;
5262     }
5263     return false ;
5264 }
5265 /*
5266 static bool HDMITX_EnableAVIInfoFrame(struct it6161 *it6161, u8 bEnable,u8 *pAVIInfoFrame)
5267 {
5268     if(!bEnable)
5269     {
5270         hdmitx_DISABLE_AVI_INFOFRM_PKT();
5271         return true ;
5272     }
5273     if(hdmitx_SetAVIInfoFrame(it6161, (AVI_InfoFrame *)pAVIInfoFrame) == ER_SUCCESS)
5274     {
5275         return true ;
5276     }
5277     return false ;
5278 }
5279 */
HDMITX_EnableAudioInfoFrame(struct it6161 * it6161,u8 bEnable,u8 * pAudioInfoFrame)5280 static bool HDMITX_EnableAudioInfoFrame(struct it6161 *it6161, u8 bEnable,u8 *pAudioInfoFrame)
5281 {
5282     if(!bEnable)
5283     {
5284         hdmitx_DISABLE_AVI_INFOFRM_PKT();
5285         return true ;
5286     }
5287     if(hdmitx_SetAudioInfoFrame(it6161, (Audio_InfoFrame *)pAudioInfoFrame) == ER_SUCCESS)
5288     {
5289         return true ;
5290     }
5291     return false ;
5292 }
5293 
5294 //////////////////////////////////////////////////////////////////////
5295 // Function: hdmitx_SetSPDInfoFrame()
5296 // Parameter: pSPDInfoFrame - the pointer to HDMI SPD Infoframe ucData
5297 // Return: N/A
5298 // Remark: Fill the SPD InfoFrame ucData,and count checksum,then fill into
5299 //         SPD InfoFrame registers.
5300 // Side-Effect: N/A
5301 //////////////////////////////////////////////////////////////////////
5302 /*
5303 SYS_STATUS hdmitx_SetSPDInfoFrame(SPD_InfoFrame *pSPDInfoFrame)
5304 {
5305     int i ;
5306     u8 ucData ;
5307 
5308     if(!pSPDInfoFrame)
5309     {
5310         return ER_FAIL ;
5311     }
5312     it6161_hdmi_tx_change_bank(it6161, 1);
5313     for(i = 0,ucData = 0 ; i < 25 ; i++)
5314     {
5315         ucData -= pSPDInfoFrame->pktbyte.SPD_DB[i] ;
5316         it6161_hdmi_tx_write(it6161, REG_TX_PKT_SPDINFO_PB1+i,pSPDInfoFrame->pktbyte.SPD_DB[i]);
5317     }
5318     ucData -= SPD_INFOFRAME_VER+SPD_INFOFRAME_TYPE+SPD_INFOFRAME_LEN ;
5319     it6161_hdmi_tx_write(it6161, REG_TX_PKT_SPDINFO_SUM,ucData); // checksum
5320     it6161_hdmi_tx_change_bank(it6161, 0);
5321     hdmitx_ENABLE_SPD_INFOFRM_PKT();
5322     return ER_SUCCESS ;
5323 }
5324 */
5325 //////////////////////////////////////////////////////////////////////
5326 // Function: hdmitx_SetMPEGInfoFrame()
5327 // Parameter: pMPEGInfoFrame - the pointer to HDMI MPEG Infoframe ucData
5328 // Return: N/A
5329 // Remark: Fill the MPEG InfoFrame ucData,and count checksum,then fill into
5330 //         MPEG InfoFrame registers.
5331 // Side-Effect: N/A
5332 //////////////////////////////////////////////////////////////////////
5333 /*
5334 SYS_STATUS hdmitx_SetMPEGInfoFrame(MPEG_InfoFrame *pMPGInfoFrame)
5335 {
5336     int i ;
5337     u8 ucData ;
5338 
5339     if(!pMPGInfoFrame)
5340     {
5341         return ER_FAIL ;
5342     }
5343     it6161_hdmi_tx_change_bank(it6161, 1);
5344 
5345     it6161_hdmi_tx_write(it6161, REG_TX_PKT_MPGINFO_FMT,pMPGInfoFrame->info.FieldRepeat|(pMPGInfoFrame->info.MpegFrame<<1));
5346     it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB0,pMPGInfoFrame->pktbyte.MPG_DB[0]);
5347     it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB1,pMPGInfoFrame->pktbyte.MPG_DB[1]);
5348     it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB2,pMPGInfoFrame->pktbyte.MPG_DB[2]);
5349     it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_DB3,pMPGInfoFrame->pktbyte.MPG_DB[3]);
5350 
5351     for(ucData = 0,i = 0 ; i < 5 ; i++)
5352     {
5353         ucData -= pMPGInfoFrame->pktbyte.MPG_DB[i] ;
5354     }
5355     ucData -= MPEG_INFOFRAME_VER+MPEG_INFOFRAME_TYPE+MPEG_INFOFRAME_LEN ;
5356 
5357     it6161_hdmi_tx_write(it6161, REG_TX_PKG_MPGINFO_SUM,ucData);
5358 
5359     it6161_hdmi_tx_change_bank(it6161, 0);
5360     hdmitx_ENABLE_SPD_INFOFRM_PKT();
5361 
5362     return ER_SUCCESS ;
5363 }
5364 */
5365 // 2009/12/04 added by Ming-chih.lung@ite.com.tw
5366 
5367 /*
5368 SYS_STATUS hdmitx_Set_GeneralPurpose_PKT(u8 *pData)
5369 {
5370     int i ;
5371 
5372     if( pData == NULL )
5373     {
5374         return ER_FAIL ;
5375 
5376     }
5377     it6161_hdmi_tx_change_bank(it6161, 1);
5378     for( i = 0x38 ; i <= 0x56 ; i++)
5379     {
5380         it6161_hdmi_tx_write(it6161, i, pData[i-0x38] );
5381     }
5382     it6161_hdmi_tx_change_bank(it6161, 0);
5383     hdmitx_ENABLE_GeneralPurpose_PKT();
5384     //hdmitx_ENABLE_NULL_PKT();
5385     return ER_SUCCESS ;
5386 }
5387 */
5388 /*
5389 static void ConfigAVIInfoFrame(u8 VIC, u8 pixelrep)
5390 {
5391     AVI_InfoFrame *AviInfo;
5392     AviInfo = (AVI_InfoFrame *)CommunBuff ;
5393 
5394     AviInfo->pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
5395     AviInfo->pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
5396     AviInfo->pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
5397 
5398     switch(it6161->hdmi_tx_output_color_space)
5399     {
5400     case F_MODE_YUV444:
5401         // AviInfo->info.ColorMode = 2 ;
5402         AviInfo->pktbyte.AVI_DB[0] = (2<<5)|(1<<4);
5403         break ;
5404     case F_MODE_YUV422:
5405         // AviInfo->info.ColorMode = 1 ;
5406         AviInfo->pktbyte.AVI_DB[0] = (1<<5)|(1<<4);
5407         break ;
5408     case F_MODE_RGB444:
5409     default:
5410         // AviInfo->info.ColorMode = 0 ;
5411         AviInfo->pktbyte.AVI_DB[0] = (0<<5)|(1<<4);
5412         break ;
5413     }
5414     AviInfo->pktbyte.AVI_DB[1] = 8 ;
5415     AviInfo->pktbyte.AVI_DB[1] |= (aspec != HDMI_16x9)?(1<<4):(2<<4); // 4:3 or 16:9
5416     AviInfo->pktbyte.AVI_DB[1] |= (Colorimetry != HDMI_ITU709)?(1<<6):(2<<6); // 4:3 or 16:9
5417     AviInfo->pktbyte.AVI_DB[2] = 0 ;
5418     AviInfo->pktbyte.AVI_DB[3] = VIC ;
5419     AviInfo->pktbyte.AVI_DB[4] =  pixelrep & 3 ;
5420     AviInfo->pktbyte.AVI_DB[5] = 0 ;
5421     AviInfo->pktbyte.AVI_DB[6] = 0 ;
5422     AviInfo->pktbyte.AVI_DB[7] = 0 ;
5423     AviInfo->pktbyte.AVI_DB[8] = 0 ;
5424     AviInfo->pktbyte.AVI_DB[9] = 0 ;
5425     AviInfo->pktbyte.AVI_DB[10] = 0 ;
5426     AviInfo->pktbyte.AVI_DB[11] = 0 ;
5427     AviInfo->pktbyte.AVI_DB[12] = 0 ;
5428 
5429     HDMITX_EnableAVIInfoFrame(it6161, true, (unsigned char *)AviInfo);
5430 }
5431 */
ConfigAudioInfoFrm(struct it6161 * it6161,u8 channel_count)5432 static void ConfigAudioInfoFrm(struct it6161 *it6161, u8 channel_count)
5433 {
5434     int i;
5435     Audio_InfoFrame *AudioInfo ;
5436     AudioInfo = (Audio_InfoFrame *)CommunBuff ;
5437 
5438     DRM_INFO("ConfigAudioInfoFrm channel count: %d", channel_count);
5439 
5440     AudioInfo->pktbyte.AUD_HB[0] = AUDIO_INFOFRAME_TYPE ;
5441     AudioInfo->pktbyte.AUD_HB[1] = 1 ;
5442     AudioInfo->pktbyte.AUD_HB[2] = AUDIO_INFOFRAME_LEN ;
5443     AudioInfo->pktbyte.AUD_DB[0] = channel_count - 1;
5444 
5445     for (i = 1 ;i < AUDIO_INFOFRAME_LEN ; i++) {
5446         AudioInfo->pktbyte.AUD_DB[i] = 0 ;
5447     }
5448 
5449     /* audio_infoframe_ca */
5450 	switch (channel_count) {
5451 		case 0 :
5452 			AudioInfo->pktbyte.AUD_DB[3] = 0xFF;
5453 			break;  // no audio
5454 		case 2 :
5455 			AudioInfo->pktbyte.AUD_DB[3] = 0x00;
5456 			break;
5457 		case 3 :
5458 			AudioInfo->pktbyte.AUD_DB[3] = 0x01;
5459 			break;  // 0x01,0x02,0x04
5460 		case 4 :
5461 			AudioInfo->pktbyte.AUD_DB[3] = 0x03;
5462 			break;  // 0x03,0x05,0x06,0x08,0x14
5463 		case 5 :
5464 			AudioInfo->pktbyte.AUD_DB[3] = 0x07;
5465 			break;  // 0x07,0x09,0x0A,0x0C,0x15,0x16,0x18
5466 		case 6 :
5467 			AudioInfo->pktbyte.AUD_DB[3] = 0x0B;
5468 			break;  // 0x0B,0x0D,0x0E,0x10,0x17,0x19,0x1A,0x1C
5469 		case 7 :
5470 			AudioInfo->pktbyte.AUD_DB[3] = 0x0F;
5471 			break;  // 0x0F,0x11,0x12,0x1B,0x1D,0x1E
5472 		case 8 :
5473 			AudioInfo->pktbyte.AUD_DB[3] = 0x1F;
5474 			break;  // 0x13,0x1F
5475 		default :
5476 			DRM_INFO("Error: Audio Channel Number Error!");
5477 	}
5478 
5479     HDMITX_EnableAudioInfoFrame(it6161, TRUE, (unsigned char *)AudioInfo);
5480 }
5481 
5482 #ifdef OUTPUT_3D_MODE
ConfigfHdmiVendorSpecificInfoFrame(struct it6161 * it6161,u8 _3D_Stru)5483 void ConfigfHdmiVendorSpecificInfoFrame(struct it6161 *it6161, u8 _3D_Stru)
5484 {
5485     VendorSpecific_InfoFrame *VS_Info;
5486 
5487     VS_Info=(VendorSpecific_InfoFrame *)CommunBuff ;
5488 
5489     VS_Info->pktbyte.VS_HB[0] = VENDORSPEC_INFOFRAME_TYPE|0x80;
5490     VS_Info->pktbyte.VS_HB[1] = VENDORSPEC_INFOFRAME_VER;
5491     VS_Info->pktbyte.VS_HB[2] = (_3D_Stru == Side_by_Side)?6:5;
5492     VS_Info->pktbyte.VS_DB[0] = 0x03;
5493     VS_Info->pktbyte.VS_DB[1] = 0x0C;
5494     VS_Info->pktbyte.VS_DB[2] = 0x00;
5495     VS_Info->pktbyte.VS_DB[3] = 0x40;
5496     switch(_3D_Stru)
5497     {
5498     case Side_by_Side:
5499     case Frame_Pcaking:
5500     case Top_and_Botton:
5501         VS_Info->pktbyte.VS_DB[4] = (_3D_Stru<<4);
5502         break;
5503     default:
5504         VS_Info->pktbyte.VS_DB[4] = (Frame_Pcaking<<4);
5505         break ;
5506     }
5507     VS_Info->pktbyte.VS_DB[5] = 0x00;
5508     HDMITX_EnableVSInfoFrame(it6161, true,(u8 *)VS_Info);
5509 }
5510 #endif //#ifdef OUTPUT_3D_MODE
5511 
hdmi_tx_audio_process(struct it6161 * it6161)5512 static void hdmi_tx_audio_process(struct it6161 *it6161)
5513 {
5514     if (it6161->support_audio) {
5515         ConfigAudioInfoFrm(it6161, bOutputAudioChannel);
5516         // HDMITX_EnableAudioOutput(T_AUDIO_LPCM, false, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,TMDSClock);
5517         HDMITX_EnableAudioOutput(it6161,
5518             //CNOFIG_INPUT_AUDIO_TYPE,
5519             bOutputAudioType,
5520             CONFIG_INPUT_AUDIO_INTERFACE,
5521             ulAudioSampleFS,
5522             bOutputAudioChannel,
5523             NULL, // pointer to cahnnel status.
5524             VideoPixelClock*(pixelrep+1));
5525         // if you have channel status , set here.
5526         // setHDMITX_ChStat(it6161, u8 ucIEC60958ChStat[]);
5527     }
5528 }
5529 
5530 #if 0
5531 static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size)
5532 {
5533 	u8 csum = 0;
5534 	size_t i;
5535 
5536 	/* compute checksum */
5537 	for (i = 0; i < size; i++)
5538 		csum += ptr[i];
5539 
5540 	return 256 - csum;
5541 }
5542 
5543 static void hdmi_infoframe_set_checksum(void *buffer, size_t size)
5544 {
5545 	u8 *ptr = buffer;
5546 
5547 	ptr[3] = hdmi_infoframe_checksum(buffer, size);
5548 }
5549 #endif
5550 
hdmi_tx_get_avi_infoframe_from_source(struct it6161 * it6161,u8 * buffer,size_t size)5551 static int hdmi_tx_get_avi_infoframe_from_source(struct it6161 *it6161, u8 *buffer, size_t size)
5552 {
5553 	struct device *dev = &it6161->i2c_mipi_rx->dev;
5554 	int err;
5555 
5556 	err = hdmi_avi_infoframe_pack(&it6161->source_avi_infoframe, buffer, size);
5557 	if (err < 0) {
5558 		DRM_DEV_ERROR(dev, "Failed to pack AVI infoframe: %d", err);
5559 		return err;
5560 	}
5561 
5562 	return 0;
5563 }
5564 
hdmi_tx_get_avi_infoframe_from_user_define(struct it6161 * it6161,u8 * buffer,size_t size)5565 static int hdmi_tx_get_avi_infoframe_from_user_define(struct it6161 *it6161, u8 *buffer, size_t size)
5566 {
5567 	struct device *dev = &it6161->i2c_hdmi_tx->dev;
5568 	struct hdmi_avi_infoframe *frame = &it6161->source_avi_infoframe;
5569 	struct drm_display_mode *display_mode = &it6161->source_display_mode;
5570 	int ret;
5571 
5572 	DRM_INFO( "user define to setup AVI infoframe");
5573 
5574 	ret = drm_hdmi_avi_infoframe_from_display_mode(frame, &it6161->connector, display_mode);
5575 	if (ret) {
5576 		DRM_DEV_ERROR(dev, "Failed to setup AVI infoframe: %d", ret);
5577 		return ret;
5578 	}
5579 
5580 	if ((it6161->hdmi_tx_output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_RGB444)
5581 		frame->colorspace =  HDMI_COLORSPACE_RGB;
5582 
5583 	if ((it6161->hdmi_tx_output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_YUV444)
5584 		frame->colorspace =  HDMI_COLORSPACE_YUV444;
5585 
5586 	if ((it6161->hdmi_tx_output_color_space & F_MODE_CLRMOD_MASK) == F_MODE_YUV422)
5587 		frame->colorspace =  HDMI_COLORSPACE_YUV422;
5588 
5589 	ret = hdmi_tx_get_avi_infoframe_from_source(it6161, buffer, size);
5590 	if (ret) {
5591 		DRM_DEV_ERROR(dev, "Failed to pack AVI infoframe: %d", ret);
5592 		return ret;
5593 	}
5594 
5595 	return 0;
5596 }
5597 
5598 static int (*hdmi_tx_get_avi_infoframe)(struct it6161*, u8*, size_t) = hdmi_tx_get_avi_infoframe_from_user_define;
5599 
hdmi_tx_setup_avi_infoframe(struct it6161 * it6161,u8 * buffer,size_t size)5600 static void hdmi_tx_setup_avi_infoframe(struct it6161 *it6161, u8 *buffer, size_t size)
5601 {
5602 	u8 i, *ptr = buffer + HDMI_INFOFRAME_HEADER_SIZE;
5603 
5604 	it6161_hdmi_tx_change_bank(it6161, 1);
5605 
5606 	for (i = 0; i < it6161->source_avi_infoframe.length; i++)
5607 		it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_DB1 + i, ptr[i]);
5608 
5609 	it6161_hdmi_tx_write(it6161, REG_TX_AVIINFO_SUM, buffer[3]);
5610 }
5611 
hdmi_tx_disable_avi_infoframe(struct it6161 * it6161)5612 static inline void hdmi_tx_disable_avi_infoframe(struct it6161 *it6161)
5613 {
5614 	it6161_hdmi_tx_change_bank(it6161, 0);
5615 	it6161_hdmi_tx_write(it6161, REG_TX_AVI_INFOFRM_CTRL, 0x00);
5616 }
5617 
hdmi_tx_enable_avi_infoframe(struct it6161 * it6161)5618 static inline void hdmi_tx_enable_avi_infoframe(struct it6161 *it6161)
5619 {
5620 	it6161_hdmi_tx_change_bank(it6161, 0);
5621 	it6161_hdmi_tx_write(it6161, REG_TX_AVI_INFOFRM_CTRL, B_TX_ENABLE_PKT | B_TX_REPEAT_PKT);
5622 }
5623 
hdmi_tx_avi_infoframe_process(struct it6161 * it6161)5624 static int hdmi_tx_avi_infoframe_process(struct it6161 *it6161)
5625 {
5626 	u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
5627 	int err;
5628 
5629 	hdmi_tx_disable_avi_infoframe(it6161);
5630 	err = hdmi_tx_get_avi_infoframe(it6161, buffer, sizeof(buffer));
5631 
5632 	if (err)
5633 		return err;
5634 
5635 	hdmi_tx_setup_avi_infoframe(it6161, buffer, sizeof(buffer));
5636 	hdmi_tx_enable_avi_infoframe(it6161);
5637 
5638 	DRM_INFO("avi_infoframe:0x%*ph", (int)ARRAY_SIZE(buffer), buffer);
5639 
5640 	return 0;
5641 }
5642 
hdmi_tx_set_output_process(struct it6161 * it6161)5643 static void hdmi_tx_set_output_process(struct it6161 *it6161)
5644 {
5645 	VIDEOPCLKLEVEL level;
5646 	u32 TMDSClock;
5647 
5648 	TMDSClock = it6161->hdmi_tx_pclk * 1000 * (it6161->source_avi_infoframe.pixel_repeat + 1);
5649 
5650 	HDMITX_DisableAudioOutput(it6161);
5651 	//hdmi_tx_hdcp_reset_auth(it6161);
5652     hdmi_tx_disable_avi_infoframe(it6161);
5653     HDMITX_EnableVSInfoFrame(it6161, false,NULL);
5654 
5655 	if (TMDSClock > 80000000L) {
5656 		level = PCLK_HIGH ;
5657 	} else if(TMDSClock > 20000000L) {
5658 		level = PCLK_MEDIUM ;
5659 	} else {
5660 		level = PCLK_LOW ;
5661 	}
5662 
5663 	hdmi_tx_enable_video_output(it6161, level);
5664 
5665 	if (it6161->hdmi_mode) {
5666 #ifdef OUTPUT_3D_MODE
5667 		ConfigfHdmiVendorSpecificInfoFrame(it6161, OUTPUT_3D_MODE);
5668 #endif
5669 
5670 		hdmi_tx_avi_infoframe_process(it6161);
5671 		hdmi_tx_audio_process(it6161);
5672 
5673         // if( it6161->support_audio )
5674         // {
5675         //     ConfigAudioInfoFrm(it6161);
5676         // #ifdef SUPPORT_HBR_AUDIO
5677         //     HDMITX_EnableAudioOutput(it6161, T_AUDIO_HBR, CONFIG_INPUT_AUDIO_INTERFACE, 768000L,8,NULL,TMDSClock);
5678         // #else
5679         //     // HDMITX_EnableAudioOutput(it6161, T_AUDIO_LPCM, false, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,TMDSClock);
5680         //     HDMITX_EnableAudioOutput(it6161, CNOFIG_INPUT_AUDIO_TYPE, CONFIG_INPUT_AUDIO_INTERFACE, ulAudioSampleFS,bOutputAudioChannel,NULL,TMDSClock);
5681         // #endif
5682         // }
5683 
5684 	}
5685 
5686 #ifdef SUPPORT_CEC
5687 	it6161_hdmi_tx_change_bank(it6161, 0);
5688 	it6161_hdmi_tx_write(it6161,  0xf, 0 );
5689 	Initial_Ext_Int1();
5690 	HDMITX_CEC_Init();
5691 #endif // SUPPORT_CEC
5692 	it6161_hdmi_tx_set_av_mute(it6161, false);
5693 	bChangeMode = false ;
5694 }
5695 
5696 /*void HDMITX_ChangeAudioOption(u8 Option, u8 channelNum, u8 AudioFs)
5697 {
5698 
5699     switch(Option )
5700     {
5701     case T_AUDIO_HBR :
5702         bOutputAudioType = T_AUDIO_HBR ;
5703         ulAudioSampleFS = 768000L ;
5704         bOutputAudioChannel = 8 ;
5705         return ;
5706     case T_AUDIO_NLPCM :
5707         bOutputAudioType = T_AUDIO_NLPCM ;
5708         bOutputAudioChannel = 2 ;
5709         break ;
5710     default:
5711         bOutputAudioType = T_AUDIO_LPCM ;
5712         if( channelNum < 1 )
5713         {
5714             bOutputAudioChannel = 1 ;
5715         }
5716         else if( channelNum > 8 )
5717         {
5718             bOutputAudioChannel = 8 ;
5719         }
5720         else
5721         {
5722             bOutputAudioChannel = channelNum ;
5723         }
5724         break ;
5725     }
5726 
5727     switch(AudioFs)
5728     {
5729     case AUDFS_44p1KHz:
5730         ulAudioSampleFS =  44100L ;
5731         break ;
5732     case AUDFS_88p2KHz:
5733         ulAudioSampleFS =  88200L ;
5734         break ;
5735     case AUDFS_176p4KHz:
5736         ulAudioSampleFS = 176400L ;
5737         break ;
5738 
5739     case AUDFS_48KHz:
5740         ulAudioSampleFS =  48000L ;
5741         break ;
5742     case AUDFS_96KHz:
5743         ulAudioSampleFS =  96000L ;
5744         break ;
5745     case AUDFS_192KHz:
5746         ulAudioSampleFS = 192000L ;
5747         break ;
5748 
5749     case AUDFS_768KHz:
5750         ulAudioSampleFS = 768000L ;
5751         break ;
5752 
5753     case AUDFS_32KHz:
5754         ulAudioSampleFS =  32000L ;
5755         break ;
5756     default:
5757         ulAudioSampleFS =  48000L ;
5758         break ;
5759     }
5760     DRM_INFO("HDMITX_ChangeAudioOption():bOutputAudioType = %02X, ulAudioSampleFS = %8ld, bOutputAudioChannel = %d\n",(int)bOutputAudioType,ulAudioSampleFS,(int)bOutputAudioChannel);
5761 }
5762 */
5763 
5764 #ifdef HDMITX_AUTO_MONITOR_INPUT
5765 
HDMITX_MonitorInputAudioChange()5766 void HDMITX_MonitorInputAudioChange()
5767 {
5768     static u32 prevAudioSampleFS = 0 ;
5769     u32 AudioFS ;
5770 
5771     if( !it6161->support_audio )
5772     {
5773         prevAudioSampleFS = 0 ;
5774     }
5775     else
5776     {
5777         AudioFS = CalcAudFS() ;
5778         DRM_INFO1(("Audio Chagne, Audio clock = %dHz\n",AudioFS)) ;
5779         if( AudioFS > 188000L ) // 192KHz
5780         {
5781             ulAudioSampleFS = 192000L ;
5782         }
5783         else if( AudioFS > 144000L ) // 176.4KHz
5784         {
5785             ulAudioSampleFS = 176400L ;
5786         }
5787         else if( AudioFS >  93000L ) // 96KHz
5788         {
5789             ulAudioSampleFS = 96000L ;
5790         }
5791         else if( AudioFS >  80000L ) // 88.2KHz
5792         {
5793             ulAudioSampleFS = 88200L ;
5794         }
5795         else if( AudioFS >  45000L ) // 48 KHz
5796         {
5797             ulAudioSampleFS = 48000L ;
5798         }
5799         else if( AudioFS >  36000L ) // 44.1KHz
5800         {
5801             ulAudioSampleFS = 44100L ;
5802         }
5803         else                         // 32KHz
5804         {
5805             ulAudioSampleFS = 32000L ;
5806         }
5807 
5808         if(!bChangeMode)
5809         {
5810             if( ulAudioSampleFS != prevAudioSampleFS )
5811             {
5812                 DRM_INFO("ulAudioSampleFS = %dHz -> %dHz\n",ulAudioSampleFS,ulAudioSampleFS);
5813                 ConfigAudioInfoFrm(it6161, 2);
5814                 HDMITX_EnableAudioOutput(it6161, CNOFIG_INPUT_AUDIO_TYPE, CONFIG_INPUT_AUDIO_INTERFACE, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,0);
5815                 // HDMITX_EnableAudioOutput(it6161, T_AUDIO_LPCM, false, ulAudioSampleFS,OUTPUT_CHANNEL,NULL,0);
5816 
5817             }
5818         }
5819 
5820         prevAudioSampleFS = ulAudioSampleFS ;
5821 
5822     }
5823 }
5824 
5825 #endif // HDMITX_AUTO_MONITOR_INPUT
5826 
mipi_rx_calc_rclk(struct it6161 * it6161)5827 static void mipi_rx_calc_rclk(struct it6161 *it6161)
5828 {
5829 	u32 sum = 0, i, retry = 5;
5830 	int t10usint;
5831 
5832 	//it6161_hdmi_tx_write(it6161, 0x8D, (CEC_I2C_SLAVE_ADDR|0x01));// Enable CRCLK
5833 	for (i = 0; i < retry; i++) {
5834 		it6161_mipi_rx_set_bits(it6161, 0x94, 0x80, 0x80); // Enable RCLK 100ms count
5835 		msleep(100);
5836 		it6161_mipi_rx_set_bits(it6161, 0x94, 0x80, 0x00); // Disable RCLK 100ms count
5837 
5838 		it6161->mipi_rx_rclk = it6161_mipi_rx_read(it6161, 0x97);
5839 		it6161->mipi_rx_rclk <<= 8;
5840 		it6161->mipi_rx_rclk += it6161_mipi_rx_read(it6161, 0x96);
5841 		it6161->mipi_rx_rclk <<=8;
5842 		it6161->mipi_rx_rclk += it6161_mipi_rx_read(it6161, 0x95);
5843 		sum += it6161->mipi_rx_rclk;
5844 	}
5845 
5846 	sum /= retry;
5847 	DRM_INFO("rclk: %d\n", sum);
5848 	//it6161->mipi_rx_rclk = sum / 100;
5849 	it6161->mipi_rx_rclk = sum / 104;
5850 	t10usint = it6161->mipi_rx_rclk / 108;//actually nxp platform msleep(100) is 108ms
5851 	DRM_INFO("it6161->mipi_rx_rclk = %d,%03d,%03d\n",(sum*10)/1000000,((sum*10)%1000000)/1000,((sum*10)%100));
5852 	DRM_INFO("T10usInt=0x%03X\n", (int)t10usint);
5853 	it6161_mipi_rx_write(it6161, 0x91, t10usint&0xFF);
5854 }
5855 
mipi_rx_calc_mclk(struct it6161 * it6161)5856 static void mipi_rx_calc_mclk(struct it6161 *it6161)
5857 {
5858 	u32 i, rddata, sum = 0, calc_time = 3;
5859 
5860 	for (i = 0; i < calc_time; i++) {
5861 		it6161_mipi_rx_set_bits(it6161, 0x9B, 0x80, 0x80);
5862 		msleep(5);
5863 		it6161_mipi_rx_set_bits(it6161, 0x9B, 0x80, 0x00);
5864 
5865 		rddata = it6161_mipi_rx_read(it6161, 0x9B) & 0x0F;
5866 		rddata <<= 8;
5867 		rddata += it6161_mipi_rx_read(it6161, 0x9A);
5868 
5869 		sum += rddata;
5870 	}
5871 
5872 	sum /= calc_time;
5873 	it6161->mipi_rx_mclk = it6161->mipi_rx_rclk * 2048 / sum;
5874 	DRM_INFO("MCLK = %d.%03dMHz", it6161->mipi_rx_mclk / 1000, it6161->mipi_rx_mclk % 1000);
5875 }
5876 
mipi_rx_calc_pclk(struct it6161 * it6161)5877 static void mipi_rx_calc_pclk(struct it6161 *it6161)
5878 {
5879 	u32 rddata, sum = 0, retry = 3;
5880 	u8 i;
5881 
5882 	it6161_mipi_rx_set_bits(it6161, 0x99, 0x80, 0x00);
5883 
5884 	for (i = 0; i < retry; i++) {
5885 		it6161_mipi_rx_set_bits(it6161, 0x99, 0x80, 0x80);
5886 		msleep(5);
5887 		it6161_mipi_rx_set_bits(it6161, 0x99, 0x80, 0x00);
5888 		msleep(1);
5889 
5890 		rddata = it6161_mipi_rx_read(it6161, 0x99) & 0x0F;
5891 		rddata <<= 8;
5892 		rddata += it6161_mipi_rx_read(it6161, 0x98);
5893 		sum += rddata;
5894 	}
5895 
5896 	sum /= retry;
5897 	DRM_INFO("pclk: %d\n", sum);
5898 	it6161->mipi_rx_pclk = it6161->mipi_rx_rclk * 2048 / sum;
5899 	//it6161->mipi_rx_pclk = it6161->mipi_rx_rclk * 1960 / sum;
5900 	DRM_INFO("it6161->mipi_rx_pclk = %d.%03dMHz", it6161->mipi_rx_pclk / 1000, it6161->mipi_rx_pclk % 1000);
5901 }
5902 
mipi_rx_show_mrec(struct it6161 * it6161)5903 static void mipi_rx_show_mrec(struct it6161 *it6161)
5904 {
5905 	int m_hfront_porch, m_hsyncw, m_hback_porch, m_hactive, MHVR2nd, MHBlank;
5906 	int m_vfront_porch, m_vsyncw, m_vback_porch, m_vactive, MVFP2nd, MVTotal;
5907 
5908 
5909 	m_hfront_porch  = mipi_rx_read_word(it6161, 0x50) & 0x3FFF;
5910 	m_hsyncw  = mipi_rx_read_word(it6161, 0x52) & 0x3FFF;
5911 	m_hback_porch  = mipi_rx_read_word(it6161, 0x54) & 0x3FFF;
5912 	m_hactive  = mipi_rx_read_word(it6161, 0x56) & 0x3FFF;
5913 	MHVR2nd  = mipi_rx_read_word(it6161, 0x58) & 0x3FFF;
5914 
5915 	MHBlank = m_hfront_porch + m_hsyncw + m_hback_porch;
5916 
5917 	m_vfront_porch  = mipi_rx_read_word(it6161, 0x5A) & 0x3FFF;
5918 	m_vsyncw  = mipi_rx_read_word(it6161, 0x5C) & 0x3FFF;
5919 	m_vback_porch  = mipi_rx_read_word(it6161, 0x5E) & 0x3FFF;
5920 	m_vactive  = mipi_rx_read_word(it6161, 0x60) & 0x3FFF;
5921 	MVFP2nd  = mipi_rx_read_word(it6161, 0x62) & 0x3FFF;
5922 
5923 	MVTotal = m_vfront_porch + m_vsyncw + m_vback_porch + m_vactive ;
5924 
5925 	DRM_INFO("m_hfront_porch    = %d\n", m_hfront_porch);
5926 	DRM_INFO("m_hsyncw    = %d\n", m_hsyncw);
5927 	DRM_INFO("m_hback_porch    = %d\n", m_hback_porch);
5928 	DRM_INFO("m_hactive   = %d\n", m_hactive);
5929 	DRM_INFO("MHVR2nd = %d\n", MHVR2nd);
5930 	DRM_INFO("MHBlank  = %d\n", MHBlank);
5931 
5932 	DRM_INFO("m_vfront_porch    = %d\n", m_vfront_porch);
5933 	DRM_INFO("m_vsyncw    = %d\n", m_vsyncw);
5934 	DRM_INFO("m_vback_porch   = %d\n", m_vback_porch);
5935 	DRM_INFO("m_vactive   = %d\n", m_vactive);
5936 	DRM_INFO("MVFP2nd   = %d\n", MVFP2nd);
5937 	DRM_INFO("MVTotal = %d\n", MVTotal);
5938 }
5939 
mipi_rx_prec_get_display_mode(struct it6161 * it6161)5940 static void mipi_rx_prec_get_display_mode(struct it6161 *it6161)
5941 {
5942 	struct drm_display_mode *display_mode = &it6161->mipi_rx_p_display_mode;
5943 	struct device *dev = &it6161->i2c_hdmi_tx->dev;
5944 	int p_hfront_porch, p_hsyncw, p_hback_porch, p_hactive, p_htotal;
5945 	int p_vfront_porch, p_vsyncw, p_vback_porch, p_vactive, p_vtotal;
5946 
5947 	p_hfront_porch  = mipi_rx_read_word(it6161, 0x30) & 0x3FFF;
5948 	p_hsyncw  = mipi_rx_read_word(it6161, 0x32) & 0x3FFF;
5949 	p_hback_porch  = mipi_rx_read_word(it6161, 0x34) & 0x3FFF;
5950 	p_hactive  = mipi_rx_read_word(it6161, 0x36) & 0x3FFF;
5951 	p_htotal  = mipi_rx_read_word(it6161, 0x38) & 0x3FFF;
5952 
5953 	//p_htotal = p_hfront_porch + p_hsyncw + p_hback_porch + p_hactive ;
5954 
5955 	p_vfront_porch  = mipi_rx_read_word(it6161, 0x3A) & 0x3FFF;
5956 	p_vsyncw  = mipi_rx_read_word(it6161, 0x3C) & 0x3FFF;
5957 	p_vback_porch  = mipi_rx_read_word(it6161, 0x3E) & 0x3FFF;
5958 	p_vactive  = mipi_rx_read_word(it6161, 0x40) & 0x3FFF;
5959 	p_vtotal  = mipi_rx_read_word(it6161, 0x42) & 0x3FFF;
5960 
5961 	//p_vtotal = p_vfront_porch + p_vsyncw + p_vback_porch + p_vactive ;
5962 
5963     display_mode->clock = it6161->mipi_rx_pclk;
5964 	display_mode->hdisplay = p_hactive;
5965 	display_mode->hsync_start = p_hactive + p_hfront_porch;
5966 	display_mode->hsync_end = p_hactive + p_hfront_porch + p_hsyncw;
5967 	display_mode->htotal = p_htotal;
5968 	display_mode->vdisplay = p_vactive;
5969 	display_mode->vsync_start = p_vactive + p_vfront_porch;
5970 	display_mode->vsync_end = p_vactive + p_vfront_porch + p_vsyncw;
5971 	display_mode->vtotal = p_vtotal;
5972 
5973     DRM_DEV_DEBUG_DRIVER(dev, "mipi pixel clock: %d KHz", display_mode->clock);
5974 	DRM_INFO("p_hfront_porch    = %d\r\n", p_hfront_porch);
5975 	DRM_INFO("p_hsyncw    = %d\r\n", p_hsyncw);
5976 	DRM_INFO("p_hback_porch   = %d\r\n", p_hback_porch);
5977 	DRM_INFO("p_hactive   = %d\r\n", p_hactive);
5978 	DRM_INFO("p_htotal = %d\r\n", p_htotal);
5979 
5980 	DRM_INFO("p_vfront_porch    = %d\r\n", p_vfront_porch);
5981 	DRM_INFO("p_vsyncw    = %d\r\n", p_vsyncw);
5982 	DRM_INFO("p_vback_porch   = %d\r\n", p_vback_porch);
5983 	DRM_INFO("p_vactive   = %d\r\n", p_vactive);
5984 	DRM_INFO("p_vtotal = %d\r\n", p_vtotal);
5985 }
5986 
mipi_rx_reset_p_domain(struct it6161 * it6161)5987 static void mipi_rx_reset_p_domain(struct it6161 *it6161)
5988 {
5989 	it6161_mipi_rx_set_bits(it6161, 0x05, 0x04, 0x04);  // Video Clock Domain Reset
5990 	it6161_mipi_rx_set_bits(it6161, 0x05, 0x04, 0x00);  // Release Video Clock Domain Reset
5991 }
5992 
it6161_mipi_rx_interrupt_clear(struct it6161 * it6161,u8 reg06,u8 reg07,u8 reg08)5993 static void it6161_mipi_rx_interrupt_clear(struct it6161 *it6161, u8 reg06, u8 reg07, u8 reg08)
5994 {
5995 	it6161_mipi_rx_write(it6161, 0x06, reg06);
5996 	it6161_mipi_rx_write(it6161, 0x07, reg07);
5997 	it6161_mipi_rx_write(it6161, 0x08, reg08);
5998 	it6161_debug("mipi rx i2c read reg06:0x%02x reg07:0x%02x reg08:0x%02x",
5999 		 it6161_mipi_rx_read(it6161, 0x06), it6161_mipi_rx_read(it6161, 0x07), it6161_mipi_rx_read(it6161, 0x08));
6000 }
6001 
it6161_mipi_rx_interrupt_reg06_process(struct it6161 * it6161,u8 reg06)6002 static void it6161_mipi_rx_interrupt_reg06_process(struct it6161 *it6161, u8 reg06)
6003 {
6004 	bool m_video_stable, p_video_stable;
6005 #ifndef __linux__
6006     struct drm_display_mode *dmt_display_mode;
6007 #endif
6008     u8 data_id;
6009 
6010     if (reg06 == 0x00)
6011         return;
6012 
6013     if (reg06 & 0x01) {
6014     	m_video_stable = mipi_rx_get_m_video_stable(it6161);
6015         DRM_INFO("PPS M video stable Change Interrupt, %sstable", m_video_stable ? "" : "un");
6016 
6017         if (m_video_stable) {
6018             data_id = it6161_mipi_rx_read(it6161, 0x28);
6019             DRM_INFO("mipi receive video format: 0x%02x", data_id);
6020             mipi_rx_calc_rclk(it6161);
6021             mipi_rx_calc_mclk(it6161);
6022             mipi_rx_show_mrec(it6161);
6023             mipi_rx_afe_configuration(it6161, data_id);
6024             mipi_rx_reset_p_domain(it6161);
6025         }
6026     }
6027 
6028     if(reg06 & 0x02)
6029     {
6030         DRM_INFO("PPS MHSync error interrupt");
6031     }
6032 
6033     if(reg06 & 0x04)
6034     {
6035         DRM_INFO("PPS MHDE Error Interrupt");
6036     }
6037 
6038     if(reg06 & 0x08)
6039     {
6040         DRM_INFO("PPS MVSync Error Interrupt");
6041     }
6042 
6043     if (reg06 & 0x10) {
6044     	p_video_stable = mipi_rx_get_p_video_stable(it6161);
6045         DRM_INFO("PPS P video stable Change Interrupt, %sstable",  p_video_stable ? "" : "un");
6046 		it6161_debug("cancel restart work\n");
6047 		cancel_delayed_work(&it6161->restart);
6048 
6049         if (p_video_stable) {
6050             DRM_INFO("PVidStb Change to HIGH");
6051             mipi_rx_calc_rclk(it6161);
6052             mipi_rx_calc_pclk(it6161);
6053             mipi_rx_prec_get_display_mode(it6161);
6054             it6161->vic = drm_match_cea_mode(&it6161->mipi_rx_p_display_mode);
6055 
6056 #ifndef __linux__
6057             if (it6161->vic == 0) {
6058                 dmt_display_mode = drm_match_dmt_mode(&it6161->mipi_rx_p_display_mode);
6059 
6060                 if (dmt_display_mode)
6061                     it6161->source_display_mode = *dmt_display_mode;
6062 
6063                 DRM_INFO("%sfind dmt timing", dmt_display_mode ? "" : "not ");
6064             } else {
6065                 it6161->source_display_mode = edid_cea_modes[it6161->vic];
6066             }
6067 #endif
6068 
6069             DRM_INFO("source output vic: %d, %s cea timing", it6161->vic, it6161->vic ? " standard" : " not");
6070             show_display_mode(it6161, &it6161->source_display_mode, 0);
6071 
6072             show_display_mode(it6161, &it6161->mipi_rx_p_display_mode, 2);
6073             mipi_rx_setup_polarity(it6161);
6074             it6161_mipi_rx_write(it6161, 0xC0,(EnTxCRC<<7) +TxCRCnum);
6075             // setup 1 sec timer interrupt
6076             it6161_mipi_rx_set_bits(it6161, 0x0b,0x40, 0x40);
6077 
6078 			switch (it6161->hdmi_tx_mode) {
6079 			case HDMI_TX_BY_PASS:
6080 				it6161_hdmi_tx_set_bits(it6161, 0xA9, 0x80, 0x80);
6081 				break;
6082 
6083 			case HDMI_TX_ENABLE_DE_ONLY:
6084 				hdmi_tx_generate_blank_timing(it6161);
6085 				break;
6086 
6087 			case HDMI_TX_ENABLE_PATTERN_GENERATOR:
6088 				hdmi_tx_setup_pattern_generator(it6161);
6089 				break;
6090 
6091 			default:
6092 				DRM_INFO("use hdmi tx normal mode");
6093 				break;
6094 			}
6095 
6096 			hdmi_tx_video_reset(it6161);
6097         }
6098     }
6099 
6100     if(reg06 & 0x20)
6101     {
6102         if(DisPHSyncErr == false)
6103         {
6104             DRM_INFO("PPS PHSync Error Interrupt");
6105         }
6106     }
6107 
6108     if(reg06 & 0x40)
6109     {
6110         DRM_INFO("PPS PHDE Error Interrupt");
6111     }
6112 
6113     if(reg06 & 0x80)
6114     {
6115         DRM_INFO("PPS MVDE Error Interrupt");
6116     }
6117 }
6118 
it6161_mipi_rx_interrupt_reg07_process(struct it6161 * it6161,u8 reg07)6119 static void it6161_mipi_rx_interrupt_reg07_process(struct it6161 *it6161, u8 reg07)
6120 {
6121     if (reg07 == 0x00)
6122         return;
6123 
6124     if(reg07 & 0x01)
6125     {
6126         DRM_INFO("PatGen PPGVidStb change interrupt !!!\n");
6127     }
6128 
6129     if(reg07 & 0x02)
6130     {
6131         DRM_INFO("PPS Data Byte Error Interrupt !!!\n");
6132     }
6133 
6134     if(reg07 & 0x04)
6135     {
6136         DRM_INFO("PPS CMOff Interrupt !!!\n");
6137     }
6138 
6139     if(reg07 & 0x08)
6140     {
6141         DRM_INFO("PPS CMOn Interrupt !!!\n");
6142     }
6143 
6144     if(reg07 & 0x10)
6145     {
6146         DRM_INFO("PPS ShutDone cmd Interrupt !!! \n");
6147     }
6148 
6149     if(reg07 & 0x20)
6150     {
6151         DRM_INFO("PPS TurnOn Interrupt !!!\n");
6152     }
6153 
6154     if((reg07 & 0x40) || (reg07 & 0x80))
6155     {
6156          if( reg07&0x40 ) {
6157              DRM_INFO("PPS FIFO over read Interrupt !!! tx video stable:%d", hdmi_tx_get_video_state(it6161));
6158              it6161_mipi_rx_set_bits(it6161, 0x07, 0x40, 0x40);
6159          }
6160          if( reg07&0x80 ) {
6161              DRM_INFO("PPS FIFO over write Interrupt !!!\n");
6162              it6161_mipi_rx_set_bits(it6161, 0x07, 0x80, 0x80);
6163          }
6164     }
6165 }
6166 
it6161_mipi_rx_interrupt_reg08_process(struct it6161 * it6161,u8 reg08)6167 static void it6161_mipi_rx_interrupt_reg08_process(struct it6161 *it6161, u8 reg08)
6168 {
6169     int crc;
6170 
6171     if (reg08 == 0x00)
6172         return;
6173 
6174     if(reg08 & 0x01)
6175     {
6176         if(DisECCErr == false)
6177         {
6178             DRM_INFO("ECC 1-bit Error Interrupt !!!\n");
6179         }
6180     }
6181 
6182     if(reg08 & 0x02)
6183     {
6184         if(DisECCErr == false)
6185         {
6186             DRM_INFO("ECC 2-bit Error Interrupt !!!\n");
6187         }
6188     }
6189 
6190     if(reg08 & 0x04)
6191     {
6192         DRM_INFO("LM FIFO Error Interrupt !!!\n");
6193     }
6194 
6195     if(reg08 & 0x08)
6196     {
6197         DRM_INFO("CRC Error Interrupt !!!\n");
6198     }
6199 
6200     if(reg08 & 0x10)
6201     {
6202         DRM_INFO("MCLK Off Interrupt !!!\n");
6203         //DRM_INFO("setP1_6 High Mipi not Stable\n");
6204         //P1_6=1;
6205     }
6206 
6207     if(reg08 & 0x20)
6208     {
6209         DRM_INFO("PPI FIFO OverWrite Interrupt !!!\n");
6210     }
6211 
6212     if(reg08 & 0x40)
6213     {
6214         DRM_INFO("FW Timer Interrupt !!!\n");
6215         it6161_mipi_rx_set_bits(it6161, 0x0b, 0x40, 0x00);
6216 
6217         if((it6161_mipi_rx_read(it6161, 0xC1)&0x03) == 0x03)
6218         {
6219             DRM_INFO("CRC Fail !!!\n");
6220         }
6221         if((it6161_mipi_rx_read(it6161, 0xC1)&0x05) == 0x05)
6222         {
6223             DRM_INFO("CRC Pass !!!\n");
6224             crc = it6161_mipi_rx_read(it6161, 0xC2) + (it6161_mipi_rx_read(it6161, 0xC3) <<8);
6225             DRM_INFO("CRCR = 0x%x !!!\n" , crc);
6226             crc = it6161_mipi_rx_read(it6161, 0xC4) + (it6161_mipi_rx_read(it6161, 0xC5) <<8);
6227             DRM_INFO("CRCG = 0x%x !!!\n" , crc);
6228             crc = it6161_mipi_rx_read(it6161, 0xC6) + (it6161_mipi_rx_read(it6161, 0xC7) <<8);
6229             DRM_INFO("CRCB = 0x%x !!!\n" , crc);
6230         }
6231     }
6232 }
6233 
it6161_hdmi_tx_interrupt_clear(struct it6161 * it6161,u8 reg06,u8 reg07,u8 reg08,u8 regee)6234 static void it6161_hdmi_tx_interrupt_clear(struct it6161 *it6161, u8 reg06, u8 reg07, u8 reg08, u8 regee)
6235 {
6236 	u8 int_clear;
6237 
6238 	if(reg06 & B_TX_INT_AUD_OVERFLOW) {
6239 		DRM_INFO("B_TX_INT_AUD_OVERFLOW");
6240 		it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST,(B_HDMITX_AUD_RST|B_TX_AREF_RST), (B_HDMITX_AUD_RST|B_TX_AREF_RST));
6241 		it6161_hdmi_tx_set_bits(it6161, REG_TX_SW_RST, B_HDMITX_AUD_RST|B_TX_AREF_RST, 0x00);
6242 		//AudioDelayCnt=AudioOutDelayCnt;
6243 		//LastRefaudfreqnum=0;
6244 	}
6245 
6246 	if(reg06 & B_TX_INT_DDCFIFO_ERR) {
6247 		DRM_INFO("DDC FIFO Error");
6248 		it6161_hdmi_tx_clear_ddc_fifo(it6161);
6249 		hdmiTxDev[0].bAuthenticated= false ;
6250 	}
6251 
6252 	if(reg06 & B_TX_INT_DDC_BUS_HANG) {
6253 		DRM_INFO("DDC BUS HANG");
6254 		it6161_hdmi_tx_abort_ddc(it6161);
6255 
6256         	if (hdmiTxDev[0].bAuthenticated) {
6257 			DRM_INFO("when DDC hang,and aborted DDC,the HDCP authentication need to restart");
6258 #ifndef _SUPPORT_HDCP_REPEATER_
6259 #ifdef ENABLE_HDCP
6260 			hdmitx_hdcp_ResumeAuthentication(it6161);
6261 #endif
6262 #else
6263 			TxHDCP_chg(TxHDCP_AuthFail);
6264 #endif
6265 		}
6266 	}
6267 
6268 	/* clear ext interrupt */
6269 	it6161_hdmi_tx_write(it6161, 0xEE, regee);
6270 	it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR0, 0xFF);
6271 	it6161_hdmi_tx_write(it6161, REG_TX_INT_CLR1, 0xFF);
6272 	/* write B_TX_INTACTDONE '1' to trigger clear interrupt */
6273 	int_clear = (it6161_hdmi_tx_read(it6161, REG_TX_SYS_STATUS)) | B_TX_CLR_AUD_CTS | B_TX_INTACTDONE ;
6274 	it6161_hdmi_tx_write(it6161, REG_TX_SYS_STATUS, int_clear);
6275 
6276 	it6161_debug("hdmi tx i2c read reg06:0x%02x reg07:0x%02x reg08:0x%02x regee:0x%02x", it6161_hdmi_tx_read(it6161, 0x06), it6161_hdmi_tx_read(it6161, 0x07), it6161_hdmi_tx_read(it6161, 0x08), it6161_hdmi_tx_read(it6161, 0xEE));
6277 }
6278 
it6161_hdmi_tx_interrupt_reg06_process(struct it6161 * it6161,u8 reg06)6279 static void it6161_hdmi_tx_interrupt_reg06_process(struct it6161 *it6161, u8 reg06)
6280 {
6281     //struct device *dev = &it6161->i2c_mipi_rx->dev;
6282 	u8 ret;//, reg0e = it6161_hdmi_tx_read(it6161, 0x0e);
6283 
6284 	if(reg06 & B_TX_INT_HPD_PLUG) {
6285 		drm_helper_hpd_irq_event(it6161->connector.dev);
6286 		if(hdmi_tx_get_sink_hpd(it6161)) {
6287 			DRM_INFO("hpd on");
6288 			ret = wait_for_completion_timeout(&it6161->wait_edid_complete, msecs_to_jiffies(2000));
6289 
6290 			if (ret == 0)
6291 				DRM_INFO("wait edid timeout");
6292 
6293 			it6161->hdmi_tx_output_color_space = OUTPUT_COLOR_MODE;
6294 			it6161->hdmi_tx_input_color_space = INPUT_COLOR_MODE;
6295 			hdmi_tx_set_capability_from_edid_parse(it6161);
6296 			reinit_completion(&it6161->wait_hdcp_event);
6297 			hdmi_tx_video_reset(it6161);
6298 
6299 			bChangeMode=true;
6300 			// 1. not only HDMI but DVI need the set the upstream HPD
6301 			// 2. Before set upstream HPD , the EDID must be ready.
6302 		} else {
6303 			DRM_INFO("hpd off");
6304 			hdmi_tx_disable_video_output(it6161);
6305 			kfree(it6161->edid);
6306 			it6161->edid = NULL;
6307 
6308 			if (it6161->hdmi_tx_mode == HDMI_TX_ENABLE_PATTERN_GENERATOR)
6309 				hdmi_tx_disable_pattern_generator(it6161);
6310         }
6311     }
6312 
6313     if (reg06 & B_TX_INT_RX_SENSE) {
6314         DRM_INFO("rx sense interrupt");
6315         hdmiTxDev[0].bAuthenticated = false;
6316     }
6317 }
6318 
it6161_hdmi_tx_interrupt_reg07_process(struct it6161 * it6161,u8 reg07)6319 static void it6161_hdmi_tx_interrupt_reg07_process(struct it6161 *it6161, u8 reg07)
6320 {
6321 	bool video_state = hdmi_tx_get_video_state(it6161);
6322 
6323 	if(reg07 & B_TX_INT_AUTH_DONE) {
6324 		DRM_INFO("hdmi tx authenticate done interrupt");
6325 		hdmi_tx_hdcp_int_mask_disable(it6161);
6326 		hdmiTxDev[0].bAuthenticated = true ;
6327 		it6161_hdmi_tx_set_av_mute(it6161, false);
6328 		complete(&it6161->wait_hdcp_event);
6329 	}
6330 	if(reg07 & B_TX_INT_AUTH_FAIL) {
6331 		hdmiTxDev[0].bAuthenticated = false;
6332 		DRM_INFO("hdmi tx interrupt authenticate fail reg46:0x%02x, start HDCP again", it6161_hdmi_tx_read(it6161, 0x46));
6333 		complete(&it6161->wait_hdcp_event);
6334 #ifdef ENABLE_HDCP
6335 		hdmi_tx_enable_hdcp(it6161);
6336 #ifdef _SUPPORT_HDCP_REPEATER_
6337 		TxHDCP_chg(TxHDCP_AuthFail) ;
6338 #endif
6339 #endif
6340 	}
6341 
6342 	if(reg07 & B_TX_INT_KSVLIST_CHK ) {
6343 		DRM_INFO("ksv list event interrupt");
6344 		schedule_work(&it6161->wait_hdcp_ksv_list);
6345 	}
6346 
6347 	if (reg07 & B_TX_INT_VID_UNSTABLE) {
6348 		if (!video_state)
6349 			DRM_INFO("hdmi tx interrupt video unstable!");
6350 	}
6351 }
6352 
it6161_hdmi_tx_interrupt_reg08_process(struct it6161 * it6161,u8 reg08)6353 static void it6161_hdmi_tx_interrupt_reg08_process(struct it6161 *it6161, u8 reg08)
6354 {
6355 	if (reg08 & B_TX_INT_VIDSTABLE) {
6356 		it6161_hdmi_tx_write(it6161, REG_TX_INT_STAT3, reg08);
6357 			if (hdmi_tx_get_video_state(it6161)) {
6358 				DRM_INFO("hdmi tx interrupt video stable link status:%d, rx reg0d:0x%02x start HDCP", getHDMITX_LinkStatus(), it6161_mipi_rx_read(it6161, 0x0D));
6359 				hdmi_tx_get_display_mode(it6161);
6360                 show_display_mode(it6161, &it6161->source_display_mode, 0);
6361                 show_display_mode(it6161, &it6161->hdmi_tx_display_mode, 1);
6362                 hdmi_tx_set_output_process(it6161);
6363 #ifdef ENABLE_HDCP
6364 				hdmi_tx_enable_hdcp(it6161);
6365 #endif
6366 			}
6367 	}
6368 }
6369 
it6161_hdmi_tx_interrupt_regee_process(struct it6161 * it6161,u8 regee)6370 static void it6161_hdmi_tx_interrupt_regee_process(struct it6161 *it6161, u8 regee)
6371 {
6372 	if (regee != 0x00) {
6373 		DRM_INFO("%s%s%s%s%s%s%s",
6374 			(regee & 0x40) ? "video parameter change ":"",
6375 			(regee & 0x20) ? "HDCP Pj check done ":"",
6376 			(regee & 0x10) ? "HDCP Ri check done ":"",
6377 			(regee & 0x8) ? "DDC bus hang ":"",
6378 			(regee & 0x4) ? "Video input FIFO auto reset ":"",
6379 			(regee & 0x2) ? "No audio input interrupt  ":"",
6380 			(regee & 0x1) ? "Audio decode error interrupt ":"");
6381 	}
6382 }
6383 
it6161_intp_threaded_handler(int unused,void * data)6384 static irqreturn_t it6161_intp_threaded_handler(int unused, void *data)
6385 {
6386 	struct it6161 *it6161 = data;
6387 	//struct device *dev = &it6161->i2c_mipi_rx->dev;
6388 	u8 mipi_rx_reg06, mipi_rx_reg07, mipi_rx_reg08, mipi_rx_reg0d;
6389 	u8 hdmi_tx_reg06, hdmi_tx_reg07, hdmi_tx_reg08, hdmi_tx_regee, hdmi_tx_reg0e;
6390 	//it6161_dump = data;
6391 
6392 	if (it6161->enable_drv_hold)
6393 		goto unlock;
6394 
6395 	mipi_rx_reg06 = it6161_mipi_rx_read(it6161, 0x06);
6396 	mipi_rx_reg07 = it6161_mipi_rx_read(it6161, 0x07);
6397 	mipi_rx_reg08 = it6161_mipi_rx_read(it6161, 0x08);
6398 	mipi_rx_reg0d = it6161_mipi_rx_read(it6161, 0x0D);
6399 
6400 	hdmi_tx_reg06 = it6161_hdmi_tx_read(it6161, 0x06);
6401 	hdmi_tx_reg07 = it6161_hdmi_tx_read(it6161, 0x07);
6402 	hdmi_tx_reg08 = it6161_hdmi_tx_read(it6161, 0x08);
6403 	hdmi_tx_reg0e = it6161_hdmi_tx_read(it6161, 0x0E);
6404 	hdmi_tx_regee = it6161_hdmi_tx_read(it6161, 0xEE);
6405 
6406     if ((mipi_rx_reg06 != 0) || (mipi_rx_reg07 != 0) || (mipi_rx_reg08 != 0)) {
6407         it6161_debug("rx reg06: 0x%02x reg07:0x%02x reg08:0x%02x reg0d:0x%02x", mipi_rx_reg06, mipi_rx_reg07, mipi_rx_reg08, mipi_rx_reg0d);
6408         it6161_mipi_rx_interrupt_clear(it6161, mipi_rx_reg06, mipi_rx_reg07, mipi_rx_reg08);
6409     }
6410 
6411     if ((hdmi_tx_reg06 != 0) || (hdmi_tx_reg07 != 0) || (hdmi_tx_reg08 != 0)) {
6412         it6161_debug("tx reg06: 0x%02x reg07: 0x%02x reg08: 0x%02x reg0e: 0x%02x regee: 0x%02x", hdmi_tx_reg06, hdmi_tx_reg07, hdmi_tx_reg08, hdmi_tx_reg0e, hdmi_tx_regee);
6413         it6161_hdmi_tx_interrupt_clear(it6161, hdmi_tx_reg06, hdmi_tx_reg07, hdmi_tx_reg08, hdmi_tx_regee);
6414     }
6415 
6416     it6161_mipi_rx_interrupt_reg08_process(it6161, mipi_rx_reg08);
6417 	it6161_mipi_rx_interrupt_reg06_process(it6161, mipi_rx_reg06);
6418 	it6161_mipi_rx_interrupt_reg07_process(it6161, mipi_rx_reg07);
6419 	it6161_hdmi_tx_interrupt_reg06_process(it6161, hdmi_tx_reg06);
6420 	it6161_hdmi_tx_interrupt_reg07_process(it6161, hdmi_tx_reg07);
6421 	it6161_hdmi_tx_interrupt_reg08_process(it6161, hdmi_tx_reg08);
6422 	it6161_hdmi_tx_interrupt_regee_process(it6161, hdmi_tx_regee);
6423 	it6161_debug("end %s", __func__);
6424 
6425 unlock:
6426 	return IRQ_HANDLED;
6427 }
6428 
mipirx_restart(struct work_struct * work)6429 static void mipirx_restart(struct work_struct *work)
6430 {
6431 	it6161_debug("****it6161: %s\n", __func__);
6432 	it6161_bridge_enable(it6161_bridge);
6433 }
6434 
6435 #if 0
6436 static ssize_t enable_drv_hold_show(struct device *dev,
6437 				    struct device_attribute *attr, char *buf)
6438 {
6439 	struct it6161 *it6161 = dev_get_drvdata(dev);
6440 
6441 	return scnprintf(buf, PAGE_SIZE, "drv_hold: %d\n", it6161->enable_drv_hold);
6442 }
6443 
6444 static ssize_t enable_drv_hold_store(struct device *dev,
6445 				     struct device_attribute *attr,
6446 				     const char *buf, size_t count)
6447 {
6448 	struct it6161 *it6161 = dev_get_drvdata(dev);
6449 	unsigned int drv_hold;
6450 
6451 	if (kstrtoint(buf, 10, &drv_hold) < 0)
6452 		return -EINVAL;
6453 
6454 	it6161->enable_drv_hold = !!drv_hold;
6455 
6456 	if (it6161->enable_drv_hold) {
6457 		it6161_mipi_rx_int_mask_disable(it6161);
6458 		it6161_hdmi_tx_int_mask_disable(it6161);
6459 	} else {
6460 		it6161_mipi_rx_interrupt_clear(it6161, 0xFF, 0xFF, 0xFF);
6461 		it6161_hdmi_tx_interrupt_clear(it6161, 0xFF, 0xFF, 0xFF, 0xFF);
6462 		it6161_mipi_rx_int_mask_enable(it6161);
6463 		it6161_hdmi_tx_int_mask_enable(it6161);
6464 	}
6465 	return count;
6466 }
6467 
6468 static ssize_t hdmi_output_color_space_store(struct device *dev,
6469 					     struct device_attribute *attr,
6470 					     const char *buf, size_t count)
6471 {
6472 	struct it6161 *it6161 = dev_get_drvdata(dev);
6473 
6474 	DRM_INFO("config color space: %s", buf);
6475 	it6161->hdmi_tx_output_color_space &= ~F_MODE_CLRMOD_MASK;
6476 
6477 	if (strncmp(buf, "ycbcr444", strlen(buf) - 1) == 0 || strncmp(buf, "yuv444", strlen(buf) - 1) == 0) {
6478 		it6161->hdmi_tx_output_color_space |= F_MODE_YUV444;
6479 		goto end;
6480 	}
6481 
6482 	if (strncmp(buf, "ycbcr422", strlen(buf) - 1) == 0 || strncmp(buf, "yuv422", strlen(buf) - 1) == 0) {
6483 		it6161->hdmi_tx_output_color_space |= F_MODE_YUV422;
6484 		goto end;
6485 	}
6486 
6487 	if (strncmp(buf, "rgb444", strlen(buf) - 1) == 0) {
6488 		it6161->hdmi_tx_output_color_space |= F_MODE_RGB444;
6489 		goto end;
6490 	}
6491 
6492 	DRM_INFO("not support this color space, only support ycbcr444/yuv444, ycbcr422/yuv422, rgb444");
6493 	return count;
6494 
6495 end:
6496 	DRM_INFO("config color space: %s value:0x%02x", buf, it6161->hdmi_tx_output_color_space);
6497 	return count;
6498 }
6499 
6500 static ssize_t hdmi_output_color_space_show(struct device *dev,
6501 					    struct device_attribute *attr, char *buf)
6502 {
6503 	struct it6161 *it6161 = dev_get_drvdata(dev);
6504 	char *str = buf, *end = buf + PAGE_SIZE;
6505 
6506 	str += scnprintf(str, end - str, "it6161->hdmi_tx_output_color_space:%d\n", it6161->hdmi_tx_output_color_space);
6507 
6508 	return str - buf;
6509 }
6510 #endif
6511 
6512 #if 0
6513 static ssize_t print_timing_show(struct device *dev,
6514 				 struct device_attribute *attr, char *buf)
6515 {
6516 	struct it6161 *it6161 = dev_get_drvdata(dev);
6517 	struct drm_display_mode *vid = &it6161->source_display_mode;
6518 	char *str = buf, *end = buf + PAGE_SIZE;
6519 
6520 	str += scnprintf(str, end - str, "---video timing---\n");
6521 	str += scnprintf(str, end - str, "PCLK:%d.%03dMHz\n", vid->clock / 1000,
6522 			 vid->clock % 1000);
6523 	str += scnprintf(str, end - str, "HTotal:%d\n", vid->htotal);
6524 	str += scnprintf(str, end - str, "HActive:%d\n", vid->hdisplay);
6525 	str += scnprintf(str, end - str, "HFrontPorch:%d\n",
6526 			 vid->hsync_start - vid->hdisplay);
6527 	str += scnprintf(str, end - str, "HSyncWidth:%d\n",
6528 			 vid->hsync_end - vid->hsync_start);
6529 	str += scnprintf(str, end - str, "HBackPorch:%d\n",
6530 			 vid->htotal - vid->hsync_end);
6531 	str += scnprintf(str, end - str, "VTotal:%d\n", vid->vtotal);
6532 	str += scnprintf(str, end - str, "VActive:%d\n", vid->vdisplay);
6533 	str += scnprintf(str, end - str, "VFrontPorch:%d\n",
6534 			 vid->vsync_start - vid->vdisplay);
6535 	str += scnprintf(str, end - str, "VSyncWidth:%d\n",
6536 			 vid->vsync_end - vid->vsync_start);
6537 	str += scnprintf(str, end - str, "VBackPorch:%d\n",
6538 			 vid->vtotal - vid->vsync_end);
6539 
6540 	return str - buf;
6541 }
6542 
6543 static ssize_t sha_debug_show(struct device *dev, struct device_attribute *attr,
6544 			      char *buf)
6545 {
6546 	int i = 0;
6547 	char *str = buf, *end = buf + PAGE_SIZE;
6548 	struct it6161 *it6161 = dev_get_drvdata(dev);
6549 
6550 	str += scnprintf(str, end - str, "sha input:\n");
6551 	for (i = 0; i < ARRAY_SIZE(it6161->sha1_input); i += 16)
6552 		str += scnprintf(str, end - str, "%16ph\n",
6553 				 it6161->sha1_input + i);
6554 
6555 	str += scnprintf(str, end - str, "av:\n");
6556 	for (i = 0; i < ARRAY_SIZE(it6161->av); i++)
6557 		str += scnprintf(str, end - str, "%4ph\n", it6161->av[i]);
6558 
6559 	str += scnprintf(str, end - str, "bv:\n");
6560 	for (i = 0; i < ARRAY_SIZE(it6161->bv); i++)
6561 		str += scnprintf(str, end - str, "%4ph\n", it6161->bv[i]);
6562 
6563 	return end - str;
6564 }
6565 
6566 static ssize_t enable_hdcp_show(struct device *dev,
6567 				struct device_attribute *attr, char *buf)
6568 {
6569 	struct it6161 *it6161 = dev_get_drvdata(dev);
6570 
6571 	return scnprintf(buf, PAGE_SIZE, "%d\n", it6161->enable_hdcp);
6572 }
6573 
6574 static ssize_t enable_hdcp_store(struct device *dev,
6575 				 struct device_attribute *attr,
6576 				 const char *buf, size_t count)
6577 {
6578 	struct it6161 *it6161 = dev_get_drvdata(dev);
6579 	unsigned int reg3f, hdcp;
6580 
6581 	if (kstrtoint(buf, 10, &hdcp) < 0)
6582 		return -EINVAL;
6583 
6584 	if (!it6161->powered || it6161->state == SYS_UNPLUG) {
6585 		DRM_DEV_DEBUG_DRIVER(dev,
6586 				     "power down or unplug, can not fire HDCP");
6587 		return -EINVAL;
6588 	}
6589 	it6161->enable_hdcp = hdcp ? true : false;
6590 
6591 	if (it6161->enable_hdcp) {
6592 		if (it6161->cp_capable) {
6593 			dptx_sys_chg(it6161, SYS_HDCP);
6594 			dptx_sys_fsm(it6161);
6595 		} else {
6596 			DRM_DEV_ERROR(dev, "sink not support HDCP");
6597 		}
6598 	} else {
6599 		dptx_set_bits(it6161, 0x05, 0x10, 0x10);
6600 		dptx_set_bits(it6161, 0x05, 0x10, 0x00);
6601 		reg3f = dptx_read(it6161, 0x3F);
6602 		hdcp = (reg3f & BIT(7)) >> 7;
6603 		DRM_DEV_DEBUG_DRIVER(dev, "%s to disable hdcp",
6604 				     hdcp ? "failed" : "succeeded");
6605 	}
6606 	return count;
6607 }
6608 
6609 static ssize_t force_pwronoff_store(struct device *dev,
6610 				    struct device_attribute *attr,
6611 				    const char *buf, size_t count)
6612 {
6613 	struct it6161 *it6161 = dev_get_drvdata(dev);
6614 	int pwr;
6615 
6616 	if (kstrtoint(buf, 10, &pwr) < 0)
6617 		return -EINVAL;
6618 	if (pwr)
6619 		it6161_poweron(it6161);
6620 	else
6621 		it6161_poweroff(it6161);
6622 	return count;
6623 }
6624 
6625 static ssize_t pwr_state_show(struct device *dev,
6626 			      struct device_attribute *attr, char *buf)
6627 {
6628 	struct it6161 *it6161 = dev_get_drvdata(dev);
6629 
6630 	return scnprintf(buf, PAGE_SIZE, "%d\n", it6161->powered);
6631 }
6632 
6633 static DEVICE_ATTR_RO(print_timing);
6634 static DEVICE_ATTR_RO(pwr_state);
6635 static DEVICE_ATTR_RO(sha_debug);
6636 static DEVICE_ATTR_WO(force_pwronoff);
6637 static DEVICE_ATTR_RW(enable_hdcp);
6638 
6639 static const struct attribute *it6161_attrs[] = {
6640 	&dev_attr_enable_drv_hold.attr,
6641 	&dev_attr_print_timing.attr,
6642 	&dev_attr_sha_debug.attr,
6643 	&dev_attr_enable_hdcp.attr,
6644 	&dev_attr_force_pwronoff.attr,
6645 	&dev_attr_pwr_state.attr,
6646 	NULL,
6647 };
6648 
6649 static void it6161_shutdown(struct i2c_client *i2c_mipi_rx)
6650 {
6651 	struct it6161 *it6161 = dev_get_drvdata(&i2c_mipi_rx->dev);
6652 
6653 	dptx_sys_chg(it6161, SYS_UNPLUG);
6654 }
6655 
6656 #endif
6657 
6658 #if 0
6659 static DEVICE_ATTR_RW(enable_drv_hold);
6660 static DEVICE_ATTR_RW(hdmi_output_color_space);
6661 
6662 static const struct attribute *it6161_attrs[] = {
6663 	&dev_attr_enable_drv_hold.attr,
6664 	&dev_attr_hdmi_output_color_space.attr,
6665 	NULL,
6666 };
6667 #endif
it6161_parse_dt(struct it6161 * it6161,struct device_node * np)6668 static int it6161_parse_dt(struct it6161 *it6161, struct device_node *np)
6669 {
6670     //struct device *dev = &adv->i2c_mipi_rx->dev;
6671 
6672     it6161->host_node = of_graph_get_remote_node(np, 0, 0);
6673     if (!it6161->host_node) {
6674         DRM_INFO("no host node");
6675         return -ENODEV;
6676     }
6677 	DRM_INFO("%s", __func__);
6678     of_node_put(it6161->host_node);
6679 
6680     return 0;
6681 }
6682 
it6161_gpio_init(struct it6161 * it6161)6683 static int it6161_gpio_init(struct it6161 *it6161)
6684 {
6685 	struct device *dev = it6161->dev;
6686 
6687 	it6161->enable_gpio = devm_gpiod_get_optional(dev, "enable",
6688 						      GPIOD_OUT_LOW);
6689 	if (IS_ERR(it6161->enable_gpio)) {
6690 		dev_err(dev, "failed to acquire enable gpio\n");
6691 		return PTR_ERR(it6161->enable_gpio);
6692 	}
6693 
6694 	it6161->test_gpio = devm_gpiod_get_optional(dev, "test",
6695 						      GPIOD_OUT_LOW);
6696 	if (IS_ERR(it6161->test_gpio)) {
6697 		dev_info(dev, "failed to acquire test gpio\n");
6698 	}
6699 
6700 	msleep(20);
6701 	gpiod_set_value_cansleep(it6161->enable_gpio, 1);
6702 	msleep(20);
6703 
6704 	return 0;
6705 }
6706 
it6161_i2c_probe(struct i2c_client * i2c_mipi_rx,const struct i2c_device_id * id)6707 static int it6161_i2c_probe(struct i2c_client *i2c_mipi_rx,
6708 			    const struct i2c_device_id *id)
6709 {
6710 	//struct it6161 *it6161;
6711 	struct device *dev = &i2c_mipi_rx->dev;
6712 	int err, intp_irq;
6713 
6714 	it6161 = devm_kzalloc(dev, sizeof(*it6161), GFP_KERNEL);
6715 	if (!it6161)
6716 		return -ENOMEM;
6717 
6718 	it6161_bridge = devm_kzalloc(dev, sizeof(*it6161), GFP_KERNEL);
6719 	if (!it6161_bridge)
6720 		return -ENOMEM;
6721 
6722 	it6161->i2c_mipi_rx = i2c_mipi_rx;
6723 	it6161->dev = &i2c_mipi_rx->dev;
6724 	// mutex_init(&it6161->lock);
6725 	mutex_init(&it6161->mode_lock);
6726 	//init_completion(&it6161->wait_hdcp_event);
6727 	init_completion(&it6161->wait_edid_complete);
6728 
6729 	//INIT_DELAYED_WORK(&it6161->hdcp_work, hdmi_tx_hdcp_work);
6730 	//INIT_WORK(&it6161->wait_hdcp_ksv_list, hdmi_tx_hdcp_auth_part2_process);
6731 	// init_waitqueue_head(&it6161->edid_wait);
6732 
6733 	/* set up mipirx restart work*/
6734 	INIT_DELAYED_WORK(&it6161->restart, mipirx_restart);
6735 
6736 	it6161->bridge.of_node = i2c_mipi_rx->dev.of_node;
6737 
6738 	it6161_parse_dt(it6161, dev->of_node);
6739 	it6161_gpio_init(it6161);
6740 
6741 	it6161->regmap_mipi_rx =
6742 		devm_regmap_init_i2c(i2c_mipi_rx, &it6161_mipi_rx_bridge_regmap_config);
6743 	if (IS_ERR(it6161->regmap_mipi_rx)) {
6744 		DRM_DEV_ERROR(dev, "regmap_mipi_rx i2c init failed");
6745 		return PTR_ERR(it6161->regmap_mipi_rx);
6746 	}
6747 
6748 	if (device_property_read_u32(dev, "it6161-addr-hdmi-tx", &it6161->it6161_addr_hdmi_tx) < 0)
6749 		it6161->it6161_addr_hdmi_tx = 0x4c;
6750 
6751 	it6161->i2c_hdmi_tx = i2c_new_dummy_device(i2c_mipi_rx->adapter, it6161->it6161_addr_hdmi_tx);
6752 	if (IS_ERR(it6161->i2c_hdmi_tx)) {
6753 		DRM_DEV_ERROR(dev, "Failed to register it6161 I2C device\n");
6754 		return PTR_ERR(it6161->i2c_hdmi_tx);
6755 	}
6756 
6757 	it6161->regmap_hdmi_tx =
6758 		devm_regmap_init_i2c(it6161->i2c_hdmi_tx, &it6161_hdmi_tx_bridge_regmap_config);
6759 
6760 	if (IS_ERR(it6161->regmap_hdmi_tx)) {
6761 		DRM_DEV_ERROR(dev, "regmap_hdmi_tx i2c init failed");
6762 		err = PTR_ERR(it6161->regmap_hdmi_tx);
6763 		goto err_hdmitx;
6764 	}
6765 
6766 	if (device_property_read_u32(dev, "it6161-addr-cec", &it6161->it6161_addr_cec) < 0)
6767 		it6161->it6161_addr_cec = 0x4E;
6768 
6769 	it6161->i2c_cec = i2c_new_dummy_device(i2c_mipi_rx->adapter, it6161->it6161_addr_cec);
6770 	if (IS_ERR(it6161->i2c_cec)) {
6771 		DRM_DEV_ERROR(dev, "i2c_cec init failed");
6772 		err = PTR_ERR(it6161->i2c_cec);
6773 		goto  err_hdmitx;
6774 	}
6775 
6776 	it6161->regmap_cec =
6777 		devm_regmap_init_i2c(it6161->i2c_cec, &it6161_cec_bridge_regmap_config);
6778 
6779 	if (IS_ERR(it6161->regmap_cec)) {
6780 		DRM_DEV_ERROR(dev, "regmap_cec i2c init failed");
6781 		err = PTR_ERR(it6161->regmap_cec);
6782 		goto err_cec;
6783 	}
6784 
6785 	if (!it6161_check_device_ready(it6161)) {
6786 		err =  -ENODEV;
6787 		goto err_cec;
6788 	}
6789 
6790 	it6161->enable_drv_hold = DEFAULT_DRV_HOLD;
6791 	it6161_set_interrupts_active_level(HIGH);
6792 
6793 	intp_irq = i2c_mipi_rx->irq;
6794 
6795 	if (!intp_irq) {
6796 		DRM_DEV_ERROR(dev, "it6112 failed to get INTP IRQ");
6797 		err = -ENODEV;
6798 		goto err_cec;
6799 	}
6800 
6801 	err = devm_request_threaded_irq(&i2c_mipi_rx->dev, intp_irq, NULL,
6802 					/*it6161_intp_threaded_handler,*/it6161_intp_threaded_handler,
6803 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
6804 					"it6161-intp", it6161);
6805 	if (err) {
6806 		DRM_DEV_ERROR(dev, "it6112 failed to request INTP threaded IRQ: %d",
6807 			      err);
6808 		goto err_cec;
6809 	}
6810 
6811 	i2c_set_clientdata(i2c_mipi_rx, it6161);
6812 	it6161->bridge.funcs = &it6161_bridge_funcs;
6813 	drm_bridge_add(&it6161->bridge);
6814 
6815 	return 0;
6816 
6817 err_cec:
6818 	i2c_unregister_device(it6161->i2c_cec);
6819 err_hdmitx:
6820 	i2c_unregister_device(it6161->i2c_hdmi_tx);
6821 
6822 	return err;
6823 }
6824 
6825 #if 0
6826 static int it6161_remove(struct i2c_client *i2c_mipi_rx)
6827 {
6828 	struct it6161 *it6161 = i2c_get_clientdata(i2c_mipi_rx);
6829 
6830 	drm_connector_unregister(&it6161->connector);
6831 	drm_connector_cleanup(&it6161->connector);
6832 	drm_bridge_remove(&it6161->bridge);
6833 	// sysfs_remove_files(&i2c_mipi_rx->dev.kobj, it6161_attrs);
6834 	// drm_dp_aux_unregister(&it6161->aux);
6835 	// it6161_poweroff(it6161);
6836 	return 0;
6837 }
6838 #endif
6839 static const struct i2c_device_id it6161_id[] = {
6840 	{ "it6161", 0 },
6841 	{ }
6842 };
6843 
6844 MODULE_DEVICE_TABLE(i2c, it6161_id);
6845 
6846 static const struct of_device_id it6161_of_match[] = {
6847 	{ .compatible = "ite,it6161" },
6848 	{ }
6849 };
6850 
6851 static struct i2c_driver it6161_i2c_driver = {
6852 	.driver = {
6853 		.name = "it6161_mipirx_hdmitx",
6854 		.of_match_table = it6161_of_match,
6855 		//.pm = &it6161_bridge_pm_ops,
6856 	},
6857 	.probe = it6161_i2c_probe,
6858 	//.remove = it6161_remove,
6859 	//.shutdown = it6161_shutdown,
6860 	.id_table = it6161_id,
6861 };
6862 
6863 module_i2c_driver(it6161_i2c_driver);
6864 
6865 MODULE_AUTHOR("allen chen <allen.chen@ite.com.tw>");
6866 MODULE_DESCRIPTION("it6161 HDMI Transmitter driver");
6867 MODULE_LICENSE("GPL v2");
6868