[U-Boot] [PATCH] 7/12 Multiadapter/multibus I2C, drivers part 4

ksi at koi8.net ksi at koi8.net
Thu Feb 12 23:25:19 CET 2009


Signed-off-by: Sergey Kubushyn <ksi at koi8.net>
---
diff -purN u-boot-i2c.orig/drivers/i2c/soft_i2c.c u-boot-i2c/drivers/i2c/soft_i2c.c
--- u-boot-i2c.orig/drivers/i2c/soft_i2c.c	2009-02-12 10:43:41.000000000 -0800
+++ u-boot-i2c/drivers/i2c/soft_i2c.c	2009-02-12 10:46:00.000000000 -0800
@@ -1,4 +1,8 @@
 /*
+ * Copyright (c) 2009 Sergey Kubushyn <ksi at koi8.net>
+ *
+ * Changes for multibus/multiadapter I2C support.
+ *
  * (C) Copyright 2001, 2002
  * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
  *
@@ -72,375 +76,461 @@ DECLARE_GLOBAL_DATA_PTR;
 #define PRINTD(fmt,args...)
 #endif
 
-#if defined(CONFIG_I2C_MULTI_BUS)
-static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0;
-#endif /* CONFIG_I2C_MULTI_BUS */
-
 /*-----------------------------------------------------------------------
  * Local functions
  */
-#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
-static void  send_reset	(void);
+#ifndef I2C_INIT
+#define I2C_INIT	do {} while(0)
 #endif
-static void  send_start	(void);
-static void  send_stop	(void);
-static void  send_ack	(int);
-static int   write_byte	(uchar byte);
-static uchar read_byte	(int);
-
-#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
-/*-----------------------------------------------------------------------
- * Send a reset sequence consisting of 9 clocks with the data signal high
- * to clock any confused device back into an idle state.  Also send a
- * <stop> at the end of the sequence for belts & suspenders.
- */
-static void send_reset(void)
-{
-	I2C_SOFT_DECLARATIONS	/* intentional without ';' */
-	int j;
-
-	I2C_SCL(1);
-	I2C_SDA(1);
-#ifdef	I2C_INIT
-	I2C_INIT;
-#endif
-	I2C_TRISTATE;
-	for(j = 0; j < 9; j++) {
-		I2C_SCL(0);
-		I2C_DELAY;
-		I2C_DELAY;
-		I2C_SCL(1);
-		I2C_DELAY;
-		I2C_DELAY;
-	}
-	send_stop();
-	I2C_TRISTATE;
-}
+#ifndef I2C_INIT2
+#define I2C_INIT2	do {} while(0)
+#endif
+#ifndef I2C_INIT3
+#define I2C_INIT3	do {} while(0)
 #endif
+#ifndef I2C_INIT4
+#define I2C_INIT4	do {} while(0)
+#endif
+
 
 /*-----------------------------------------------------------------------
  * START: High -> Low on SDA while SCL is High
  */
-static void send_start(void)
-{
-	I2C_SOFT_DECLARATIONS	/* intentional without ';' */
-
-	I2C_DELAY;
-	I2C_SDA(1);
-	I2C_ACTIVE;
-	I2C_DELAY;
-	I2C_SCL(1);
-	I2C_DELAY;
-	I2C_SDA(0);
-	I2C_DELAY;
+#define I2C_SOFT_SEND_START(n) \
+static void send_start##n(void) \
+{ \
+	I2C_SOFT_DECLARATIONS##n \
+	I2C_DELAY##n; \
+	I2C_SDA##n(1); \
+	I2C_ACTIVE##n; \
+	I2C_DELAY##n; \
+	I2C_SCL##n(1); \
+	I2C_DELAY##n; \
+	I2C_SDA##n(0); \
+	I2C_DELAY##n; \
 }
 
+
 /*-----------------------------------------------------------------------
  * STOP: Low -> High on SDA while SCL is High
  */
-static void send_stop(void)
-{
-	I2C_SOFT_DECLARATIONS	/* intentional without ';' */
-
-	I2C_SCL(0);
-	I2C_DELAY;
-	I2C_SDA(0);
-	I2C_ACTIVE;
-	I2C_DELAY;
-	I2C_SCL(1);
-	I2C_DELAY;
-	I2C_SDA(1);
-	I2C_DELAY;
-	I2C_TRISTATE;
+#define I2C_SOFT_SEND_STOP(n) \
+static void send_stop##n(void) \
+{ \
+	I2C_SOFT_DECLARATIONS##n \
+	I2C_SCL##n(0); \
+	I2C_DELAY##n; \
+	I2C_SDA##n(0); \
+	I2C_ACTIVE##n; \
+	I2C_DELAY##n; \
+	I2C_SCL##n(1); \
+	I2C_DELAY##n; \
+	I2C_SDA##n(1); \
+	I2C_DELAY##n; \
+	I2C_TRISTATE##n; \
 }
 
 
 /*-----------------------------------------------------------------------
  * ack should be I2C_ACK or I2C_NOACK
  */
-static void send_ack(int ack)
-{
-	I2C_SOFT_DECLARATIONS	/* intentional without ';' */
-
-	I2C_SCL(0);
-	I2C_DELAY;
-	I2C_ACTIVE;
-	I2C_SDA(ack);
-	I2C_DELAY;
-	I2C_SCL(1);
-	I2C_DELAY;
-	I2C_DELAY;
-	I2C_SCL(0);
-	I2C_DELAY;
+#define I2C_SOFT_SEND_ACK(n) \
+static void send_ack##n(int ack) \
+{ \
+	I2C_SOFT_DECLARATIONS##n \
+	I2C_SCL##n(0); \
+	I2C_DELAY##n; \
+	I2C_ACTIVE##n; \
+	I2C_SDA##n(ack); \
+	I2C_DELAY##n; \
+	I2C_SCL##n(1); \
+	I2C_DELAY##n; \
+	I2C_DELAY##n; \
+	I2C_SCL##n(0); \
+	I2C_DELAY##n; \
 }
 
 
 /*-----------------------------------------------------------------------
- * Send 8 bits and look for an acknowledgement.
+ * Send a reset sequence consisting of 9 clocks with the data signal high
+ * to clock any confused device back into an idle state.  Also send a
+ * <stop> at the end of the sequence for belts & suspenders.
  */
-static int write_byte(uchar data)
-{
-	I2C_SOFT_DECLARATIONS	/* intentional without ';' */
-	int j;
-	int nack;
-
-	I2C_ACTIVE;
-	for(j = 0; j < 8; j++) {
-		I2C_SCL(0);
-		I2C_DELAY;
-		I2C_SDA(data & 0x80);
-		I2C_DELAY;
-		I2C_SCL(1);
-		I2C_DELAY;
-		I2C_DELAY;
-
-		data <<= 1;
-	}
-
-	/*
-	 * Look for an <ACK>(negative logic) and return it.
-	 */
-	I2C_SCL(0);
-	I2C_DELAY;
-	I2C_SDA(1);
-	I2C_TRISTATE;
-	I2C_DELAY;
-	I2C_SCL(1);
-	I2C_DELAY;
-	I2C_DELAY;
-	nack = I2C_READ;
-	I2C_SCL(0);
-	I2C_DELAY;
-	I2C_ACTIVE;
-
-	return(nack);	/* not a nack is an ack */
+#define I2C_SOFT_SEND_RESET(n) \
+static void send_reset##n(void) \
+{ \
+	I2C_SOFT_DECLARATIONS##n \
+	int j; \
+	I2C_SCL##n(1); \
+	I2C_SDA##n(1); \
+	I2C_INIT##n; \
+	I2C_TRISTATE##n; \
+	for(j = 0; j < 9; j++) { \
+		I2C_SCL##n(0); \
+		I2C_DELAY##n; \
+		I2C_DELAY##n; \
+		I2C_SCL##n(1); \
+		I2C_DELAY##n; \
+		I2C_DELAY##n; \
+	} \
+	send_stop##n(); \
+	I2C_TRISTATE##n; \
 }
 
-#if defined(CONFIG_I2C_MULTI_BUS)
-/*
- * Functions for multiple I2C bus handling
- */
-unsigned int i2c_get_bus_num(void)
-{
-	return i2c_bus_num;
-}
-
-int i2c_set_bus_num(unsigned int bus)
-{
-#if defined(CONFIG_I2C_MUX)
-	if (bus < CONFIG_SYS_MAX_I2C_BUS) {
-		i2c_bus_num = bus;
-	} else {
-		int	ret;
-
-		ret = i2x_mux_select_mux(bus);
-		if (ret == 0)
-			i2c_bus_num = bus;
-		else
-			return ret;
-	}
-#else
-	if (bus >= CONFIG_SYS_MAX_I2C_BUS)
-		return -1;
-	i2c_bus_num = bus;
-#endif
-	return 0;
-}
 
-/* TODO: add 100/400k switching */
-unsigned int i2c_get_bus_speed(void)
-{
-	return CONFIG_SYS_I2C_SPEED;
+/*-----------------------------------------------------------------------
+ * Send 8 bits and look for an acknowledgement.
+ */
+#define I2C_SOFT_WRITE_BYTE(n) \
+static int write_byte##n(uchar data) \
+{ \
+	I2C_SOFT_DECLARATIONS##n \
+	int j; \
+	int nack; \
+	I2C_ACTIVE##n; \
+	for(j = 0; j < 8; j++) { \
+		I2C_SCL##n(0); \
+		I2C_DELAY##n; \
+		I2C_SDA##n(data & 0x80); \
+		I2C_DELAY##n; \
+		I2C_SCL##n(1); \
+		I2C_DELAY##n; \
+		I2C_DELAY##n; \
+		data <<= 1; \
+	} \
+	I2C_SCL##n(0); \
+	I2C_DELAY##n; \
+	I2C_SDA##n(1); \
+	I2C_TRISTATE##n; \
+	I2C_DELAY##n; \
+	I2C_SCL##n(1); \
+	I2C_DELAY##n; \
+	I2C_DELAY##n; \
+	nack = I2C_READ##n; \
+	I2C_SCL##n(0); \
+	I2C_DELAY##n; \
+	I2C_ACTIVE##n; \
+	return(nack); \
 }
 
-int i2c_set_bus_speed(unsigned int speed)
-{
-	if (speed != CONFIG_SYS_I2C_SPEED)
-		return -1;
-
-	return 0;
-}
-#endif
 
 /*-----------------------------------------------------------------------
  * if ack == I2C_ACK, ACK the byte so can continue reading, else
  * send I2C_NOACK to end the read.
  */
-static uchar read_byte(int ack)
-{
-	I2C_SOFT_DECLARATIONS	/* intentional without ';' */
-	int  data;
-	int  j;
-
-	/*
-	 * Read 8 bits, MSB first.
-	 */
-	I2C_TRISTATE;
-	I2C_SDA(1);
-	data = 0;
-	for(j = 0; j < 8; j++) {
-		I2C_SCL(0);
-		I2C_DELAY;
-		I2C_SCL(1);
-		I2C_DELAY;
-		data <<= 1;
-		data |= I2C_READ;
-		I2C_DELAY;
-	}
-	send_ack(ack);
-
-	return(data);
-}
-
-/*=====================================================================*/
-/*                         Public Functions                            */
-/*=====================================================================*/
+#define I2C_SOFT_READ_BYTE(n) \
+static uchar read_byte##n(int ack) \
+{ \
+	I2C_SOFT_DECLARATIONS##n \
+	int  data; \
+	int  j; \
+	I2C_TRISTATE##n; \
+	I2C_SDA##n(1); \
+	data = 0; \
+	for(j = 0; j < 8; j++) { \
+		I2C_SCL##n(0); \
+		I2C_DELAY##n; \
+		I2C_SCL##n(1); \
+		I2C_DELAY##n; \
+		data <<= 1; \
+		data |= I2C_READ##n; \
+		I2C_DELAY##n; \
+	} \
+	send_ack##n(ack); \
+	return(data); \
+}
 
-/*-----------------------------------------------------------------------
+
+/*============================================================*/
+/*                         I2C Ops                            */
+/*============================================================*/
+
+/*--------------------------------------------------------------
  * Initialization
  */
-void i2c_init (int speed, int slaveaddr)
-{
-#if defined(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();
+
+#ifdef CONFIG_SYS_I2C_INIT_BOARD
+#define I2C_SOFT_INIT_ADAPTER(n) \
+static void soft_i2c_init##n(int speed, int slaveaddr) \
+{ \
+	/* 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.                  */ \
+	SOFT_I2C_INIT_BOARD; \
+}
 #else
-	/*
-	 * WARNING: Do NOT save speed in a static variable: if the
-	 * I2C routines are called before RAM is initialized (to read
-	 * the DIMM SPD, for instance), RAM won't be usable and your
-	 * system will crash.
-	 */
-	send_reset ();
-#endif
+#define I2C_SOFT_INIT_ADAPTER(n) \
+static void soft_i2c_init##n(int speed, int slaveaddr) \
+{ \
+	/* WARNING: Do NOT save speed in a static variable: if the	*/ \
+	/* I2C routines are called before RAM is initialized (to read	*/ \
+	/* the DIMM SPD, for instance), RAM won't be usable and your	*/ \
+	/* system will crash. */ \
+	send_reset##n(); \
 }
+#endif
+
 
 /*-----------------------------------------------------------------------
  * Probe to see if a chip is present.  Also good for checking for the
  * completion of EEPROM writes since the chip stops responding until
  * the write completes (typically 10mSec).
  */
-int i2c_probe(uchar addr)
-{
-	int rc;
-
-	/*
-	 * perform 1 byte write transaction with just address byte
-	 * (fake write)
-	 */
-	send_start();
-	rc = write_byte ((addr << 1) | 0);
-	send_stop();
-
-	return (rc ? 1 : 0);
+#define I2C_SOFT_PROBE(n) \
+static int soft_i2c_probe##n(uchar addr) \
+{ \
+	int rc; \
+	/* perform 1 byte write transaction with just address byte */ \
+	/* (fake write) */ \
+	send_start##n(); \
+	rc = write_byte##n((addr << 1) | 0); \
+	send_stop##n(); \
+	return (rc ? 1 : 0); \
 }
 
+
 /*-----------------------------------------------------------------------
  * Read bytes
  */
-int  i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	int shift;
-	PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
-		chip, addr, alen, buffer, len);
+#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
+#define RRSS_STOP	0
+#else
+#define RRSS_STOP	1
+#endif
 
 #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW
-	/*
-	 * EEPROM chips that implement "address overflow" are ones
-	 * like Catalyst 24WC04/08/16 which has 9/10/11 bits of
-	 * address and the extra bits end up in the "chip address"
-	 * bit slots. This makes a 24WC08 (1Kbyte) chip look like
-	 * four 256 byte chips.
-	 *
-	 * Note that we consider the length of the address field to
-	 * still be one byte because the extra address bits are
-	 * hidden in the chip address.
-	 */
-	chip |= ((addr >> (alen * 8)) & CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
-
-	PRINTD("i2c_read: fix addr_overflow: chip %02X addr %02X\n",
-		chip, addr);
-#endif
-
-	/*
-	 * Do the addressing portion of a write cycle to set the
-	 * chip's address pointer.  If the address length is zero,
-	 * don't do the normal write cycle to set the address pointer,
-	 * there is no address pointer in this chip.
-	 */
-	send_start();
-	if(alen > 0) {
-		if(write_byte(chip << 1)) {	/* write cycle */
-			send_stop();
-			PRINTD("i2c_read, no chip responded %02X\n", chip);
-			return(1);
-		}
-		shift = (alen-1) * 8;
-		while(alen-- > 0) {
-			if(write_byte(addr >> shift)) {
-				PRINTD("i2c_read, address not <ACK>ed\n");
-				return(1);
-			}
-			shift -= 8;
-		}
-
-		/* Some I2C chips need a stop/start sequence here,
-		 * other chips don't work with a full stop and need
-		 * only a start.  Default behaviour is to send the
-		 * stop/start sequence.
-		 */
-#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START
-		send_start();
+#define	DO_EEAD_OVF	chip |= ((addr >> (alen * 8)) & \
+				CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW); \
+			PRINTD("%s: fix addr_overflow: chip %02X addr %02X\n", \
+				__FUNCTION__, chip, addr);
+
 #else
-		send_stop();
-		send_start();
+#define	DO_EEAD_OVF
 #endif
-	}
-	/*
-	 * Send the chip address again, this time for a read cycle.
-	 * Then read the data.  On the last byte, we do a NACK instead
-	 * of an ACK(len == 0) to terminate the read.
-	 */
-	write_byte((chip << 1) | 1);	/* read cycle */
-	while(len-- > 0) {
-		*buffer++ = read_byte(len == 0);
-	}
-	send_stop();
-	return(0);
+
+#define I2C_SOFT_READ(n) \
+static int soft_i2c_read##n(uchar chip, uint addr, int alen, uchar *buffer, int len) \
+{ \
+	int shift; \
+	PRINTD("%s: chip %02X addr %02X alen %d buffer %p len %d\n", \
+		__FUNCTION__, chip, addr, alen, buffer, len); \
+	/* EEPROM chips that implement "address overflow" are ones	*/ \
+	/* like Catalyst 24WC04/08/16 which has 9/10/11 bits of		*/ \
+	/* address and the extra bits end up in the "chip address"	*/ \
+	/* bit slots. This makes a 24WC08 (1Kbyte) chip look like	*/ \
+	/* four 256 byte chips. */ \
+	/* */ \
+	/* Note that we consider the length of the address field to	*/ \
+	/* still be one byte because the extra address bits are		*/ \
+	/* hidden in the chip address. */ \
+	DO_EEAD_OVF \
+	/* Do the addressing portion of a write cycle to set the	*/ \
+	/* chip's address pointer.  If the address length is zero,	*/ \
+	/* don't do the normal write cycle to set the address pointer,	*/ \
+	/* there is no address pointer in this chip. */ \
+	send_start##n(); \
+	if(alen > 0) { \
+		if(write_byte##n(chip << 1)) {	/* write cycle */ \
+			send_stop##n(); \
+			PRINTD("%s, no chip responded %02X\n", __FUNCTION__, chip); \
+			return(1); \
+		} \
+		shift = (alen-1) * 8; \
+		while(alen-- > 0) { \
+			if(write_byte##n(addr >> shift)) { \
+				PRINTD("%s, address not <ACK>ed\n", __FUNCTION__); \
+				return(1); \
+			} \
+			shift -= 8; \
+		} \
+		if(RRSS_STOP) { \
+			send_stop##n();	/* reportedly some chips need a full stop */ \
+		} \
+		send_start##n(); \
+	} \
+	/* Send the chip address again, this time for a read cycle.	*/ \
+	/* Then read the data.  On the last byte, we do a NACK instead	*/ \
+	/* of an ACK(len == 0) to terminate the read. */ \
+	write_byte##n((chip << 1) | 1);	/* read cycle */ \
+	while(len-- > 0) { \
+		*buffer++ = read_byte##n(len == 0); \
+	} \
+	send_stop##n(); \
+	return(0); \
 }
 
+
 /*-----------------------------------------------------------------------
  * Write bytes
  */
-int  i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
-{
-	int shift, failures = 0;
-
-	PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n",
-		chip, addr, alen, buffer, len);
-
-	send_start();
-	if(write_byte(chip << 1)) {	/* write cycle */
-		send_stop();
-		PRINTD("i2c_write, no chip responded %02X\n", chip);
-		return(1);
-	}
-	shift = (alen-1) * 8;
-	while(alen-- > 0) {
-		if(write_byte(addr >> shift)) {
-			PRINTD("i2c_write, address not <ACK>ed\n");
-			return(1);
-		}
-		shift -= 8;
-	}
-
-	while(len-- > 0) {
-		if(write_byte(*buffer++)) {
-			failures++;
-		}
-	}
-	send_stop();
-	return(failures);
+#define I2C_SOFT_WRITE(n) \
+static int  soft_i2c_write##n(uchar chip, uint addr, int alen, uchar *buffer, int len) \
+{ \
+	int shift, failures = 0; \
+	PRINTD("%s: chip %02X addr %02X alen %d buffer %p len %d\n", \
+		__FUNCTION__, chip, addr, alen, buffer, len); \
+	send_start##n(); \
+	if(write_byte##n(chip << 1)) {	/* write cycle */ \
+		send_stop##n(); \
+		PRINTD("%s, no chip responded %02X\n", __FUNCTION__, chip); \
+		return(1); \
+	} \
+	shift = (alen-1) * 8; \
+	while(alen-- > 0) { \
+		if(write_byte##n(addr >> shift)) { \
+			PRINTD("%s, address not <ACK>ed\n", __FUNCTION__); \
+			return(1); \
+		} \
+		shift -= 8; \
+	} \
+	while(len-- > 0) { \
+		if(write_byte##n(*buffer++)) { \
+			failures++; \
+		} \
+	} \
+	send_stop##n(); \
+	return(failures); \
 }
+
+
+#define I2C_SOFT_GET_BUS_SPEED(n) \
+static unsigned int soft_i2c_get_bus_speed##n(void) \
+{ \
+	return CONFIG_SYS_SOFT_I2C##n##_SPEED; \
+}
+
+
+#define I2C_SOFT_SET_BUS_SPEED(n) \
+static unsigned int soft_i2c_set_bus_speed##n(unsigned int speed) \
+{ \
+	if (speed != CONFIG_SYS_SOFT_I2C##n##_SPEED) \
+		return -1; \
+	return(speed); \
+}
+
+
+/*============================================================*/
+/*                  Here comes the real stuff                 */
+/*============================================================*/
+I2C_SOFT_SEND_START()
+I2C_SOFT_SEND_STOP()
+I2C_SOFT_SEND_ACK()
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET()
+#endif
+I2C_SOFT_WRITE_BYTE()
+I2C_SOFT_READ_BYTE()
+I2C_SOFT_INIT_ADAPTER()
+I2C_SOFT_PROBE()
+I2C_SOFT_READ()
+I2C_SOFT_WRITE()
+I2C_SOFT_GET_BUS_SPEED()
+I2C_SOFT_SET_BUS_SPEED()
+
+#if defined(I2C_SOFT_DECLARATIONS2)
+I2C_SOFT_SEND_START(2)
+I2C_SOFT_SEND_STOP(2)
+I2C_SOFT_SEND_ACK(2)
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET(2)
+#endif
+I2C_SOFT_WRITE_BYTE(2)
+I2C_SOFT_READ_BYTE(2)
+I2C_SOFT_INIT_ADAPTER(2)
+I2C_SOFT_PROBE(2)
+I2C_SOFT_READ(2)
+I2C_SOFT_WRITE(2)
+I2C_SOFT_GET_BUS_SPEED(2)
+I2C_SOFT_SET_BUS_SPEED(2)
+#endif
+
+#if defined(I2C_SOFT_DECLARATIONS3)
+I2C_SOFT_SEND_START(3)
+I2C_SOFT_SEND_STOP(3)
+I2C_SOFT_SEND_ACK(3)
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET(3)
+#endif
+I2C_SOFT_WRITE_BYTE(3)
+I2C_SOFT_READ_BYTE(3)
+I2C_SOFT_INIT_ADAPTER(3)
+I2C_SOFT_PROBE(3)
+I2C_SOFT_READ(3)
+I2C_SOFT_WRITE(3)
+I2C_SOFT_GET_BUS_SPEED(3)
+I2C_SOFT_SET_BUS_SPEED(3)
+#endif
+
+#if defined(I2C_SOFT_DECLARATIONS4)
+I2C_SOFT_SEND_START(4)
+I2C_SOFT_SEND_STOP(4)
+I2C_SOFT_SEND_ACK(4)
+#if !defined(CONFIG_SYS_I2C_INIT_BOARD)
+I2C_SOFT_SEND_RESET(4)
+#endif
+I2C_SOFT_WRITE_BYTE(4)
+I2C_SOFT_READ_BYTE(4)
+I2C_SOFT_INIT_ADAPTER(4)
+I2C_SOFT_PROBE(4)
+I2C_SOFT_READ(4)
+I2C_SOFT_WRITE(4)
+I2C_SOFT_GET_BUS_SPEED(4)
+I2C_SOFT_SET_BUS_SPEED(4)
+#endif
+
+i2c_adap_t	soft_i2c_adap[] = {
+	{
+		.init		=	soft_i2c_init,
+		.probe		=	soft_i2c_probe,
+		.read		=	soft_i2c_read,
+		.write		=	soft_i2c_write,
+		.set_bus_speed	=	soft_i2c_set_bus_speed,
+		.get_bus_speed	=	soft_i2c_get_bus_speed,
+		.speed		=	CONFIG_SYS_SOFT_I2C_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C_SLAVE,
+		.init_done	=	0,
+		.name		=	"soft-i2c"
+	},
+#if defined(I2C_SOFT_DECLARATIONS2)
+	{
+		.init		=	soft_i2c_init2,
+		.probe		=	soft_i2c_probe2,
+		.read		=	soft_i2c_read2,
+		.write		=	soft_i2c_write2,
+		.set_bus_speed	=	soft_i2c_set_bus_speed2,
+		.get_bus_speed	=	soft_i2c_get_bus_speed2,
+		.speed		=	CONFIG_SYS_SOFT_I2C2_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C2_SLAVE,
+		.init_done	=	0,
+		.name		=	"soft-i2c#2"
+	},
+#endif
+#if defined(I2C_SOFT_DECLARATIONS3)
+	{
+		.init		=	soft_i2c_init3,
+		.probe		=	soft_i2c_probe3,
+		.read		=	soft_i2c_read3,
+		.write		=	soft_i2c_write3,
+		.set_bus_speed	=	soft_i2c_set_bus_speed3,
+		.get_bus_speed	=	soft_i2c_get_bus_speed3,
+		.speed		=	CONFIG_SYS_SOFT_I2C3_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C3_SLAVE,
+		.init_done	=	0,
+		.name		=	"soft-i2c#3"
+	},
+#endif
+#if defined(I2C_SOFT_DECLARATIONS4)
+	{
+		.init		=	soft_i2c_init4,
+		.probe		=	soft_i2c_probe4,
+		.read		=	soft_i2c_read4,
+		.write		=	soft_i2c_write4,
+		.set_bus_speed	=	soft_i2c_set_bus_speed4,
+		.get_bus_speed	=	soft_i2c_get_bus_speed4,
+		.speed		=	CONFIG_SYS_SOFT_I2C4_SPEED,
+		.slaveaddr	=	CONFIG_SYS_SOFT_I2C4_SLAVE,
+		.init_done	=	0,
+		.name		=	"soft-i2c#4"
+	},
+#endif
+};


More information about the U-Boot mailing list