summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sparc64/dev/ofwi2c.c7
-rw-r--r--sys/arch/sparc64/dev/pcfiic_ebus.c30
-rw-r--r--sys/dev/ic/pcf8584.c60
-rw-r--r--sys/dev/ic/pcf8584var.h4
4 files changed, 59 insertions, 42 deletions
diff --git a/sys/arch/sparc64/dev/ofwi2c.c b/sys/arch/sparc64/dev/ofwi2c.c
index d56c2e90485..bca19895827 100644
--- a/sys/arch/sparc64/dev/ofwi2c.c
+++ b/sys/arch/sparc64/dev/ofwi2c.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofwi2c.c,v 1.3 2006/02/09 12:16:25 dlg Exp $ */
+/* $OpenBSD: ofwi2c.c,v 1.4 2006/06/14 01:15:19 deraadt Exp $ */
/*
* Copyright (c) 2006 Theo de Raadt
@@ -46,7 +46,8 @@ ofwiic_pci_scan(struct device *self, struct i2cbus_attach_args *iba, void *aux)
if (name[0] == '\0')
continue;
- if (strcmp(name, "i2c-smbus") == 0)
+ if (strcmp(name, "i2c-smbus") == 0 ||
+ strcmp(name, "i2c") == 0)
ofwiic_scan(self, iba, &node);
}
}
@@ -75,7 +76,7 @@ ofwiic_scan(struct device *self, struct i2cbus_attach_args *iba, void *aux)
memset(&ia, 0, sizeof(ia));
ia.ia_tag = iba->iba_tag;
- ia.ia_addr = reg[1] >> 1;
+ ia.ia_addr = (reg[0] << 7) | (reg[1] >> 1);
ia.ia_name = name;
ia.ia_cookie = &node;
diff --git a/sys/arch/sparc64/dev/pcfiic_ebus.c b/sys/arch/sparc64/dev/pcfiic_ebus.c
index 126ac46a9bc..6084b6dec9e 100644
--- a/sys/arch/sparc64/dev/pcfiic_ebus.c
+++ b/sys/arch/sparc64/dev/pcfiic_ebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcfiic_ebus.c,v 1.3 2006/02/09 12:16:25 dlg Exp $ */
+/* $OpenBSD: pcfiic_ebus.c,v 1.4 2006/06/14 01:15:19 deraadt Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -64,10 +64,11 @@ pcfiic_ebus_match(struct device *parent, void *match, void *aux)
if (OF_getprop(ea->ea_node, "compatible", compat, sizeof(compat)) == -1)
return (0);
- if (strcmp(compat, "i2cpcf,8584") != 0)
- return (0);
+ if (strcmp(compat, "i2cpcf,8584") ||
+ strcmp(compat, "SUNW,bbc-i2c"))
+ return (1);
- return (1);
+ return (0);
}
void
@@ -80,17 +81,15 @@ pcfiic_ebus_attach(struct device *parent, struct device *self, void *aux)
sc->sc_iot = ea->ea_memtag;
- if (ea->ea_nregs != 1) {
- printf(": expected 1 register, got %d\n", ea->ea_nregs);
+ if (ea->ea_nregs < 1 || ea->ea_nregs > 2) {
+ printf(": expected 1 or 2 registers, got %d\n", ea->ea_nregs);
return;
}
if (OF_getprop(ea->ea_node, "own-address", &addr, sizeof(addr)) == -1) {
- printf(": unable to get own address\n");
- return;
- }
- if (addr == 0x00 || addr > 0xff) {
- printf(": invalid address on I2C bus\n");
+ addr = 0xaa;
+ } else if (addr == 0x00 || addr > 0xff) {
+ printf(": invalid address on I2C bus");
return;
}
@@ -100,6 +99,15 @@ pcfiic_ebus_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (ea->ea_nregs == 2) {
+ if (ebus_bus_map(sc->sc_iot, 0, EBUS_PADDR_FROM_REG(&ea->ea_regs[1]),
+ ea->ea_regs[1].size, 0, 0, &sc->sc_ioh2) != 0) {
+ printf(": can't map 2nd register space\n");
+ return;
+ }
+ sc->sc_master = 1;
+ }
+
if (ea->ea_nintrs >= 1)
esc->esc_ih = bus_intr_establish(sc->sc_iot, ea->ea_intrs[0],
IPL_BIO, 0, pcfiic_intr, sc, self->dv_xname);
diff --git a/sys/dev/ic/pcf8584.c b/sys/dev/ic/pcf8584.c
index e709479a3af..b23ec11a33e 100644
--- a/sys/dev/ic/pcf8584.c
+++ b/sys/dev/ic/pcf8584.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcf8584.c,v 1.2 2006/02/01 11:09:16 dlg Exp $ */
+/* $OpenBSD: pcf8584.c,v 1.3 2006/06/14 01:15:17 deraadt Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -85,18 +85,12 @@ int pcfiic_xmit(struct pcfiic_softc *, u_int8_t, const u_int8_t *,
int pcfiic_recv(struct pcfiic_softc *, u_int8_t, u_int8_t *,
size_t);
-u_int8_t pcfiic_read(struct pcfiic_softc *, bus_size_t);
-void pcfiic_write(struct pcfiic_softc *, bus_size_t, u_int8_t);
+volatile u_int8_t pcfiic_read(struct pcfiic_softc *, bus_size_t);
+volatile void pcfiic_write(struct pcfiic_softc *, bus_size_t, u_int8_t);
+void pcfiic_choose_bus(struct pcfiic_softc *, u_int8_t);
int pcfiic_wait_nBB(struct pcfiic_softc *);
int pcfiic_wait_pin(struct pcfiic_softc *, volatile u_int8_t *);
-#define pcfiic_ctrl_start(_sc) pcfiic_write((_sc), PCF_S1, \
- PCF_CTRL_START)
-#define pcfiic_ctrl_repstart(_sc) pcf_write((_sc), PCF_S1, \
- PCF_CTRL_REPSTART)
-#define pcfiic_ctrl_stop(_sc) pcfiic_write((_sc), PCF_S1, \
- PCF_CTRL_STOP)
-
void
pcfiic_attach(struct pcfiic_softc *sc, i2c_addr_t addr,
void (*scan_func)(struct device *, struct i2cbus_attach_args *, void *),
@@ -113,11 +107,15 @@ pcfiic_attach(struct pcfiic_softc *sc, i2c_addr_t addr,
pcfiic_write(sc, PCF_S1, PCF_CTRL_PIN|PCF_CTRL_ES1);
pcfiic_write(sc, PCF_S0, PCF_CLOCK_12);
- pcfiic_write(sc, PCF_S1, PCF_CTRL_PIN | PCF_CTRL_ESO | PCF_CTRL_ENI |
- PCF_CTRL_ACK);
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_IDLE);
+
+// pcfiic_read(sc, PCF_S0); /* dummy read */
printf("\n");
+ if (sc->sc_master)
+ pcfiic_choose_bus(sc, 0);
+
lockinit(&sc->sc_lock, PRIBIO | PCATCH, "iiclk", 0, 0);
sc->sc_i2c.ic_cookie = sc;
sc->sc_i2c.ic_acquire_bus = pcfiic_i2c_acquire_bus;
@@ -175,16 +173,19 @@ pcfiic_i2c_exec(void *arg, i2c_op_t op, i2c_addr_t addr,
if (cold || sc->sc_poll)
flags |= I2C_F_POLL;
+ if (sc->sc_master)
+ pcfiic_choose_bus(sc, addr >> 7);
+
if (cmdlen > 0) {
- if (pcfiic_xmit(sc, addr, cmdbuf, cmdlen) != 0)
+ if (pcfiic_xmit(sc, addr & 0x7f, cmdbuf, cmdlen) != 0)
return (1);
}
if (len > 0) {
if (I2C_OP_WRITE_P(op))
- ret = pcfiic_xmit(sc, addr, buf, len);
+ ret = pcfiic_xmit(sc, addr & 0x7f, buf, len);
else
- ret = pcfiic_recv(sc, addr, buf, len);
+ ret = pcfiic_recv(sc, addr & 0x7f, buf, len);
}
return (ret);
@@ -198,13 +199,11 @@ pcfiic_xmit(struct pcfiic_softc *sc, u_int8_t addr, const u_int8_t *buf,
int err = 0;
volatile u_int8_t r;
-
while ((pcfiic_read(sc, PCF_S1) & PCF_STAT_nBB) == 0)
;
pcfiic_write(sc, PCF_S0, addr << 1);
-
- pcfiic_write(sc, PCF_S1, 0xc5);
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_START);
for (i = 0; i <= len; i++) {
while ((r = pcfiic_read(sc, PCF_S1)) & PCF_STAT_PIN)
@@ -219,7 +218,7 @@ pcfiic_xmit(struct pcfiic_softc *sc, u_int8_t addr, const u_int8_t *buf,
pcfiic_write(sc, PCF_S0, buf[i]);
}
- pcfiic_write(sc, PCF_S1, 0xc3);
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_STOP);
return (err);
}
@@ -235,25 +234,25 @@ pcfiic_recv(struct pcfiic_softc *sc, u_int8_t addr, u_int8_t *buf, size_t len)
if (pcfiic_wait_nBB(sc) != 0)
return (1);
-
- pcfiic_ctrl_start(sc);
+
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_START);
i = 0;
for (i = 0; i <= len; i++) {
if (pcfiic_wait_pin(sc, &r) != 0) {
- pcfiic_ctrl_stop(sc);
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_STOP);
return (1);
}
if ((i != len) && (r & PCF_STAT_LRB)) {
- pcfiic_ctrl_stop(sc);
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_STOP);
return (1);
}
if (i == len - 1) {
pcfiic_write(sc, PCF_S1, PCF_CTRL_ESO);
} else if (i == len) {
- pcfiic_ctrl_stop(sc);
+ pcfiic_write(sc, PCF_S1, PCF_CTRL_STOP);
}
r = pcfiic_read(sc, PCF_S0);
@@ -264,8 +263,7 @@ pcfiic_recv(struct pcfiic_softc *sc, u_int8_t addr, u_int8_t *buf, size_t len)
return (err);
}
-
-u_int8_t
+volatile u_int8_t
pcfiic_read(struct pcfiic_softc *sc, bus_size_t r)
{
bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 1,
@@ -273,7 +271,7 @@ pcfiic_read(struct pcfiic_softc *sc, bus_size_t r)
return (bus_space_read_1(sc->sc_iot, sc->sc_ioh, r));
}
-void
+volatile void
pcfiic_write(struct pcfiic_softc *sc, bus_size_t r, u_int8_t v)
{
bus_space_write_1(sc->sc_iot, sc->sc_ioh, r, v);
@@ -281,6 +279,14 @@ pcfiic_write(struct pcfiic_softc *sc, bus_size_t r, u_int8_t v)
BUS_SPACE_BARRIER_WRITE);
}
+void
+pcfiic_choose_bus(struct pcfiic_softc *sc, u_int8_t bus)
+{
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh2, 0, bus);
+ bus_space_barrier(sc->sc_iot, sc->sc_ioh2, 0, 1,
+ BUS_SPACE_BARRIER_WRITE);
+}
+
int
pcfiic_wait_nBB(struct pcfiic_softc *sc)
{
diff --git a/sys/dev/ic/pcf8584var.h b/sys/dev/ic/pcf8584var.h
index 7fbdac1d50a..c3a0ed576bc 100644
--- a/sys/dev/ic/pcf8584var.h
+++ b/sys/dev/ic/pcf8584var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcf8584var.h,v 1.1 2006/02/01 11:03:34 dlg Exp $ */
+/* $OpenBSD: pcf8584var.h,v 1.2 2006/06/14 01:15:17 deraadt Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
@@ -21,6 +21,8 @@ struct pcfiic_softc {
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ bus_space_handle_t sc_ioh2;
+ int sc_master;
int sc_poll;