diff options
author | Dirk Eibach <dirk.eibach@gdsys.cc> | 2015-10-28 10:46:22 (GMT) |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-11-12 20:59:01 (GMT) |
commit | 071be896947a2b6ab791657e250da6fc995360a8 (patch) | |
tree | 56d3ab5c5ae926e3e9197fa75d296c1b089ee172 /drivers/i2c | |
parent | 5b47d407e477b9995127aacca2d9a4665e2fde23 (diff) | |
download | u-boot-071be896947a2b6ab791657e250da6fc995360a8.tar.xz |
i2c: ihs_i2c: Dual channel support
Support two i2c masters per FPGA.
Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Acked-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/ihs_i2c.c | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c index 19fbe59..737beaf 100644 --- a/drivers/i2c/ihs_i2c.c +++ b/drivers/i2c/ihs_i2c.c @@ -11,6 +11,28 @@ DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_SYS_I2C_IHS_DUAL +#define I2C_SET_REG(fld, val) \ + { if (I2C_ADAP_HWNR & 0x10) \ + FPGA_SET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \ + else \ + FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); } +#else +#define I2C_SET_REG(fld, val) \ + FPGA_SET_REG(I2C_ADAP_HWNR, i2c0.fld, val); +#endif + +#ifdef CONFIG_SYS_I2C_IHS_DUAL +#define I2C_GET_REG(fld, val) \ + { if (I2C_ADAP_HWNR & 0x10) \ + FPGA_GET_REG(I2C_ADAP_HWNR & 0xf, i2c1.fld, val); \ + else \ + FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); } +#else +#define I2C_GET_REG(fld, val) \ + FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val); +#endif + enum { I2CINT_ERROR_EV = 1 << 13, I2CINT_TRANSMIT_EV = 1 << 14, @@ -29,14 +51,14 @@ static int wait_for_int(bool read) u16 val; unsigned int ctr = 0; - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + I2C_GET_REG(interrupt_status, &val); while (!(val & (I2CINT_ERROR_EV | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) { udelay(10); if (ctr++ > 5000) { return 1; } - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + I2C_GET_REG(interrupt_status, &val); } return (val & I2CINT_ERROR_EV) ? 1 : 0; @@ -47,30 +69,30 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read, { u16 val; - FPGA_SET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, I2CINT_ERROR_EV + I2C_SET_REG(interrupt_status, I2CINT_ERROR_EV | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV); - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.interrupt_status, &val); + I2C_GET_REG(interrupt_status, &val); if (!read && len) { val = buffer[0]; if (len > 1) val |= buffer[1] << 8; - FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox_ext, val); + I2C_SET_REG(write_mailbox_ext, val); } - FPGA_SET_REG(I2C_ADAP_HWNR, i2c.write_mailbox, - I2CMB_NATIVE - | (read ? 0 : I2CMB_WRITE) - | (chip << 1) - | ((len > 1) ? I2CMB_2BYTE : 0) - | (is_last ? 0 : I2CMB_HOLD_BUS)); + I2C_SET_REG(write_mailbox, + I2CMB_NATIVE + | (read ? 0 : I2CMB_WRITE) + | (chip << 1) + | ((len > 1) ? I2CMB_2BYTE : 0) + | (is_last ? 0 : I2CMB_HOLD_BUS)); if (wait_for_int(read)) return 1; if (read) { - FPGA_GET_REG(I2C_ADAP_HWNR, i2c.read_mailbox_ext, &val); + I2C_GET_REG(read_mailbox_ext, &val); buffer[0] = val & 0xff; if (len > 1) buffer[1] = val >> 8; @@ -163,7 +185,7 @@ static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, } static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap, - unsigned int speed) + unsigned int speed) { if (speed != adap->speed) return 1; @@ -179,6 +201,13 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs0, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_0, CONFIG_SYS_I2C_IHS_SLAVE_0, 0) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs0_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_0_1, + CONFIG_SYS_I2C_IHS_SLAVE_0_1, 16) +#endif #endif #ifdef CONFIG_SYS_I2C_IHS_CH1 U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe, @@ -186,6 +215,13 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs1, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_1, CONFIG_SYS_I2C_IHS_SLAVE_1, 1) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs1_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_1_1, + CONFIG_SYS_I2C_IHS_SLAVE_1_1, 17) +#endif #endif #ifdef CONFIG_SYS_I2C_IHS_CH2 U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe, @@ -193,6 +229,13 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs2, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_2, CONFIG_SYS_I2C_IHS_SLAVE_2, 2) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs2_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_2_1, + CONFIG_SYS_I2C_IHS_SLAVE_2_1, 18) +#endif #endif #ifdef CONFIG_SYS_I2C_IHS_CH3 U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe, @@ -200,4 +243,11 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs3, ihs_i2c_init, ihs_i2c_probe, ihs_i2c_set_bus_speed, CONFIG_SYS_I2C_IHS_SPEED_3, CONFIG_SYS_I2C_IHS_SLAVE_3, 3) +#ifdef CONFIG_SYS_I2C_IHS_DUAL +U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe, + ihs_i2c_read, ihs_i2c_write, + ihs_i2c_set_bus_speed, + CONFIG_SYS_I2C_IHS_SPEED_3_1, + CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19) +#endif #endif |