3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <gdsys_fpga.h>
12 DECLARE_GLOBAL_DATA_PTR;
14 #ifdef CONFIG_SYS_I2C_IHS_DUAL
15 #define I2C_SET_REG(fld, val) \
16 { if (I2C_ADAP_HWNR & 0x10) \
17 FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
19 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); }
21 #define I2C_SET_REG(fld, val) \
22 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val);
25 #ifdef CONFIG_SYS_I2C_IHS_DUAL
26 #define I2C_GET_REG(fld, val) \
27 { if (I2C_ADAP_HWNR & 0x10) \
28 FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
30 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); }
32 #define I2C_GET_REG(fld, val) \
33 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val);
37 I2CINT_ERROR_EV = 1 << 13,
38 I2CINT_TRANSMIT_EV = 1 << 14,
39 I2CINT_RECEIVE_EV = 1 << 15,
43 I2CMB_WRITE = 1 << 10,
44 I2CMB_2BYTE = 1 << 11,
45 I2CMB_HOLD_BUS = 1 << 13,
46 I2CMB_NATIVE = 2 << 14,
49 static int wait_for_int(bool read)
54 I2C_GET_REG(interrupt_status, &val);
55 while (!(val & (I2CINT_ERROR_EV
56 | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) {
61 I2C_GET_REG(interrupt_status, &val);
64 return (val & I2CINT_ERROR_EV) ? 1 : 0;
67 static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
72 I2C_SET_REG(interrupt_status, I2CINT_ERROR_EV
73 | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV);
74 I2C_GET_REG(interrupt_status, &val);
80 val |= buffer[1] << 8;
81 I2C_SET_REG(write_mailbox_ext, val);
84 I2C_SET_REG(write_mailbox,
86 | (read ? 0 : I2CMB_WRITE)
88 | ((len > 1) ? I2CMB_2BYTE : 0)
89 | (is_last ? 0 : I2CMB_HOLD_BUS));
91 if (wait_for_int(read))
95 I2C_GET_REG(read_mailbox_ext, &val);
96 buffer[0] = val & 0xff;
104 static int ihs_i2c_address(uchar chip, uint addr, int alen, bool hold_bus)
106 int shift = (alen-1) * 8;
109 int transfer = min(alen, 2);
111 bool is_last = alen <= transfer;
113 buf[0] = addr >> shift;
115 buf[1] = addr >> (shift - 8);
117 if (ihs_i2c_transfer(chip, buf, transfer, false,
118 hold_bus ? false : is_last))
128 static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, uint addr,
129 int alen, uchar *buffer, int len, bool read)
134 if (ihs_i2c_address(chip, addr, alen, !read))
138 int transfer = min(len, 2);
140 if (ihs_i2c_transfer(chip, buffer, transfer, read,
153 static void ihs_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
155 #ifdef CONFIG_SYS_I2C_INIT_BOARD
157 * Call board specific i2c bus reset routine before accessing the
158 * environment, which might be in a chip on that bus. For details
159 * about this problem see doc/I2C_Edge_Conditions.
165 static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
169 if (ihs_i2c_transfer(chip, buffer, 0, true, true))
175 static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
176 int alen, uchar *buffer, int len)
178 return ihs_i2c_access(adap, chip, addr, alen, buffer, len, true);
181 static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
182 int alen, uchar *buffer, int len)
184 return ihs_i2c_access(adap, chip, addr, alen, buffer, len, false);
187 static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
190 if (speed != adap->speed)
196 * Register IHS i2c adapters
198 #ifdef CONFIG_SYS_I2C_IHS_CH0
199 U_BOOT_I2C_ADAP_COMPLETE(ihs0, ihs_i2c_init, ihs_i2c_probe,
200 ihs_i2c_read, ihs_i2c_write,
201 ihs_i2c_set_bus_speed,
202 CONFIG_SYS_I2C_IHS_SPEED_0,
203 CONFIG_SYS_I2C_IHS_SLAVE_0, 0)
204 #ifdef CONFIG_SYS_I2C_IHS_DUAL
205 U_BOOT_I2C_ADAP_COMPLETE(ihs0_1, ihs_i2c_init, ihs_i2c_probe,
206 ihs_i2c_read, ihs_i2c_write,
207 ihs_i2c_set_bus_speed,
208 CONFIG_SYS_I2C_IHS_SPEED_0_1,
209 CONFIG_SYS_I2C_IHS_SLAVE_0_1, 16)
212 #ifdef CONFIG_SYS_I2C_IHS_CH1
213 U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe,
214 ihs_i2c_read, ihs_i2c_write,
215 ihs_i2c_set_bus_speed,
216 CONFIG_SYS_I2C_IHS_SPEED_1,
217 CONFIG_SYS_I2C_IHS_SLAVE_1, 1)
218 #ifdef CONFIG_SYS_I2C_IHS_DUAL
219 U_BOOT_I2C_ADAP_COMPLETE(ihs1_1, ihs_i2c_init, ihs_i2c_probe,
220 ihs_i2c_read, ihs_i2c_write,
221 ihs_i2c_set_bus_speed,
222 CONFIG_SYS_I2C_IHS_SPEED_1_1,
223 CONFIG_SYS_I2C_IHS_SLAVE_1_1, 17)
226 #ifdef CONFIG_SYS_I2C_IHS_CH2
227 U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe,
228 ihs_i2c_read, ihs_i2c_write,
229 ihs_i2c_set_bus_speed,
230 CONFIG_SYS_I2C_IHS_SPEED_2,
231 CONFIG_SYS_I2C_IHS_SLAVE_2, 2)
232 #ifdef CONFIG_SYS_I2C_IHS_DUAL
233 U_BOOT_I2C_ADAP_COMPLETE(ihs2_1, ihs_i2c_init, ihs_i2c_probe,
234 ihs_i2c_read, ihs_i2c_write,
235 ihs_i2c_set_bus_speed,
236 CONFIG_SYS_I2C_IHS_SPEED_2_1,
237 CONFIG_SYS_I2C_IHS_SLAVE_2_1, 18)
240 #ifdef CONFIG_SYS_I2C_IHS_CH3
241 U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe,
242 ihs_i2c_read, ihs_i2c_write,
243 ihs_i2c_set_bus_speed,
244 CONFIG_SYS_I2C_IHS_SPEED_3,
245 CONFIG_SYS_I2C_IHS_SLAVE_3, 3)
246 #ifdef CONFIG_SYS_I2C_IHS_DUAL
247 U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe,
248 ihs_i2c_read, ihs_i2c_write,
249 ihs_i2c_set_bus_speed,
250 CONFIG_SYS_I2C_IHS_SPEED_3_1,
251 CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19)