3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
5 * SPDX-License-Identifier: GPL-2.0+
13 #include "../misc/gdsys_soc.h"
15 #include <gdsys_fpga.h>
17 #include <asm/unaligned.h>
26 REG_INTERRUPT_STATUS
= 0x00,
27 REG_INTERRUPT_ENABLE_CONTROL
= 0x02,
28 REG_WRITE_MAILBOX_EXT
= 0x04,
29 REG_WRITE_MAILBOX
= 0x06,
30 REG_READ_MAILBOX_EXT
= 0x08,
31 REG_READ_MAILBOX
= 0x0A,
34 #else /* !CONFIG_DM_I2C */
35 DECLARE_GLOBAL_DATA_PTR
;
37 #ifdef CONFIG_SYS_I2C_IHS_DUAL
39 #define I2C_SET_REG(fld, val) \
41 if (I2C_ADAP_HWNR & 0x10) \
42 FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
44 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
47 #define I2C_SET_REG(fld, val) \
48 FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
51 #ifdef CONFIG_SYS_I2C_IHS_DUAL
52 #define I2C_GET_REG(fld, val) \
54 if (I2C_ADAP_HWNR & 0x10) \
55 FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \
57 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); \
60 #define I2C_GET_REG(fld, val) \
61 FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
63 #endif /* CONFIG_DM_I2C */
66 I2CINT_ERROR_EV
= BIT(13),
67 I2CINT_TRANSMIT_EV
= BIT(14),
68 I2CINT_RECEIVE_EV
= BIT(15),
73 I2CMB_WRITE
= 1 << 10,
74 I2CMB_1BYTE
= 0 << 11,
75 I2CMB_2BYTE
= 1 << 11,
76 I2CMB_DONT_HOLD_BUS
= 0 << 13,
77 I2CMB_HOLD_BUS
= 1 << 13,
78 I2CMB_NATIVE
= 2 << 14,
87 static int wait_for_int(struct udevice
*dev
, int read
)
89 static int wait_for_int(bool read
)
95 struct ihs_i2c_priv
*priv
= dev_get_priv(dev
);
98 gdsys_soc_get_fpga(dev
, &fpga
);
102 fpgamap_read16(fpga
, priv
->addr
+ REG_INTERRUPT_STATUS
, &val
);
104 I2C_GET_REG(interrupt_status
, &val
);
106 /* Wait until error or receive/transmit interrupt was raised */
107 while (!(val
& (I2CINT_ERROR_EV
108 | (read
? I2CINT_RECEIVE_EV
: I2CINT_TRANSMIT_EV
)))) {
113 fpgamap_read16(fpga
, priv
->addr
+ REG_INTERRUPT_STATUS
, &val
);
115 I2C_GET_REG(interrupt_status
, &val
);
119 return (val
& I2CINT_ERROR_EV
) ? 1 : 0;
123 static int ihs_i2c_transfer(struct udevice
*dev
, uchar chip
,
124 uchar
*buffer
, int len
, int read
, bool is_last
)
126 static int ihs_i2c_transfer(uchar chip
, uchar
*buffer
, int len
, bool read
,
132 struct ihs_i2c_priv
*priv
= dev_get_priv(dev
);
133 struct udevice
*fpga
;
135 gdsys_soc_get_fpga(dev
, &fpga
);
138 /* Clear interrupt status */
140 fpgamap_write16(fpga
, priv
->addr
+ REG_INTERRUPT_STATUS
,
141 I2CINT_ERROR_EV
| I2CINT_RECEIVE_EV
| I2CINT_TRANSMIT_EV
);
142 fpgamap_read16(fpga
, priv
->addr
+ REG_INTERRUPT_STATUS
, &val
);
144 I2C_SET_REG(interrupt_status
, I2CINT_ERROR_EV
145 | I2CINT_RECEIVE_EV
| I2CINT_TRANSMIT_EV
);
146 I2C_GET_REG(interrupt_status
, &val
);
149 /* If we want to write and have data, write the bytes to the mailbox */
154 val
|= buffer
[1] << 8;
156 fpgamap_write16(fpga
, priv
->addr
+ REG_WRITE_MAILBOX_EXT
, val
);
158 I2C_SET_REG(write_mailbox_ext
, val
);
163 fpgamap_write16(fpga
, priv
->addr
+ REG_WRITE_MAILBOX
,
165 | (read
? I2CMB_READ
: I2CMB_WRITE
)
167 | ((len
> 1) ? I2CMB_2BYTE
: I2CMB_1BYTE
)
168 | (!is_last
? I2CMB_HOLD_BUS
: I2CMB_DONT_HOLD_BUS
));
170 I2C_SET_REG(write_mailbox
,
172 | (read
? 0 : I2CMB_WRITE
)
174 | ((len
> 1) ? I2CMB_2BYTE
: 0)
175 | (is_last
? 0 : I2CMB_HOLD_BUS
));
179 if (wait_for_int(dev
, read
))
181 if (wait_for_int(read
))
185 /* If we want to read, get the bytes from the mailbox */
188 fpgamap_read16(fpga
, priv
->addr
+ REG_READ_MAILBOX_EXT
, &val
);
190 I2C_GET_REG(read_mailbox_ext
, &val
);
192 buffer
[0] = val
& 0xff;
194 buffer
[1] = val
>> 8;
201 static int ihs_i2c_send_buffer(struct udevice
*dev
, uchar chip
, u8
*data
, int len
, bool hold_bus
, int read
)
203 static int ihs_i2c_send_buffer(uchar chip
, u8
*data
, int len
, bool hold_bus
,
208 int transfer
= min(len
, 2);
209 bool is_last
= len
<= transfer
;
212 if (ihs_i2c_transfer(dev
, chip
, data
, transfer
, read
,
213 hold_bus
? false : is_last
))
216 if (ihs_i2c_transfer(chip
, data
, transfer
, read
,
217 hold_bus
? false : is_last
))
229 static int ihs_i2c_address(struct udevice
*dev
, uchar chip
, u8
*addr
, int alen
,
232 static int ihs_i2c_address(uchar chip
, u8
*addr
, int alen
, bool hold_bus
)
236 return ihs_i2c_send_buffer(dev
, chip
, addr
, alen
, hold_bus
, I2COP_WRITE
);
238 return ihs_i2c_send_buffer(chip
, addr
, alen
, hold_bus
, I2COP_WRITE
);
243 static int ihs_i2c_access(struct udevice
*dev
, uchar chip
, u8
*addr
,
244 int alen
, uchar
*buffer
, int len
, int read
)
246 static int ihs_i2c_access(struct i2c_adapter
*adap
, uchar chip
, u8
*addr
,
247 int alen
, uchar
*buffer
, int len
, int read
)
250 /* Don't hold the bus if length of data to send/receive is zero */
252 if (len
<= 0 || ihs_i2c_address(dev
, chip
, addr
, alen
, len
))
255 if (len
<= 0 || ihs_i2c_address(chip
, addr
, alen
, len
))
260 return ihs_i2c_send_buffer(dev
, chip
, buffer
, len
, false, read
);
262 return ihs_i2c_send_buffer(chip
, buffer
, len
, false, read
);
268 int ihs_i2c_probe(struct udevice
*bus
)
270 struct ihs_i2c_priv
*priv
= dev_get_priv(bus
);
273 addr
= dev_read_u32_default(bus
, "reg", -1);
280 static int ihs_i2c_set_bus_speed(struct udevice
*bus
, uint speed
)
282 struct ihs_i2c_priv
*priv
= dev_get_priv(bus
);
284 if (speed
!= priv
->speed
&& priv
->speed
!= 0)
292 static int ihs_i2c_xfer(struct udevice
*bus
, struct i2c_msg
*msg
, int nmsgs
)
294 struct i2c_msg
*dmsg
, *omsg
, dummy
;
296 memset(&dummy
, 0, sizeof(struct i2c_msg
));
298 /* We expect either two messages (one with an offset and one with the
299 * actucal data) or one message (just data)
301 if (nmsgs
> 2 || nmsgs
== 0) {
302 debug("%s: Only one or two messages are supported.", __func__
);
306 omsg
= nmsgs
== 1 ? &dummy
: msg
;
307 dmsg
= nmsgs
== 1 ? msg
: msg
+ 1;
309 if (dmsg
->flags
& I2C_M_RD
)
310 return ihs_i2c_access(bus
, dmsg
->addr
, omsg
->buf
,
311 omsg
->len
, dmsg
->buf
, dmsg
->len
,
314 return ihs_i2c_access(bus
, dmsg
->addr
, omsg
->buf
,
315 omsg
->len
, dmsg
->buf
, dmsg
->len
,
319 static int ihs_i2c_probe_chip(struct udevice
*bus
, u32 chip_addr
,
324 if (ihs_i2c_transfer(bus
, chip_addr
, buffer
, 0, I2COP_READ
, true))
330 static const struct dm_i2c_ops ihs_i2c_ops
= {
331 .xfer
= ihs_i2c_xfer
,
332 .probe_chip
= ihs_i2c_probe_chip
,
333 .set_bus_speed
= ihs_i2c_set_bus_speed
,
336 static const struct udevice_id ihs_i2c_ids
[] = {
337 { .compatible
= "gdsys,ihs_i2cmaster", },
341 U_BOOT_DRIVER(i2c_ihs
) = {
344 .of_match
= ihs_i2c_ids
,
345 .probe
= ihs_i2c_probe
,
346 .priv_auto_alloc_size
= sizeof(struct ihs_i2c_priv
),
350 #else /* CONFIG_DM_I2C */
352 static void ihs_i2c_init(struct i2c_adapter
*adap
, int speed
, int slaveaddr
)
354 #ifdef CONFIG_SYS_I2C_INIT_BOARD
356 * Call board specific i2c bus reset routine before accessing the
357 * environment, which might be in a chip on that bus. For details
358 * about this problem see doc/I2C_Edge_Conditions.
364 static int ihs_i2c_probe(struct i2c_adapter
*adap
, uchar chip
)
368 if (ihs_i2c_transfer(chip
, buffer
, 0, I2COP_READ
, true))
374 static int ihs_i2c_read(struct i2c_adapter
*adap
, uchar chip
, uint addr
,
375 int alen
, uchar
*buffer
, int len
)
379 put_unaligned_le32(addr
, addr_bytes
);
381 return ihs_i2c_access(adap
, chip
, addr_bytes
, alen
, buffer
, len
,
385 static int ihs_i2c_write(struct i2c_adapter
*adap
, uchar chip
, uint addr
,
386 int alen
, uchar
*buffer
, int len
)
390 put_unaligned_le32(addr
, addr_bytes
);
392 return ihs_i2c_access(adap
, chip
, addr_bytes
, alen
, buffer
, len
,
396 static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter
*adap
,
399 if (speed
!= adap
->speed
)
405 * Register IHS i2c adapters
407 #ifdef CONFIG_SYS_I2C_IHS_CH0
408 U_BOOT_I2C_ADAP_COMPLETE(ihs0
, ihs_i2c_init
, ihs_i2c_probe
,
409 ihs_i2c_read
, ihs_i2c_write
,
410 ihs_i2c_set_bus_speed
,
411 CONFIG_SYS_I2C_IHS_SPEED_0
,
412 CONFIG_SYS_I2C_IHS_SLAVE_0
, 0)
413 #ifdef CONFIG_SYS_I2C_IHS_DUAL
414 U_BOOT_I2C_ADAP_COMPLETE(ihs0_1
, ihs_i2c_init
, ihs_i2c_probe
,
415 ihs_i2c_read
, ihs_i2c_write
,
416 ihs_i2c_set_bus_speed
,
417 CONFIG_SYS_I2C_IHS_SPEED_0_1
,
418 CONFIG_SYS_I2C_IHS_SLAVE_0_1
, 16)
421 #ifdef CONFIG_SYS_I2C_IHS_CH1
422 U_BOOT_I2C_ADAP_COMPLETE(ihs1
, ihs_i2c_init
, ihs_i2c_probe
,
423 ihs_i2c_read
, ihs_i2c_write
,
424 ihs_i2c_set_bus_speed
,
425 CONFIG_SYS_I2C_IHS_SPEED_1
,
426 CONFIG_SYS_I2C_IHS_SLAVE_1
, 1)
427 #ifdef CONFIG_SYS_I2C_IHS_DUAL
428 U_BOOT_I2C_ADAP_COMPLETE(ihs1_1
, ihs_i2c_init
, ihs_i2c_probe
,
429 ihs_i2c_read
, ihs_i2c_write
,
430 ihs_i2c_set_bus_speed
,
431 CONFIG_SYS_I2C_IHS_SPEED_1_1
,
432 CONFIG_SYS_I2C_IHS_SLAVE_1_1
, 17)
435 #ifdef CONFIG_SYS_I2C_IHS_CH2
436 U_BOOT_I2C_ADAP_COMPLETE(ihs2
, ihs_i2c_init
, ihs_i2c_probe
,
437 ihs_i2c_read
, ihs_i2c_write
,
438 ihs_i2c_set_bus_speed
,
439 CONFIG_SYS_I2C_IHS_SPEED_2
,
440 CONFIG_SYS_I2C_IHS_SLAVE_2
, 2)
441 #ifdef CONFIG_SYS_I2C_IHS_DUAL
442 U_BOOT_I2C_ADAP_COMPLETE(ihs2_1
, ihs_i2c_init
, ihs_i2c_probe
,
443 ihs_i2c_read
, ihs_i2c_write
,
444 ihs_i2c_set_bus_speed
,
445 CONFIG_SYS_I2C_IHS_SPEED_2_1
,
446 CONFIG_SYS_I2C_IHS_SLAVE_2_1
, 18)
449 #ifdef CONFIG_SYS_I2C_IHS_CH3
450 U_BOOT_I2C_ADAP_COMPLETE(ihs3
, ihs_i2c_init
, ihs_i2c_probe
,
451 ihs_i2c_read
, ihs_i2c_write
,
452 ihs_i2c_set_bus_speed
,
453 CONFIG_SYS_I2C_IHS_SPEED_3
,
454 CONFIG_SYS_I2C_IHS_SLAVE_3
, 3)
455 #ifdef CONFIG_SYS_I2C_IHS_DUAL
456 U_BOOT_I2C_ADAP_COMPLETE(ihs3_1
, ihs_i2c_init
, ihs_i2c_probe
,
457 ihs_i2c_read
, ihs_i2c_write
,
458 ihs_i2c_set_bus_speed
,
459 CONFIG_SYS_I2C_IHS_SPEED_3_1
,
460 CONFIG_SYS_I2C_IHS_SLAVE_3_1
, 19)
463 #endif /* CONFIG_DM_I2C */