diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-06-14 01:15:20 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2006-06-14 01:15:20 +0000 |
commit | 45923ad8dcc1575cd5409dcbae1eaa9af4dcb692 (patch) | |
tree | 1afde14edd65ab5f223742281df64fa45b02713c | |
parent | 885d192adb7db427b5e2d7f0227e94844c0fa6cc (diff) |
support the iic busses on the ultrasparc III machines (something is still
wrong, likely clocking); tested to not break older machines by dlg & djm
-rw-r--r-- | sys/arch/sparc64/dev/ofwi2c.c | 7 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/pcfiic_ebus.c | 30 | ||||
-rw-r--r-- | sys/dev/ic/pcf8584.c | 60 | ||||
-rw-r--r-- | sys/dev/ic/pcf8584var.h | 4 |
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; |