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