
Hello Hans,
Am 04.04.2015 14:13, schrieb Hans de Goede:
Hi,
On 04-04-15 13:27, Paul Kocialkowski wrote:
Orion5x, Kirkwood and Armada XP platforms come with a single TWSI (I2C) MVTWSI controller. However, other platforms using MVTWSI may come with more: this is the case on Allwinner (sunxi) platforms, where up to 4 controllers can be found on the same chip.
Signed-off-by: Paul Kocialkowski contact@paulk.fr
Looks good to me:
Acked-by: Hans de Goede hdegoede@redhat.com
Heiko can you pick this one up please ? The second patch will likely cause conflicts in the sunxi tree so I will pack that one up once you've merged the first one, also I've some review remarks for the second patch so that needs to be respun.
No need to wait for me, please pick up the hole series. I look through the patch, and send my comments (now for v3). Then you can pick up this patches through your sunxi tree.
bye, Heiko
Regards,
Hans
arch/arm/include/asm/arch-sunxi/i2c.h | 2 +- arch/arm/mach-kirkwood/include/mach/config.h | 2 +- drivers/i2c/mvtwsi.c | 124 ++++++++++++++++++++------- include/configs/db-mv784mp-gp.h | 2 +- include/configs/edminiv2.h | 2 +- include/configs/maxbcm.h | 2 +- 6 files changed, 100 insertions(+), 34 deletions(-)
diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h index dc5406b..502e3c6 100644 --- a/arch/arm/include/asm/arch-sunxi/i2c.h +++ b/arch/arm/include/asm/arch-sunxi/i2c.h @@ -8,7 +8,7 @@
#include <asm/arch/cpu.h>
-#define CONFIG_I2C_MVTWSI_BASE SUNXI_TWI0_BASE +#define CONFIG_I2C_MVTWSI_BASE0 SUNXI_TWI0_BASE /* This is abp0-clk on sun4i/5i/7i / abp1-clk on sun6i/sun8i which is 24MHz */ #define CONFIG_SYS_TCLK 24000000
diff --git a/arch/arm/mach-kirkwood/include/mach/config.h b/arch/arm/mach-kirkwood/include/mach/config.h index e77ac40..d049395 100644 --- a/arch/arm/mach-kirkwood/include/mach/config.h +++ b/arch/arm/mach-kirkwood/include/mach/config.h @@ -44,7 +44,7 @@ #define CONFIG_SYS_INIT_SP_ADDR 0xC8012000 #define CONFIG_NR_DRAM_BANKS_MAX 2
-#define CONFIG_I2C_MVTWSI_BASE KW_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 KW_TWSI_BASE #define MV_UART_CONSOLE_BASE KW_UART0_BASE #define MV_SATA_BASE KW_SATA_BASE #define MV_SATA_PORT0_OFFSET KW_SATA_PORT0_OFFSET diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index 6f6edd5..331d73c 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -14,7 +14,7 @@ #include <asm/io.h>
/*
- include a file that will provide CONFIG_I2C_MVTWSI_BASE
*/
- include a file that will provide CONFIG_I2C_MVTWSI_BASE*
- and possibly other settings
@@ -91,11 +91,37 @@ struct mvtwsi_registers { #define MVTWSI_STATUS_IDLE 0xF8
/*
- The single instance of the controller we'll be dealing with
*/
- MVTWSI controller base
-static struct mvtwsi_registers *twsi =
- (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE;
+static struct mvtwsi_registers *twsi_get_base(struct i2c_adapter *adap) +{
- switch (adap->hwadapnr) {
- case 0:
return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE0;
+#ifdef CONFIG_I2C_MVTWSI_BASE1
- case 1:
return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE1;
+#endif +#ifdef CONFIG_I2C_MVTWSI_BASE2
- case 2:
return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE2;
+#endif +#ifdef CONFIG_I2C_MVTWSI_BASE3
- case 3:
return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE3;
+#endif +#ifdef CONFIG_I2C_MVTWSI_BASE4
- case 4:
return (struct mvtwsi_registers *) CONFIG_I2C_MVTWSI_BASE4;
+#endif
- default:
printf("Missing mvtwsi controller %d base\n", adap->hwadapnr);
break;
- }
- return NULL;
+}
/*
- Returned statuses are 0 for success and nonzero otherwise.
@@ -117,8 +143,9 @@ static struct mvtwsi_registers *twsi =
- Wait for IFLG to raise, or return 'timeout'; then if status is as expected,
- return 0 (ok) or return 'wrong status'.
*/ -static int twsi_wait(int expected_status) +static int twsi_wait(struct i2c_adapter *adap, int expected_status) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap); int control, status; int timeout = 1000;
@@ -153,35 +180,40 @@ static u8 twsi_control_flags = MVTWSI_CONTROL_TWSIEN;
- Assert the START condition, either in a single I2C transaction
- or inside back-to-back ones (repeated starts).
*/ -static int twsi_start(int expected_status) +static int twsi_start(struct i2c_adapter *adap, int expected_status) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap);
/* globally set TWSIEN in case it was not */ twsi_control_flags |= MVTWSI_CONTROL_TWSIEN; /* assert START */ writel(twsi_control_flags | MVTWSI_CONTROL_START, &twsi->control); /* wait for controller to process START */
- return twsi_wait(expected_status);
return twsi_wait(adap, expected_status); }
/*
- Send a byte (i2c address or data).
*/
-static int twsi_send(u8 byte, int expected_status) +static int twsi_send(struct i2c_adapter *adap, u8 byte, int expected_status) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap);
/* put byte in data register for sending */ writel(byte, &twsi->data); /* clear any pending interrupt -- that'll cause sending */ writel(twsi_control_flags, &twsi->control); /* wait for controller to receive byte and check ACK */
- return twsi_wait(expected_status);
return twsi_wait(adap, expected_status); }
/*
- Receive a byte.
- Global mvtwsi_control_flags variable says if we should ack or nak.
*/
-static int twsi_recv(u8 *byte) +static int twsi_recv(struct i2c_adapter *adap, u8 *byte) {
struct mvtwsi_registers *twsi = twsi_get_base(adap); int expected_status, status;
/* compute expected status based on ACK bit in global control flags */
@@ -192,7 +224,7 @@ static int twsi_recv(u8 *byte) /* acknowledge *previous state* and launch receive */ writel(twsi_control_flags, &twsi->control); /* wait for controller to receive byte and assert ACK or NAK */
- status = twsi_wait(expected_status);
- status = twsi_wait(adap, expected_status); /* if we did receive expected byte then store it */ if (status == 0) *byte = readl(&twsi->data);
@@ -204,8 +236,9 @@ static int twsi_recv(u8 *byte)
- Assert the STOP condition.
- This is also used to force the bus back in idle (SDA=SCL=1).
*/ -static int twsi_stop(int status) +static int twsi_stop(struct i2c_adapter *adap, int status) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap); int control, stop_status; int timeout = 1000;
@@ -244,6 +277,7 @@ static unsigned int twsi_calc_freq(const int n, const int m) */ static void twsi_reset(struct i2c_adapter *adap) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap); /* ensure controller will be enabled by any twsi*() function */ twsi_control_flags = MVTWSI_CONTROL_TWSIEN; /* reset controller */
@@ -259,6 +293,7 @@ static void twsi_reset(struct i2c_adapter *adap) static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap, unsigned int requested_speed) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap); unsigned int tmp_speed, highest_speed, n, m; unsigned int baud = 0x44; /* baudrate at controller reset */
@@ -281,6 +316,8 @@ static unsigned int twsi_i2c_set_bus_speed(struct i2c_adapter *adap,
static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) {
- struct mvtwsi_registers *twsi = twsi_get_base(adap);
/* reset controller */ twsi_reset(adap); /* set speed */
@@ -289,7 +326,7 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd) writel(slaveadd, &twsi->slave_address); writel(0, &twsi->xtnd_slave_addr); /* assert STOP but don't care for the result */
- (void) twsi_stop(0);
(void) twsi_stop(adap, 0); }
/*
@@ -297,7 +334,8 @@ static void twsi_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
- Common to i2c_probe, i2c_read and i2c_write.
- Expected address status will derive from direction bit (bit 0) in addr.
*/ -static int i2c_begin(int expected_start_status, u8 addr) +static int i2c_begin(struct i2c_adapter *adap, int expected_start_status,
{ int status, expected_addr_status;u8 addr)
@@ -307,10 +345,10 @@ static int i2c_begin(int expected_start_status, u8 addr) else /* writing */ expected_addr_status = MVTWSI_STATUS_ADDR_W_ACK; /* assert START */
- status = twsi_start(expected_start_status);
- status = twsi_start(adap, expected_start_status); /* send out the address if the start went well */ if (status == 0)
status = twsi_send(addr, expected_addr_status);
}status = twsi_send(adap, addr, expected_addr_status); /* return ok or status of first failure to caller */ return status;
@@ -325,12 +363,12 @@ static int twsi_i2c_probe(struct i2c_adapter *adap, uchar chip) int status;
/* begin i2c read */
- status = i2c_begin(MVTWSI_STATUS_START, (chip << 1) | 1);
- status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1) | 1); /* dummy read was accepted: receive byte but NAK it. */ if (status == 0)
status = twsi_recv(&dummy_byte);
status = twsi_recv(adap, &dummy_byte); /* Stop transaction */
- twsi_stop(0);
- twsi_stop(adap, 0); /* return 0 or status of first failure */ return status; }
@@ -351,15 +389,15 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, int status;
/* begin i2c write to send the address bytes */
- status = i2c_begin(MVTWSI_STATUS_START, (chip << 1));
- status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--)
status = twsi_send(addr >> (8*alen),
status = twsi_send(adap, addr >> (8*alen), MVTWSI_STATUS_DATA_W_ACK); /* begin i2c read to receive eeprom data bytes */ if (status == 0)
status = i2c_begin(
MVTWSI_STATUS_REPEATED_START, (chip << 1) | 1);
status = i2c_begin(adap, MVTWSI_STATUS_REPEATED_START,
(chip << 1) | 1); /* prepare ACK if at least one byte must be received */ if (length > 0) twsi_control_flags |= MVTWSI_CONTROL_ACK;
@@ -369,10 +407,10 @@ static int twsi_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr, if (length == 0) twsi_control_flags &= ~MVTWSI_CONTROL_ACK; /* read current byte */
status = twsi_recv(data++);
status = twsi_recv(adap, data++); } /* Stop transaction */
- status = twsi_stop(status);
- status = twsi_stop(adap, status); /* return 0 or status of first failure */ return status; }
@@ -387,16 +425,16 @@ static int twsi_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr, int status;
/* begin i2c write to send the eeprom adress bytes then data bytes */
- status = i2c_begin(MVTWSI_STATUS_START, (chip << 1));
- status = i2c_begin(adap, MVTWSI_STATUS_START, (chip << 1)); /* send addr bytes */ while ((status == 0) && alen--)
status = twsi_send(addr >> (8*alen),
status = twsi_send(adap, addr >> (8*alen), MVTWSI_STATUS_DATA_W_ACK); /* send data bytes */ while ((status == 0) && (length-- > 0))
status = twsi_send(*(data++), MVTWSI_STATUS_DATA_W_ACK);
status = twsi_send(adap, *(data++), MVTWSI_STATUS_DATA_W_ACK); /* Stop transaction */
- status = twsi_stop(status);
- status = twsi_stop(adap, status); /* return 0 or status of first failure */ return status; }
@@ -405,3 +443,31 @@ U_BOOT_I2C_ADAP_COMPLETE(twsi0, twsi_i2c_init, twsi_i2c_probe, twsi_i2c_read, twsi_i2c_write, twsi_i2c_set_bus_speed, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 0) +#ifdef CONFIG_I2C_MVTWSI_BASE1 +U_BOOT_I2C_ADAP_COMPLETE(twsi1, twsi_i2c_init, twsi_i2c_probe,
twsi_i2c_read, twsi_i2c_write,
twsi_i2c_set_bus_speed,
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 1)
+#endif +#ifdef CONFIG_I2C_MVTWSI_BASE2 +U_BOOT_I2C_ADAP_COMPLETE(twsi2, twsi_i2c_init, twsi_i2c_probe,
twsi_i2c_read, twsi_i2c_write,
twsi_i2c_set_bus_speed,
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 2)
+#endif +#ifdef CONFIG_I2C_MVTWSI_BASE3 +U_BOOT_I2C_ADAP_COMPLETE(twsi3, twsi_i2c_init, twsi_i2c_probe,
twsi_i2c_read, twsi_i2c_write,
twsi_i2c_set_bus_speed,
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 3)
+#endif +#ifdef CONFIG_I2C_MVTWSI_BASE4 +U_BOOT_I2C_ADAP_COMPLETE(twsi4, twsi_i2c_init, twsi_i2c_probe,
twsi_i2c_read, twsi_i2c_write,
twsi_i2c_set_bus_speed,
CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE, 4)
+#endif diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h index 1683a15..4dd7b11 100644 --- a/include/configs/db-mv784mp-gp.h +++ b/include/configs/db-mv784mp-gp.h @@ -37,7 +37,7 @@ /* I2C */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI -#define CONFIG_I2C_MVTWSI_BASE MVEBU_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 MVEBU_TWSI_BASE #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000
diff --git a/include/configs/edminiv2.h b/include/configs/edminiv2.h index 5ce01fb..bd08740 100644 --- a/include/configs/edminiv2.h +++ b/include/configs/edminiv2.h @@ -208,7 +208,7 @@ #ifdef CONFIG_CMD_I2C #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI -#define CONFIG_I2C_MVTWSI_BASE ORION5X_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 ORION5X_TWSI_BASE #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000 #endif diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h index 5999d60..e909623 100644 --- a/include/configs/maxbcm.h +++ b/include/configs/maxbcm.h @@ -35,7 +35,7 @@ /* I2C */ #define CONFIG_SYS_I2C #define CONFIG_SYS_I2C_MVTWSI -#define CONFIG_I2C_MVTWSI_BASE MVEBU_TWSI_BASE +#define CONFIG_I2C_MVTWSI_BASE0 MVEBU_TWSI_BASE #define CONFIG_SYS_I2C_SLAVE 0x0 #define CONFIG_SYS_I2C_SPEED 100000