static int i2s_attach(device_t self) { struct i2s_softc *sc; struct resource *dbdma_irq; void *dbdma_ih; int rid, oirq, err; phandle_t port; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->aoa.sc_dev = self; sc->node = ofw_bus_get_node(self); port = of_find_firstchild_byname(sc->node, "i2s-a"); if (port == -1) return (ENXIO); sc->soundnode = of_find_firstchild_byname(port, "sound"); if (sc->soundnode == -1) return (ENXIO); mtx_init(&sc->port_mtx, "port_mtx", NULL, MTX_DEF); /* Map the controller register space. */ rid = 0; sc->reg = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->reg == NULL) return ENXIO; /* Map the DBDMA channel register space. */ rid = 1; sc->aoa.sc_odma = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->aoa.sc_odma == NULL) return ENXIO; /* Establish the DBDMA channel edge-triggered interrupt. */ rid = 1; dbdma_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (dbdma_irq == NULL) return (ENXIO); /* Now initialize the controller. */ err = i2s_setup(sc, 44100, 16, 64); if (err != 0) return (err); snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt, sc, &dbdma_ih); oirq = rman_get_start(dbdma_irq); err = powerpc_config_intr(oirq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); if (err != 0) return (err); /* * Register a hook for delayed attach in order to allow * the I2C controller to attach. */ if ((i2s_delayed_attach = malloc(sizeof(struct intr_config_hook), M_TEMP, M_WAITOK | M_ZERO)) == NULL) return (ENOMEM); i2s_delayed_attach->ich_func = i2s_postattach; i2s_delayed_attach->ich_arg = sc; if (config_intrhook_establish(i2s_delayed_attach) != 0) return (ENOMEM); return (aoa_attach(sc)); }
static int davbus_attach(device_t self) { struct davbus_softc *sc; struct resource *dbdma_irq, *cintr; void *cookie; char compat[64]; int rid, oirq, err; sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); sc->aoa.sc_dev = self; sc->node = ofw_bus_get_node(self); sc->soundnode = OF_child(sc->node); /* Map the controller register space. */ rid = 0; sc->reg = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->reg == NULL) return (ENXIO); /* Map the DBDMA channel register space. */ rid = 1; sc->aoa.sc_odma = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->aoa.sc_odma == NULL) return (ENXIO); /* Establish the DBDMA channel edge-triggered interrupt. */ rid = 1; dbdma_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (dbdma_irq == NULL) return (ENXIO); oirq = rman_get_start(dbdma_irq); DPRINTF(("interrupting at irq %d\n", oirq)); err = powerpc_config_intr(oirq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW); if (err != 0) return (err); snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt, sc, &cookie); /* Now initialize the controller. */ bzero(compat, sizeof(compat)); OF_getprop(sc->soundnode, "compatible", compat, sizeof(compat)); OF_getprop(sc->soundnode, "device-id", &sc->device_id, sizeof(u_int)); mtx_init(&sc->mutex, "DAVbus", NULL, MTX_DEF); device_printf(self, "codec: <%s>\n", compat); /* Setup the control interrupt. */ rid = 0; cintr = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (cintr != NULL) bus_setup_intr(self, cintr, INTR_TYPE_MISC | INTR_MPSAFE, NULL, davbus_cint, sc, &cookie); /* Initialize controller registers. */ bus_write_4(sc->reg, DAVBUS_SOUND_CTRL, DAVBUS_INPUT_SUBFRAME0 | DAVBUS_OUTPUT_SUBFRAME0 | DAVBUS_RATE_44100 | DAVBUS_INTR_PORTCHG); /* Attach DBDMA engine and PCM layer */ err = aoa_attach(sc); if (err) return (err); /* Install codec module */ if (strcmp(compat, "screamer") == 0) mixer_init(self, &screamer_mixer_class, sc); else if (strcmp(compat, "burgundy") == 0) mixer_init(self, &burgundy_mixer_class, sc); return (0); }