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