1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2014
3*4882a593Smuzhiyun * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <i2c.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #define ADV7611_I2C_ADDR 0x4c
12*4882a593Smuzhiyun #define ADV7611_RDINFO 0x2051
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun /*
15*4882a593Smuzhiyun * ADV7611 I2C Addresses in u-boot notation
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun enum {
18*4882a593Smuzhiyun CP_I2C_ADDR = 0x22,
19*4882a593Smuzhiyun DPLL_I2C_ADDR = 0x26,
20*4882a593Smuzhiyun KSV_I2C_ADDR = 0x32,
21*4882a593Smuzhiyun HDMI_I2C_ADDR = 0x34,
22*4882a593Smuzhiyun EDID_I2C_ADDR = 0x36,
23*4882a593Smuzhiyun INFOFRAME_I2C_ADDR = 0x3e,
24*4882a593Smuzhiyun CEC_I2C_ADDR = 0x40,
25*4882a593Smuzhiyun IO_I2C_ADDR = ADV7611_I2C_ADDR,
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * Global Control Registers
30*4882a593Smuzhiyun */
31*4882a593Smuzhiyun enum {
32*4882a593Smuzhiyun IO_RD_INFO_MSB = 0xea,
33*4882a593Smuzhiyun IO_RD_INFO_LSB = 0xeb,
34*4882a593Smuzhiyun IO_CEC_ADDR = 0xf4,
35*4882a593Smuzhiyun IO_INFOFRAME_ADDR = 0xf5,
36*4882a593Smuzhiyun IO_DPLL_ADDR = 0xf8,
37*4882a593Smuzhiyun IO_KSV_ADDR = 0xf9,
38*4882a593Smuzhiyun IO_EDID_ADDR = 0xfa,
39*4882a593Smuzhiyun IO_HDMI_ADDR = 0xfb,
40*4882a593Smuzhiyun IO_CP_ADDR = 0xfd,
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun int adv7611_i2c[] = CONFIG_SYS_ADV7611_I2C;
44*4882a593Smuzhiyun
adv7611_probe(unsigned int screen)45*4882a593Smuzhiyun int adv7611_probe(unsigned int screen)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun int old_bus = i2c_get_bus_num();
48*4882a593Smuzhiyun unsigned int rd_info;
49*4882a593Smuzhiyun int res = 0;
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun i2c_set_bus_num(adv7611_i2c[screen]);
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun rd_info = (i2c_reg_read(IO_I2C_ADDR, IO_RD_INFO_MSB) << 8)
54*4882a593Smuzhiyun | i2c_reg_read(IO_I2C_ADDR, IO_RD_INFO_LSB);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun if (rd_info != ADV7611_RDINFO) {
57*4882a593Smuzhiyun res = -1;
58*4882a593Smuzhiyun goto out;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /*
62*4882a593Smuzhiyun * set I2C addresses to default values
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_CEC_ADDR, CEC_I2C_ADDR << 1);
65*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_INFOFRAME_ADDR, INFOFRAME_I2C_ADDR << 1);
66*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_DPLL_ADDR, DPLL_I2C_ADDR << 1);
67*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_KSV_ADDR, KSV_I2C_ADDR << 1);
68*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_EDID_ADDR, EDID_I2C_ADDR << 1);
69*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_HDMI_ADDR, HDMI_I2C_ADDR << 1);
70*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, IO_CP_ADDR, CP_I2C_ADDR << 1);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * do magic initialization sequence from
74*4882a593Smuzhiyun * "ADV7611 Register Settings Recommendations Revision 1.5"
75*4882a593Smuzhiyun * with most registers undocumented
76*4882a593Smuzhiyun */
77*4882a593Smuzhiyun i2c_reg_write(CP_I2C_ADDR, 0x6c, 0x00);
78*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x9b, 0x03);
79*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x6f, 0x08);
80*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x85, 0x1f);
81*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x87, 0x70);
82*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x57, 0xda);
83*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x58, 0x01);
84*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x03, 0x98);
85*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x4c, 0x44);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun /*
88*4882a593Smuzhiyun * IO_REG_02, default 0xf0
89*4882a593Smuzhiyun *
90*4882a593Smuzhiyun * INP_COLOR_SPACE (IO, Address 0x02[7:4])
91*4882a593Smuzhiyun * default: 0b1111 auto
92*4882a593Smuzhiyun * set to : 0b0001 force RGB (range 0 to 255) input
93*4882a593Smuzhiyun *
94*4882a593Smuzhiyun * RGB_OUT (IO, Address 0x02[1])
95*4882a593Smuzhiyun * default: 0 YPbPr color space output
96*4882a593Smuzhiyun * set to : 1 RGB color space output
97*4882a593Smuzhiyun */
98*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, 0x02, 0x12);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /*
101*4882a593Smuzhiyun * IO_REG_03, default 0x00
102*4882a593Smuzhiyun *
103*4882a593Smuzhiyun * OP_FORMAT_SEL (IO, Address 0x03[7:0])
104*4882a593Smuzhiyun * default: 0x00 8-bit SDR ITU-656 mode
105*4882a593Smuzhiyun * set to : 0x40 24-bit 4:4:4 SDR mode
106*4882a593Smuzhiyun */
107*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, 0x03, 0x40);
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /*
110*4882a593Smuzhiyun * IO_REG_05, default 0x2c
111*4882a593Smuzhiyun *
112*4882a593Smuzhiyun * AVCODE_INSERT_EN (IO, Address 0x05[2])
113*4882a593Smuzhiyun * default: 1 insert AV codes into data stream
114*4882a593Smuzhiyun * set to : 0 do not insert AV codes into data stream
115*4882a593Smuzhiyun */
116*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, 0x05, 0x28);
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun /*
119*4882a593Smuzhiyun * IO_REG_0C, default 0x62
120*4882a593Smuzhiyun *
121*4882a593Smuzhiyun * POWER_DOWN (IO, Address 0x0C[5])
122*4882a593Smuzhiyun * default: 1 chip is powered down
123*4882a593Smuzhiyun * set to : 0 chip is operational
124*4882a593Smuzhiyun */
125*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, 0x0c, 0x42);
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /*
128*4882a593Smuzhiyun * IO_REG_15, default 0xbe
129*4882a593Smuzhiyun *
130*4882a593Smuzhiyun * TRI_SYNCS (IO, Address 0x15[3)
131*4882a593Smuzhiyun * TRI_LLC (IO, Address 0x15[2])
132*4882a593Smuzhiyun * TRI_PIX (IO, Address 0x15[1])
133*4882a593Smuzhiyun * default: 1 video output pins are tristate
134*4882a593Smuzhiyun * set to : 0 video output pins are active
135*4882a593Smuzhiyun */
136*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, 0x15, 0xb0);
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /*
139*4882a593Smuzhiyun * HDMI_REGISTER_02H, default 0xff
140*4882a593Smuzhiyun *
141*4882a593Smuzhiyun * CLOCK_TERMA_DISABLE (HDMI, Address 0x83[0])
142*4882a593Smuzhiyun * default: 1 disable termination
143*4882a593Smuzhiyun * set to : 0 enable termination
144*4882a593Smuzhiyun * Future options are:
145*4882a593Smuzhiyun * - use the chips automatic termination control
146*4882a593Smuzhiyun * - set this manually on cable detect
147*4882a593Smuzhiyun * but at the moment this seems a safe default.
148*4882a593Smuzhiyun */
149*4882a593Smuzhiyun i2c_reg_write(HDMI_I2C_ADDR, 0x83, 0xfe);
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /*
152*4882a593Smuzhiyun * HDMI_CP_CNTRL_1, default 0x01
153*4882a593Smuzhiyun *
154*4882a593Smuzhiyun * HDMI_FRUN_EN (CP, Address 0xBA[0])
155*4882a593Smuzhiyun * default: 1 Enable the free run feature in HDMI mode
156*4882a593Smuzhiyun * set to : 0 Disable the free run feature in HDMI mode
157*4882a593Smuzhiyun */
158*4882a593Smuzhiyun i2c_reg_write(CP_I2C_ADDR, 0xba, 0x00);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun /*
161*4882a593Smuzhiyun * INT1_CONFIGURATION, default 0x20
162*4882a593Smuzhiyun *
163*4882a593Smuzhiyun * INTRQ_DUR_SEL[1:0] (IO, Address 0x40[7:6])
164*4882a593Smuzhiyun * default: 00 Interrupt signal is active for 4 Xtal periods
165*4882a593Smuzhiyun * set to : 11 Active until cleared
166*4882a593Smuzhiyun *
167*4882a593Smuzhiyun * INTRQ_OP_SEL[1:0] (IO, Address 0x40[1:0])
168*4882a593Smuzhiyun * default: 00 Open drain
169*4882a593Smuzhiyun * set to : 10 Drives high when active
170*4882a593Smuzhiyun */
171*4882a593Smuzhiyun i2c_reg_write(IO_I2C_ADDR, 0x40, 0xc2);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun out:
174*4882a593Smuzhiyun i2c_set_bus_num(old_bus);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun return res;
177*4882a593Smuzhiyun }
178