Example #1
0
/* semantic note: must start at beginning of buffer */
static int
ds1rchan_trigger(kobj_t obj, void *data, int go)
{
	struct sc_rchinfo *ch = data;
	struct sc_info *sc = ch->parent;
	u_int32_t x;

	if (!PCMTRIG_COMMON(go))
		return 0;
	if (go == PCMTRIG_START) {
		ch->run = 1;
		ds_setuprch(ch);
		snd_mtxlock(sc->lock);
		x = ds_rd(sc, YDSXGR_MAPOFREC, 4);
		x |= (ch->num == DS1_RECPRIMARY)? 0x02 : 0x01;
		ds_wr(sc, YDSXGR_MAPOFREC, x, 4);
		ds_wr(sc, YDSXGR_MODE, 0x00000003, 4);
		snd_mtxunlock(sc->lock);
	} else {
		ch->run = 0;
		snd_mtxlock(sc->lock);
		x = ds_rd(sc, YDSXGR_MAPOFREC, 4);
		x &= ~((ch->num == DS1_RECPRIMARY)? 0x02 : 0x01);
		ds_wr(sc, YDSXGR_MAPOFREC, x, 4);
		snd_mtxunlock(sc->lock);
	}

	return 0;
}
Example #2
0
/* semantic note: must start at beginning of buffer */
static int
ds1pchan_trigger(kobj_t obj, void *data, int go)
{
	struct sc_pchinfo *ch = data;
	struct sc_info *sc = ch->parent;
	int stereo;

	if (!PCMTRIG_COMMON(go))
		return 0;
	stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
	if (go == PCMTRIG_START) {
		ch->run = 1;
		ds_setuppch(ch);
		ds_enapslot(sc, ch->lsnum, 1);
		ds_enapslot(sc, ch->rsnum, stereo);
		snd_mtxlock(sc->lock);
		ds_wr(sc, YDSXGR_MODE, 0x00000003, 4);
		snd_mtxunlock(sc->lock);
	} else {
		ch->run = 0;
		/* ds_setuppch(ch); */
		ds_enapslot(sc, ch->lsnum, 0);
		ds_enapslot(sc, ch->rsnum, 0);
	}

	return 0;
}
Example #3
0
static int
bcmchan_trigger(kobj_t obj, void *data, int go)
{
	struct bcm2835_audio_chinfo *ch = data;
	struct bcm2835_audio_info *sc = ch->parent;

	if (!PCMTRIG_COMMON(go))
		return (0);

	bcm2835_audio_lock(sc);

	switch (go) {
	case PCMTRIG_START:
		bcm2835_audio_start(ch);
		ch->playback_state = PLAYBACK_STARTING;
		/* wakeup worker thread */
		cv_signal(&sc->data_cv);
		break;

	case PCMTRIG_STOP:
	case PCMTRIG_ABORT:
		ch->playback_state = 1;
		bcm2835_audio_stop(ch);
		break;

	default:
		break;
	}

	bcm2835_audio_unlock(sc);
	return 0;
}
Example #4
0
static int
bcmchan_trigger(kobj_t obj, void *data, int go)
{
	struct bcm2835_audio_chinfo *ch = data;
	struct bcm2835_audio_info *sc = ch->parent;

	if (!PCMTRIG_COMMON(go))
		return (0);

	switch (go) {
	case PCMTRIG_START:
		/* kickstart data flow */
		chn_intr(sc->pch.channel);
		ch->submitted_samples = 0;
		ch->retrieved_samples = 0;
		bcm2835_worker_play_start(sc);
		break;

	case PCMTRIG_STOP:
	case PCMTRIG_ABORT:
		bcm2835_worker_play_stop(sc);
		break;

	default:
		break;
	}
	return 0;
}
Example #5
0
static int
viachan_trigger(kobj_t obj, void *data, int go)
{
	struct via_chinfo *ch = data;
	struct via_info *via = ch->parent;
	struct via_dma_op *ado;
	bus_addr_t sgd_addr = ch->sgd_addr;

	if (!PCMTRIG_COMMON(go))
		return 0;

	ado = ch->sgd_table;
	DEB(printf("ado located at va=%p pa=%x\n", ado, sgd_addr));

	snd_mtxlock(via->lock);
	if (go == PCMTRIG_START) {
		via_buildsgdt(ch);
		via_wr(via, ch->base, sgd_addr, 4);
		via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1);
	} else
		via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1);
	snd_mtxunlock(via->lock);

	DEB(printf("viachan_trigger: go=%d\n", go));
	return 0;
}
Example #6
0
static int
fm801ch_trigger(kobj_t obj, void *data, int go)
{
	struct fm801_chinfo *ch = data;
	struct fm801_info *fm801 = ch->parent;
	u_int32_t baseaddr = sndbuf_getbufaddr(ch->buffer);
	u_int32_t k1;

	DPRINT("fm801ch_trigger go %d , ", go);

	if (!PCMTRIG_COMMON(go))
		return 0;

	if (ch->dir == PCMDIR_PLAY) {
		if (go == PCMTRIG_START) {

			fm801->play_start = baseaddr;
			fm801->play_nextblk = fm801->play_start + fm801->play_blksize;
			fm801->play_flip = 0;
			fm801_wr(fm801, FM_PLAY_DMALEN, fm801->play_blksize - 1, 2);
			fm801_wr(fm801, FM_PLAY_DMABUF1,fm801->play_start,4);
			fm801_wr(fm801, FM_PLAY_DMABUF2,fm801->play_nextblk,4);
			fm801_wr(fm801, FM_PLAY_CTL,
					FM_PLAY_START | FM_PLAY_STOPNOW | fm801->play_fmt | fm801->play_shift,
					2 );
			} else {
			fm801->play_flip = 0;
			k1 = fm801_rd(fm801, FM_PLAY_CTL,2);
			fm801_wr(fm801, FM_PLAY_CTL,
				(k1 & ~(FM_PLAY_STOPNOW | FM_PLAY_START)) |
				FM_PLAY_BUF1_LAST | FM_PLAY_BUF2_LAST, 2 );
		}
	} else if(ch->dir == PCMDIR_REC) {
		if (go == PCMTRIG_START) {
			fm801->rec_start = baseaddr;
			fm801->rec_nextblk = fm801->rec_start + fm801->rec_blksize;
			fm801->rec_flip = 0;
			fm801_wr(fm801, FM_REC_DMALEN, fm801->rec_blksize - 1, 2);
			fm801_wr(fm801, FM_REC_DMABUF1,fm801->rec_start,4);
			fm801_wr(fm801, FM_REC_DMABUF2,fm801->rec_nextblk,4);
			fm801_wr(fm801, FM_REC_CTL,
					FM_REC_START | FM_REC_STOPNOW | fm801->rec_fmt | fm801->rec_shift,
					2 );
			} else {
			fm801->rec_flip = 0;
			k1 = fm801_rd(fm801, FM_REC_CTL,2);
			fm801_wr(fm801, FM_REC_CTL,
				(k1 & ~(FM_REC_STOPNOW | FM_REC_START)) |
				FM_REC_BUF1_LAST | FM_REC_BUF2_LAST, 2);
		}
	}

	return 0;
}
Example #7
0
static int
ua_chan_trigger(kobj_t obj, void *data, int go)
{
	if (PCMTRIG_COMMON(go)) {
		if (go == PCMTRIG_START) {
			uaudio_chan_start(data);
		} else {
			uaudio_chan_stop(data);
		}
	}
	return (0);
}
static int
ad1816chan_trigger(kobj_t obj, void *data, int go)
{
    struct ad1816_chinfo *ch = data;
    struct ad1816_info *ad1816 = ch->parent;
    int wr, reg;

    if (!PCMTRIG_COMMON(go))
        return 0;

    sndbuf_dma(ch->buffer, go);
    wr = (ch->dir == PCMDIR_PLAY);
    reg = wr? AD1816_PLAY : AD1816_CAPT;
    ad1816_lock(ad1816);
    switch (go) {
    case PCMTRIG_START:
        /* start only if not already running */
        if (!(io_rd(ad1816, reg) & AD1816_ENABLE)) {
            int cnt = ((ch->blksz) >> 2) - 1;
            ad1816_write(ad1816, wr? 8 : 10, cnt); /* count */
            ad1816_write(ad1816, wr? 9 : 11, 0); /* reset cur cnt */
            ad1816_write(ad1816, 1, ad1816_read(ad1816, 1) |
                         (wr? 0x8000 : 0x4000)); /* enable int */
            /* enable playback */
            io_wr(ad1816, reg, io_rd(ad1816, reg) | AD1816_ENABLE);
            if (!(io_rd(ad1816, reg) & AD1816_ENABLE))
                printf("ad1816: failed to start %s DMA!\n",
                       wr? "play" : "rec");
        }
        break;

    case PCMTRIG_STOP:
    case PCMTRIG_ABORT:		/* XXX check this... */
        /* we don't test here if it is running... */
        if (wr) {
            ad1816_write(ad1816, 1, ad1816_read(ad1816, 1) &
                         ~(wr? 0x8000 : 0x4000));
            /* disable int */
            io_wr(ad1816, reg, io_rd(ad1816, reg) & ~AD1816_ENABLE);
            /* disable playback */
            if (io_rd(ad1816, reg) & AD1816_ENABLE)
                printf("ad1816: failed to stop %s DMA!\n",
                       wr? "play" : "rec");
            ad1816_write(ad1816, wr? 8 : 10, 0); /* reset base cnt */
            ad1816_write(ad1816, wr? 9 : 11, 0); /* reset cur cnt */
        }
        break;
    }
Example #9
0
static int
nmchan_trigger(kobj_t obj, void *data, int go)
{
	struct sc_chinfo *ch = data;
	struct sc_info *sc = ch->parent;
	int ssz;

	if (!PCMTRIG_COMMON(go))
		return 0;

	ssz = (ch->fmt & AFMT_16BIT)? 2 : 1;
	if (AFMT_CHANNEL(ch->fmt) > 1)
		ssz <<= 1;

	if (ch->dir == PCMDIR_PLAY) {
		if (go == PCMTRIG_START) {
			ch->active = 1;
			ch->wmark = ch->blksize;
			nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4);
			nm_wr(sc, NM_PBUFFER_END, sc->pbuf + NM_BUFFSIZE - ssz, 4);
			nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4);
			nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + ch->wmark, 4);
			nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN |
				NM_PLAYBACK_ENABLE_FLAG, 1);
			nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2);
		} else {
			ch->active = 0;
			nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1);
			nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2);
		}
	} else {
		if (go == PCMTRIG_START) {
			ch->active = 1;
			ch->wmark = ch->blksize;
			nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN |
				NM_RECORD_ENABLE_FLAG, 1);
			nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4);
			nm_wr(sc, NM_RBUFFER_END, sc->rbuf + NM_BUFFSIZE, 4);
			nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4);
			nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + ch->wmark, 4);
		} else {
			ch->active = 0;
			nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1);
		}
	}
	return 0;
}