Esempio n. 1
0
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));
}
Esempio n. 2
0
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);
}