예제 #1
0
static int
atiixp_pci_suspend(device_t dev)
{
	struct atiixp_info *sc = pcm_getdevinfo(dev);
	uint32_t value;

	/* quickly disable interrupts and save channels active state */
	atiixp_lock(sc);
	atiixp_disable_interrupts(sc);
	value = atiixp_rd(sc, ATI_REG_CMD);
	sc->pch.active = (value & ATI_REG_CMD_SEND_EN) ? 1 : 0;
	sc->rch.active = (value & ATI_REG_CMD_RECEIVE_EN) ? 1 : 0;
	atiixp_unlock(sc);

	/* stop everything */
	if (sc->pch.channel && sc->pch.active)
		atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP);
	if (sc->rch.channel && sc->rch.active)
		atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP);

	/* power down aclink and pci bus */
	atiixp_lock(sc);
	value = atiixp_rd(sc, ATI_REG_CMD);
	value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET;
	atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN);
	pci_set_powerstate(dev, PCI_POWERSTATE_D3);
	atiixp_unlock(sc);

	return 0;
}
예제 #2
0
static int
cs4281_pci_resume(device_t dev)
{
    struct sc_info *sc;

    sc = pcm_getdevinfo(dev);

    /* power up */
    cs4281_power(sc, 0);

    /* initialize chip */
    if (cs4281_init(sc) == -1) {
        device_printf(dev, "unable to reinitialize the card\n");
        return ENXIO;
    }

    /* restore mixer state */
    if (mixer_reinit(dev) == -1) {
	device_printf(dev, "unable to reinitialize the mixer\n");
	return ENXIO;
    }

    /* restore chip state */
    cs4281chan_setspeed(NULL, &sc->rch, sc->rch.spd);
    cs4281chan_setblocksize(NULL, &sc->rch, sc->rch.blksz);
    cs4281chan_setformat(NULL, &sc->rch, sc->rch.fmt);
    adcdac_go(&sc->rch, sc->rch.dma_active);

    cs4281chan_setspeed(NULL, &sc->pch, sc->pch.spd);
    cs4281chan_setblocksize(NULL, &sc->pch, sc->pch.blksz);
    cs4281chan_setformat(NULL, &sc->pch, sc->pch.fmt);
    adcdac_go(&sc->pch, sc->pch.dma_active);

    return 0;
}
예제 #3
0
static int
bcm2835_audio_detach(device_t dev)
{
	int r;
	struct bcm2835_audio_info *sc;
	sc = pcm_getdevinfo(dev);

	/* Stop worker thread */
	BCM2835_AUDIO_LOCK(sc);
	sc->worker_state = WORKER_STOPPING;
	cv_signal(&sc->worker_cv);
	/* Wait for thread to exit */
	while (sc->worker_state != WORKER_STOPPED)
		cv_wait_sig(&sc->worker_cv, &sc->lock);
	BCM2835_AUDIO_UNLOCK(sc);

	r = pcm_unregister(dev);
	if (r)
		return r;

	mtx_destroy(&sc->lock);
	cv_destroy(&sc->worker_cv);

	bcm2835_audio_release(sc);

    	free(sc, M_DEVBUF);

	return 0;
}
예제 #4
0
static int
bcm2835_audio_detach(device_t dev)
{
	int r;
	struct bcm2835_audio_info *sc;
	sc = pcm_getdevinfo(dev);

	/* Stop worker thread */
	sc->unloading = 1;
	cv_signal(&sc->data_cv);

	r = pcm_unregister(dev);
	if (r)
		return r;

	mtx_destroy(&sc->vchi_lock);
	mtx_destroy(&sc->msg_avail_lock);
	cv_destroy(&sc->msg_avail_cv);
	mtx_destroy(&sc->data_lock);
	cv_destroy(&sc->data_cv);

	bcm2835_audio_release(sc);

	if (sc->lock) {
		snd_mtxfree(sc->lock);
		sc->lock = NULL;
	}

    	free(sc, M_DEVBUF);

	return 0;
}
예제 #5
0
static int
sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS)
{
	struct via_info *via;
	device_t dev;
	uint32_t r;
	int err, new_en;

	dev = oidp->oid_arg1;
	via = pcm_getdevinfo(dev);
	snd_mtxlock(via->lock);
	r = pci_read_config(dev, VIA_PCI_SPDIF, 1);
	snd_mtxunlock(via->lock);
	new_en = (r & VIA_SPDIF_EN) ? 1 : 0;
	err = sysctl_handle_int(oidp, &new_en, 0, req);

	if (err || req->newptr == NULL)
		return err;
	if (new_en < 0 || new_en > 1)
		return EINVAL;

	if (new_en)
		r |= VIA_SPDIF_EN;
	else
		r &= ~VIA_SPDIF_EN;
	snd_mtxlock(via->lock);
	pci_write_config(dev, VIA_PCI_SPDIF, r, 1);
	snd_mtxunlock(via->lock);

	return 0;
}
예제 #6
0
static int
sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS)
{
	struct via_info *via;
	device_t dev;
	int err, val;

	dev = oidp->oid_arg1;
	via = pcm_getdevinfo(dev);
	snd_mtxlock(via->lock);
	val = via->dxs_src;
	snd_mtxunlock(via->lock);
	err = sysctl_handle_int(oidp, &val, 0, req);

	if (err || req->newptr == NULL)
		return err;
	if (val < 0 || val > 1)
		return EINVAL;

	snd_mtxlock(via->lock);
	via->dxs_src = val;
	snd_mtxunlock(via->lock);

	return 0;
}
예제 #7
0
파일: fm801.c 프로젝트: kusumi/DragonFlyBSD
static int
fm801_pci_detach(device_t dev)
{
	int r;
	struct fm801_info *fm801;

	DPRINT("Forte Media FM801 detach\n");

	fm801 = pcm_getdevinfo(dev);

	r = bus_generic_detach(dev);
	if (r)
		return r;
	if (fm801->radio != NULL) {
		r = device_delete_child(dev, fm801->radio);
		if (r)
			return r;
		fm801->radio = NULL;
	}

	r = pcm_unregister(dev);
	if (r)
		return r;

	bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
	bus_teardown_intr(dev, fm801->irq, fm801->ih);
	bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
	bus_dma_tag_destroy(fm801->parent_dmat);
	kfree(fm801, M_DEVBUF);
	return 0;
}
예제 #8
0
/*
 * Construct and set status string
 */
static void
au88x0_set_status(device_t dev)
{
	char status[SND_STATUSLEN];
	struct au88x0_info *aui;

	aui = pcm_getdevinfo(dev);
	snprintf(status, sizeof status, "at %s 0x%lx irq %ld %s",
	    (aui->aui_regtype == SYS_RES_IOPORT)? "io" : "memory",
	    rman_get_start(aui->aui_reg), rman_get_start(aui->aui_irq),PCM_KLDSTRING(snd_au88x0));
	pcm_setstatus(dev, status);
}
예제 #9
0
파일: fm801.c 프로젝트: kusumi/DragonFlyBSD
static struct resource *
fm801_alloc_resource(device_t bus, device_t child, int type, int *rid,
		     u_long start, u_long end, u_long count, u_int flags)
{
	struct fm801_info *fm801;

	fm801 = pcm_getdevinfo(bus);

	if (type == SYS_RES_IOPORT && *rid == PCIR_BAR(0))
		return (fm801->reg);

	return (NULL);
}
예제 #10
0
static int
cs4281_pci_suspend(device_t dev)
{
    struct sc_info *sc;

    sc = pcm_getdevinfo(dev);

    sc->rch.dma_active = adcdac_go(&sc->rch, 0);
    sc->pch.dma_active = adcdac_go(&sc->pch, 0);

    cs4281_power(sc, 3);

    return 0;
}
예제 #11
0
파일: uaudio_pcm.c 프로젝트: MarginC/kame
static int
ua_detach(device_t dev)
{
	int r;
	struct ua_info *sc;

	r = pcm_unregister(dev);
	if (r)
		return r;

	sc = pcm_getdevinfo(dev);
	bus_dma_tag_destroy(sc->parent_dmat);
	free(sc, M_DEVBUF);

	return 0;
}
예제 #12
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
static int
ds_pci_resume(device_t dev)
{
       struct sc_info *sc;

       sc = pcm_getdevinfo(dev);

       if (ds_init(sc) == -1) {
           device_printf(dev, "unable to reinitialize the card\n");
           return ENXIO;
       }
       if (mixer_reinit(dev) == -1) {
               device_printf(dev, "unable to reinitialize the mixer\n");
               return ENXIO;
       }
       return 0;
}
예제 #13
0
파일: neomagic.c 프로젝트: JabirTech/Source
static int
nm_pci_suspend(device_t dev)
{
	struct sc_info *sc;

	sc = pcm_getdevinfo(dev);

	/* stop playing */
	if (sc->pch.active) {
		nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1);
		nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2);
	}
	/* stop recording */
	if (sc->rch.active) {
		nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
	}
	return 0;
}
예제 #14
0
static int
atiixp_pci_resume(device_t dev)
{
	struct atiixp_info *sc = pcm_getdevinfo(dev);

	atiixp_lock(sc);
	/* power up pci bus */
	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
	pci_enable_io(dev, SYS_RES_MEMORY);
	pci_enable_busmaster(dev);
	/* reset / power up aclink */
	atiixp_reset_aclink(sc);
	atiixp_unlock(sc);

	if (mixer_reinit(dev) == -1) {
		device_printf(dev, "unable to reinitialize the mixer\n");
		return ENXIO;
	}

	/*
	 * Resume channel activities. Reset channel format regardless
	 * of its previous state.
	 */
	if (sc->pch.channel) {
		if (sc->pch.fmt)
			atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
		if (sc->pch.active)
			atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START);
	}
	if (sc->rch.channel) {
		if (sc->rch.fmt)
			atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
		if (sc->rch.active)
			atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
	}

	/* enable interrupts */
	atiixp_lock(sc);
	atiixp_enable_interrupts(sc);
	atiixp_unlock(sc);

	return 0;
}
예제 #15
0
파일: neomagic.c 프로젝트: JabirTech/Source
static int
nm_pci_detach(device_t dev)
{
	int r;
	struct sc_info *sc;

	r = pcm_unregister(dev);
	if (r)
		return r;

	sc = pcm_getdevinfo(dev);
	bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf);
	bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
	bus_teardown_intr(dev, sc->irq, sc->ih);
	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
	free(sc, M_DEVBUF);

	return 0;
}
예제 #16
0
static int
atiixp_pci_detach(device_t dev)
{
	int r;
	struct atiixp_info *sc;

	sc = pcm_getdevinfo(dev);
	if (sc != NULL) {
		if (sc->codec != NULL) {
			r = pcm_unregister(dev);
			if (r)
				return r;
		}
		sc->codec = NULL;
		atiixp_disable_interrupts(sc);
		atiixp_release_resource(sc);
		kfree(sc, M_DEVBUF);
	}
	return 0;
}
예제 #17
0
/*
 * Detach
 */
static int
au88x0_pci_detach(device_t dev)
{
	struct au88x0_info *aui;
	int error;

	aui = pcm_getdevinfo(dev);
	if ((error = pcm_unregister(dev)) != 0)
		return (error);

	/* release resources in reverse order */
	bus_dma_tag_destroy(aui->aui_dmat);
	bus_teardown_intr(dev, aui->aui_irq, aui->aui_irqh);
	bus_release_resource(dev, aui->aui_irqtype,
	    aui->aui_irqid, aui->aui_irq);
	bus_release_resource(dev, aui->aui_regtype,
	    aui->aui_regid, aui->aui_reg);
	kfree(aui, M_DEVBUF);

	return (0);
}
예제 #18
0
static int
via_detach(device_t dev)
{
	int r;
	struct via_info *via = NULL;

	r = pcm_unregister(dev);
	if (r) return r;

	via = pcm_getdevinfo(dev);
	bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
	bus_teardown_intr(dev, via->irq, via->ih);
	bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
	bus_dma_tag_destroy(via->parent_dmat);
	bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
	bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
	bus_dma_tag_destroy(via->sgd_dmat);
	snd_mtxfree(via->lock);
	kfree(via, M_DEVBUF);
	return 0;
}
예제 #19
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
static int
ds_pci_detach(device_t dev)
{
    	int r;
	struct sc_info *sc;

	r = pcm_unregister(dev);
	if (r)
    		return r;

	sc = pcm_getdevinfo(dev);
	ds_uninit(sc);
	bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
	bus_teardown_intr(dev, sc->irq, sc->ih);
	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
	bus_dma_tag_destroy(sc->buffer_dmat);
	bus_dma_tag_destroy(sc->control_dmat);
	snd_mtxfree(sc->lock);
	free(sc, M_DEVBUF);
       	return 0;
}
예제 #20
0
static int
cs4281_pci_detach(device_t dev)
{
    int r;
    struct sc_info *sc;

    r = pcm_unregister(dev);
    if (r)
	return r;

    sc = pcm_getdevinfo(dev);

    /* power off */
    cs4281_power(sc, 3);

    bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
    bus_release_resource(dev, SYS_RES_MEMORY, sc->memid, sc->mem);
    bus_teardown_intr(dev, sc->irq, sc->ih);
    bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
    bus_dma_tag_destroy(sc->parent_dmat);
    free(sc, M_DEVBUF);

    return 0;
}
예제 #21
0
파일: neomagic.c 프로젝트: JabirTech/Source
static int
nm_pci_resume(device_t dev)
{
	struct sc_info *sc;

	sc = pcm_getdevinfo(dev);

	/*
	 * Reinit audio device.
	 * Don't call nm_init(). It would change buftop if X ran or
	 * is running. This makes playing and recording buffer address
	 * shift but these buffers of channel layer are not changed.
	 * As a result of this inconsistency, periodic noise will be
	 * generated while playing.
	 */
	nm_wr(sc, 0, 0x11, 1);
	nm_wr(sc, 0x214, 0, 2);

	/* Reinit mixer */
    	if (mixer_reinit(dev) == -1) {
		device_printf(dev, "unable to reinitialize the mixer\n");
		return ENXIO;
	}
	/* restart playing */
	if (sc->pch.active) {
		nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
			  NM_PLAYBACK_ENABLE_FLAG, 1);
		nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2);
	}
	/* restart recording */
	if (sc->rch.active) {
		nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
			  NM_RECORD_ENABLE_FLAG, 1);
	}
	return 0;
}