3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
5 * SPDX-License-Identifier: GPL-2.0+
7 * NOTE: This driver should be converted to driver model before June 2017.
8 * Please see doc/driver-model/i2c-howto.txt for instructions.
13 #include <gdsys_fpga.h>
15 DECLARE_GLOBAL_DATA_PTR
;
17 #ifdef CONFIG_SYS_I2C_IHS_DUAL
18 #define I2C_SET_REG(fld, val) \
20 if (I2C_ADAP_HWNR & 0x10) \
21 FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
23 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
26 #define I2C_SET_REG(fld, val) \
27 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
30 #ifdef CONFIG_SYS_I2C_IHS_DUAL
31 #define I2C_GET_REG(fld, val) \
33 if (I2C_ADAP_HWNR & 0x10) \
34 FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
36 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
39 #define I2C_GET_REG(fld, val) \
40 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
44 I2CINT_ERROR_EV
= 1 << 13,
45 I2CINT_TRANSMIT_EV
= 1 << 14,
46 I2CINT_RECEIVE_EV
= 1 << 15,
50 I2CMB_WRITE
= 1 << 10,
51 I2CMB_2BYTE
= 1 << 11,
52 I2CMB_HOLD_BUS
= 1 << 13,
53 I2CMB_NATIVE
= 2 << 14,
56 static int wait_for_int(bool read
)
61 I2C_GET_REG(interrupt_status
, &val
);
62 while (!(val
& (I2CINT_ERROR_EV
63 | (read
? I2CINT_RECEIVE_EV
: I2CINT_TRANSMIT_EV
)))) {
68 I2C_GET_REG(interrupt_status
, &val
);
71 return (val
& I2CINT_ERROR_EV
) ? 1 : 0;
74 static int ihs_i2c_transfer(uchar chip
, uchar
*buffer
, int len
, bool read
,
79 I2C_SET_REG(interrupt_status
, I2CINT_ERROR_EV
80 | I2CINT_RECEIVE_EV
| I2CINT_TRANSMIT_EV
);
81 I2C_GET_REG(interrupt_status
, &val
);
87 val
|= buffer
[1] << 8;
88 I2C_SET_REG(write_mailbox_ext
, val
);
91 I2C_SET_REG(write_mailbox
,
93 | (read
? 0 : I2CMB_WRITE
)
95 | ((len
> 1) ? I2CMB_2BYTE
: 0)
96 | (is_last
? 0 : I2CMB_HOLD_BUS
));
98 if (wait_for_int(read
))
102 I2C_GET_REG(read_mailbox_ext
, &val
);
103 buffer
[0] = val
& 0xff;
105 buffer
[1] = val
>> 8;
111 static int ihs_i2c_address(uchar chip
, uint addr
, int alen
, bool hold_bus
)
113 int shift
= (alen
-1) * 8;
116 int transfer
= min(alen
, 2);
118 bool is_last
= alen
<= transfer
;
120 buf
[0] = addr
>> shift
;
122 buf
[1] = addr
>> (shift
- 8);
124 if (ihs_i2c_transfer(chip
, buf
, transfer
, false,
125 hold_bus
? false : is_last
))
135 static int ihs_i2c_access(struct i2c_adapter
*adap
, uchar chip
, uint addr
,
136 int alen
, uchar
*buffer
, int len
, bool read
)
141 if (ihs_i2c_address(chip
, addr
, alen
, len
))
145 int transfer
= min(len
, 2);
147 if (ihs_i2c_transfer(chip
, buffer
, transfer
, read
,
160 static void ihs_i2c_init(struct i2c_adapter
*adap
, int speed
, int slaveaddr
)
162 #ifdef CONFIG_SYS_I2C_INIT_BOARD
164 * Call board specific i2c bus reset routine before accessing the
165 * environment, which might be in a chip on that bus. For details
166 * about this problem see doc/I2C_Edge_Conditions.
172 static int ihs_i2c_probe(struct i2c_adapter
*adap
, uchar chip
)
176 if (ihs_i2c_transfer(chip
, buffer
, 0, true, true))
182 static int ihs_i2c_read(struct i2c_adapter
*adap
, uchar chip
, uint addr
,
183 int alen
, uchar
*buffer
, int len
)
185 return ihs_i2c_access(adap
, chip
, addr
, alen
, buffer
, len
, true);
188 static int ihs_i2c_write(struct i2c_adapter
*adap
, uchar chip
, uint addr
,
189 int alen
, uchar
*buffer
, int len
)
191 return ihs_i2c_access(adap
, chip
, addr
, alen
, buffer
, len
, false);
194 static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter
*adap
,
197 if (speed
!= adap
->speed
)
203 * Register IHS i2c adapters
205 #ifdef CONFIG_SYS_I2C_IHS_CH0
206 U_BOOT_I2C_ADAP_COMPLETE(ihs0
, ihs_i2c_init
, ihs_i2c_probe
,
207 ihs_i2c_read
, ihs_i2c_write
,
208 ihs_i2c_set_bus_speed
,
209 CONFIG_SYS_I2C_IHS_SPEED_0
,
210 CONFIG_SYS_I2C_IHS_SLAVE_0
, 0)
211 #ifdef CONFIG_SYS_I2C_IHS_DUAL
212 U_BOOT_I2C_ADAP_COMPLETE(ihs0_1
, ihs_i2c_init
, ihs_i2c_probe
,
213 ihs_i2c_read
, ihs_i2c_write
,
214 ihs_i2c_set_bus_speed
,
215 CONFIG_SYS_I2C_IHS_SPEED_0_1
,
216 CONFIG_SYS_I2C_IHS_SLAVE_0_1
, 16)
219 #ifdef CONFIG_SYS_I2C_IHS_CH1
220 U_BOOT_I2C_ADAP_COMPLETE(ihs1
, ihs_i2c_init
, ihs_i2c_probe
,
221 ihs_i2c_read
, ihs_i2c_write
,
222 ihs_i2c_set_bus_speed
,
223 CONFIG_SYS_I2C_IHS_SPEED_1
,
224 CONFIG_SYS_I2C_IHS_SLAVE_1
, 1)
225 #ifdef CONFIG_SYS_I2C_IHS_DUAL
226 U_BOOT_I2C_ADAP_COMPLETE(ihs1_1
, ihs_i2c_init
, ihs_i2c_probe
,
227 ihs_i2c_read
, ihs_i2c_write
,
228 ihs_i2c_set_bus_speed
,
229 CONFIG_SYS_I2C_IHS_SPEED_1_1
,
230 CONFIG_SYS_I2C_IHS_SLAVE_1_1
, 17)
233 #ifdef CONFIG_SYS_I2C_IHS_CH2
234 U_BOOT_I2C_ADAP_COMPLETE(ihs2
, ihs_i2c_init
, ihs_i2c_probe
,
235 ihs_i2c_read
, ihs_i2c_write
,
236 ihs_i2c_set_bus_speed
,
237 CONFIG_SYS_I2C_IHS_SPEED_2
,
238 CONFIG_SYS_I2C_IHS_SLAVE_2
, 2)
239 #ifdef CONFIG_SYS_I2C_IHS_DUAL
240 U_BOOT_I2C_ADAP_COMPLETE(ihs2_1
, ihs_i2c_init
, ihs_i2c_probe
,
241 ihs_i2c_read
, ihs_i2c_write
,
242 ihs_i2c_set_bus_speed
,
243 CONFIG_SYS_I2C_IHS_SPEED_2_1
,
244 CONFIG_SYS_I2C_IHS_SLAVE_2_1
, 18)
247 #ifdef CONFIG_SYS_I2C_IHS_CH3
248 U_BOOT_I2C_ADAP_COMPLETE(ihs3
, ihs_i2c_init
, ihs_i2c_probe
,
249 ihs_i2c_read
, ihs_i2c_write
,
250 ihs_i2c_set_bus_speed
,
251 CONFIG_SYS_I2C_IHS_SPEED_3
,
252 CONFIG_SYS_I2C_IHS_SLAVE_3
, 3)
253 #ifdef CONFIG_SYS_I2C_IHS_DUAL
254 U_BOOT_I2C_ADAP_COMPLETE(ihs3_1
, ihs_i2c_init
, ihs_i2c_probe
,
255 ihs_i2c_read
, ihs_i2c_write
,
256 ihs_i2c_set_bus_speed
,
257 CONFIG_SYS_I2C_IHS_SPEED_3_1
,
258 CONFIG_SYS_I2C_IHS_SLAVE_3_1
, 19)