Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/macppc/dev allow to attach a normal iic bus, implem...
details: https://anonhg.NetBSD.org/src/rev/90de2824fd84
branches: trunk
changeset: 583529:90de2824fd84
user: macallan <macallan%NetBSD.org@localhost>
date: Wed Aug 10 14:26:46 2005 +0000
description:
allow to attach a normal iic bus, implements only iic_exec() and locking functions so far.
diffstat:
sys/arch/macppc/dev/ki2c.c | 171 ++++++++++++++++++++++++++++----------------
1 files changed, 110 insertions(+), 61 deletions(-)
diffs (228 lines):
diff -r f6d137b86028 -r 90de2824fd84 sys/arch/macppc/dev/ki2c.c
--- a/sys/arch/macppc/dev/ki2c.c Wed Aug 10 14:20:44 2005 +0000
+++ b/sys/arch/macppc/dev/ki2c.c Wed Aug 10 14:26:46 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ki2c.c,v 1.2 2005/06/05 20:16:35 nathanw Exp $ */
+/* $NetBSD: ki2c.c,v 1.3 2005/08/10 14:26:46 macallan Exp $ */
/* Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai Exp */
/*-
@@ -35,61 +35,7 @@
#include <uvm/uvm_extern.h>
#include <machine/autoconf.h>
-/* Keywest I2C Register offsets */
-#define MODE 0
-#define CONTROL 1
-#define STATUS 2
-#define ISR 3
-#define IER 4
-#define ADDR 5
-#define SUBADDR 6
-#define DATA 7
-
-/* MODE */
-#define I2C_SPEED 0x03 /* Speed mask */
-#define I2C_100kHz 0x00
-#define I2C_50kHz 0x01
-#define I2C_25kHz 0x02
-#define I2C_MODE 0x0c /* Mode mask */
-#define I2C_DUMBMODE 0x00 /* Dumb mode */
-#define I2C_STDMODE 0x04 /* Standard mode */
-#define I2C_STDSUBMODE 0x08 /* Standard mode + sub address */
-#define I2C_COMBMODE 0x0c /* Combined mode */
-#define I2C_PORT 0xf0 /* Port mask */
-
-/* CONTROL */
-#define I2C_CT_AAK 0x01 /* Send AAK */
-#define I2C_CT_ADDR 0x02 /* Send address(es) */
-#define I2C_CT_STOP 0x04 /* Send STOP */
-#define I2C_CT_START 0x08 /* Send START */
-
-/* STATUS */
-#define I2C_ST_BUSY 0x01 /* Busy */
-#define I2C_ST_LASTAAK 0x02 /* Last AAK */
-#define I2C_ST_LASTRW 0x04 /* Last R/W */
-#define I2C_ST_SDA 0x08 /* SDA */
-#define I2C_ST_SCL 0x10 /* SCL */
-
-/* ISR/IER */
-#define I2C_INT_DATA 0x01 /* Data byte sent/received */
-#define I2C_INT_ADDR 0x02 /* Address sent */
-#define I2C_INT_STOP 0x04 /* STOP condition sent */
-#define I2C_INT_START 0x08 /* START condition sent */
-
-/* I2C flags */
-#define I2C_BUSY 0x01
-#define I2C_READING 0x02
-#define I2C_ERROR 0x04
-
-struct ki2c_softc {
- struct device sc_dev;
- u_char *sc_reg;
- int sc_regstep;
-
- int sc_flags;
- u_char *sc_data;
- int sc_resid;
-};
+#include <macppc/dev/ki2cvar.h>
int ki2c_match(struct device *, struct cfdata *, void *);
void ki2c_attach(struct device *, struct device *, void *);
@@ -103,7 +49,15 @@
int ki2c_poll(struct ki2c_softc *, int);
int ki2c_start(struct ki2c_softc *, int, int, void *, int);
int ki2c_read(struct ki2c_softc *, int, int, void *, int);
-int ki2c_write(struct ki2c_softc *, int, int, const void *, int);
+int ki2c_write(struct ki2c_softc *, int, int, void *, int);
+int ki2c_print __P((void *, const char *));
+
+/* I2C glue */
+static int ki2c_i2c_acquire_bus(void *, int);
+static void ki2c_i2c_release_bus(void *, int);
+static int ki2c_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
+ void *, size_t, int);
+
struct cfattach ki2c_ca = {
"ki2c", {}, sizeof(struct ki2c_softc), ki2c_match, ki2c_attach
@@ -132,8 +86,13 @@
struct ki2c_softc *sc = (struct ki2c_softc *)self;
struct confargs *ca = aux;
int node = ca->ca_node;
- int rate;
+ int rate, child, namelen;
+ struct ki2c_confargs ka;
+ struct i2cbus_attach_args iba;
+ char name[32];
+ u_int reg[20];
+
ca->ca_reg[0] += ca->ca_baseaddr;
if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
@@ -157,6 +116,56 @@
ki2c_setmode(sc, I2C_STDSUBMODE);
ki2c_setspeed(sc, I2C_100kHz); /* XXX rate */
+
+ lockinit(&sc->sc_buslock, PRIBIO|PCATCH, sc->sc_dev.dv_xname, 0, 0);
+ ki2c_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP);
+
+ /* fill in the i2c tag */
+ sc->sc_i2c.ic_cookie = sc;
+ sc->sc_i2c.ic_acquire_bus = ki2c_i2c_acquire_bus;
+ sc->sc_i2c.ic_release_bus = ki2c_i2c_release_bus;
+ sc->sc_i2c.ic_send_start = NULL;
+ sc->sc_i2c.ic_send_stop = NULL;
+ sc->sc_i2c.ic_initiate_xfer = NULL;
+ sc->sc_i2c.ic_read_byte = NULL;
+ sc->sc_i2c.ic_write_byte = NULL;
+ sc->sc_i2c.ic_exec = ki2c_i2c_exec;
+
+ iba.iba_name = "iic";
+ iba.iba_tag = &sc->sc_i2c;
+ (void) config_found(&sc->sc_dev, &iba, iicbus_print);
+
+
+ for (child = OF_child(node); child; child = OF_peer(child)) {
+ namelen = OF_getprop(child, "name", name, sizeof(name));
+ if (namelen < 0)
+ continue;
+ if (namelen >= sizeof(name))
+ continue;
+
+ name[namelen] = 0;
+ ka.ka_name = name;
+ ka.ka_node = child;
+ if (OF_getprop(child, "reg", reg, sizeof(reg))>0) {
+ ka.ka_addr = reg[0];
+ ka.ka_tag = &sc->sc_i2c;
+ config_found(self, &ka, ki2c_print);
+ }
+ }
+}
+
+int
+ki2c_print(aux, ki2c)
+ void *aux;
+ const char *ki2c;
+{
+ struct ki2c_confargs *ka = aux;
+
+ if (ki2c) {
+ aprint_normal("%s at %s", ka->ka_name, ki2c);
+ aprint_normal(" address 0x%x", ka->ka_addr);
+ }
+ return UNCONF;
}
u_int
@@ -231,7 +240,6 @@
u_int isr, x;
isr = ki2c_readreg(sc, ISR);
-
if (isr & I2C_INT_ADDR) {
#if 0
if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) {
@@ -353,6 +361,9 @@
void *data;
{
sc->sc_flags = I2C_READING;
+ #ifdef KI2C_DEBUG
+ printf("ki2c_read: %02x %d\n", addr, len);
+ #endif
return ki2c_start(sc, addr, subaddr, data, len);
}
@@ -360,8 +371,46 @@
ki2c_write(sc, addr, subaddr, data, len)
struct ki2c_softc *sc;
int addr, subaddr, len;
- const void *data;
+ void *data;
{
sc->sc_flags = 0;
- return ki2c_start(sc, addr, subaddr, __UNCONST(data), len);
+ #ifdef KI2C_DEBUG
+ printf("ki2c_write: %02x %d\n",addr,len);
+ #endif
+ return ki2c_start(sc, addr, subaddr, data, len);
+}
+
+static int
+ki2c_i2c_acquire_bus(void *cookie, int flags)
+{
+ struct ki2c_softc *sc = cookie;
+
+ return (lockmgr(&sc->sc_buslock, LK_EXCLUSIVE, NULL));
}
+
+static void
+ki2c_i2c_release_bus(void *cookie, int flags)
+{
+ struct ki2c_softc *sc = cookie;
+
+ (void) lockmgr(&sc->sc_buslock, LK_RELEASE, NULL);
+}
+
+int
+ki2c_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *vcmd,
+ size_t cmdlen, void *vbuf, size_t buflen, int flags)
+{
+ struct ki2c_softc *sc = cookie;
+
+ /* we handle the subaddress stuff ourselves */
+ ki2c_setmode(sc, I2C_STDMODE);
+
+ if (ki2c_write(sc, addr, 0, __UNCONST(vcmd), cmdlen) !=0 )
+ return -1;
+ if (I2C_OP_READ_P(op))
+ {
+ if (ki2c_read(sc, addr, 0, vbuf, buflen) !=0 )
+ return -1;
+ }
+ return 0;
+}
Home |
Main Index |
Thread Index |
Old Index