All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place
@ 2011-03-14 10:16 Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 2/8] pxa_i2c: use structure to replace the direclty define Lei Wen
                   ` (4 more replies)
  0 siblings, 5 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-14 10:16 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/pxa_i2c.c     |  469 +++++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 472 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/pxa_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..16308ac 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -35,6 +35,7 @@ COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += omap24xx_i2c.o
 COBJS-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
 COBJS-$(CONFIG_PPC4XX_I2C) += ppc4xx_i2c.o
+COBJS-$(CONFIG_PXA_I2C) += pxa_i2c.o
 COBJS-$(CONFIG_DRIVER_S3C24X0_I2C) += s3c24x0_i2c.o
 COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
diff --git a/drivers/i2c/pxa_i2c.c b/drivers/i2c/pxa_i2c.c
new file mode 100644
index 0000000..7aa49ae
--- /dev/null
+++ b/drivers/i2c/pxa_i2c.c
@@ -0,0 +1,469 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+/* FIXME: this file is PXA255 specific! What about other XScales? */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
+#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+
+/**
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+
+static void i2c_reset( void )
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+
+/**
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
+{
+	int timeout = 10000;
+
+	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
+		udelay( 10 );
+		if( timeout-- < 0 ) return 0;
+	}
+
+	return 1;
+}
+
+
+/**
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch(msg->direction) {
+
+	case I2C_WRITE:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0,ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE,0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0,ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF,0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+
+	default:
+
+		goto transfer_error_illegal_param;
+
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
+		i2c_reset();
+		return ret;
+
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+
+/**
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg)) return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg)) return -1;
+
+	return 0;
+}
+
+
+/**
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+	int ret;
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     &= 0xFE;
+	if ((ret=i2c_transfer(&msg))) return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+
+		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if ((ret=i2c_transfer(&msg))) return -1;
+	}
+
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if ((ret=i2c_transfer(&msg))) return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+
+		if (len==0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if ((ret=i2c_transfer(&msg))) return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
+		buffer++;
+
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+
+/**
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     &= 0xFE;
+	if (i2c_transfer(&msg)) return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg)) return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
+
+		if (len==0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg)) return -1;
+
+	}
+
+	i2c_reset();
+
+	return 0;
+
+}
+
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..57d633c 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_PXA_I2C			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..7a7c539 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_PXA_I2C			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 2/8] pxa_i2c: use structure to replace the direclty define
  2011-03-14 10:16 [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-14 10:16 ` Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 3/8] I2C: add i2c support for Pantheon platform Lei Wen
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-14 10:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/pxa/cpu.c                   |   11 +++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 ------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/pxa_i2c.c                    |  139 +++++++++++++++++++++---------
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 6 files changed, 111 insertions(+), 106 deletions(-)

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..24b59e7 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,14 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/pxa_i2c.c b/drivers/i2c/pxa_i2c.c
index 7aa49ae..0e37417 100644
--- a/drivers/i2c/pxa_i2c.c
+++ b/drivers/i2c/pxa_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -30,8 +33,6 @@
  * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
  */
 
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
 #include <common.h>
 #include <asm/io.h>
 
@@ -42,9 +43,41 @@
  *	- I2C_PXA_SLAVE_ADDR
  */
 
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
+extern void i2c_clk_enable(void);
+
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
 
 /*#define	DEBUG_I2C	1	/###* activate local debugging output  */
 #define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
@@ -86,6 +119,21 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct pxa_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
+#define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
 
 /**
  * i2c_pxa_reset: - reset the host controller
@@ -94,21 +142,17 @@ struct i2c_msg {
 
 static void i2c_reset( void )
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
+	PXAI2C_OR(&base->icr, ICR_UR);	/* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
+
+	i2c_clk_enable();
+
+	writel(I2C_PXA_SLAVE_ADDR, &base->isar);/* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
+	PXAI2C_OR(&base->icr, ICR_IUE);		/* enable unit */
 	udelay(100);
 }
 
@@ -121,12 +165,14 @@ static void i2c_reset( void )
  */
 static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
 {
-	int timeout = 10000;
+	int timeout = 10000, isr;
 
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
+	do {
+		isr = readl(&base->isr);
+		udelay(10);
 		if( timeout-- < 0 ) return 0;
-	}
+	} while (((isr & set_mask)!=set_mask)
+		 || ((isr & cleared_mask)!=0));
 
 	return 1;
 }
@@ -162,26 +208,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		PXAI2C_AND(&base->icr, ~ICR_START);
+		PXAI2C_AND(&base->icr, ~ICR_STOP);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			PXAI2C_OR(&base->icr, ICR_START);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			PXAI2C_OR(&base->icr, ICR_STOP);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			PXAI2C_OR(&base->icr, ICR_ACKNAK);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
+		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
+		PXAI2C_OR(&base->icr, ICR_TB);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE,0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		PXAI2C_OR(&base->isr, ISR_ITE);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -196,27 +242,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		PXAI2C_AND(&base->icr, ~ICR_START);
+		PXAI2C_AND(&base->icr, ~ICR_STOP);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			PXAI2C_OR(&base->icr, ICR_START);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			PXAI2C_OR(&base->icr, ICR_STOP);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			PXAI2C_OR(&base->icr, ICR_ACKNAK);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
+		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
+		PXAI2C_OR(&base->icr, ICR_TB);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF,0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
+		PXAI2C_OR(&base->isr, ISR_IRF);
 
 		break;
 
@@ -266,10 +312,19 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
 	/* environment, which might be in a chip on that bus. For details   */
 	/* about this problem see doc/I2C_Edge_Conditions.                  */
+
+	/* disable I2C controller first, otherwhise it thinks we want to    */
+	/* talk to the slave port...                                        */
+	icr = readl(&base->icr);
+	PXAI2C_AND(&base->icr, ~(ICR_SCLE | ICR_IUE));
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 57d633c..b459668 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_PXA_I2C			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 7a7c539..8cdad23 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_PXA_I2C			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 3/8] I2C: add i2c support for Pantheon platform
  2011-03-14 10:16 [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 2/8] pxa_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-14 10:16 ` Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 4/8] I2C: pxa_i2c: add multi bus support Lei Wen
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-14 10:16 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   10 ++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h |    2 ++
 board/Marvell/dkb/dkb.c                  |    4 ++++
 include/configs/dkb.h                    |   11 +++++++++++
 5 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..88ecfae 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,10 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +80,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_PXA_I2C
+void i2c_clk_enable (void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..041e64c 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -34,6 +34,8 @@
 /* UART2 */
 #define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
 #define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP53_CI2C_SCL		MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP54_CI2C_SDA		MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..75c4b99 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -56,6 +56,17 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
+/*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C
+#define CONFIG_PXA_I2C			1
+#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 4/8] I2C: pxa_i2c: add multi bus support
  2011-03-14 10:16 [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 2/8] pxa_i2c: use structure to replace the direclty define Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 3/8] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-14 10:16 ` Lei Wen
  2011-03-14 10:16 ` [U-Boot] [PATCH 5/8] I2C: add i2c support for Armada100 platform Lei Wen
  2011-03-14 12:03 ` [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Prafulla Wadaskar
  4 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-14 10:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 drivers/i2c/pxa_i2c.c |   38 ++++++++++++++++++++++++++++++++++++--
 include/configs/dkb.h |    4 +++-
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/pxa_i2c.c b/drivers/i2c/pxa_i2c.c
index 0e37417..17b83ab 100644
--- a/drivers/i2c/pxa_i2c.c
+++ b/drivers/i2c/pxa_i2c.c
@@ -131,9 +131,38 @@ struct pxa_i2c {
 	u32 isar;
 };
 
-static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
 #define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
 #define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
+static struct pxa_i2c *base;
+
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
+static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
+static unsigned int current_bus = 0;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct pxa_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if(!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /**
  * i2c_pxa_reset: - reset the host controller
@@ -311,6 +340,12 @@ i2c_transfer_finish:
 
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct pxa_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
@@ -520,5 +555,4 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	return 0;
 
 }
-
 #endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 75c4b99..b1a2319 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -62,7 +62,9 @@
  */
 #define CONFIG_CMD_I2C
 #define CONFIG_PXA_I2C			1
-#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_PXA_I2C_NUM		1
+#define CONFIG_I2C_MULTI_BUS		1
+#define CONFIG_PXA_I2C_REG		{0xd4011000}
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED		0
 #define CONFIG_SYS_I2C_SLAVE		0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 5/8] I2C: add i2c support for Armada100 platform
  2011-03-14 10:16 [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Lei Wen
                   ` (2 preceding siblings ...)
  2011-03-14 10:16 ` [U-Boot] [PATCH 4/8] I2C: pxa_i2c: add multi bus support Lei Wen
@ 2011-03-14 10:16 ` Lei Wen
  2011-03-14 12:03 ` [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Prafulla Wadaskar
  4 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-14 10:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   14 ++++++++++++++
 arch/arm/include/asm/arch-armada100/mfp.h |    4 ++++
 board/Marvell/aspenite/aspenite.c         |    5 +++++
 include/configs/aspenite.h                |   12 ++++++++++++
 4 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..8039ad2 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,14 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +98,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_PXA_I2C
+void i2c_clk_enable (void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..f22b5e7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -60,6 +60,10 @@
 #define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
 #define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
 
+/* I2c */
+#define MFP105_CI2C_SDA		MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM
+#define MFP106_CI2C_SCL		MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM
+
 /* More macros can be defined here... */
 
 #define MFP_PIN_MAX	117
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..50f8ed7 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -63,6 +63,18 @@
 #undef CONFIG_ARCH_MISC_INIT
 
 /*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C		1
+#define CONFIG_PXA_I2C		1
+#define CONFIG_PXA_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+
+/*
  * Environment variables configurations
  */
 #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place
  2011-03-14 10:16 [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Lei Wen
                   ` (3 preceding siblings ...)
  2011-03-14 10:16 ` [U-Boot] [PATCH 5/8] I2C: add i2c support for Armada100 platform Lei Wen
@ 2011-03-14 12:03 ` Prafulla Wadaskar
  2011-03-15  1:36   ` Lei Wen
  4 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-14 12:03 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Monday, March 14, 2011 3:46 PM
> To: u-boot at lists.denx.de; Marek Vasut; Prafulla Wadaskar; Lei Wen
> Subject: [PATCH 1/8] pxa: move i2c driver to the common place
> 
> For better sharing with other platform other than pxa's,
> it is more convenient to put the driver to the common place.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  arch/arm/cpu/pxa/Makefile |    1 -
>  arch/arm/cpu/pxa/i2c.c    |  469 --------------------------------------
> -------
>  drivers/i2c/Makefile      |    1 +
>  drivers/i2c/pxa_i2c.c     |  469
> +++++++++++++++++++++++++++++++++++++++++++++

Hi Lei
It looks like this is cut-paste, have you done git-mv? Pls confirm

Secondly
Since this will be supported by multiple Marvell SoC cores.
How about renaming new moved i2c driver as mvi2c.c?

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place
  2011-03-14 12:03 ` [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Prafulla Wadaskar
@ 2011-03-15  1:36   ` Lei Wen
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
                       ` (5 more replies)
  0 siblings, 6 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-15  1:36 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Mon, Mar 14, 2011 at 8:03 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Monday, March 14, 2011 3:46 PM
>> To: u-boot at lists.denx.de; Marek Vasut; Prafulla Wadaskar; Lei Wen
>> Subject: [PATCH 1/8] pxa: move i2c driver to the common place
>>
>> For better sharing with other platform other than pxa's,
>> it is more convenient to put the driver to the common place.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> ?arch/arm/cpu/pxa/Makefile | ? ?1 -
>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 --------------------------------------
>> -------
>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>> ?drivers/i2c/pxa_i2c.c ? ? | ?469
>> +++++++++++++++++++++++++++++++++++++++++++++
>
> Hi Lei
> It looks like this is cut-paste, have you done git-mv? Pls confirm
Good catch. :) I would use the git-mv to redo the patch.

>
> Secondly
> Since this will be supported by multiple Marvell SoC cores.
> How about renaming new moved i2c driver as mvi2c.c?

Yep, I'm ok with this change. I would post modified patch later.

Thanks,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100
  2011-03-15  1:36   ` Lei Wen
@ 2011-03-15  3:40     ` Lei Wen
  2011-03-15  8:12       ` Wolfgang Denk
                         ` (6 more replies)
  2011-03-15  3:40     ` [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place Lei Wen
                       ` (4 subsequent siblings)
  5 siblings, 7 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-15  3:40 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

Lei Wen (5):
  pxa: move i2c driver to the common place
  mvi2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mvi2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   14 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c     |   10 +
 arch/arm/cpu/pxa/Makefile                 |    1 -
 arch/arm/cpu/pxa/cpu.c                    |   11 +
 arch/arm/cpu/pxa/i2c.c                    |  469 ------------------------
 arch/arm/include/asm/arch-armada100/mfp.h |    4 +
 arch/arm/include/asm/arch-pantheon/cpu.h  |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h  |    2 +
 arch/arm/include/asm/arch-pxa/pxa-regs.h  |   56 ---
 board/Marvell/aspenite/aspenite.c         |    5 +
 board/Marvell/dkb/dkb.c                   |    4 +
 board/innokom/innokom.c                   |    9 +-
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/mvi2c.c                       |  559 +++++++++++++++++++++++++++++
 include/configs/aspenite.h                |   12 +
 include/configs/dkb.h                     |   11 +
 include/configs/innokom.h                 |    2 +
 include/configs/xm250.h                   |    2 +
 18 files changed, 641 insertions(+), 535 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mvi2c.c

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place
  2011-03-15  1:36   ` Lei Wen
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
@ 2011-03-15  3:40     ` Lei Wen
  2011-03-15  6:48       ` Heiko Schocher
  2011-03-15  8:09       ` Wolfgang Denk
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define Lei Wen
                       ` (3 subsequent siblings)
  5 siblings, 2 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-15  3:40 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mvi2c.c       |  469 +++++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 472 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mvi2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..360ffb6 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mvi2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
new file mode 100644
index 0000000..7aa49ae
--- /dev/null
+++ b/drivers/i2c/mvi2c.c
@@ -0,0 +1,469 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+/* FIXME: this file is PXA255 specific! What about other XScales? */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
+#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+
+/**
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+
+static void i2c_reset( void )
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+
+/**
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
+{
+	int timeout = 10000;
+
+	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
+		udelay( 10 );
+		if( timeout-- < 0 ) return 0;
+	}
+
+	return 1;
+}
+
+
+/**
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch(msg->direction) {
+
+	case I2C_WRITE:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0,ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE,0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0,ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF,0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+
+	default:
+
+		goto transfer_error_illegal_param;
+
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
+		i2c_reset();
+		return ret;
+
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+
+/**
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg)) return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg)) return -1;
+
+	return 0;
+}
+
+
+/**
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+	int ret;
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     &= 0xFE;
+	if ((ret=i2c_transfer(&msg))) return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+
+		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if ((ret=i2c_transfer(&msg))) return -1;
+	}
+
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if ((ret=i2c_transfer(&msg))) return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+
+		if (len==0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if ((ret=i2c_transfer(&msg))) return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
+		buffer++;
+
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+
+/**
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     &= 0xFE;
+	if (i2c_transfer(&msg)) return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg)) return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
+
+		if (len==0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg)) return -1;
+
+	}
+
+	i2c_reset();
+
+	return 0;
+
+}
+
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define
  2011-03-15  1:36   ` Lei Wen
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
  2011-03-15  3:40     ` [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-15  3:40     ` Lei Wen
  2011-03-15  6:54       ` Heiko Schocher
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform Lei Wen
                       ` (2 subsequent siblings)
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-15  3:40 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/pxa/cpu.c                   |   11 +++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 ------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mvi2c.c                      |  139 +++++++++++++++++++++---------
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 6 files changed, 111 insertions(+), 106 deletions(-)

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..24b59e7 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,14 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
index 7aa49ae..0e37417 100644
--- a/drivers/i2c/mvi2c.c
+++ b/drivers/i2c/mvi2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -30,8 +33,6 @@
  * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
  */
 
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
 #include <common.h>
 #include <asm/io.h>
 
@@ -42,9 +43,41 @@
  *	- I2C_PXA_SLAVE_ADDR
  */
 
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
+extern void i2c_clk_enable(void);
+
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
 
 /*#define	DEBUG_I2C	1	/###* activate local debugging output  */
 #define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
@@ -86,6 +119,21 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct pxa_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
+#define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
 
 /**
  * i2c_pxa_reset: - reset the host controller
@@ -94,21 +142,17 @@ struct i2c_msg {
 
 static void i2c_reset( void )
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
+	PXAI2C_OR(&base->icr, ICR_UR);	/* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
+
+	i2c_clk_enable();
+
+	writel(I2C_PXA_SLAVE_ADDR, &base->isar);/* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
+	PXAI2C_OR(&base->icr, ICR_IUE);		/* enable unit */
 	udelay(100);
 }
 
@@ -121,12 +165,14 @@ static void i2c_reset( void )
  */
 static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
 {
-	int timeout = 10000;
+	int timeout = 10000, isr;
 
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
+	do {
+		isr = readl(&base->isr);
+		udelay(10);
 		if( timeout-- < 0 ) return 0;
-	}
+	} while (((isr & set_mask)!=set_mask)
+		 || ((isr & cleared_mask)!=0));
 
 	return 1;
 }
@@ -162,26 +208,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		PXAI2C_AND(&base->icr, ~ICR_START);
+		PXAI2C_AND(&base->icr, ~ICR_STOP);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			PXAI2C_OR(&base->icr, ICR_START);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			PXAI2C_OR(&base->icr, ICR_STOP);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			PXAI2C_OR(&base->icr, ICR_ACKNAK);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
+		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
+		PXAI2C_OR(&base->icr, ICR_TB);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE,0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		PXAI2C_OR(&base->isr, ISR_ITE);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -196,27 +242,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		PXAI2C_AND(&base->icr, ~ICR_START);
+		PXAI2C_AND(&base->icr, ~ICR_STOP);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			PXAI2C_OR(&base->icr, ICR_START);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			PXAI2C_OR(&base->icr, ICR_STOP);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			PXAI2C_OR(&base->icr, ICR_ACKNAK);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
+		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
+		PXAI2C_OR(&base->icr, ICR_TB);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF,0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
+		PXAI2C_OR(&base->isr, ISR_IRF);
 
 		break;
 
@@ -266,10 +312,19 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
 	/* environment, which might be in a chip on that bus. For details   */
 	/* about this problem see doc/I2C_Edge_Conditions.                  */
+
+	/* disable I2C controller first, otherwhise it thinks we want to    */
+	/* talk to the slave port...                                        */
+	icr = readl(&base->icr);
+	PXAI2C_AND(&base->icr, ~(ICR_SCLE | ICR_IUE));
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..1ddee03 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..682d1ed 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform
  2011-03-15  1:36   ` Lei Wen
                       ` (2 preceding siblings ...)
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define Lei Wen
@ 2011-03-15  3:40     ` Lei Wen
  2011-03-15  6:58       ` Heiko Schocher
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support Lei Wen
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-15  3:40 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   10 ++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h |    2 ++
 board/Marvell/dkb/dkb.c                  |    4 ++++
 include/configs/dkb.h                    |   11 +++++++++++
 5 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..88ecfae 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,10 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +80,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable (void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..041e64c 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -34,6 +34,8 @@
 /* UART2 */
 #define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
 #define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP53_CI2C_SCL		MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP54_CI2C_SDA		MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..75c4b99 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -56,6 +56,17 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
+/*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support
  2011-03-15  1:36   ` Lei Wen
                       ` (3 preceding siblings ...)
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-15  3:40     ` Lei Wen
  2011-03-15  7:01       ` Heiko Schocher
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-15  3:40 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 drivers/i2c/mvi2c.c |   37 ++++++++++++++++++++++++++++++++++++-
 1 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
index 0e37417..ca1add8 100644
--- a/drivers/i2c/mvi2c.c
+++ b/drivers/i2c/mvi2c.c
@@ -131,9 +131,38 @@ struct pxa_i2c {
 	u32 isar;
 };
 
-static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
 #define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
 #define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
+static struct pxa_i2c *base;
+
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
+static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
+static unsigned int current_bus = 0;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct pxa_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if(!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /**
  * i2c_pxa_reset: - reset the host controller
@@ -311,6 +340,12 @@ i2c_transfer_finish:
 
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct pxa_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform
  2011-03-15  1:36   ` Lei Wen
                       ` (4 preceding siblings ...)
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support Lei Wen
@ 2011-03-15  3:40     ` Lei Wen
  2011-03-15  7:08       ` Heiko Schocher
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-15  3:40 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   14 ++++++++++++++
 arch/arm/include/asm/arch-armada100/mfp.h |    4 ++++
 board/Marvell/aspenite/aspenite.c         |    5 +++++
 include/configs/aspenite.h                |   12 ++++++++++++
 4 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..8039ad2 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,14 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +98,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable (void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..f22b5e7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -60,6 +60,10 @@
 #define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
 #define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
 
+/* I2c */
+#define MFP105_CI2C_SDA		MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM
+#define MFP106_CI2C_SCL		MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM
+
 /* More macros can be defined here... */
 
 #define MFP_PIN_MAX	117
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..50f8ed7 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -63,6 +63,18 @@
 #undef CONFIG_ARCH_MISC_INIT
 
 /*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C		1
+#define CONFIG_I2C_MV		1
+#define CONFIG_PXA_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+
+/*
  * Environment variables configurations
  */
 #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place
  2011-03-15  3:40     ` [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-15  6:48       ` Heiko Schocher
  2011-03-17  6:25         ` Lei Wen
  2011-03-15  8:09       ` Wolfgang Denk
  1 sibling, 1 reply; 123+ messages in thread
From: Heiko Schocher @ 2011-03-15  6:48 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> For better sharing with other platform other than pxa's,
> it is more convenient to put the driver to the common place.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> v2: rename previous pxa_i2c to mvi2c.

Maybe a Coding Style cleanup would be good for this file ...
(I know, you don;t wrote this file...)

>  arch/arm/cpu/pxa/Makefile |    1 -
>  arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
>  drivers/i2c/Makefile      |    1 +
>  drivers/i2c/mvi2c.c       |  469 +++++++++++++++++++++++++++++++++++++++++++++

Why you don;t use git format-patch -M ?
If so, I wouldn;t stumbled over the Coding Style ;-)

>  include/configs/innokom.h |    1 +
>  include/configs/xm250.h   |    1 +
>  6 files changed, 472 insertions(+), 470 deletions(-)
>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>  create mode 100644 drivers/i2c/mvi2c.c
> 
[...]
> diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
> new file mode 100644
> index 0000000..7aa49ae
> --- /dev/null
> +++ b/drivers/i2c/mvi2c.c
> @@ -0,0 +1,469 @@
> +/*
> + * (C) Copyright 2000
> + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
> + *
> + * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
> + * Marius Groeger <mgroeger@sysgo.de>
> + *
> + * (C) Copyright 2003 Pengutronix e.K.
> + * Robert Schwebel <r.schwebel@pengutronix.de>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + *
> + * Back ported to the 8xx platform (from the 8260 platform) by
> + * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
> + */
> +
> +/* FIXME: this file is PXA255 specific! What about other XScales? */

As you rename this file to mv, please change this comment.

> +
> +#include <common.h>
> +#include <asm/io.h>
> +
> +#ifdef CONFIG_HARD_I2C
> +
> +/*
> + *	- CONFIG_SYS_I2C_SPEED
> + *	- I2C_PXA_SLAVE_ADDR
> + */
> +
> +#include <asm/arch/hardware.h>
> +#include <asm/arch/pxa-regs.h>
> +#include <i2c.h>
> +
> +/*#define	DEBUG_I2C	1	/###* activate local debugging output  */

Please remove dead code.

> +#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
> +
> +#if (CONFIG_SYS_I2C_SPEED == 400000)
> +#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)

Line too long.

> +#else
> +#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
> +#endif
> +
> +#define I2C_ISR_INIT		0x7FF
> +
> +#ifdef DEBUG_I2C
> +#define PRINTD(x) printf x
> +#else
> +#define PRINTD(x)
> +#endif
> +
> +
> +/* Shall the current transfer have a start/stop condition? */
> +#define I2C_COND_NORMAL		0
> +#define I2C_COND_START		1
> +#define I2C_COND_STOP		2
> +
> +/* Shall the current transfer be ack/nacked or being waited for it? */
> +#define I2C_ACKNAK_WAITACK	1
> +#define I2C_ACKNAK_SENDACK	2
> +#define I2C_ACKNAK_SENDNAK	4
> +
> +/* Specify who shall transfer the data (master or slave) */
> +#define I2C_READ		0
> +#define I2C_WRITE		1
> +
> +/* All transfers are described by this data structure */
> +struct i2c_msg {
> +	u8 condition;
> +	u8 acknack;
> +	u8 direction;
> +	u8 data;
> +};
> +
> +

Only one empty line.

> +/**
> + * i2c_pxa_reset: - reset the host controller
> + *
> + */

Wrong comment style, no empty line after the comment necessary.
Fix globally please.

> +
> +static void i2c_reset( void )

No spaces after "(" and before ")"
Fix globally please.

> +{
> +	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
> +	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
> +	udelay(100);
> +	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
> +#ifdef CONFIG_CPU_MONAHANS
> +	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
> +	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
> +#else /* CONFIG_CPU_MONAHANS */
> +	/* set the global I2C clock on */
> +	writel(readl(CKEN) | CKEN14_I2C, CKEN);
> +#endif
> +	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
> +	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
> +	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
> +	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
> +	udelay(100);
> +}
> +
> +
> +/**
> + * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
> + *	                  are set and cleared
> + *
> + * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
> + */
> +static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )

Line too long.

> +{
> +	int timeout = 10000;
> +
> +	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
              ^                 ^                                         ^
              no space          space around "!="                         space

> +		udelay( 10 );
> +		if( timeout-- < 0 ) return 0;

return please in a new line, please fix globally.

> +	}
> +
> +	return 1;
> +}
> +
> +
> +/**
> + * i2c_transfer: - Transfer one byte over the i2c bus
> + *
> + * This function can tranfer a byte over the i2c bus in both directions.
> + * It is used by the public API functions.
> + *
> + * @return:  0: transfer successful
> + *          -1: message is empty
> + *          -2: transmit timeout
> + *          -3: ACK missing
> + *          -4: receive timeout
> + *          -5: illegal parameters
> + *          -6: bus is busy and couldn't be aquired
> + */
> +int i2c_transfer(struct i2c_msg *msg)
> +{
> +	int ret;
> +
> +	if (!msg)
> +		goto transfer_error_msg_empty;
> +
> +	switch(msg->direction) {
> +

no empty line please.

> +	case I2C_WRITE:
> +
> +		/* check if bus is not busy */
> +		if (!i2c_isr_set_cleared(0,ISR_IBB))
                                           ^
                                           add a space please
> +			goto transfer_error_bus_busy;
> +
> +		/* start transmission */
> +		writel(readl(ICR) & ~ICR_START, ICR);
> +		writel(readl(ICR) & ~ICR_STOP, ICR);
> +		writel(msg->data, IDBR);
> +		if (msg->condition == I2C_COND_START)
> +			writel(readl(ICR) | ICR_START, ICR);
> +		if (msg->condition == I2C_COND_STOP)
> +			writel(readl(ICR) | ICR_STOP, ICR);
> +		if (msg->acknack == I2C_ACKNAK_SENDNAK)
> +			writel(readl(ICR) | ICR_ACKNAK, ICR);
> +		if (msg->acknack == I2C_ACKNAK_SENDACK)
> +			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> +		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> +		writel(readl(ICR) | ICR_TB, ICR);
> +
> +		/* transmit register empty? */
> +		if (!i2c_isr_set_cleared(ISR_ITE,0))
                                                 ^
                                                 here too, fix
                                                 globally please.

> +			goto transfer_error_transmit_timeout;
> +
> +		/* clear 'transmit empty' state */
> +		writel(readl(ISR) | ISR_ITE, ISR);
> +
> +		/* wait for ACK from slave */
> +		if (msg->acknack == I2C_ACKNAK_WAITACK)
> +			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
> +				goto transfer_error_ack_missing;
> +		break;
> +
> +	case I2C_READ:
> +
> +		/* check if bus is not busy */
> +		if (!i2c_isr_set_cleared(0,ISR_IBB))
> +			goto transfer_error_bus_busy;
> +
> +		/* start receive */
> +		writel(readl(ICR) & ~ICR_START, ICR);
> +		writel(readl(ICR) & ~ICR_STOP, ICR);
> +		if (msg->condition == I2C_COND_START)
> +			writel(readl(ICR) | ICR_START, ICR);
> +		if (msg->condition == I2C_COND_STOP)
> +			writel(readl(ICR) | ICR_STOP, ICR);
> +		if (msg->acknack == I2C_ACKNAK_SENDNAK)
> +			writel(readl(ICR) | ICR_ACKNAK, ICR);
> +		if (msg->acknack == I2C_ACKNAK_SENDACK)
> +			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> +		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> +		writel(readl(ICR) | ICR_TB, ICR);
> +
> +		/* receive register full? */
> +		if (!i2c_isr_set_cleared(ISR_IRF,0))
> +			goto transfer_error_receive_timeout;
> +
> +		msg->data = readl(IDBR);
> +
> +		/* clear 'receive empty' state */
> +		writel(readl(ISR) | ISR_IRF, ISR);
> +
> +		break;
> +
> +	default:
> +
> +		goto transfer_error_illegal_param;
> +
> +	}
> +
> +	return 0;
> +
> +transfer_error_msg_empty:
> +		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
> +		ret = -1; goto i2c_transfer_finish;
> +
> +transfer_error_transmit_timeout:
> +		PRINTD(("i2c_transfer: error: transmit timeout\n"));
> +		ret = -2; goto i2c_transfer_finish;
> +
> +transfer_error_ack_missing:
> +		PRINTD(("i2c_transfer: error: ACK missing\n"));
> +		ret = -3; goto i2c_transfer_finish;
> +
> +transfer_error_receive_timeout:
> +		PRINTD(("i2c_transfer: error: receive timeout\n"));
> +		ret = -4; goto i2c_transfer_finish;
> +
> +transfer_error_illegal_param:
> +		PRINTD(("i2c_transfer: error: illegal parameters\n"));
> +		ret = -5; goto i2c_transfer_finish;
> +
> +transfer_error_bus_busy:
> +		PRINTD(("i2c_transfer: error: bus is busy\n"));
> +		ret = -6; goto i2c_transfer_finish;
> +
> +i2c_transfer_finish:
> +		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
> +		i2c_reset();
> +		return ret;
> +
> +}
> +
> +/* ------------------------------------------------------------------------ */
> +/* API Functions                                                            */
> +/* ------------------------------------------------------------------------ */
> +
> +void i2c_init(int speed, int slaveaddr)
> +{
> +#ifdef CONFIG_SYS_I2C_INIT_BOARD
> +	/* call board specific i2c bus reset routine before accessing the   */
> +	/* environment, which might be in a chip on that bus. For details   */
> +	/* about this problem see doc/I2C_Edge_Conditions.                  */
> +	i2c_init_board();
> +#endif
> +}
> +
> +
> +/**
> + * i2c_probe: - Test if a chip answers for a given i2c address
> + *
> + * @chip:	address of the chip which is searched for
> + * @return:	0 if a chip was found, -1 otherwhise
> + */
> +
> +int i2c_probe(uchar chip)
> +{
> +	struct i2c_msg msg;
> +
> +	i2c_reset();
> +
> +	msg.condition = I2C_COND_START;
> +	msg.acknack   = I2C_ACKNAK_WAITACK;
> +	msg.direction = I2C_WRITE;
> +	msg.data      = (chip << 1) + 1;
> +	if (i2c_transfer(&msg)) return -1;
> +
> +	msg.condition = I2C_COND_STOP;
> +	msg.acknack   = I2C_ACKNAK_SENDNAK;
> +	msg.direction = I2C_READ;
> +	msg.data      = 0x00;
> +	if (i2c_transfer(&msg)) return -1;
> +
> +	return 0;
> +}
> +
> +
> +/**
> + * i2c_read: - Read multiple bytes from an i2c device
> + *
> + * The higher level routines take into account that this function is only
> + * called with len < page length of the device (see configuration file)
> + *
> + * @chip:	address of the chip which is to be read
> + * @addr:	i2c data address within the chip
> + * @alen:	length of the i2c data address (1..2 bytes)
> + * @buffer:	where to write the data
> + * @len:	how much byte do we want to read
> + * @return:	0 in case of success
> + */
> +
> +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	struct i2c_msg msg;
> +	u8 addr_bytes[3]; /* lowest...highest byte of data address */
> +	int ret;
> +
> +	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));

Line too long, add space after ","

> +
> +	i2c_reset();
> +
> +	/* dummy chip address write */
> +	PRINTD(("i2c_read: dummy chip address write\n"));
> +	msg.condition = I2C_COND_START;
> +	msg.acknack   = I2C_ACKNAK_WAITACK;
> +	msg.direction = I2C_WRITE;
> +	msg.data      = (chip << 1);
> +	msg.data     &= 0xFE;
> +	if ((ret=i2c_transfer(&msg))) return -1;

Please move the ret = i2c_transfer out of the if condition
"return -1" please in a new line.

> +
> +	/*
> +	 * send memory address bytes;
> +	 * alen defines how much bytes we have to send.
> +	 */
> +	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
> +	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
> +	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
> +	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
> +
> +	while (--alen >= 0) {
> +
> +		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
> +		msg.condition = I2C_COND_NORMAL;
> +		msg.acknack   = I2C_ACKNAK_WAITACK;
> +		msg.direction = I2C_WRITE;
> +		msg.data      = addr_bytes[alen];
> +		if ((ret=i2c_transfer(&msg))) return -1;
> +	}
> +
> +
> +	/* start read sequence */
> +	PRINTD(("i2c_read: start read sequence\n"));
> +	msg.condition = I2C_COND_START;
> +	msg.acknack   = I2C_ACKNAK_WAITACK;
> +	msg.direction = I2C_WRITE;
> +	msg.data      = (chip << 1);
> +	msg.data     |= 0x01;
> +	if ((ret=i2c_transfer(&msg))) return -1;
> +
> +	/* read bytes; send NACK at last byte */
> +	while (len--) {
> +
> +		if (len==0) {
> +			msg.condition = I2C_COND_STOP;
> +			msg.acknack   = I2C_ACKNAK_SENDNAK;
> +		} else {
> +			msg.condition = I2C_COND_NORMAL;
> +			msg.acknack   = I2C_ACKNAK_SENDACK;
> +		}
> +
> +		msg.direction = I2C_READ;
> +		msg.data      = 0x00;
> +		if ((ret=i2c_transfer(&msg))) return -1;
> +
> +		*buffer = msg.data;
> +		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
> +		buffer++;
> +
> +	}
> +
> +	i2c_reset();
> +
> +	return 0;
> +}
> +
> +
> +/**
> + * i2c_write: -  Write multiple bytes to an i2c device
> + *
> + * The higher level routines take into account that this function is only
> + * called with len < page length of the device (see configuration file)
> + *
> + * @chip:	address of the chip which is to be written
> + * @addr:	i2c data address within the chip
> + * @alen:	length of the i2c data address (1..2 bytes)
> + * @buffer:	where to find the data to be written
> + * @len:	how much byte do we want to read
> + * @return:	0 in case of success
> + */
> +
> +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	struct i2c_msg msg;
> +	u8 addr_bytes[3]; /* lowest...highest byte of data address */
> +
> +	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
> +
> +	i2c_reset();
> +
> +	/* chip address write */
> +	PRINTD(("i2c_write: chip address write\n"));
> +	msg.condition = I2C_COND_START;
> +	msg.acknack   = I2C_ACKNAK_WAITACK;
> +	msg.direction = I2C_WRITE;
> +	msg.data      = (chip << 1);
> +	msg.data     &= 0xFE;
> +	if (i2c_transfer(&msg)) return -1;
> +
> +	/*
> +	 * send memory address bytes;
> +	 * alen defines how much bytes we have to send.
> +	 */
> +	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
> +	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
> +	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
> +
> +	while (--alen >= 0) {
> +
> +		PRINTD(("i2c_write: send memory word address\n"));
> +		msg.condition = I2C_COND_NORMAL;
> +		msg.acknack   = I2C_ACKNAK_WAITACK;
> +		msg.direction = I2C_WRITE;
> +		msg.data      = addr_bytes[alen];
> +		if (i2c_transfer(&msg)) return -1;
> +	}
> +
> +	/* write bytes; send NACK at last byte */
> +	while (len--) {
> +
> +		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
> +
> +		if (len==0)
> +			msg.condition = I2C_COND_STOP;
> +		else
> +			msg.condition = I2C_COND_NORMAL;
> +
> +		msg.acknack   = I2C_ACKNAK_WAITACK;
> +		msg.direction = I2C_WRITE;
> +		msg.data      = *(buffer++);
> +
> +		if (i2c_transfer(&msg)) return -1;
> +
> +	}
> +
> +	i2c_reset();
> +
> +	return 0;
> +
> +}
> +
> +#endif	/* CONFIG_HARD_I2C */
> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
> index d8fcbdb..0ea73c9 100644
> --- a/include/configs/innokom.h
> +++ b/include/configs/innokom.h
> @@ -140,6 +140,7 @@
>  /*
>   * I2C bus
>   */
> +#define CONFIG_I2C_MV			1
>  #define CONFIG_HARD_I2C			1
>  #define CONFIG_SYS_I2C_SPEED			50000
>  #define CONFIG_SYS_I2C_SLAVE			0xfe
> diff --git a/include/configs/xm250.h b/include/configs/xm250.h
> index 497cb91..b4b940a 100644
> --- a/include/configs/xm250.h
> +++ b/include/configs/xm250.h
> @@ -61,6 +61,7 @@
>  /*
>   * I2C bus
>   */
> +#define CONFIG_I2C_MV			1
>  #define CONFIG_HARD_I2C			1
>  #define CONFIG_SYS_I2C_SPEED			50000
>  #define CONFIG_SYS_I2C_SLAVE			0xfe

Thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define Lei Wen
@ 2011-03-15  6:54       ` Heiko Schocher
  2011-03-17  6:28         ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Heiko Schocher @ 2011-03-15  6:54 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  arch/arm/cpu/pxa/cpu.c                   |   11 +++
>  arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 ------------
>  board/innokom/innokom.c                  |    9 +--
>  drivers/i2c/mvi2c.c                      |  139 +++++++++++++++++++++---------
>  include/configs/innokom.h                |    1 +
>  include/configs/xm250.h                  |    1 +
>  6 files changed, 111 insertions(+), 106 deletions(-)
> 
> diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
> index 7d49cbb..24b59e7 100644
> --- a/arch/arm/cpu/pxa/cpu.c
> +++ b/arch/arm/cpu/pxa/cpu.c
> @@ -318,3 +318,14 @@ int arch_cpu_init(void)
>  	pxa_clock_setup();
>  	return 0;
>  }
> +
> +void i2c_clk_enable(void)
> +{
> +#ifdef CONFIG_CPU_MONAHANS
> +	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
> +	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
> +#else /* CONFIG_CPU_MONAHANS */
> +	/* set the global I2C clock on */
> +	writel(readl(CKEN) | CKEN14_I2C, CKEN);
> +#endif
> +}
> diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
> index 65a387f..109fdc0 100644
> --- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
> +++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
> @@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
>  		IrSR_XMITIR_IR_MODE)
>  
>  /*
> - * I2C registers
> - */
> -#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
> -#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
> -#define ICR		0x40301690  /* I2C Control Register - ICR */
> -#define ISR		0x40301698  /* I2C Status Register - ISR */
> -#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
> -
> -#ifdef CONFIG_CPU_MONAHANS
> -#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
> -#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
> -#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
> -#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
> -#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
> -#else
> -#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
> -#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
> -#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
> -#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
> -#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
> -#endif
> -
> -/* ----- Control register bits ---------------------------------------- */
> -
> -#define ICR_START	0x1		/* start bit */
> -#define ICR_STOP	0x2		/* stop bit */
> -#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
> -#define ICR_TB		0x8		/* transfer byte bit */
> -#define ICR_MA		0x10		/* master abort */
> -#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
> -#define ICR_IUE		0x40		/* unit enable */
> -#define ICR_GCD		0x80		/* general call disable */
> -#define ICR_ITEIE	0x100		/* enable tx interrupts */
> -#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
> -#define ICR_BEIE	0x400		/* enable bus error ints */
> -#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
> -#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
> -#define ICR_SADIE	0x2000		/* slave address detected int enable */
> -#define ICR_UR		0x4000		/* unit reset */
> -#define ICR_FM		0x8000		/* Fast Mode */
> -
> -/* ----- Status register bits ----------------------------------------- */
> -
> -#define ISR_RWM		0x1		/* read/write mode */
> -#define ISR_ACKNAK	0x2		/* ack/nak status */
> -#define ISR_UB		0x4		/* unit busy */
> -#define ISR_IBB		0x8		/* bus busy */
> -#define ISR_SSD		0x10		/* slave stop detected */
> -#define ISR_ALD		0x20		/* arbitration loss detected */
> -#define ISR_ITE		0x40		/* tx buffer empty */
> -#define ISR_IRF		0x80		/* rx buffer full */
> -#define ISR_GCAD	0x100		/* general call address detected */
> -#define ISR_SAD		0x200		/* slave address detected */
> -#define ISR_BED		0x400		/* bus error no ACK/NAK */
> -
> -/*
>   * Serial Audio Controller
>   */
>  /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
> diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
> index e658c35..22de7e3 100644
> --- a/board/innokom/innokom.c
> +++ b/board/innokom/innokom.c
> @@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
>   */
>  int i2c_init_board(void)
>  {
> -	int i, icr;
> -
> -	/* disable I2C controller first, otherwhise it thinks we want to    */
> -	/* talk to the slave port...                                        */
> -	icr = readl(ICR);
> -	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
> +	int i;
>  
>  	/* set gpio pin low _before_ we change direction to output          */
>  	writel(GPIO_bit(70), GPCR(70));
> @@ -63,8 +58,6 @@ int i2c_init_board(void)
>  		udelay(10);
>  	}
>  
> -	writel(icr, ICR);
> -
>  	return 0;
>  }
>  
> diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
> index 7aa49ae..0e37417 100644
> --- a/drivers/i2c/mvi2c.c
> +++ b/drivers/i2c/mvi2c.c
> @@ -8,6 +8,9 @@
>   * (C) Copyright 2003 Pengutronix e.K.
>   * Robert Schwebel <r.schwebel@pengutronix.de>
>   *
> + * (C) Copyright 2011 Marvell Inc.
> + * Lei Wen <leiwen@marvell.com>
> + *
>   * See file CREDITS for list of people who contributed to this
>   * project.
>   *
> @@ -30,8 +33,6 @@
>   * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
>   */
>  
> -/* FIXME: this file is PXA255 specific! What about other XScales? */

Ah, you remove this comment here, Ok!

> -
>  #include <common.h>
>  #include <asm/io.h>
>  
> @@ -42,9 +43,41 @@
>   *	- I2C_PXA_SLAVE_ADDR
>   */
>  
> -#include <asm/arch/hardware.h>
> -#include <asm/arch/pxa-regs.h>
>  #include <i2c.h>
> +extern void i2c_clk_enable(void);

Hmm... as you define this function in arch/arm/cpu/pxa/cpu.c
there should be somewhere an appropriate header file, where
it fits in, so we can avoid this extern.

> +
> +/* ----- Control register bits ---------------------------------------- */
> +
> +#define ICR_START	0x1		/* start bit */
> +#define ICR_STOP	0x2		/* stop bit */
> +#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
> +#define ICR_TB		0x8		/* transfer byte bit */
> +#define ICR_MA		0x10		/* master abort */
> +#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
> +#define ICR_IUE		0x40		/* unit enable */
> +#define ICR_GCD		0x80		/* general call disable */
> +#define ICR_ITEIE	0x100		/* enable tx interrupts */
> +#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
> +#define ICR_BEIE	0x400		/* enable bus error ints */
> +#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
> +#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
> +#define ICR_SADIE	0x2000		/* slave address detected int enable */
> +#define ICR_UR		0x4000		/* unit reset */
> +#define ICR_FM		0x8000		/* Fast Mode */
> +
> +/* ----- Status register bits ----------------------------------------- */
> +
> +#define ISR_RWM		0x1		/* read/write mode */
> +#define ISR_ACKNAK	0x2		/* ack/nak status */
> +#define ISR_UB		0x4		/* unit busy */
> +#define ISR_IBB		0x8		/* bus busy */
> +#define ISR_SSD		0x10		/* slave stop detected */
> +#define ISR_ALD		0x20		/* arbitration loss detected */
> +#define ISR_ITE		0x40		/* tx buffer empty */
> +#define ISR_IRF		0x80		/* rx buffer full */
> +#define ISR_GCAD	0x100		/* general call address detected */
> +#define ISR_SAD		0x200		/* slave address detected */
> +#define ISR_BED		0x400		/* bus error no ACK/NAK */
>  
>  /*#define	DEBUG_I2C	1	/###* activate local debugging output  */
>  #define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
> @@ -86,6 +119,21 @@ struct i2c_msg {
>  	u8 data;
>  };
>  
> +struct pxa_i2c {
> +	u32 ibmr;
> +	u32 pad0;
> +	u32 idbr;
> +	u32 pad1;
> +	u32 icr;
> +	u32 pad2;
> +	u32 isr;
> +	u32 pad3;
> +	u32 isar;
> +};
> +
> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> +#define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
> +#define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
>  
>  /**
>   * i2c_pxa_reset: - reset the host controller
> @@ -94,21 +142,17 @@ struct i2c_msg {
>  
>  static void i2c_reset( void )
>  {
> -	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
> -	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
> +	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
> +	PXAI2C_OR(&base->icr, ICR_UR);	/* reset the unit */
>  	udelay(100);
> -	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
> -#ifdef CONFIG_CPU_MONAHANS
> -	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
> -	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
> -#else /* CONFIG_CPU_MONAHANS */
> -	/* set the global I2C clock on */
> -	writel(readl(CKEN) | CKEN14_I2C, CKEN);
> -#endif
> -	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
> -	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
> -	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
> -	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
> +	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
> +
> +	i2c_clk_enable();
> +
> +	writel(I2C_PXA_SLAVE_ADDR, &base->isar);/* set our slave address */
> +	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */
> +	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
> +	PXAI2C_OR(&base->icr, ICR_IUE);		/* enable unit */
>  	udelay(100);
>  }
>  
> @@ -121,12 +165,14 @@ static void i2c_reset( void )
>   */
>  static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
>  {
> -	int timeout = 10000;
> +	int timeout = 10000, isr;
>  
> -	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
> -		udelay( 10 );
> +	do {
> +		isr = readl(&base->isr);
> +		udelay(10);
>  		if( timeout-- < 0 ) return 0;
> -	}
> +	} while (((isr & set_mask)!=set_mask)
                                  ^
                                  Spaces around "!="
                                  Please fix globally, thanks!
> +		 || ((isr & cleared_mask)!=0));
>  
>  	return 1;
>  }
> @@ -162,26 +208,26 @@ int i2c_transfer(struct i2c_msg *msg)
>  			goto transfer_error_bus_busy;
>  
>  		/* start transmission */
> -		writel(readl(ICR) & ~ICR_START, ICR);
> -		writel(readl(ICR) & ~ICR_STOP, ICR);
> -		writel(msg->data, IDBR);
> +		PXAI2C_AND(&base->icr, ~ICR_START);
> +		PXAI2C_AND(&base->icr, ~ICR_STOP);
> +		writel(msg->data, &base->idbr);
>  		if (msg->condition == I2C_COND_START)
> -			writel(readl(ICR) | ICR_START, ICR);
> +			PXAI2C_OR(&base->icr, ICR_START);
>  		if (msg->condition == I2C_COND_STOP)
> -			writel(readl(ICR) | ICR_STOP, ICR);
> +			PXAI2C_OR(&base->icr, ICR_STOP);
>  		if (msg->acknack == I2C_ACKNAK_SENDNAK)
> -			writel(readl(ICR) | ICR_ACKNAK, ICR);
> +			PXAI2C_OR(&base->icr, ICR_ACKNAK);
>  		if (msg->acknack == I2C_ACKNAK_SENDACK)
> -			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> -		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> -		writel(readl(ICR) | ICR_TB, ICR);
> +			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
> +		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
> +		PXAI2C_OR(&base->icr, ICR_TB);
>  
>  		/* transmit register empty? */
>  		if (!i2c_isr_set_cleared(ISR_ITE,0))
>  			goto transfer_error_transmit_timeout;
>  
>  		/* clear 'transmit empty' state */
> -		writel(readl(ISR) | ISR_ITE, ISR);
> +		PXAI2C_OR(&base->isr, ISR_ITE);
>  
>  		/* wait for ACK from slave */
>  		if (msg->acknack == I2C_ACKNAK_WAITACK)
> @@ -196,27 +242,27 @@ int i2c_transfer(struct i2c_msg *msg)
>  			goto transfer_error_bus_busy;
>  
>  		/* start receive */
> -		writel(readl(ICR) & ~ICR_START, ICR);
> -		writel(readl(ICR) & ~ICR_STOP, ICR);
> +		PXAI2C_AND(&base->icr, ~ICR_START);
> +		PXAI2C_AND(&base->icr, ~ICR_STOP);
>  		if (msg->condition == I2C_COND_START)
> -			writel(readl(ICR) | ICR_START, ICR);
> +			PXAI2C_OR(&base->icr, ICR_START);
>  		if (msg->condition == I2C_COND_STOP)
> -			writel(readl(ICR) | ICR_STOP, ICR);
> +			PXAI2C_OR(&base->icr, ICR_STOP);
>  		if (msg->acknack == I2C_ACKNAK_SENDNAK)
> -			writel(readl(ICR) | ICR_ACKNAK, ICR);
> +			PXAI2C_OR(&base->icr, ICR_ACKNAK);
>  		if (msg->acknack == I2C_ACKNAK_SENDACK)
> -			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> -		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> -		writel(readl(ICR) | ICR_TB, ICR);
> +			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
> +		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
> +		PXAI2C_OR(&base->icr, ICR_TB);
>  
>  		/* receive register full? */
>  		if (!i2c_isr_set_cleared(ISR_IRF,0))
>  			goto transfer_error_receive_timeout;
>  
> -		msg->data = readl(IDBR);
> +		msg->data = readl(&base->idbr);
>  
>  		/* clear 'receive empty' state */
> -		writel(readl(ISR) | ISR_IRF, ISR);
> +		PXAI2C_OR(&base->isr, ISR_IRF);
>  
>  		break;
>  
> @@ -266,10 +312,19 @@ i2c_transfer_finish:
>  void i2c_init(int speed, int slaveaddr)
>  {
>  #ifdef CONFIG_SYS_I2C_INIT_BOARD
> +	u32 icr;
>  	/* call board specific i2c bus reset routine before accessing the   */
>  	/* environment, which might be in a chip on that bus. For details   */
>  	/* about this problem see doc/I2C_Edge_Conditions.                  */
> +
> +	/* disable I2C controller first, otherwhise it thinks we want to    */
> +	/* talk to the slave port...                                        */

Wrong comment style, please fix

> +	icr = readl(&base->icr);
> +	PXAI2C_AND(&base->icr, ~(ICR_SCLE | ICR_IUE));
> +
>  	i2c_init_board();
> +
> +	writel(icr, &base->icr);
>  #endif
>  }
>  
> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
> index 0ea73c9..1ddee03 100644
> --- a/include/configs/innokom.h
> +++ b/include/configs/innokom.h
> @@ -141,6 +141,7 @@
>   * I2C bus
>   */
>  #define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0x40301680

Hmm.. is there no define for this magic value?

>  #define CONFIG_HARD_I2C			1
>  #define CONFIG_SYS_I2C_SPEED			50000
>  #define CONFIG_SYS_I2C_SLAVE			0xfe
> diff --git a/include/configs/xm250.h b/include/configs/xm250.h
> index b4b940a..682d1ed 100644
> --- a/include/configs/xm250.h
> +++ b/include/configs/xm250.h
> @@ -62,6 +62,7 @@
>   * I2C bus
>   */
>  #define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0x40301680
>  #define CONFIG_HARD_I2C			1
>  #define CONFIG_SYS_I2C_SPEED			50000
>  #define CONFIG_SYS_I2C_SLAVE			0xfe

Apart from this few comments patch looks fine, thanks!

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-15  6:58       ` Heiko Schocher
  0 siblings, 0 replies; 123+ messages in thread
From: Heiko Schocher @ 2011-03-15  6:58 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> Add i2c support to dkb board with pantheon soc.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   10 ++++++++++
>  arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
>  arch/arm/include/asm/arch-pantheon/mfp.h |    2 ++
>  board/Marvell/dkb/dkb.c                  |    4 ++++
>  include/configs/dkb.h                    |   11 +++++++++++
>  5 files changed, 30 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> index 9ddc77c..88ecfae 100644
> --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> @@ -59,6 +59,10 @@ int arch_cpu_init(void)
>  	/* Enable GPIO clock */
>  	writel(APBC_APBCLK, &apbclkres->gpio);
>  
> +	/* Enable I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
> +
>  	icache_enable();
>  
>  	return 0;
> @@ -76,3 +80,9 @@ int print_cpuinfo(void)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_I2C_MV
> +void i2c_clk_enable (void)
> +{
> +}
> +#endif
> diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
> index 30f4393..60955c5 100644
> --- a/arch/arm/include/asm/arch-pantheon/cpu.h
> +++ b/arch/arm/include/asm/arch-pantheon/cpu.h
> @@ -50,7 +50,9 @@ struct panthapb_registers {
>  	u32 uart0;	/*0x000*/
>  	u32 uart1;	/*0x004*/
>  	u32 gpio;	/*0x008*/
> -	u8 pad0[0x034 - 0x08 - 4];
> +	u8 pad0[0x02c - 0x08 - 4];
> +	u32 twsi;	/*0x02c*/
> +	u8 pad1[0x034 - 0x2c - 4];
>  	u32 timers;	/*0x034*/
>  };
>  
> diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
> index fb291cf..041e64c 100644
> --- a/arch/arm/include/asm/arch-pantheon/mfp.h
> +++ b/arch/arm/include/asm/arch-pantheon/mfp.h
> @@ -34,6 +34,8 @@
>  /* UART2 */
>  #define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
>  #define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
> +#define MFP53_CI2C_SCL		MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM
> +#define MFP54_CI2C_SDA		MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM

Please add braces around this multiple or concatenation

>  /* More macros can be defined here... */
>  
> diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
> index 72a2d2a..00f73e7 100644
> --- a/board/Marvell/dkb/dkb.c
> +++ b/board/Marvell/dkb/dkb.c
> @@ -36,6 +36,10 @@ int board_early_init_f(void)
>  		MFP47_UART2_RXD,
>  		MFP48_UART2_TXD,
>  
> +		/* I2C */
> +		MFP53_CI2C_SCL,
> +		MFP54_CI2C_SDA,
> +
>  		MFP_EOC		/*End of configureation*/
>  	};
>  	/* configure MFP's */
> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
> index 638af5e..75c4b99 100644
> --- a/include/configs/dkb.h
> +++ b/include/configs/dkb.h
> @@ -56,6 +56,17 @@
>  #include "mv-common.h"
>  
>  #undef CONFIG_ARCH_MISC_INIT
> +
> +/*
> + * I2C definition
> + */
> +#define CONFIG_CMD_I2C
> +#define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0xd4011000
> +#define CONFIG_HARD_I2C			1
> +#define CONFIG_SYS_I2C_SPEED		0
> +#define CONFIG_SYS_I2C_SLAVE		0xfe
> +
>  /*
>   * Environment variables configurations
>   */

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support Lei Wen
@ 2011-03-15  7:01       ` Heiko Schocher
  0 siblings, 0 replies; 123+ messages in thread
From: Heiko Schocher @ 2011-03-15  7:01 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  drivers/i2c/mvi2c.c |   37 ++++++++++++++++++++++++++++++++++++-
>  1 files changed, 36 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
> index 0e37417..ca1add8 100644
> --- a/drivers/i2c/mvi2c.c
> +++ b/drivers/i2c/mvi2c.c
> @@ -131,9 +131,38 @@ struct pxa_i2c {
>  	u32 isar;
>  };
>  
> -static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
>  #define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
>  #define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
> +static struct pxa_i2c *base;
> +
> +#ifdef CONFIG_I2C_MULTI_BUS
> +static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
> +static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
> +static unsigned int current_bus = 0;
> +
> +int i2c_set_bus_num(unsigned int bus)
> +{
> +	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
> +		printf("Bad bus: %d\n", bus);
> +		return -1;
> +	}
> +
> +	base = (struct pxa_i2c *)i2c_regs[bus];
> +	current_bus = bus;
> +
> +	if(!bus_initialized[current_bus]) {
          ^
          add a space here, thanks

> +		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> +		bus_initialized[current_bus] = 1;
> +	}
> +
> +	return 0;
> +}
> +
> +unsigned int i2c_get_bus_num(void)
> +{
> +	return current_bus;
> +}
> +#endif
>  
>  /**
>   * i2c_pxa_reset: - reset the host controller
> @@ -311,6 +340,12 @@ i2c_transfer_finish:
>  
>  void i2c_init(int speed, int slaveaddr)
>  {
> +#ifdef CONFIG_I2C_MULTI_BUS
> +	base = (struct pxa_i2c *)i2c_regs[current_bus];
> +#else
> +	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> +#endif
> +
>  #ifdef CONFIG_SYS_I2C_INIT_BOARD
>  	u32 icr;
>  	/* call board specific i2c bus reset routine before accessing the   */

beside of that, your patch looks good.

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform
  2011-03-15  3:40     ` [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform Lei Wen
@ 2011-03-15  7:08       ` Heiko Schocher
  2011-03-17  6:38         ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Heiko Schocher @ 2011-03-15  7:08 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  arch/arm/cpu/arm926ejs/armada100/cpu.c    |   14 ++++++++++++++
>  arch/arm/include/asm/arch-armada100/mfp.h |    4 ++++
>  board/Marvell/aspenite/aspenite.c         |    5 +++++
>  include/configs/aspenite.h                |   12 ++++++++++++
>  4 files changed, 35 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> index 62aa175..8039ad2 100644
> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> @@ -62,6 +62,14 @@ int arch_cpu_init(void)
>  	/* Enable GPIO clock */
>  	writel(APBC_APBCLK, &apb1clkres->gpio);
>  
> +	/* Enable general I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
> +
> +	/* Enable power I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
> +

If boards based on this cpu type don;t use i2c, i2c clock and
power would be enabled ... wouldn;t it be better, if we enable
this only if CONFIG_I2C_MV is defined?

Hmm.. are the comments OK? In the first "block" you only
use twsi0 register, in the second "block" only twsi1 ...?

>  	/*
>  	 * Enable Functional and APB clock at 14.7456MHz
>  	 * for configured UART console
> @@ -90,3 +98,9 @@ int print_cpuinfo(void)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_I2C_MV
> +void i2c_clk_enable (void)
> +{
> +}
> +#endif
> diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
> index d21a79f..f22b5e7 100644
> --- a/arch/arm/include/asm/arch-armada100/mfp.h
> +++ b/arch/arm/include/asm/arch-armada100/mfp.h
> @@ -60,6 +60,10 @@
>  #define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
>  #define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
>  
> +/* I2c */
> +#define MFP105_CI2C_SDA		MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM
> +#define MFP106_CI2C_SCL		MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM
> +

Please add braces around this multiple or concatenation

>  /* More macros can be defined here... */
>  
>  #define MFP_PIN_MAX	117
> diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
> index 046ffd6..34ac7aa 100644
> --- a/board/Marvell/aspenite/aspenite.c
> +++ b/board/Marvell/aspenite/aspenite.c
> @@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
>  int board_early_init_f(void)
>  {
>  	u32 mfp_cfg[] = {
> +		/* I2C */
> +		MFP105_CI2C_SDA,
> +		MFP106_CI2C_SCL,
> +
>  		/* Enable Console on UART1 */
>  		MFP107_UART1_RXD,
>  		MFP108_UART1_TXD,
> +
>  		MFP_EOC		/*End of configureation*/
>  	};
>  	/* configure MFP's */
> diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
> index fd35f3e..50f8ed7 100644
> --- a/include/configs/aspenite.h
> +++ b/include/configs/aspenite.h
> @@ -63,6 +63,18 @@
>  #undef CONFIG_ARCH_MISC_INIT
>  
>  /*
> + * I2C definition
> + */
> +#define CONFIG_CMD_I2C		1
> +#define CONFIG_I2C_MV		1
> +#define CONFIG_PXA_I2C_NUM	2
> +#define CONFIG_I2C_MULTI_BUS	1
> +#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
> +#define CONFIG_HARD_I2C		1
> +#define CONFIG_SYS_I2C_SPEED	0
> +#define CONFIG_SYS_I2C_SLAVE	0xfe
> +
> +/*
>   * Environment variables configurations
>   */
>  #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */

Thanks!

bye,
Heiko

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place
  2011-03-15  3:40     ` [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place Lei Wen
  2011-03-15  6:48       ` Heiko Schocher
@ 2011-03-15  8:09       ` Wolfgang Denk
  1 sibling, 0 replies; 123+ messages in thread
From: Wolfgang Denk @ 2011-03-15  8:09 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <1300160443-12552-2-git-send-email-leiwen@marvell.com> you wrote:
> For better sharing with other platform other than pxa's,
> it is more convenient to put the driver to the common place.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> v2: rename previous pxa_i2c to mvi2c.
> 
>  arch/arm/cpu/pxa/Makefile |    1 -
>  arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
>  drivers/i2c/Makefile      |    1 +
>  drivers/i2c/mvi2c.c       |  469 +++++++++++++++++++++++++++++++++++++++++++++

I object against the name "mvi2c" - it's impossible to understand what
this is supposed to mean.  Please make this mv_i2c or marvell_i2c or
similar, so we can see that "mv" or "marvell" is just a prefix.

Thanks.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Testing can show the presense of bugs, but not their absence.
                                                   -- Edsger Dijkstra

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
@ 2011-03-15  8:12       ` Wolfgang Denk
  2011-03-17  6:26         ` Lei Wen
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
                         ` (5 subsequent siblings)
  6 siblings, 1 reply; 123+ messages in thread
From: Wolfgang Denk @ 2011-03-15  8:12 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <1300160443-12552-1-git-send-email-leiwen@marvell.com> you wrote:
> V2:
> rename the previous pxa_i2c to mvi2c, since this driver would be shared
> by many other Marvell platforms.
> 
> Lei Wen (5):
>   pxa: move i2c driver to the common place
>   mvi2c: use structure to replace the direclty define
>   I2C: add i2c support for Pantheon platform
>   I2C: mvi2c: add multi bus support
>   I2C: add i2c support for Armada100 platform

Checkpatch says:

[U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place
total: 57 errors, 7 warnings, 497 lines checked
[U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the
total: 2 errors, 1 warnings, 333 lines checked
[U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform
total: 2 errors, 1 warnings, 64 lines checked
[U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support
total: 2 errors, 0 warnings, 51 lines checked
[U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform
total: 2 errors, 1 warnings, 65 lines checked

Please cleanup!

and next time please run checkpatch _before_ submitting!

Thanks.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
There is, however, a strange, musty smell in the air that reminds  me
of something...hmm...yes...I've got it...there's a VMS nearby, or I'm
a Blit.          - Larry Wall in Configure from the perl distribution

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place
  2011-03-15  6:48       ` Heiko Schocher
@ 2011-03-17  6:25         ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:25 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On Tue, Mar 15, 2011 at 2:48 PM, Heiko Schocher <hs@denx.de> wrote:
> Hello Lei,
>
> Lei Wen wrote:
>> For better sharing with other platform other than pxa's,
>> it is more convenient to put the driver to the common place.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> v2: rename previous pxa_i2c to mvi2c.
>
> Maybe a Coding Style cleanup would be good for this file ...
> (I know, you don;t wrote this file...)
>
>> ?arch/arm/cpu/pxa/Makefile | ? ?1 -
>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 ---------------------------------------------
>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>> ?drivers/i2c/mvi2c.c ? ? ? | ?469 +++++++++++++++++++++++++++++++++++++++++++++
>
> Why you don;t use git format-patch -M ?
> If so, I wouldn;t stumbled over the Coding Style ;-)
>
>> ?include/configs/innokom.h | ? ?1 +
>> ?include/configs/xm250.h ? | ? ?1 +
>> ?6 files changed, 472 insertions(+), 470 deletions(-)
>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>> ?create mode 100644 drivers/i2c/mvi2c.c
>>
> [...]
>> diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
>> new file mode 100644
>> index 0000000..7aa49ae
>> --- /dev/null
>> +++ b/drivers/i2c/mvi2c.c
>> @@ -0,0 +1,469 @@
>> +/*
>> + * (C) Copyright 2000
>> + * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
>> + *
>> + * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
>> + * Marius Groeger <mgroeger@sysgo.de>
>> + *
>> + * (C) Copyright 2003 Pengutronix e.K.
>> + * Robert Schwebel <r.schwebel@pengutronix.de>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + *
>> + * Back ported to the 8xx platform (from the 8260 platform) by
>> + * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
>> + */
>> +
>> +/* FIXME: this file is PXA255 specific! What about other XScales? */
>
> As you rename this file to mv, please change this comment.
>
>> +
>> +#include <common.h>
>> +#include <asm/io.h>
>> +
>> +#ifdef CONFIG_HARD_I2C
>> +
>> +/*
>> + * ? - CONFIG_SYS_I2C_SPEED
>> + * ? - I2C_PXA_SLAVE_ADDR
>> + */
>> +
>> +#include <asm/arch/hardware.h>
>> +#include <asm/arch/pxa-regs.h>
>> +#include <i2c.h>
>> +
>> +/*#define ? ?DEBUG_I2C ? ? ? 1 ? ? ? /###* activate local debugging output ?*/
>
> Please remove dead code.
>
>> +#define I2C_PXA_SLAVE_ADDR ? 0x1 ? ? /* slave pxa unit address ? ? ? ? ? */
>> +
>> +#if (CONFIG_SYS_I2C_SPEED == 400000)
>> +#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
>
> Line too long.
>
>> +#else
>> +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
>> +#endif
>> +
>> +#define I2C_ISR_INIT ? ? ? ? 0x7FF
>> +
>> +#ifdef DEBUG_I2C
>> +#define PRINTD(x) printf x
>> +#else
>> +#define PRINTD(x)
>> +#endif
>> +
>> +
>> +/* Shall the current transfer have a start/stop condition? */
>> +#define I2C_COND_NORMAL ? ? ? ? ? ? ?0
>> +#define I2C_COND_START ? ? ? ? ? ? ? 1
>> +#define I2C_COND_STOP ? ? ? ? ? ? ? ?2
>> +
>> +/* Shall the current transfer be ack/nacked or being waited for it? */
>> +#define I2C_ACKNAK_WAITACK ? 1
>> +#define I2C_ACKNAK_SENDACK ? 2
>> +#define I2C_ACKNAK_SENDNAK ? 4
>> +
>> +/* Specify who shall transfer the data (master or slave) */
>> +#define I2C_READ ? ? ? ? ? ? 0
>> +#define I2C_WRITE ? ? ? ? ? ?1
>> +
>> +/* All transfers are described by this data structure */
>> +struct i2c_msg {
>> + ? ? u8 condition;
>> + ? ? u8 acknack;
>> + ? ? u8 direction;
>> + ? ? u8 data;
>> +};
>> +
>> +
>
> Only one empty line.
>
>> +/**
>> + * i2c_pxa_reset: - reset the host controller
>> + *
>> + */
>
> Wrong comment style, no empty line after the comment necessary.
> Fix globally please.
>
>> +
>> +static void i2c_reset( void )
>
> No spaces after "(" and before ")"
> Fix globally please.
>
>> +{
>> + ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
>> + ? ? writel(readl(ICR) | ICR_UR, ICR); ? ? ? /* reset the unit */
>> + ? ? udelay(100);
>> + ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
>> +#ifdef CONFIG_CPU_MONAHANS
>> + ? ? /* | CKENB_1_PWM1 | CKENB_0_PWM0); */
>> + ? ? writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
>> +#else /* CONFIG_CPU_MONAHANS */
>> + ? ? /* set the global I2C clock on */
>> + ? ? writel(readl(CKEN) | CKEN14_I2C, CKEN);
>> +#endif
>> + ? ? writel(I2C_PXA_SLAVE_ADDR, ISAR); ? ? ? /* set our slave address */
>> + ? ? writel(I2C_ICR_INIT, ICR); ? ? ? ? ? ? ?/* set control reg values */
>> + ? ? writel(I2C_ISR_INIT, ISR); ? ? ? ? ? ? ?/* set clear interrupt bits */
>> + ? ? writel(readl(ICR) | ICR_IUE, ICR); ? ? ?/* enable unit */
>> + ? ? udelay(100);
>> +}
>> +
>> +
>> +/**
>> + * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
>> + * ? ? ? ? ? ? ? ? ? ? are set and cleared
>> + *
>> + * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
>> + */
>> +static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
>
> Line too long.
>
>> +{
>> + ? ? int timeout = 10000;
>> +
>> + ? ? while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
> ? ? ? ? ? ? ?^ ? ? ? ? ? ? ? ? ^ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ^
> ? ? ? ? ? ? ?no space ? ? ? ? ?space around "!=" ? ? ? ? ? ? ? ? ? ? ? ? space
>
>> + ? ? ? ? ? ? udelay( 10 );
>> + ? ? ? ? ? ? if( timeout-- < 0 ) return 0;
>
> return please in a new line, please fix globally.
>
>> + ? ? }
>> +
>> + ? ? return 1;
>> +}
>> +
>> +
>> +/**
>> + * i2c_transfer: - Transfer one byte over the i2c bus
>> + *
>> + * This function can tranfer a byte over the i2c bus in both directions.
>> + * It is used by the public API functions.
>> + *
>> + * @return: ?0: transfer successful
>> + * ? ? ? ? ?-1: message is empty
>> + * ? ? ? ? ?-2: transmit timeout
>> + * ? ? ? ? ?-3: ACK missing
>> + * ? ? ? ? ?-4: receive timeout
>> + * ? ? ? ? ?-5: illegal parameters
>> + * ? ? ? ? ?-6: bus is busy and couldn't be aquired
>> + */
>> +int i2c_transfer(struct i2c_msg *msg)
>> +{
>> + ? ? int ret;
>> +
>> + ? ? if (!msg)
>> + ? ? ? ? ? ? goto transfer_error_msg_empty;
>> +
>> + ? ? switch(msg->direction) {
>> +
>
> no empty line please.
>
>> + ? ? case I2C_WRITE:
>> +
>> + ? ? ? ? ? ? /* check if bus is not busy */
>> + ? ? ? ? ? ? if (!i2c_isr_set_cleared(0,ISR_IBB))
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ^
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? add a space please
>> + ? ? ? ? ? ? ? ? ? ? goto transfer_error_bus_busy;
>> +
>> + ? ? ? ? ? ? /* start transmission */
>> + ? ? ? ? ? ? writel(readl(ICR) & ~ICR_START, ICR);
>> + ? ? ? ? ? ? writel(readl(ICR) & ~ICR_STOP, ICR);
>> + ? ? ? ? ? ? writel(msg->data, IDBR);
>> + ? ? ? ? ? ? if (msg->condition == I2C_COND_START)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_START, ICR);
>> + ? ? ? ? ? ? if (msg->condition == I2C_COND_STOP)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_STOP, ICR);
>> + ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDNAK)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> + ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> +
>> + ? ? ? ? ? ? /* transmit register empty? */
>> + ? ? ? ? ? ? if (!i2c_isr_set_cleared(ISR_ITE,0))
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ^
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? here too, fix
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? globally please.
>
>> + ? ? ? ? ? ? ? ? ? ? goto transfer_error_transmit_timeout;
>> +
>> + ? ? ? ? ? ? /* clear 'transmit empty' state */
>> + ? ? ? ? ? ? writel(readl(ISR) | ISR_ITE, ISR);
>> +
>> + ? ? ? ? ? ? /* wait for ACK from slave */
>> + ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_WAITACK)
>> + ? ? ? ? ? ? ? ? ? ? if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_ack_missing;
>> + ? ? ? ? ? ? break;
>> +
>> + ? ? case I2C_READ:
>> +
>> + ? ? ? ? ? ? /* check if bus is not busy */
>> + ? ? ? ? ? ? if (!i2c_isr_set_cleared(0,ISR_IBB))
>> + ? ? ? ? ? ? ? ? ? ? goto transfer_error_bus_busy;
>> +
>> + ? ? ? ? ? ? /* start receive */
>> + ? ? ? ? ? ? writel(readl(ICR) & ~ICR_START, ICR);
>> + ? ? ? ? ? ? writel(readl(ICR) & ~ICR_STOP, ICR);
>> + ? ? ? ? ? ? if (msg->condition == I2C_COND_START)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_START, ICR);
>> + ? ? ? ? ? ? if (msg->condition == I2C_COND_STOP)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_STOP, ICR);
>> + ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDNAK)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> + ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> +
>> + ? ? ? ? ? ? /* receive register full? */
>> + ? ? ? ? ? ? if (!i2c_isr_set_cleared(ISR_IRF,0))
>> + ? ? ? ? ? ? ? ? ? ? goto transfer_error_receive_timeout;
>> +
>> + ? ? ? ? ? ? msg->data = readl(IDBR);
>> +
>> + ? ? ? ? ? ? /* clear 'receive empty' state */
>> + ? ? ? ? ? ? writel(readl(ISR) | ISR_IRF, ISR);
>> +
>> + ? ? ? ? ? ? break;
>> +
>> + ? ? default:
>> +
>> + ? ? ? ? ? ? goto transfer_error_illegal_param;
>> +
>> + ? ? }
>> +
>> + ? ? return 0;
>> +
>> +transfer_error_msg_empty:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
>> + ? ? ? ? ? ? ret = -1; goto i2c_transfer_finish;
>> +
>> +transfer_error_transmit_timeout:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: error: transmit timeout\n"));
>> + ? ? ? ? ? ? ret = -2; goto i2c_transfer_finish;
>> +
>> +transfer_error_ack_missing:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: error: ACK missing\n"));
>> + ? ? ? ? ? ? ret = -3; goto i2c_transfer_finish;
>> +
>> +transfer_error_receive_timeout:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: error: receive timeout\n"));
>> + ? ? ? ? ? ? ret = -4; goto i2c_transfer_finish;
>> +
>> +transfer_error_illegal_param:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: error: illegal parameters\n"));
>> + ? ? ? ? ? ? ret = -5; goto i2c_transfer_finish;
>> +
>> +transfer_error_bus_busy:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: error: bus is busy\n"));
>> + ? ? ? ? ? ? ret = -6; goto i2c_transfer_finish;
>> +
>> +i2c_transfer_finish:
>> + ? ? ? ? ? ? PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
>> + ? ? ? ? ? ? i2c_reset();
>> + ? ? ? ? ? ? return ret;
>> +
>> +}
>> +
>> +/* ------------------------------------------------------------------------ */
>> +/* API Functions ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
>> +/* ------------------------------------------------------------------------ */
>> +
>> +void i2c_init(int speed, int slaveaddr)
>> +{
>> +#ifdef CONFIG_SYS_I2C_INIT_BOARD
>> + ? ? /* call board specific i2c bus reset routine before accessing the ? */
>> + ? ? /* environment, which might be in a chip on that bus. For details ? */
>> + ? ? /* about this problem see doc/I2C_Edge_Conditions. ? ? ? ? ? ? ? ? ?*/
>> + ? ? i2c_init_board();
>> +#endif
>> +}
>> +
>> +
>> +/**
>> + * i2c_probe: - Test if a chip answers for a given i2c address
>> + *
>> + * @chip: ? ?address of the chip which is searched for
>> + * @return: ?0 if a chip was found, -1 otherwhise
>> + */
>> +
>> +int i2c_probe(uchar chip)
>> +{
>> + ? ? struct i2c_msg msg;
>> +
>> + ? ? i2c_reset();
>> +
>> + ? ? msg.condition = I2C_COND_START;
>> + ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? msg.direction = I2C_WRITE;
>> + ? ? msg.data ? ? ?= (chip << 1) + 1;
>> + ? ? if (i2c_transfer(&msg)) return -1;
>> +
>> + ? ? msg.condition = I2C_COND_STOP;
>> + ? ? msg.acknack ? = I2C_ACKNAK_SENDNAK;
>> + ? ? msg.direction = I2C_READ;
>> + ? ? msg.data ? ? ?= 0x00;
>> + ? ? if (i2c_transfer(&msg)) return -1;
>> +
>> + ? ? return 0;
>> +}
>> +
>> +
>> +/**
>> + * i2c_read: - Read multiple bytes from an i2c device
>> + *
>> + * The higher level routines take into account that this function is only
>> + * called with len < page length of the device (see configuration file)
>> + *
>> + * @chip: ? ?address of the chip which is to be read
>> + * @addr: ? ?i2c data address within the chip
>> + * @alen: ? ?length of the i2c data address (1..2 bytes)
>> + * @buffer: ?where to write the data
>> + * @len: ? ? how much byte do we want to read
>> + * @return: ?0 in case of success
>> + */
>> +
>> +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
>> +{
>> + ? ? struct i2c_msg msg;
>> + ? ? u8 addr_bytes[3]; /* lowest...highest byte of data address */
>> + ? ? int ret;
>> +
>> + ? ? PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
>
> Line too long, add space after ","
>
>> +
>> + ? ? i2c_reset();
>> +
>> + ? ? /* dummy chip address write */
>> + ? ? PRINTD(("i2c_read: dummy chip address write\n"));
>> + ? ? msg.condition = I2C_COND_START;
>> + ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? msg.direction = I2C_WRITE;
>> + ? ? msg.data ? ? ?= (chip << 1);
>> + ? ? msg.data ? ? &= 0xFE;
>> + ? ? if ((ret=i2c_transfer(&msg))) return -1;
>
> Please move the ret = i2c_transfer out of the if condition
> "return -1" please in a new line.
>
>> +
>> + ? ? /*
>> + ? ? ?* send memory address bytes;
>> + ? ? ?* alen defines how much bytes we have to send.
>> + ? ? ?*/
>> + ? ? /*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
>> + ? ? addr_bytes[0] = (u8)((addr >> ?0) & 0x000000FF);
>> + ? ? addr_bytes[1] = (u8)((addr >> ?8) & 0x000000FF);
>> + ? ? addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
>> +
>> + ? ? while (--alen >= 0) {
>> +
>> + ? ? ? ? ? ? PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
>> + ? ? ? ? ? ? msg.condition = I2C_COND_NORMAL;
>> + ? ? ? ? ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? ? ? ? ? msg.direction = I2C_WRITE;
>> + ? ? ? ? ? ? msg.data ? ? ?= addr_bytes[alen];
>> + ? ? ? ? ? ? if ((ret=i2c_transfer(&msg))) return -1;
>> + ? ? }
>> +
>> +
>> + ? ? /* start read sequence */
>> + ? ? PRINTD(("i2c_read: start read sequence\n"));
>> + ? ? msg.condition = I2C_COND_START;
>> + ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? msg.direction = I2C_WRITE;
>> + ? ? msg.data ? ? ?= (chip << 1);
>> + ? ? msg.data ? ? |= 0x01;
>> + ? ? if ((ret=i2c_transfer(&msg))) return -1;
>> +
>> + ? ? /* read bytes; send NACK at last byte */
>> + ? ? while (len--) {
>> +
>> + ? ? ? ? ? ? if (len==0) {
>> + ? ? ? ? ? ? ? ? ? ? msg.condition = I2C_COND_STOP;
>> + ? ? ? ? ? ? ? ? ? ? msg.acknack ? = I2C_ACKNAK_SENDNAK;
>> + ? ? ? ? ? ? } else {
>> + ? ? ? ? ? ? ? ? ? ? msg.condition = I2C_COND_NORMAL;
>> + ? ? ? ? ? ? ? ? ? ? msg.acknack ? = I2C_ACKNAK_SENDACK;
>> + ? ? ? ? ? ? }
>> +
>> + ? ? ? ? ? ? msg.direction = I2C_READ;
>> + ? ? ? ? ? ? msg.data ? ? ?= 0x00;
>> + ? ? ? ? ? ? if ((ret=i2c_transfer(&msg))) return -1;
>> +
>> + ? ? ? ? ? ? *buffer = msg.data;
>> + ? ? ? ? ? ? PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
>> + ? ? ? ? ? ? buffer++;
>> +
>> + ? ? }
>> +
>> + ? ? i2c_reset();
>> +
>> + ? ? return 0;
>> +}
>> +
>> +
>> +/**
>> + * i2c_write: - ?Write multiple bytes to an i2c device
>> + *
>> + * The higher level routines take into account that this function is only
>> + * called with len < page length of the device (see configuration file)
>> + *
>> + * @chip: ? ?address of the chip which is to be written
>> + * @addr: ? ?i2c data address within the chip
>> + * @alen: ? ?length of the i2c data address (1..2 bytes)
>> + * @buffer: ?where to find the data to be written
>> + * @len: ? ? how much byte do we want to read
>> + * @return: ?0 in case of success
>> + */
>> +
>> +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
>> +{
>> + ? ? struct i2c_msg msg;
>> + ? ? u8 addr_bytes[3]; /* lowest...highest byte of data address */
>> +
>> + ? ? PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
>> +
>> + ? ? i2c_reset();
>> +
>> + ? ? /* chip address write */
>> + ? ? PRINTD(("i2c_write: chip address write\n"));
>> + ? ? msg.condition = I2C_COND_START;
>> + ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? msg.direction = I2C_WRITE;
>> + ? ? msg.data ? ? ?= (chip << 1);
>> + ? ? msg.data ? ? &= 0xFE;
>> + ? ? if (i2c_transfer(&msg)) return -1;
>> +
>> + ? ? /*
>> + ? ? ?* send memory address bytes;
>> + ? ? ?* alen defines how much bytes we have to send.
>> + ? ? ?*/
>> + ? ? addr_bytes[0] = (u8)((addr >> ?0) & 0x000000FF);
>> + ? ? addr_bytes[1] = (u8)((addr >> ?8) & 0x000000FF);
>> + ? ? addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
>> +
>> + ? ? while (--alen >= 0) {
>> +
>> + ? ? ? ? ? ? PRINTD(("i2c_write: send memory word address\n"));
>> + ? ? ? ? ? ? msg.condition = I2C_COND_NORMAL;
>> + ? ? ? ? ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? ? ? ? ? msg.direction = I2C_WRITE;
>> + ? ? ? ? ? ? msg.data ? ? ?= addr_bytes[alen];
>> + ? ? ? ? ? ? if (i2c_transfer(&msg)) return -1;
>> + ? ? }
>> +
>> + ? ? /* write bytes; send NACK at last byte */
>> + ? ? while (len--) {
>> +
>> + ? ? ? ? ? ? PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
>> +
>> + ? ? ? ? ? ? if (len==0)
>> + ? ? ? ? ? ? ? ? ? ? msg.condition = I2C_COND_STOP;
>> + ? ? ? ? ? ? else
>> + ? ? ? ? ? ? ? ? ? ? msg.condition = I2C_COND_NORMAL;
>> +
>> + ? ? ? ? ? ? msg.acknack ? = I2C_ACKNAK_WAITACK;
>> + ? ? ? ? ? ? msg.direction = I2C_WRITE;
>> + ? ? ? ? ? ? msg.data ? ? ?= *(buffer++);
>> +
>> + ? ? ? ? ? ? if (i2c_transfer(&msg)) return -1;
>> +
>> + ? ? }
>> +
>> + ? ? i2c_reset();
>> +
>> + ? ? return 0;
>> +
>> +}
>> +
>> +#endif ? ? ? /* CONFIG_HARD_I2C */
>> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
>> index d8fcbdb..0ea73c9 100644
>> --- a/include/configs/innokom.h
>> +++ b/include/configs/innokom.h
>> @@ -140,6 +140,7 @@
>> ?/*
>> ? * I2C bus
>> ? */
>> +#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> ?#define CONFIG_HARD_I2C ? ? ? ? ? ? ? ? ? ? ?1
>> ?#define CONFIG_SYS_I2C_SPEED ? ? ? ? ? ? ? ? 50000
>> ?#define CONFIG_SYS_I2C_SLAVE ? ? ? ? ? ? ? ? 0xfe
>> diff --git a/include/configs/xm250.h b/include/configs/xm250.h
>> index 497cb91..b4b940a 100644
>> --- a/include/configs/xm250.h
>> +++ b/include/configs/xm250.h
>> @@ -61,6 +61,7 @@
>> ?/*
>> ? * I2C bus
>> ? */
>> +#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> ?#define CONFIG_HARD_I2C ? ? ? ? ? ? ? ? ? ? ?1
>> ?#define CONFIG_SYS_I2C_SPEED ? ? ? ? ? ? ? ? 50000
>> ?#define CONFIG_SYS_I2C_SLAVE ? ? ? ? ? ? ? ? 0xfe
>

Thanks for reviewing, I would post the V3 patch to fix the code style issue...

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100
  2011-03-15  8:12       ` Wolfgang Denk
@ 2011-03-17  6:26         ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:26 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

On Tue, Mar 15, 2011 at 4:12 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Lei Wen,
>
> In message <1300160443-12552-1-git-send-email-leiwen@marvell.com> you wrote:
>> V2:
>> rename the previous pxa_i2c to mvi2c, since this driver would be shared
>> by many other Marvell platforms.
>>
>> Lei Wen (5):
>> ? pxa: move i2c driver to the common place
>> ? mvi2c: use structure to replace the direclty define
>> ? I2C: add i2c support for Pantheon platform
>> ? I2C: mvi2c: add multi bus support
>> ? I2C: add i2c support for Armada100 platform
>
> Checkpatch says:
>
> [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place
> total: 57 errors, 7 warnings, 497 lines checked
> [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the
> total: 2 errors, 1 warnings, 333 lines checked
> [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform
> total: 2 errors, 1 warnings, 64 lines checked
> [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support
> total: 2 errors, 0 warnings, 51 lines checked
> [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform
> total: 2 errors, 1 warnings, 65 lines checked
>
> Please cleanup!
>
> and next time please run checkpatch _before_ submitting!
>

Thanks for reminding this. V3 patch to come. :)

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define
  2011-03-15  6:54       ` Heiko Schocher
@ 2011-03-17  6:28         ` Lei Wen
  2011-03-17  7:12           ` Heiko Schocher
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:28 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On Tue, Mar 15, 2011 at 2:54 PM, Heiko Schocher <hs@denx.de> wrote:
> Hello Lei,
>
> Lei Wen wrote:
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? | ? 11 +++
>> ?arch/arm/include/asm/arch-pxa/pxa-regs.h | ? 56 ------------
>> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ?| ? ?9 +--
>> ?drivers/i2c/mvi2c.c ? ? ? ? ? ? ? ? ? ? ?| ?139 +++++++++++++++++++++---------
>> ?include/configs/innokom.h ? ? ? ? ? ? ? ?| ? ?1 +
>> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ?| ? ?1 +
>> ?6 files changed, 111 insertions(+), 106 deletions(-)
>>
>> diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
>> index 7d49cbb..24b59e7 100644
>> --- a/arch/arm/cpu/pxa/cpu.c
>> +++ b/arch/arm/cpu/pxa/cpu.c
>> @@ -318,3 +318,14 @@ int arch_cpu_init(void)
>> ? ? ? pxa_clock_setup();
>> ? ? ? return 0;
>> ?}
>> +
>> +void i2c_clk_enable(void)
>> +{
>> +#ifdef CONFIG_CPU_MONAHANS
>> + ? ? /* | CKENB_1_PWM1 | CKENB_0_PWM0); */
>> + ? ? writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
>> +#else /* CONFIG_CPU_MONAHANS */
>> + ? ? /* set the global I2C clock on */
>> + ? ? writel(readl(CKEN) | CKEN14_I2C, CKEN);
>> +#endif
>> +}
>> diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
>> index 65a387f..109fdc0 100644
>> --- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
>> +++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
>> @@ -456,62 +456,6 @@ typedef void ? ? ? ? ? ? (*ExcpHndlr) (void) ;
>> ? ? ? ? ? ? ? IrSR_XMITIR_IR_MODE)
>>
>> ?/*
>> - * I2C registers
>> - */
>> -#define IBMR ? ? ? ? 0x40301680 ?/* I2C Bus Monitor Register - IBMR */
>> -#define IDBR ? ? ? ? 0x40301688 ?/* I2C Data Buffer Register - IDBR */
>> -#define ICR ? ? ? ? ?0x40301690 ?/* I2C Control Register - ICR */
>> -#define ISR ? ? ? ? ?0x40301698 ?/* I2C Status Register - ISR */
>> -#define ISAR ? ? ? ? 0x403016A0 ?/* I2C Slave Address Register - ISAR */
>> -
>> -#ifdef CONFIG_CPU_MONAHANS
>> -#define PWRIBMR ? ? ? ? ? ? ?0x40f500C0 ?/* Power I2C Bus Monitor Register-IBMR */
>> -#define PWRIDBR ? ? ? ? ? ? ?0x40f500C4 ?/* Power I2C Data Buffer Register-IDBR */
>> -#define PWRICR ? ? ? ? ? ? ? 0x40f500C8 ?/* Power I2C Control Register - ICR */
>> -#define PWRISR ? ? ? ? ? ? ? 0x40f500CC ?/* Power I2C Status Register - ISR */
>> -#define PWRISAR ? ? ? ? ? ? ?0x40f500D0 ?/* Power I2C Slave Address Register-ISAR */
>> -#else
>> -#define PWRIBMR ? ? ? ? ? ? ?0x40f00180 ?/* Power I2C Bus Monitor Register-IBMR */
>> -#define PWRIDBR ? ? ? ? ? ? ?0x40f00188 ?/* Power I2C Data Buffer Register-IDBR */
>> -#define PWRICR ? ? ? ? ? ? ? 0x40f00190 ?/* Power I2C Control Register - ICR */
>> -#define PWRISR ? ? ? ? ? ? ? 0x40f00198 ?/* Power I2C Status Register - ISR */
>> -#define PWRISAR ? ? ? ? ? ? ?0x40f001A0 ?/* Power I2C Slave Address Register-ISAR */
>> -#endif
>> -
>> -/* ----- Control register bits ---------------------------------------- */
>> -
>> -#define ICR_START ? ?0x1 ? ? ? ? ? ? /* start bit */
>> -#define ICR_STOP ? ? 0x2 ? ? ? ? ? ? /* stop bit */
>> -#define ICR_ACKNAK ? 0x4 ? ? ? ? ? ? /* send ACK(0) or NAK(1) */
>> -#define ICR_TB ? ? ? ? ? ? ? 0x8 ? ? ? ? ? ? /* transfer byte bit */
>> -#define ICR_MA ? ? ? ? ? ? ? 0x10 ? ? ? ? ? ?/* master abort */
>> -#define ICR_SCLE ? ? 0x20 ? ? ? ? ? ?/* master clock enable, mona SCLEA */
>> -#define ICR_IUE ? ? ? ? ? ? ?0x40 ? ? ? ? ? ?/* unit enable */
>> -#define ICR_GCD ? ? ? ? ? ? ?0x80 ? ? ? ? ? ?/* general call disable */
>> -#define ICR_ITEIE ? ?0x100 ? ? ? ? ? /* enable tx interrupts */
>> -#define ICR_IRFIE ? ?0x200 ? ? ? ? ? /* enable rx interrupts, mona: DRFIE */
>> -#define ICR_BEIE ? ? 0x400 ? ? ? ? ? /* enable bus error ints */
>> -#define ICR_SSDIE ? ?0x800 ? ? ? ? ? /* slave STOP detected int enable */
>> -#define ICR_ALDIE ? ?0x1000 ? ? ? ? ?/* enable arbitration interrupt */
>> -#define ICR_SADIE ? ?0x2000 ? ? ? ? ?/* slave address detected int enable */
>> -#define ICR_UR ? ? ? ? ? ? ? 0x4000 ? ? ? ? ?/* unit reset */
>> -#define ICR_FM ? ? ? ? ? ? ? 0x8000 ? ? ? ? ?/* Fast Mode */
>> -
>> -/* ----- Status register bits ----------------------------------------- */
>> -
>> -#define ISR_RWM ? ? ? ? ? ? ?0x1 ? ? ? ? ? ? /* read/write mode */
>> -#define ISR_ACKNAK ? 0x2 ? ? ? ? ? ? /* ack/nak status */
>> -#define ISR_UB ? ? ? ? ? ? ? 0x4 ? ? ? ? ? ? /* unit busy */
>> -#define ISR_IBB ? ? ? ? ? ? ?0x8 ? ? ? ? ? ? /* bus busy */
>> -#define ISR_SSD ? ? ? ? ? ? ?0x10 ? ? ? ? ? ?/* slave stop detected */
>> -#define ISR_ALD ? ? ? ? ? ? ?0x20 ? ? ? ? ? ?/* arbitration loss detected */
>> -#define ISR_ITE ? ? ? ? ? ? ?0x40 ? ? ? ? ? ?/* tx buffer empty */
>> -#define ISR_IRF ? ? ? ? ? ? ?0x80 ? ? ? ? ? ?/* rx buffer full */
>> -#define ISR_GCAD ? ? 0x100 ? ? ? ? ? /* general call address detected */
>> -#define ISR_SAD ? ? ? ? ? ? ?0x200 ? ? ? ? ? /* slave address detected */
>> -#define ISR_BED ? ? ? ? ? ? ?0x400 ? ? ? ? ? /* bus error no ACK/NAK */
>> -
>> -/*
>> ? * Serial Audio Controller
>> ? */
>> ?/* FIXME the audio defines collide w/ the SA1111 defines. ?I don't like these
>> diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
>> index e658c35..22de7e3 100644
>> --- a/board/innokom/innokom.c
>> +++ b/board/innokom/innokom.c
>> @@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
>> ? */
>> ?int i2c_init_board(void)
>> ?{
>> - ? ? int i, icr;
>> -
>> - ? ? /* disable I2C controller first, otherwhise it thinks we want to ? ?*/
>> - ? ? /* talk to the slave port... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
>> - ? ? icr = readl(ICR);
>> - ? ? writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
>> + ? ? int i;
>>
>> ? ? ? /* set gpio pin low _before_ we change direction to output ? ? ? ? ?*/
>> ? ? ? writel(GPIO_bit(70), GPCR(70));
>> @@ -63,8 +58,6 @@ int i2c_init_board(void)
>> ? ? ? ? ? ? ? udelay(10);
>> ? ? ? }
>>
>> - ? ? writel(icr, ICR);
>> -
>> ? ? ? return 0;
>> ?}
>>
>> diff --git a/drivers/i2c/mvi2c.c b/drivers/i2c/mvi2c.c
>> index 7aa49ae..0e37417 100644
>> --- a/drivers/i2c/mvi2c.c
>> +++ b/drivers/i2c/mvi2c.c
>> @@ -8,6 +8,9 @@
>> ? * (C) Copyright 2003 Pengutronix e.K.
>> ? * Robert Schwebel <r.schwebel@pengutronix.de>
>> ? *
>> + * (C) Copyright 2011 Marvell Inc.
>> + * Lei Wen <leiwen@marvell.com>
>> + *
>> ? * See file CREDITS for list of people who contributed to this
>> ? * project.
>> ? *
>> @@ -30,8 +33,6 @@
>> ? * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
>> ? */
>>
>> -/* FIXME: this file is PXA255 specific! What about other XScales? */
>
> Ah, you remove this comment here, Ok!
>
>> -
>> ?#include <common.h>
>> ?#include <asm/io.h>
>>
>> @@ -42,9 +43,41 @@
>> ? * ? - I2C_PXA_SLAVE_ADDR
>> ? */
>>
>> -#include <asm/arch/hardware.h>
>> -#include <asm/arch/pxa-regs.h>
>> ?#include <i2c.h>
>> +extern void i2c_clk_enable(void);
>
> Hmm... as you define this function in arch/arm/cpu/pxa/cpu.c
> there should be somewhere an appropriate header file, where
> it fits in, so we can avoid this extern.
>
>> +
>> +/* ----- Control register bits ---------------------------------------- */
>> +
>> +#define ICR_START ? ?0x1 ? ? ? ? ? ? /* start bit */
>> +#define ICR_STOP ? ? 0x2 ? ? ? ? ? ? /* stop bit */
>> +#define ICR_ACKNAK ? 0x4 ? ? ? ? ? ? /* send ACK(0) or NAK(1) */
>> +#define ICR_TB ? ? ? ? ? ? ? 0x8 ? ? ? ? ? ? /* transfer byte bit */
>> +#define ICR_MA ? ? ? ? ? ? ? 0x10 ? ? ? ? ? ?/* master abort */
>> +#define ICR_SCLE ? ? 0x20 ? ? ? ? ? ?/* master clock enable, mona SCLEA */
>> +#define ICR_IUE ? ? ? ? ? ? ?0x40 ? ? ? ? ? ?/* unit enable */
>> +#define ICR_GCD ? ? ? ? ? ? ?0x80 ? ? ? ? ? ?/* general call disable */
>> +#define ICR_ITEIE ? ?0x100 ? ? ? ? ? /* enable tx interrupts */
>> +#define ICR_IRFIE ? ?0x200 ? ? ? ? ? /* enable rx interrupts, mona: DRFIE */
>> +#define ICR_BEIE ? ? 0x400 ? ? ? ? ? /* enable bus error ints */
>> +#define ICR_SSDIE ? ?0x800 ? ? ? ? ? /* slave STOP detected int enable */
>> +#define ICR_ALDIE ? ?0x1000 ? ? ? ? ?/* enable arbitration interrupt */
>> +#define ICR_SADIE ? ?0x2000 ? ? ? ? ?/* slave address detected int enable */
>> +#define ICR_UR ? ? ? ? ? ? ? 0x4000 ? ? ? ? ?/* unit reset */
>> +#define ICR_FM ? ? ? ? ? ? ? 0x8000 ? ? ? ? ?/* Fast Mode */
>> +
>> +/* ----- Status register bits ----------------------------------------- */
>> +
>> +#define ISR_RWM ? ? ? ? ? ? ?0x1 ? ? ? ? ? ? /* read/write mode */
>> +#define ISR_ACKNAK ? 0x2 ? ? ? ? ? ? /* ack/nak status */
>> +#define ISR_UB ? ? ? ? ? ? ? 0x4 ? ? ? ? ? ? /* unit busy */
>> +#define ISR_IBB ? ? ? ? ? ? ?0x8 ? ? ? ? ? ? /* bus busy */
>> +#define ISR_SSD ? ? ? ? ? ? ?0x10 ? ? ? ? ? ?/* slave stop detected */
>> +#define ISR_ALD ? ? ? ? ? ? ?0x20 ? ? ? ? ? ?/* arbitration loss detected */
>> +#define ISR_ITE ? ? ? ? ? ? ?0x40 ? ? ? ? ? ?/* tx buffer empty */
>> +#define ISR_IRF ? ? ? ? ? ? ?0x80 ? ? ? ? ? ?/* rx buffer full */
>> +#define ISR_GCAD ? ? 0x100 ? ? ? ? ? /* general call address detected */
>> +#define ISR_SAD ? ? ? ? ? ? ?0x200 ? ? ? ? ? /* slave address detected */
>> +#define ISR_BED ? ? ? ? ? ? ?0x400 ? ? ? ? ? /* bus error no ACK/NAK */
>>
>> ?/*#define ? ?DEBUG_I2C ? ? ? 1 ? ? ? /###* activate local debugging output ?*/
>> ?#define I2C_PXA_SLAVE_ADDR ? 0x1 ? ? /* slave pxa unit address ? ? ? ? ? */
>> @@ -86,6 +119,21 @@ struct i2c_msg {
>> ? ? ? u8 data;
>> ?};
>>
>> +struct pxa_i2c {
>> + ? ? u32 ibmr;
>> + ? ? u32 pad0;
>> + ? ? u32 idbr;
>> + ? ? u32 pad1;
>> + ? ? u32 icr;
>> + ? ? u32 pad2;
>> + ? ? u32 isr;
>> + ? ? u32 pad3;
>> + ? ? u32 isar;
>> +};
>> +
>> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
>> +#define PXAI2C_AND(reg, val) writel(readl(reg) & val, reg)
>> +#define PXAI2C_OR(reg, val) ?writel(readl(reg) | val, reg)
>>
>> ?/**
>> ? * i2c_pxa_reset: - reset the host controller
>> @@ -94,21 +142,17 @@ struct i2c_msg {
>>
>> ?static void i2c_reset( void )
>> ?{
>> - ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
>> - ? ? writel(readl(ICR) | ICR_UR, ICR); ? ? ? /* reset the unit */
>> + ? ? PXAI2C_AND(&base->icr, ~ICR_IUE); ? ? ? /* disable unit */
>> + ? ? PXAI2C_OR(&base->icr, ICR_UR); ?/* reset the unit */
>> ? ? ? udelay(100);
>> - ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
>> -#ifdef CONFIG_CPU_MONAHANS
>> - ? ? /* | CKENB_1_PWM1 | CKENB_0_PWM0); */
>> - ? ? writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
>> -#else /* CONFIG_CPU_MONAHANS */
>> - ? ? /* set the global I2C clock on */
>> - ? ? writel(readl(CKEN) | CKEN14_I2C, CKEN);
>> -#endif
>> - ? ? writel(I2C_PXA_SLAVE_ADDR, ISAR); ? ? ? /* set our slave address */
>> - ? ? writel(I2C_ICR_INIT, ICR); ? ? ? ? ? ? ?/* set control reg values */
>> - ? ? writel(I2C_ISR_INIT, ISR); ? ? ? ? ? ? ?/* set clear interrupt bits */
>> - ? ? writel(readl(ICR) | ICR_IUE, ICR); ? ? ?/* enable unit */
>> + ? ? PXAI2C_AND(&base->icr, ~ICR_IUE); ? ? ? /* disable unit */
>> +
>> + ? ? i2c_clk_enable();
>> +
>> + ? ? writel(I2C_PXA_SLAVE_ADDR, &base->isar);/* set our slave address */
>> + ? ? writel(I2C_ICR_INIT, &base->icr); ? ? ? /* set control reg values */
>> + ? ? writel(I2C_ISR_INIT, &base->isr); ? ? ? /* set clear interrupt bits */
>> + ? ? PXAI2C_OR(&base->icr, ICR_IUE); ? ? ? ? /* enable unit */
>> ? ? ? udelay(100);
>> ?}
>>
>> @@ -121,12 +165,14 @@ static void i2c_reset( void )
>> ? */
>> ?static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
>> ?{
>> - ? ? int timeout = 10000;
>> + ? ? int timeout = 10000, isr;
>>
>> - ? ? while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
>> - ? ? ? ? ? ? udelay( 10 );
>> + ? ? do {
>> + ? ? ? ? ? ? isr = readl(&base->isr);
>> + ? ? ? ? ? ? udelay(10);
>> ? ? ? ? ? ? ? if( timeout-- < 0 ) return 0;
>> - ? ? }
>> + ? ? } while (((isr & set_mask)!=set_mask)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?^
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Spaces around "!="
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Please fix globally, thanks!
>> + ? ? ? ? ? ? ?|| ((isr & cleared_mask)!=0));
>>
>> ? ? ? return 1;
>> ?}
>> @@ -162,26 +208,26 @@ int i2c_transfer(struct i2c_msg *msg)
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_bus_busy;
>>
>> ? ? ? ? ? ? ? /* start transmission */
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_START, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_STOP, ICR);
>> - ? ? ? ? ? ? writel(msg->data, IDBR);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_START);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_STOP);
>> + ? ? ? ? ? ? writel(msg->data, &base->idbr);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_START)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_START, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_START);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_STOP)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_STOP, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_STOP);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDNAK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_ACKNAK);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ALDIE);
>> + ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_TB);
>>
>> ? ? ? ? ? ? ? /* transmit register empty? */
>> ? ? ? ? ? ? ? if (!i2c_isr_set_cleared(ISR_ITE,0))
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_transmit_timeout;
>>
>> ? ? ? ? ? ? ? /* clear 'transmit empty' state */
>> - ? ? ? ? ? ? writel(readl(ISR) | ISR_ITE, ISR);
>> + ? ? ? ? ? ? PXAI2C_OR(&base->isr, ISR_ITE);
>>
>> ? ? ? ? ? ? ? /* wait for ACK from slave */
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_WAITACK)
>> @@ -196,27 +242,27 @@ int i2c_transfer(struct i2c_msg *msg)
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_bus_busy;
>>
>> ? ? ? ? ? ? ? /* start receive */
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_START, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_STOP, ICR);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_START);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_STOP);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_START)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_START, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_START);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_STOP)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_STOP, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_STOP);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDNAK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_ACKNAK);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ALDIE);
>> + ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_TB);
>>
>> ? ? ? ? ? ? ? /* receive register full? */
>> ? ? ? ? ? ? ? if (!i2c_isr_set_cleared(ISR_IRF,0))
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_receive_timeout;
>>
>> - ? ? ? ? ? ? msg->data = readl(IDBR);
>> + ? ? ? ? ? ? msg->data = readl(&base->idbr);
>>
>> ? ? ? ? ? ? ? /* clear 'receive empty' state */
>> - ? ? ? ? ? ? writel(readl(ISR) | ISR_IRF, ISR);
>> + ? ? ? ? ? ? PXAI2C_OR(&base->isr, ISR_IRF);
>>
>> ? ? ? ? ? ? ? break;
>>
>> @@ -266,10 +312,19 @@ i2c_transfer_finish:
>> ?void i2c_init(int speed, int slaveaddr)
>> ?{
>> ?#ifdef CONFIG_SYS_I2C_INIT_BOARD
>> + ? ? u32 icr;
>> ? ? ? /* call board specific i2c bus reset routine before accessing the ? */
>> ? ? ? /* environment, which might be in a chip on that bus. For details ? */
>> ? ? ? /* about this problem see doc/I2C_Edge_Conditions. ? ? ? ? ? ? ? ? ?*/
>> +
>> + ? ? /* disable I2C controller first, otherwhise it thinks we want to ? ?*/
>> + ? ? /* talk to the slave port... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/
>
> Wrong comment style, please fix
>
>> + ? ? icr = readl(&base->icr);
>> + ? ? PXAI2C_AND(&base->icr, ~(ICR_SCLE | ICR_IUE));
>> +
>> ? ? ? i2c_init_board();
>> +
>> + ? ? writel(icr, &base->icr);
>> ?#endif
>> ?}
>>
>> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
>> index 0ea73c9..1ddee03 100644
>> --- a/include/configs/innokom.h
>> +++ b/include/configs/innokom.h
>> @@ -141,6 +141,7 @@
>> ? * I2C bus
>> ? */
>> ?#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_PXA_I2C_REG ? ? ? ? ? 0x40301680
>
> Hmm.. is there no define for this magic value?
>

This value is for i2c base address. Do you mean it need a description?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform
  2011-03-15  7:08       ` Heiko Schocher
@ 2011-03-17  6:38         ` Lei Wen
  2011-03-17  7:15           ` Heiko Schocher
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:38 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On Tue, Mar 15, 2011 at 3:08 PM, Heiko Schocher
<heiko.schocher@invitel.hu> wrote:
> Hello Lei,
>
> Lei Wen wrote:
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>>  arch/arm/cpu/arm926ejs/armada100/cpu.c    |   14 ++++++++++++++
>>  arch/arm/include/asm/arch-armada100/mfp.h |    4 ++++
>>  board/Marvell/aspenite/aspenite.c         |    5 +++++
>>  include/configs/aspenite.h                |   12 ++++++++++++
>>  4 files changed, 35 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> index 62aa175..8039ad2 100644
>> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> @@ -62,6 +62,14 @@ int arch_cpu_init(void)
>>       /* Enable GPIO clock */
>>       writel(APBC_APBCLK, &apb1clkres->gpio);
>>
>> +     /* Enable general I2C clock */
>> +     writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
>> +     writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
>> +
>> +     /* Enable power I2C clock */
>> +     writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
>> +     writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
>> +
>
> If boards based on this cpu type don;t use i2c, i2c clock and
> power would be enabled ... wouldn;t it be better, if we enable
> this only if CONFIG_I2C_MV is defined?

Good point, I would modify to follow this.

>
> Hmm.. are the comments OK? In the first "block" you only
> use twsi0 register, in the second "block" only twsi1 ...?

The comments is following what the spec says...
In spec, the twsi0 named as general, and twsi1 named as power one.

Thanks for reviewing!

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 0/5] add i2c support to pantheon and aramada100
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
  2011-03-15  8:12       ` Wolfgang Denk
@ 2011-03-17  6:45       ` Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
                           ` (6 more replies)
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place Lei Wen
                         ` (4 subsequent siblings)
  6 siblings, 7 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:45 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

V3:
Clean the code sytle issue

Lei Wen (5):
  pxa: move i2c driver to the common place
  mv_i2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mv_i2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c     |   12 +
 arch/arm/cpu/pxa/Makefile                 |    1 -
 arch/arm/cpu/pxa/cpu.c                    |   11 +
 arch/arm/cpu/pxa/i2c.c                    |  469 ----------------------------
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++-
 arch/arm/include/asm/arch-pantheon/cpu.h  |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h  |    6 +-
 arch/arm/include/asm/arch-pxa/pxa-regs.h  |   56 ----
 board/Marvell/aspenite/aspenite.c         |    5 +
 board/Marvell/dkb/dkb.c                   |    4 +
 board/innokom/innokom.c                   |    9 +-
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/mv_i2c.c                      |  481 +++++++++++++++++++++++++++++
 drivers/i2c/mv_i2c.h                      |   83 +++++
 include/configs/aspenite.h                |   12 +
 include/configs/dkb.h                     |   11 +
 include/configs/innokom.h                 |    2 +
 include/configs/xm250.h                   |    2 +
 19 files changed, 670 insertions(+), 555 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c
 create mode 100644 drivers/i2c/mv_i2c.h

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
  2011-03-15  8:12       ` Wolfgang Denk
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
@ 2011-03-17  6:45       ` Lei Wen
  2011-03-22 11:42         ` Prafulla Wadaskar
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
                         ` (3 subsequent siblings)
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:45 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 455 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
new file mode 100644
index 0000000..09756a4
--- /dev/null
+++ b/drivers/i2c/mv_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+/*
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void)
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
+{
+	int timeout = 10000;
+
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch (msg->direction) {
+	case I2C_WRITE:
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+	default:
+		goto transfer_error_illegal_param;
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
+		i2c_reset();
+		return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+/*
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+		if (len == 0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if (i2c_transfer(&msg))
+			return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+		buffer++;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+/*
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+
+		if (len == 0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
                         ` (2 preceding siblings ...)
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-17  6:45       ` Lei Wen
  2011-03-22 11:17         ` Prafulla Wadaskar
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform Lei Wen
                         ` (2 subsequent siblings)
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:45 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code sytle issue

 arch/arm/cpu/pxa/cpu.c                   |   11 +++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mv_i2c.c                     |  133 ++++++++++++++---------------
 drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 7 files changed, 161 insertions(+), 133 deletions(-)
 create mode 100644 drivers/i2c/mv_i2c.h

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..24b59e7 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,14 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 09756a4..152ea43 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -34,44 +37,16 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
-			| ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
+#include "mv_i2c.h"
 
 #ifdef DEBUG_I2C
 #define PRINTD(x) printf x
 #else
 #define PRINTD(x)
 #endif
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
+#define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
+#define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)
 
 /* All transfers are described by this data structure */
 struct i2c_msg {
@@ -81,27 +56,37 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct pxa_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+
 /*
  * i2c_pxa_reset: - reset the host controller
  *
  */
 static void i2c_reset(void)
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
+	PXAI2C_OR(&base->icr, ICR_UR);		/* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	PXAI2C_AND(&base->icr, ~ICR_IUE);	/* disable unit */
+
+	i2c_clk_enable();
+
+	writel(CONFIG_SYS_I2C_SLAVE, &base->isar);/* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
+	PXAI2C_OR(&base->icr, ICR_IUE);		/* enable unit */
 	udelay(100);
 }
 
@@ -114,13 +99,15 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 10000;
+	int timeout = 10000, isr;
 
-	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+	do {
+		isr = readl(&base->isr);
 		udelay(10);
 		if (timeout-- < 0)
 			return 0;
-	}
+	} while (((isr & set_mask) != set_mask)
+		|| ((isr & cleared_mask) != 0));
 
 	return 1;
 }
@@ -153,26 +140,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		PXAI2C_AND(&base->icr, ~ICR_START);
+		PXAI2C_AND(&base->icr, ~ICR_STOP);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			PXAI2C_OR(&base->icr, ICR_START);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			PXAI2C_OR(&base->icr, ICR_STOP);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			PXAI2C_OR(&base->icr, ICR_ACKNAK);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
+		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
+		PXAI2C_OR(&base->icr, ICR_TB);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		PXAI2C_OR(&base->isr, ISR_ITE);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -187,28 +174,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		PXAI2C_AND(&base->icr, ~ICR_START);
+		PXAI2C_AND(&base->icr, ~ICR_STOP);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			PXAI2C_OR(&base->icr, ICR_START);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			PXAI2C_OR(&base->icr, ICR_STOP);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			PXAI2C_OR(&base->icr, ICR_ACKNAK);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
+		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
+		PXAI2C_OR(&base->icr, ICR_TB);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
+		PXAI2C_OR(&base->isr, ISR_IRF);
 		break;
 	default:
 		goto transfer_error_illegal_param;
@@ -252,10 +238,19 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
 	/* environment, which might be in a chip on that bus. For details   */
 	/* about this problem see doc/I2C_Edge_Conditions.                  */
+
+	/* disable I2C controller first, otherwhise it thinks we want to    */
+	/* talk to the slave port...                                        */
+	icr = readl(&base->icr);
+	PXAI2C_AND(&base->icr, ~(ICR_SCLE | ICR_IUE));
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
new file mode 100644
index 0000000..41af0d9
--- /dev/null
+++ b/drivers/i2c/mv_i2c.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Inc, <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MV_I2C_H_
+#define _MV_I2C_H_
+extern void i2c_clk_enable(void);
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+		| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
+
+#endif
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..1ddee03 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..682d1ed 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
                         ` (3 preceding siblings ...)
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-17  6:45       ` Lei Wen
  2011-03-22 11:22         ` Prafulla Wadaskar
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 4/5] I2C: mv_i2c: add multi bus support Lei Wen
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:45 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

 arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
 board/Marvell/dkb/dkb.c                  |    4 ++++
 include/configs/dkb.h                    |   11 +++++++++++
 5 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..8b2eafa 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,12 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+#endif
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +82,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..e939196 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -32,8 +32,10 @@
  * offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..1b18c44 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -56,6 +56,17 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
+/*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 4/5] I2C: mv_i2c: add multi bus support
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
                         ` (4 preceding siblings ...)
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-17  6:45       ` Lei Wen
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:45 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code style issue

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 152ea43..b849913 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -68,7 +68,35 @@ struct pxa_i2c {
 	u32 isar;
 };
 
-static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+static struct pxa_i2c *base;
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
+static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
+static unsigned int current_bus;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct pxa_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /*
  * i2c_pxa_reset: - reset the host controller
@@ -237,6 +265,12 @@ i2c_transfer_finish:
 /* ------------------------------------------------------------------------ */
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct pxa_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform
  2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
                         ` (5 preceding siblings ...)
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 4/5] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-03-17  6:45       ` Lei Wen
  2011-03-22 11:40         ` Prafulla Wadaskar
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-17  6:45 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++-------------
 board/Marvell/aspenite/aspenite.c         |    5 +++
 include/configs/aspenite.h                |   12 ++++++++
 4 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..c21938e 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,16 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +100,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..73783a7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -37,28 +37,32 @@
  * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART1 */
-#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART3 */
-#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+
+/* I2c */
+#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..a6fa45e 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -63,6 +63,18 @@
 #undef CONFIG_ARCH_MISC_INIT
 
 /*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C		1
+#define CONFIG_I2C_MV		1
+#define CONFIG_PXA_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+
+/*
  * Environment variables configurations
  */
 #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define
  2011-03-17  6:28         ` Lei Wen
@ 2011-03-17  7:12           ` Heiko Schocher
  0 siblings, 0 replies; 123+ messages in thread
From: Heiko Schocher @ 2011-03-17  7:12 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> On Tue, Mar 15, 2011 at 2:54 PM, Heiko Schocher <hs@denx.de> wrote:
>> Hello Lei,
>>
>> Lei Wen wrote:
>>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>>> ---
>>>  arch/arm/cpu/pxa/cpu.c                   |   11 +++
>>>  arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 ------------
>>>  board/innokom/innokom.c                  |    9 +--
>>>  drivers/i2c/mvi2c.c                      |  139 +++++++++++++++++++++---------
>>>  include/configs/innokom.h                |    1 +
>>>  include/configs/xm250.h                  |    1 +
>>>  6 files changed, 111 insertions(+), 106 deletions(-)
>>>
[...]
>>> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
>>> index 0ea73c9..1ddee03 100644
>>> --- a/include/configs/innokom.h
>>> +++ b/include/configs/innokom.h
>>> @@ -141,6 +141,7 @@
>>>   * I2C bus
>>>   */
>>>  #define CONFIG_I2C_MV                        1
>>> +#define CONFIG_PXA_I2C_REG           0x40301680
>> Hmm.. is there no define for this magic value?
>>
> 
> This value is for i2c base address. Do you mean it need a description?

There should be in a cpu specific header a define for it, which you
can use here.

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform
  2011-03-17  6:38         ` Lei Wen
@ 2011-03-17  7:15           ` Heiko Schocher
  0 siblings, 0 replies; 123+ messages in thread
From: Heiko Schocher @ 2011-03-17  7:15 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> On Tue, Mar 15, 2011 at 3:08 PM, Heiko Schocher
> <heiko.schocher@invitel.hu> wrote:
>> Hello Lei,
>>
>> Lei Wen wrote:
>>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>>> ---
>>>  arch/arm/cpu/arm926ejs/armada100/cpu.c    |   14 ++++++++++++++
>>>  arch/arm/include/asm/arch-armada100/mfp.h |    4 ++++
>>>  board/Marvell/aspenite/aspenite.c         |    5 +++++
>>>  include/configs/aspenite.h                |   12 ++++++++++++
>>>  4 files changed, 35 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
>>> index 62aa175..8039ad2 100644
>>> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
>>> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
>>> @@ -62,6 +62,14 @@ int arch_cpu_init(void)
>>>       /* Enable GPIO clock */
>>>       writel(APBC_APBCLK, &apb1clkres->gpio);
>>>
>>> +     /* Enable general I2C clock */
>>> +     writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
>>> +     writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
>>> +
>>> +     /* Enable power I2C clock */
>>> +     writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
>>> +     writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
>>> +
>> If boards based on this cpu type don;t use i2c, i2c clock and
>> power would be enabled ... wouldn;t it be better, if we enable
>> this only if CONFIG_I2C_MV is defined?
> 
> Good point, I would modify to follow this.
> 
>> Hmm.. are the comments OK? In the first "block" you only
>> use twsi0 register, in the second "block" only twsi1 ...?
> 
> The comments is following what the spec says...
> In spec, the twsi0 named as general, and twsi1 named as power one.

Ah, ok. So the names in the struct are misleading.

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-22 11:17         ` Prafulla Wadaskar
  2011-03-22 12:34           ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-22 11:17 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 17, 2011 12:15 PM
> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> adrian.wenl at gmail.com
> Subject: [PATCH V3 2/5] mv_i2c: use structure to replace the direclty
> define
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V3:
> clean code sytle issue
> 
>  arch/arm/cpu/pxa/cpu.c                   |   11 +++
>  arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
>  board/innokom/innokom.c                  |    9 +--
>  drivers/i2c/mv_i2c.c                     |  133 ++++++++++++++---------
> ------
>  drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
>  include/configs/innokom.h                |    1 +
>  include/configs/xm250.h                  |    1 +
>  7 files changed, 161 insertions(+), 133 deletions(-)
>  create mode 100644 drivers/i2c/mv_i2c.h
> 
...snip...
> diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
> index 09756a4..152ea43 100644
> --- a/drivers/i2c/mv_i2c.c
> +++ b/drivers/i2c/mv_i2c.c
> @@ -8,6 +8,9 @@
>   * (C) Copyright 2003 Pengutronix e.K.
>   * Robert Schwebel <r.schwebel@pengutronix.de>
>   *
> + * (C) Copyright 2011 Marvell Inc.
> + * Lei Wen <leiwen@marvell.com>
> + *
>   * See file CREDITS for list of people who contributed to this
>   * project.
>   *
> @@ -34,44 +37,16 @@
>  #include <asm/io.h>
> 
>  #ifdef CONFIG_HARD_I2C
> -
> -/*
> - *	- CONFIG_SYS_I2C_SPEED
> - *	- I2C_PXA_SLAVE_ADDR
> - */
> -
> -#include <asm/arch/hardware.h>
> -#include <asm/arch/pxa-regs.h>
>  #include <i2c.h>
> -
> -#if (CONFIG_SYS_I2C_SPEED == 400000)
> -#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
> ICR_GCD \
> -			| ICR_SCLE)
> -#else
> -#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
> ICR_SCLE)
> -#endif
> -
> -#define I2C_ISR_INIT		0x7FF
> +#include "mv_i2c.h"
> 
>  #ifdef DEBUG_I2C
>  #define PRINTD(x) printf x
>  #else
>  #define PRINTD(x)
>  #endif
> -
> -/* Shall the current transfer have a start/stop condition? */
> -#define I2C_COND_NORMAL		0
> -#define I2C_COND_START		1
> -#define I2C_COND_STOP		2
> -
> -/* Shall the current transfer be ack/nacked or being waited for it? */
> -#define I2C_ACKNAK_WAITACK	1
> -#define I2C_ACKNAK_SENDACK	2
> -#define I2C_ACKNAK_SENDNAK	4
> -
> -/* Specify who shall transfer the data (master or slave) */
> -#define I2C_READ		0
> -#define I2C_WRITE		1
> +#define PXAI2C_AND(reg, val)	writel(readl(reg) & val, reg)
> +#define PXAI2C_OR(reg, val)	writel(readl(reg) | val, reg)

With reference to the file name MVI2C_ is better macro name to be used here.
Applicable for s/pxa/mv/g in the entire file too
 
> 
>  /* All transfers are described by this data structure */
>  struct i2c_msg {
> @@ -81,27 +56,37 @@ struct i2c_msg {
>  	u8 data;
>  };
> 
> +struct pxa_i2c {
> +	u32 ibmr;
> +	u32 pad0;
> +	u32 idbr;
> +	u32 pad1;
> +	u32 icr;
> +	u32 pad2;
> +	u32 isr;
> +	u32 pad3;
> +	u32 isar;
> +};

Please document the long names of these register with their offsets.

> +
> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> +
...snip...
>  		if (msg->acknack == I2C_ACKNAK_SENDACK)
> -			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> -		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> -		writel(readl(ICR) | ICR_TB, ICR);
> +			PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
> +		PXAI2C_AND(&base->icr, ~ICR_ALDIE);
> +		PXAI2C_OR(&base->icr, ICR_TB);

What are benefits of those macros?
To me this looks ugly and looses readability.

...snip...
> diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
> new file mode 100644
> index 0000000..41af0d9
> --- /dev/null
> +++ b/drivers/i2c/mv_i2c.h
> @@ -0,0 +1,83 @@
> +/*
> + * (C) Copyright 2011
> + * Marvell Inc, <www.marvell.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _MV_I2C_H_
> +#define _MV_I2C_H_
> +extern void i2c_clk_enable(void);
> +
> +/* Shall the current transfer have a start/stop condition? */
> +#define I2C_COND_NORMAL		0
> +#define I2C_COND_START		1
> +#define I2C_COND_STOP		2

How about prefixing the macros in this file as MVI2C instead of I2C?

...snip...
> +#endif
> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
> index 0ea73c9..1ddee03 100644
> --- a/include/configs/innokom.h
> +++ b/include/configs/innokom.h
> @@ -141,6 +141,7 @@
>   * I2C bus
>   */
>  #define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0x40301680

Please define i2c base address in armada100.h and in pantheon.h and use it in driver, avoid this definition here.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-22 11:22         ` Prafulla Wadaskar
  2011-03-22 12:38           ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-22 11:22 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 17, 2011 12:15 PM
> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> adrian.wenl at gmail.com
> Subject: [PATCH V3 3/5] I2C: add i2c support for Pantheon platform
> 
> Add i2c support to dkb board with pantheon soc.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V3:
> clean code sytle issue
> Add i2c clock enable code include in I2C configure define block
> 
>  arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
>  arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
>  arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
>  board/Marvell/dkb/dkb.c                  |    4 ++++
>  include/configs/dkb.h                    |   11 +++++++++++
>  5 files changed, 34 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> index 9ddc77c..8b2eafa 100644
> --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> @@ -59,6 +59,12 @@ int arch_cpu_init(void)
>  	/* Enable GPIO clock */
>  	writel(APBC_APBCLK, &apbclkres->gpio);
> 
> +#ifdef CONFIG_I2C_MV
> +	/* Enable I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
> +#endif
> +
>  	icache_enable();
> 
>  	return 0;
> @@ -76,3 +82,9 @@ int print_cpuinfo(void)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_I2C_MV
> +void i2c_clk_enable(void)
> +{
> +}

Empty function !!

> +#endif
> diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h
> b/arch/arm/include/asm/arch-pantheon/cpu.h
> index 30f4393..60955c5 100644
> --- a/arch/arm/include/asm/arch-pantheon/cpu.h
> +++ b/arch/arm/include/asm/arch-pantheon/cpu.h
> @@ -50,7 +50,9 @@ struct panthapb_registers {
>  	u32 uart0;	/*0x000*/
>  	u32 uart1;	/*0x004*/
>  	u32 gpio;	/*0x008*/
> -	u8 pad0[0x034 - 0x08 - 4];
> +	u8 pad0[0x02c - 0x08 - 4];
> +	u32 twsi;	/*0x02c*/
> +	u8 pad1[0x034 - 0x2c - 4];
>  	u32 timers;	/*0x034*/
>  };
> 
> diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h
> b/arch/arm/include/asm/arch-pantheon/mfp.h
> index fb291cf..e939196 100644
> --- a/arch/arm/include/asm/arch-pantheon/mfp.h
> +++ b/arch/arm/include/asm/arch-pantheon/mfp.h
> @@ -32,8 +32,10 @@
>   * offset, pull,pF, drv,dF, edge,eF ,afn,aF
>   */
>  /* UART2 */
> -#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> -#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> +#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> 
>  /* More macros can be defined here... */
> 
> diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
> index 72a2d2a..00f73e7 100644
> --- a/board/Marvell/dkb/dkb.c
> +++ b/board/Marvell/dkb/dkb.c
> @@ -36,6 +36,10 @@ int board_early_init_f(void)
>  		MFP47_UART2_RXD,
>  		MFP48_UART2_TXD,
> 
> +		/* I2C */
> +		MFP53_CI2C_SCL,
> +		MFP54_CI2C_SDA,
> +
>  		MFP_EOC		/*End of configureation*/
>  	};
>  	/* configure MFP's */
> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
> index 638af5e..1b18c44 100644
> --- a/include/configs/dkb.h
> +++ b/include/configs/dkb.h
> @@ -56,6 +56,17 @@
>  #include "mv-common.h"
> 
>  #undef CONFIG_ARCH_MISC_INIT
> +
> +/*
> + * I2C definition
> + */
> +#define CONFIG_CMD_I2C
> +#define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0xd4011000
> +#define CONFIG_HARD_I2C			1
> +#define CONFIG_SYS_I2C_SPEED		0
> +#define CONFIG_SYS_I2C_SLAVE		0xfe
> +
What about if I don't want to include this support
These configuration must if ifdefed with CONFIG_CMD_I2C which will be defined in board config file.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform Lei Wen
@ 2011-03-22 11:40         ` Prafulla Wadaskar
  2011-03-22 12:39           ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-22 11:40 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 17, 2011 12:15 PM
> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> adrian.wenl at gmail.com
> Subject: [PATCH V3 5/5] I2C: add i2c support for Armada100 platform
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V3:
> clean code sytle issue
> Add i2c clock enable code include in I2C configure define block
> 
>  arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
>  arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++------
> -------
>  board/Marvell/aspenite/aspenite.c         |    5 +++
>  include/configs/aspenite.h                |   12 ++++++++
>  4 files changed, 55 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c
> b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> index 62aa175..c21938e 100644
> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> @@ -62,6 +62,16 @@ int arch_cpu_init(void)
>  	/* Enable GPIO clock */
>  	writel(APBC_APBCLK, &apb1clkres->gpio);
> 
> +#ifdef CONFIG_I2C_MV
> +	/* Enable general I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
> +
> +	/* Enable power I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
> +#endif
> +
>  	/*
>  	 * Enable Functional and APB clock at 14.7456MHz
>  	 * for configured UART console
> @@ -90,3 +100,9 @@ int print_cpuinfo(void)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_I2C_MV
> +void i2c_clk_enable(void)
> +{
> +}

Empty function, you can better ifdef calling line

> +#endif
> diff --git a/arch/arm/include/asm/arch-armada100/mfp.h
> b/arch/arm/include/asm/arch-armada100/mfp.h
> index d21a79f..73783a7 100644
> --- a/arch/arm/include/asm/arch-armada100/mfp.h
> +++ b/arch/arm/include/asm/arch-armada100/mfp.h
> @@ -37,28 +37,32 @@
>   * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
>   */
>  /* UART1 */
> -#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
> -#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
> -#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
> -#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
> -#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
> -#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
> -#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
> -#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
> -#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 |
> MFP_DRIVE_MEDIUM
> -#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
> -#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
> -#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
> +#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
> +#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
> +#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
> +#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
> +#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
> +#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> +#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
> +#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> +#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 |
> MFP_DRIVE_MEDIUM)
> +#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> +#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
> +#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> 
>  /* UART2 */
> -#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> -#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> -#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> -#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> +#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> 
>  /* UART3 */
> -#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> -#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> +#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +
> +/* I2c */
> +#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 |
> MFP_DRIVE_MEDIUM)
> +#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 |
> MFP_DRIVE_MEDIUM)
> 
>  /* More macros can be defined here... */
> 
> diff --git a/board/Marvell/aspenite/aspenite.c
> b/board/Marvell/aspenite/aspenite.c
> index 046ffd6..34ac7aa 100644
> --- a/board/Marvell/aspenite/aspenite.c
> +++ b/board/Marvell/aspenite/aspenite.c
> @@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
>  int board_early_init_f(void)
>  {
>  	u32 mfp_cfg[] = {
> +		/* I2C */
> +		MFP105_CI2C_SDA,
> +		MFP106_CI2C_SCL,
> +
>  		/* Enable Console on UART1 */
>  		MFP107_UART1_RXD,
>  		MFP108_UART1_TXD,
> +
>  		MFP_EOC		/*End of configureation*/
>  	};
>  	/* configure MFP's */
> diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
> index fd35f3e..a6fa45e 100644
> --- a/include/configs/aspenite.h
> +++ b/include/configs/aspenite.h
> @@ -63,6 +63,18 @@
>  #undef CONFIG_ARCH_MISC_INIT
> 
>  /*
> + * I2C definition
> + */
> +#define CONFIG_CMD_I2C		1
> +#define CONFIG_I2C_MV		1
> +#define CONFIG_PXA_I2C_NUM	2
> +#define CONFIG_I2C_MULTI_BUS	1
> +#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
> +#define CONFIG_HARD_I2C		1
> +#define CONFIG_SYS_I2C_SPEED	0
> +#define CONFIG_SYS_I2C_SLAVE	0xfe

Same use ifdef CONFIG_CMD_I2C

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-22 11:42         ` Prafulla Wadaskar
  2011-03-22 12:43           ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-22 11:42 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 17, 2011 12:15 PM
> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> adrian.wenl at gmail.com
> Subject: [PATCH V3 1/5] pxa: move i2c driver to the common place
> 
> For better sharing with other platform other than pxa's,
> it is more convenient to put the driver to the common place.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> v2: rename previous pxa_i2c to mvi2c.
> 
> V3: change previous name from pxa_i2c to mv_i2c
>     clean code style issue exist in original code
> 
>  arch/arm/cpu/pxa/Makefile |    1 -
>  arch/arm/cpu/pxa/i2c.c    |  469 --------------------------------------
> -------
>  drivers/i2c/Makefile      |    1 +
>  drivers/i2c/mv_i2c.c      |  452
> +++++++++++++++++++++++++++++++++++++++++++
>  include/configs/innokom.h |    1 +
>  include/configs/xm250.h   |    1 +
>  6 files changed, 455 insertions(+), 470 deletions(-)
>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>  create mode 100644 drivers/i2c/mv_i2c.c


...snip...

> -#endif	/* CONFIG_HARD_I2C */
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 052fe36..00a12cc 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
>  COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
>  COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
>  COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o

Mvtwsi and mv_i2c are two i2c drivers for Marvell.
Can you merge these two?

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-22 11:17         ` Prafulla Wadaskar
@ 2011-03-22 12:34           ` Lei Wen
  2011-03-22 15:16             ` Wolfgang Denk
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-22 12:34 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Tue, Mar 22, 2011 at 7:17 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Thursday, March 17, 2011 12:15 PM
>> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
>> adrian.wenl at gmail.com
>> Subject: [PATCH V3 2/5] mv_i2c: use structure to replace the direclty
>> define
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V3:
>> clean code sytle issue
>>
>> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? | ? 11 +++
>> ?arch/arm/include/asm/arch-pxa/pxa-regs.h | ? 56 -------------
>> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ?| ? ?9 +--
>> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? | ?133 ++++++++++++++---------
>> ------
>> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? | ? 83 +++++++++++++++++++
>> ?include/configs/innokom.h ? ? ? ? ? ? ? ?| ? ?1 +
>> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ?| ? ?1 +
>> ?7 files changed, 161 insertions(+), 133 deletions(-)
>> ?create mode 100644 drivers/i2c/mv_i2c.h
>>
> ...snip...
>> diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
>> index 09756a4..152ea43 100644
>> --- a/drivers/i2c/mv_i2c.c
>> +++ b/drivers/i2c/mv_i2c.c
>> @@ -8,6 +8,9 @@
>> ? * (C) Copyright 2003 Pengutronix e.K.
>> ? * Robert Schwebel <r.schwebel@pengutronix.de>
>> ? *
>> + * (C) Copyright 2011 Marvell Inc.
>> + * Lei Wen <leiwen@marvell.com>
>> + *
>> ? * See file CREDITS for list of people who contributed to this
>> ? * project.
>> ? *
>> @@ -34,44 +37,16 @@
>> ?#include <asm/io.h>
>>
>> ?#ifdef CONFIG_HARD_I2C
>> -
>> -/*
>> - * ? - CONFIG_SYS_I2C_SPEED
>> - * ? - I2C_PXA_SLAVE_ADDR
>> - */
>> -
>> -#include <asm/arch/hardware.h>
>> -#include <asm/arch/pxa-regs.h>
>> ?#include <i2c.h>
>> -
>> -#if (CONFIG_SYS_I2C_SPEED == 400000)
>> -#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
>> ICR_GCD \
>> - ? ? ? ? ? ? ? ? ? ? | ICR_SCLE)
>> -#else
>> -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
>> ICR_SCLE)
>> -#endif
>> -
>> -#define I2C_ISR_INIT ? ? ? ? 0x7FF
>> +#include "mv_i2c.h"
>>
>> ?#ifdef DEBUG_I2C
>> ?#define PRINTD(x) printf x
>> ?#else
>> ?#define PRINTD(x)
>> ?#endif
>> -
>> -/* Shall the current transfer have a start/stop condition? */
>> -#define I2C_COND_NORMAL ? ? ? ? ? ? ?0
>> -#define I2C_COND_START ? ? ? ? ? ? ? 1
>> -#define I2C_COND_STOP ? ? ? ? ? ? ? ?2
>> -
>> -/* Shall the current transfer be ack/nacked or being waited for it? */
>> -#define I2C_ACKNAK_WAITACK ? 1
>> -#define I2C_ACKNAK_SENDACK ? 2
>> -#define I2C_ACKNAK_SENDNAK ? 4
>> -
>> -/* Specify who shall transfer the data (master or slave) */
>> -#define I2C_READ ? ? ? ? ? ? 0
>> -#define I2C_WRITE ? ? ? ? ? ?1
>> +#define PXAI2C_AND(reg, val) writel(readl(reg) & val, reg)
>> +#define PXAI2C_OR(reg, val) ?writel(readl(reg) | val, reg)
>
> With reference to the file name MVI2C_ is better macro name to be used here.
> Applicable for s/pxa/mv/g in the entire file too
>
>>
>> ?/* All transfers are described by this data structure */
>> ?struct i2c_msg {
>> @@ -81,27 +56,37 @@ struct i2c_msg {
>> ? ? ? u8 data;
>> ?};
>>
>> +struct pxa_i2c {
>> + ? ? u32 ibmr;
>> + ? ? u32 pad0;
>> + ? ? u32 idbr;
>> + ? ? u32 pad1;
>> + ? ? u32 icr;
>> + ? ? u32 pad2;
>> + ? ? u32 isr;
>> + ? ? u32 pad3;
>> + ? ? u32 isar;
>> +};
>
> Please document the long names of these register with their offsets.

Good point, I would do it in next post.

>
>> +
>> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
>> +
> ...snip...
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> + ? ? ? ? ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ACKNAK);
>> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ALDIE);
>> + ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_TB);
>
> What are benefits of those macros?
> To me this looks ugly and looses readability.

This intend for short the original too long code, but I don't reject to return
to the readl, write one.

>
> ...snip...
>> diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
>> new file mode 100644
>> index 0000000..41af0d9
>> --- /dev/null
>> +++ b/drivers/i2c/mv_i2c.h
>> @@ -0,0 +1,83 @@
>> +/*
>> + * (C) Copyright 2011
>> + * Marvell Inc, <www.marvell.com>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +#ifndef _MV_I2C_H_
>> +#define _MV_I2C_H_
>> +extern void i2c_clk_enable(void);
>> +
>> +/* Shall the current transfer have a start/stop condition? */
>> +#define I2C_COND_NORMAL ? ? ? ? ? ? ?0
>> +#define I2C_COND_START ? ? ? ? ? ? ? 1
>> +#define I2C_COND_STOP ? ? ? ? ? ? ? ?2
>
> How about prefixing the macros in this file as MVI2C instead of I2C?

I am ok with this change proposal.

>
> ...snip...
>> +#endif
>> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
>> index 0ea73c9..1ddee03 100644
>> --- a/include/configs/innokom.h
>> +++ b/include/configs/innokom.h
>> @@ -141,6 +141,7 @@
>> ? * I2C bus
>> ? */
>> ?#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_PXA_I2C_REG ? ? ? ? ? 0x40301680
>
> Please define i2c base address in armada100.h and in pantheon.h and use it in driver, avoid this definition here.

This is not armada100 nor pantheon board, but innokom board...
This driver intend to be used by all Marvell pxa series.
So for innokom board where should it define itself?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform
  2011-03-22 11:22         ` Prafulla Wadaskar
@ 2011-03-22 12:38           ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-22 12:38 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Tue, Mar 22, 2011 at 7:22 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Thursday, March 17, 2011 12:15 PM
>> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
>> adrian.wenl at gmail.com
>> Subject: [PATCH V3 3/5] I2C: add i2c support for Pantheon platform
>>
>> Add i2c support to dkb board with pantheon soc.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V3:
>> clean code sytle issue
>> Add i2c clock enable code include in I2C configure define block
>>
>> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ?| ? 12 ++++++++++++
>> ?arch/arm/include/asm/arch-pantheon/cpu.h | ? ?4 +++-
>> ?arch/arm/include/asm/arch-pantheon/mfp.h | ? ?6 ++++--
>> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ?| ? ?4 ++++
>> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ?| ? 11 +++++++++++
>> ?5 files changed, 34 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> index 9ddc77c..8b2eafa 100644
>> --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> @@ -59,6 +59,12 @@ int arch_cpu_init(void)
>> ? ? ? /* Enable GPIO clock */
>> ? ? ? writel(APBC_APBCLK, &apbclkres->gpio);
>>
>> +#ifdef CONFIG_I2C_MV
>> + ? ? /* Enable I2C clock */
>> + ? ? writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
>> + ? ? writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
>> +#endif
>> +
>> ? ? ? icache_enable();
>>
>> ? ? ? return 0;
>> @@ -76,3 +82,9 @@ int print_cpuinfo(void)
>> ? ? ? return 0;
>> ?}
>> ?#endif
>> +
>> +#ifdef CONFIG_I2C_MV
>> +void i2c_clk_enable(void)
>> +{
>> +}
>
> Empty function !!

As you might notice, this driver is directly taken from original cpu/pxa/i2c.c.
Original driver implent a global i2c clock enable in the reset
function call, which
is not needed by other platform, like the armada100 and pantheon.

But certainly I couldn't just rudely remove that code. So this is the reason
why I crreate the i2c_clk_enable function call and define it as void
one for the armada100
and pantheon.

>
>> +#endif
>> diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h
>> b/arch/arm/include/asm/arch-pantheon/cpu.h
>> index 30f4393..60955c5 100644
>> --- a/arch/arm/include/asm/arch-pantheon/cpu.h
>> +++ b/arch/arm/include/asm/arch-pantheon/cpu.h
>> @@ -50,7 +50,9 @@ struct panthapb_registers {
>> ? ? ? u32 uart0; ? ? ?/*0x000*/
>> ? ? ? u32 uart1; ? ? ?/*0x004*/
>> ? ? ? u32 gpio; ? ? ? /*0x008*/
>> - ? ? u8 pad0[0x034 - 0x08 - 4];
>> + ? ? u8 pad0[0x02c - 0x08 - 4];
>> + ? ? u32 twsi; ? ? ? /*0x02c*/
>> + ? ? u8 pad1[0x034 - 0x2c - 4];
>> ? ? ? u32 timers; ? ? /*0x034*/
>> ?};
>>
>> diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h
>> b/arch/arm/include/asm/arch-pantheon/mfp.h
>> index fb291cf..e939196 100644
>> --- a/arch/arm/include/asm/arch-pantheon/mfp.h
>> +++ b/arch/arm/include/asm/arch-pantheon/mfp.h
>> @@ -32,8 +32,10 @@
>> ? * offset, pull,pF, drv,dF, edge,eF ,afn,aF
>> ? */
>> ?/* UART2 */
>> -#define MFP47_UART2_RXD ? ? ? ? ? ? ?MFP_REG(0x198) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM
>> -#define MFP48_UART2_TXD ? ? ? ? ? ? ?MFP_REG(0x19c) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM
>> +#define MFP47_UART2_RXD ? ? ? ? ? ? ?(MFP_REG(0x198) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM)
>> +#define MFP48_UART2_TXD ? ? ? ? ? ? ?(MFP_REG(0x19c) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM)
>> +#define MFP53_CI2C_SCL ? ? ? ? ? ? ? (MFP_REG(0x1b0) | MFP_AF2 |
>> MFP_DRIVE_MEDIUM)
>> +#define MFP54_CI2C_SDA ? ? ? ? ? ? ? (MFP_REG(0x1b4) | MFP_AF2 |
>> MFP_DRIVE_MEDIUM)
>>
>> ?/* More macros can be defined here... */
>>
>> diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
>> index 72a2d2a..00f73e7 100644
>> --- a/board/Marvell/dkb/dkb.c
>> +++ b/board/Marvell/dkb/dkb.c
>> @@ -36,6 +36,10 @@ int board_early_init_f(void)
>> ? ? ? ? ? ? ? MFP47_UART2_RXD,
>> ? ? ? ? ? ? ? MFP48_UART2_TXD,
>>
>> + ? ? ? ? ? ? /* I2C */
>> + ? ? ? ? ? ? MFP53_CI2C_SCL,
>> + ? ? ? ? ? ? MFP54_CI2C_SDA,
>> +
>> ? ? ? ? ? ? ? MFP_EOC ? ? ? ? /*End of configureation*/
>> ? ? ? };
>> ? ? ? /* configure MFP's */
>> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
>> index 638af5e..1b18c44 100644
>> --- a/include/configs/dkb.h
>> +++ b/include/configs/dkb.h
>> @@ -56,6 +56,17 @@
>> ?#include "mv-common.h"
>>
>> ?#undef CONFIG_ARCH_MISC_INIT
>> +
>> +/*
>> + * I2C definition
>> + */
>> +#define CONFIG_CMD_I2C
>> +#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_PXA_I2C_REG ? ? ? ? ? 0xd4011000
>> +#define CONFIG_HARD_I2C ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_SYS_I2C_SPEED ? ? ? ? 0
>> +#define CONFIG_SYS_I2C_SLAVE ? ? ? ? 0xfe
>> +
> What about if I don't want to include this support
> These configuration must if ifdefed with CONFIG_CMD_I2C which will be defined in board config file.

Yep, that make sense. I would include this change for next post.

Thanks,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform
  2011-03-22 11:40         ` Prafulla Wadaskar
@ 2011-03-22 12:39           ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-22 12:39 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Tue, Mar 22, 2011 at 7:40 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Thursday, March 17, 2011 12:15 PM
>> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
>> adrian.wenl at gmail.com
>> Subject: [PATCH V3 5/5] I2C: add i2c support for Armada100 platform
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V3:
>> clean code sytle issue
>> Add i2c clock enable code include in I2C configure define block
>>
>> ?arch/arm/cpu/arm926ejs/armada100/cpu.c ? ?| ? 16 +++++++++++
>> ?arch/arm/include/asm/arch-armada100/mfp.h | ? 40 ++++++++++++++++------
>> -------
>> ?board/Marvell/aspenite/aspenite.c ? ? ? ? | ? ?5 +++
>> ?include/configs/aspenite.h ? ? ? ? ? ? ? ?| ? 12 ++++++++
>> ?4 files changed, 55 insertions(+), 18 deletions(-)
>>
>> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> b/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> index 62aa175..c21938e 100644
>> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
>> @@ -62,6 +62,16 @@ int arch_cpu_init(void)
>> ? ? ? /* Enable GPIO clock */
>> ? ? ? writel(APBC_APBCLK, &apb1clkres->gpio);
>>
>> +#ifdef CONFIG_I2C_MV
>> + ? ? /* Enable general I2C clock */
>> + ? ? writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
>> + ? ? writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
>> +
>> + ? ? /* Enable power I2C clock */
>> + ? ? writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
>> + ? ? writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
>> +#endif
>> +
>> ? ? ? /*
>> ? ? ? ?* Enable Functional and APB clock at 14.7456MHz
>> ? ? ? ?* for configured UART console
>> @@ -90,3 +100,9 @@ int print_cpuinfo(void)
>> ? ? ? return 0;
>> ?}
>> ?#endif
>> +
>> +#ifdef CONFIG_I2C_MV
>> +void i2c_clk_enable(void)
>> +{
>> +}
>
> Empty function, you can better ifdef calling line

Same reason as I explain in previous email...

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-22 11:42         ` Prafulla Wadaskar
@ 2011-03-22 12:43           ` Lei Wen
  2011-03-23  7:38             ` Prafulla Wadaskar
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-22 12:43 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Tue, Mar 22, 2011 at 7:42 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Thursday, March 17, 2011 12:15 PM
>> To: Heiko Schocher; Wolfgang Denk; Prafulla Wadaskar; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
>> adrian.wenl at gmail.com
>> Subject: [PATCH V3 1/5] pxa: move i2c driver to the common place
>>
>> For better sharing with other platform other than pxa's,
>> it is more convenient to put the driver to the common place.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> v2: rename previous pxa_i2c to mvi2c.
>>
>> V3: change previous name from pxa_i2c to mv_i2c
>> ? ? clean code style issue exist in original code
>>
>> ?arch/arm/cpu/pxa/Makefile | ? ?1 -
>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 --------------------------------------
>> -------
>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452
>> +++++++++++++++++++++++++++++++++++++++++++
>> ?include/configs/innokom.h | ? ?1 +
>> ?include/configs/xm250.h ? | ? ?1 +
>> ?6 files changed, 455 insertions(+), 470 deletions(-)
>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>> ?create mode 100644 drivers/i2c/mv_i2c.c
>
>
> ...snip...
>
>> -#endif ? ? ? /* CONFIG_HARD_I2C */
>> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
>> index 052fe36..00a12cc 100644
>> --- a/drivers/i2c/Makefile
>> +++ b/drivers/i2c/Makefile
>> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
>> ?COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
>> ?COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
>> ?COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
>> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
>
> Mvtwsi and mv_i2c are two i2c drivers for Marvell.
> Can you merge these two?

As I explain to you before. Although kirkwood and pxa series are both
the product
of Marvell, but it don't necessary means that they must have the same controller
for both product line. For the i2c part, they just use two different controller.
So why you keep request merge those two? Do you mean you want to
create a unique I2C
framework for whole i2c drivers in drivers/i2c?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-22 12:34           ` Lei Wen
@ 2011-03-22 15:16             ` Wolfgang Denk
  2011-03-23  8:48               ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Wolfgang Denk @ 2011-03-22 15:16 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <AANLkTikMYpVVJDRnGRVZ3XZsYTn_yprpfMUUp_3DdHbJ@mail.gmail.com> you wrote:
> 
...
> >> -                     writel(readl(ICR) & ~ICR_ACKNA> K, ICR);
> >> -             writel(readl(ICR) & ~ICR_ALDIE, ICR);
> >> -             writel(readl(ICR) | ICR_TB, ICR);
> >> +                     PXAI2C_AND(&base->icr, ~ICR_AC> KNAK);
> >> +             PXAI2C_AND(&base->icr, ~ICR_ALDIE);
> >> +             PXAI2C_OR(&base->icr, ICR_TB);
> >
> > What are benefits of those macros?
> > To me this looks ugly and looses readability.
>
> This intend for short the original too long code, but I don't reject to ret> urn
> to the readl, write one.

Please either use plain writel() / readl() accessors, or,
alternatively, implement standard accessors that could be used by
everybody else for the same purpose, too.

See for example the misc clrbits*(), setbits*() or clrsetbits*()
macros as dfined for example in "arch/powerpc/include/asm/io.h"

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Deliver yesterday, code today, think tomorrow."

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-22 12:43           ` Lei Wen
@ 2011-03-23  7:38             ` Prafulla Wadaskar
  2011-03-23  8:22               ` Heiko Schocher
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-23  7:38 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:adrian.wenl at gmail.com]
> Sent: Tuesday, March 22, 2011 6:14 PM
> To: Prafulla Wadaskar
> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
> 
...snip...
> >> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
> >> ?drivers/i2c/mv_i2c.c ? ? ?| ?452
> >> +++++++++++++++++++++++++++++++++++++++++++
> >> ?include/configs/innokom.h | ? ?1 +
> >> ?include/configs/xm250.h ? | ? ?1 +
> >> ?6 files changed, 455 insertions(+), 470 deletions(-)
> >> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
> >> ?create mode 100644 drivers/i2c/mv_i2c.c
> >
> >
> > ...snip...
> >
> >> -#endif ? ? ? /* CONFIG_HARD_I2C */
> >> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> >> index 052fe36..00a12cc 100644
> >> --- a/drivers/i2c/Makefile
> >> +++ b/drivers/i2c/Makefile
> >> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
> >> ?COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
> >> ?COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
> >> ?COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
> >> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
> >
> > Mvtwsi and mv_i2c are two i2c drivers for Marvell.
> > Can you merge these two?
> 
> As I explain to you before. Although kirkwood and pxa series are both
> the product
> of Marvell, but it don't necessary means that they must have the same
> controller
> for both product line. For the i2c part, they just use two different
> controller.
> So why you keep request merge those two? Do you mean you want to
> create a unique I2C
> framework for whole i2c drivers in drivers/i2c?

Hi Lei

1. Most of i2c drivers supported in u-boot are either in SoC specific folder or in drivers/i2c folder, there is no as such thumb rule here.
2. Secondly all these drivers have some common code, mostly i2c_read, i2c_write, i2c_probe, etc.. 
3. Specific to Marvell, we already have mvtwsi.c that supports Kirkwood and Orion5X SoCs. Whereas you are adding new mvi2c.c that will support armada100, pantheon apart from pxa.
4. What about if we need to support some new Marvell SoC with different i2C controller? Do we add one more driver?

I would love if some one creates drivers/i2c/i2c_core.c??? not necessarily you ;-)

Here is what I would like to suggest.
1. cmd_i2c mostly interfaced with i2c_probe, i2c_read, i2c_write, i2c_get_bun_num, i2c_set_bus_num, those should go in drivers/i2c_core.c
2. APIs like i2c_start, i2c_stop, i2c_send, i2c_recv, i2c_reset are more I2C controller specific and those will be different implementation on different SoCs, those can go in SoC specific i2c driver file.
3. all I2C driver files should be in drivers/i2c/
4. i2c_read/write API need to be redefined since those are not generic to be used to access any I2C peripheral( most of the device don't need address to be programmed)
5. Flags must be provided for i2c_read/write APIs to have precise control to execute I2C_START/I2C_STOP sequence in the call.

Since you are the one starting with re-using pxa driver for armada100 and Pantheon SoC, why don't you split it into i2c_core.c and i2c_pxa.c? then add i2c_armada100.c and i2c_pantheon.c?
Others can migrate in the similar way. (even mvtwsi,c)

Hi Heiko
What do you think on this?

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  7:38             ` Prafulla Wadaskar
@ 2011-03-23  8:22               ` Heiko Schocher
  2011-03-23  8:43                 ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Heiko Schocher @ 2011-03-23  8:22 UTC (permalink / raw)
  To: u-boot

Hello Prafulla,

Prafulla Wadaskar wrote:
>> -----Original Message-----
>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>> Sent: Tuesday, March 22, 2011 6:14 PM
>> To: Prafulla Wadaskar
>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
>>
> ...snip...
>>>>  drivers/i2c/Makefile      |    1 +
>>>>  drivers/i2c/mv_i2c.c      |  452
>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>>  include/configs/innokom.h |    1 +
>>>>  include/configs/xm250.h   |    1 +
>>>>  6 files changed, 455 insertions(+), 470 deletions(-)
>>>>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>>>>  create mode 100644 drivers/i2c/mv_i2c.c
>>>
>>> ...snip...
>>>
>>>> -#endif       /* CONFIG_HARD_I2C */
>>>> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
>>>> index 052fe36..00a12cc 100644
>>>> --- a/drivers/i2c/Makefile
>>>> +++ b/drivers/i2c/Makefile
>>>> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
>>>>  COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
>>>>  COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
>>>>  COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
>>>> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
>>> Mvtwsi and mv_i2c are two i2c drivers for Marvell.
>>> Can you merge these two?
>> As I explain to you before. Although kirkwood and pxa series are both
>> the product
>> of Marvell, but it don't necessary means that they must have the same
>> controller
>> for both product line. For the i2c part, they just use two different
>> controller.
>> So why you keep request merge those two? Do you mean you want to
>> create a unique I2C
>> framework for whole i2c drivers in drivers/i2c?
> 
> Hi Lei
> 
> 1. Most of i2c drivers supported in u-boot are either in SoC specific folder or in drivers/i2c folder, there is no as such thumb rule here.

New drivers should go to drivers/i2c !
The existing (old) drivers are just not moved ...
patches welcome!

> 2. Secondly all these drivers have some common code, mostly i2c_read, i2c_write, i2c_probe, etc.. 
> 3. Specific to Marvell, we already have mvtwsi.c that supports Kirkwood and Orion5X SoCs. Whereas you are adding new mvi2c.c that will support armada100, pantheon apart from pxa.
> 4. What about if we need to support some new Marvell SoC with different i2C controller? Do we add one more driver?
> 
> I would love if some one creates drivers/i2c/i2c_core.c??? not necessarily you ;-)
> 
> Here is what I would like to suggest.
> 1. cmd_i2c mostly interfaced with i2c_probe, i2c_read, i2c_write, i2c_get_bun_num, i2c_set_bus_num, those should go in drivers/i2c_core.c

Yep, but see below comment.

> 2. APIs like i2c_start, i2c_stop, i2c_send, i2c_recv, i2c_reset are more I2C controller specific and those will be different implementation on different SoCs, those can go in SoC specific i2c driver file.

Yep.

> 3. all I2C driver files should be in drivers/i2c/

Yep.

> 4. i2c_read/write API need to be redefined since those are not generic to be used to access any I2C peripheral( most of the device don't need address to be programmed)

With which devices do you have problems? You can set with
"i2c mw chip address.0 ..." an addresslen = 0 ... or?

> 5. Flags must be provided for i2c_read/write APIs to have precise control to execute I2C_START/I2C_STOP sequence in the call.

If needed, yes.

> Since you are the one starting with re-using pxa driver for armada100 and Pantheon SoC, why don't you split it into i2c_core.c and i2c_pxa.c? then add i2c_armada100.c and i2c_pantheon.c?
> Others can migrate in the similar way. (even mvtwsi,c)
> 
> Hi Heiko
> What do you think on this?

I made such a i2c_core.c file in the multibus/multiadapter branch
for the i2c subsystem, see here:

http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=shortlog;h=refs/heads/multibus_v2

(also you can grep in u-boot ML for discussions about)

Actual state:
- arm boards: i2c driver tested on suen3 (kirkwood based board)
- powerpc boards: i2c driver tested on mpc82xx, 83xx, 8xx boards
- all others just coded not tested ...
  (A result of lacking hw and/or time)

ToDo:
- rebase against current head
  (Sorry, didn;t found time to rebase it since Oktober 2010)
- Update README
- porting arrived new i2c drivers, boards since Oktober 2010
  to this new i2c approach
- testing, testing, testing ... Testers welcome!

I prefer to integrate this to mainline, before we do above steps
(4?) and 5. As Lei mentioned, if a soc/board has different i2c
controllers and more than one bus we *need* this approach,
so it is not worthwhile to introduce a i2c_core file only ...
instead we should forwarding this branch to mainline?

Patches are welcome ;-)

I am afraid, this would get such a big cut as the arm relocation
changes ... and it affects all archs.

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  8:22               ` Heiko Schocher
@ 2011-03-23  8:43                 ` Lei Wen
  2011-03-23  8:53                   ` Heiko Schocher
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-23  8:43 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On Wed, Mar 23, 2011 at 4:22 PM, Heiko Schocher <hs@denx.de> wrote:
> Hello Prafulla,
>
> Prafulla Wadaskar wrote:
>>> -----Original Message-----
>>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>>> Sent: Tuesday, March 22, 2011 6:14 PM
>>> To: Prafulla Wadaskar
>>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
>>>
>> ...snip...
>>>>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>>>>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452
>>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>>> ?include/configs/innokom.h | ? ?1 +
>>>>> ?include/configs/xm250.h ? | ? ?1 +
>>>>> ?6 files changed, 455 insertions(+), 470 deletions(-)
>>>>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>>>>> ?create mode 100644 drivers/i2c/mv_i2c.c
>>>>
>>>> ...snip...
>>>>
>>>>> -#endif ? ? ? /* CONFIG_HARD_I2C */
>>>>> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
>>>>> index 052fe36..00a12cc 100644
>>>>> --- a/drivers/i2c/Makefile
>>>>> +++ b/drivers/i2c/Makefile
>>>>> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
>>>>> ?COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
>>>>> ?COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
>>>>> ?COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
>>>>> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
>>>> Mvtwsi and mv_i2c are two i2c drivers for Marvell.
>>>> Can you merge these two?
>>> As I explain to you before. Although kirkwood and pxa series are both
>>> the product
>>> of Marvell, but it don't necessary means that they must have the same
>>> controller
>>> for both product line. For the i2c part, they just use two different
>>> controller.
>>> So why you keep request merge those two? Do you mean you want to
>>> create a unique I2C
>>> framework for whole i2c drivers in drivers/i2c?
>>
>> Hi Lei
>>
>> 1. Most of i2c drivers supported in u-boot are either in SoC specific folder or in drivers/i2c folder, there is no as such thumb rule here.
>
> New drivers should go to drivers/i2c !
> The existing (old) drivers are just not moved ...
> patches welcome!
>
>> 2. Secondly all these drivers have some common code, mostly i2c_read, i2c_write, i2c_probe, etc..
>> 3. Specific to Marvell, we already have mvtwsi.c that supports Kirkwood and Orion5X SoCs. Whereas you are adding new mvi2c.c that will support armada100, pantheon apart from pxa.
>> 4. What about if we need to support some new Marvell SoC with different i2C controller? Do we add one more driver?
>>
>> I would love if some one creates drivers/i2c/i2c_core.c??? not necessarily you ;-)
>>
>> Here is what I would like to suggest.
>> 1. cmd_i2c mostly interfaced with i2c_probe, i2c_read, i2c_write, i2c_get_bun_num, i2c_set_bus_num, those should go in drivers/i2c_core.c
>
> Yep, but see below comment.
>
>> 2. APIs like i2c_start, i2c_stop, i2c_send, i2c_recv, i2c_reset are more I2C controller specific and those will be different implementation on different SoCs, those can go in SoC specific i2c driver file.
>
> Yep.
>
>> 3. all I2C driver files should be in drivers/i2c/
>
> Yep.
>
>> 4. i2c_read/write API need to be redefined since those are not generic to be used to access any I2C peripheral( most of the device don't need address to be programmed)
>
> With which devices do you have problems? You can set with
> "i2c mw chip address.0 ..." an addresslen = 0 ... or?
>
>> 5. Flags must be provided for i2c_read/write APIs to have precise control to execute I2C_START/I2C_STOP sequence in the call.
>
> If needed, yes.
>
>> Since you are the one starting with re-using pxa driver for armada100 and Pantheon SoC, why don't you split it into i2c_core.c and i2c_pxa.c? then add i2c_armada100.c and i2c_pantheon.c?
>> Others can migrate in the similar way. (even mvtwsi,c)
>>
>> Hi Heiko
>> What do you think on this?
>
> I made such a i2c_core.c file in the multibus/multiadapter branch
> for the i2c subsystem, see here:
>
> http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=shortlog;h=refs/heads/multibus_v2
>
> (also you can grep in u-boot ML for discussions about)
>
> Actual state:
> - arm boards: i2c driver tested on suen3 (kirkwood based board)
> - powerpc boards: i2c driver tested on mpc82xx, 83xx, 8xx boards
> - all others just coded not tested ...
> ?(A result of lacking hw and/or time)
>
> ToDo:
> - rebase against current head
> ?(Sorry, didn;t found time to rebase it since Oktober 2010)
> - Update README
> - porting arrived new i2c drivers, boards since Oktober 2010
> ?to this new i2c approach
> - testing, testing, testing ... Testers welcome!
>
> I prefer to integrate this to mainline, before we do above steps
> (4?) and 5. As Lei mentioned, if a soc/board has different i2c
> controllers and more than one bus we *need* this approach,
> so it is not worthwhile to introduce a i2c_core file only ...
> instead we should forwarding this branch to mainline?
>
> Patches are welcome ;-)
>
> I am afraid, this would get such a big cut as the arm relocation
> changes ... and it affects all archs.

It is certainly a big change for introduce the i2c-core framework. :)

Also my incoming mmc/sd enabling patch for pantheon and armada100
is also based on this i2c enabling patch, as I need the i2c to turn on the
repsonding pmic power connection.

While we could get a i2c working pantheon, armada100,  and other pxa
series platform now with this patch set. So what about Could we merge
this first, and
gradually change to the i2c framework, test and make it mature.

Prafulla,
What do you think for this proposal?

Thanks,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-22 15:16             ` Wolfgang Denk
@ 2011-03-23  8:48               ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-23  8:48 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

On Tue, Mar 22, 2011 at 11:16 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Lei Wen,
>
> In message <AANLkTikMYpVVJDRnGRVZ3XZsYTn_yprpfMUUp_3DdHbJ@mail.gmail.com> you wrote:
>>
> ...
>> >> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNA> K, ICR);
>> >> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> >> - ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> >> + ? ? ? ? ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_AC> KNAK);
>> >> + ? ? ? ? ? ? PXAI2C_AND(&base->icr, ~ICR_ALDIE);
>> >> + ? ? ? ? ? ? PXAI2C_OR(&base->icr, ICR_TB);
>> >
>> > What are benefits of those macros?
>> > To me this looks ugly and looses readability.
>>
>> This intend for short the original too long code, but I don't reject to ret> urn
>> to the readl, write one.
>
> Please either use plain writel() / readl() accessors, or,
> alternatively, implement standard accessors that could be used by
> everybody else for the same purpose, too.
>
> See for example the misc clrbits*(), setbits*() or clrsetbits*()
> macros as dfined for example in "arch/powerpc/include/asm/io.h"

Yep, that is what I want. :)
I would post next patch set include this suggestion.

Thanks,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  8:43                 ` Lei Wen
@ 2011-03-23  8:53                   ` Heiko Schocher
  2011-03-23  8:56                     ` Lei Wen
  2011-03-23  9:12                     ` Prafulla Wadaskar
  0 siblings, 2 replies; 123+ messages in thread
From: Heiko Schocher @ 2011-03-23  8:53 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> Hi Heiko,
> 
> On Wed, Mar 23, 2011 at 4:22 PM, Heiko Schocher <hs@denx.de> wrote:
>> Hello Prafulla,
>>
>> Prafulla Wadaskar wrote:
>>>> -----Original Message-----
>>>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>>>> Sent: Tuesday, March 22, 2011 6:14 PM
>>>> To: Prafulla Wadaskar
>>>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>>>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>>>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
>>>>
>>> ...snip...
>>>>>>  drivers/i2c/Makefile      |    1 +
>>>>>>  drivers/i2c/mv_i2c.c      |  452
>>>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>>>>  include/configs/innokom.h |    1 +
>>>>>>  include/configs/xm250.h   |    1 +
>>>>>>  6 files changed, 455 insertions(+), 470 deletions(-)
>>>>>>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>>>>>>  create mode 100644 drivers/i2c/mv_i2c.c
>>>>> ...snip...
>>>>>
>>>>>> -#endif       /* CONFIG_HARD_I2C */
>>>>>> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
>>>>>> index 052fe36..00a12cc 100644
>>>>>> --- a/drivers/i2c/Makefile
>>>>>> +++ b/drivers/i2c/Makefile
>>>>>> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
>>>>>>  COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
>>>>>>  COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
>>>>>>  COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
>>>>>> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
>>>>> Mvtwsi and mv_i2c are two i2c drivers for Marvell.
>>>>> Can you merge these two?
>>>> As I explain to you before. Although kirkwood and pxa series are both
>>>> the product
>>>> of Marvell, but it don't necessary means that they must have the same
>>>> controller
>>>> for both product line. For the i2c part, they just use two different
>>>> controller.
>>>> So why you keep request merge those two? Do you mean you want to
>>>> create a unique I2C
>>>> framework for whole i2c drivers in drivers/i2c?
>>> Hi Lei
>>>
>>> 1. Most of i2c drivers supported in u-boot are either in SoC specific folder or in drivers/i2c folder, there is no as such thumb rule here.
>> New drivers should go to drivers/i2c !
>> The existing (old) drivers are just not moved ...
>> patches welcome!
>>
>>> 2. Secondly all these drivers have some common code, mostly i2c_read, i2c_write, i2c_probe, etc..
>>> 3. Specific to Marvell, we already have mvtwsi.c that supports Kirkwood and Orion5X SoCs. Whereas you are adding new mvi2c.c that will support armada100, pantheon apart from pxa.
>>> 4. What about if we need to support some new Marvell SoC with different i2C controller? Do we add one more driver?
>>>
>>> I would love if some one creates drivers/i2c/i2c_core.c??? not necessarily you ;-)
>>>
>>> Here is what I would like to suggest.
>>> 1. cmd_i2c mostly interfaced with i2c_probe, i2c_read, i2c_write, i2c_get_bun_num, i2c_set_bus_num, those should go in drivers/i2c_core.c
>> Yep, but see below comment.
>>
>>> 2. APIs like i2c_start, i2c_stop, i2c_send, i2c_recv, i2c_reset are more I2C controller specific and those will be different implementation on different SoCs, those can go in SoC specific i2c driver file.
>> Yep.
>>
>>> 3. all I2C driver files should be in drivers/i2c/
>> Yep.
>>
>>> 4. i2c_read/write API need to be redefined since those are not generic to be used to access any I2C peripheral( most of the device don't need address to be programmed)
>> With which devices do you have problems? You can set with
>> "i2c mw chip address.0 ..." an addresslen = 0 ... or?
>>
>>> 5. Flags must be provided for i2c_read/write APIs to have precise control to execute I2C_START/I2C_STOP sequence in the call.
>> If needed, yes.
>>
>>> Since you are the one starting with re-using pxa driver for armada100 and Pantheon SoC, why don't you split it into i2c_core.c and i2c_pxa.c? then add i2c_armada100.c and i2c_pantheon.c?
>>> Others can migrate in the similar way. (even mvtwsi,c)
>>>
>>> Hi Heiko
>>> What do you think on this?
>> I made such a i2c_core.c file in the multibus/multiadapter branch
>> for the i2c subsystem, see here:
>>
>> http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=shortlog;h=refs/heads/multibus_v2
>>
>> (also you can grep in u-boot ML for discussions about)
>>
>> Actual state:
>> - arm boards: i2c driver tested on suen3 (kirkwood based board)
>> - powerpc boards: i2c driver tested on mpc82xx, 83xx, 8xx boards
>> - all others just coded not tested ...
>>  (A result of lacking hw and/or time)
>>
>> ToDo:
>> - rebase against current head
>>  (Sorry, didn;t found time to rebase it since Oktober 2010)
>> - Update README
>> - porting arrived new i2c drivers, boards since Oktober 2010
>>  to this new i2c approach
>> - testing, testing, testing ... Testers welcome!
>>
>> I prefer to integrate this to mainline, before we do above steps
>> (4?) and 5. As Lei mentioned, if a soc/board has different i2c
>> controllers and more than one bus we *need* this approach,
>> so it is not worthwhile to introduce a i2c_core file only ...
>> instead we should forwarding this branch to mainline?
>>
>> Patches are welcome ;-)
>>
>> I am afraid, this would get such a big cut as the arm relocation
>> changes ... and it affects all archs.
> 
> It is certainly a big change for introduce the i2c-core framework. :)
> 
> Also my incoming mmc/sd enabling patch for pantheon and armada100
> is also based on this i2c enabling patch, as I need the i2c to turn on the
> repsonding pmic power connection.
> 
> While we could get a i2c working pantheon, armada100,  and other pxa
> series platform now with this patch set. So what about Could we merge
> this first, and
> gradually change to the i2c framework, test and make it mature.

I am fine with that, but please address the other comments from
Prafulla and Wolfgang (rename defines, use standard accessors).

If you plan to investigate time for the multibus/multiadapter
i2c branch, let me know, maybe I can rebase this branch before
you use it.

> Prafulla,
> What do you think for this proposal?
> 
> Thanks,
> Lei

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  8:53                   ` Heiko Schocher
@ 2011-03-23  8:56                     ` Lei Wen
  2011-03-23  9:07                       ` Heiko Schocher
  2011-03-23  9:12                     ` Prafulla Wadaskar
  1 sibling, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-23  8:56 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

On Wed, Mar 23, 2011 at 4:53 PM, Heiko Schocher <hs@denx.de> wrote:
> Hello Lei,
>
> Lei Wen wrote:
>> Hi Heiko,
>>
>> On Wed, Mar 23, 2011 at 4:22 PM, Heiko Schocher <hs@denx.de> wrote:
>>> Hello Prafulla,
>>>
>>> Prafulla Wadaskar wrote:
>>>>> -----Original Message-----
>>>>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>>>>> Sent: Tuesday, March 22, 2011 6:14 PM
>>>>> To: Prafulla Wadaskar
>>>>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>>>>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>>>>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
>>>>>
>>>> ...snip...
>>>>>>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>>>>>>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452
>>>>>>> +++++++++++++++++++++++++++++++++++++++++++
>>>>>>> ?include/configs/innokom.h | ? ?1 +
>>>>>>> ?include/configs/xm250.h ? | ? ?1 +
>>>>>>> ?6 files changed, 455 insertions(+), 470 deletions(-)
>>>>>>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>>>>>>> ?create mode 100644 drivers/i2c/mv_i2c.c
>>>>>> ...snip...
>>>>>>
>>>>>>> -#endif ? ? ? /* CONFIG_HARD_I2C */
>>>>>>> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
>>>>>>> index 052fe36..00a12cc 100644
>>>>>>> --- a/drivers/i2c/Makefile
>>>>>>> +++ b/drivers/i2c/Makefile
>>>>>>> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
>>>>>>> ?COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
>>>>>>> ?COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
>>>>>>> ?COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
>>>>>>> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
>>>>>> Mvtwsi and mv_i2c are two i2c drivers for Marvell.
>>>>>> Can you merge these two?
>>>>> As I explain to you before. Although kirkwood and pxa series are both
>>>>> the product
>>>>> of Marvell, but it don't necessary means that they must have the same
>>>>> controller
>>>>> for both product line. For the i2c part, they just use two different
>>>>> controller.
>>>>> So why you keep request merge those two? Do you mean you want to
>>>>> create a unique I2C
>>>>> framework for whole i2c drivers in drivers/i2c?
>>>> Hi Lei
>>>>
>>>> 1. Most of i2c drivers supported in u-boot are either in SoC specific folder or in drivers/i2c folder, there is no as such thumb rule here.
>>> New drivers should go to drivers/i2c !
>>> The existing (old) drivers are just not moved ...
>>> patches welcome!
>>>
>>>> 2. Secondly all these drivers have some common code, mostly i2c_read, i2c_write, i2c_probe, etc..
>>>> 3. Specific to Marvell, we already have mvtwsi.c that supports Kirkwood and Orion5X SoCs. Whereas you are adding new mvi2c.c that will support armada100, pantheon apart from pxa.
>>>> 4. What about if we need to support some new Marvell SoC with different i2C controller? Do we add one more driver?
>>>>
>>>> I would love if some one creates drivers/i2c/i2c_core.c??? not necessarily you ;-)
>>>>
>>>> Here is what I would like to suggest.
>>>> 1. cmd_i2c mostly interfaced with i2c_probe, i2c_read, i2c_write, i2c_get_bun_num, i2c_set_bus_num, those should go in drivers/i2c_core.c
>>> Yep, but see below comment.
>>>
>>>> 2. APIs like i2c_start, i2c_stop, i2c_send, i2c_recv, i2c_reset are more I2C controller specific and those will be different implementation on different SoCs, those can go in SoC specific i2c driver file.
>>> Yep.
>>>
>>>> 3. all I2C driver files should be in drivers/i2c/
>>> Yep.
>>>
>>>> 4. i2c_read/write API need to be redefined since those are not generic to be used to access any I2C peripheral( most of the device don't need address to be programmed)
>>> With which devices do you have problems? You can set with
>>> "i2c mw chip address.0 ..." an addresslen = 0 ... or?
>>>
>>>> 5. Flags must be provided for i2c_read/write APIs to have precise control to execute I2C_START/I2C_STOP sequence in the call.
>>> If needed, yes.
>>>
>>>> Since you are the one starting with re-using pxa driver for armada100 and Pantheon SoC, why don't you split it into i2c_core.c and i2c_pxa.c? then add i2c_armada100.c and i2c_pantheon.c?
>>>> Others can migrate in the similar way. (even mvtwsi,c)
>>>>
>>>> Hi Heiko
>>>> What do you think on this?
>>> I made such a i2c_core.c file in the multibus/multiadapter branch
>>> for the i2c subsystem, see here:
>>>
>>> http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=shortlog;h=refs/heads/multibus_v2
>>>
>>> (also you can grep in u-boot ML for discussions about)
>>>
>>> Actual state:
>>> - arm boards: i2c driver tested on suen3 (kirkwood based board)
>>> - powerpc boards: i2c driver tested on mpc82xx, 83xx, 8xx boards
>>> - all others just coded not tested ...
>>> ?(A result of lacking hw and/or time)
>>>
>>> ToDo:
>>> - rebase against current head
>>> ?(Sorry, didn;t found time to rebase it since Oktober 2010)
>>> - Update README
>>> - porting arrived new i2c drivers, boards since Oktober 2010
>>> ?to this new i2c approach
>>> - testing, testing, testing ... Testers welcome!
>>>
>>> I prefer to integrate this to mainline, before we do above steps
>>> (4?) and 5. As Lei mentioned, if a soc/board has different i2c
>>> controllers and more than one bus we *need* this approach,
>>> so it is not worthwhile to introduce a i2c_core file only ...
>>> instead we should forwarding this branch to mainline?
>>>
>>> Patches are welcome ;-)
>>>
>>> I am afraid, this would get such a big cut as the arm relocation
>>> changes ... and it affects all archs.
>>
>> It is certainly a big change for introduce the i2c-core framework. :)
>>
>> Also my incoming mmc/sd enabling patch for pantheon and armada100
>> is also based on this i2c enabling patch, as I need the i2c to turn on the
>> repsonding pmic power connection.
>>
>> While we could get a i2c working pantheon, armada100, ?and other pxa
>> series platform now with this patch set. So what about Could we merge
>> this first, and
>> gradually change to the i2c framework, test and make it mature.
>
> I am fine with that, but please address the other comments from
> Prafulla and Wolfgang (rename defines, use standard accessors).

Ok, I would post another round of patch to fix those issue Prafulla and Wolfgang
metioned.

>
> If you plan to investigate time for the multibus/multiadapter
> i2c branch, let me know, maybe I can rebase this branch before
> you use it.

Currently, I have no bandwidth to do this... :(
Maybe I would try to investigate when I have time.

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  8:56                     ` Lei Wen
@ 2011-03-23  9:07                       ` Heiko Schocher
  2011-03-23  9:16                         ` Prafulla Wadaskar
  0 siblings, 1 reply; 123+ messages in thread
From: Heiko Schocher @ 2011-03-23  9:07 UTC (permalink / raw)
  To: u-boot

Hello Lei,

Lei Wen wrote:
> Hi Heiko,
> 
> On Wed, Mar 23, 2011 at 4:53 PM, Heiko Schocher <hs@denx.de> wrote:
>> Hello Lei,
>>
>> Lei Wen wrote:
>>> Hi Heiko,
>>>
>>> On Wed, Mar 23, 2011 at 4:22 PM, Heiko Schocher <hs@denx.de> wrote:
>>>> Hello Prafulla,
>>>>
>>>> Prafulla Wadaskar wrote:
>>>>>> -----Original Message-----
>>>>>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>>>>>> Sent: Tuesday, March 22, 2011 6:14 PM
>>>>>> To: Prafulla Wadaskar
>>>>>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>>>>>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>>>>>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
>>>>>>
[...]
>>> Also my incoming mmc/sd enabling patch for pantheon and armada100
>>> is also based on this i2c enabling patch, as I need the i2c to turn on the
>>> repsonding pmic power connection.
>>>
>>> While we could get a i2c working pantheon, armada100,  and other pxa
>>> series platform now with this patch set. So what about Could we merge
>>> this first, and
>>> gradually change to the i2c framework, test and make it mature.
>> I am fine with that, but please address the other comments from
>> Prafulla and Wolfgang (rename defines, use standard accessors).
> 
> Ok, I would post another round of patch to fix those issue Prafulla and Wolfgang
> metioned.

Ok, thanks!

>> If you plan to investigate time for the multibus/multiadapter
>> i2c branch, let me know, maybe I can rebase this branch before
>> you use it.
> 
> Currently, I have no bandwidth to do this... :(
> Maybe I would try to investigate when I have time.

:-(

Thats also my state ... please give me a notice, if you find some time,
so we can sync us ...

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  8:53                   ` Heiko Schocher
  2011-03-23  8:56                     ` Lei Wen
@ 2011-03-23  9:12                     ` Prafulla Wadaskar
  1 sibling, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-23  9:12 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Heiko Schocher [mailto:hs at denx.de]
> Sent: Wednesday, March 23, 2011 2:23 PM
> To: Lei Wen
> Cc: Prafulla Wadaskar; Lei Wen; Wolfgang Denk; u-boot at lists.denx.de;
> Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
> 
> Hello Lei,
> 
> Lei Wen wrote:
> > Hi Heiko,
> >
> > On Wed, Mar 23, 2011 at 4:22 PM, Heiko Schocher <hs@denx.de> wrote:
> >> Hello Prafulla,
> >>
> >> Prafulla Wadaskar wrote:
> >>>> -----Original Message-----
> >>>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
> >>>> Sent: Tuesday, March 22, 2011 6:14 PM
> >>>> To: Prafulla Wadaskar
> >>>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de;
> Marek
> >>>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> >>>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common
> place
> >>>>
> >>> ...snip...
> >>>>>>  drivers/i2c/Makefile      |    1 +
> >>>>>>  drivers/i2c/mv_i2c.c      |  452
> >>>>>> +++++++++++++++++++++++++++++++++++++++++++
> >>>>>>  include/configs/innokom.h |    1 +
> >>>>>>  include/configs/xm250.h   |    1 +
> >>>>>>  6 files changed, 455 insertions(+), 470 deletions(-)
> >>>>>>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
> >>>>>>  create mode 100644 drivers/i2c/mv_i2c.c
> >>>>> ...snip...
> >>>>>
> >>>>>> -#endif       /* CONFIG_HARD_I2C */
> >>>>>> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> >>>>>> index 052fe36..00a12cc 100644
> >>>>>> --- a/drivers/i2c/Makefile
> >>>>>> +++ b/drivers/i2c/Makefile
> >>>>>> @@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
> >>>>>>  COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
> >>>>>>  COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
> >>>>>>  COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
> >>>>>> +COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
> >>>>> Mvtwsi and mv_i2c are two i2c drivers for Marvell.
> >>>>> Can you merge these two?
> >>>> As I explain to you before. Although kirkwood and pxa series are
> both
> >>>> the product
> >>>> of Marvell, but it don't necessary means that they must have the
> same
> >>>> controller
> >>>> for both product line. For the i2c part, they just use two
> different
> >>>> controller.
> >>>> So why you keep request merge those two? Do you mean you want to
> >>>> create a unique I2C
> >>>> framework for whole i2c drivers in drivers/i2c?
> >>> Hi Lei
> >>>
> >>> 1. Most of i2c drivers supported in u-boot are either in SoC
> specific folder or in drivers/i2c folder, there is no as such thumb rule
> here.
> >> New drivers should go to drivers/i2c !
> >> The existing (old) drivers are just not moved ...
> >> patches welcome!
> >>
> >>> 2. Secondly all these drivers have some common code, mostly
> i2c_read, i2c_write, i2c_probe, etc..
> >>> 3. Specific to Marvell, we already have mvtwsi.c that supports
> Kirkwood and Orion5X SoCs. Whereas you are adding new mvi2c.c that will
> support armada100, pantheon apart from pxa.
> >>> 4. What about if we need to support some new Marvell SoC with
> different i2C controller? Do we add one more driver?
> >>>
> >>> I would love if some one creates drivers/i2c/i2c_core.c??? not
> necessarily you ;-)
> >>>
> >>> Here is what I would like to suggest.
> >>> 1. cmd_i2c mostly interfaced with i2c_probe, i2c_read, i2c_write,
> i2c_get_bun_num, i2c_set_bus_num, those should go in drivers/i2c_core.c
> >> Yep, but see below comment.
> >>
> >>> 2. APIs like i2c_start, i2c_stop, i2c_send, i2c_recv, i2c_reset are
> more I2C controller specific and those will be different implementation
> on different SoCs, those can go in SoC specific i2c driver file.
> >> Yep.
> >>
> >>> 3. all I2C driver files should be in drivers/i2c/
> >> Yep.
> >>
> >>> 4. i2c_read/write API need to be redefined since those are not
> generic to be used to access any I2C peripheral( most of the device
> don't need address to be programmed)
> >> With which devices do you have problems? You can set with
> >> "i2c mw chip address.0 ..." an addresslen = 0 ... or?
> >>
> >>> 5. Flags must be provided for i2c_read/write APIs to have precise
> control to execute I2C_START/I2C_STOP sequence in the call.
> >> If needed, yes.
> >>
> >>> Since you are the one starting with re-using pxa driver for
> armada100 and Pantheon SoC, why don't you split it into i2c_core.c and
> i2c_pxa.c? then add i2c_armada100.c and i2c_pantheon.c?
> >>> Others can migrate in the similar way. (even mvtwsi,c)
> >>>
> >>> Hi Heiko
> >>> What do you think on this?
> >> I made such a i2c_core.c file in the multibus/multiadapter branch
> >> for the i2c subsystem, see here:
> >>
> >> http://git.denx.de/?p=u-boot/u-boot-
> i2c.git;a=shortlog;h=refs/heads/multibus_v2
> >>
> >> (also you can grep in u-boot ML for discussions about)
> >>
> >> Actual state:
> >> - arm boards: i2c driver tested on suen3 (kirkwood based board)
> >> - powerpc boards: i2c driver tested on mpc82xx, 83xx, 8xx boards
> >> - all others just coded not tested ...
> >>  (A result of lacking hw and/or time)
> >>
> >> ToDo:
> >> - rebase against current head
> >>  (Sorry, didn;t found time to rebase it since Oktober 2010)
> >> - Update README
> >> - porting arrived new i2c drivers, boards since Oktober 2010
> >>  to this new i2c approach
> >> - testing, testing, testing ... Testers welcome!
> >>
> >> I prefer to integrate this to mainline, before we do above steps
> >> (4?) and 5. As Lei mentioned, if a soc/board has different i2c
> >> controllers and more than one bus we *need* this approach,
> >> so it is not worthwhile to introduce a i2c_core file only ...
> >> instead we should forwarding this branch to mainline?
> >>
> >> Patches are welcome ;-)
> >>
> >> I am afraid, this would get such a big cut as the arm relocation
> >> changes ... and it affects all archs.
> >
> > It is certainly a big change for introduce the i2c-core framework. :)
> >
> > Also my incoming mmc/sd enabling patch for pantheon and armada100
> > is also based on this i2c enabling patch, as I need the i2c to turn on
> the
> > repsonding pmic power connection.
> >
> > While we could get a i2c working pantheon, armada100,  and other pxa
> > series platform now with this patch set. So what about Could we merge
> > this first, and
> > gradually change to the i2c framework, test and make it mature.
> 
> I am fine with that, but please address the other comments from
> Prafulla and Wolfgang (rename defines, use standard accessors).

Hi Lei
I can understand your dependency.
Even I am fine with that, my intention was if we can make it better why not :-)

> 
> If you plan to investigate time for the multibus/multiadapter
> i2c branch, let me know, maybe I can rebase this branch before
> you use it.

This is a good approach indeed.
If you (Lei) agree, I will pull the multibus/multiadapter patches on u-boot-marvell.git which will be a good starting reference for your work.
If not, you may continue as you requested.

BTW: in his patch, he has renamed and moved boards/Marvell/common/i2c.c to mv_i2c.c.
I will be happy to see and test if the patch series by Heiko gets mainlined.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place
  2011-03-23  9:07                       ` Heiko Schocher
@ 2011-03-23  9:16                         ` Prafulla Wadaskar
  0 siblings, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-23  9:16 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Heiko Schocher [mailto:hs at denx.de]
> Sent: Wednesday, March 23, 2011 2:37 PM
> To: Lei Wen
> Cc: Prafulla Wadaskar; Lei Wen; Wolfgang Denk; u-boot at lists.denx.de;
> Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common place
> 
> Hello Lei,
> 
> Lei Wen wrote:
> > Hi Heiko,
> >
> > On Wed, Mar 23, 2011 at 4:53 PM, Heiko Schocher <hs@denx.de> wrote:
> >> Hello Lei,
> >>
> >> Lei Wen wrote:
> >>> Hi Heiko,
> >>>
> >>> On Wed, Mar 23, 2011 at 4:22 PM, Heiko Schocher <hs@denx.de> wrote:
> >>>> Hello Prafulla,
> >>>>
> >>>> Prafulla Wadaskar wrote:
> >>>>>> -----Original Message-----
> >>>>>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
> >>>>>> Sent: Tuesday, March 22, 2011 6:14 PM
> >>>>>> To: Prafulla Wadaskar
> >>>>>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de;
> Marek
> >>>>>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> >>>>>> Subject: Re: [PATCH V3 1/5] pxa: move i2c driver to the common
> place
> >>>>>>
> [...]
> >>> Also my incoming mmc/sd enabling patch for pantheon and armada100
> >>> is also based on this i2c enabling patch, as I need the i2c to turn
> on the
> >>> repsonding pmic power connection.
> >>>
> >>> While we could get a i2c working pantheon, armada100,  and other pxa
> >>> series platform now with this patch set. So what about Could we
> merge
> >>> this first, and
> >>> gradually change to the i2c framework, test and make it mature.
> >> I am fine with that, but please address the other comments from
> >> Prafulla and Wolfgang (rename defines, use standard accessors).
> >
> > Ok, I would post another round of patch to fix those issue Prafulla
> and Wolfgang
> > metioned.
> 
> Ok, thanks!
> 
> >> If you plan to investigate time for the multibus/multiadapter
> >> i2c branch, let me know, maybe I can rebase this branch before
> >> you use it.
> >
> > Currently, I have no bandwidth to do this... :(
> > Maybe I would try to investigate when I have time.
> 
> :-(
> 
> Thats also my state ... please give me a notice, if you find some time,
> so we can sync us ...

Sorry I posted earlier email before checking this email.
Even same the my state too :-)
Well Let's lei get his stuff, we will think of migration latter :-(

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 0/6] add i2c support to pantheon and aramada100
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
                             ` (6 more replies)
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
                           ` (5 subsequent siblings)
  6 siblings, 7 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

V3:
Clean the code sytle issue

V4:
add and* and or* to make set bit operation generic
Also make i2c definition included in the ifdef
 
Lei Wen (6):
  io: add and* and or* operation api to set and clear bit
  pxa: move i2c driver to the common place
  mv_i2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mv_i2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c     |   12 +
 arch/arm/cpu/pxa/Makefile                 |    1 -
 arch/arm/cpu/pxa/cpu.c                    |   11 +
 arch/arm/cpu/pxa/i2c.c                    |  469 ----------------------------
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++-
 arch/arm/include/asm/arch-pantheon/cpu.h  |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h  |    6 +-
 arch/arm/include/asm/arch-pxa/pxa-regs.h  |   56 ----
 arch/arm/include/asm/io.h                 |    8 +
 board/Marvell/aspenite/aspenite.c         |    5 +
 board/Marvell/dkb/dkb.c                   |    4 +
 board/innokom/innokom.c                   |    9 +-
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/mv_i2c.c                      |  479 +++++++++++++++++++++++++++++
 drivers/i2c/mv_i2c.h                      |   83 +++++
 include/configs/aspenite.h                |   14 +
 include/configs/dkb.h                     |   13 +
 include/configs/innokom.h                 |    2 +
 include/configs/xm250.h                   |    2 +
 20 files changed, 680 insertions(+), 555 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c
 create mode 100644 drivers/i2c/mv_i2c.h

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  2011-03-28  5:57           ` Wolfgang Denk
  2011-03-28 16:05           ` Scott Wood
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 2/6] pxa: move i2c driver to the common place Lei Wen
                           ` (4 subsequent siblings)
  6 siblings, 2 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

Those api take use of read*/write* to align the current dmb usage.
Also this could short the code length in one line.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
 arch/arm/include/asm/io.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1fbc531..71e85e8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
 #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
 #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
 
+#define orb(v,c)       writeb(readb(c) | v, c)
+#define orw(v,c)       writew(readw(c) | v, c)
+#define orl(v,c)       writel(readl(c) | v, c)
+
+#define andb(v,c)      writeb(readb(c) & v, c)
+#define andw(v,c)      writew(readw(c) & v, c)
+#define andl(v,c)      writel(readl(c) & v, c)
+
 /*
  * The compiler seems to be incapable of optimising constants
  * properly.  Spell it out to the compiler in some cases.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 2/6] pxa: move i2c driver to the common place
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
                           ` (3 subsequent siblings)
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 455 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
new file mode 100644
index 0000000..09756a4
--- /dev/null
+++ b/drivers/i2c/mv_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+/*
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void)
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
+{
+	int timeout = 10000;
+
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch (msg->direction) {
+	case I2C_WRITE:
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+	default:
+		goto transfer_error_illegal_param;
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
+		i2c_reset();
+		return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+/*
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+		if (len == 0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if (i2c_transfer(&msg))
+			return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+		buffer++;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+/*
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+
+		if (len == 0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 3/6] mv_i2c: use structure to replace the direclty define
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
                           ` (2 preceding siblings ...)
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 2/6] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 4/6] I2C: add i2c support for Pantheon platform Lei Wen
                           ` (2 subsequent siblings)
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

Add i2c_clk_enable in the cpu specific code, since previous platform it,
while new platform don't need. In the pantheon and armada100 platform,
this function is defined as NULL one.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code sytle issue

 arch/arm/cpu/pxa/cpu.c                   |   11 +++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mv_i2c.c                     |  131 ++++++++++++++----------------
 drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 7 files changed, 159 insertions(+), 133 deletions(-)
 create mode 100644 drivers/i2c/mv_i2c.h

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..24b59e7 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,14 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 09756a4..734148b 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -34,24 +37,8 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
-			| ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
+#include "mv_i2c.h"
 
 #ifdef DEBUG_I2C
 #define PRINTD(x) printf x
@@ -59,20 +46,6 @@
 #define PRINTD(x)
 #endif
 
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
 /* All transfers are described by this data structure */
 struct i2c_msg {
 	u8 condition;
@@ -81,27 +54,37 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct pxa_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+
 /*
  * i2c_pxa_reset: - reset the host controller
  *
  */
 static void i2c_reset(void)
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	andl(~ICR_IUE, &base->icr);	/* disable unit */
+	orl(ICR_UR, &base->icr);	/* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	andl(~ICR_IUE, &base->icr);	/* disable unit */
+
+	i2c_clk_enable();
+
+	writel(CONFIG_SYS_I2C_SLAVE, &base->isar);/* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
+	orl(ICR_IUE, &base->icr);		/* enable unit */
 	udelay(100);
 }
 
@@ -114,13 +97,15 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 10000;
+	int timeout = 10000, isr;
 
-	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+	do {
+		isr = readl(&base->isr);
 		udelay(10);
 		if (timeout-- < 0)
 			return 0;
-	}
+	} while (((isr & set_mask) != set_mask)
+		|| ((isr & cleared_mask) != 0));
 
 	return 1;
 }
@@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		andl(~ICR_START, &base->icr);
+		andl(~ICR_STOP, &base->icr);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			orl(ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			orl(ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			orl(ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			andl(~ICR_ACKNAK, &base->icr);
+		andl(~ICR_ALDIE, &base->icr);
+		orl(ICR_TB, &base->icr);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		orl(ISR_ITE, &base->isr);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		andl(~ICR_START, &base->icr);
+		andl(~ICR_STOP, &base->icr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			orl(ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			orl(ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			orl(ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			andl(~ICR_ACKNAK, &base->icr);
+		andl(~ICR_ALDIE, &base->icr);
+		orl(ICR_TB, &base->icr);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
+		orl(ISR_IRF, &base->isr);
 		break;
 	default:
 		goto transfer_error_illegal_param;
@@ -252,10 +236,19 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
 	/* environment, which might be in a chip on that bus. For details   */
 	/* about this problem see doc/I2C_Edge_Conditions.                  */
+
+	/* disable I2C controller first, otherwhise it thinks we want to    */
+	/* talk to the slave port...                                        */
+	icr = readl(&base->icr);
+	andl(~(ICR_SCLE | ICR_IUE), &base->icr);
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
new file mode 100644
index 0000000..41af0d9
--- /dev/null
+++ b/drivers/i2c/mv_i2c.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Inc, <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MV_I2C_H_
+#define _MV_I2C_H_
+extern void i2c_clk_enable(void);
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+		| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
+
+#endif
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..1ddee03 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..682d1ed 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 4/6] I2C: add i2c support for Pantheon platform
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
                           ` (3 preceding siblings ...)
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 5/6] I2C: mv_i2c: add multi bus support Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 6/6] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition included in the ifdef

 arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
 board/Marvell/dkb/dkb.c                  |    4 ++++
 include/configs/dkb.h                    |   13 +++++++++++++
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..8b2eafa 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,12 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+#endif
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +82,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..e939196 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -32,8 +32,10 @@
  * offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..599c8b8 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -56,6 +56,19 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
+/*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+#endif
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 5/6] I2C: mv_i2c: add multi bus support
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
                           ` (4 preceding siblings ...)
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 4/6] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 6/6] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

Add the ability to support multiple i2c bus for mv_i2c

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code style issue

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 734148b..7a808c9 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -66,7 +66,35 @@ struct pxa_i2c {
 	u32 isar;
 };
 
-static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+static struct pxa_i2c *base;
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
+static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
+static unsigned int current_bus;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct pxa_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /*
  * i2c_pxa_reset: - reset the host controller
@@ -235,6 +263,12 @@ i2c_transfer_finish:
 /* ------------------------------------------------------------------------ */
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct pxa_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 6/6] I2C: add i2c support for Armada100 platform
  2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
                           ` (5 preceding siblings ...)
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 5/6] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-03-28  5:48         ` Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  5:48 UTC (permalink / raw)
  To: u-boot

Add i2c support to aspenite board with Armada100 soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition include in the ifdef

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++-------------
 board/Marvell/aspenite/aspenite.c         |    5 +++
 include/configs/aspenite.h                |   14 ++++++++++
 4 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..c21938e 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,16 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +100,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..73783a7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -37,28 +37,32 @@
  * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART1 */
-#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART3 */
-#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+
+/* I2c */
+#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..acaf8b2 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -63,6 +63,20 @@
 #undef CONFIG_ARCH_MISC_INIT
 
 /*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C		1
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV		1
+#define CONFIG_PXA_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+#endif
+
+/*
  * Environment variables configurations
  */
 #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
@ 2011-03-28  5:57           ` Wolfgang Denk
  2011-03-28  6:01             ` Lei Wen
  2011-03-28  6:03             ` Lei Wen
  2011-03-28 16:05           ` Scott Wood
  1 sibling, 2 replies; 123+ messages in thread
From: Wolfgang Denk @ 2011-03-28  5:57 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <1301291335-13734-2-git-send-email-leiwen@marvell.com> you wrote:
> Those api take use of read*/write* to align the current dmb usage.
> Also this could short the code length in one line.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  arch/arm/include/asm/io.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
> index 1fbc531..71e85e8 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
>  #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
>  #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
>  
> +#define orb(v,c)       writeb(readb(c) | v, c)
> +#define orw(v,c)       writew(readw(c) | v, c)
> +#define orl(v,c)       writel(readl(c) | v, c)
> +
> +#define andb(v,c)      writeb(readb(c) & v, c)
> +#define andw(v,c)      writew(readw(c) & v, c)
> +#define andl(v,c)      writel(readl(c) & v, c)

checkpatch gixes errors for all of these lines:

ERROR: space required after that ',' (ctx:VxV)
#72: FILE: arch/arm/include/asm/io.h:144:
+#define orb(v,c)       writeb(readb(c) | v, c)
              ^

etc.

Please fix.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Once they go up, who cares where  they  come  down?  That's  not  my
department."                                       - Werner von Braun

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  5:57           ` Wolfgang Denk
@ 2011-03-28  6:01             ` Lei Wen
  2011-03-28  6:03             ` Lei Wen
  1 sibling, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:01 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

On Mon, Mar 28, 2011 at 1:57 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Lei Wen,
>
> In message <1301291335-13734-2-git-send-email-leiwen@marvell.com> you wrote:
>> Those api take use of read*/write* to align the current dmb usage.
>> Also this could short the code length in one line.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> ?arch/arm/include/asm/io.h | ? ?8 ++++++++
>> ?1 files changed, 8 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
>> index 1fbc531..71e85e8 100644
>> --- a/arch/arm/include/asm/io.h
>> +++ b/arch/arm/include/asm/io.h
>> @@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
>> ?#define readw(c) ? ? ({ u16 __v = __arch_getw(c); __iormb(); __v; })
>> ?#define readl(c) ? ? ({ u32 __v = __arch_getl(c); __iormb(); __v; })
>>
>> +#define orb(v,c) ? ? ? writeb(readb(c) | v, c)
>> +#define orw(v,c) ? ? ? writew(readw(c) | v, c)
>> +#define orl(v,c) ? ? ? writel(readl(c) | v, c)
>> +
>> +#define andb(v,c) ? ? ?writeb(readb(c) & v, c)
>> +#define andw(v,c) ? ? ?writew(readw(c) & v, c)
>> +#define andl(v,c) ? ? ?writel(readl(c) & v, c)
>
> checkpatch gixes errors for all of these lines:
>
> ERROR: space required after that ',' (ctx:VxV)
> #72: FILE: arch/arm/include/asm/io.h:144:
> +#define orb(v,c) ? ? ? writeb(readb(c) | v, c)
> ? ? ? ? ? ? ?^
>
> etc.
>
> Please fix.

Sorry for this... patch to come...

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  5:57           ` Wolfgang Denk
  2011-03-28  6:01             ` Lei Wen
@ 2011-03-28  6:03             ` Lei Wen
  2011-03-28  6:29               ` Wolfgang Denk
  1 sibling, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:03 UTC (permalink / raw)
  To: u-boot

Those api take use of read*/write* to align the current dmb usage.
Also this could short the code length in one line.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V4.1
fix code style issue

 arch/arm/include/asm/io.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1fbc531..71e85e8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
 #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
 #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
 
+#define orb(v, c)       writeb(readb(c) | v, c)
+#define orw(v, c)       writew(readw(c) | v, c)
+#define orl(v, c)       writel(readl(c) | v, c)
+
+#define andb(v, c)      writeb(readb(c) & v, c)
+#define andw(v, c)      writew(readw(c) & v, c)
+#define andl(v, c)      writel(readl(c) & v, c)
+
 /*
  * The compiler seems to be incapable of optimising constants
  * properly.  Spell it out to the compiler in some cases.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  6:03             ` Lei Wen
@ 2011-03-28  6:29               ` Wolfgang Denk
  2011-03-28  7:04                 ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Wolfgang Denk @ 2011-03-28  6:29 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <1301292225-15069-1-git-send-email-leiwen@marvell.com> you wrote:
> Those api take use of read*/write* to align the current dmb usage.
> Also this could short the code length in one line.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V4.1
> fix code style issue

That should be V4.1 (or better V5) in the Subject then, too.


Please also note that all your patches are missing a correct
changelog.

1/6 has no changelog at all.
2/6 fails to document the v4 changes
3/6 shows only V3 changes
4/6 ditto
5/6 ditto
6/6 ditto 

This is not acceptable.  I do not intend to read and compare ll the
previous versions, so I refuse to review this.

You may consider this a NAK to the whole patch series.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Though a program be but three lines long,
someday it will have to be maintained."
- The Tao of Programming

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 0/6] add i2c support to pantheon and aramada100
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
                               ` (5 more replies)
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
                             ` (5 subsequent siblings)
  6 siblings, 6 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

V3:
Clean the code sytle issue

V4:
add and* and or* to make set bit operation generic
Also make i2c definition included in the ifdef

V5:
Fix code style issue of the first patch
 
Lei Wen (6):
  io: add and* and or* operation api to set and clear bit
  pxa: move i2c driver to the common place
  mv_i2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mv_i2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c     |   12 +
 arch/arm/cpu/pxa/Makefile                 |    1 -
 arch/arm/cpu/pxa/cpu.c                    |   11 +
 arch/arm/cpu/pxa/i2c.c                    |  469 ----------------------------
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++-
 arch/arm/include/asm/arch-pantheon/cpu.h  |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h  |    6 +-
 arch/arm/include/asm/arch-pxa/pxa-regs.h  |   56 ----
 arch/arm/include/asm/io.h                 |    8 +
 board/Marvell/aspenite/aspenite.c         |    5 +
 board/Marvell/dkb/dkb.c                   |    4 +
 board/innokom/innokom.c                   |    9 +-
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/mv_i2c.c                      |  479 +++++++++++++++++++++++++++++
 drivers/i2c/mv_i2c.h                      |   83 +++++
 include/configs/aspenite.h                |   14 +
 include/configs/dkb.h                     |   13 +
 include/configs/innokom.h                 |    2 +
 include/configs/xm250.h                   |    2 +
 20 files changed, 680 insertions(+), 555 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c
 create mode 100644 drivers/i2c/mv_i2c.h

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 2/6] pxa: move i2c driver to the common place Lei Wen
                             ` (4 subsequent siblings)
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

Those api take use of read*/write* to align the current dmb usage.
Also this could short the code length in one line.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
V3:
V4:
Move original driver specific bit set to the general place

V5:
fix code style issue

 arch/arm/include/asm/io.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1fbc531..71e85e8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
 #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
 #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
 
+#define orb(v, c)       writeb(readb(c) | v, c)
+#define orw(v, c)       writew(readw(c) | v, c)
+#define orl(v, c)       writel(readl(c) | v, c)
+
+#define andb(v, c)      writeb(readb(c) & v, c)
+#define andw(v, c)      writew(readw(c) & v, c)
+#define andl(v, c)      writel(readl(c) & v, c)
+
 /*
  * The compiler seems to be incapable of optimising constants
  * properly.  Spell it out to the compiler in some cases.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 2/6] pxa: move i2c driver to the common place
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
                             ` (3 subsequent siblings)
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

V4:
V5:
NO CHANGE

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 455 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
new file mode 100644
index 0000000..09756a4
--- /dev/null
+++ b/drivers/i2c/mv_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+/*
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void)
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
+{
+	int timeout = 10000;
+
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch (msg->direction) {
+	case I2C_WRITE:
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+	default:
+		goto transfer_error_illegal_param;
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
+		i2c_reset();
+		return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+/*
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+		if (len == 0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if (i2c_transfer(&msg))
+			return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+		buffer++;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+/*
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+
+		if (len == 0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
                             ` (2 preceding siblings ...)
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 2/6] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-29 13:27             ` Prafulla Wadaskar
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform Lei Wen
                             ` (2 subsequent siblings)
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

Add i2c_clk_enable in the cpu specific code, since previous platform it,
while new platform don't need. In the pantheon and armada100 platform,
this function is defined as NULL one.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue

V4:
V5:
NO CHANGE

 arch/arm/cpu/pxa/cpu.c                   |   11 +++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mv_i2c.c                     |  131 ++++++++++++++----------------
 drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 7 files changed, 159 insertions(+), 133 deletions(-)
 create mode 100644 drivers/i2c/mv_i2c.h

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..24b59e7 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,14 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 09756a4..734148b 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -34,24 +37,8 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
-			| ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
+#include "mv_i2c.h"
 
 #ifdef DEBUG_I2C
 #define PRINTD(x) printf x
@@ -59,20 +46,6 @@
 #define PRINTD(x)
 #endif
 
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
 /* All transfers are described by this data structure */
 struct i2c_msg {
 	u8 condition;
@@ -81,27 +54,37 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct pxa_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+
 /*
  * i2c_pxa_reset: - reset the host controller
  *
  */
 static void i2c_reset(void)
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	andl(~ICR_IUE, &base->icr);	/* disable unit */
+	orl(ICR_UR, &base->icr);	/* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	andl(~ICR_IUE, &base->icr);	/* disable unit */
+
+	i2c_clk_enable();
+
+	writel(CONFIG_SYS_I2C_SLAVE, &base->isar);/* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
+	orl(ICR_IUE, &base->icr);		/* enable unit */
 	udelay(100);
 }
 
@@ -114,13 +97,15 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 10000;
+	int timeout = 10000, isr;
 
-	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+	do {
+		isr = readl(&base->isr);
 		udelay(10);
 		if (timeout-- < 0)
 			return 0;
-	}
+	} while (((isr & set_mask) != set_mask)
+		|| ((isr & cleared_mask) != 0));
 
 	return 1;
 }
@@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		andl(~ICR_START, &base->icr);
+		andl(~ICR_STOP, &base->icr);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			orl(ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			orl(ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			orl(ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			andl(~ICR_ACKNAK, &base->icr);
+		andl(~ICR_ALDIE, &base->icr);
+		orl(ICR_TB, &base->icr);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		orl(ISR_ITE, &base->isr);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		andl(~ICR_START, &base->icr);
+		andl(~ICR_STOP, &base->icr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			orl(ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			orl(ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			orl(ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			andl(~ICR_ACKNAK, &base->icr);
+		andl(~ICR_ALDIE, &base->icr);
+		orl(ICR_TB, &base->icr);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
+		orl(ISR_IRF, &base->isr);
 		break;
 	default:
 		goto transfer_error_illegal_param;
@@ -252,10 +236,19 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
 	/* environment, which might be in a chip on that bus. For details   */
 	/* about this problem see doc/I2C_Edge_Conditions.                  */
+
+	/* disable I2C controller first, otherwhise it thinks we want to    */
+	/* talk to the slave port...                                        */
+	icr = readl(&base->icr);
+	andl(~(ICR_SCLE | ICR_IUE), &base->icr);
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
new file mode 100644
index 0000000..41af0d9
--- /dev/null
+++ b/drivers/i2c/mv_i2c.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Inc, <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MV_I2C_H_
+#define _MV_I2C_H_
+extern void i2c_clk_enable(void);
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+		| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
+
+#endif
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..1ddee03 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..682d1ed 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
                             ` (3 preceding siblings ...)
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-29 13:07             ` Prafulla Wadaskar
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 5/6] I2C: mv_i2c: add multi bus support Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 6/6] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition included in the ifdef

V5:
NO CHANGE

 arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
 board/Marvell/dkb/dkb.c                  |    4 ++++
 include/configs/dkb.h                    |   13 +++++++++++++
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..8b2eafa 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,12 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+#endif
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +82,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..e939196 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -32,8 +32,10 @@
  * offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..599c8b8 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -56,6 +56,19 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
+/*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+#endif
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 5/6] I2C: mv_i2c: add multi bus support
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
                             ` (4 preceding siblings ...)
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 6/6] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

Add the ability to support multiple i2c bus for mv_i2c

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
NO CHANGE

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 734148b..7a808c9 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -66,7 +66,35 @@ struct pxa_i2c {
 	u32 isar;
 };
 
-static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+static struct pxa_i2c *base;
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
+static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
+static unsigned int current_bus;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct pxa_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /*
  * i2c_pxa_reset: - reset the host controller
@@ -235,6 +263,12 @@ i2c_transfer_finish:
 /* ------------------------------------------------------------------------ */
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct pxa_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 6/6] I2C: add i2c support for Armada100 platform
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
                             ` (5 preceding siblings ...)
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 5/6] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-03-28  6:53           ` Lei Wen
  2011-03-29 13:09             ` Prafulla Wadaskar
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-28  6:53 UTC (permalink / raw)
  To: u-boot

Add i2c support to aspenite board with Armada100 soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition include in the ifdef

V5:
NO CHANGE

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++-------------
 board/Marvell/aspenite/aspenite.c         |    5 +++
 include/configs/aspenite.h                |   14 ++++++++++
 4 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..c21938e 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,16 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +100,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..73783a7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -37,28 +37,32 @@
  * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART1 */
-#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART3 */
-#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+
+/* I2c */
+#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..acaf8b2 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -63,6 +63,20 @@
 #undef CONFIG_ARCH_MISC_INIT
 
 /*
+ * I2C definition
+ */
+#define CONFIG_CMD_I2C		1
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV		1
+#define CONFIG_PXA_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+#endif
+
+/*
  * Environment variables configurations
  */
 #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  6:29               ` Wolfgang Denk
@ 2011-03-28  7:04                 ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-28  7:04 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

On Mon, Mar 28, 2011 at 2:29 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Lei Wen,
>
> In message <1301292225-15069-1-git-send-email-leiwen@marvell.com> you wrote:
>> Those api take use of read*/write* to align the current dmb usage.
>> Also this could short the code length in one line.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V4.1
>> fix code style issue
>
> That should be V4.1 (or better V5) in the Subject then, too.
>
>
> Please also note that all your patches are missing a correct
> changelog.
>
> 1/6 has no changelog at all.
> 2/6 fails to document the v4 changes
> 3/6 shows only V3 changes
> 4/6 ditto
> 5/6 ditto
> 6/6 ditto
>

Thanks for this reminding. I've post V5 seris to add those changelog.

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28  5:48         ` [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
  2011-03-28  5:57           ` Wolfgang Denk
@ 2011-03-28 16:05           ` Scott Wood
  2011-03-29  2:47             ` Lei Wen
  2011-03-29  2:53             ` [U-Boot] [PATCH V5.1 " Lei Wen
  1 sibling, 2 replies; 123+ messages in thread
From: Scott Wood @ 2011-03-28 16:05 UTC (permalink / raw)
  To: u-boot

On Sun, 27 Mar 2011 22:48:50 -0700
Lei Wen <leiwen@marvell.com> wrote:

> Those api take use of read*/write* to align the current dmb usage.
> Also this could short the code length in one line.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
>  arch/arm/include/asm/io.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
> index 1fbc531..71e85e8 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
>  #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
>  #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
>  
> +#define orb(v,c)       writeb(readb(c) | v, c)
> +#define orw(v,c)       writew(readw(c) | v, c)
> +#define orl(v,c)       writel(readl(c) | v, c)
> +
> +#define andb(v,c)      writeb(readb(c) & v, c)
> +#define andw(v,c)      writew(readw(c) & v, c)
> +#define andl(v,c)      writel(readl(c) & v, c)
> +
>  /*
>   * The compiler seems to be incapable of optimising constants
>   * properly.  Spell it out to the compiler in some cases.

What does this do that setbits*/clrbits* don't?

Other than be missing parentheses around "v", causing problems if a
complex expression is passed in.

-scott

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28 16:05           ` Scott Wood
@ 2011-03-29  2:47             ` Lei Wen
  2011-03-29 16:03               ` Scott Wood
  2011-03-29  2:53             ` [U-Boot] [PATCH V5.1 " Lei Wen
  1 sibling, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-29  2:47 UTC (permalink / raw)
  To: u-boot

Hi Scott,

On Tue, Mar 29, 2011 at 12:05 AM, Scott Wood <scottwood@freescale.com> wrote:
> On Sun, 27 Mar 2011 22:48:50 -0700
> Lei Wen <leiwen@marvell.com> wrote:
>
>> Those api take use of read*/write* to align the current dmb usage.
>> Also this could short the code length in one line.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> ?arch/arm/include/asm/io.h | ? ?8 ++++++++
>> ?1 files changed, 8 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
>> index 1fbc531..71e85e8 100644
>> --- a/arch/arm/include/asm/io.h
>> +++ b/arch/arm/include/asm/io.h
>> @@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
>> ?#define readw(c) ? ? ({ u16 __v = __arch_getw(c); __iormb(); __v; })
>> ?#define readl(c) ? ? ({ u32 __v = __arch_getl(c); __iormb(); __v; })
>>
>> +#define orb(v,c) ? ? ? writeb(readb(c) | v, c)
>> +#define orw(v,c) ? ? ? writew(readw(c) | v, c)
>> +#define orl(v,c) ? ? ? writel(readl(c) | v, c)
>> +
>> +#define andb(v,c) ? ? ?writeb(readb(c) & v, c)
>> +#define andw(v,c) ? ? ?writew(readw(c) & v, c)
>> +#define andl(v,c) ? ? ?writel(readl(c) & v, c)
>> +
>> ?/*
>> ? * The compiler seems to be incapable of optimising constants
>> ? * properly. ?Spell it out to the compiler in some cases.
>
> What does this do that setbits*/clrbits* don't?

Those and*/or* include the dmb() operation included in the read*/write*, which
is not included in the __raw_read*/__raw_write* that setbits*/clrbits* refer to.
I think it's better to keep another instance to set the bit, since
there is read* and __raw_read*
exist and have difference.

>
> Other than be missing parentheses aro und "v", causing problems if a
> complex expression is passed in.

Yep, that make sense. Thanks for pionting it out, I would make a
update for this patch.

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5.1 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-28 16:05           ` Scott Wood
  2011-03-29  2:47             ` Lei Wen
@ 2011-03-29  2:53             ` Lei Wen
  2011-03-29  5:40               ` Prafulla Wadaskar
  1 sibling, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-29  2:53 UTC (permalink / raw)
  To: u-boot

Those api take use of read*/write* to align the current dmb usage.
Also this could short the code length in one line.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
V3:
V4:
Move original driver specific bit set to the general place

V5:
fix code style issue

V5.1:
Add parentheses for the around incoming parameters to prevent
parsing the complex expression wrong.

 arch/arm/include/asm/io.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1fbc531..71e85e8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr, void *data, int longlen)
 #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
 #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
 
+#define orb(v, c)       writeb(readb(c) | (v), c)
+#define orw(v, c)       writew(readw(c) | (v), c)
+#define orl(v, c)       writel(readl(c) | (v), c)
+
+#define andb(v, c)      writeb(readb(c) & (v), c)
+#define andw(v, c)      writew(readw(c) & (v), c)
+#define andl(v, c)      writel(readl(c) & (v), c)
+
 /*
  * The compiler seems to be incapable of optimising constants
  * properly.  Spell it out to the compiler in some cases.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5.1 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-29  2:53             ` [U-Boot] [PATCH V5.1 " Lei Wen
@ 2011-03-29  5:40               ` Prafulla Wadaskar
  2011-03-29  5:44                 ` Mike Frysinger
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-29  5:40 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Tuesday, March 29, 2011 8:24 AM
> To: Scott Wood; Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V5.1 1/6] io: add and* and or* operation api to set and
> clear bit
> 
> Those api take use of read*/write* to align the current dmb usage.
> Also this could short the code length in one line.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> V3:
> V4:
> Move original driver specific bit set to the general place
> 
> V5:
> fix code style issue
> 
> V5.1:
> Add parentheses for the around incoming parameters to prevent
> parsing the complex expression wrong.
> 
>  arch/arm/include/asm/io.h |    8 ++++++++
>  1 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
> index 1fbc531..71e85e8 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -141,6 +141,14 @@ extern inline void __raw_readsl(unsigned int addr,
> void *data, int longlen)
>  #define readw(c)	({ u16 __v = __arch_getw(c); __iormb(); __v; })
>  #define readl(c)	({ u32 __v = __arch_getl(c); __iormb(); __v; })
> 
> +#define orb(v, c)       writeb(readb(c) | (v), c)

If I am not wrong, this should be like
#define orb(v, c)       writeb((readb(c) | v), c)

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5.1 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-29  5:40               ` Prafulla Wadaskar
@ 2011-03-29  5:44                 ` Mike Frysinger
  0 siblings, 0 replies; 123+ messages in thread
From: Mike Frysinger @ 2011-03-29  5:44 UTC (permalink / raw)
  To: u-boot

On Tue, Mar 29, 2011 at 1:40 AM, Prafulla Wadaskar wrote:
> From: Lei Wen [mailto:leiwen at marvell.com]
>> +#define orb(v, c) ? ? ? writeb(readb(c) | (v), c)
>
> If I am not wrong, this should be like
> #define orb(v, c) ? ? ? writeb((readb(c) | v), c)

no, Lei's version is correct.  yours mishandles v, and adds useless
paren to the first arg to writeb.  writeb itself should be wrapping
its first arg in paren if need be.
-mike

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-29 13:07             ` Prafulla Wadaskar
  2011-03-30 14:05               ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-29 13:07 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Monday, March 28, 2011 12:24 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
> 
> Add i2c support to dkb board with pantheon soc.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code sytle issue
> Add i2c clock enable code include in I2C configure define block
> 
> V4:
> make i2c definition included in the ifdef
> 
> V5:
> NO CHANGE
> 
>  arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
>  arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
>  arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
>  board/Marvell/dkb/dkb.c                  |    4 ++++
>  include/configs/dkb.h                    |   13 +++++++++++++
>  5 files changed, 36 insertions(+), 3 deletions(-)
> 
...snip...

> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
> index 638af5e..599c8b8 100644
> --- a/include/configs/dkb.h
> +++ b/include/configs/dkb.h
> @@ -56,6 +56,19 @@
>  #include "mv-common.h"
> 
>  #undef CONFIG_ARCH_MISC_INIT
> +
> +/*
> + * I2C definition
> + */
> +#define CONFIG_CMD_I2C

This command definition should be moved up (below #include <config_cmd_default.h>

Otherwise ack for rest of the code

Regards..
Prafulla . .

> +#ifdef CONFIG_CMD_I2C
> +#define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0xd4011000
> +#define CONFIG_HARD_I2C			1
> +#define CONFIG_SYS_I2C_SPEED		0
> +#define CONFIG_SYS_I2C_SLAVE		0xfe
> +#endif
> +
>  /*
>   * Environment variables configurations
>   */
> --
> 1.7.0.4

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 6/6] I2C: add i2c support for Armada100 platform
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 6/6] I2C: add i2c support for Armada100 platform Lei Wen
@ 2011-03-29 13:09             ` Prafulla Wadaskar
  0 siblings, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-29 13:09 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Monday, March 28, 2011 12:24 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V5 6/6] I2C: add i2c support for Armada100 platform
> 
> Add i2c support to aspenite board with Armada100 soc.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code sytle issue
> Add i2c clock enable code include in I2C configure define block
> 
> V4:
> make i2c definition include in the ifdef
> 
> V5:
> NO CHANGE
> 
>  arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
>  arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++------
> -------
>  board/Marvell/aspenite/aspenite.c         |    5 +++
>  include/configs/aspenite.h                |   14 ++++++++++
>  4 files changed, 57 insertions(+), 18 deletions(-)
...snip...
>  /*
> + * I2C definition
> + */
> +#define CONFIG_CMD_I2C		1

Same here, move up with other command configs.

> +#ifdef CONFIG_CMD_I2C
> +#define CONFIG_I2C_MV		1
> +#define CONFIG_PXA_I2C_NUM	2
> +#define CONFIG_I2C_MULTI_BUS	1
> +#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
> +#define CONFIG_HARD_I2C		1
> +#define CONFIG_SYS_I2C_SPEED	0
> +#define CONFIG_SYS_I2C_SLAVE	0xfe
> +#endif
> +
> +/*
>   * Environment variables configurations
>   */
>  #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-29 13:27             ` Prafulla Wadaskar
  2011-03-30 14:11               ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-29 13:27 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Monday, March 28, 2011 12:24 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V5 3/6] mv_i2c: use structure to replace the direclty
> define
> 
> Add i2c_clk_enable in the cpu specific code, since previous platform it,
> while new platform don't need. In the pantheon and armada100 platform,
> this function is defined as NULL one.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code sytle issue
> 
> V4:
> V5:
> NO CHANGE
> 
>  arch/arm/cpu/pxa/cpu.c                   |   11 +++
>  arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
>  board/innokom/innokom.c                  |    9 +--
>  drivers/i2c/mv_i2c.c                     |  131 ++++++++++++++---------
> -------
>  drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
>  include/configs/innokom.h                |    1 +
>  include/configs/xm250.h                  |    1 +
>  7 files changed, 159 insertions(+), 133 deletions(-)
>  create mode 100644 drivers/i2c/mv_i2c.h
> 
...snip...
> diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
> index 09756a4..734148b 100644
> --- a/drivers/i2c/mv_i2c.c
> +++ b/drivers/i2c/mv_i2c.c
> @@ -8,6 +8,9 @@
>   * (C) Copyright 2003 Pengutronix e.K.
>   * Robert Schwebel <r.schwebel@pengutronix.de>
>   *
> + * (C) Copyright 2011 Marvell Inc.
> + * Lei Wen <leiwen@marvell.com>
> + *
>   * See file CREDITS for list of people who contributed to this
>   * project.
>   *
> @@ -34,24 +37,8 @@
>  #include <asm/io.h>
> 
>  #ifdef CONFIG_HARD_I2C
> -
> -/*
> - *	- CONFIG_SYS_I2C_SPEED
> - *	- I2C_PXA_SLAVE_ADDR
> - */
> -
> -#include <asm/arch/hardware.h>
> -#include <asm/arch/pxa-regs.h>
>  #include <i2c.h>
> -
> -#if (CONFIG_SYS_I2C_SPEED == 400000)
> -#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
> ICR_GCD \
> -			| ICR_SCLE)
> -#else
> -#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
> ICR_SCLE)
> -#endif
> -
> -#define I2C_ISR_INIT		0x7FF
> +#include "mv_i2c.h"
> 
>  #ifdef DEBUG_I2C
>  #define PRINTD(x) printf x
> @@ -59,20 +46,6 @@
>  #define PRINTD(x)
>  #endif
> 
> -/* Shall the current transfer have a start/stop condition? */
> -#define I2C_COND_NORMAL		0
> -#define I2C_COND_START		1
> -#define I2C_COND_STOP		2
> -
> -/* Shall the current transfer be ack/nacked or being waited for it? */
> -#define I2C_ACKNAK_WAITACK	1
> -#define I2C_ACKNAK_SENDACK	2
> -#define I2C_ACKNAK_SENDNAK	4
> -
> -/* Specify who shall transfer the data (master or slave) */
> -#define I2C_READ		0
> -#define I2C_WRITE		1
> -
>  /* All transfers are described by this data structure */
>  struct i2c_msg {
>  	u8 condition;
> @@ -81,27 +54,37 @@ struct i2c_msg {
>  	u8 data;
>  };
> 
> +struct pxa_i2c {
> +	u32 ibmr;
> +	u32 pad0;
> +	u32 idbr;
> +	u32 pad1;
> +	u32 icr;
> +	u32 pad2;
> +	u32 isr;
> +	u32 pad3;
> +	u32 isar;
> +};

(Optional to implement)
It is better if you can push register structure definition to the SoC specific header file, so that if there are new SoC that has different register structures that can be addressed cleanly.

> +
> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> +
>  /*
>   * i2c_pxa_reset: - reset the host controller
>   *
>   */
>  static void i2c_reset(void)
>  {
> -	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
> -	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
> +	andl(~ICR_IUE, &base->icr);	/* disable unit */
> +	orl(ICR_UR, &base->icr);	/* reset the unit */

Apart from discussion going on for patch - [PATCH V5.1 1/6] io: add and* and or* operation api to set and clear bit

The original code looks more readable to me.

>  	udelay(100);
> -	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
> -#ifdef CONFIG_CPU_MONAHANS
> -	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
> -	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
> -#else /* CONFIG_CPU_MONAHANS */
> -	/* set the global I2C clock on */
> -	writel(readl(CKEN) | CKEN14_I2C, CKEN);
> -#endif
> -	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
> -	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
> -	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
> -	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
> +	andl(~ICR_IUE, &base->icr);	/* disable unit */
> +
> +	i2c_clk_enable();
> +
> +	writel(CONFIG_SYS_I2C_SLAVE, &base->isar);/* set our slave address
> */
> +	writel(I2C_ICR_INIT, &base->icr);	/* set control reg values */

Why don't you do I2C_ICR_INIT | ICR_IUE here and avoid orl below?

> +	writel(I2C_ISR_INIT, &base->isr);	/* set clear interrupt bits */
> +	orl(ICR_IUE, &base->icr);		/* enable unit */
>  	udelay(100);
>  }

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-29  2:47             ` Lei Wen
@ 2011-03-29 16:03               ` Scott Wood
  2011-03-30 14:08                 ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Scott Wood @ 2011-03-29 16:03 UTC (permalink / raw)
  To: u-boot

On Tue, 29 Mar 2011 10:47:04 +0800
Lei Wen <adrian.wenl@gmail.com> wrote:

> Hi Scott,
> 
> On Tue, Mar 29, 2011 at 12:05 AM, Scott Wood <scottwood@freescale.com> wrote:
> > What does this do that setbits*/clrbits* don't?
> 
> Those and*/or* include the dmb() operation included in the read*/write*, which
> is not included in the __raw_read*/__raw_write* that setbits*/clrbits* refer to.
> I think it's better to keep another instance to set the bit, since
> there is read* and __raw_read*
> exist and have difference.

But why are setbits/clrbits using raw accesses?  That's not how they're
defined on powerpc, which is where these accessors originated.  I suspect
they were defined that way out of laziness from before ARM made a
distinction between raw and non-raw accessors, and it is now a bug in
setbits/clrbits (and out_be*, in_le*, etc) which should be fixed rather
than introducing an alternative.

And then if you want a raw version of these functions, introduce
raw_setbits_le32, raw_in_le16, etc.

-Scott

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
  2011-03-29 13:07             ` Prafulla Wadaskar
@ 2011-03-30 14:05               ` Lei Wen
  2011-03-30 18:56                 ` Prafulla Wadaskar
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-30 14:05 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Tue, Mar 29, 2011 at 9:07 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Monday, March 28, 2011 12:24 PM
>> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
>> Tang; adrian.wenl at gmail.com
>> Subject: [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
>>
>> Add i2c support to dkb board with pantheon soc.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V2:
>> NO CHANGE
>>
>> V3:
>> clean code sytle issue
>> Add i2c clock enable code include in I2C configure define block
>>
>> V4:
>> make i2c definition included in the ifdef
>>
>> V5:
>> NO CHANGE
>>
>> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ?| ? 12 ++++++++++++
>> ?arch/arm/include/asm/arch-pantheon/cpu.h | ? ?4 +++-
>> ?arch/arm/include/asm/arch-pantheon/mfp.h | ? ?6 ++++--
>> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ?| ? ?4 ++++
>> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ?| ? 13 +++++++++++++
>> ?5 files changed, 36 insertions(+), 3 deletions(-)
>>
> ...snip...
>
>> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
>> index 638af5e..599c8b8 100644
>> --- a/include/configs/dkb.h
>> +++ b/include/configs/dkb.h
>> @@ -56,6 +56,19 @@
>> ?#include "mv-common.h"
>>
>> ?#undef CONFIG_ARCH_MISC_INIT
>> +
>> +/*
>> + * I2C definition
>> + */
>> +#define CONFIG_CMD_I2C
>
> This command definition should be moved up (below #include <config_cmd_default.h>

I'm ok to put this define to the config_cmd_default.h, but this mean
many other platform need
which didn't not need the i2c but include the <config_cmd_default.h>,
need to undef the i2c now.
Does that worth the change?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit
  2011-03-29 16:03               ` Scott Wood
@ 2011-03-30 14:08                 ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-30 14:08 UTC (permalink / raw)
  To: u-boot

Hi Scott,

On Wed, Mar 30, 2011 at 12:03 AM, Scott Wood <scottwood@freescale.com> wrote:
> On Tue, 29 Mar 2011 10:47:04 +0800
> Lei Wen <adrian.wenl@gmail.com> wrote:
>
>> Hi Scott,
>>
>> On Tue, Mar 29, 2011 at 12:05 AM, Scott Wood <scottwood@freescale.com> wrote:
>> > What does this do that setbits*/clrbits* don't?
>>
>> Those and*/or* include the dmb() operation included in the read*/write*, which
>> is not included in the __raw_read*/__raw_write* that setbits*/clrbits* refer to.
>> I think it's better to keep another instance to set the bit, since
>> there is read* and __raw_read*
>> exist and have difference.
>
> But why are setbits/clrbits using raw accesses? ?That's not how they're
> defined on powerpc, which is where these accessors originated. ?I suspect
> they were defined that way out of laziness from before ARM made a
> distinction between raw and non-raw accessors, and it is now a bug in
> setbits/clrbits (and out_be*, in_le*, etc) which should be fixed rather
> than introducing an alternative.
>
> And then if you want a raw version of these functions, introduce
> raw_setbits_le32, raw_in_le16, etc.
>


Yep, that make sense to me. But since this patch is tend to be more discussion.
I'm going to remove this change out of this patch set, and post seperately.
Meanwhile, just use the writel(readl* style in this patch set for current stage.

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define
  2011-03-29 13:27             ` Prafulla Wadaskar
@ 2011-03-30 14:11               ` Lei Wen
  2011-03-30 18:54                 ` Prafulla Wadaskar
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-30 14:11 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Tue, Mar 29, 2011 at 9:27 PM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Monday, March 28, 2011 12:24 PM
>> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
>> Tang; adrian.wenl at gmail.com
>> Subject: [PATCH V5 3/6] mv_i2c: use structure to replace the direclty
>> define
>>
>> Add i2c_clk_enable in the cpu specific code, since previous platform it,
>> while new platform don't need. In the pantheon and armada100 platform,
>> this function is defined as NULL one.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V2:
>> NO CHANGE
>>
>> V3:
>> clean code sytle issue
>>
>> V4:
>> V5:
>> NO CHANGE
>>
>> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? | ? 11 +++
>> ?arch/arm/include/asm/arch-pxa/pxa-regs.h | ? 56 -------------
>> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ?| ? ?9 +--
>> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? | ?131 ++++++++++++++---------
>> -------
>> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? | ? 83 +++++++++++++++++++
>> ?include/configs/innokom.h ? ? ? ? ? ? ? ?| ? ?1 +
>> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ?| ? ?1 +
>> ?7 files changed, 159 insertions(+), 133 deletions(-)
>> ?create mode 100644 drivers/i2c/mv_i2c.h
>>
> ...snip...
>> diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
>> index 09756a4..734148b 100644
>> --- a/drivers/i2c/mv_i2c.c
>> +++ b/drivers/i2c/mv_i2c.c
>> @@ -8,6 +8,9 @@
>> ? * (C) Copyright 2003 Pengutronix e.K.
>> ? * Robert Schwebel <r.schwebel@pengutronix.de>
>> ? *
>> + * (C) Copyright 2011 Marvell Inc.
>> + * Lei Wen <leiwen@marvell.com>
>> + *
>> ? * See file CREDITS for list of people who contributed to this
>> ? * project.
>> ? *
>> @@ -34,24 +37,8 @@
>> ?#include <asm/io.h>
>>
>> ?#ifdef CONFIG_HARD_I2C
>> -
>> -/*
>> - * ? - CONFIG_SYS_I2C_SPEED
>> - * ? - I2C_PXA_SLAVE_ADDR
>> - */
>> -
>> -#include <asm/arch/hardware.h>
>> -#include <asm/arch/pxa-regs.h>
>> ?#include <i2c.h>
>> -
>> -#if (CONFIG_SYS_I2C_SPEED == 400000)
>> -#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
>> ICR_GCD \
>> - ? ? ? ? ? ? ? ? ? ? | ICR_SCLE)
>> -#else
>> -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
>> ICR_SCLE)
>> -#endif
>> -
>> -#define I2C_ISR_INIT ? ? ? ? 0x7FF
>> +#include "mv_i2c.h"
>>
>> ?#ifdef DEBUG_I2C
>> ?#define PRINTD(x) printf x
>> @@ -59,20 +46,6 @@
>> ?#define PRINTD(x)
>> ?#endif
>>
>> -/* Shall the current transfer have a start/stop condition? */
>> -#define I2C_COND_NORMAL ? ? ? ? ? ? ?0
>> -#define I2C_COND_START ? ? ? ? ? ? ? 1
>> -#define I2C_COND_STOP ? ? ? ? ? ? ? ?2
>> -
>> -/* Shall the current transfer be ack/nacked or being waited for it? */
>> -#define I2C_ACKNAK_WAITACK ? 1
>> -#define I2C_ACKNAK_SENDACK ? 2
>> -#define I2C_ACKNAK_SENDNAK ? 4
>> -
>> -/* Specify who shall transfer the data (master or slave) */
>> -#define I2C_READ ? ? ? ? ? ? 0
>> -#define I2C_WRITE ? ? ? ? ? ?1
>> -
>> ?/* All transfers are described by this data structure */
>> ?struct i2c_msg {
>> ? ? ? u8 condition;
>> @@ -81,27 +54,37 @@ struct i2c_msg {
>> ? ? ? u8 data;
>> ?};
>>
>> +struct pxa_i2c {
>> + ? ? u32 ibmr;
>> + ? ? u32 pad0;
>> + ? ? u32 idbr;
>> + ? ? u32 pad1;
>> + ? ? u32 icr;
>> + ? ? u32 pad2;
>> + ? ? u32 isr;
>> + ? ? u32 pad3;
>> + ? ? u32 isar;
>> +};
>
> (Optional to implement)
> It is better if you can push register structure definition to the SoC specific header file, so that if there are new SoC that has different register structures that can be addressed cleanly.

For current there is no different register arrage for this structure,
so I think it is
ok to just keep it current state. For the adding register doc
description, I have no
objection.
>
>> +
>> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
>> +
>> ?/*
>> ? * i2c_pxa_reset: - reset the host controller
>> ? *
>> ? */
>> ?static void i2c_reset(void)
>> ?{
>> - ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
>> - ? ? writel(readl(ICR) | ICR_UR, ICR); ? ? ? /* reset the unit */
>> + ? ? andl(~ICR_IUE, &base->icr); ? ? /* disable unit */
>> + ? ? orl(ICR_UR, &base->icr); ? ? ? ?/* reset the unit */
>
> Apart from discussion going on for patch - [PATCH V5.1 1/6] io: add and* and or* operation api to set and clear bit
>
> The original code looks more readable to me.
>
>> ? ? ? udelay(100);
>> - ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
>> -#ifdef CONFIG_CPU_MONAHANS
>> - ? ? /* | CKENB_1_PWM1 | CKENB_0_PWM0); */
>> - ? ? writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
>> -#else /* CONFIG_CPU_MONAHANS */
>> - ? ? /* set the global I2C clock on */
>> - ? ? writel(readl(CKEN) | CKEN14_I2C, CKEN);
>> -#endif
>> - ? ? writel(I2C_PXA_SLAVE_ADDR, ISAR); ? ? ? /* set our slave address */
>> - ? ? writel(I2C_ICR_INIT, ICR); ? ? ? ? ? ? ?/* set control reg values */
>> - ? ? writel(I2C_ISR_INIT, ISR); ? ? ? ? ? ? ?/* set clear interrupt bits */
>> - ? ? writel(readl(ICR) | ICR_IUE, ICR); ? ? ?/* enable unit */
>> + ? ? andl(~ICR_IUE, &base->icr); ? ? /* disable unit */
>> +
>> + ? ? i2c_clk_enable();
>> +
>> + ? ? writel(CONFIG_SYS_I2C_SLAVE, &base->isar);/* set our slave address
>> */
>> + ? ? writel(I2C_ICR_INIT, &base->icr); ? ? ? /* set control reg values */
>
> Why don't you do I2C_ICR_INIT | ICR_IUE here and avoid orl below?
>

This part of logic is the same which I brought from the pxa/i2c code.
I cannot make sure if I do this change whether it would make harm to
the original
platform or not... So my suggestion is keep it like it is. Is that ok for you?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define
  2011-03-30 14:11               ` Lei Wen
@ 2011-03-30 18:54                 ` Prafulla Wadaskar
  0 siblings, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-30 18:54 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:adrian.wenl at gmail.com]
> Sent: Wednesday, March 30, 2011 7:42 PM
> To: Prafulla Wadaskar
> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> Subject: Re: [PATCH V5 3/6] mv_i2c: use structure to replace the
> direclty define
> 
> Hi Prafulla,
> 
> On Tue, Mar 29, 2011 at 9:27 PM, Prafulla Wadaskar
> <prafulla@marvell.com> wrote:
> >
> >
> >> -----Original Message-----
> >> From: Lei Wen [mailto:leiwen at marvell.com]
> >> Sent: Monday, March 28, 2011 12:24 PM
> >> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> >> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> Yu
> >> Tang; adrian.wenl at gmail.com
> >> Subject: [PATCH V5 3/6] mv_i2c: use structure to replace the direclty
> >> define
> >>
> >> Add i2c_clk_enable in the cpu specific code, since previous platform
> it,
> >> while new platform don't need. In the pantheon and armada100
> platform,
> >> this function is defined as NULL one.
> >>
> >> Signed-off-by: Lei Wen <leiwen@marvell.com>
> >> ---
> >> Changelog:
> >> V2:
> >> NO CHANGE
> >>
> >> V3:
> >> clean code sytle issue
> >>
> >> V4:
> >> V5:
> >> NO CHANGE
> >>
> >> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? | ? 11 +++
> >> ?arch/arm/include/asm/arch-pxa/pxa-regs.h | ? 56 -------------
> >> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ?| ? ?9 +--
> >> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? | ?131 ++++++++++++++------
> ---
> >> -------
> >> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? | ? 83 +++++++++++++++++++
> >> ?include/configs/innokom.h ? ? ? ? ? ? ? ?| ? ?1 +
> >> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ?| ? ?1 +
> >> ?7 files changed, 159 insertions(+), 133 deletions(-)
> >> ?create mode 100644 drivers/i2c/mv_i2c.h
> >>
> > ...snip...
> >> diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
> >> index 09756a4..734148b 100644
> >> --- a/drivers/i2c/mv_i2c.c
> >> +++ b/drivers/i2c/mv_i2c.c
> >> @@ -8,6 +8,9 @@
> >> ? * (C) Copyright 2003 Pengutronix e.K.
> >> ? * Robert Schwebel <r.schwebel@pengutronix.de>
> >> ? *
> >> + * (C) Copyright 2011 Marvell Inc.
> >> + * Lei Wen <leiwen@marvell.com>
> >> + *
> >> ? * See file CREDITS for list of people who contributed to this
> >> ? * project.
> >> ? *
> >> @@ -34,24 +37,8 @@
> >> ?#include <asm/io.h>
> >>
> >> ?#ifdef CONFIG_HARD_I2C
> >> -
> >> -/*
> >> - * ? - CONFIG_SYS_I2C_SPEED
> >> - * ? - I2C_PXA_SLAVE_ADDR
> >> - */
> >> -
> >> -#include <asm/arch/hardware.h>
> >> -#include <asm/arch/pxa-regs.h>
> >> ?#include <i2c.h>
> >> -
> >> -#if (CONFIG_SYS_I2C_SPEED == 400000)
> >> -#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
> >> ICR_GCD \
> >> - ? ? ? ? ? ? ? ? ? ? | ICR_SCLE)
> >> -#else
> >> -#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
> >> ICR_SCLE)
> >> -#endif
> >> -
> >> -#define I2C_ISR_INIT ? ? ? ? 0x7FF
> >> +#include "mv_i2c.h"
> >>
> >> ?#ifdef DEBUG_I2C
> >> ?#define PRINTD(x) printf x
> >> @@ -59,20 +46,6 @@
> >> ?#define PRINTD(x)
> >> ?#endif
> >>
> >> -/* Shall the current transfer have a start/stop condition? */
> >> -#define I2C_COND_NORMAL ? ? ? ? ? ? ?0
> >> -#define I2C_COND_START ? ? ? ? ? ? ? 1
> >> -#define I2C_COND_STOP ? ? ? ? ? ? ? ?2
> >> -
> >> -/* Shall the current transfer be ack/nacked or being waited for it?
> */
> >> -#define I2C_ACKNAK_WAITACK ? 1
> >> -#define I2C_ACKNAK_SENDACK ? 2
> >> -#define I2C_ACKNAK_SENDNAK ? 4
> >> -
> >> -/* Specify who shall transfer the data (master or slave) */
> >> -#define I2C_READ ? ? ? ? ? ? 0
> >> -#define I2C_WRITE ? ? ? ? ? ?1
> >> -
> >> ?/* All transfers are described by this data structure */
> >> ?struct i2c_msg {
> >> ? ? ? u8 condition;
> >> @@ -81,27 +54,37 @@ struct i2c_msg {
> >> ? ? ? u8 data;
> >> ?};
> >>
> >> +struct pxa_i2c {
> >> + ? ? u32 ibmr;
> >> + ? ? u32 pad0;
> >> + ? ? u32 idbr;
> >> + ? ? u32 pad1;
> >> + ? ? u32 icr;
> >> + ? ? u32 pad2;
> >> + ? ? u32 isr;
> >> + ? ? u32 pad3;
> >> + ? ? u32 isar;
> >> +};
> >
> > (Optional to implement)
> > It is better if you can push register structure definition to the SoC
> specific header file, so that if there are new SoC that has different
> register structures that can be addressed cleanly.
> 
> For current there is no different register arrage for this structure,
> so I think it is
> ok to just keep it current state. For the adding register doc
> description, I have no
> objection.

That was just a suggestion, it up to you.

> >
> >> +
> >> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> >> +
> >> ?/*
> >> ? * i2c_pxa_reset: - reset the host controller
> >> ? *
> >> ? */
> >> ?static void i2c_reset(void)
> >> ?{
> >> - ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
> >> - ? ? writel(readl(ICR) | ICR_UR, ICR); ? ? ? /* reset the unit */
> >> + ? ? andl(~ICR_IUE, &base->icr); ? ? /* disable unit */
> >> + ? ? orl(ICR_UR, &base->icr); ? ? ? ?/* reset the unit */
> >
> > Apart from discussion going on for patch - [PATCH V5.1 1/6] io: add
> and* and or* operation api to set and clear bit
> >
> > The original code looks more readable to me.
> >
> >> ? ? ? udelay(100);
> >> - ? ? writel(readl(ICR) & ~ICR_IUE, ICR); ? ? /* disable unit */
> >> -#ifdef CONFIG_CPU_MONAHANS
> >> - ? ? /* | CKENB_1_PWM1 | CKENB_0_PWM0); */
> >> - ? ? writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
> >> -#else /* CONFIG_CPU_MONAHANS */
> >> - ? ? /* set the global I2C clock on */
> >> - ? ? writel(readl(CKEN) | CKEN14_I2C, CKEN);
> >> -#endif
> >> - ? ? writel(I2C_PXA_SLAVE_ADDR, ISAR); ? ? ? /* set our slave
> address */
> >> - ? ? writel(I2C_ICR_INIT, ICR); ? ? ? ? ? ? ?/* set control reg
> values */
> >> - ? ? writel(I2C_ISR_INIT, ISR); ? ? ? ? ? ? ?/* set clear interrupt
> bits */
> >> - ? ? writel(readl(ICR) | ICR_IUE, ICR); ? ? ?/* enable unit */
> >> + ? ? andl(~ICR_IUE, &base->icr); ? ? /* disable unit */
> >> +
> >> + ? ? i2c_clk_enable();
> >> +
> >> + ? ? writel(CONFIG_SYS_I2C_SLAVE, &base->isar);/* set our slave
> address
> >> */
> >> + ? ? writel(I2C_ICR_INIT, &base->icr); ? ? ? /* set control reg
> values */
> >
> > Why don't you do I2C_ICR_INIT | ICR_IUE here and avoid orl below?
> >
> 
> This part of logic is the same which I brought from the pxa/i2c code.
> I cannot make sure if I do this change whether it would make harm to
> the original
> platform or not... So my suggestion is keep it like it is. Is that ok
> for you?

That should not make a difference, but if we don't have h/w to test I respect your comments.

Regards..
Prafulla . .

> 
> Best regards,
> Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
  2011-03-30 14:05               ` Lei Wen
@ 2011-03-30 18:56                 ` Prafulla Wadaskar
  2011-03-31  7:49                   ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-03-30 18:56 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:adrian.wenl at gmail.com]
> Sent: Wednesday, March 30, 2011 7:36 PM
> To: Prafulla Wadaskar
> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> Subject: Re: [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
> 
> Hi Prafulla,
> 
> On Tue, Mar 29, 2011 at 9:07 PM, Prafulla Wadaskar
> <prafulla@marvell.com> wrote:
> >
> >
> >> -----Original Message-----
> >> From: Lei Wen [mailto:leiwen at marvell.com]
> >> Sent: Monday, March 28, 2011 12:24 PM
> >> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> >> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> Yu
> >> Tang; adrian.wenl at gmail.com
> >> Subject: [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
> >>
> >> Add i2c support to dkb board with pantheon soc.
> >>
> >> Signed-off-by: Lei Wen <leiwen@marvell.com>
> >> ---
> >> Changelog:
> >> V2:
> >> NO CHANGE
> >>
> >> V3:
> >> clean code sytle issue
> >> Add i2c clock enable code include in I2C configure define block
> >>
> >> V4:
> >> make i2c definition included in the ifdef
> >>
> >> V5:
> >> NO CHANGE
> >>
> >> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ?| ? 12 ++++++++++++
> >> ?arch/arm/include/asm/arch-pantheon/cpu.h | ? ?4 +++-
> >> ?arch/arm/include/asm/arch-pantheon/mfp.h | ? ?6 ++++--
> >> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ?| ? ?4 ++++
> >> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ?| ? 13 +++++++++++++
> >> ?5 files changed, 36 insertions(+), 3 deletions(-)
> >>
> > ...snip...
> >
> >> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
> >> index 638af5e..599c8b8 100644
> >> --- a/include/configs/dkb.h
> >> +++ b/include/configs/dkb.h
> >> @@ -56,6 +56,19 @@
> >> ?#include "mv-common.h"
> >>
> >> ?#undef CONFIG_ARCH_MISC_INIT
> >> +
> >> +/*
> >> + * I2C definition
> >> + */
> >> +#define CONFIG_CMD_I2C
> >
> > This command definition should be moved up (below #include
> <config_cmd_default.h>
> 
> I'm ok to put this define to the config_cmd_default.h, but this mean
> many other platform need
> which didn't not need the i2c but include the <config_cmd_default.h>,
> need to undef the i2c now.
> Does that worth the change?

I don't mean here to put it in to the config_cmd_default.h
I means put it below #include <config_cmd_default.h> line where other commands are defined/undefed.

Regards..
Prafulla . .

> 
> Best regards,
> Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
  2011-03-30 18:56                 ` Prafulla Wadaskar
@ 2011-03-31  7:49                   ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-31  7:49 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Thu, Mar 31, 2011 at 2:56 AM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>> Sent: Wednesday, March 30, 2011 7:36 PM
>> To: Prafulla Wadaskar
>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>> Subject: Re: [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
>>
>> Hi Prafulla,
>>
>> On Tue, Mar 29, 2011 at 9:07 PM, Prafulla Wadaskar
>> <prafulla@marvell.com> wrote:
>> >
>> >
>> >> -----Original Message-----
>> >> From: Lei Wen [mailto:leiwen at marvell.com]
>> >> Sent: Monday, March 28, 2011 12:24 PM
>> >> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> >> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
>> Yu
>> >> Tang; adrian.wenl at gmail.com
>> >> Subject: [PATCH V5 4/6] I2C: add i2c support for Pantheon platform
>> >>
>> >> Add i2c support to dkb board with pantheon soc.
>> >>
>> >> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> >> ---
>> >> Changelog:
>> >> V2:
>> >> NO CHANGE
>> >>
>> >> V3:
>> >> clean code sytle issue
>> >> Add i2c clock enable code include in I2C configure define block
>> >>
>> >> V4:
>> >> make i2c definition included in the ifdef
>> >>
>> >> V5:
>> >> NO CHANGE
>> >>
>> >> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ?| ? 12 ++++++++++++
>> >> ?arch/arm/include/asm/arch-pantheon/cpu.h | ? ?4 +++-
>> >> ?arch/arm/include/asm/arch-pantheon/mfp.h | ? ?6 ++++--
>> >> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ?| ? ?4 ++++
>> >> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ?| ? 13 +++++++++++++
>> >> ?5 files changed, 36 insertions(+), 3 deletions(-)
>> >>
>> > ...snip...
>> >
>> >> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
>> >> index 638af5e..599c8b8 100644
>> >> --- a/include/configs/dkb.h
>> >> +++ b/include/configs/dkb.h
>> >> @@ -56,6 +56,19 @@
>> >> ?#include "mv-common.h"
>> >>
>> >> ?#undef CONFIG_ARCH_MISC_INIT
>> >> +
>> >> +/*
>> >> + * I2C definition
>> >> + */
>> >> +#define CONFIG_CMD_I2C
>> >
>> > This command definition should be moved up (below #include
>> <config_cmd_default.h>
>>
>> I'm ok to put this define to the config_cmd_default.h, but this mean
>> many other platform need
>> which didn't not need the i2c but include the <config_cmd_default.h>,
>> need to undef the i2c now.
>> Does that worth the change?
>
> I don't mean here to put it in to the config_cmd_default.h
> I means put it below #include <config_cmd_default.h> line where other commands are defined/undefed.
>

Understand...
Patch to come...

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 0/5] add i2c support to pantheon and aramada100
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
@ 2011-03-31  8:37             ` Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
                                 ` (5 more replies)
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 1/5] pxa: move i2c driver to the common place Lei Wen
                               ` (4 subsequent siblings)
  5 siblings, 6 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-31  8:37 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

V3:
Clean the code sytle issue

V4:
add and* and or* to make set bit operation generic
Also make i2c definition included in the ifdef

V5:
Fix code style issue of the first patch
 
V6:
Seperate the and* and or* patch out of the patch set
Move CONFIG_CMD_I2C define place

Lei Wen (5):
  pxa: move i2c driver to the common place
  mv_i2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mv_i2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c     |   12 +
 arch/arm/cpu/pxa/Makefile                 |    1 -
 arch/arm/cpu/pxa/cpu.c                    |   11 +
 arch/arm/cpu/pxa/i2c.c                    |  469 ----------------------------
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++-
 arch/arm/include/asm/arch-pantheon/cpu.h  |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h  |    6 +-
 arch/arm/include/asm/arch-pxa/pxa-regs.h  |   56 ----
 board/Marvell/aspenite/aspenite.c         |    5 +
 board/Marvell/dkb/dkb.c                   |    4 +
 board/innokom/innokom.c                   |    9 +-
 drivers/i2c/Makefile                      |    1 +
 drivers/i2c/mv_i2c.c                      |  479 +++++++++++++++++++++++++++++
 drivers/i2c/mv_i2c.h                      |   83 +++++
 include/configs/aspenite.h                |   14 +
 include/configs/dkb.h                     |   13 +
 include/configs/innokom.h                 |    2 +
 include/configs/xm250.h                   |    2 +
 19 files changed, 672 insertions(+), 555 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c
 create mode 100644 drivers/i2c/mv_i2c.h

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 1/5] pxa: move i2c driver to the common place
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
@ 2011-03-31  8:37             ` Lei Wen
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
                               ` (3 subsequent siblings)
  5 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-03-31  8:37 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

V4:
V5:
V6:
NO CHANGE

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 455 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
new file mode 100644
index 0000000..09756a4
--- /dev/null
+++ b/drivers/i2c/mv_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+/*
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void)
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
+{
+	int timeout = 10000;
+
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch (msg->direction) {
+	case I2C_WRITE:
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+	default:
+		goto transfer_error_illegal_param;
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
+		i2c_reset();
+		return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+/*
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+		if (len == 0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if (i2c_transfer(&msg))
+			return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+		buffer++;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+/*
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+
+		if (len == 0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 1/5] pxa: move i2c driver to the common place Lei Wen
@ 2011-03-31  8:37             ` Lei Wen
  2011-04-01 18:29               ` Prafulla Wadaskar
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform Lei Wen
                               ` (2 subsequent siblings)
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-31  8:37 UTC (permalink / raw)
  To: u-boot

Add i2c_clk_enable in the cpu specific code, since previous platform it,
while new platform don't need. In the pantheon and armada100 platform,
this function is defined as NULL one.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue

V4:
V5:
V6:
NO CHANGE

 arch/arm/cpu/pxa/cpu.c                   |   11 +++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mv_i2c.c                     |  131 ++++++++++++++----------------
 drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 7 files changed, 159 insertions(+), 133 deletions(-)
 create mode 100644 drivers/i2c/mv_i2c.h

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..24b59e7 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,14 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 09756a4..3f145de 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -34,24 +37,8 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
-			| ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
+#include "mv_i2c.h"
 
 #ifdef DEBUG_I2C
 #define PRINTD(x) printf x
@@ -59,20 +46,6 @@
 #define PRINTD(x)
 #endif
 
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
 /* All transfers are described by this data structure */
 struct i2c_msg {
 	u8 condition;
@@ -81,27 +54,37 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct pxa_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+
 /*
  * i2c_pxa_reset: - reset the host controller
  *
  */
 static void i2c_reset(void)
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
+	writel(readl(&base->icr) | ICR_UR, &base->icr);	  /* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
+
+	i2c_clk_enable();
+
+	writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr); /* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */
+	writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */
 	udelay(100);
 }
 
@@ -114,13 +97,15 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 10000;
+	int timeout = 1000, isr;
 
-	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+	do {
+		isr = readl(&base->isr);
 		udelay(10);
 		if (timeout-- < 0)
 			return 0;
-	}
+	} while (((isr & set_mask) != set_mask)
+		|| ((isr & cleared_mask) != 0));
 
 	return 1;
 }
@@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		writel(readl(&base->icr) & ~ICR_START, &base->icr);
+		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			writel(readl(&base->icr) | ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			writel(readl(&base->icr) | ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
+		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
+		writel(readl(&base->icr) | ICR_TB, &base->icr);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		writel(readl(&base->isr) | ISR_ITE, &base->isr);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(readl(&base->icr) & ~ICR_START, &base->icr);
+		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			writel(readl(&base->icr) | ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			writel(readl(&base->icr) | ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
+		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
+		writel(readl(&base->icr) | ICR_TB, &base->icr);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
+		writel(readl(&base->isr) | ISR_IRF, &base->isr);
 		break;
 	default:
 		goto transfer_error_illegal_param;
@@ -252,10 +236,19 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
+	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
 	/* environment, which might be in a chip on that bus. For details   */
 	/* about this problem see doc/I2C_Edge_Conditions.                  */
+
+	/* disable I2C controller first, otherwhise it thinks we want to    */
+	/* talk to the slave port...                                        */
+	icr = readl(&base->icr);
+	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
new file mode 100644
index 0000000..41af0d9
--- /dev/null
+++ b/drivers/i2c/mv_i2c.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Inc, <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MV_I2C_H_
+#define _MV_I2C_H_
+extern void i2c_clk_enable(void);
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+		| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
+
+#endif
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..1ddee03 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..682d1ed 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
                               ` (2 preceding siblings ...)
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-03-31  8:37             ` Lei Wen
  2011-04-01 18:34               ` Prafulla Wadaskar
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 4/5] I2C: mv_i2c: add multi bus support Lei Wen
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-31  8:37 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition included in the ifdef

V5:
NO CHANGE

V6:
Move the CONFIG_CMD_I2C define place

 arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
 board/Marvell/dkb/dkb.c                  |    4 ++++
 include/configs/dkb.h                    |   13 +++++++++++++
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..8b2eafa 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,12 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+#endif
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +82,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..e939196 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -32,8 +32,10 @@
  * offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..c893a9d 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -47,6 +47,7 @@
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
 #include <config_cmd_default.h>
 #define CONFIG_CMD_AUTOSCRIPT
+#define CONFIG_CMD_I2C
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
 /*
@@ -56,6 +57,18 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
+/*
+ * I2C definition
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_PXA_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+#endif
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 4/5] I2C: mv_i2c: add multi bus support
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
                               ` (3 preceding siblings ...)
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-03-31  8:37             ` Lei Wen
  2011-04-01 18:36               ` Prafulla Wadaskar
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-31  8:37 UTC (permalink / raw)
  To: u-boot

Add the ability to support multiple i2c bus for mv_i2c

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
V6:
NO CHANGE

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 3f145de..3a3f7d7 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -66,7 +66,35 @@ struct pxa_i2c {
 	u32 isar;
 };
 
-static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+static struct pxa_i2c *base;
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
+static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
+static unsigned int current_bus;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct pxa_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /*
  * i2c_pxa_reset: - reset the host controller
@@ -235,6 +263,12 @@ i2c_transfer_finish:
 /* ------------------------------------------------------------------------ */
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct pxa_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/* call board specific i2c bus reset routine before accessing the   */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 5/5] I2C: add i2c support for Armada100 platform
  2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
                               ` (4 preceding siblings ...)
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 4/5] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-03-31  8:37             ` Lei Wen
  2011-04-01 18:39               ` Prafulla Wadaskar
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-03-31  8:37 UTC (permalink / raw)
  To: u-boot

Add i2c support to aspenite board with Armada100 soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
NO CHANGE

V6:
Move the CONFIG_CMD_I2C define place

 arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
 arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++-------------
 board/Marvell/aspenite/aspenite.c         |    5 +++
 include/configs/aspenite.h                |   14 ++++++++++
 4 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..c21938e 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,16 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +100,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..73783a7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -37,28 +37,32 @@
  * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART1 */
-#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART3 */
-#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+
+/* I2c */
+#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..b25e40b 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -52,6 +52,7 @@
  */
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
 #include <config_cmd_default.h>
+#define CONFIG_CMD_I2C
 #define CONFIG_CMD_AUTOSCRIPT
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
@@ -63,6 +64,19 @@
 #undef CONFIG_ARCH_MISC_INIT
 
 /*
+ * I2C definition
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV		1
+#define CONFIG_PXA_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+#endif
+
+/*
  * Environment variables configurations
  */
 #define CONFIG_ENV_IS_NOWHERE	1	/* if env in SDRAM */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-04-01 18:29               ` Prafulla Wadaskar
  2011-04-03 11:30                 ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-01 18:29 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 31, 2011 2:07 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V6 2/5] mv_i2c: use structure to replace the direclty
> define
> 
> Add i2c_clk_enable in the cpu specific code, since previous platform it,
> while new platform don't need. In the pantheon and armada100 platform,
> this function is defined as NULL one.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code sytle issue
> 
> V4:
> V5:
> V6:
> NO CHANGE
> 
>  arch/arm/cpu/pxa/cpu.c                   |   11 +++
>  arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 -------------
>  board/innokom/innokom.c                  |    9 +--
>  drivers/i2c/mv_i2c.c                     |  131 ++++++++++++++---------
> -------
>  drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++++
>  include/configs/innokom.h                |    1 +
>  include/configs/xm250.h                  |    1 +
>  7 files changed, 159 insertions(+), 133 deletions(-)
>  create mode 100644 drivers/i2c/mv_i2c.h
> 
> diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
> index 7d49cbb..24b59e7 100644
> --- a/arch/arm/cpu/pxa/cpu.c
> +++ b/arch/arm/cpu/pxa/cpu.c
> @@ -318,3 +318,14 @@ int arch_cpu_init(void)
>  	pxa_clock_setup();
>  	return 0;
>  }
> +
> +void i2c_clk_enable(void)
> +{
> +#ifdef CONFIG_CPU_MONAHANS
> +	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */

This comment line looks like part of code, Can be rephrased in better way.
 
> +	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
> +#else /* CONFIG_CPU_MONAHANS */
> +	/* set the global I2C clock on */
> +	writel(readl(CKEN) | CKEN14_I2C, CKEN);
> +#endif
> +}

...snip...

> @@ -81,27 +54,37 @@ struct i2c_msg {
>  	u8 data;
>  };
> 
> +struct pxa_i2c {
> +	u32 ibmr;
> +	u32 pad0;
> +	u32 idbr;
> +	u32 pad1;
> +	u32 icr;
> +	u32 pad2;
> +	u32 isr;
> +	u32 pad3;
> +	u32 isar;
> +};
> +
> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;

I think to sync with mc_i2c change at least the macro CONFIG_PXA_I2C_REG
Need to be renamed as CONFIG_MV_I2C_REG, because the same will be referred by other SoC code.
 
> +
>  /*
>   * i2c_pxa_reset: - reset the host controller
>   *
>   */

...snip...
> @@ -114,13 +97,15 @@ static void i2c_reset(void)
>  static int i2c_isr_set_cleared(unsigned long set_mask,
>  			       unsigned long cleared_mask)
>  {
> -	int timeout = 10000;
> +	int timeout = 1000, isr;

Is this done purposely? Or reducing timeout value from 10000 to 1000 has some meaning?

> 
> -	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) !=
> 0)) {
> +	do {
> +		isr = readl(&base->isr);
>  		udelay(10);
>  		if (timeout-- < 0)
>  			return 0;
> -	}
> +	} while (((isr & set_mask) != set_mask)
> +		|| ((isr & cleared_mask) != 0));
> 
>  	return 1;
>  }
> @@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
>  			goto transfer_error_bus_busy;
> 
>  		/* start transmission */
> -		writel(readl(ICR) & ~ICR_START, ICR);
> -		writel(readl(ICR) & ~ICR_STOP, ICR);
> -		writel(msg->data, IDBR);
> +		writel(readl(&base->icr) & ~ICR_START, &base->icr);
> +		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
> +		writel(msg->data, &base->idbr);
>  		if (msg->condition == I2C_COND_START)
> -			writel(readl(ICR) | ICR_START, ICR);
> +			writel(readl(&base->icr) | ICR_START, &base->icr);
>  		if (msg->condition == I2C_COND_STOP)
> -			writel(readl(ICR) | ICR_STOP, ICR);
> +			writel(readl(&base->icr) | ICR_STOP, &base->icr);
>  		if (msg->acknack == I2C_ACKNAK_SENDNAK)
> -			writel(readl(ICR) | ICR_ACKNAK, ICR);
> +			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
>  		if (msg->acknack == I2C_ACKNAK_SENDACK)
> -			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> -		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> -		writel(readl(ICR) | ICR_TB, ICR);
> +			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
> +		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
> +		writel(readl(&base->icr) | ICR_TB, &base->icr);
> 
>  		/* transmit register empty? */
>  		if (!i2c_isr_set_cleared(ISR_ITE, 0))
>  			goto transfer_error_transmit_timeout;
> 
>  		/* clear 'transmit empty' state */
> -		writel(readl(ISR) | ISR_ITE, ISR);
> +		writel(readl(&base->isr) | ISR_ITE, &base->isr);
> 
>  		/* wait for ACK from slave */
>  		if (msg->acknack == I2C_ACKNAK_WAITACK)
> @@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
>  			goto transfer_error_bus_busy;
> 
>  		/* start receive */
> -		writel(readl(ICR) & ~ICR_START, ICR);
> -		writel(readl(ICR) & ~ICR_STOP, ICR);
> +		writel(readl(&base->icr) & ~ICR_START, &base->icr);
> +		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
>  		if (msg->condition == I2C_COND_START)
> -			writel(readl(ICR) | ICR_START, ICR);
> +			writel(readl(&base->icr) | ICR_START, &base->icr);
>  		if (msg->condition == I2C_COND_STOP)
> -			writel(readl(ICR) | ICR_STOP, ICR);
> +			writel(readl(&base->icr) | ICR_STOP, &base->icr);
>  		if (msg->acknack == I2C_ACKNAK_SENDNAK)
> -			writel(readl(ICR) | ICR_ACKNAK, ICR);
> +			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
>  		if (msg->acknack == I2C_ACKNAK_SENDACK)
> -			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
> -		writel(readl(ICR) & ~ICR_ALDIE, ICR);
> -		writel(readl(ICR) | ICR_TB, ICR);
> +			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
> +		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
> +		writel(readl(&base->icr) | ICR_TB, &base->icr);
> 
>  		/* receive register full? */
>  		if (!i2c_isr_set_cleared(ISR_IRF, 0))
>  			goto transfer_error_receive_timeout;
> 
> -		msg->data = readl(IDBR);
> +		msg->data = readl(&base->idbr);
> 
>  		/* clear 'receive empty' state */
> -		writel(readl(ISR) | ISR_IRF, ISR);
> -
> +		writel(readl(&base->isr) | ISR_IRF, &base->isr);
>  		break;
>  	default:
>  		goto transfer_error_illegal_param;
> @@ -252,10 +236,19 @@ i2c_transfer_finish:
>  void i2c_init(int speed, int slaveaddr)
>  {
>  #ifdef CONFIG_SYS_I2C_INIT_BOARD
> +	u32 icr;
>  	/* call board specific i2c bus reset routine before accessing the
> */
>  	/* environment, which might be in a chip on that bus. For details
> */
>  	/* about this problem see doc/I2C_Edge_Conditions.
> */
> +
> +	/* disable I2C controller first, otherwhise it thinks we want to
> */
> +	/* talk to the slave port...
> */

Again, commenting style can be improved for overall block of comments.

> +	icr = readl(&base->icr);
> +	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
> +
>  	i2c_init_board();
> +
> +	writel(icr, &base->icr);
>  #endif
>  }
> 
> diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
> new file mode 100644
> index 0000000..41af0d9
> --- /dev/null
> +++ b/drivers/i2c/mv_i2c.h
> @@ -0,0 +1,83 @@
> +/*
> + * (C) Copyright 2011
> + * Marvell Inc, <www.marvell.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _MV_I2C_H_
> +#define _MV_I2C_H_
> +extern void i2c_clk_enable(void);
> +
> +/* Shall the current transfer have a start/stop condition? */
> +#define I2C_COND_NORMAL		0
> +#define I2C_COND_START		1
> +#define I2C_COND_STOP		2
> +
> +/* Shall the current transfer be ack/nacked or being waited for it? */
> +#define I2C_ACKNAK_WAITACK	1
> +#define I2C_ACKNAK_SENDACK	2
> +#define I2C_ACKNAK_SENDNAK	4
> +
> +/* Specify who shall transfer the data (master or slave) */
> +#define I2C_READ		0
> +#define I2C_WRITE		1
> +
> +#if (CONFIG_SYS_I2C_SPEED == 400000)
> +#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
> ICR_GCD \
> +		| ICR_SCLE)
> +#else
> +#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
> ICR_SCLE)
> +#endif
> +
> +#define I2C_ISR_INIT		0x7FF
> +/* ----- Control register bits ----------------------------------------
> */
> +
> +#define ICR_START	0x1		/* start bit */
> +#define ICR_STOP	0x2		/* stop bit */
> +#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
> +#define ICR_TB		0x8		/* transfer byte bit */
> +#define ICR_MA		0x10		/* master abort */
> +#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
> +#define ICR_IUE		0x40		/* unit enable */
> +#define ICR_GCD		0x80		/* general call disable */
> +#define ICR_ITEIE	0x100		/* enable tx interrupts */
> +#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE
> */
> +#define ICR_BEIE	0x400		/* enable bus error ints */
> +#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
> +#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
> +#define ICR_SADIE	0x2000		/* slave address detected int enable
> */
> +#define ICR_UR		0x4000		/* unit reset */
> +#define ICR_FM		0x8000		/* Fast Mode */
> +
> +/* ----- Status register bits -----------------------------------------
> */
> +
> +#define ISR_RWM		0x1		/* read/write mode */
> +#define ISR_ACKNAK	0x2		/* ack/nak status */
> +#define ISR_UB		0x4		/* unit busy */
> +#define ISR_IBB		0x8		/* bus busy */
> +#define ISR_SSD		0x10		/* slave stop detected */
> +#define ISR_ALD		0x20		/* arbitration loss detected */
> +#define ISR_ITE		0x40		/* tx buffer empty */
> +#define ISR_IRF		0x80		/* rx buffer full */
> +#define ISR_GCAD	0x100		/* general call address detected */
> +#define ISR_SAD		0x200		/* slave address detected */
> +#define ISR_BED		0x400		/* bus error no ACK/NAK */
> +
> +#endif
> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
> index 0ea73c9..1ddee03 100644
> --- a/include/configs/innokom.h
> +++ b/include/configs/innokom.h
> @@ -141,6 +141,7 @@
>   * I2C bus
>   */
>  #define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0x40301680

This should be CONFIG_MV_I2C_REG

>  #define CONFIG_HARD_I2C			1
>  #define CONFIG_SYS_I2C_SPEED			50000
>  #define CONFIG_SYS_I2C_SLAVE			0xfe
> diff --git a/include/configs/xm250.h b/include/configs/xm250.h
> index b4b940a..682d1ed 100644
> --- a/include/configs/xm250.h
> +++ b/include/configs/xm250.h
> @@ -62,6 +62,7 @@
>   * I2C bus
>   */
>  #define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0x40301680

Ditto

>  #define CONFIG_HARD_I2C			1
>  #define CONFIG_SYS_I2C_SPEED			50000
>  #define CONFIG_SYS_I2C_SLAVE			0xfe
> --

Regards..
Prafulla . .

> 1.7.0.4

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-04-01 18:34               ` Prafulla Wadaskar
  2011-04-03 11:32                 ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-01 18:34 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 31, 2011 2:07 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V6 3/5] I2C: add i2c support for Pantheon platform
> 
> Add i2c support to dkb board with pantheon soc.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code sytle issue
> Add i2c clock enable code include in I2C configure define block
> 
> V4:
> make i2c definition included in the ifdef
> 
> V5:
> NO CHANGE
> 
> V6:
> Move the CONFIG_CMD_I2C define place
> 
>  arch/arm/cpu/arm926ejs/pantheon/cpu.c    |   12 ++++++++++++
>  arch/arm/include/asm/arch-pantheon/cpu.h |    4 +++-
>  arch/arm/include/asm/arch-pantheon/mfp.h |    6 ++++--
>  board/Marvell/dkb/dkb.c                  |    4 ++++
>  include/configs/dkb.h                    |   13 +++++++++++++
>  5 files changed, 36 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> index 9ddc77c..8b2eafa 100644
> --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
> @@ -59,6 +59,12 @@ int arch_cpu_init(void)
>  	/* Enable GPIO clock */
>  	writel(APBC_APBCLK, &apbclkres->gpio);
> 
> +#ifdef CONFIG_I2C_MV
> +	/* Enable I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
> +#endif
> +
>  	icache_enable();
> 
>  	return 0;
> @@ -76,3 +82,9 @@ int print_cpuinfo(void)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_I2C_MV
> +void i2c_clk_enable(void)
> +{
> +}
> +#endif
> diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h
> b/arch/arm/include/asm/arch-pantheon/cpu.h
> index 30f4393..60955c5 100644
> --- a/arch/arm/include/asm/arch-pantheon/cpu.h
> +++ b/arch/arm/include/asm/arch-pantheon/cpu.h
> @@ -50,7 +50,9 @@ struct panthapb_registers {
>  	u32 uart0;	/*0x000*/
>  	u32 uart1;	/*0x004*/
>  	u32 gpio;	/*0x008*/
> -	u8 pad0[0x034 - 0x08 - 4];
> +	u8 pad0[0x02c - 0x08 - 4];
> +	u32 twsi;	/*0x02c*/
> +	u8 pad1[0x034 - 0x2c - 4];
>  	u32 timers;	/*0x034*/
>  };
> 
> diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h
> b/arch/arm/include/asm/arch-pantheon/mfp.h
> index fb291cf..e939196 100644
> --- a/arch/arm/include/asm/arch-pantheon/mfp.h
> +++ b/arch/arm/include/asm/arch-pantheon/mfp.h
> @@ -32,8 +32,10 @@
>   * offset, pull,pF, drv,dF, edge,eF ,afn,aF
>   */
>  /* UART2 */
> -#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> -#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> +#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> 
>  /* More macros can be defined here... */
> 
> diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
> index 72a2d2a..00f73e7 100644
> --- a/board/Marvell/dkb/dkb.c
> +++ b/board/Marvell/dkb/dkb.c
> @@ -36,6 +36,10 @@ int board_early_init_f(void)
>  		MFP47_UART2_RXD,
>  		MFP48_UART2_TXD,
> 
> +		/* I2C */
> +		MFP53_CI2C_SCL,
> +		MFP54_CI2C_SDA,
> +
>  		MFP_EOC		/*End of configureation*/
>  	};
>  	/* configure MFP's */
> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
> index 638af5e..c893a9d 100644
> --- a/include/configs/dkb.h
> +++ b/include/configs/dkb.h
> @@ -47,6 +47,7 @@
>  #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
>  #include <config_cmd_default.h>
>  #define CONFIG_CMD_AUTOSCRIPT
> +#define CONFIG_CMD_I2C
>  #undef CONFIG_CMD_NET
>  #undef CONFIG_CMD_NFS
>  /*
> @@ -56,6 +57,18 @@
>  #include "mv-common.h"
> 
>  #undef CONFIG_ARCH_MISC_INIT


> +
> +/*
> + * I2C definition
> + */
> +#ifdef CONFIG_CMD_I2C
> +#define CONFIG_I2C_MV			1
> +#define CONFIG_PXA_I2C_REG		0xd4011000

PXA looks invalid reference here, should be MV.

> +#define CONFIG_HARD_I2C			1
> +#define CONFIG_SYS_I2C_SPEED		0
> +#define CONFIG_SYS_I2C_SLAVE		0xfe
> +#endif

Sorry being not reported earlier.
But this #ifdefed code should be in mv-common.h or <arch/config.h> so that it can be shared across all the boards supported by the same SoC or IP.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 4/5] I2C: mv_i2c: add multi bus support
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 4/5] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-04-01 18:36               ` Prafulla Wadaskar
  0 siblings, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-01 18:36 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 31, 2011 2:07 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V6 4/5] I2C: mv_i2c: add multi bus support
> 
> Add the ability to support multiple i2c bus for mv_i2c
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code style issue
> 
> V4:
> V5:
> V6:
> NO CHANGE
> 
>  drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
>  1 files changed, 35 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
> index 3f145de..3a3f7d7 100644
> --- a/drivers/i2c/mv_i2c.c
> +++ b/drivers/i2c/mv_i2c.c
> @@ -66,7 +66,35 @@ struct pxa_i2c {
>  	u32 isar;
>  };
> 
> -static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> +static struct pxa_i2c *base;
> +#ifdef CONFIG_I2C_MULTI_BUS
> +static u32 i2c_regs[CONFIG_PXA_I2C_NUM] = CONFIG_PXA_I2C_REG;
> +static unsigned int bus_initialized[CONFIG_PXA_I2C_NUM];
> +static unsigned int current_bus;
> +
> +int i2c_set_bus_num(unsigned int bus)
> +{
> +	if ((bus < 0) || (bus >= CONFIG_PXA_I2C_NUM)) {
> +		printf("Bad bus: %d\n", bus);
> +		return -1;
> +	}
> +
> +	base = (struct pxa_i2c *)i2c_regs[bus];
> +	current_bus = bus;
> +
> +	if (!bus_initialized[current_bus]) {
> +		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> +		bus_initialized[current_bus] = 1;
> +	}
> +
> +	return 0;
> +}
> +
> +unsigned int i2c_get_bus_num(void)
> +{
> +	return current_bus;
> +}
> +#endif
> 
>  /*
>   * i2c_pxa_reset: - reset the host controller
> @@ -235,6 +263,12 @@ i2c_transfer_finish:
>  /* --------------------------------------------------------------------
> ---- */
>  void i2c_init(int speed, int slaveaddr)
>  {
> +#ifdef CONFIG_I2C_MULTI_BUS
> +	base = (struct pxa_i2c *)i2c_regs[current_bus];
> +#else
> +	base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
> +#endif
> +
>  #ifdef CONFIG_SYS_I2C_INIT_BOARD
>  	u32 icr;
>  	/* call board specific i2c bus reset routine before accessing the
> */

Ack, except s/PXA/MV/g

Regards..
Prafulla . .

> --
> 1.7.0.4

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 5/5] I2C: add i2c support for Armada100 platform
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 5/5] I2C: add i2c support for Armada100 platform Lei Wen
@ 2011-04-01 18:39               ` Prafulla Wadaskar
  0 siblings, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-01 18:39 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Thursday, March 31, 2011 2:07 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V6 5/5] I2C: add i2c support for Armada100 platform
> 
> Add i2c support to aspenite board with Armada100 soc.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> V2:
> NO CHANGE
> 
> V3:
> clean code style issue
> 
> V4:
> V5:
> NO CHANGE
> 
> V6:
> Move the CONFIG_CMD_I2C define place
> 
>  arch/arm/cpu/arm926ejs/armada100/cpu.c    |   16 +++++++++++
>  arch/arm/include/asm/arch-armada100/mfp.h |   40 ++++++++++++++++------
> -------
>  board/Marvell/aspenite/aspenite.c         |    5 +++
>  include/configs/aspenite.h                |   14 ++++++++++
>  4 files changed, 57 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c
> b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> index 62aa175..c21938e 100644
> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> @@ -62,6 +62,16 @@ int arch_cpu_init(void)
>  	/* Enable GPIO clock */
>  	writel(APBC_APBCLK, &apb1clkres->gpio);
> 
> +#ifdef CONFIG_I2C_MV
> +	/* Enable general I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
> +
> +	/* Enable power I2C clock */
> +	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
> +	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
> +#endif
> +
>  	/*
>  	 * Enable Functional and APB clock at 14.7456MHz
>  	 * for configured UART console
> @@ -90,3 +100,9 @@ int print_cpuinfo(void)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_I2C_MV
> +void i2c_clk_enable(void)
> +{
> +}
> +#endif
> diff --git a/arch/arm/include/asm/arch-armada100/mfp.h
> b/arch/arm/include/asm/arch-armada100/mfp.h
> index d21a79f..73783a7 100644
> --- a/arch/arm/include/asm/arch-armada100/mfp.h
> +++ b/arch/arm/include/asm/arch-armada100/mfp.h
> @@ -37,28 +37,32 @@
>   * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
>   */
>  /* UART1 */
> -#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
> -#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
> -#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
> -#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
> -#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
> -#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
> -#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
> -#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
> -#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 |
> MFP_DRIVE_MEDIUM
> -#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
> -#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
> -#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
> +#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
> +#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
> +#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
> +#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
> +#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
> +#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> +#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
> +#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> +#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 |
> MFP_DRIVE_MEDIUM)
> +#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> +#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
> +#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
> 
>  /* UART2 */
> -#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> -#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM
> -#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> -#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> +#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 |
> MFP_DRIVE_MEDIUM)
> +#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> 
>  /* UART3 */
> -#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> -#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 |
> MFP_DRIVE_MEDIUM
> +#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 |
> MFP_DRIVE_MEDIUM)
> +
> +/* I2c */
> +#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 |
> MFP_DRIVE_MEDIUM)
> +#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 |
> MFP_DRIVE_MEDIUM)
> 
>  /* More macros can be defined here... */
> 
> diff --git a/board/Marvell/aspenite/aspenite.c
> b/board/Marvell/aspenite/aspenite.c
> index 046ffd6..34ac7aa 100644
> --- a/board/Marvell/aspenite/aspenite.c
> +++ b/board/Marvell/aspenite/aspenite.c
> @@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
>  int board_early_init_f(void)
>  {
>  	u32 mfp_cfg[] = {
> +		/* I2C */
> +		MFP105_CI2C_SDA,
> +		MFP106_CI2C_SCL,
> +
>  		/* Enable Console on UART1 */
>  		MFP107_UART1_RXD,
>  		MFP108_UART1_TXD,
> +
>  		MFP_EOC		/*End of configureation*/
>  	};
>  	/* configure MFP's */
> diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
> index fd35f3e..b25e40b 100644
> --- a/include/configs/aspenite.h
> +++ b/include/configs/aspenite.h
> @@ -52,6 +52,7 @@
>   */
>  #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
>  #include <config_cmd_default.h>
> +#define CONFIG_CMD_I2C
>  #define CONFIG_CMD_AUTOSCRIPT
>  #undef CONFIG_CMD_NET
>  #undef CONFIG_CMD_NFS
> @@ -63,6 +64,19 @@
>  #undef CONFIG_ARCH_MISC_INIT
> 
>  /*
> + * I2C definition
> + */
> +#ifdef CONFIG_CMD_I2C
> +#define CONFIG_I2C_MV		1
> +#define CONFIG_PXA_I2C_NUM	2
> +#define CONFIG_I2C_MULTI_BUS	1
> +#define CONFIG_PXA_I2C_REG	{0xd4011000, 0xd4025000}
> +#define CONFIG_HARD_I2C		1
> +#define CONFIG_SYS_I2C_SPEED	0
> +#define CONFIG_SYS_I2C_SLAVE	0xfe
> +#endif

This should go to arch/config.h

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define
  2011-04-01 18:29               ` Prafulla Wadaskar
@ 2011-04-03 11:30                 ` Lei Wen
  2011-04-03 13:21                   ` Wolfgang Denk
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-04-03 11:30 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Sat, Apr 2, 2011 at 2:29 AM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Thursday, March 31, 2011 2:07 PM
>> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
>> Tang; adrian.wenl at gmail.com
>> Subject: [PATCH V6 2/5] mv_i2c: use structure to replace the direclty
>> define
>>
>> Add i2c_clk_enable in the cpu specific code, since previous platform it,
>> while new platform don't need. In the pantheon and armada100 platform,
>> this function is defined as NULL one.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V2:
>> NO CHANGE
>>
>> V3:
>> clean code sytle issue
>>
>> V4:
>> V5:
>> V6:
>> NO CHANGE
>>
>> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? | ? 11 +++
>> ?arch/arm/include/asm/arch-pxa/pxa-regs.h | ? 56 -------------
>> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ?| ? ?9 +--
>> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? | ?131 ++++++++++++++---------
>> -------
>> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? | ? 83 +++++++++++++++++++
>> ?include/configs/innokom.h ? ? ? ? ? ? ? ?| ? ?1 +
>> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ?| ? ?1 +
>> ?7 files changed, 159 insertions(+), 133 deletions(-)
>> ?create mode 100644 drivers/i2c/mv_i2c.h
>>
>> diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
>> index 7d49cbb..24b59e7 100644
>> --- a/arch/arm/cpu/pxa/cpu.c
>> +++ b/arch/arm/cpu/pxa/cpu.c
>> @@ -318,3 +318,14 @@ int arch_cpu_init(void)
>> ? ? ? pxa_clock_setup();
>> ? ? ? return 0;
>> ?}
>> +
>> +void i2c_clk_enable(void)
>> +{
>> +#ifdef CONFIG_CPU_MONAHANS
>> + ? ? /* | CKENB_1_PWM1 | CKENB_0_PWM0); */
>
> This comment line looks like part of code, Can be rephrased in better way.
Yep.

>
>> + ? ? writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
>> +#else /* CONFIG_CPU_MONAHANS */
>> + ? ? /* set the global I2C clock on */
>> + ? ? writel(readl(CKEN) | CKEN14_I2C, CKEN);
>> +#endif
>> +}
>
> ...snip...
>
>> @@ -81,27 +54,37 @@ struct i2c_msg {
>> ? ? ? u8 data;
>> ?};
>>
>> +struct pxa_i2c {
>> + ? ? u32 ibmr;
>> + ? ? u32 pad0;
>> + ? ? u32 idbr;
>> + ? ? u32 pad1;
>> + ? ? u32 icr;
>> + ? ? u32 pad2;
>> + ? ? u32 isr;
>> + ? ? u32 pad3;
>> + ? ? u32 isar;
>> +};
>> +
>> +static struct pxa_i2c *base = (struct pxa_i2c *)CONFIG_PXA_I2C_REG;
>
> I think to sync with mc_i2c change at least the macro CONFIG_PXA_I2C_REG
> Need to be renamed as CONFIG_MV_I2C_REG, because the same will be referred by other SoC code.

Ok, I would do this change for next post.
>
>> +
>> ?/*
>> ? * i2c_pxa_reset: - reset the host controller
>> ? *
>> ? */
>
> ...snip...
>> @@ -114,13 +97,15 @@ static void i2c_reset(void)
>> ?static int i2c_isr_set_cleared(unsigned long set_mask,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long cleared_mask)
>> ?{
>> - ? ? int timeout = 10000;
>> + ? ? int timeout = 1000, isr;
>
> Is this done purposely? Or reducing timeout value from 10000 to 1000 has some meaning?

You may notice original comment above this function is timeout if (no
match within 10 ms).
So the 10ms is 1000*10us, not the 10000*10us. In this patch I correct
this to match its comments.

>
>>
>> - ? ? while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) !=
>> 0)) {
>> + ? ? do {
>> + ? ? ? ? ? ? isr = readl(&base->isr);
>> ? ? ? ? ? ? ? udelay(10);
>> ? ? ? ? ? ? ? if (timeout-- < 0)
>> ? ? ? ? ? ? ? ? ? ? ? return 0;
>> - ? ? }
>> + ? ? } while (((isr & set_mask) != set_mask)
>> + ? ? ? ? ? ? || ((isr & cleared_mask) != 0));
>>
>> ? ? ? return 1;
>> ?}
>> @@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_bus_busy;
>>
>> ? ? ? ? ? ? ? /* start transmission */
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_START, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_STOP, ICR);
>> - ? ? ? ? ? ? writel(msg->data, IDBR);
>> + ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_START, &base->icr);
>> + ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
>> + ? ? ? ? ? ? writel(msg->data, &base->idbr);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_START)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_START, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) | ICR_START, &base->icr);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_STOP)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_STOP, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) | ICR_STOP, &base->icr);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDNAK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
>> + ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
>> + ? ? ? ? ? ? writel(readl(&base->icr) | ICR_TB, &base->icr);
>>
>> ? ? ? ? ? ? ? /* transmit register empty? */
>> ? ? ? ? ? ? ? if (!i2c_isr_set_cleared(ISR_ITE, 0))
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_transmit_timeout;
>>
>> ? ? ? ? ? ? ? /* clear 'transmit empty' state */
>> - ? ? ? ? ? ? writel(readl(ISR) | ISR_ITE, ISR);
>> + ? ? ? ? ? ? writel(readl(&base->isr) | ISR_ITE, &base->isr);
>>
>> ? ? ? ? ? ? ? /* wait for ACK from slave */
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_WAITACK)
>> @@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_bus_busy;
>>
>> ? ? ? ? ? ? ? /* start receive */
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_START, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_STOP, ICR);
>> + ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_START, &base->icr);
>> + ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_START)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_START, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) | ICR_START, &base->icr);
>> ? ? ? ? ? ? ? if (msg->condition == I2C_COND_STOP)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_STOP, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) | ICR_STOP, &base->icr);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDNAK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) | ICR_ACKNAK, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
>> ? ? ? ? ? ? ? if (msg->acknack == I2C_ACKNAK_SENDACK)
>> - ? ? ? ? ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ACKNAK, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) & ~ICR_ALDIE, ICR);
>> - ? ? ? ? ? ? writel(readl(ICR) | ICR_TB, ICR);
>> + ? ? ? ? ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
>> + ? ? ? ? ? ? writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
>> + ? ? ? ? ? ? writel(readl(&base->icr) | ICR_TB, &base->icr);
>>
>> ? ? ? ? ? ? ? /* receive register full? */
>> ? ? ? ? ? ? ? if (!i2c_isr_set_cleared(ISR_IRF, 0))
>> ? ? ? ? ? ? ? ? ? ? ? goto transfer_error_receive_timeout;
>>
>> - ? ? ? ? ? ? msg->data = readl(IDBR);
>> + ? ? ? ? ? ? msg->data = readl(&base->idbr);
>>
>> ? ? ? ? ? ? ? /* clear 'receive empty' state */
>> - ? ? ? ? ? ? writel(readl(ISR) | ISR_IRF, ISR);
>> -
>> + ? ? ? ? ? ? writel(readl(&base->isr) | ISR_IRF, &base->isr);
>> ? ? ? ? ? ? ? break;
>> ? ? ? default:
>> ? ? ? ? ? ? ? goto transfer_error_illegal_param;
>> @@ -252,10 +236,19 @@ i2c_transfer_finish:
>> ?void i2c_init(int speed, int slaveaddr)
>> ?{
>> ?#ifdef CONFIG_SYS_I2C_INIT_BOARD
>> + ? ? u32 icr;
>> ? ? ? /* call board specific i2c bus reset routine before accessing the
>> */
>> ? ? ? /* environment, which might be in a chip on that bus. For details
>> */
>> ? ? ? /* about this problem see doc/I2C_Edge_Conditions.
>> */
>> +
>> + ? ? /* disable I2C controller first, otherwhise it thinks we want to
>> */
>> + ? ? /* talk to the slave port...
>> */
>
> Again, commenting style can be improved for overall block of comments.

Yep.

>
>> + ? ? icr = readl(&base->icr);
>> + ? ? writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
>> +
>> ? ? ? i2c_init_board();
>> +
>> + ? ? writel(icr, &base->icr);
>> ?#endif
>> ?}
>>
>> diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
>> new file mode 100644
>> index 0000000..41af0d9
>> --- /dev/null
>> +++ b/drivers/i2c/mv_i2c.h
>> @@ -0,0 +1,83 @@
>> +/*
>> + * (C) Copyright 2011
>> + * Marvell Inc, <www.marvell.com>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +#ifndef _MV_I2C_H_
>> +#define _MV_I2C_H_
>> +extern void i2c_clk_enable(void);
>> +
>> +/* Shall the current transfer have a start/stop condition? */
>> +#define I2C_COND_NORMAL ? ? ? ? ? ? ?0
>> +#define I2C_COND_START ? ? ? ? ? ? ? 1
>> +#define I2C_COND_STOP ? ? ? ? ? ? ? ?2
>> +
>> +/* Shall the current transfer be ack/nacked or being waited for it? */
>> +#define I2C_ACKNAK_WAITACK ? 1
>> +#define I2C_ACKNAK_SENDACK ? 2
>> +#define I2C_ACKNAK_SENDNAK ? 4
>> +
>> +/* Specify who shall transfer the data (master or slave) */
>> +#define I2C_READ ? ? ? ? ? ? 0
>> +#define I2C_WRITE ? ? ? ? ? ?1
>> +
>> +#if (CONFIG_SYS_I2C_SPEED == 400000)
>> +#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE |
>> ICR_GCD \
>> + ? ? ? ? ? ? | ICR_SCLE)
>> +#else
>> +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD |
>> ICR_SCLE)
>> +#endif
>> +
>> +#define I2C_ISR_INIT ? ? ? ? 0x7FF
>> +/* ----- Control register bits ----------------------------------------
>> */
>> +
>> +#define ICR_START ? ?0x1 ? ? ? ? ? ? /* start bit */
>> +#define ICR_STOP ? ? 0x2 ? ? ? ? ? ? /* stop bit */
>> +#define ICR_ACKNAK ? 0x4 ? ? ? ? ? ? /* send ACK(0) or NAK(1) */
>> +#define ICR_TB ? ? ? ? ? ? ? 0x8 ? ? ? ? ? ? /* transfer byte bit */
>> +#define ICR_MA ? ? ? ? ? ? ? 0x10 ? ? ? ? ? ?/* master abort */
>> +#define ICR_SCLE ? ? 0x20 ? ? ? ? ? ?/* master clock enable, mona SCLEA */
>> +#define ICR_IUE ? ? ? ? ? ? ?0x40 ? ? ? ? ? ?/* unit enable */
>> +#define ICR_GCD ? ? ? ? ? ? ?0x80 ? ? ? ? ? ?/* general call disable */
>> +#define ICR_ITEIE ? ?0x100 ? ? ? ? ? /* enable tx interrupts */
>> +#define ICR_IRFIE ? ?0x200 ? ? ? ? ? /* enable rx interrupts, mona: DRFIE
>> */
>> +#define ICR_BEIE ? ? 0x400 ? ? ? ? ? /* enable bus error ints */
>> +#define ICR_SSDIE ? ?0x800 ? ? ? ? ? /* slave STOP detected int enable */
>> +#define ICR_ALDIE ? ?0x1000 ? ? ? ? ?/* enable arbitration interrupt */
>> +#define ICR_SADIE ? ?0x2000 ? ? ? ? ?/* slave address detected int enable
>> */
>> +#define ICR_UR ? ? ? ? ? ? ? 0x4000 ? ? ? ? ?/* unit reset */
>> +#define ICR_FM ? ? ? ? ? ? ? 0x8000 ? ? ? ? ?/* Fast Mode */
>> +
>> +/* ----- Status register bits -----------------------------------------
>> */
>> +
>> +#define ISR_RWM ? ? ? ? ? ? ?0x1 ? ? ? ? ? ? /* read/write mode */
>> +#define ISR_ACKNAK ? 0x2 ? ? ? ? ? ? /* ack/nak status */
>> +#define ISR_UB ? ? ? ? ? ? ? 0x4 ? ? ? ? ? ? /* unit busy */
>> +#define ISR_IBB ? ? ? ? ? ? ?0x8 ? ? ? ? ? ? /* bus busy */
>> +#define ISR_SSD ? ? ? ? ? ? ?0x10 ? ? ? ? ? ?/* slave stop detected */
>> +#define ISR_ALD ? ? ? ? ? ? ?0x20 ? ? ? ? ? ?/* arbitration loss detected */
>> +#define ISR_ITE ? ? ? ? ? ? ?0x40 ? ? ? ? ? ?/* tx buffer empty */
>> +#define ISR_IRF ? ? ? ? ? ? ?0x80 ? ? ? ? ? ?/* rx buffer full */
>> +#define ISR_GCAD ? ? 0x100 ? ? ? ? ? /* general call address detected */
>> +#define ISR_SAD ? ? ? ? ? ? ?0x200 ? ? ? ? ? /* slave address detected */
>> +#define ISR_BED ? ? ? ? ? ? ?0x400 ? ? ? ? ? /* bus error no ACK/NAK */
>> +
>> +#endif
>> diff --git a/include/configs/innokom.h b/include/configs/innokom.h
>> index 0ea73c9..1ddee03 100644
>> --- a/include/configs/innokom.h
>> +++ b/include/configs/innokom.h
>> @@ -141,6 +141,7 @@
>> ? * I2C bus
>> ? */
>> ?#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_PXA_I2C_REG ? ? ? ? ? 0x40301680
>
> This should be CONFIG_MV_I2C_REG
>
>> ?#define CONFIG_HARD_I2C ? ? ? ? ? ? ? ? ? ? ?1
>> ?#define CONFIG_SYS_I2C_SPEED ? ? ? ? ? ? ? ? 50000
>> ?#define CONFIG_SYS_I2C_SLAVE ? ? ? ? ? ? ? ? 0xfe
>> diff --git a/include/configs/xm250.h b/include/configs/xm250.h
>> index b4b940a..682d1ed 100644
>> --- a/include/configs/xm250.h
>> +++ b/include/configs/xm250.h
>> @@ -62,6 +62,7 @@
>> ? * I2C bus
>> ? */
>> ?#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_PXA_I2C_REG ? ? ? ? ? 0x40301680
>
> Ditto
>
>> ?#define CONFIG_HARD_I2C ? ? ? ? ? ? ? ? ? ? ?1
>> ?#define CONFIG_SYS_I2C_SPEED ? ? ? ? ? ? ? ? 50000
>> ?#define CONFIG_SYS_I2C_SLAVE ? ? ? ? ? ? ? ? 0xfe
>> --
>

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform
  2011-04-01 18:34               ` Prafulla Wadaskar
@ 2011-04-03 11:32                 ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-03 11:32 UTC (permalink / raw)
  To: u-boot

On Sat, Apr 2, 2011 at 2:34 AM, Prafulla Wadaskar <prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Thursday, March 31, 2011 2:07 PM
>> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
>> Tang; adrian.wenl at gmail.com
>> Subject: [PATCH V6 3/5] I2C: add i2c support for Pantheon platform
>>
>> Add i2c support to dkb board with pantheon soc.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> V2:
>> NO CHANGE
>>
>> V3:
>> clean code sytle issue
>> Add i2c clock enable code include in I2C configure define block
>>
>> V4:
>> make i2c definition included in the ifdef
>>
>> V5:
>> NO CHANGE
>>
>> V6:
>> Move the CONFIG_CMD_I2C define place
>>
>> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ?| ? 12 ++++++++++++
>> ?arch/arm/include/asm/arch-pantheon/cpu.h | ? ?4 +++-
>> ?arch/arm/include/asm/arch-pantheon/mfp.h | ? ?6 ++++--
>> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ?| ? ?4 ++++
>> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ?| ? 13 +++++++++++++
>> ?5 files changed, 36 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> index 9ddc77c..8b2eafa 100644
>> --- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> +++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
>> @@ -59,6 +59,12 @@ int arch_cpu_init(void)
>> ? ? ? /* Enable GPIO clock */
>> ? ? ? writel(APBC_APBCLK, &apbclkres->gpio);
>>
>> +#ifdef CONFIG_I2C_MV
>> + ? ? /* Enable I2C clock */
>> + ? ? writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
>> + ? ? writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
>> +#endif
>> +
>> ? ? ? icache_enable();
>>
>> ? ? ? return 0;
>> @@ -76,3 +82,9 @@ int print_cpuinfo(void)
>> ? ? ? return 0;
>> ?}
>> ?#endif
>> +
>> +#ifdef CONFIG_I2C_MV
>> +void i2c_clk_enable(void)
>> +{
>> +}
>> +#endif
>> diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h
>> b/arch/arm/include/asm/arch-pantheon/cpu.h
>> index 30f4393..60955c5 100644
>> --- a/arch/arm/include/asm/arch-pantheon/cpu.h
>> +++ b/arch/arm/include/asm/arch-pantheon/cpu.h
>> @@ -50,7 +50,9 @@ struct panthapb_registers {
>> ? ? ? u32 uart0; ? ? ?/*0x000*/
>> ? ? ? u32 uart1; ? ? ?/*0x004*/
>> ? ? ? u32 gpio; ? ? ? /*0x008*/
>> - ? ? u8 pad0[0x034 - 0x08 - 4];
>> + ? ? u8 pad0[0x02c - 0x08 - 4];
>> + ? ? u32 twsi; ? ? ? /*0x02c*/
>> + ? ? u8 pad1[0x034 - 0x2c - 4];
>> ? ? ? u32 timers; ? ? /*0x034*/
>> ?};
>>
>> diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h
>> b/arch/arm/include/asm/arch-pantheon/mfp.h
>> index fb291cf..e939196 100644
>> --- a/arch/arm/include/asm/arch-pantheon/mfp.h
>> +++ b/arch/arm/include/asm/arch-pantheon/mfp.h
>> @@ -32,8 +32,10 @@
>> ? * offset, pull,pF, drv,dF, edge,eF ,afn,aF
>> ? */
>> ?/* UART2 */
>> -#define MFP47_UART2_RXD ? ? ? ? ? ? ?MFP_REG(0x198) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM
>> -#define MFP48_UART2_TXD ? ? ? ? ? ? ?MFP_REG(0x19c) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM
>> +#define MFP47_UART2_RXD ? ? ? ? ? ? ?(MFP_REG(0x198) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM)
>> +#define MFP48_UART2_TXD ? ? ? ? ? ? ?(MFP_REG(0x19c) | MFP_AF6 |
>> MFP_DRIVE_MEDIUM)
>> +#define MFP53_CI2C_SCL ? ? ? ? ? ? ? (MFP_REG(0x1b0) | MFP_AF2 |
>> MFP_DRIVE_MEDIUM)
>> +#define MFP54_CI2C_SDA ? ? ? ? ? ? ? (MFP_REG(0x1b4) | MFP_AF2 |
>> MFP_DRIVE_MEDIUM)
>>
>> ?/* More macros can be defined here... */
>>
>> diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
>> index 72a2d2a..00f73e7 100644
>> --- a/board/Marvell/dkb/dkb.c
>> +++ b/board/Marvell/dkb/dkb.c
>> @@ -36,6 +36,10 @@ int board_early_init_f(void)
>> ? ? ? ? ? ? ? MFP47_UART2_RXD,
>> ? ? ? ? ? ? ? MFP48_UART2_TXD,
>>
>> + ? ? ? ? ? ? /* I2C */
>> + ? ? ? ? ? ? MFP53_CI2C_SCL,
>> + ? ? ? ? ? ? MFP54_CI2C_SDA,
>> +
>> ? ? ? ? ? ? ? MFP_EOC ? ? ? ? /*End of configureation*/
>> ? ? ? };
>> ? ? ? /* configure MFP's */
>> diff --git a/include/configs/dkb.h b/include/configs/dkb.h
>> index 638af5e..c893a9d 100644
>> --- a/include/configs/dkb.h
>> +++ b/include/configs/dkb.h
>> @@ -47,6 +47,7 @@
>> ?#define CONFIG_SYS_NO_FLASH ? ? ? ? ?/* Declare no flash (NOR/SPI) */
>> ?#include <config_cmd_default.h>
>> ?#define CONFIG_CMD_AUTOSCRIPT
>> +#define CONFIG_CMD_I2C
>> ?#undef CONFIG_CMD_NET
>> ?#undef CONFIG_CMD_NFS
>> ?/*
>> @@ -56,6 +57,18 @@
>> ?#include "mv-common.h"
>>
>> ?#undef CONFIG_ARCH_MISC_INIT
>
>
>> +
>> +/*
>> + * I2C definition
>> + */
>> +#ifdef CONFIG_CMD_I2C
>> +#define CONFIG_I2C_MV ? ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_PXA_I2C_REG ? ? ? ? ? 0xd4011000
>
> PXA looks invalid reference here, should be MV.
>
>> +#define CONFIG_HARD_I2C ? ? ? ? ? ? ? ? ? ? ?1
>> +#define CONFIG_SYS_I2C_SPEED ? ? ? ? 0
>> +#define CONFIG_SYS_I2C_SLAVE ? ? ? ? 0xfe
>> +#endif
>
> Sorry being not reported earlier.
> But this #ifdefed code should be in mv-common.h or <arch/config.h> so that it can be shared across all the boards supported by the same SoC or IP.

I'd prefer to put it into <arch/config.h>. Would do this change for next post.

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 0/5] add i2c support to pantheon and aramada100
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
@ 2011-04-03 13:00               ` Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
                                   ` (6 more replies)
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 1/5] pxa: move i2c driver to the common place Lei Wen
                                 ` (4 subsequent siblings)
  5 siblings, 7 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-03 13:00 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

V3:
Clean the code sytle issue

V4:
add and* and or* to make set bit operation generic
Also make i2c definition included in the ifdef

V5:
Fix code style issue of the first patch
 
V6:
Seperate the and* and or* patch out of the patch set
Move CONFIG_CMD_I2C define place

V7:
Fix comments style
Make global change from PXA to MV
Move i2c config setting to <arch/config>

Lei Wen (5):
  pxa: move i2c driver to the common place
  mv_i2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mv_i2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c       |   16 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c        |   12 +
 arch/arm/cpu/pxa/Makefile                    |    1 -
 arch/arm/cpu/pxa/cpu.c                       |   10 +
 arch/arm/cpu/pxa/i2c.c                       |  469 -------------------------
 arch/arm/include/asm/arch-armada100/config.h |   12 +
 arch/arm/include/asm/arch-armada100/mfp.h    |   40 ++-
 arch/arm/include/asm/arch-pantheon/config.h  |   10 +
 arch/arm/include/asm/arch-pantheon/cpu.h     |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h     |    6 +-
 arch/arm/include/asm/arch-pxa/pxa-regs.h     |   56 ---
 board/Marvell/aspenite/aspenite.c            |    5 +
 board/Marvell/dkb/dkb.c                      |    4 +
 board/innokom/innokom.c                      |    9 +-
 drivers/i2c/Makefile                         |    1 +
 drivers/i2c/mv_i2c.c                         |  481 ++++++++++++++++++++++++++
 drivers/i2c/mv_i2c.h                         |   83 +++++
 include/configs/aspenite.h                   |    1 +
 include/configs/dkb.h                        |    2 +
 include/configs/innokom.h                    |    2 +
 include/configs/xm250.h                      |    2 +
 21 files changed, 671 insertions(+), 555 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c
 create mode 100644 drivers/i2c/mv_i2c.h

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 1/5] pxa: move i2c driver to the common place
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
@ 2011-04-03 13:00               ` Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
                                 ` (3 subsequent siblings)
  5 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-03 13:00 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

V4:
V5:
V6:
V7:
NO CHANGE

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 455 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
new file mode 100644
index 0000000..09756a4
--- /dev/null
+++ b/drivers/i2c/mv_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+/*
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void)
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
+{
+	int timeout = 10000;
+
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch (msg->direction) {
+	case I2C_WRITE:
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+	default:
+		goto transfer_error_illegal_param;
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
+		i2c_reset();
+		return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+/*
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+		if (len == 0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if (i2c_transfer(&msg))
+			return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+		buffer++;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+/*
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+
+		if (len == 0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 2/5] mv_i2c: use structure to replace the direclty define
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 1/5] pxa: move i2c driver to the common place Lei Wen
@ 2011-04-03 13:00               ` Lei Wen
  2011-04-03 13:27                 ` Wolfgang Denk
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 3/5] I2C: add i2c support for Pantheon platform Lei Wen
                                 ` (2 subsequent siblings)
  5 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-04-03 13:00 UTC (permalink / raw)
  To: u-boot

Add i2c_clk_enable in the cpu specific code, since previous platform it,
while new platform don't need. In the pantheon and armada100 platform,
this function is defined as NULL one.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue

V4:
V5:
V6:
NO CHANGE

V7:
Fix comments style
Make global change from PXA to MV

 arch/arm/cpu/pxa/cpu.c                   |   10 ++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 ------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mv_i2c.c                     |  141 ++++++++++++++---------------
 drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 7 files changed, 164 insertions(+), 137 deletions(-)
 create mode 100644 drivers/i2c/mv_i2c.h

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..9970a4b 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,13 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+	/* set the global I2C clock on */
+#ifdef CONFIG_CPU_MONAHANS
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 09756a4..7ea66d4 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -34,24 +37,8 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
-			| ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
+#include "mv_i2c.h"
 
 #ifdef DEBUG_I2C
 #define PRINTD(x) printf x
@@ -59,20 +46,6 @@
 #define PRINTD(x)
 #endif
 
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
 /* All transfers are described by this data structure */
 struct i2c_msg {
 	u8 condition;
@@ -81,27 +54,37 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct mv_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct mv_i2c *base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
+
 /*
- * i2c_pxa_reset: - reset the host controller
+ * i2c_reset: - reset the host controller
  *
  */
 static void i2c_reset(void)
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
+	writel(readl(&base->icr) | ICR_UR, &base->icr);	  /* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
+
+	i2c_clk_enable();
+
+	writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr); /* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */
+	writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */
 	udelay(100);
 }
 
@@ -114,13 +97,15 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 10000;
+	int timeout = 1000, isr;
 
-	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+	do {
+		isr = readl(&base->isr);
 		udelay(10);
 		if (timeout-- < 0)
 			return 0;
-	}
+	} while (((isr & set_mask) != set_mask)
+		|| ((isr & cleared_mask) != 0));
 
 	return 1;
 }
@@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		writel(readl(&base->icr) & ~ICR_START, &base->icr);
+		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			writel(readl(&base->icr) | ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			writel(readl(&base->icr) | ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
+		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
+		writel(readl(&base->icr) | ICR_TB, &base->icr);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		writel(readl(&base->isr) | ISR_ITE, &base->isr);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(readl(&base->icr) & ~ICR_START, &base->icr);
+		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			writel(readl(&base->icr) | ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			writel(readl(&base->icr) | ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
+		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
+		writel(readl(&base->icr) | ICR_TB, &base->icr);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
+		writel(readl(&base->isr) | ISR_IRF, &base->isr);
 		break;
 	default:
 		goto transfer_error_illegal_param;
@@ -252,10 +236,21 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	u32 icr;
+	/*
+	 * call board specific i2c bus reset routine before accessing the
+	 * environment, which might be in a chip on that bus. For details
+	 * about this problem see doc/I2C_Edge_Conditions.
+	 *
+	 * disable I2C controller first, otherwhise it thinks we want to
+	 * talk to the slave port...
+	 */
+	icr = readl(&base->icr);
+	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
new file mode 100644
index 0000000..41af0d9
--- /dev/null
+++ b/drivers/i2c/mv_i2c.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Inc, <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MV_I2C_H_
+#define _MV_I2C_H_
+extern void i2c_clk_enable(void);
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+		| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
+
+#endif
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..744d65c 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_MV_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..232baf3 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_MV_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 3/5] I2C: add i2c support for Pantheon platform
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
                                 ` (2 preceding siblings ...)
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-04-03 13:00               ` Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 4/5] I2C: mv_i2c: add multi bus support Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  5 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-03 13:00 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition included in the ifdef

V5:
NO CHANGE

V6:
Move the CONFIG_CMD_I2C define place

V7:
Make global change from PXA to MV
move i2c setting to <arch/config>

 arch/arm/cpu/arm926ejs/pantheon/cpu.c       |   12 ++++++++++++
 arch/arm/include/asm/arch-pantheon/config.h |   10 ++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h    |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h    |    6 ++++--
 board/Marvell/dkb/dkb.c                     |    4 ++++
 include/configs/dkb.h                       |    2 ++
 6 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..8b2eafa 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,12 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+#endif
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +82,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/config.h b/arch/arm/include/asm/arch-pantheon/config.h
index 710b386..5658592 100644
--- a/arch/arm/include/asm/arch-pantheon/config.h
+++ b/arch/arm/include/asm/arch-pantheon/config.h
@@ -34,5 +34,15 @@
 #define MV_UART_CONSOLE_BASE	PANTHEON_UART1_BASE
 #define CONFIG_SYS_NS16550_IER	(1 << 6)	/* Bit 6 in UART_IER register
 						represents UART Unit Enable */
+/*
+ * I2C definition
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_MV_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+#endif
 
 #endif /* _PANTHEON_CONFIG_H */
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..e939196 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -32,8 +32,10 @@
  * offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..b400d0a 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -47,6 +47,7 @@
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
 #include <config_cmd_default.h>
 #define CONFIG_CMD_AUTOSCRIPT
+#define CONFIG_CMD_I2C
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
 /*
@@ -56,6 +57,7 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 4/5] I2C: mv_i2c: add multi bus support
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
                                 ` (3 preceding siblings ...)
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 3/5] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-04-03 13:00               ` Lei Wen
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 5/5] I2C: add i2c support for Armada100 platform Lei Wen
  5 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-03 13:00 UTC (permalink / raw)
  To: u-boot

Add the ability to support multiple i2c bus for mv_i2c

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
V6:
NO CHANGE

V7:
Make global change from PXA to MV

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 7ea66d4..dcbe1ae 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -66,7 +66,35 @@ struct mv_i2c {
 	u32 isar;
 };
 
-static struct mv_i2c *base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
+static struct mv_i2c *base;
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
+static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
+static unsigned int current_bus;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_MV_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct mv_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /*
  * i2c_reset: - reset the host controller
@@ -235,6 +263,12 @@ i2c_transfer_finish:
 /* ------------------------------------------------------------------------ */
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct mv_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/*
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 5/5] I2C: add i2c support for Armada100 platform
  2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
                                 ` (4 preceding siblings ...)
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 4/5] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-04-03 13:00               ` Lei Wen
  5 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-03 13:00 UTC (permalink / raw)
  To: u-boot

Add i2c support to aspenite board with Armada100 soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
NO CHANGE

V6:
Move the CONFIG_CMD_I2C define place

V7:
Make global change from PXA to MV
move i2c setting to <arch/config>

 arch/arm/cpu/arm926ejs/armada100/cpu.c       |   16 ++++++++++
 arch/arm/include/asm/arch-armada100/config.h |   12 ++++++++
 arch/arm/include/asm/arch-armada100/mfp.h    |   40 ++++++++++++++-----------
 board/Marvell/aspenite/aspenite.c            |    5 +++
 include/configs/aspenite.h                   |    1 +
 5 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..c21938e 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,16 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +100,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/config.h b/arch/arm/include/asm/arch-armada100/config.h
index d804002..1126b38 100644
--- a/arch/arm/include/asm/arch-armada100/config.h
+++ b/arch/arm/include/asm/arch-armada100/config.h
@@ -40,5 +40,17 @@
 #define MV_UART_CONSOLE_BASE	ARMD1_UART1_BASE
 #define CONFIG_SYS_NS16550_IER	(1 << 6)	/* Bit 6 in UART_IER register
 						represents UART Unit Enable */
+/*
+ * I2C definition
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV		1
+#define CONFIG_MV_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_MV_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+#endif
 
 #endif /* _ARMD1_CONFIG_H */
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..73783a7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -37,28 +37,32 @@
  * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART1 */
-#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART3 */
-#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+
+/* I2c */
+#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..1619db5 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -52,6 +52,7 @@
  */
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
 #include <config_cmd_default.h>
+#define CONFIG_CMD_I2C
 #define CONFIG_CMD_AUTOSCRIPT
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define
  2011-04-03 11:30                 ` Lei Wen
@ 2011-04-03 13:21                   ` Wolfgang Denk
  0 siblings, 0 replies; 123+ messages in thread
From: Wolfgang Denk @ 2011-04-03 13:21 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <BANLkTinqDkchrug8GAo2U6LMA0mKrfdb2Q@mail.gmail.com> you wrote:
> 
> >> @@ -114,13 +97,15 @@ static void i2c_reset(void)
> >>  static int i2c_isr_set_cleared(unsigned long set_mask,
> >>                              unsigned long>  cleared_mask)
> >>  {
> >> -     int timeout = 10000;
> >> +     int timeout = 1000, isr;
> >
> > Is this done purposely? Or reducing timeout value from 10000 to 1000 has > some meaning?
>
> You may notice original comment above this function is timeout if (no
> match within 10 ms).
> So the 10ms is 1000*10us, not the 10000*10us. In this patch I correct
> this to match its comments.

Please split this fix (and all similar changes) out into separate
patches, explain what you are doing and why in the commit messages,
and submit separately.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Q:  How do you play religious roulette?
A:  You stand around in a circle  and  blaspheme  and  see  who  gets
    struck by lightning first.

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V7 2/5] mv_i2c: use structure to replace the direclty define
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-04-03 13:27                 ` Wolfgang Denk
  0 siblings, 0 replies; 123+ messages in thread
From: Wolfgang Denk @ 2011-04-03 13:27 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <1301835656-20512-3-git-send-email-leiwen@marvell.com> you wrote:
> Add i2c_clk_enable in the cpu specific code, since previous platform it,
> while new platform don't need. In the pantheon and armada100 platform,
> this function is defined as NULL one.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
...
> @@ -114,13 +97,15 @@ static void i2c_reset(void)
>  static int i2c_isr_set_cleared(unsigned long set_mask,
>  			       unsigned long cleared_mask)
>  {
> -	int timeout = 10000;
> +	int timeout = 1000, isr;

As mentioned before: such fixes must be split off into separate
patches and suent independent from this patch series.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Unser Kopf ist rund, damit das Denken die Richtung wechseln kann.
                                                   -- Francis Picabia

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
@ 2011-04-05  8:00                 ` Lei Wen
  2011-04-07 13:29                   ` Prafulla Wadaskar
                                     ` (2 more replies)
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place Lei Wen
                                   ` (5 subsequent siblings)
  6 siblings, 3 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:00 UTC (permalink / raw)
  To: u-boot

V2:
rename the previous pxa_i2c to mvi2c, since this driver would be shared
by many other Marvell platforms.

V3:
Clean the code sytle issue

V4:
add and* and or* to make set bit operation generic
Also make i2c definition included in the ifdef

V5:
Fix code style issue of the first patch
 
V6:
Seperate the and* and or* patch out of the patch set
Move CONFIG_CMD_I2C define place

V7:
Fix comments style
Make global change from PXA to MV
Move i2c config setting to <arch/config>

V8:
Seperate timeout fix patch out

Lei Wen (6):
  pxa: move i2c driver to the common place
  mv_i2c: fix timeout value to be consistent with comments
  mv_i2c: use structure to replace the direclty define
  I2C: add i2c support for Pantheon platform
  I2C: mv_i2c: add multi bus support
  I2C: add i2c support for Armada100 platform

 arch/arm/cpu/arm926ejs/armada100/cpu.c       |   16 +
 arch/arm/cpu/arm926ejs/pantheon/cpu.c        |   12 +
 arch/arm/cpu/pxa/Makefile                    |    1 -
 arch/arm/cpu/pxa/cpu.c                       |   10 +
 arch/arm/cpu/pxa/i2c.c                       |  469 -------------------------
 arch/arm/include/asm/arch-armada100/config.h |   12 +
 arch/arm/include/asm/arch-armada100/mfp.h    |   40 ++-
 arch/arm/include/asm/arch-pantheon/config.h  |   10 +
 arch/arm/include/asm/arch-pantheon/cpu.h     |    4 +-
 arch/arm/include/asm/arch-pantheon/mfp.h     |    6 +-
 arch/arm/include/asm/arch-pxa/pxa-regs.h     |   56 ---
 board/Marvell/aspenite/aspenite.c            |    5 +
 board/Marvell/dkb/dkb.c                      |    4 +
 board/innokom/innokom.c                      |    9 +-
 drivers/i2c/Makefile                         |    1 +
 drivers/i2c/mv_i2c.c                         |  481 ++++++++++++++++++++++++++
 drivers/i2c/mv_i2c.h                         |   83 +++++
 include/configs/aspenite.h                   |    1 +
 include/configs/dkb.h                        |    2 +
 include/configs/innokom.h                    |    2 +
 include/configs/xm250.h                      |    2 +
 21 files changed, 671 insertions(+), 555 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c
 create mode 100644 drivers/i2c/mv_i2c.h

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
@ 2011-04-05  8:00                 ` Lei Wen
  2011-04-20 22:32                   ` Wolfgang Denk
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 2/6] mv_i2c: fix timeout value to be consistent with comments Lei Wen
                                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:00 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

V4:
V5:
V6:
V7:
V8:
NO CHANGE

 arch/arm/cpu/pxa/Makefile |    1 -
 arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
 drivers/i2c/Makefile      |    1 +
 drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
 include/configs/innokom.h |    1 +
 include/configs/xm250.h   |    1 +
 6 files changed, 455 insertions(+), 470 deletions(-)
 delete mode 100644 arch/arm/cpu/pxa/i2c.c
 create mode 100644 drivers/i2c/mv_i2c.c

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/arch/arm/cpu/pxa/i2c.c
deleted file mode 100644
index 7aa49ae..0000000
--- a/arch/arm/cpu/pxa/i2c.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * (C) Copyright 2000
- * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
- *
- * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * (C) Copyright 2003 Pengutronix e.K.
- * Robert Schwebel <r.schwebel@pengutronix.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
- * Back ported to the 8xx platform (from the 8260 platform) by
- * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
- */
-
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
-#include <common.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
-#include <i2c.h>
-
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
-
-#ifdef DEBUG_I2C
-#define PRINTD(x) printf x
-#else
-#define PRINTD(x)
-#endif
-
-
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
-/* All transfers are described by this data structure */
-struct i2c_msg {
-	u8 condition;
-	u8 acknack;
-	u8 direction;
-	u8 data;
-};
-
-
-/**
- * i2c_pxa_reset: - reset the host controller
- *
- */
-
-static void i2c_reset( void )
-{
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
-	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
-	udelay(100);
-}
-
-
-/**
- * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
- *	                  are set and cleared
- *
- * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
- */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
-{
-	int timeout = 10000;
-
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
-	}
-
-	return 1;
-}
-
-
-/**
- * i2c_transfer: - Transfer one byte over the i2c bus
- *
- * This function can tranfer a byte over the i2c bus in both directions.
- * It is used by the public API functions.
- *
- * @return:  0: transfer successful
- *          -1: message is empty
- *          -2: transmit timeout
- *          -3: ACK missing
- *          -4: receive timeout
- *          -5: illegal parameters
- *          -6: bus is busy and couldn't be aquired
- */
-int i2c_transfer(struct i2c_msg *msg)
-{
-	int ret;
-
-	if (!msg)
-		goto transfer_error_msg_empty;
-
-	switch(msg->direction) {
-
-	case I2C_WRITE:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
-			goto transfer_error_transmit_timeout;
-
-		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
-
-		/* wait for ACK from slave */
-		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
-				goto transfer_error_ack_missing;
-		break;
-
-	case I2C_READ:
-
-		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
-			goto transfer_error_bus_busy;
-
-		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
-		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
-		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
-
-		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
-			goto transfer_error_receive_timeout;
-
-		msg->data = readl(IDBR);
-
-		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
-		break;
-
-	default:
-
-		goto transfer_error_illegal_param;
-
-	}
-
-	return 0;
-
-transfer_error_msg_empty:
-		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
-		ret = -1; goto i2c_transfer_finish;
-
-transfer_error_transmit_timeout:
-		PRINTD(("i2c_transfer: error: transmit timeout\n"));
-		ret = -2; goto i2c_transfer_finish;
-
-transfer_error_ack_missing:
-		PRINTD(("i2c_transfer: error: ACK missing\n"));
-		ret = -3; goto i2c_transfer_finish;
-
-transfer_error_receive_timeout:
-		PRINTD(("i2c_transfer: error: receive timeout\n"));
-		ret = -4; goto i2c_transfer_finish;
-
-transfer_error_illegal_param:
-		PRINTD(("i2c_transfer: error: illegal parameters\n"));
-		ret = -5; goto i2c_transfer_finish;
-
-transfer_error_bus_busy:
-		PRINTD(("i2c_transfer: error: bus is busy\n"));
-		ret = -6; goto i2c_transfer_finish;
-
-i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
-		i2c_reset();
-		return ret;
-
-}
-
-/* ------------------------------------------------------------------------ */
-/* API Functions                                                            */
-/* ------------------------------------------------------------------------ */
-
-void i2c_init(int speed, int slaveaddr)
-{
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
-	i2c_init_board();
-#endif
-}
-
-
-/**
- * i2c_probe: - Test if a chip answers for a given i2c address
- *
- * @chip:	address of the chip which is searched for
- * @return:	0 if a chip was found, -1 otherwhise
- */
-
-int i2c_probe(uchar chip)
-{
-	struct i2c_msg msg;
-
-	i2c_reset();
-
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
-
-	msg.condition = I2C_COND_STOP;
-	msg.acknack   = I2C_ACKNAK_SENDNAK;
-	msg.direction = I2C_READ;
-	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
-
-	return 0;
-}
-
-
-/**
- * i2c_read: - Read multiple bytes from an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be read
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to write the data
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
-
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* dummy chip address write */
-	PRINTD(("i2c_read: dummy chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
-	}
-
-
-	/* start read sequence */
-	PRINTD(("i2c_read: start read sequence\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
-
-	/* read bytes; send NACK@last byte */
-	while (len--) {
-
-		if (len==0) {
-			msg.condition = I2C_COND_STOP;
-			msg.acknack   = I2C_ACKNAK_SENDNAK;
-		} else {
-			msg.condition = I2C_COND_NORMAL;
-			msg.acknack   = I2C_ACKNAK_SENDACK;
-		}
-
-		msg.direction = I2C_READ;
-		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
-
-		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-		buffer++;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-}
-
-
-/**
- * i2c_write: -  Write multiple bytes to an i2c device
- *
- * The higher level routines take into account that this function is only
- * called with len < page length of the device (see configuration file)
- *
- * @chip:	address of the chip which is to be written
- * @addr:	i2c data address within the chip
- * @alen:	length of the i2c data address (1..2 bytes)
- * @buffer:	where to find the data to be written
- * @len:	how much byte do we want to read
- * @return:	0 in case of success
- */
-
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	struct i2c_msg msg;
-	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
-
-	i2c_reset();
-
-	/* chip address write */
-	PRINTD(("i2c_write: chip address write\n"));
-	msg.condition = I2C_COND_START;
-	msg.acknack   = I2C_ACKNAK_WAITACK;
-	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
-
-	/*
-	 * send memory address bytes;
-	 * alen defines how much bytes we have to send.
-	 */
-	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
-	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
-	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
-
-	while (--alen >= 0) {
-
-		PRINTD(("i2c_write: send memory word address\n"));
-		msg.condition = I2C_COND_NORMAL;
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
-	}
-
-	/* write bytes; send NACK at last byte */
-	while (len--) {
-
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
-			msg.condition = I2C_COND_STOP;
-		else
-			msg.condition = I2C_COND_NORMAL;
-
-		msg.acknack   = I2C_ACKNAK_WAITACK;
-		msg.direction = I2C_WRITE;
-		msg.data      = *(buffer++);
-
-		if (i2c_transfer(&msg)) return -1;
-
-	}
-
-	i2c_reset();
-
-	return 0;
-
-}
-
-#endif	/* CONFIG_HARD_I2C */
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
new file mode 100644
index 0000000..09756a4
--- /dev/null
+++ b/drivers/i2c/mv_i2c.c
@@ -0,0 +1,452 @@
+/*
+ * (C) Copyright 2000
+ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio at tin.it
+ *
+ * (C) Copyright 2000 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2003 Pengutronix e.K.
+ * Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Back ported to the 8xx platform (from the 8260 platform) by
+ * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_HARD_I2C
+
+/*
+ *	- CONFIG_SYS_I2C_SPEED
+ *	- I2C_PXA_SLAVE_ADDR
+ */
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/pxa-regs.h>
+#include <i2c.h>
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+
+#ifdef DEBUG_I2C
+#define PRINTD(x) printf x
+#else
+#define PRINTD(x)
+#endif
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+/* All transfers are described by this data structure */
+struct i2c_msg {
+	u8 condition;
+	u8 acknack;
+	u8 direction;
+	u8 data;
+};
+
+/*
+ * i2c_pxa_reset: - reset the host controller
+ *
+ */
+static void i2c_reset(void)
+{
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	udelay(100);
+	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
+#ifdef CONFIG_CPU_MONAHANS
+	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else /* CONFIG_CPU_MONAHANS */
+	/* set the global I2C clock on */
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
+	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
+	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
+	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	udelay(100);
+}
+
+/*
+ * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
+ *	                  are set and cleared
+ *
+ * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
+ */
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
+{
+	int timeout = 10000;
+
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
+	}
+
+	return 1;
+}
+
+/*
+ * i2c_transfer: - Transfer one byte over the i2c bus
+ *
+ * This function can tranfer a byte over the i2c bus in both directions.
+ * It is used by the public API functions.
+ *
+ * @return:  0: transfer successful
+ *          -1: message is empty
+ *          -2: transmit timeout
+ *          -3: ACK missing
+ *          -4: receive timeout
+ *          -5: illegal parameters
+ *          -6: bus is busy and couldn't be aquired
+ */
+int i2c_transfer(struct i2c_msg *msg)
+{
+	int ret;
+
+	if (!msg)
+		goto transfer_error_msg_empty;
+
+	switch (msg->direction) {
+	case I2C_WRITE:
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start transmission */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(msg->data, IDBR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* transmit register empty? */
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
+			goto transfer_error_transmit_timeout;
+
+		/* clear 'transmit empty' state */
+		writel(readl(ISR) | ISR_ITE, ISR);
+
+		/* wait for ACK from slave */
+		if (msg->acknack == I2C_ACKNAK_WAITACK)
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
+				goto transfer_error_ack_missing;
+		break;
+
+	case I2C_READ:
+
+		/* check if bus is not busy */
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
+			goto transfer_error_bus_busy;
+
+		/* start receive */
+		writel(readl(ICR) & ~ICR_START, ICR);
+		writel(readl(ICR) & ~ICR_STOP, ICR);
+		if (msg->condition == I2C_COND_START)
+			writel(readl(ICR) | ICR_START, ICR);
+		if (msg->condition == I2C_COND_STOP)
+			writel(readl(ICR) | ICR_STOP, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDNAK)
+			writel(readl(ICR) | ICR_ACKNAK, ICR);
+		if (msg->acknack == I2C_ACKNAK_SENDACK)
+			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
+		writel(readl(ICR) & ~ICR_ALDIE, ICR);
+		writel(readl(ICR) | ICR_TB, ICR);
+
+		/* receive register full? */
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
+			goto transfer_error_receive_timeout;
+
+		msg->data = readl(IDBR);
+
+		/* clear 'receive empty' state */
+		writel(readl(ISR) | ISR_IRF, ISR);
+
+		break;
+	default:
+		goto transfer_error_illegal_param;
+	}
+
+	return 0;
+
+transfer_error_msg_empty:
+		PRINTD(("i2c_transfer: error: 'msg' is empty\n"));
+		ret = -1; goto i2c_transfer_finish;
+
+transfer_error_transmit_timeout:
+		PRINTD(("i2c_transfer: error: transmit timeout\n"));
+		ret = -2; goto i2c_transfer_finish;
+
+transfer_error_ack_missing:
+		PRINTD(("i2c_transfer: error: ACK missing\n"));
+		ret = -3; goto i2c_transfer_finish;
+
+transfer_error_receive_timeout:
+		PRINTD(("i2c_transfer: error: receive timeout\n"));
+		ret = -4; goto i2c_transfer_finish;
+
+transfer_error_illegal_param:
+		PRINTD(("i2c_transfer: error: illegal parameters\n"));
+		ret = -5; goto i2c_transfer_finish;
+
+transfer_error_bus_busy:
+		PRINTD(("i2c_transfer: error: bus is busy\n"));
+		ret = -6; goto i2c_transfer_finish;
+
+i2c_transfer_finish:
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
+		i2c_reset();
+		return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+/* API Functions                                                            */
+/* ------------------------------------------------------------------------ */
+void i2c_init(int speed, int slaveaddr)
+{
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+	/* call board specific i2c bus reset routine before accessing the   */
+	/* environment, which might be in a chip on that bus. For details   */
+	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	i2c_init_board();
+#endif
+}
+
+/*
+ * i2c_probe: - Test if a chip answers for a given i2c address
+ *
+ * @chip:	address of the chip which is searched for
+ * @return:	0 if a chip was found, -1 otherwhise
+ */
+int i2c_probe(uchar chip)
+{
+	struct i2c_msg msg;
+
+	i2c_reset();
+
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1) + 1;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	msg.condition = I2C_COND_STOP;
+	msg.acknack   = I2C_ACKNAK_SENDNAK;
+	msg.direction = I2C_READ;
+	msg.data      = 0x00;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be read
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to write the data
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* dummy chip address write */
+	PRINTD(("i2c_read: dummy chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	/*addr &= ((1 << CONFIG_SYS_EEPROM_PAGE_WRITE_BITS)-1); */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* start read sequence */
+	PRINTD(("i2c_read: start read sequence\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data      = (chip << 1);
+	msg.data     |= 0x01;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/* read bytes; send NACK@last byte */
+	while (len--) {
+		if (len == 0) {
+			msg.condition = I2C_COND_STOP;
+			msg.acknack   = I2C_ACKNAK_SENDNAK;
+		} else {
+			msg.condition = I2C_COND_NORMAL;
+			msg.acknack   = I2C_ACKNAK_SENDACK;
+		}
+
+		msg.direction = I2C_READ;
+		msg.data      = 0x00;
+		if (i2c_transfer(&msg))
+			return -1;
+
+		*buffer = msg.data;
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+		buffer++;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+
+/*
+ * i2c_write: -  Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip:	address of the chip which is to be written
+ * @addr:	i2c data address within the chip
+ * @alen:	length of the i2c data address (1..2 bytes)
+ * @buffer:	where to find the data to be written
+ * @len:	how much byte do we want to read
+ * @return:	0 in case of success
+ */
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	struct i2c_msg msg;
+	u8 addr_bytes[3]; /* lowest...highest byte of data address */
+
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
+
+	i2c_reset();
+
+	/* chip address write */
+	PRINTD(("i2c_write: chip address write\n"));
+	msg.condition = I2C_COND_START;
+	msg.acknack   = I2C_ACKNAK_WAITACK;
+	msg.direction = I2C_WRITE;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
+
+	/*
+	 * send memory address bytes;
+	 * alen defines how much bytes we have to send.
+	 */
+	addr_bytes[0] = (u8)((addr >>  0) & 0x000000FF);
+	addr_bytes[1] = (u8)((addr >>  8) & 0x000000FF);
+	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
+
+	while (--alen >= 0) {
+		PRINTD(("i2c_write: send memory word address\n"));
+		msg.condition = I2C_COND_NORMAL;
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = addr_bytes[alen];
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	/* write bytes; send NACK at last byte */
+	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
+
+		if (len == 0)
+			msg.condition = I2C_COND_STOP;
+		else
+			msg.condition = I2C_COND_NORMAL;
+
+		msg.acknack   = I2C_ACKNAK_WAITACK;
+		msg.direction = I2C_WRITE;
+		msg.data      = *(buffer++);
+
+		if (i2c_transfer(&msg))
+			return -1;
+	}
+
+	i2c_reset();
+
+	return 0;
+}
+#endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 2/6] mv_i2c: fix timeout value to be consistent with comments
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place Lei Wen
@ 2011-04-05  8:00                 ` Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
                                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:00 UTC (permalink / raw)
  To: u-boot

The original 10000 value would be 100ms, which is not
the comments said.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
V2:
V3:
V4:
V5:
V6:
V7:
NO CHANGE

V8:
seperate timeout fix patch out

 drivers/i2c/mv_i2c.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 09756a4..562b950 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -114,7 +114,7 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 10000;
+	int timeout = 1000;
 
 	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
 		udelay(10);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 3/6] mv_i2c: use structure to replace the direclty define
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
                                   ` (2 preceding siblings ...)
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 2/6] mv_i2c: fix timeout value to be consistent with comments Lei Wen
@ 2011-04-05  8:00                 ` Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 4/6] I2C: add i2c support for Pantheon platform Lei Wen
                                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:00 UTC (permalink / raw)
  To: u-boot

Add i2c_clk_enable in the cpu specific code, since previous platform it,
while new platform don't need. In the pantheon and armada100 platform,
this function is defined as NULL one.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue

V4:
V5:
V6:
NO CHANGE

V7:
Fix comments style
Make global change from PXA to MV

V8:
seperate timeout value fix out

 arch/arm/cpu/pxa/cpu.c                   |   10 ++
 arch/arm/include/asm/arch-pxa/pxa-regs.h |   56 ------------
 board/innokom/innokom.c                  |    9 +--
 drivers/i2c/mv_i2c.c                     |  141 ++++++++++++++---------------
 drivers/i2c/mv_i2c.h                     |   83 +++++++++++++++++
 include/configs/innokom.h                |    1 +
 include/configs/xm250.h                  |    1 +
 7 files changed, 164 insertions(+), 137 deletions(-)
 create mode 100644 drivers/i2c/mv_i2c.h

diff --git a/arch/arm/cpu/pxa/cpu.c b/arch/arm/cpu/pxa/cpu.c
index 7d49cbb..9970a4b 100644
--- a/arch/arm/cpu/pxa/cpu.c
+++ b/arch/arm/cpu/pxa/cpu.c
@@ -318,3 +318,13 @@ int arch_cpu_init(void)
 	pxa_clock_setup();
 	return 0;
 }
+
+void i2c_clk_enable(void)
+{
+	/* set the global I2C clock on */
+#ifdef CONFIG_CPU_MONAHANS
+	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
+#else
+	writel(readl(CKEN) | CKEN14_I2C, CKEN);
+#endif
+}
diff --git a/arch/arm/include/asm/arch-pxa/pxa-regs.h b/arch/arm/include/asm/arch-pxa/pxa-regs.h
index 65a387f..109fdc0 100644
--- a/arch/arm/include/asm/arch-pxa/pxa-regs.h
+++ b/arch/arm/include/asm/arch-pxa/pxa-regs.h
@@ -456,62 +456,6 @@ typedef void		(*ExcpHndlr) (void) ;
 		IrSR_XMITIR_IR_MODE)
 
 /*
- * I2C registers
- */
-#define IBMR		0x40301680  /* I2C Bus Monitor Register - IBMR */
-#define IDBR		0x40301688  /* I2C Data Buffer Register - IDBR */
-#define ICR		0x40301690  /* I2C Control Register - ICR */
-#define ISR		0x40301698  /* I2C Status Register - ISR */
-#define ISAR		0x403016A0  /* I2C Slave Address Register - ISAR */
-
-#ifdef CONFIG_CPU_MONAHANS
-#define PWRIBMR		0x40f500C0  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f500C4  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f500C8  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f500CC  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f500D0  /* Power I2C Slave Address Register-ISAR */
-#else
-#define PWRIBMR		0x40f00180  /* Power I2C Bus Monitor Register-IBMR */
-#define PWRIDBR		0x40f00188  /* Power I2C Data Buffer Register-IDBR */
-#define PWRICR		0x40f00190  /* Power I2C Control Register - ICR */
-#define PWRISR		0x40f00198  /* Power I2C Status Register - ISR */
-#define PWRISAR		0x40f001A0  /* Power I2C Slave Address Register-ISAR */
-#endif
-
-/* ----- Control register bits ---------------------------------------- */
-
-#define ICR_START	0x1		/* start bit */
-#define ICR_STOP	0x2		/* stop bit */
-#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
-#define ICR_TB		0x8		/* transfer byte bit */
-#define ICR_MA		0x10		/* master abort */
-#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
-#define ICR_IUE		0x40		/* unit enable */
-#define ICR_GCD		0x80		/* general call disable */
-#define ICR_ITEIE	0x100		/* enable tx interrupts */
-#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
-#define ICR_BEIE	0x400		/* enable bus error ints */
-#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
-#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
-#define ICR_SADIE	0x2000		/* slave address detected int enable */
-#define ICR_UR		0x4000		/* unit reset */
-#define ICR_FM		0x8000		/* Fast Mode */
-
-/* ----- Status register bits ----------------------------------------- */
-
-#define ISR_RWM		0x1		/* read/write mode */
-#define ISR_ACKNAK	0x2		/* ack/nak status */
-#define ISR_UB		0x4		/* unit busy */
-#define ISR_IBB		0x8		/* bus busy */
-#define ISR_SSD		0x10		/* slave stop detected */
-#define ISR_ALD		0x20		/* arbitration loss detected */
-#define ISR_ITE		0x40		/* tx buffer empty */
-#define ISR_IRF		0x80		/* rx buffer full */
-#define ISR_GCAD	0x100		/* general call address detected */
-#define ISR_SAD		0x200		/* slave address detected */
-#define ISR_BED		0x400		/* bus error no ACK/NAK */
-
-/*
  * Serial Audio Controller
  */
 /* FIXME the audio defines collide w/ the SA1111 defines.  I don't like these
diff --git a/board/innokom/innokom.c b/board/innokom/innokom.c
index e658c35..22de7e3 100644
--- a/board/innokom/innokom.c
+++ b/board/innokom/innokom.c
@@ -45,12 +45,7 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 int i2c_init_board(void)
 {
-	int i, icr;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	icr = readl(ICR);
-	writel(readl(ICR) & ~(ICR_SCLE | ICR_IUE), ICR);
+	int i;
 
 	/* set gpio pin low _before_ we change direction to output          */
 	writel(GPIO_bit(70), GPCR(70));
@@ -63,8 +58,6 @@ int i2c_init_board(void)
 		udelay(10);
 	}
 
-	writel(icr, ICR);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index 562b950..7ea66d4 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -8,6 +8,9 @@
  * (C) Copyright 2003 Pengutronix e.K.
  * Robert Schwebel <r.schwebel@pengutronix.de>
  *
+ * (C) Copyright 2011 Marvell Inc.
+ * Lei Wen <leiwen@marvell.com>
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -34,24 +37,8 @@
 #include <asm/io.h>
 
 #ifdef CONFIG_HARD_I2C
-
-/*
- *	- CONFIG_SYS_I2C_SPEED
- *	- I2C_PXA_SLAVE_ADDR
- */
-
-#include <asm/arch/hardware.h>
-#include <asm/arch/pxa-regs.h>
 #include <i2c.h>
-
-#if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
-			| ICR_SCLE)
-#else
-#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
-#endif
-
-#define I2C_ISR_INIT		0x7FF
+#include "mv_i2c.h"
 
 #ifdef DEBUG_I2C
 #define PRINTD(x) printf x
@@ -59,20 +46,6 @@
 #define PRINTD(x)
 #endif
 
-/* Shall the current transfer have a start/stop condition? */
-#define I2C_COND_NORMAL		0
-#define I2C_COND_START		1
-#define I2C_COND_STOP		2
-
-/* Shall the current transfer be ack/nacked or being waited for it? */
-#define I2C_ACKNAK_WAITACK	1
-#define I2C_ACKNAK_SENDACK	2
-#define I2C_ACKNAK_SENDNAK	4
-
-/* Specify who shall transfer the data (master or slave) */
-#define I2C_READ		0
-#define I2C_WRITE		1
-
 /* All transfers are described by this data structure */
 struct i2c_msg {
 	u8 condition;
@@ -81,27 +54,37 @@ struct i2c_msg {
 	u8 data;
 };
 
+struct mv_i2c {
+	u32 ibmr;
+	u32 pad0;
+	u32 idbr;
+	u32 pad1;
+	u32 icr;
+	u32 pad2;
+	u32 isr;
+	u32 pad3;
+	u32 isar;
+};
+
+static struct mv_i2c *base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
+
 /*
- * i2c_pxa_reset: - reset the host controller
+ * i2c_reset: - reset the host controller
  *
  */
 static void i2c_reset(void)
 {
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
+	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
+	writel(readl(&base->icr) | ICR_UR, &base->icr);	  /* reset the unit */
 	udelay(100);
-	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
-#ifdef CONFIG_CPU_MONAHANS
-	/* | CKENB_1_PWM1 | CKENB_0_PWM0); */
-	writel(readl(CKENB) | (CKENB_4_I2C), CKENB);
-#else /* CONFIG_CPU_MONAHANS */
-	/* set the global I2C clock on */
-	writel(readl(CKEN) | CKEN14_I2C, CKEN);
-#endif
-	writel(I2C_PXA_SLAVE_ADDR, ISAR);	/* set our slave address */
-	writel(I2C_ICR_INIT, ICR);		/* set control reg values */
-	writel(I2C_ISR_INIT, ISR);		/* set clear interrupt bits */
-	writel(readl(ICR) | ICR_IUE, ICR);	/* enable unit */
+	writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
+
+	i2c_clk_enable();
+
+	writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */
+	writel(I2C_ICR_INIT, &base->icr); /* set control reg values */
+	writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */
+	writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */
 	udelay(100);
 }
 
@@ -114,13 +97,15 @@ static void i2c_reset(void)
 static int i2c_isr_set_cleared(unsigned long set_mask,
 			       unsigned long cleared_mask)
 {
-	int timeout = 1000;
+	int timeout = 1000, isr;
 
-	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+	do {
+		isr = readl(&base->isr);
 		udelay(10);
 		if (timeout-- < 0)
 			return 0;
-	}
+	} while (((isr & set_mask) != set_mask)
+		|| ((isr & cleared_mask) != 0));
 
 	return 1;
 }
@@ -153,26 +138,26 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
-		writel(msg->data, IDBR);
+		writel(readl(&base->icr) & ~ICR_START, &base->icr);
+		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
+		writel(msg->data, &base->idbr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			writel(readl(&base->icr) | ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			writel(readl(&base->icr) | ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
+		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
+		writel(readl(&base->icr) | ICR_TB, &base->icr);
 
 		/* transmit register empty? */
 		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
-		writel(readl(ISR) | ISR_ITE, ISR);
+		writel(readl(&base->isr) | ISR_ITE, &base->isr);
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
@@ -187,28 +172,27 @@ int i2c_transfer(struct i2c_msg *msg)
 			goto transfer_error_bus_busy;
 
 		/* start receive */
-		writel(readl(ICR) & ~ICR_START, ICR);
-		writel(readl(ICR) & ~ICR_STOP, ICR);
+		writel(readl(&base->icr) & ~ICR_START, &base->icr);
+		writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
 		if (msg->condition == I2C_COND_START)
-			writel(readl(ICR) | ICR_START, ICR);
+			writel(readl(&base->icr) | ICR_START, &base->icr);
 		if (msg->condition == I2C_COND_STOP)
-			writel(readl(ICR) | ICR_STOP, ICR);
+			writel(readl(&base->icr) | ICR_STOP, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDNAK)
-			writel(readl(ICR) | ICR_ACKNAK, ICR);
+			writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
 		if (msg->acknack == I2C_ACKNAK_SENDACK)
-			writel(readl(ICR) & ~ICR_ACKNAK, ICR);
-		writel(readl(ICR) & ~ICR_ALDIE, ICR);
-		writel(readl(ICR) | ICR_TB, ICR);
+			writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
+		writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
+		writel(readl(&base->icr) | ICR_TB, &base->icr);
 
 		/* receive register full? */
 		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
-		msg->data = readl(IDBR);
+		msg->data = readl(&base->idbr);
 
 		/* clear 'receive empty' state */
-		writel(readl(ISR) | ISR_IRF, ISR);
-
+		writel(readl(&base->isr) | ISR_IRF, &base->isr);
 		break;
 	default:
 		goto transfer_error_illegal_param;
@@ -252,10 +236,21 @@ i2c_transfer_finish:
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
-	/* call board specific i2c bus reset routine before accessing the   */
-	/* environment, which might be in a chip on that bus. For details   */
-	/* about this problem see doc/I2C_Edge_Conditions.                  */
+	u32 icr;
+	/*
+	 * call board specific i2c bus reset routine before accessing the
+	 * environment, which might be in a chip on that bus. For details
+	 * about this problem see doc/I2C_Edge_Conditions.
+	 *
+	 * disable I2C controller first, otherwhise it thinks we want to
+	 * talk to the slave port...
+	 */
+	icr = readl(&base->icr);
+	writel(readl(&base->icr) & ~(ICR_SCLE | ICR_IUE), &base->icr);
+
 	i2c_init_board();
+
+	writel(icr, &base->icr);
 #endif
 }
 
diff --git a/drivers/i2c/mv_i2c.h b/drivers/i2c/mv_i2c.h
new file mode 100644
index 0000000..41af0d9
--- /dev/null
+++ b/drivers/i2c/mv_i2c.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2011
+ * Marvell Inc, <www.marvell.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _MV_I2C_H_
+#define _MV_I2C_H_
+extern void i2c_clk_enable(void);
+
+/* Shall the current transfer have a start/stop condition? */
+#define I2C_COND_NORMAL		0
+#define I2C_COND_START		1
+#define I2C_COND_STOP		2
+
+/* Shall the current transfer be ack/nacked or being waited for it? */
+#define I2C_ACKNAK_WAITACK	1
+#define I2C_ACKNAK_SENDACK	2
+#define I2C_ACKNAK_SENDNAK	4
+
+/* Specify who shall transfer the data (master or slave) */
+#define I2C_READ		0
+#define I2C_WRITE		1
+
+#if (CONFIG_SYS_I2C_SPEED == 400000)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+		| ICR_SCLE)
+#else
+#define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#endif
+
+#define I2C_ISR_INIT		0x7FF
+/* ----- Control register bits ---------------------------------------- */
+
+#define ICR_START	0x1		/* start bit */
+#define ICR_STOP	0x2		/* stop bit */
+#define ICR_ACKNAK	0x4		/* send ACK(0) or NAK(1) */
+#define ICR_TB		0x8		/* transfer byte bit */
+#define ICR_MA		0x10		/* master abort */
+#define ICR_SCLE	0x20		/* master clock enable, mona SCLEA */
+#define ICR_IUE		0x40		/* unit enable */
+#define ICR_GCD		0x80		/* general call disable */
+#define ICR_ITEIE	0x100		/* enable tx interrupts */
+#define ICR_IRFIE	0x200		/* enable rx interrupts, mona: DRFIE */
+#define ICR_BEIE	0x400		/* enable bus error ints */
+#define ICR_SSDIE	0x800		/* slave STOP detected int enable */
+#define ICR_ALDIE	0x1000		/* enable arbitration interrupt */
+#define ICR_SADIE	0x2000		/* slave address detected int enable */
+#define ICR_UR		0x4000		/* unit reset */
+#define ICR_FM		0x8000		/* Fast Mode */
+
+/* ----- Status register bits ----------------------------------------- */
+
+#define ISR_RWM		0x1		/* read/write mode */
+#define ISR_ACKNAK	0x2		/* ack/nak status */
+#define ISR_UB		0x4		/* unit busy */
+#define ISR_IBB		0x8		/* bus busy */
+#define ISR_SSD		0x10		/* slave stop detected */
+#define ISR_ALD		0x20		/* arbitration loss detected */
+#define ISR_ITE		0x40		/* tx buffer empty */
+#define ISR_IRF		0x80		/* rx buffer full */
+#define ISR_GCAD	0x100		/* general call address detected */
+#define ISR_SAD		0x200		/* slave address detected */
+#define ISR_BED		0x400		/* bus error no ACK/NAK */
+
+#endif
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index 0ea73c9..744d65c 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -141,6 +141,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_MV_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index b4b940a..232baf3 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -62,6 +62,7 @@
  * I2C bus
  */
 #define CONFIG_I2C_MV			1
+#define CONFIG_MV_I2C_REG		0x40301680
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 4/6] I2C: add i2c support for Pantheon platform
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
                                   ` (3 preceding siblings ...)
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
@ 2011-04-05  8:00                 ` Lei Wen
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 5/6] I2C: mv_i2c: add multi bus support Lei Wen
  2011-04-05  8:01                 ` [U-Boot] [PATCH V8 6/6] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:00 UTC (permalink / raw)
  To: u-boot

Add i2c support to dkb board with pantheon soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code sytle issue
Add i2c clock enable code include in I2C configure define block

V4:
make i2c definition included in the ifdef

V5:
NO CHANGE

V6:
Move the CONFIG_CMD_I2C define place

V7:
Make global change from PXA to MV
move i2c setting to <arch/config>

V8:
NO CHANGE

 arch/arm/cpu/arm926ejs/pantheon/cpu.c       |   12 ++++++++++++
 arch/arm/include/asm/arch-pantheon/config.h |   10 ++++++++++
 arch/arm/include/asm/arch-pantheon/cpu.h    |    4 +++-
 arch/arm/include/asm/arch-pantheon/mfp.h    |    6 ++++--
 board/Marvell/dkb/dkb.c                     |    4 ++++
 include/configs/dkb.h                       |    2 ++
 6 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/pantheon/cpu.c b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
index 9ddc77c..8b2eafa 100644
--- a/arch/arm/cpu/arm926ejs/pantheon/cpu.c
+++ b/arch/arm/cpu/arm926ejs/pantheon/cpu.c
@@ -59,6 +59,12 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apbclkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+	writel(APBC_FNCLK | APBC_APBCLK, &apbclkres->twsi);
+#endif
+
 	icache_enable();
 
 	return 0;
@@ -76,3 +82,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-pantheon/config.h b/arch/arm/include/asm/arch-pantheon/config.h
index 710b386..5658592 100644
--- a/arch/arm/include/asm/arch-pantheon/config.h
+++ b/arch/arm/include/asm/arch-pantheon/config.h
@@ -34,5 +34,15 @@
 #define MV_UART_CONSOLE_BASE	PANTHEON_UART1_BASE
 #define CONFIG_SYS_NS16550_IER	(1 << 6)	/* Bit 6 in UART_IER register
 						represents UART Unit Enable */
+/*
+ * I2C definition
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV			1
+#define CONFIG_MV_I2C_REG		0xd4011000
+#define CONFIG_HARD_I2C			1
+#define CONFIG_SYS_I2C_SPEED		0
+#define CONFIG_SYS_I2C_SLAVE		0xfe
+#endif
 
 #endif /* _PANTHEON_CONFIG_H */
diff --git a/arch/arm/include/asm/arch-pantheon/cpu.h b/arch/arm/include/asm/arch-pantheon/cpu.h
index 30f4393..60955c5 100644
--- a/arch/arm/include/asm/arch-pantheon/cpu.h
+++ b/arch/arm/include/asm/arch-pantheon/cpu.h
@@ -50,7 +50,9 @@ struct panthapb_registers {
 	u32 uart0;	/*0x000*/
 	u32 uart1;	/*0x004*/
 	u32 gpio;	/*0x008*/
-	u8 pad0[0x034 - 0x08 - 4];
+	u8 pad0[0x02c - 0x08 - 4];
+	u32 twsi;	/*0x02c*/
+	u8 pad1[0x034 - 0x2c - 4];
 	u32 timers;	/*0x034*/
 };
 
diff --git a/arch/arm/include/asm/arch-pantheon/mfp.h b/arch/arm/include/asm/arch-pantheon/mfp.h
index fb291cf..e939196 100644
--- a/arch/arm/include/asm/arch-pantheon/mfp.h
+++ b/arch/arm/include/asm/arch-pantheon/mfp.h
@@ -32,8 +32,10 @@
  * offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x198) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x19c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP53_CI2C_SCL		(MFP_REG(0x1b0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP54_CI2C_SDA		(MFP_REG(0x1b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/dkb/dkb.c b/board/Marvell/dkb/dkb.c
index 72a2d2a..00f73e7 100644
--- a/board/Marvell/dkb/dkb.c
+++ b/board/Marvell/dkb/dkb.c
@@ -36,6 +36,10 @@ int board_early_init_f(void)
 		MFP47_UART2_RXD,
 		MFP48_UART2_TXD,
 
+		/* I2C */
+		MFP53_CI2C_SCL,
+		MFP54_CI2C_SDA,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/dkb.h b/include/configs/dkb.h
index 638af5e..b400d0a 100644
--- a/include/configs/dkb.h
+++ b/include/configs/dkb.h
@@ -47,6 +47,7 @@
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
 #include <config_cmd_default.h>
 #define CONFIG_CMD_AUTOSCRIPT
+#define CONFIG_CMD_I2C
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
 /*
@@ -56,6 +57,7 @@
 #include "mv-common.h"
 
 #undef CONFIG_ARCH_MISC_INIT
+
 /*
  * Environment variables configurations
  */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 5/6] I2C: mv_i2c: add multi bus support
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
                                   ` (4 preceding siblings ...)
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 4/6] I2C: add i2c support for Pantheon platform Lei Wen
@ 2011-04-05  8:00                 ` Lei Wen
  2011-04-05  8:01                 ` [U-Boot] [PATCH V8 6/6] I2C: add i2c support for Armada100 platform Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:00 UTC (permalink / raw)
  To: u-boot

Add the ability to support multiple i2c bus for mv_i2c

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
V6:
NO CHANGE

V7:
Make global change from PXA to MV

V8:
NO CHANGE

 drivers/i2c/mv_i2c.c |   36 +++++++++++++++++++++++++++++++++++-
 1 files changed, 35 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/mv_i2c.c b/drivers/i2c/mv_i2c.c
index acc3193..d377d7e 100644
--- a/drivers/i2c/mv_i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -66,7 +66,35 @@ struct mv_i2c {
 	u32 isar;
 };
 
-static struct mv_i2c *base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
+static struct mv_i2c *base;
+#ifdef CONFIG_I2C_MULTI_BUS
+static u32 i2c_regs[CONFIG_MV_I2C_NUM] = CONFIG_MV_I2C_REG;
+static unsigned int bus_initialized[CONFIG_MV_I2C_NUM];
+static unsigned int current_bus;
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if ((bus < 0) || (bus >= CONFIG_MV_I2C_NUM)) {
+		printf("Bad bus: %d\n", bus);
+		return -1;
+	}
+
+	base = (struct mv_i2c *)i2c_regs[bus];
+	current_bus = bus;
+
+	if (!bus_initialized[current_bus]) {
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+		bus_initialized[current_bus] = 1;
+	}
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return current_bus;
+}
+#endif
 
 /*
  * i2c_reset: - reset the host controller
@@ -235,6 +263,12 @@ i2c_transfer_finish:
 /* ------------------------------------------------------------------------ */
 void i2c_init(int speed, int slaveaddr)
 {
+#ifdef CONFIG_I2C_MULTI_BUS
+	base = (struct mv_i2c *)i2c_regs[current_bus];
+#else
+	base = (struct mv_i2c *)CONFIG_MV_I2C_REG;
+#endif
+
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
 	u32 icr;
 	/*
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 6/6] I2C: add i2c support for Armada100 platform
  2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
                                   ` (5 preceding siblings ...)
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 5/6] I2C: mv_i2c: add multi bus support Lei Wen
@ 2011-04-05  8:01                 ` Lei Wen
  6 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-05  8:01 UTC (permalink / raw)
  To: u-boot

Add i2c support to aspenite board with Armada100 soc.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
V2:
NO CHANGE

V3:
clean code style issue

V4:
V5:
NO CHANGE

V6:
Move the CONFIG_CMD_I2C define place

V7:
Make global change from PXA to MV
move i2c setting to <arch/config>

V8:
NO CHANGE

 arch/arm/cpu/arm926ejs/armada100/cpu.c       |   16 ++++++++++
 arch/arm/include/asm/arch-armada100/config.h |   12 ++++++++
 arch/arm/include/asm/arch-armada100/mfp.h    |   40 ++++++++++++++-----------
 board/Marvell/aspenite/aspenite.c            |    5 +++
 include/configs/aspenite.h                   |    1 +
 5 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index 62aa175..c21938e 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -62,6 +62,16 @@ int arch_cpu_init(void)
 	/* Enable GPIO clock */
 	writel(APBC_APBCLK, &apb1clkres->gpio);
 
+#ifdef CONFIG_I2C_MV
+	/* Enable general I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi0);
+
+	/* Enable power I2C clock */
+	writel(APBC_RST | APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+	writel(APBC_FNCLK | APBC_APBCLK, &apb1clkres->twsi1);
+#endif
+
 	/*
 	 * Enable Functional and APB clock at 14.7456MHz
 	 * for configured UART console
@@ -90,3 +100,9 @@ int print_cpuinfo(void)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_I2C_MV
+void i2c_clk_enable(void)
+{
+}
+#endif
diff --git a/arch/arm/include/asm/arch-armada100/config.h b/arch/arm/include/asm/arch-armada100/config.h
index d804002..1126b38 100644
--- a/arch/arm/include/asm/arch-armada100/config.h
+++ b/arch/arm/include/asm/arch-armada100/config.h
@@ -40,5 +40,17 @@
 #define MV_UART_CONSOLE_BASE	ARMD1_UART1_BASE
 #define CONFIG_SYS_NS16550_IER	(1 << 6)	/* Bit 6 in UART_IER register
 						represents UART Unit Enable */
+/*
+ * I2C definition
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MV		1
+#define CONFIG_MV_I2C_NUM	2
+#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_MV_I2C_REG	{0xd4011000, 0xd4025000}
+#define CONFIG_HARD_I2C		1
+#define CONFIG_SYS_I2C_SPEED	0
+#define CONFIG_SYS_I2C_SLAVE	0xfe
+#endif
 
 #endif /* _ARMD1_CONFIG_H */
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d21a79f..73783a7 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -37,28 +37,32 @@
  * 				    offset, pull,pF, drv,dF, edge,eF ,afn,aF
  */
 /* UART1 */
-#define MFP107_UART1_TXD	MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP107_UART1_RXD	MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP108_UART1_RXD	MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST
-#define MFP108_UART1_TXD	MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST
-#define MFP109_UART1_CTS	MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP109_UART1_RTS	MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_RTS	MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP110_UART1_CTS	MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_RI		MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP111_UART1_DSR	MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DTR	MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM
-#define MFP112_UART1_DCD	MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP107_UART1_TXD	(MFP_REG(0x01ac) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP107_UART1_RXD	(MFP_REG(0x01ac) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP108_UART1_RXD	(MFP_REG(0x01b0) | MFP_AF1 | MFP_DRIVE_FAST)
+#define MFP108_UART1_TXD	(MFP_REG(0x01b0) | MFP_AF2 | MFP_DRIVE_FAST)
+#define MFP109_UART1_CTS	(MFP_REG(0x01b4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP109_UART1_RTS	(MFP_REG(0x01b4) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_RTS	(MFP_REG(0x01b8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP110_UART1_CTS	(MFP_REG(0x01b8) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_RI		(MFP_REG(0x01bc) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP111_UART1_DSR	(MFP_REG(0x01bc) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DTR	(MFP_REG(0x01c0) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP112_UART1_DCD	(MFP_REG(0x01c0) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART2 */
-#define MFP47_UART2_RXD		MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP48_UART2_TXD		MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM
-#define MFP88_UART2_RXD		MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFP89_UART2_TXD		MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFP47_UART2_RXD		(MFP_REG(0x0028) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP48_UART2_TXD		(MFP_REG(0x002c) | MFP_AF6 | MFP_DRIVE_MEDIUM)
+#define MFP88_UART2_RXD		(MFP_REG(0x0160) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFP89_UART2_TXD		(MFP_REG(0x0164) | MFP_AF2 | MFP_DRIVE_MEDIUM)
 
 /* UART3 */
-#define MFPO8_UART3_RXD		MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM
-#define MFPO9_UART3_TXD		MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM
+#define MFPO8_UART3_RXD		(MFP_REG(0x06c) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+#define MFPO9_UART3_TXD		(MFP_REG(0x070) | MFP_AF2 | MFP_DRIVE_MEDIUM)
+
+/* I2c */
+#define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
+#define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
 /* More macros can be defined here... */
 
diff --git a/board/Marvell/aspenite/aspenite.c b/board/Marvell/aspenite/aspenite.c
index 046ffd6..34ac7aa 100644
--- a/board/Marvell/aspenite/aspenite.c
+++ b/board/Marvell/aspenite/aspenite.c
@@ -33,9 +33,14 @@ DECLARE_GLOBAL_DATA_PTR;
 int board_early_init_f(void)
 {
 	u32 mfp_cfg[] = {
+		/* I2C */
+		MFP105_CI2C_SDA,
+		MFP106_CI2C_SCL,
+
 		/* Enable Console on UART1 */
 		MFP107_UART1_RXD,
 		MFP108_UART1_TXD,
+
 		MFP_EOC		/*End of configureation*/
 	};
 	/* configure MFP's */
diff --git a/include/configs/aspenite.h b/include/configs/aspenite.h
index fd35f3e..1619db5 100644
--- a/include/configs/aspenite.h
+++ b/include/configs/aspenite.h
@@ -52,6 +52,7 @@
  */
 #define CONFIG_SYS_NO_FLASH		/* Declare no flash (NOR/SPI) */
 #include <config_cmd_default.h>
+#define CONFIG_CMD_I2C
 #define CONFIG_CMD_AUTOSCRIPT
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
@ 2011-04-07 13:29                   ` Prafulla Wadaskar
  2011-04-07 13:33                     ` Heiko Schocher
  2011-04-13 14:01                   ` Prafulla Wadaskar
  2011-04-13 14:38                   ` Prafulla Wadaskar
  2 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-07 13:29 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Tuesday, April 05, 2011 1:31 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
> 
> V2:
> rename the previous pxa_i2c to mvi2c, since this driver would be shared
> by many other Marvell platforms.
> 
> V3:
> Clean the code sytle issue
> 
> V4:
> add and* and or* to make set bit operation generic
> Also make i2c definition included in the ifdef
> 
> V5:
> Fix code style issue of the first patch
> 
> V6:
> Seperate the and* and or* patch out of the patch set
> Move CONFIG_CMD_I2C define place
> 
> V7:
> Fix comments style
> Make global change from PXA to MV
> Move i2c config setting to <arch/config>
> 
> V8:
> Seperate timeout fix patch out
> 
> Lei Wen (6):
>   pxa: move i2c driver to the common place
>   mv_i2c: fix timeout value to be consistent with comments
>   mv_i2c: use structure to replace the direclty define
>   I2C: add i2c support for Pantheon platform
>   I2C: mv_i2c: add multi bus support
>   I2C: add i2c support for Armada100 platform

I am okay with this patch series.
I will pull them on this week end.
Meanwhile further comments if any are welcomed.

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-07 13:29                   ` Prafulla Wadaskar
@ 2011-04-07 13:33                     ` Heiko Schocher
  0 siblings, 0 replies; 123+ messages in thread
From: Heiko Schocher @ 2011-04-07 13:33 UTC (permalink / raw)
  To: u-boot

Hello Prafulle,

Prafulla Wadaskar wrote:
> 
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Tuesday, April 05, 2011 1:31 PM
>> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
>> Tang; adrian.wenl at gmail.com
>> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
>>
>> V2:
>> rename the previous pxa_i2c to mvi2c, since this driver would be shared
>> by many other Marvell platforms.
>>
>> V3:
>> Clean the code sytle issue
>>
>> V4:
>> add and* and or* to make set bit operation generic
>> Also make i2c definition included in the ifdef
>>
>> V5:
>> Fix code style issue of the first patch
>>
>> V6:
>> Seperate the and* and or* patch out of the patch set
>> Move CONFIG_CMD_I2C define place
>>
>> V7:
>> Fix comments style
>> Make global change from PXA to MV
>> Move i2c config setting to <arch/config>
>>
>> V8:
>> Seperate timeout fix patch out
>>
>> Lei Wen (6):
>>   pxa: move i2c driver to the common place
>>   mv_i2c: fix timeout value to be consistent with comments
>>   mv_i2c: use structure to replace the direclty define
>>   I2C: add i2c support for Pantheon platform
>>   I2C: mv_i2c: add multi bus support
>>   I2C: add i2c support for Armada100 platform
> 
> I am okay with this patch series.
> I will pull them on this week end.
> Meanwhile further comments if any are welcomed.

Ah, Ok, so you can add my:

Acked-by: Heiko Schocher <hs@denx.de>

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
  2011-04-07 13:29                   ` Prafulla Wadaskar
@ 2011-04-13 14:01                   ` Prafulla Wadaskar
  2011-04-13 14:14                     ` Lei Wen
  2011-04-13 14:38                   ` Prafulla Wadaskar
  2 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-13 14:01 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Tuesday, April 05, 2011 1:31 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
> 
> V2:
> rename the previous pxa_i2c to mvi2c, since this driver would be shared
> by many other Marvell platforms.
> 
> V3:
> Clean the code sytle issue
> 
> V4:
> add and* and or* to make set bit operation generic
> Also make i2c definition included in the ifdef
> 
> V5:
> Fix code style issue of the first patch
> 
> V6:
> Seperate the and* and or* patch out of the patch set
> Move CONFIG_CMD_I2C define place
> 
> V7:
> Fix comments style
> Make global change from PXA to MV
> Move i2c config setting to <arch/config>
> 
> V8:
> Seperate timeout fix patch out
> 
> Lei Wen (6):
>   pxa: move i2c driver to the common place
>   mv_i2c: fix timeout value to be consistent with comments
>   mv_i2c: use structure to replace the direclty define
>   I2C: add i2c support for Pantheon platform
>   I2C: mv_i2c: add multi bus support
>   I2C: add i2c support for Armada100 platform
> 
>  arch/arm/cpu/arm926ejs/armada100/cpu.c       |   16 +
>  arch/arm/cpu/arm926ejs/pantheon/cpu.c        |   12 +
>  arch/arm/cpu/pxa/Makefile                    |    1 -
>  arch/arm/cpu/pxa/cpu.c                       |   10 +
>  arch/arm/cpu/pxa/i2c.c                       |  469 -------------------
> ------
>  arch/arm/include/asm/arch-armada100/config.h |   12 +
>  arch/arm/include/asm/arch-armada100/mfp.h    |   40 ++-
>  arch/arm/include/asm/arch-pantheon/config.h  |   10 +
>  arch/arm/include/asm/arch-pantheon/cpu.h     |    4 +-
>  arch/arm/include/asm/arch-pantheon/mfp.h     |    6 +-
>  arch/arm/include/asm/arch-pxa/pxa-regs.h     |   56 ---
>  board/Marvell/aspenite/aspenite.c            |    5 +
>  board/Marvell/dkb/dkb.c                      |    4 +
>  board/innokom/innokom.c                      |    9 +-
>  drivers/i2c/Makefile                         |    1 +
>  drivers/i2c/mv_i2c.c                         |  481
> ++++++++++++++++++++++++++
>  drivers/i2c/mv_i2c.h                         |   83 +++++
>  include/configs/aspenite.h                   |    1 +
>  include/configs/dkb.h                        |    2 +
>  include/configs/innokom.h                    |    2 +
>  include/configs/xm250.h                      |    2 +
>  21 files changed, 671 insertions(+), 555 deletions(-)
>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>  create mode 100644 drivers/i2c/mv_i2c.c
>  create mode 100644 drivers/i2c/mv_i2c.h

Dear Lei
I have trying to apply this patch series to u-boot-marvell.git master branch.
Since I have rebased this branch to latest u-boot-arm.git master.

This patch series cannot be cleanly applied.

Can you pls provide new one in sync with latest pull from u-boot-marvell.git master branch?

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-13 14:01                   ` Prafulla Wadaskar
@ 2011-04-13 14:14                     ` Lei Wen
  2011-04-13 14:26                       ` Prafulla Wadaskar
  0 siblings, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-04-13 14:14 UTC (permalink / raw)
  To: u-boot

Hi Prafulla,

On Wed, Apr 13, 2011 at 10:01 PM, Prafulla Wadaskar
<prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:leiwen at marvell.com]
>> Sent: Tuesday, April 05, 2011 1:31 PM
>> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
>> Tang; adrian.wenl at gmail.com
>> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
>>
>> V2:
>> rename the previous pxa_i2c to mvi2c, since this driver would be shared
>> by many other Marvell platforms.
>>
>> V3:
>> Clean the code sytle issue
>>
>> V4:
>> add and* and or* to make set bit operation generic
>> Also make i2c definition included in the ifdef
>>
>> V5:
>> Fix code style issue of the first patch
>>
>> V6:
>> Seperate the and* and or* patch out of the patch set
>> Move CONFIG_CMD_I2C define place
>>
>> V7:
>> Fix comments style
>> Make global change from PXA to MV
>> Move i2c config setting to <arch/config>
>>
>> V8:
>> Seperate timeout fix patch out
>>
>> Lei Wen (6):
>> ? pxa: move i2c driver to the common place
>> ? mv_i2c: fix timeout value to be consistent with comments
>> ? mv_i2c: use structure to replace the direclty define
>> ? I2C: add i2c support for Pantheon platform
>> ? I2C: mv_i2c: add multi bus support
>> ? I2C: add i2c support for Armada100 platform
>>
>> ?arch/arm/cpu/arm926ejs/armada100/cpu.c ? ? ? | ? 16 +
>> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ? ? ?| ? 12 +
>> ?arch/arm/cpu/pxa/Makefile ? ? ? ? ? ? ? ? ? ?| ? ?1 -
>> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? ? ? | ? 10 +
>> ?arch/arm/cpu/pxa/i2c.c ? ? ? ? ? ? ? ? ? ? ? | ?469 -------------------
>> ------
>> ?arch/arm/include/asm/arch-armada100/config.h | ? 12 +
>> ?arch/arm/include/asm/arch-armada100/mfp.h ? ?| ? 40 ++-
>> ?arch/arm/include/asm/arch-pantheon/config.h ?| ? 10 +
>> ?arch/arm/include/asm/arch-pantheon/cpu.h ? ? | ? ?4 +-
>> ?arch/arm/include/asm/arch-pantheon/mfp.h ? ? | ? ?6 +-
>> ?arch/arm/include/asm/arch-pxa/pxa-regs.h ? ? | ? 56 ---
>> ?board/Marvell/aspenite/aspenite.c ? ? ? ? ? ?| ? ?5 +
>> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ? ? ?| ? ?4 +
>> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ? ? ?| ? ?9 +-
>> ?drivers/i2c/Makefile ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
>> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? ? ? | ?481
>> ++++++++++++++++++++++++++
>> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? ? ? | ? 83 +++++
>> ?include/configs/aspenite.h ? ? ? ? ? ? ? ? ? | ? ?1 +
>> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
>> ?include/configs/innokom.h ? ? ? ? ? ? ? ? ? ?| ? ?2 +
>> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
>> ?21 files changed, 671 insertions(+), 555 deletions(-)
>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>> ?create mode 100644 drivers/i2c/mv_i2c.c
>> ?create mode 100644 drivers/i2c/mv_i2c.h
>
> Dear Lei
> I have trying to apply this patch series to u-boot-marvell.git master branch.
> Since I have rebased this branch to latest u-boot-arm.git master.
>
> This patch series cannot be cleanly applied.
>
> Can you pls provide new one in sync with latest pull from u-boot-marvell.git master branch?
>

I just apply those patch on master branch without any warning.
Are you apply the V8 series?

leiwen at ubuntu:~/reps/works/u-boot-marvell$ git am
~/reps/works/u-boot/20110411/0001-pxa-move-i2c-driver-to-the-common-place.patch
Applying: pxa: move i2c driver to the common place
leiwen at ubuntu:~/reps/works/u-boot-marvell$ git am
~/reps/works/u-boot/20110411/0002-mv_i2c-fix-timeout-value-to-be-consistent-with-comme.patch
Applying: mv_i2c: fix timeout value to be consistent with comments
leiwen at ubuntu:~/reps/works/u-boot-marvell$ git am
~/reps/works/u-boot/20110411/0003-mv_i2c-use-structure-to-replace-the-direclty-define.patch
Applying: mv_i2c: use structure to replace the direclty define
leiwen at ubuntu:~/reps/works/u-boot-marvell$ git am
~/reps/works/u-boot/20110411/0004-I2C-add-i2c-support-for-Pantheon-platform.patch
Applying: I2C: add i2c support for Pantheon platform
leiwen at ubuntu:~/reps/works/u-boot-marvell$ git am
~/reps/works/u-boot/20110411/0005-I2C-mv_i2c-add-multi-bus-support.patch
Applying: I2C: mv_i2c: add multi bus support
leiwen at ubuntu:~/reps/works/u-boot-marvell$ git am
~/reps/works/u-boot/20110411/0006-I2C-add-i2c-support-for-Armada100-platform.patch
Applying: I2C: add i2c support for Armada100 platform


7ad84a1ad5fb2d55efcf87a5b37d1e013283191e I2C: add i2c support for
Armada100 platform
7fe7e01ca592e978b18ec37bd4ac36cfb13b7538 I2C: mv_i2c: add multi bus support
89f9b6a3714fd898f46370b3729040b29b820681 I2C: add i2c support for
Pantheon platform
8bb0300e9de3d45959282fa0ddcd06e48f3edfaf mv_i2c: use structure to
replace the direclty define
04390287c9101169fbf6f7015290f2f73cf6b193 mv_i2c: fix timeout value to
be consistent with comments
84e1db708ade04ab014b72bcdc8e657bc9ae5b1c pxa: move i2c driver to the
common place
162987fcf760ed54df5fb95018036ade636b5cd3 MX25: tx25: Add _end section
on nand_spl
feb28e18dab7c583b6d0d20e89256271ef1ac6ad MX31: mx31pdk: fix nand_spl

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-13 14:14                     ` Lei Wen
@ 2011-04-13 14:26                       ` Prafulla Wadaskar
  2011-04-13 14:36                         ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-13 14:26 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:adrian.wenl at gmail.com]
> Sent: Wednesday, April 13, 2011 7:44 PM
> To: Prafulla Wadaskar
> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
> Subject: Re: [PATCH V8 0/6] add i2c support to pantheon and aramada100
> 
> Hi Prafulla,
> 
> On Wed, Apr 13, 2011 at 10:01 PM, Prafulla Wadaskar
> <prafulla@marvell.com> wrote:
> >
> >
> >> -----Original Message-----
> >> From: Lei Wen [mailto:leiwen at marvell.com]
> >> Sent: Tuesday, April 05, 2011 1:31 PM
> >> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> >> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
> Yu
> >> Tang; adrian.wenl at gmail.com
> >> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
> >>
> >> V2:
> >> rename the previous pxa_i2c to mvi2c, since this driver would be
> shared
> >> by many other Marvell platforms.
> >>
> >> V3:
> >> Clean the code sytle issue
> >>
> >> V4:
> >> add and* and or* to make set bit operation generic
> >> Also make i2c definition included in the ifdef
> >>
> >> V5:
> >> Fix code style issue of the first patch
> >>
> >> V6:
> >> Seperate the and* and or* patch out of the patch set
> >> Move CONFIG_CMD_I2C define place
> >>
> >> V7:
> >> Fix comments style
> >> Make global change from PXA to MV
> >> Move i2c config setting to <arch/config>
> >>
> >> V8:
> >> Seperate timeout fix patch out
> >>
> >> Lei Wen (6):
> >> ? pxa: move i2c driver to the common place
> >> ? mv_i2c: fix timeout value to be consistent with comments
> >> ? mv_i2c: use structure to replace the direclty define
> >> ? I2C: add i2c support for Pantheon platform
> >> ? I2C: mv_i2c: add multi bus support
> >> ? I2C: add i2c support for Armada100 platform
> >>
> >> ?arch/arm/cpu/arm926ejs/armada100/cpu.c ? ? ? | ? 16 +
> >> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ? ? ?| ? 12 +
> >> ?arch/arm/cpu/pxa/Makefile ? ? ? ? ? ? ? ? ? ?| ? ?1 -
> >> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? ? ? | ? 10 +
> >> ?arch/arm/cpu/pxa/i2c.c ? ? ? ? ? ? ? ? ? ? ? | ?469 ----------------
> ---
> >> ------
> >> ?arch/arm/include/asm/arch-armada100/config.h | ? 12 +
> >> ?arch/arm/include/asm/arch-armada100/mfp.h ? ?| ? 40 ++-
> >> ?arch/arm/include/asm/arch-pantheon/config.h ?| ? 10 +
> >> ?arch/arm/include/asm/arch-pantheon/cpu.h ? ? | ? ?4 +-
> >> ?arch/arm/include/asm/arch-pantheon/mfp.h ? ? | ? ?6 +-
> >> ?arch/arm/include/asm/arch-pxa/pxa-regs.h ? ? | ? 56 ---
> >> ?board/Marvell/aspenite/aspenite.c ? ? ? ? ? ?| ? ?5 +
> >> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ? ? ?| ? ?4 +
> >> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ? ? ?| ? ?9 +-
> >> ?drivers/i2c/Makefile ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
> >> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? ? ? | ?481
> >> ++++++++++++++++++++++++++
> >> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? ? ? | ? 83 +++++
> >> ?include/configs/aspenite.h ? ? ? ? ? ? ? ? ? | ? ?1 +
> >> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
> >> ?include/configs/innokom.h ? ? ? ? ? ? ? ? ? ?| ? ?2 +
> >> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
> >> ?21 files changed, 671 insertions(+), 555 deletions(-)
> >> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
> >> ?create mode 100644 drivers/i2c/mv_i2c.c
> >> ?create mode 100644 drivers/i2c/mv_i2c.h
> >
> > Dear Lei
> > I have trying to apply this patch series to u-boot-marvell.git master
> branch.
> > Since I have rebased this branch to latest u-boot-arm.git master.
> >
> > This patch series cannot be cleanly applied.
> >
> > Can you pls provide new one in sync with latest pull from u-boot-
> marvell.git master branch?
> >
> 
> I just apply those patch on master branch without any warning.
> Are you apply the V8 series?

Yes, I am using V8 patches.
Have you done git pull before that?
What is your latest git log? (before applying patches)

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-13 14:26                       ` Prafulla Wadaskar
@ 2011-04-13 14:36                         ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-13 14:36 UTC (permalink / raw)
  To: u-boot

On Wed, Apr 13, 2011 at 10:26 PM, Prafulla Wadaskar
<prafulla@marvell.com> wrote:
>
>
>> -----Original Message-----
>> From: Lei Wen [mailto:adrian.wenl at gmail.com]
>> Sent: Wednesday, April 13, 2011 7:44 PM
>> To: Prafulla Wadaskar
>> Cc: Lei Wen; Heiko Schocher; Wolfgang Denk; u-boot at lists.denx.de; Marek
>> Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu Tang
>> Subject: Re: [PATCH V8 0/6] add i2c support to pantheon and aramada100
>>
>> Hi Prafulla,
>>
>> On Wed, Apr 13, 2011 at 10:01 PM, Prafulla Wadaskar
>> <prafulla@marvell.com> wrote:
>> >
>> >
>> >> -----Original Message-----
>> >> From: Lei Wen [mailto:leiwen at marvell.com]
>> >> Sent: Tuesday, April 05, 2011 1:31 PM
>> >> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
>> >> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik;
>> Yu
>> >> Tang; adrian.wenl at gmail.com
>> >> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
>> >>
>> >> V2:
>> >> rename the previous pxa_i2c to mvi2c, since this driver would be
>> shared
>> >> by many other Marvell platforms.
>> >>
>> >> V3:
>> >> Clean the code sytle issue
>> >>
>> >> V4:
>> >> add and* and or* to make set bit operation generic
>> >> Also make i2c definition included in the ifdef
>> >>
>> >> V5:
>> >> Fix code style issue of the first patch
>> >>
>> >> V6:
>> >> Seperate the and* and or* patch out of the patch set
>> >> Move CONFIG_CMD_I2C define place
>> >>
>> >> V7:
>> >> Fix comments style
>> >> Make global change from PXA to MV
>> >> Move i2c config setting to <arch/config>
>> >>
>> >> V8:
>> >> Seperate timeout fix patch out
>> >>
>> >> Lei Wen (6):
>> >> ? pxa: move i2c driver to the common place
>> >> ? mv_i2c: fix timeout value to be consistent with comments
>> >> ? mv_i2c: use structure to replace the direclty define
>> >> ? I2C: add i2c support for Pantheon platform
>> >> ? I2C: mv_i2c: add multi bus support
>> >> ? I2C: add i2c support for Armada100 platform
>> >>
>> >> ?arch/arm/cpu/arm926ejs/armada100/cpu.c ? ? ? | ? 16 +
>> >> ?arch/arm/cpu/arm926ejs/pantheon/cpu.c ? ? ? ?| ? 12 +
>> >> ?arch/arm/cpu/pxa/Makefile ? ? ? ? ? ? ? ? ? ?| ? ?1 -
>> >> ?arch/arm/cpu/pxa/cpu.c ? ? ? ? ? ? ? ? ? ? ? | ? 10 +
>> >> ?arch/arm/cpu/pxa/i2c.c ? ? ? ? ? ? ? ? ? ? ? | ?469 ----------------
>> ---
>> >> ------
>> >> ?arch/arm/include/asm/arch-armada100/config.h | ? 12 +
>> >> ?arch/arm/include/asm/arch-armada100/mfp.h ? ?| ? 40 ++-
>> >> ?arch/arm/include/asm/arch-pantheon/config.h ?| ? 10 +
>> >> ?arch/arm/include/asm/arch-pantheon/cpu.h ? ? | ? ?4 +-
>> >> ?arch/arm/include/asm/arch-pantheon/mfp.h ? ? | ? ?6 +-
>> >> ?arch/arm/include/asm/arch-pxa/pxa-regs.h ? ? | ? 56 ---
>> >> ?board/Marvell/aspenite/aspenite.c ? ? ? ? ? ?| ? ?5 +
>> >> ?board/Marvell/dkb/dkb.c ? ? ? ? ? ? ? ? ? ? ?| ? ?4 +
>> >> ?board/innokom/innokom.c ? ? ? ? ? ? ? ? ? ? ?| ? ?9 +-
>> >> ?drivers/i2c/Makefile ? ? ? ? ? ? ? ? ? ? ? ? | ? ?1 +
>> >> ?drivers/i2c/mv_i2c.c ? ? ? ? ? ? ? ? ? ? ? ? | ?481
>> >> ++++++++++++++++++++++++++
>> >> ?drivers/i2c/mv_i2c.h ? ? ? ? ? ? ? ? ? ? ? ? | ? 83 +++++
>> >> ?include/configs/aspenite.h ? ? ? ? ? ? ? ? ? | ? ?1 +
>> >> ?include/configs/dkb.h ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
>> >> ?include/configs/innokom.h ? ? ? ? ? ? ? ? ? ?| ? ?2 +
>> >> ?include/configs/xm250.h ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
>> >> ?21 files changed, 671 insertions(+), 555 deletions(-)
>> >> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>> >> ?create mode 100644 drivers/i2c/mv_i2c.c
>> >> ?create mode 100644 drivers/i2c/mv_i2c.h
>> >
>> > Dear Lei
>> > I have trying to apply this patch series to u-boot-marvell.git master
>> branch.
>> > Since I have rebased this branch to latest u-boot-arm.git master.
>> >
>> > This patch series cannot be cleanly applied.
>> >
>> > Can you pls provide new one in sync with latest pull from u-boot-
>> marvell.git master branch?
>> >
>>
>> I just apply those patch on master branch without any warning.
>> Are you apply the V8 series?
>
> Yes, I am using V8 patches.
> Have you done git pull before that?
> What is your latest git log? (before applying patches)
>

The commit apply is based on:
commit 162987fcf760ed54df5fb95018036ade636b5cd3
Author: Fabio Estevam <festevam@gmail.com>
Date:   Sun Apr 3 12:17:19 2011 +0000

    MX25: tx25: Add _end section on nand_spl

Isn't it the latest?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 0/6] add i2c support to pantheon and aramada100
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
  2011-04-07 13:29                   ` Prafulla Wadaskar
  2011-04-13 14:01                   ` Prafulla Wadaskar
@ 2011-04-13 14:38                   ` Prafulla Wadaskar
  2 siblings, 0 replies; 123+ messages in thread
From: Prafulla Wadaskar @ 2011-04-13 14:38 UTC (permalink / raw)
  To: u-boot



> -----Original Message-----
> From: Lei Wen [mailto:leiwen at marvell.com]
> Sent: Tuesday, April 05, 2011 1:31 PM
> To: Heiko Schocher; Prafulla Wadaskar; Wolfgang Denk; u-
> boot at lists.denx.de; Marek Vasut; Ashish Karkare; Prabhanjan Sarnaik; Yu
> Tang; adrian.wenl at gmail.com
> Subject: [PATCH V8 0/6] add i2c support to pantheon and aramada100
> 
> V2:
> rename the previous pxa_i2c to mvi2c, since this driver would be shared
> by many other Marvell platforms.
> 
> V3:
> Clean the code sytle issue
> 
> V4:
> add and* and or* to make set bit operation generic
> Also make i2c definition included in the ifdef
> 
> V5:
> Fix code style issue of the first patch
> 
> V6:
> Seperate the and* and or* patch out of the patch set
> Move CONFIG_CMD_I2C define place
> 
> V7:
> Fix comments style
> Make global change from PXA to MV
> Move i2c config setting to <arch/config>
> 
> V8:
> Seperate timeout fix patch out
> 
> Lei Wen (6):
>   pxa: move i2c driver to the common place
>   mv_i2c: fix timeout value to be consistent with comments
>   mv_i2c: use structure to replace the direclty define
>   I2C: add i2c support for Pantheon platform
>   I2C: mv_i2c: add multi bus support
>   I2C: add i2c support for Armada100 platform
> 
>  arch/arm/cpu/arm926ejs/armada100/cpu.c       |   16 +
>  arch/arm/cpu/arm926ejs/pantheon/cpu.c        |   12 +
>  arch/arm/cpu/pxa/Makefile                    |    1 -
>  arch/arm/cpu/pxa/cpu.c                       |   10 +
>  arch/arm/cpu/pxa/i2c.c                       |  469 -------------------
> ------
>  arch/arm/include/asm/arch-armada100/config.h |   12 +
>  arch/arm/include/asm/arch-armada100/mfp.h    |   40 ++-
>  arch/arm/include/asm/arch-pantheon/config.h  |   10 +
>  arch/arm/include/asm/arch-pantheon/cpu.h     |    4 +-
>  arch/arm/include/asm/arch-pantheon/mfp.h     |    6 +-
>  arch/arm/include/asm/arch-pxa/pxa-regs.h     |   56 ---
>  board/Marvell/aspenite/aspenite.c            |    5 +
>  board/Marvell/dkb/dkb.c                      |    4 +
>  board/innokom/innokom.c                      |    9 +-
>  drivers/i2c/Makefile                         |    1 +
>  drivers/i2c/mv_i2c.c                         |  481
> ++++++++++++++++++++++++++
>  drivers/i2c/mv_i2c.h                         |   83 +++++
>  include/configs/aspenite.h                   |    1 +
>  include/configs/dkb.h                        |    2 +
>  include/configs/innokom.h                    |    2 +
>  include/configs/xm250.h                      |    2 +
>  21 files changed, 671 insertions(+), 555 deletions(-)
>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>  create mode 100644 drivers/i2c/mv_i2c.c
>  create mode 100644 drivers/i2c/mv_i2c.h

Applied this patch series to u-boot-marvell.git master branch

Regards..
Prafulla . .

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place
  2011-04-05  8:00                 ` [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place Lei Wen
@ 2011-04-20 22:32                   ` Wolfgang Denk
  2011-04-21  2:42                     ` Lei Wen
  2011-04-21  3:31                     ` [U-Boot] [PATCH V8.1 " Lei Wen
  0 siblings, 2 replies; 123+ messages in thread
From: Wolfgang Denk @ 2011-04-20 22:32 UTC (permalink / raw)
  To: u-boot

Dear Lei Wen,

In message <1301990460-31029-2-git-send-email-leiwen@marvell.com> you wrote:
> For better sharing with other platform other than pxa's,
> it is more convenient to put the driver to the common place.
> 
> Signed-off-by: Lei Wen <leiwen@marvell.com>
> ---
> Changelog:
> v2: rename previous pxa_i2c to mvi2c.
> 
> V3: change previous name from pxa_i2c to mv_i2c
>     clean code style issue exist in original code
> 
> V4:
> V5:
> V6:
> V7:
> V8:
> NO CHANGE
> 
>  arch/arm/cpu/pxa/Makefile |    1 -
>  arch/arm/cpu/pxa/i2c.c    |  469 ---------------------------------------------
>  drivers/i2c/Makefile      |    1 +
>  drivers/i2c/mv_i2c.c      |  452 +++++++++++++++++++++++++++++++++++++++++++
>  include/configs/innokom.h |    1 +
>  include/configs/xm250.h   |    1 +
>  6 files changed, 455 insertions(+), 470 deletions(-)
>  delete mode 100644 arch/arm/cpu/pxa/i2c.c
>  create mode 100644 drivers/i2c/mv_i2c.c

I understand that arch/arm/cpu/pxa/i2c.c got renamed into
drivers/i2c/mv_i2c.c ?  Then please make sure this is visible in git
history, i. e. this should be a rename (eventually with
modifications), but not a remove/add.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
>  Is there a way to determine Yesterday's date using Unix utilities?
         echo "what is yesterday's date?" | /bin/mail root
         -- Randal L. Schwartz in <ukbuh2y982.fsf@julie.teleport.com>

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place
  2011-04-20 22:32                   ` Wolfgang Denk
@ 2011-04-21  2:42                     ` Lei Wen
  2011-04-21  2:47                       ` Macpaul Lin
  2011-04-21  3:31                     ` [U-Boot] [PATCH V8.1 " Lei Wen
  1 sibling, 1 reply; 123+ messages in thread
From: Lei Wen @ 2011-04-21  2:42 UTC (permalink / raw)
  To: u-boot

Hi Wolfgang,

On Thu, Apr 21, 2011 at 6:32 AM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Lei Wen,
>
> In message <1301990460-31029-2-git-send-email-leiwen@marvell.com> you wrote:
>> For better sharing with other platform other than pxa's,
>> it is more convenient to put the driver to the common place.
>>
>> Signed-off-by: Lei Wen <leiwen@marvell.com>
>> ---
>> Changelog:
>> v2: rename previous pxa_i2c to mvi2c.
>>
>> V3: change previous name from pxa_i2c to mv_i2c
>> ? ? clean code style issue exist in original code
>>
>> V4:
>> V5:
>> V6:
>> V7:
>> V8:
>> NO CHANGE
>>
>> ?arch/arm/cpu/pxa/Makefile | ? ?1 -
>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 ---------------------------------------------
>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452 +++++++++++++++++++++++++++++++++++++++++++
>> ?include/configs/innokom.h | ? ?1 +
>> ?include/configs/xm250.h ? | ? ?1 +
>> ?6 files changed, 455 insertions(+), 470 deletions(-)
>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>> ?create mode 100644 drivers/i2c/mv_i2c.c
>
> I understand that arch/arm/cpu/pxa/i2c.c got renamed into
> drivers/i2c/mv_i2c.c ? ?Then please make sure this is visible in git
> history, i. e. this should be a rename (eventually with
> modifications), but not a remove/add.
>

There is no way to for git to do this... I try to do this with git mv, but that
also don't shows the rename operation in the formated patch.
Is there some advanced git command could accomplish that?

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place
  2011-04-21  2:42                     ` Lei Wen
@ 2011-04-21  2:47                       ` Macpaul Lin
  2011-04-21  2:50                         ` Lei Wen
  0 siblings, 1 reply; 123+ messages in thread
From: Macpaul Lin @ 2011-04-21  2:47 UTC (permalink / raw)
  To: u-boot

Hi Lei Wen,

2011/4/21 Lei Wen <adrian.wenl@gmail.com>:
> Hi Wolfgang,
>
> On Thu, Apr 21, 2011 at 6:32 AM, Wolfgang Denk <wd@denx.de> wrote:
>> Dear Lei Wen,
>>
>>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 ---------------------------------------------
>>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452 +++++++++++++++++++++++++++++++++++++++++++
>>> ?include/configs/innokom.h | ? ?1 +
>>> ?include/configs/xm250.h ? | ? ?1 +
>>> ?6 files changed, 455 insertions(+), 470 deletions(-)
>>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>>> ?create mode 100644 drivers/i2c/mv_i2c.c
>>
>> I understand that arch/arm/cpu/pxa/i2c.c got renamed into
>> drivers/i2c/mv_i2c.c ? ?Then please make sure this is visible in git
>> history, i. e. this should be a rename (eventually with
>> modifications), but not a remove/add.
>>
>
> There is no way to for git to do this... I try to do this with git mv, but that
> also don't shows the rename operation in the formated patch.
> Is there some advanced git command could accomplish that?
>
> Best regards,
> Lei

Sorry I didn't follow your discussion before.
According to this mail I've read, I guess you need to use git
--format-patch with -M or -C
option to avoid git generating such details.

>>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 ---------------------------------------------
>>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452 +++++++++++++++++++++++++++++++++++++++++++

Not sure if this really resolve your problem. :)

-- 
Best regards,
Macpaul Lin

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place
  2011-04-21  2:47                       ` Macpaul Lin
@ 2011-04-21  2:50                         ` Lei Wen
  0 siblings, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-21  2:50 UTC (permalink / raw)
  To: u-boot

Hi Macpaul,

On Thu, Apr 21, 2011 at 10:47 AM, Macpaul Lin <macpaul@gmail.com> wrote:
> Hi Lei Wen,
>
> 2011/4/21 Lei Wen <adrian.wenl@gmail.com>:
>> Hi Wolfgang,
>>
>> On Thu, Apr 21, 2011 at 6:32 AM, Wolfgang Denk <wd@denx.de> wrote:
>>> Dear Lei Wen,
>>>
>>>> ?arch/arm/cpu/pxa/i2c.c ? ?| ?469 ---------------------------------------------
>>>> ?drivers/i2c/Makefile ? ? ?| ? ?1 +
>>>> ?drivers/i2c/mv_i2c.c ? ? ?| ?452 +++++++++++++++++++++++++++++++++++++++++++
>>>> ?include/configs/innokom.h | ? ?1 +
>>>> ?include/configs/xm250.h ? | ? ?1 +
>>>> ?6 files changed, 455 insertions(+), 470 deletions(-)
>>>> ?delete mode 100644 arch/arm/cpu/pxa/i2c.c
>>>> ?create mode 100644 drivers/i2c/mv_i2c.c
>>>
>>> I understand that arch/arm/cpu/pxa/i2c.c got renamed into
>>> drivers/i2c/mv_i2c.c ? ?Then please make sure this is visible in git
>>> history, i. e. this should be a rename (eventually with
>>> modifications), but not a remove/add.
>>>
>>
>> There is no way to for git to do this... I try to do this with git mv, but that
>> also don't shows the rename operation in the formated patch.
>> Is there some advanced git command could accomplish that?
>>
>> Best regards,
>> Lei
>
> Sorry I didn't follow your discussion before.
> According to this mail I've read, I guess you need to use git
> --format-patch with -M or -C
> option to avoid git generating such details.

I see...
Thanks for your help.

Best regards,
Lei

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [U-Boot] [PATCH V8.1 1/6] pxa: move i2c driver to the common place
  2011-04-20 22:32                   ` Wolfgang Denk
  2011-04-21  2:42                     ` Lei Wen
@ 2011-04-21  3:31                     ` Lei Wen
  1 sibling, 0 replies; 123+ messages in thread
From: Lei Wen @ 2011-04-21  3:31 UTC (permalink / raw)
  To: u-boot

For better sharing with other platform other than pxa's,
it is more convenient to put the driver to the common place.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
Changelog:
v2: rename previous pxa_i2c to mvi2c.

V3: change previous name from pxa_i2c to mv_i2c
    clean code style issue exist in original code

V4:
V5:
V6:
V7:
V8:
NO CHANGE

V8.1
Format the patch with -M to show the rename history

 arch/arm/cpu/pxa/Makefile                      |    1 -
 drivers/i2c/Makefile                           |    1 +
 arch/arm/cpu/pxa/i2c.c => drivers/i2c/mv_i2c.c |  127 ++++++++++-------------
 include/configs/innokom.h                      |    1 +
 include/configs/xm250.h                        |    1 +
 5 files changed, 58 insertions(+), 73 deletions(-)
 rename arch/arm/cpu/pxa/i2c.c => drivers/i2c/mv_i2c.c (86%)

diff --git a/arch/arm/cpu/pxa/Makefile b/arch/arm/cpu/pxa/Makefile
index 49a6ed3..e8b59a3 100644
--- a/arch/arm/cpu/pxa/Makefile
+++ b/arch/arm/cpu/pxa/Makefile
@@ -28,7 +28,6 @@ LIB	= $(obj)lib$(CPU).o
 START	= start.o
 
 COBJS	+= cpu.o
-COBJS	+= i2c.o
 COBJS	+= pxafb.o
 COBJS	+= timer.o
 COBJS	+= usb.o
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..00a12cc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -29,6 +29,7 @@ COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
 COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
 COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
 COBJS-$(CONFIG_I2C_MVTWSI) += mvtwsi.o
+COBJS-$(CONFIG_I2C_MV) += mv_i2c.o
 COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
 COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/arch/arm/cpu/pxa/i2c.c b/drivers/i2c/mv_i2c.c
similarity index 86%
rename from arch/arm/cpu/pxa/i2c.c
rename to drivers/i2c/mv_i2c.c
index 7aa49ae..09756a4 100644
--- a/arch/arm/cpu/pxa/i2c.c
+++ b/drivers/i2c/mv_i2c.c
@@ -30,8 +30,6 @@
  * Murray.Jensen at cmst.csiro.au, 27-Jan-01.
  */
 
-/* FIXME: this file is PXA255 specific! What about other XScales? */
-
 #include <common.h>
 #include <asm/io.h>
 
@@ -46,11 +44,9 @@
 #include <asm/arch/pxa-regs.h>
 #include <i2c.h>
 
-/*#define	DEBUG_I2C	1	/###* activate local debugging output  */
-#define I2C_PXA_SLAVE_ADDR	0x1	/* slave pxa unit address           */
-
 #if (CONFIG_SYS_I2C_SPEED == 400000)
-#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
+#define I2C_ICR_INIT	(ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
+			| ICR_SCLE)
 #else
 #define I2C_ICR_INIT	(ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
 #endif
@@ -63,7 +59,6 @@
 #define PRINTD(x)
 #endif
 
-
 /* Shall the current transfer have a start/stop condition? */
 #define I2C_COND_NORMAL		0
 #define I2C_COND_START		1
@@ -86,13 +81,11 @@ struct i2c_msg {
 	u8 data;
 };
 
-
-/**
+/*
  * i2c_pxa_reset: - reset the host controller
  *
  */
-
-static void i2c_reset( void )
+static void i2c_reset(void)
 {
 	writel(readl(ICR) & ~ICR_IUE, ICR);	/* disable unit */
 	writel(readl(ICR) | ICR_UR, ICR);	/* reset the unit */
@@ -112,27 +105,27 @@ static void i2c_reset( void )
 	udelay(100);
 }
 
-
-/**
+/*
  * i2c_isr_set_cleared: - wait until certain bits of the I2C status register
  *	                  are set and cleared
  *
  * @return: 1 in case of success, 0 means timeout (no match within 10 ms).
  */
-static int i2c_isr_set_cleared( unsigned long set_mask, unsigned long cleared_mask )
+static int i2c_isr_set_cleared(unsigned long set_mask,
+			       unsigned long cleared_mask)
 {
 	int timeout = 10000;
 
-	while( ((ISR & set_mask)!=set_mask) || ((ISR & cleared_mask)!=0) ){
-		udelay( 10 );
-		if( timeout-- < 0 ) return 0;
+	while (((ISR & set_mask) != set_mask) || ((ISR & cleared_mask) != 0)) {
+		udelay(10);
+		if (timeout-- < 0)
+			return 0;
 	}
 
 	return 1;
 }
 
-
-/**
+/*
  * i2c_transfer: - Transfer one byte over the i2c bus
  *
  * This function can tranfer a byte over the i2c bus in both directions.
@@ -153,12 +146,10 @@ int i2c_transfer(struct i2c_msg *msg)
 	if (!msg)
 		goto transfer_error_msg_empty;
 
-	switch(msg->direction) {
-
+	switch (msg->direction) {
 	case I2C_WRITE:
-
 		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
 			goto transfer_error_bus_busy;
 
 		/* start transmission */
@@ -177,7 +168,7 @@ int i2c_transfer(struct i2c_msg *msg)
 		writel(readl(ICR) | ICR_TB, ICR);
 
 		/* transmit register empty? */
-		if (!i2c_isr_set_cleared(ISR_ITE,0))
+		if (!i2c_isr_set_cleared(ISR_ITE, 0))
 			goto transfer_error_transmit_timeout;
 
 		/* clear 'transmit empty' state */
@@ -185,14 +176,14 @@ int i2c_transfer(struct i2c_msg *msg)
 
 		/* wait for ACK from slave */
 		if (msg->acknack == I2C_ACKNAK_WAITACK)
-			if (!i2c_isr_set_cleared(0,ISR_ACKNAK))
+			if (!i2c_isr_set_cleared(0, ISR_ACKNAK))
 				goto transfer_error_ack_missing;
 		break;
 
 	case I2C_READ:
 
 		/* check if bus is not busy */
-		if (!i2c_isr_set_cleared(0,ISR_IBB))
+		if (!i2c_isr_set_cleared(0, ISR_IBB))
 			goto transfer_error_bus_busy;
 
 		/* start receive */
@@ -210,7 +201,7 @@ int i2c_transfer(struct i2c_msg *msg)
 		writel(readl(ICR) | ICR_TB, ICR);
 
 		/* receive register full? */
-		if (!i2c_isr_set_cleared(ISR_IRF,0))
+		if (!i2c_isr_set_cleared(ISR_IRF, 0))
 			goto transfer_error_receive_timeout;
 
 		msg->data = readl(IDBR);
@@ -219,11 +210,8 @@ int i2c_transfer(struct i2c_msg *msg)
 		writel(readl(ISR) | ISR_IRF, ISR);
 
 		break;
-
 	default:
-
 		goto transfer_error_illegal_param;
-
 	}
 
 	return 0;
@@ -253,16 +241,14 @@ transfer_error_bus_busy:
 		ret = -6; goto i2c_transfer_finish;
 
 i2c_transfer_finish:
-		PRINTD(("i2c_transfer: ISR: 0x%04x\n",ISR));
+		PRINTD(("i2c_transfer: ISR: 0x%04x\n", ISR));
 		i2c_reset();
 		return ret;
-
 }
 
 /* ------------------------------------------------------------------------ */
 /* API Functions                                                            */
 /* ------------------------------------------------------------------------ */
-
 void i2c_init(int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
@@ -273,14 +259,12 @@ void i2c_init(int speed, int slaveaddr)
 #endif
 }
 
-
-/**
+/*
  * i2c_probe: - Test if a chip answers for a given i2c address
  *
  * @chip:	address of the chip which is searched for
  * @return:	0 if a chip was found, -1 otherwhise
  */
-
 int i2c_probe(uchar chip)
 {
 	struct i2c_msg msg;
@@ -291,19 +275,20 @@ int i2c_probe(uchar chip)
 	msg.acknack   = I2C_ACKNAK_WAITACK;
 	msg.direction = I2C_WRITE;
 	msg.data      = (chip << 1) + 1;
-	if (i2c_transfer(&msg)) return -1;
+	if (i2c_transfer(&msg))
+		return -1;
 
 	msg.condition = I2C_COND_STOP;
 	msg.acknack   = I2C_ACKNAK_SENDNAK;
 	msg.direction = I2C_READ;
 	msg.data      = 0x00;
-	if (i2c_transfer(&msg)) return -1;
+	if (i2c_transfer(&msg))
+		return -1;
 
 	return 0;
 }
 
-
-/**
+/*
  * i2c_read: - Read multiple bytes from an i2c device
  *
  * The higher level routines take into account that this function is only
@@ -316,14 +301,13 @@ int i2c_probe(uchar chip)
  * @len:	how much byte do we want to read
  * @return:	0 in case of success
  */
-
 int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 {
 	struct i2c_msg msg;
 	u8 addr_bytes[3]; /* lowest...highest byte of data address */
-	int ret;
 
-	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
+	PRINTD(("i2c_read(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
 
 	i2c_reset();
 
@@ -332,9 +316,10 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	msg.condition = I2C_COND_START;
 	msg.acknack   = I2C_ACKNAK_WAITACK;
 	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if ((ret=i2c_transfer(&msg))) return -1;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
 
 	/*
 	 * send memory address bytes;
@@ -346,16 +331,15 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
 
 	while (--alen >= 0) {
-
-		PRINTD(("i2c_read: send memory word address byte %1d\n",alen));
+		PRINTD(("i2c_read: send memory word address byte %1d\n", alen));
 		msg.condition = I2C_COND_NORMAL;
 		msg.acknack   = I2C_ACKNAK_WAITACK;
 		msg.direction = I2C_WRITE;
 		msg.data      = addr_bytes[alen];
-		if ((ret=i2c_transfer(&msg))) return -1;
+		if (i2c_transfer(&msg))
+			return -1;
 	}
 
-
 	/* start read sequence */
 	PRINTD(("i2c_read: start read sequence\n"));
 	msg.condition = I2C_COND_START;
@@ -363,12 +347,12 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	msg.direction = I2C_WRITE;
 	msg.data      = (chip << 1);
 	msg.data     |= 0x01;
-	if ((ret=i2c_transfer(&msg))) return -1;
+	if (i2c_transfer(&msg))
+		return -1;
 
 	/* read bytes; send NACK@last byte */
 	while (len--) {
-
-		if (len==0) {
+		if (len == 0) {
 			msg.condition = I2C_COND_STOP;
 			msg.acknack   = I2C_ACKNAK_SENDNAK;
 		} else {
@@ -378,12 +362,13 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 
 		msg.direction = I2C_READ;
 		msg.data      = 0x00;
-		if ((ret=i2c_transfer(&msg))) return -1;
+		if (i2c_transfer(&msg))
+			return -1;
 
 		*buffer = msg.data;
-		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
+		PRINTD(("i2c_read: reading byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
 		buffer++;
-
 	}
 
 	i2c_reset();
@@ -391,8 +376,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	return 0;
 }
 
-
-/**
+/*
  * i2c_write: -  Write multiple bytes to an i2c device
  *
  * The higher level routines take into account that this function is only
@@ -405,13 +389,13 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
  * @len:	how much byte do we want to read
  * @return:	0 in case of success
  */
-
 int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 {
 	struct i2c_msg msg;
 	u8 addr_bytes[3]; /* lowest...highest byte of data address */
 
-	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n",chip,addr,alen,len));
+	PRINTD(("i2c_write(chip=0x%02x, addr=0x%02x, alen=0x%02x, "
+		"len=0x%02x)\n", chip, addr, alen, len));
 
 	i2c_reset();
 
@@ -420,9 +404,10 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	msg.condition = I2C_COND_START;
 	msg.acknack   = I2C_ACKNAK_WAITACK;
 	msg.direction = I2C_WRITE;
-	msg.data      = (chip << 1);
-	msg.data     &= 0xFE;
-	if (i2c_transfer(&msg)) return -1;
+	msg.data = (chip << 1);
+	msg.data &= 0xFE;
+	if (i2c_transfer(&msg))
+		return -1;
 
 	/*
 	 * send memory address bytes;
@@ -433,21 +418,21 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	addr_bytes[2] = (u8)((addr >> 16) & 0x000000FF);
 
 	while (--alen >= 0) {
-
 		PRINTD(("i2c_write: send memory word address\n"));
 		msg.condition = I2C_COND_NORMAL;
 		msg.acknack   = I2C_ACKNAK_WAITACK;
 		msg.direction = I2C_WRITE;
 		msg.data      = addr_bytes[alen];
-		if (i2c_transfer(&msg)) return -1;
+		if (i2c_transfer(&msg))
+			return -1;
 	}
 
 	/* write bytes; send NACK at last byte */
 	while (len--) {
+		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",
+			(unsigned int)buffer, *buffer));
 
-		PRINTD(("i2c_write: writing byte (0x%08x)=0x%02x\n",(unsigned int)buffer,*buffer));
-
-		if (len==0)
+		if (len == 0)
 			msg.condition = I2C_COND_STOP;
 		else
 			msg.condition = I2C_COND_NORMAL;
@@ -456,14 +441,12 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 		msg.direction = I2C_WRITE;
 		msg.data      = *(buffer++);
 
-		if (i2c_transfer(&msg)) return -1;
-
+		if (i2c_transfer(&msg))
+			return -1;
 	}
 
 	i2c_reset();
 
 	return 0;
-
 }
-
 #endif	/* CONFIG_HARD_I2C */
diff --git a/include/configs/innokom.h b/include/configs/innokom.h
index d8fcbdb..0ea73c9 100644
--- a/include/configs/innokom.h
+++ b/include/configs/innokom.h
@@ -140,6 +140,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
diff --git a/include/configs/xm250.h b/include/configs/xm250.h
index 497cb91..b4b940a 100644
--- a/include/configs/xm250.h
+++ b/include/configs/xm250.h
@@ -61,6 +61,7 @@
 /*
  * I2C bus
  */
+#define CONFIG_I2C_MV			1
 #define CONFIG_HARD_I2C			1
 #define CONFIG_SYS_I2C_SPEED			50000
 #define CONFIG_SYS_I2C_SLAVE			0xfe
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

end of thread, other threads:[~2011-04-21  3:31 UTC | newest]

Thread overview: 123+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-14 10:16 [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Lei Wen
2011-03-14 10:16 ` [U-Boot] [PATCH 2/8] pxa_i2c: use structure to replace the direclty define Lei Wen
2011-03-14 10:16 ` [U-Boot] [PATCH 3/8] I2C: add i2c support for Pantheon platform Lei Wen
2011-03-14 10:16 ` [U-Boot] [PATCH 4/8] I2C: pxa_i2c: add multi bus support Lei Wen
2011-03-14 10:16 ` [U-Boot] [PATCH 5/8] I2C: add i2c support for Armada100 platform Lei Wen
2011-03-14 12:03 ` [U-Boot] [PATCH 1/8] pxa: move i2c driver to the common place Prafulla Wadaskar
2011-03-15  1:36   ` Lei Wen
2011-03-15  3:40     ` [U-Boot] [PATCH 0/5] add i2c support to pantheon and aramada100 Lei Wen
2011-03-15  8:12       ` Wolfgang Denk
2011-03-17  6:26         ` Lei Wen
2011-03-17  6:45       ` [U-Boot] [PATCH V3 " Lei Wen
2011-03-28  5:48         ` [U-Boot] [PATCH V4 0/6] " Lei Wen
2011-03-28  6:53           ` [U-Boot] [PATCH V5 " Lei Wen
2011-03-31  8:37             ` [U-Boot] [PATCH V6 0/5] " Lei Wen
2011-04-03 13:00               ` [U-Boot] [PATCH V7 " Lei Wen
2011-04-05  8:00                 ` [U-Boot] [PATCH V8 0/6] " Lei Wen
2011-04-07 13:29                   ` Prafulla Wadaskar
2011-04-07 13:33                     ` Heiko Schocher
2011-04-13 14:01                   ` Prafulla Wadaskar
2011-04-13 14:14                     ` Lei Wen
2011-04-13 14:26                       ` Prafulla Wadaskar
2011-04-13 14:36                         ` Lei Wen
2011-04-13 14:38                   ` Prafulla Wadaskar
2011-04-05  8:00                 ` [U-Boot] [PATCH V8 1/6] pxa: move i2c driver to the common place Lei Wen
2011-04-20 22:32                   ` Wolfgang Denk
2011-04-21  2:42                     ` Lei Wen
2011-04-21  2:47                       ` Macpaul Lin
2011-04-21  2:50                         ` Lei Wen
2011-04-21  3:31                     ` [U-Boot] [PATCH V8.1 " Lei Wen
2011-04-05  8:00                 ` [U-Boot] [PATCH V8 2/6] mv_i2c: fix timeout value to be consistent with comments Lei Wen
2011-04-05  8:00                 ` [U-Boot] [PATCH V8 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
2011-04-05  8:00                 ` [U-Boot] [PATCH V8 4/6] I2C: add i2c support for Pantheon platform Lei Wen
2011-04-05  8:00                 ` [U-Boot] [PATCH V8 5/6] I2C: mv_i2c: add multi bus support Lei Wen
2011-04-05  8:01                 ` [U-Boot] [PATCH V8 6/6] I2C: add i2c support for Armada100 platform Lei Wen
2011-04-03 13:00               ` [U-Boot] [PATCH V7 1/5] pxa: move i2c driver to the common place Lei Wen
2011-04-03 13:00               ` [U-Boot] [PATCH V7 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
2011-04-03 13:27                 ` Wolfgang Denk
2011-04-03 13:00               ` [U-Boot] [PATCH V7 3/5] I2C: add i2c support for Pantheon platform Lei Wen
2011-04-03 13:00               ` [U-Boot] [PATCH V7 4/5] I2C: mv_i2c: add multi bus support Lei Wen
2011-04-03 13:00               ` [U-Boot] [PATCH V7 5/5] I2C: add i2c support for Armada100 platform Lei Wen
2011-03-31  8:37             ` [U-Boot] [PATCH V6 1/5] pxa: move i2c driver to the common place Lei Wen
2011-03-31  8:37             ` [U-Boot] [PATCH V6 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
2011-04-01 18:29               ` Prafulla Wadaskar
2011-04-03 11:30                 ` Lei Wen
2011-04-03 13:21                   ` Wolfgang Denk
2011-03-31  8:37             ` [U-Boot] [PATCH V6 3/5] I2C: add i2c support for Pantheon platform Lei Wen
2011-04-01 18:34               ` Prafulla Wadaskar
2011-04-03 11:32                 ` Lei Wen
2011-03-31  8:37             ` [U-Boot] [PATCH V6 4/5] I2C: mv_i2c: add multi bus support Lei Wen
2011-04-01 18:36               ` Prafulla Wadaskar
2011-03-31  8:37             ` [U-Boot] [PATCH V6 5/5] I2C: add i2c support for Armada100 platform Lei Wen
2011-04-01 18:39               ` Prafulla Wadaskar
2011-03-28  6:53           ` [U-Boot] [PATCH V5 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
2011-03-28  6:53           ` [U-Boot] [PATCH V5 2/6] pxa: move i2c driver to the common place Lei Wen
2011-03-28  6:53           ` [U-Boot] [PATCH V5 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
2011-03-29 13:27             ` Prafulla Wadaskar
2011-03-30 14:11               ` Lei Wen
2011-03-30 18:54                 ` Prafulla Wadaskar
2011-03-28  6:53           ` [U-Boot] [PATCH V5 4/6] I2C: add i2c support for Pantheon platform Lei Wen
2011-03-29 13:07             ` Prafulla Wadaskar
2011-03-30 14:05               ` Lei Wen
2011-03-30 18:56                 ` Prafulla Wadaskar
2011-03-31  7:49                   ` Lei Wen
2011-03-28  6:53           ` [U-Boot] [PATCH V5 5/6] I2C: mv_i2c: add multi bus support Lei Wen
2011-03-28  6:53           ` [U-Boot] [PATCH V5 6/6] I2C: add i2c support for Armada100 platform Lei Wen
2011-03-29 13:09             ` Prafulla Wadaskar
2011-03-28  5:48         ` [U-Boot] [PATCH V4 1/6] io: add and* and or* operation api to set and clear bit Lei Wen
2011-03-28  5:57           ` Wolfgang Denk
2011-03-28  6:01             ` Lei Wen
2011-03-28  6:03             ` Lei Wen
2011-03-28  6:29               ` Wolfgang Denk
2011-03-28  7:04                 ` Lei Wen
2011-03-28 16:05           ` Scott Wood
2011-03-29  2:47             ` Lei Wen
2011-03-29 16:03               ` Scott Wood
2011-03-30 14:08                 ` Lei Wen
2011-03-29  2:53             ` [U-Boot] [PATCH V5.1 " Lei Wen
2011-03-29  5:40               ` Prafulla Wadaskar
2011-03-29  5:44                 ` Mike Frysinger
2011-03-28  5:48         ` [U-Boot] [PATCH V4 2/6] pxa: move i2c driver to the common place Lei Wen
2011-03-28  5:48         ` [U-Boot] [PATCH V4 3/6] mv_i2c: use structure to replace the direclty define Lei Wen
2011-03-28  5:48         ` [U-Boot] [PATCH V4 4/6] I2C: add i2c support for Pantheon platform Lei Wen
2011-03-28  5:48         ` [U-Boot] [PATCH V4 5/6] I2C: mv_i2c: add multi bus support Lei Wen
2011-03-28  5:48         ` [U-Boot] [PATCH V4 6/6] I2C: add i2c support for Armada100 platform Lei Wen
2011-03-17  6:45       ` [U-Boot] [PATCH V3 1/5] pxa: move i2c driver to the common place Lei Wen
2011-03-22 11:42         ` Prafulla Wadaskar
2011-03-22 12:43           ` Lei Wen
2011-03-23  7:38             ` Prafulla Wadaskar
2011-03-23  8:22               ` Heiko Schocher
2011-03-23  8:43                 ` Lei Wen
2011-03-23  8:53                   ` Heiko Schocher
2011-03-23  8:56                     ` Lei Wen
2011-03-23  9:07                       ` Heiko Schocher
2011-03-23  9:16                         ` Prafulla Wadaskar
2011-03-23  9:12                     ` Prafulla Wadaskar
2011-03-17  6:45       ` [U-Boot] [PATCH V3 2/5] mv_i2c: use structure to replace the direclty define Lei Wen
2011-03-22 11:17         ` Prafulla Wadaskar
2011-03-22 12:34           ` Lei Wen
2011-03-22 15:16             ` Wolfgang Denk
2011-03-23  8:48               ` Lei Wen
2011-03-17  6:45       ` [U-Boot] [PATCH V3 3/5] I2C: add i2c support for Pantheon platform Lei Wen
2011-03-22 11:22         ` Prafulla Wadaskar
2011-03-22 12:38           ` Lei Wen
2011-03-17  6:45       ` [U-Boot] [PATCH V3 4/5] I2C: mv_i2c: add multi bus support Lei Wen
2011-03-17  6:45       ` [U-Boot] [PATCH V3 5/5] I2C: add i2c support for Armada100 platform Lei Wen
2011-03-22 11:40         ` Prafulla Wadaskar
2011-03-22 12:39           ` Lei Wen
2011-03-15  3:40     ` [U-Boot] [PATCH V2 1/5] pxa: move i2c driver to the common place Lei Wen
2011-03-15  6:48       ` Heiko Schocher
2011-03-17  6:25         ` Lei Wen
2011-03-15  8:09       ` Wolfgang Denk
2011-03-15  3:40     ` [U-Boot] [PATCH v2 2/5] mvi2c: use structure to replace the direclty define Lei Wen
2011-03-15  6:54       ` Heiko Schocher
2011-03-17  6:28         ` Lei Wen
2011-03-17  7:12           ` Heiko Schocher
2011-03-15  3:40     ` [U-Boot] [PATCH v2 3/5] I2C: add i2c support for Pantheon platform Lei Wen
2011-03-15  6:58       ` Heiko Schocher
2011-03-15  3:40     ` [U-Boot] [PATCH v2 4/5] I2C: mvi2c: add multi bus support Lei Wen
2011-03-15  7:01       ` Heiko Schocher
2011-03-15  3:40     ` [U-Boot] [PATCH v2 5/5] I2C: add i2c support for Armada100 platform Lei Wen
2011-03-15  7:08       ` Heiko Schocher
2011-03-17  6:38         ` Lei Wen
2011-03-17  7:15           ` Heiko Schocher

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.