Dynamically attach tiiic using the FDT.
authorjsg <jsg@openbsd.org>
Sun, 26 Jun 2016 07:25:05 +0000 (07:25 +0000)
committerjsg <jsg@openbsd.org>
Sun, 26 Jun 2016 07:25:05 +0000 (07:25 +0000)
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
sys/arch/armv7/conf/RAMDISK
sys/arch/armv7/omap/files.omap
sys/arch/armv7/omap/omap.c
sys/arch/armv7/omap/ti_iic.c

index b6600cf..cb1e5b7 100644 (file)
@@ -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?
index 33c82d1..b272214 100644 (file)
@@ -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?
index 961b9a3..9a2c464 100644 (file)
@@ -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
index 6065124..a9ab55a 100644 (file)
@@ -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 <drahn@openbsd.com>
  *
@@ -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 }
 };
index 3eef2f3..55db923 100644 (file)
@@ -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 <machine/bus.h>
 #include <machine/intr.h>
+#include <machine/fdt.h>
 
 #include <dev/i2c/i2cvar.h>
 
@@ -68,6 +69,8 @@
 #include <armv7/omap/sitara_cmreg.h>
 #include <armv7/omap/ti_iicreg.h>
 
+#include <dev/ofw/openfirm.h>
+
 #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", &reg, sizeof(reg)) != sizeof(reg))
+                       continue;
+
+               memset(&ia, 0, sizeof(ia));
+               ia.ia_tag = iba->iba_tag;
+               ia.ia_addr = bemtoh32(&reg[0]);
+               ia.ia_name = name;
+               ia.ia_cookie = &node;
+       
+               config_found(self, &ia, iic_print);
+       }
+}