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)----