i2c: zynq: Support for 0-length register address
Subsystems (2)
PATCH v2 1/2 i2c: zynq: Support for 0-length register address
From: Michael Burr <[email protected]>
Fixed bug with alen == 0 in 'i2c_write', 'i2c_read' Further minor corrections:
- Write 'address' register before 'data' register.
- Write 'transfer_size' register before 'address' register.
---
Changes in v2:
- Fix incorrect rebase
Changes in v1:
- Based on original thread from Michael Burr
http://lists.denx.de/pipermail/u-boot/2013-October/165060.html
- MS rebase on latest&greatest
drivers/i2c/zynq_i2c.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)
drivers/i2c/zynq_i2c.c +23 -19
@@ -189,20 +189,22 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,* Temporarily disable restart (by clearing hold) * It doesn't seem to work. */ -clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_RW | -ZYNQ_I2C_CONTROL_HOLD ); +clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD );writel (0xFF , &zynq_i2c->interrupt_status); -while (alen--) -writel (addr >> (8 *alen), &zynq_i2c->data); -writel (dev, &zynq_i2c->address); +if (alen) { +clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_RW ); +writel (dev, &zynq_i2c->address); +while (alen--) +writel (addr >> (8 * alen), &zynq_i2c->data); -/* Wait for the address to be sent */ -if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { -/* Release the bus */ -clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD ); -return -ETIMEDOUT ; +/* Wait for the address to be sent */ +if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { +/* Release the bus */ +clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD ); +return -ETIMEDOUT ; + } +debug ("Device acked address\n" ); } -debug ("Device acked address\n" );setbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_CLR_FIFO |ZYNQ_I2C_CONTROL_RW );
@@ -247,17 +249,19 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, ZYNQ_I2C_CONTROL_HOLD);clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_RW );writel (0xFF , &zynq_i2c->interrupt_status); -while (alen--) -writel (addr >> (8 *alen), &zynq_i2c->data); -/* Start the tranfer */ writel (dev, &zynq_i2c->address); -if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { -/* Release the bus */ -clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD ); -return -ETIMEDOUT ; +if (alen) { +while (alen--) +writel (addr >> (8 * alen), &zynq_i2c->data); +/* Start the tranfer */ +if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { +/* Release the bus */ +clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD ); +return -ETIMEDOUT ; + } +debug ("Device acked address\n" ); } -debug ("Device acked address\n" );while (length--) {writel (*(cur_data++), &zynq_i2c->data);if (readl (&zynq_i2c->transfer_size) ==ZYNQ_I2C_FIFO_DEPTH ) {
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140122/f32bc710/attachment.pgp>
PATCH v2 2/2 i2c: zynq: Add support for the second i2c controller
From: Michael Burr <[email protected]>
Initialize the second i2c controller.
---
Changes in v2: None
Changes in v1:
- Based on original thread from Michael Burr
http://lists.denx.de/pipermail/u-boot/2013-October/165017.html
Heiko did some changes in this mainline patch
"i2c, zynq: convert zynq i2c driver to new multibus/multiadapter framework" (sha1: 0bdffe71fddeaa46768a39305797e4512dee0f15)
- MS rebase on latest&greatest
drivers/i2c/zynq_i2c.c | 44 ++++++++++++++++++++++++++----------------- include/configs/zynq-common.h | 6 +++--- 2 files changed, 30 insertions(+), 20 deletions(-)
drivers/i2c/zynq_i2c.c +27 -17
@@ -64,19 +64,21 @@ struct zynq_i2c_registers {#define ZYNQ_I2C_FIFO_DEPTH 16#define ZYNQ_I2C_TRANSFERT_SIZE_MAX 255/* Controller transfer limit */ -#if defined(CONFIG_ZYNQ_I2C0 ) -# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR0 -#else -# define ZYNQ_I2C_BASE ZYNQ_I2C_BASEADDR1 -#endif - -static struct zynq_i2c_registers *zynq_i2c = - (struct zynq_i2c_registers *)ZYNQ_I2C_BASE ; +static struct zynq_i2c_registers *i2c_select (struct i2c_adapter *adap) +{ +return adap->hwadapnr ? +/* Zynq PS I2C1 */ + (struct zynq_i2c_registers *)ZYNQ_I2C_BASEADDR1 : +/* Zynq PS I2C0 */ + (struct zynq_i2c_registers *)ZYNQ_I2C_BASEADDR0 ; +}/* I2C init called by cmd_i2c when doing 'i2c reset'. */ static void zynq_i2c_init (struct i2c_adapter *adap,int requested_speed,int slaveadd) { +struct zynq_i2c_registers *zynq_i2c =i2c_select (adap); +/* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */ writel ((16 <<ZYNQ_I2C_CONTROL_DIV_B_SHIFT ) | (2 <<ZYNQ_I2C_CONTROL_DIV_A_SHIFT ), &zynq_i2c->control);
@@ -87,7 +89,7 @@ static void zynq_i2c_init(struct i2c_adapter *adap, int requested_speed, }#ifdef DEBUG -static void zynq_i2c_debug_status (void ) +static void zynq_i2c_debug_status (struct zynq_i2c_registers *zynq_i2c) {int int_status;int status;
@@ -129,7 +131,7 @@ static void zynq_i2c_debug_status(void)#endif /* Wait for an interrupt */ -static u32 zynq_i2c_wait (u32 mask) +static u32 zynq_i2c_wait (struct zynq_i2c_registers *zynq_i2c,u32 mask) {int timeout, int_status;
@@ -140,7 +142,7 @@ static u32 zynq_i2c_wait(u32 mask)break ; }#ifdef DEBUG -zynq_i2c_debug_status (); + zynq_i2c_debug_status(zynq_i2c));#endif /* Clear interrupt status flags */ writel (int_status & mask, &zynq_i2c->interrupt_status);
@@ -154,6 +156,8 @@ static u32 zynq_i2c_wait(u32 mask)*/ static int zynq_i2c_probe (struct i2c_adapter *adap,u8 dev) { +struct zynq_i2c_registers *zynq_i2c =i2c_select (adap); +/* Attempt to read a byte */ setbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_CLR_FIFO |ZYNQ_I2C_CONTROL_RW );
@@ -162,7 +166,7 @@ static int zynq_i2c_probe(struct i2c_adapter *adap, u8 dev)writel (dev, &zynq_i2c->address);writel (1 , &zynq_i2c->transfer_size); -return (zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP | +return (zynq_i2c_wait (zynq_i2c,ZYNQ_I2C_INTERRUPT_COMP |ZYNQ_I2C_INTERRUPT_NACK ) &ZYNQ_I2C_INTERRUPT_COMP ) ?0 : -ETIMEDOUT ; }
@@ -177,6 +181,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,u32 status;u32 i =0 ;u8 *cur_data = data; +struct zynq_i2c_registers *zynq_i2c =i2c_select (adap);/* Check the hardware can handle the requested bytes */ if ((length <0 ) || (length >ZYNQ_I2C_TRANSFERT_SIZE_MAX ))
@@ -198,7 +203,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,writel (addr >> (8 * alen), &zynq_i2c->data);/* Wait for the address to be sent */ -if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { +if (!zynq_i2c_wait (zynq_i2c,ZYNQ_I2C_INTERRUPT_COMP )) {/* Release the bus */ clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD );return -ETIMEDOUT ;
@@ -214,7 +219,7 @@ static int zynq_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr,/* Wait for data */ do { - status = zynq_i2c_wait(ZYNQ_I2C_INTERRUPT_COMP | + status = zynq_i2c_wait(zynq_i2c, ZYNQ_I2C_INTERRUPT_COMP | ZYNQ_I2C_INTERRUPT_DATA); if (!status) { /* Release the bus */
@@ -243,6 +248,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, int alen, u8 *data, int length) { u8 *cur_data = data; +struct zynq_i2c_registers *zynq_i2c =i2c_select (adap);/* Write the register address */ setbits_le32(&zynq_i2c->control, ZYNQ_I2C_CONTROL_CLR_FIFO |
@@ -254,7 +260,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,while (alen--)writel (addr >> (8 * alen), &zynq_i2c->data);/* Start the tranfer */ -if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { +if (!zynq_i2c_wait (zynq_i2c,ZYNQ_I2C_INTERRUPT_COMP )) {/* Release the bus */ clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD );return -ETIMEDOUT ;
@@ -265,7 +271,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,while (length--) {writel (*(cur_data++), &zynq_i2c->data);if (readl (&zynq_i2c->transfer_size) ==ZYNQ_I2C_FIFO_DEPTH ) { -if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) { +if (!zynq_i2c_wait (zynq_i2c,ZYNQ_I2C_INTERRUPT_COMP )) {/* Release the bus */ clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD );
@@ -277,7 +283,7 @@ static int zynq_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr,/* All done... release the bus */ clrbits_le32 (&zynq_i2c->control,ZYNQ_I2C_CONTROL_HOLD );/* Wait for the address and data to be sent */ -if (!zynq_i2c_wait (ZYNQ_I2C_INTERRUPT_COMP )) +if (!zynq_i2c_wait (zynq_i2c,ZYNQ_I2C_INTERRUPT_COMP ))return -ETIMEDOUT ;return 0 ; }
@@ -295,3 +301,7 @@ U_BOOT_I2C_ADAP_COMPLETE(zynq_0, zynq_i2c_init, zynq_i2c_probe, zynq_i2c_read, zynq_i2c_write, zynq_i2c_set_bus_speed, CONFIG_SYS_I2C_ZYNQ_SPEED, CONFIG_SYS_I2C_ZYNQ_SLAVE, 0) +U_BOOT_I2C_ADAP_COMPLETE (zynq_1, zynq_i2c_init, zynq_i2c_probe, zynq_i2c_read, + zynq_i2c_write, zynq_i2c_set_bus_speed, +CONFIG_SYS_I2C_ZYNQ_SPEED ,CONFIG_SYS_I2C_ZYNQ_SLAVE , +1 )
include/configs/zynq-common.h +3 -3
@@ -104,13 +104,13 @@# define CONFIG_DOS_PARTITION #endif +#define CONFIG_SYS_I2C_ZYNQ /* I2C */ -#if defined(CONFIG_ZYNQ_I2C0 ) || defined(CONFIG_ZYNQ_I2C1 ) +#if defined(CONFIG_SYS_I2C_ZYNQ )# define CONFIG_CMD_I2C # define CONFIG_SYS_I2C -# define CONFIG_SYS_I2C_ZYNQ # define CONFIG_SYS_I2C_ZYNQ_SPEED 100000 -# define CONFIG_SYS_I2C_ZYNQ_SLAVE 1 +# define CONFIG_SYS_I2C_ZYNQ_SLAVE 0#endif /* EEPROM */
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140122/4856731c/attachment.pgp>
PATCH v2 2/2 i2c: zynq: Add support for the second i2c controller
Hello Michal,
Am 22.01.2014 09:46, schrieb Michal Simek:
Quoted 17 lines
From: Michael Burr<[email protected]>
Initialize the second i2c controller.
Signed-off-by Michael Burr<[email protected]>Signed-off-by Michal Simek<[email protected]>---
Changes in v2: None
Changes in v1:
- Based on original thread from Michael Burr
http://lists.denx.de/pipermail/u-boot/2013-October/165017.html
Heiko did some changes in this mainline patch
"i2c, zynq: convert zynq i2c driver to new multibus/multiadapter framework" (sha1:0bdffe71fddeaa46768a39305797e4512dee0f15)
- MS rebase on latest&greatest
Quoted 3 lines
drivers/i2c/zynq_i2c.c | 44 ++++++++++++++++++++++++++----------------- include/configs/zynq-common.h | 6 +++--- 2 files changed, 30 insertions(+), 20 deletions(-)
Applied to u-boot-i2c.git, thanks!
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
PATCH v2 1/2 i2c: zynq: Support for 0-length register address
In reply to Michal SimekHello Michal,
Am 22.01.2014 09:46, schrieb Michal Simek:
Quoted 15 lines
From: Michael Burr<[email protected]>
Fixed bug with alen == 0 in '
i2c_write', 'i2c_read' Further minor corrections:
- Write 'address' register before 'data' register.
- Write 'transfer_size' register before 'address' register.Signed-off-by Michael Burr<[email protected]>Signed-off-by Michal Simek<[email protected]>---
Changes in v2:
- Fix incorrect rebase
Quoted 7 lines
Changes in v1:
- Based on original thread from Michael Burr
http://lists.denx.de/pipermail/u-boot/2013-October/165060.html
- MS rebase on latest&greatestdrivers/i2c/zynq_i2c.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-)
Applied to u-boot-i2c.git, thanks!
bye,
Heiko
Signature · 2 lines
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany