summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2008-04-22 01:44:20 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2008-04-22 01:44:20 +0000
commitb70db97df6806d3452b9ce89d83b5b24b0ac45da (patch)
tree5f0f68a8480765e244d0684ea51b6aa455d5a1f0 /sys/arch/sparc64/dev
parent396152b0049c394b7709787db5afd7b98b6944ce (diff)
Works better, but still needs debug on to work..
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r--sys/arch/sparc64/dev/mgiic.c224
1 files changed, 131 insertions, 93 deletions
diff --git a/sys/arch/sparc64/dev/mgiic.c b/sys/arch/sparc64/dev/mgiic.c
index f122477923a..2187d2f01a6 100644
--- a/sys/arch/sparc64/dev/mgiic.c
+++ b/sys/arch/sparc64/dev/mgiic.c
@@ -1,6 +1,6 @@
-/* $OpenBSD: mgiic.c,v 1.1 2008/04/21 04:50:23 deraadt Exp $ */
+/* $OpenBSD: mgiic.c,v 1.2 2008/04/22 01:44:19 deraadt Exp $ */
/*
- * Copyright (c) 2008 Mark Kettenis <kettenis@openbsd.org>
+ * Copyright (c) 2008 Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -24,7 +24,6 @@
#include <uvm/uvm_extern.h>
-#define _SPARC_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <machine/autoconf.h>
#include <machine/openfirm.h>
@@ -32,36 +31,36 @@
#include <dev/i2c/i2cvar.h>
#include <sparc64/dev/ofwi2cvar.h>
-#define MGIIC_SLAVEADDR 0x00
-#define MGIIC_SLAVEXADDR 0x08
-#define MGIIC_DATA 0x10
-#define MGIIC_CONTROL 0x18
-#define MGIIC_CONTROL_IEN 0x80
-#define MGIIC_CONTROL_ENAB 0x40
-#define MGIIC_CONTROL_STA 0x20
-#define MGIIC_CONTROL_STP 0x10
-#define MGIIC_CONTROL_IFLG 0x08
-#define MGIIC_CONTROL_AAK 0x04
-#define MGIIC_STATUS 0x20
-#define MGIIC_STATUS_BUSERR 0x00
-#define MGIIC_STATUS_STARTSENT 0x08
-#define MGIIC_STATUS_REPEATSTART 0x10
-#define MGIIC_STATUS_ADDR_W_ACKR 0x18
-#define MGIIC_STATUS_ADDR_W_NOACKR 0x20
-#define MGIIC_STATUS_MDATA_ACKR 0x28
-#define MGIIC_STATUS_MDATA_NOACKR 0x30
-#define MGIIC_STATUS_ARBLOST 0x38
-#define MGIIC_STATUS_ADDR_R_ACKR 0x40
-#define MGIIC_STATUS_ADDR_R_NOACKR 0x48
-#define MGIIC_STATUS_MDATA_ACKT 0x50
-#define MGIIC_STATUS_MDATA_NOACKT 0x58
-#define MGIIC_STATUS_SADDR_W_ACKT 0x60
-#define MGIIC_STATUS_ARBLOST_SLW_ACKT 0x68
-#define MGIIC_STATUS_GC_TACK 0x70
-#define MGIIC_STATUS_ARBLOST_GC_ACKT 0x78
-#define MGIIC_STATUS_IDLE 0xf8
-#define MGIIC_CLOCKCONTROL 0x28
-#define MGIIC_SOFTRESET 0x30
+#define MGSLAVEADDR 0x00
+#define MGSLAVEXADDR 0x08
+#define MGDATA 0x10
+#define MGCONTROL 0x18
+#define MGCONTROL_IEN 0x80
+#define MGCONTROL_ENAB 0x40
+#define MGCONTROL_STA 0x20
+#define MGCONTROL_STP 0x10
+#define MGCONTROL_IFLG 0x08
+#define MGCONTROL_AAK 0x04
+#define MGSTATUS 0x20
+#define MGSTATUS_BUSERR 0x00
+#define MGSTATUS_STARTSENT 0x08
+#define MGSTATUS_REPEATSTART 0x10
+#define MGSTATUS_ADDR_W_ACKR 0x18
+#define MGSTATUS_ADDR_W_NOACKR 0x20
+#define MGSTATUS_MDATA_ACKR 0x28
+#define MGSTATUS_MDATA_NOACKR 0x30
+#define MGSTATUS_ARBLOST 0x38
+#define MGSTATUS_ADDR_R_ACKR 0x40
+#define MGSTATUS_ADDR_R_NOACKR 0x48
+#define MGSTATUS_MDATA_ACKT 0x50
+#define MGSTATUS_MDATA_NOACKT 0x58
+#define MGSTATUS_SADDR_W_ACKT 0x60
+#define MGSTATUS_ARBLOST_SLW_ACKT 0x68
+#define MGSTATUS_GC_TACK 0x70
+#define MGSTATUS_ARBLOST_GC_ACKT 0x78
+#define MGSTATUS_IDLE 0xf8
+#define MGCLOCKCONTROL 0x28
+#define MGSOFTRESET 0x30
struct mgiic_softc {
struct device sc_dev;
@@ -92,7 +91,8 @@ void mgiic_i2c_release_bus(void *, int);
int mgiic_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
size_t, void *, size_t, int);
-int mgiic_xmit(struct mgiic_softc *, u_int8_t, const u_int8_t *, size_t);
+int mgiic_xmit(struct mgiic_softc *, u_int8_t, const u_int8_t *,
+ size_t);
int mgiic_recv(struct mgiic_softc *, u_int8_t, u_int8_t *, size_t);
volatile u_int8_t mgiic_read(struct mgiic_softc *, bus_size_t);
volatile void mgiic_write(struct mgiic_softc *, bus_size_t, u_int8_t);
@@ -107,13 +107,10 @@ mgiic_match(struct device *parent, void *match, void *aux)
if (strcmp(ma->ma_name, "i2c") != 0)
return (0);
-
if (OF_getprop(ma->ma_node, "compatible", compat, sizeof(compat)) == -1)
return (0);
-
if (strcmp(compat, "fire-i2c") == 0)
return (1);
-
return (0);
}
@@ -123,7 +120,6 @@ mgiic_attach(struct device *parent, struct device *self, void *aux)
struct mgiic_softc *sc = (struct mgiic_softc *)self;
struct mainbus_attach_args *ma = aux;
struct i2cbus_attach_args iba;
- int i;
sc->sc_bt = ma->ma_bustag;
@@ -133,17 +129,14 @@ mgiic_attach(struct device *parent, struct device *self, void *aux)
return;
}
- printf(": ");
- for (i = 0; i < 7; i++)
- printf("%04x ", mgiic_read(sc, i * 8));
- printf("\n");
-
rw_init(&sc->sc_lock, "iiclk");
sc->sc_i2c.ic_cookie = sc;
sc->sc_i2c.ic_acquire_bus = mgiic_i2c_acquire_bus;
sc->sc_i2c.ic_release_bus = mgiic_i2c_release_bus;
sc->sc_i2c.ic_exec = mgiic_i2c_exec;
+ printf("\n");
+
bzero(&iba, sizeof(iba));
iba.iba_name = "iic";
iba.iba_tag = &sc->sc_i2c;
@@ -179,7 +172,7 @@ mgiic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr,
const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
{
struct mgiic_softc *sc = arg;
- int ret = 0, i = 0;
+ int ret = 0;
if (addr & ~0x7f)
return (1);
@@ -188,8 +181,9 @@ mgiic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr,
flags |= I2C_F_POLL;
if (cmdlen > 0)
- if (mgiic_xmit(sc, addr & 0x7f, cmdbuf, cmdlen) != 0)
- return (1);
+ ret = mgiic_xmit(sc, addr & 0x7f, cmdbuf, cmdlen);
+ if (ret != 0)
+ goto done;
if (len > 0) {
if (I2C_OP_WRITE_P(op))
@@ -197,10 +191,8 @@ mgiic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr,
else
ret = mgiic_recv(sc, addr & 0x7f, buf, len);
}
+done:
printf("e%d\n", ret);
- for (i = 0; i < 7; i++)
- printf("%04x ", mgiic_read(sc, i * 8));
- printf("\n");
return (ret);
}
@@ -208,85 +200,134 @@ int
mgiic_xmit(struct mgiic_softc *sc, u_int8_t addr, const u_int8_t *buf,
size_t len)
{
- int err = 1;
- int i;
+ int err = 1, i = 0;
- mgiic_control(sc, MGIIC_CONTROL_STA, 0);
+top:
+ printf("xmit s%02x STA ", mgiic_read(sc, MGSTATUS));
+ mgiic_control(sc, MGCONTROL_STA, MGCONTROL_IFLG);
if (mgiic_poll(sc))
goto bail;
- if (mgiic_read(sc, MGIIC_STATUS) != 0x08)
+ printf("s%02x ", mgiic_read(sc, MGSTATUS));
+ if (mgiic_read(sc, MGSTATUS) != MGSTATUS_STARTSENT)
goto bail;
- mgiic_write(sc, MGIIC_DATA, addr << 1);
- mgiic_control(sc, 0, MGIIC_CONTROL_IFLG);
-
- for (i = 0; i < len; i++) {
+ mgiic_write(sc, MGDATA, addr << 1);
+ printf("a%02x ", addr << 1);
+ mgiic_control(sc, 0, MGCONTROL_IFLG);
+
+ while (i < len) {
if (mgiic_poll(sc))
- goto bail;
- switch (mgiic_read(sc, MGIIC_STATUS)) {
- case 0x18:
- case 0x20:
- case 0x28:
- case 0x30:
- mgiic_write(sc, MGIIC_DATA, buf[i]);
+ goto bail;
+ printf("s%02x ", mgiic_read(sc, MGSTATUS));
+ switch (mgiic_read(sc, MGSTATUS)) {
+ case MGSTATUS_ADDR_W_ACKR:
+ case MGSTATUS_MDATA_ACKR:
+ mgiic_write(sc, MGDATA, buf[i]);
printf("w%02x ", buf[i]);
- mgiic_control(sc, 0, MGIIC_CONTROL_IFLG);
+ i++;
+ mgiic_control(sc, 0, MGCONTROL_IFLG);
break;
+ case MGSTATUS_ADDR_W_NOACKR:
+ case MGSTATUS_MDATA_NOACKR:
+ mgiic_write(sc, MGDATA, buf[i]);
+ printf("w%02x ", buf[i]);
+ mgiic_control(sc, 0, MGCONTROL_IFLG);
+ break;
+ case MGSTATUS_BUSERR:
+ mgiic_control(sc, MGCONTROL_STP, MGCONTROL_IFLG);
+ i = 0;
+ if (mgiic_poll(sc))
+ goto bail;
+ goto top;
+ case MGSTATUS_IDLE:
default:
+ err = 1;
goto bail;
}
}
+ printf("OK ");
err = 0;
bail:
- mgiic_control(sc, MGIIC_CONTROL_STP, MGIIC_CONTROL_IFLG);
- while (mgiic_read(sc, MGIIC_STATUS) != 0xf8)
+ if (err)
+ printf("BAIL STP s%02x\n", mgiic_read(sc, MGSTATUS));
+ mgiic_control(sc, MGCONTROL_STP, MGCONTROL_IFLG);
+ while (mgiic_read(sc, MGSTATUS) != MGSTATUS_IDLE)
;
+ printf("s%02x\n", mgiic_read(sc, MGSTATUS));
return (err);
}
int
mgiic_recv(struct mgiic_softc *sc, u_int8_t addr, u_int8_t *buf, size_t len)
{
- int err = 1;
- int i;
-
- mgiic_control(sc, MGIIC_CONTROL_STA, 0);
+ int err = 1, i = 0;
+ printf("recv s%02x ", mgiic_read(sc, MGSTATUS));
+ mgiic_control(sc, MGCONTROL_STA, MGCONTROL_IFLG);
if (mgiic_poll(sc))
goto bail;
- if (mgiic_read(sc, MGIIC_STATUS) != 0x08)
+
+ printf("s%02x ", mgiic_read(sc, MGSTATUS));
+ if (mgiic_read(sc, MGSTATUS) != MGSTATUS_STARTSENT)
goto bail;
- mgiic_write(sc, MGIIC_DATA, (addr << 1) | 0x01);
- mgiic_control(sc, 0, MGIIC_CONTROL_IFLG);
+re_address:
+ mgiic_write(sc, MGDATA, (addr << 1) | 0x01);
+ printf("a%02x ", (addr << 1) | 0x01);
+ mgiic_control(sc, 0, MGCONTROL_IFLG);
- for (i = 0; i < len; ) {
+ while (i < len) {
if (mgiic_poll(sc))
goto bail;
- switch (mgiic_read(sc, MGIIC_STATUS)) {
- case 0x40:
- mgiic_control(sc, 0, MGIIC_CONTROL_IFLG);
- break;
- case 0x48:
- mgiic_control(sc, MGIIC_CONTROL_STA, MGIIC_CONTROL_IFLG);
+ printf("s%02x ", mgiic_read(sc, MGSTATUS));
+ switch (mgiic_read(sc, MGSTATUS)) {
+ case MGSTATUS_ADDR_R_ACKR:
+ if (len - i > 1)
+ mgiic_control(sc, MGCONTROL_AAK, MGCONTROL_IFLG);
+ else
+ mgiic_control(sc, 0, MGCONTROL_IFLG);
+ break;
+ case MGSTATUS_ADDR_R_NOACKR:
+ mgiic_control(sc, MGCONTROL_STA, MGCONTROL_IFLG);
break;
- case 0x50:
- case 0x58:
- buf[i] = mgiic_read(sc, MGIIC_DATA);
+ case MGSTATUS_REPEATSTART:
+ goto re_address;
+ case MGSTATUS_MDATA_ACKT:
+ buf[i] = mgiic_read(sc, MGDATA);
printf("r%02x ", buf[i]);
i++;
- mgiic_control(sc, MGIIC_CONTROL_AAK, MGIIC_CONTROL_IFLG);
+ if (len - i > 1)
+ mgiic_control(sc, MGCONTROL_AAK, MGCONTROL_IFLG);
+ else
+ mgiic_control(sc, 0, MGCONTROL_IFLG|MGCONTROL_AAK);
+ break;
+ case MGSTATUS_MDATA_NOACKT:
+ buf[i] = mgiic_read(sc, MGDATA);
+ printf("r%02x ", buf[i]);
+ i++;
+ if (len == i) {
+ printf("DONE ");
+ err = 0;
+ goto bail;
+ }
+ printf("SHORT ");
+ goto bail;
break;
default:
+ printf("BAD");
goto bail;
}
}
+ printf("OK ");
err = 0;
bail:
- mgiic_control(sc, MGIIC_CONTROL_STP, MGIIC_CONTROL_IFLG);
- while (mgiic_read(sc, MGIIC_STATUS) != 0xf8)
+ if (err)
+ printf("BAIL STP s%02x\n", mgiic_read(sc, MGSTATUS));
+ mgiic_control(sc, MGCONTROL_STP, MGCONTROL_IFLG | MGCONTROL_AAK);
+ while (mgiic_read(sc, MGSTATUS) != MGSTATUS_IDLE)
;
+ printf("s%02x\n", mgiic_read(sc, MGSTATUS));
return (err);
}
@@ -313,9 +354,8 @@ mgiic_control(struct mgiic_softc *sc, u_int8_t on, u_int8_t off)
{
u_int8_t val;
- val = (mgiic_read(sc, MGIIC_CONTROL) | on) & ~off;
- printf("s%02xc%02x ", mgiic_read(sc, MGIIC_STATUS), val);
- return mgiic_write(sc, MGIIC_CONTROL, val);
+ val = (mgiic_read(sc, MGCONTROL) | on) & ~off;
+ mgiic_write(sc, MGCONTROL, val);
}
int
@@ -324,10 +364,8 @@ mgiic_poll(struct mgiic_softc *sc)
int i;
for (i = 0; i < 1000; i++) {
- if (mgiic_read(sc, MGIIC_CONTROL) & MGIIC_CONTROL_IFLG) {
- printf("s%02x ", mgiic_read(sc, MGIIC_STATUS));
+ if (mgiic_read(sc, MGCONTROL) & MGCONTROL_IFLG)
return (0);
- }
delay(100);
}
return (1);