From b8746ecc91c1c70018f67d0d661646271ebb559b Mon Sep 17 00:00:00 2001 From: jsg Date: Sun, 26 Jun 2016 07:25:05 +0000 Subject: [PATCH] Dynamically attach tiiic using the FDT. Only match on omap4 compatible controllers such as the one in the am335x on bbb. omap3 has different register offsets and a different compatible string. This reuses kettenis' fdt i2c scan function from imxiic(4). --- sys/arch/armv7/conf/GENERIC | 6 +-- sys/arch/armv7/conf/RAMDISK | 6 +-- sys/arch/armv7/omap/files.omap | 4 +- sys/arch/armv7/omap/omap.c | 5 +- sys/arch/armv7/omap/ti_iic.c | 94 +++++++++++++++++++++++++++++----- 5 files changed, 90 insertions(+), 25 deletions(-) diff --git a/sys/arch/armv7/conf/GENERIC b/sys/arch/armv7/conf/GENERIC index b6600cf9827..cb1e5b7c091 100644 --- a/sys/arch/armv7/conf/GENERIC +++ b/sys/arch/armv7/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.24 2016/06/26 05:16:33 jsg Exp $ +# $OpenBSD: GENERIC,v 1.25 2016/06/26 07:25:05 jsg Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -67,8 +67,8 @@ sitaracm* at omap? # sitara control module omdog* at fdt? # watchdog timer omgpio* at omap? # user-visible GPIO pins? gpio* at omgpio? -#tiiic* at omap? -#iic* at tiiic? +tiiic* at fdt? +iic* at tiiic? gptimer* at omap? # general purpose timers dmtimer* at omap? # am335x dual mode timers omusbtll* at omap? diff --git a/sys/arch/armv7/conf/RAMDISK b/sys/arch/armv7/conf/RAMDISK index 33c82d19989..b272214fdf5 100644 --- a/sys/arch/armv7/conf/RAMDISK +++ b/sys/arch/armv7/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.21 2016/06/26 05:16:33 jsg Exp $ +# $OpenBSD: RAMDISK,v 1.22 2016/06/26 07:25:05 jsg Exp $ machine armv7 arm @@ -66,8 +66,8 @@ sitaracm* at omap? # sitara control module omdog* at fdt? # watchdog timer omgpio* at omap? # user-visible GPIO pins? gpio* at omgpio? -#tiiic* at omap? -#iic* at tiiic? +tiiic* at fdt? +iic* at tiiic? gptimer* at omap? # general purpose timers dmtimer* at omap? # am335x dual mode timers omusbtll* at omap? diff --git a/sys/arch/armv7/omap/files.omap b/sys/arch/armv7/omap/files.omap index 961b9a394e7..9a2c4640099 100644 --- a/sys/arch/armv7/omap/files.omap +++ b/sys/arch/armv7/omap/files.omap @@ -1,4 +1,4 @@ -# $OpenBSD: files.omap,v 1.11 2016/06/26 05:16:33 jsg Exp $ +# $OpenBSD: files.omap,v 1.12 2016/06/26 07:25:05 jsg Exp $ define omap {} device omap: omap @@ -31,7 +31,7 @@ attach omgpio at omap file arch/armv7/omap/omgpio.c omgpio device tiiic: i2cbus -attach tiiic at omap +attach tiiic at fdt file arch/armv7/omap/ti_iic.c tiiic device edma diff --git a/sys/arch/armv7/omap/omap.c b/sys/arch/armv7/omap/omap.c index 6065124283d..a9ab55a7903 100644 --- a/sys/arch/armv7/omap/omap.c +++ b/sys/arch/armv7/omap/omap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omap.c,v 1.13 2016/06/26 05:16:33 jsg Exp $ */ +/* $OpenBSD: omap.c,v 1.14 2016/06/26 07:25:05 jsg Exp $ */ /* * Copyright (c) 2005,2008 Dale Rahn * @@ -61,9 +61,6 @@ struct board_dev beaglebone_devs[] = { { "omgpio", 1 }, { "omgpio", 2 }, { "omgpio", 3 }, - { "tiiic", 0 }, - { "tiiic", 1 }, - { "tiiic", 2 }, { "cpsw", 0 }, { NULL, 0 } }; diff --git a/sys/arch/armv7/omap/ti_iic.c b/sys/arch/armv7/omap/ti_iic.c index 3eef2f34c23..55db923ba01 100644 --- a/sys/arch/armv7/omap/ti_iic.c +++ b/sys/arch/armv7/omap/ti_iic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ti_iic.c,v 1.4 2016/06/26 05:30:21 jsg Exp $ */ +/* $OpenBSD: ti_iic.c,v 1.5 2016/06/26 07:25:05 jsg Exp $ */ /* $NetBSD: ti_iic.c,v 1.4 2013/04/25 13:04:27 rkujawa Exp $ */ /* @@ -59,6 +59,7 @@ #include #include +#include #include @@ -68,6 +69,8 @@ #include #include +#include + #ifndef AM335X_I2C_SLAVE_ADDR #define AM335X_I2C_SLAVE_ADDR 0x01 #endif @@ -96,6 +99,7 @@ struct ti_iic_softc { bus_space_handle_t sc_ioh; void *sc_ih; + int sc_node; ti_i2cop_t sc_op; int sc_buflen; int sc_bufidx; @@ -117,6 +121,7 @@ struct ti_iic_softc { #define DEVNAME(sc) ((sc)->sc_dev.dv_xname) +int ti_iic_match(struct device *, void *, void *); void ti_iic_attach(struct device *, struct device *, void *); int ti_iic_intr(void *); @@ -124,6 +129,7 @@ int ti_iic_acquire_bus(void *, int); void ti_iic_release_bus(void *, int); int ti_iic_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, void *, size_t, int); +void ti_iic_scan(struct device *, struct i2cbus_attach_args *, void *); int ti_iic_reset(struct ti_iic_softc *); int ti_iic_op(struct ti_iic_softc *, i2c_addr_t, ti_i2cop_t, uint8_t *, @@ -137,46 +143,74 @@ uint32_t ti_iic_stat(struct ti_iic_softc *, uint32_t); int ti_iic_flush(struct ti_iic_softc *); struct cfattach tiiic_ca = { - sizeof (struct ti_iic_softc), NULL, ti_iic_attach + sizeof (struct ti_iic_softc), ti_iic_match, ti_iic_attach }; struct cfdriver tiiic_cd = { NULL, "tiiic", DV_DULL }; +int +ti_iic_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return OF_is_compatible(faa->fa_node, "ti,omap4-i2c"); +} + void -ti_iic_attach(struct device *parent, struct device *self, void *args) +ti_iic_attach(struct device *parent, struct device *self, void *aux) { struct ti_iic_softc *sc = (struct ti_iic_softc *)self; - struct armv7_attach_args *aa = args; + struct fdt_attach_args *faa = aux; struct i2cbus_attach_args iba; uint16_t rev; const char *mode; u_int state; + int irq, unit, len; char buf[20]; + char hwmods[128]; char *pin; /* BBB specific pin names */ char *pins[6] = {"I2C0_SDA", "I2C0_SCL", "SPIO_D1", "SPI0_CS0", "UART1_CTSn", "UART1_RTSn"}; - sc->sc_iot = aa->aa_iot; + if (faa->fa_nreg != 2 || (faa->fa_nintr != 1 && faa->fa_nintr != 3)) + return; + + sc->sc_iot = faa->fa_iot; + sc->sc_node = faa->fa_node; + + if (faa->fa_nintr == 1) + irq = faa->fa_intr[0]; + else + irq = faa->fa_intr[1]; + + unit = 0; + if ((len = OF_getprop(faa->fa_node, "ti,hwmods", hwmods, + sizeof(hwmods))) == 5) { + if (!strncmp(hwmods, "i2c", 3) && + (hwmods[3] > '0') && (hwmods[3] <= '9')) + unit = hwmods[3] - '1'; + } + rw_init(&sc->sc_buslock, "tiiilk"); sc->sc_rxthres = sc->sc_txthres = 4; - if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, - aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) + if (bus_space_map(sc->sc_iot, faa->fa_reg[0], + faa->fa_reg[1], 0, &sc->sc_ioh)) panic("%s: bus_space_map failed!", DEVNAME(sc)); - sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_NET, + sc->sc_ih = arm_intr_establish(irq, IPL_NET, ti_iic_intr, sc, DEVNAME(sc)); - prcm_enablemodule(PRCM_I2C0 + aa->aa_dev->unit); + prcm_enablemodule(PRCM_I2C0 + unit); if (board_id == BOARD_ID_AM335X_BEAGLEBONE) { - pin = pins[aa->aa_dev->unit * 2]; - snprintf(buf, sizeof buf, "I2C%d_SDA", aa->aa_dev->unit); + pin = pins[unit * 2]; + snprintf(buf, sizeof buf, "I2C%d_SDA", unit); if (sitara_cm_padconf_set(pin, buf, (0x01 << 4) | (0x01 << 5) | (0x01 << 6)) != 0) { printf(": can't switch %s pad\n", buf); @@ -186,8 +220,8 @@ ti_iic_attach(struct device *parent, struct device *self, void *args) printf(": %s state %d ", mode, state); } - pin = pins[aa->aa_dev->unit * 2 + 1]; - snprintf(buf, sizeof buf, "I2C%d_SCL", aa->aa_dev->unit); + pin = pins[unit * 2 + 1]; + snprintf(buf, sizeof buf, "I2C%d_SCL", unit); if (sitara_cm_padconf_set(pin, buf, (0x01 << 4) | (0x01 << 5) | (0x01 << 6)) != 0) { printf(": can't switch %s pad\n", buf); @@ -214,6 +248,8 @@ ti_iic_attach(struct device *parent, struct device *self, void *args) bzero(&iba, sizeof iba); iba.iba_name = "iic"; iba.iba_tag = &sc->sc_ic; + iba.iba_bus_scan = ti_iic_scan; + iba.iba_bus_scan_arg = &sc->sc_node; (void) config_found(&sc->sc_dev, &iba, iicbus_print); } @@ -587,3 +623,35 @@ ti_iic_flush(struct ti_iic_softc *sc) I2C_WRITE_REG(sc, AM335X_I2C_CNT, 0); return 0; } + +void +ti_iic_scan(struct device *self, struct i2cbus_attach_args *iba, void *aux) +{ + int iba_node = *(int *)aux; + extern int iic_print(void *, const char *); + struct i2c_attach_args ia; + char name[32]; + uint32_t reg[1]; + int node; + + for (node = OF_child(iba_node); node; node = OF_peer(node)) { + memset(name, 0, sizeof(name)); + memset(reg, 0, sizeof(reg)); + + if (OF_getprop(node, "compatible", name, sizeof(name)) == -1) + continue; + if (name[0] == '\0') + continue; + + if (OF_getprop(node, "reg", ®, sizeof(reg)) != sizeof(reg)) + continue; + + memset(&ia, 0, sizeof(ia)); + ia.ia_tag = iba->iba_tag; + ia.ia_addr = bemtoh32(®[0]); + ia.ia_name = name; + ia.ia_cookie = &node; + + config_found(self, &ia, iic_print); + } +} -- 2.20.1