Example #1
0
static paddr_t
yds_mappage(void *addr, void *mem, off_t off, int prot)
{
	struct yds_softc *sc;
	struct yds_dma *p;

	if (off < 0)
		return -1;
	sc = addr;
	p = yds_find_dma(sc, mem);
	if (p == NULL)
		return -1;
	return bus_dmamem_mmap(sc->sc_dmatag, p->segs, p->nsegs,
	    off, prot, BUS_DMA_WAITOK);
}
Example #2
0
static void
yds_dump_play_slot(struct yds_softc *sc, int bank)
{
	int i, j;
	u_int32_t *p;
	u_int32_t num;
	struct yds_dma *dma;

	for (i = 0; i < N_PLAY_SLOTS; i++) {
		printf("pbankp[%d] = %p,", i*2, sc->pbankp[i*2]);
		printf("pbankp[%d] = %p\n", i*2+1, sc->pbankp[i*2+1]);
	}

	p = (u_int32_t*)sc->ptbl;
	for (i = 0; i < N_PLAY_SLOTS+1; i++) {
		printf("ptbl + %d:0x%x\n", i, *p);
		p++;
	}

	num = *(u_int32_t*)sc->ptbl;
	printf("num = %d\n", num);

	for (i = 0; i < num; i++) {

		p = (u_int32_t *)sc->pbankp[i];

		dma = yds_find_dma(sc,(void *)p);

		for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
		    sizeof(u_int32_t); j++) {
			printf("    0x%02x: 0x%08x\n",
			       (unsigned) (j * sizeof(u_int32_t)),
			       (unsigned) *p++);
		}
		/*
		p = (u_int32_t *)sc->pbankp[i*2 + 1];
		printf("  pbankp[%d] : %p\n", i*2 + 1, p);
		for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
		    sizeof(u_int32_t); j++) {
			printf("    0x%02x: 0x%08x\n",
				j * sizeof(u_int32_t), *p++);
				delay(1);
		}	
		*/
	}
}
Example #3
0
int
yds_trigger_input(void *addr, void *start, void *end, int blksize,
    void (*intr)(void *), void *arg, struct audio_params *param)
{
	struct yds_softc *sc = addr;
	struct yds_dma *p;
	u_int srate, format;
	struct rec_slot_ctrl_bank *rsb;
	bus_addr_t s;
	size_t l;

	mtx_enter(&audio_lock);
#ifdef DIAGNOSTIC
	if (sc->sc_rec.intr)
		panic("yds_trigger_input: already running");
#endif
	sc->sc_rec.intr = intr;
	sc->sc_rec.intr_arg = arg;
	sc->sc_rec.offset = 0;
	sc->sc_rec.blksize = blksize;

	DPRINTFN(1, ("yds_trigger_input: "
	    "sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n", 
	    addr, start, end, blksize, intr, arg));
	DPRINTFN(1, (" parameters: rate=%lu, precision=%u, channels=%u\n",
	    param->sample_rate, param->precision, param->channels));

	p = yds_find_dma(sc, start);
	if (!p) {
		printf("yds_trigger_input: bad addr %p\n", start);
		mtx_leave(&audio_lock);
		return (EINVAL);
	}
	sc->sc_rec.dma = p;

	s = DMAADDR(p);
	l = ((char *)end - (char *)start);
	sc->sc_rec.length = l;

	sc->sc_rec.factor = 1;
	if (param->channels == 2)
		sc->sc_rec.factor *= 2;
	if (param->precision != 8)
		sc->sc_rec.factor *= 2;

	rsb = &sc->rbank[0];
	memset(rsb, 0, sizeof(*rsb));
	rsb->pgbase = s;
	rsb->pgloopendadr = l;
	/* Seems all 4 banks must be set up... */
	sc->rbank[1] = *rsb;
	sc->rbank[2] = *rsb;
	sc->rbank[3] = *rsb;

	YWRITE4(sc, YDS_ADC_IN_VOLUME, 0x3fff3fff);
	YWRITE4(sc, YDS_REC_IN_VOLUME, 0x3fff3fff);
	srate = 48000 * 4096 / param->sample_rate - 1;
	format = ((param->precision == 8 ? YDS_FORMAT_8BIT : 0) |
		  (param->channels == 2 ? YDS_FORMAT_STEREO : 0));
	DPRINTF(("srate=%d, format=%08x\n", srate, format));
#ifdef YDS_USE_REC_SLOT
	YWRITE4(sc, YDS_DAC_REC_VOLUME, 0x3fff3fff);
	YWRITE4(sc, YDS_P44_REC_VOLUME, 0x3fff3fff);
	YWRITE4(sc, YDS_MAPOF_REC, YDS_RECSLOT_VALID);
	YWRITE4(sc, YDS_REC_SAMPLE_RATE, srate);
	YWRITE4(sc, YDS_REC_FORMAT, format);
#else
	YWRITE4(sc, YDS_MAPOF_REC, YDS_ADCSLOT_VALID);
	YWRITE4(sc, YDS_ADC_SAMPLE_RATE, srate);
	YWRITE4(sc, YDS_ADC_FORMAT, format);
#endif
	/* Now the rec slot for the next frame is set up!! */
	/* Sync record slot control data */
	bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
			sc->rbankoff,
			sizeof(struct rec_slot_ctrl_bank)*
			    N_REC_SLOT_CTRL*
			    N_REC_SLOT_CTRL_BANK,
			BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
	/* Sync ring buffer */
	bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,
			BUS_DMASYNC_PREREAD);
	/* HERE WE GO!! */
	YWRITE4(sc, YDS_MODE,
		YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2);
	mtx_leave(&audio_lock);
	return 0;
}
Example #4
0
int
yds_trigger_output(void *addr, void *start, void *end, int blksize,
    void (*intr)(void *), void *arg, struct audio_params *param)
#define P44		(sc->sc_flags & YDS_CAP_HAS_P44)
{
	struct yds_softc *sc = addr;
	struct yds_dma *p;
	struct play_slot_ctrl_bank *psb;
	const u_int gain = 0x40000000;
	bus_addr_t s;
	size_t l;
	int i;
	int p44, channels;

	mtx_enter(&audio_lock);
#ifdef DIAGNOSTIC
	if (sc->sc_play.intr)
		panic("yds_trigger_output: already running");
#endif
	sc->sc_play.intr = intr;
	sc->sc_play.intr_arg = arg;
	sc->sc_play.offset = 0;
	sc->sc_play.blksize = blksize;

	DPRINTFN(1, ("yds_trigger_output: sc=%p start=%p end=%p "
	    "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));

	p = yds_find_dma(sc, start);
	if (!p) {
		printf("yds_trigger_output: bad addr %p\n", start);
		mtx_leave(&audio_lock);
		return (EINVAL);
	}
	sc->sc_play.dma = p;

#ifdef DIAGNOSTIC
	{
		u_int32_t ctrlsize;
		if ((ctrlsize = YREAD4(sc, YDS_PLAY_CTRLSIZE)) !=
		    sizeof(struct play_slot_ctrl_bank) / sizeof(u_int32_t))
			panic("%s: invalid play slot ctrldata %d %d",
			      sc->sc_dev.dv_xname, ctrlsize,
			      sizeof(struct play_slot_ctrl_bank));
	}
#endif

#ifdef YDS_USE_P44
	/* The document says the P44 SRC supports only stereo, 16bit PCM. */
	if (P44)
		p44 = ((param->sample_rate == 44100) &&
		       (param->channels == 2) &&
		       (param->precision == 16));
	else
#endif
		p44 = 0;
	channels = p44 ? 1 : param->channels;

	s = DMAADDR(p);
	l = ((char *)end - (char *)start);
	sc->sc_play.length = l;

	*sc->ptbl = channels;	/* Num of play */

	sc->sc_play.factor = 1;
	if (param->channels == 2)
		sc->sc_play.factor *= 2;
	if (param->precision != 8)
		sc->sc_play.factor *= 2;
	l /= sc->sc_play.factor;

	psb = sc->pbankp[0];
	memset(psb, 0, sizeof(*psb));
	psb->format = ((channels == 2 ? PSLT_FORMAT_STEREO : 0) |
		       (param->precision == 8 ? PSLT_FORMAT_8BIT : 0) |
		       (p44 ? PSLT_FORMAT_SRC441 : 0));
	psb->pgbase = s;
	psb->pgloopend = l;
	if (!p44) {
		psb->pgdeltaend = (param->sample_rate * 65536 / 48000) << 12;
		psb->lpfkend = yds_get_lpfk(param->sample_rate);
		psb->eggainend = gain;
		psb->lpfq = yds_get_lpfq(param->sample_rate);
		psb->pgdelta = psb->pgdeltaend;
		psb->lpfk = yds_get_lpfk(param->sample_rate);
		psb->eggain = gain;
	}

	for (i = 0; i < channels; i++) {
		/* i == 0: left or mono, i == 1: right */
		psb = sc->pbankp[i*2];
		if (i)
			/* copy from left */
			*psb = *(sc->pbankp[0]);
		if (channels == 2) {
			/* stereo */
			if (i == 0) {
				psb->lchgain = psb->lchgainend = gain;
			} else {
				psb->lchgain = psb->lchgainend = 0;
				psb->rchgain = psb->rchgainend = gain;
				psb->format |= PSLT_FORMAT_RCH;
			}
		} else if (!p44) {
			/* mono */
			psb->lchgain = psb->rchgain = gain;
			psb->lchgainend = psb->rchgainend = gain;
		}
		/* copy to the other bank */
		*(sc->pbankp[i*2+1]) = *psb;
	}

	YDS_DUMP_PLAY_SLOT(5, sc, 0);
	YDS_DUMP_PLAY_SLOT(5, sc, 1);

	if (p44)
		YWRITE4(sc, YDS_P44_OUT_VOLUME, 0x3fff3fff);
	else
		YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0x3fff3fff);

	/* Now the play slot for the next frame is set up!! */
	/* Sync play slot control data for both directions */
	bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,
			sc->ptbloff,
			sizeof(struct play_slot_ctrl_bank) *
			    channels * N_PLAY_SLOT_CTRL_BANK,
			BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
	/* Sync ring buffer */
	bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,
			BUS_DMASYNC_PREWRITE);
	/* HERE WE GO!! */
	YWRITE4(sc, YDS_MODE,
		YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2);
	mtx_leave(&audio_lock);
	return 0;
}