Subject: 2byte read/write on SMBus
To: None <port-evbmips@NetBSD.org, shige@netbsd.org>
From: KIYOHARA Takashi <kiyohara@kk.iij4u.or.jp>
List: port-evbmips
Date: 05/21/2006 03:09:36
----Next_Part(Sun_May_21_03:09:36_2006_393)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi! shige and all,


Our OMSAL400 should read/write 2 bytes on SMBus.  It is possible by the
addition of the following functions to a present mounting. 

Have you any idea?  ;-)

Thanks,
--
kiyohara

----Next_Part(Sun_May_21_03:09:36_2006_393)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="smbus.diff"

Index: sys/arch/mips/alchemy/dev/ausmbus_psc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/ausmbus_psc.c,v
retrieving revision 1.4
diff -u -r1.4 ausmbus_psc.c
--- sys/arch/mips/alchemy/dev/ausmbus_psc.c	27 Mar 2006 19:03:50 -0000	1.4
+++ sys/arch/mips/alchemy/dev/ausmbus_psc.c	20 May 2006 17:24:37 -0000
@@ -87,8 +87,11 @@
 /* subroutine functions for i2c_controller */
 static int	ausmbus_receive_1(struct ausmbus_softc *, uint8_t *);
 static int	ausmbus_read_1(struct ausmbus_softc *, uint8_t, uint8_t *);
+static int	ausmbus_read_2(struct ausmbus_softc *, uint8_t, uint8_t *);
 static int	ausmbus_send_1(struct ausmbus_softc *, uint8_t);
 static int	ausmbus_write_1(struct ausmbus_softc *, uint8_t, uint8_t);
+static int	ausmbus_write_2(struct ausmbus_softc *, uint8_t, uint8_t,
+				uint8_t);
 static int	ausmbus_wait_mastertx(struct ausmbus_softc *sc);
 static int	ausmbus_wait_masterrx(struct ausmbus_softc *sc);
 static int	ausmbus_initiate_xfer(void *, i2c_addr_t, int);
@@ -228,6 +231,11 @@
 		return ausmbus_read_1(sc, *cmd, buf);
 	}
 
+	/* Read word */
+	if ((I2C_OP_READ_P(op)) && (cmdlen == 1) && (buflen == 2)) {
+		return ausmbus_read_2(sc, *cmd, buf);
+	}
+
 	/* Send byte */
 	if ((I2C_OP_WRITE_P(op)) && (cmdlen == 0) && (buflen == 1)) {
 		return ausmbus_send_1(sc, *buf);
@@ -238,11 +246,14 @@
 		return ausmbus_write_1(sc, *cmd, *buf);
 	}
 
+	/* Write word */
+	if ((I2C_OP_WRITE_P(op)) && (cmdlen == 1) && (buflen == 2)) {
+		return ausmbus_write_2(sc, *cmd, *buf, *(buf + 1));
+	}
+
 	/*
 	 * XXX: TODO Please Support other protocols defined in SMBus 2.0 
 	 * - Quick Command
-	 * - Write word
-	 * - Read word
 	 * - Process call
 	 * - Block write/read
 	 * - Clock write-block read process cal
@@ -298,6 +309,39 @@
 }
 
 static int
+ausmbus_read_2(struct ausmbus_softc *sc, uint8_t cmd, uint8_t *vp)
+{
+	int error;
+
+	error = ausmbus_initiate_xfer(sc, sc->sc_smbus_slave_addr, I2C_F_WRITE);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_write_byte(sc, cmd, I2C_F_READ);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_initiate_xfer(sc, sc->sc_smbus_slave_addr, I2C_F_READ);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_read_byte(sc, vp, 0);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_read_byte(sc, vp + 1, I2C_F_STOP);
+	if (error != 0) {
+		return error;
+	}
+
+	return 0;
+}
+
+static int
 ausmbus_send_1(struct ausmbus_softc *sc, uint8_t val)
 {
 	int error;
@@ -339,6 +383,34 @@
 }
 
 static int
+ausmbus_write_2(struct ausmbus_softc *sc, uint8_t cmd, uint8_t vh, uint8_t vl)
+{
+	int error;
+
+	error = ausmbus_initiate_xfer(sc, sc->sc_smbus_slave_addr, I2C_F_WRITE);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_write_byte(sc, cmd, 0);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_write_byte(sc, vh, 0);
+	if (error != 0) {
+		return error;
+	}
+
+	error = ausmbus_write_byte(sc, vl, I2C_F_STOP);
+	if (error != 0) {
+		return error;
+	}
+
+	return 0;
+}
+
+static int
 ausmbus_wait_mastertx(struct ausmbus_softc *sc)
 {
 	uint32_t v;

----Next_Part(Sun_May_21_03:09:36_2006_393)----