2byte read/write on SMBus

KIYOHARA Takashi <[email protected]>
Newsgroups gmane.os.netbsd.ports.evbmips
Message-ID <[email protected]>
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
smbus.diff (text/plain, 3.1 KB)
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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.