예제 #1
0
파일: fm801.c 프로젝트: kusumi/DragonFlyBSD
static int
fm801ch_setformat(kobj_t obj, void *data, u_int32_t format)
{
	struct fm801_chinfo *ch = data;
	struct fm801_info *fm801 = ch->parent;

	DPRINT("fm801ch_setformat 0x%x : %s, %s, %s, %s\n", format,
		(AFMT_CHANNEL(format) > 1)?"stereo":"mono",
		(format & AFMT_16BIT) ? "16bit":"8bit",
		(format & AFMT_SIGNED)? "signed":"unsigned",
		(format & AFMT_BIGENDIAN)?"bigendiah":"littleendian" );

	if(ch->dir == PCMDIR_PLAY) {
		fm801->play_fmt =
		    (AFMT_CHANNEL(format) > 1)? FM_PLAY_STEREO : 0;
		fm801->play_fmt |= (format & AFMT_16BIT) ? FM_PLAY_16BIT : 0;
		return 0;
	}

	if(ch->dir == PCMDIR_REC ) {
		fm801->rec_fmt = (AFMT_CHANNEL(format) > 1)? FM_REC_STEREO:0;
		fm801->rec_fmt |= (format & AFMT_16BIT) ? FM_PLAY_16BIT : 0;
		return 0;
	}

	return 0;
}
예제 #2
0
파일: neomagic.c 프로젝트: JabirTech/Source
static int
nm_setch(struct sc_chinfo *ch)
{
	struct sc_info *sc = ch->parent;
	u_int32_t base;
	u_int8_t x;

	for (x = 0; x < 8; x++)
		if (ch->spd < (samplerates[x] + samplerates[x + 1]) / 2)
			break;

	if (x == 8) return 1;

	ch->spd = samplerates[x];
	nm_loadcoeff(sc, ch->dir, x);

	x <<= 4;
	x &= NM_RATE_MASK;
	if (ch->fmt & AFMT_16BIT) x |= NM_RATE_BITS_16;
	if (AFMT_CHANNEL(ch->fmt) > 1) x |= NM_RATE_STEREO;

	base = (ch->dir == PCMDIR_PLAY)? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET;
	nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1);
	return 0;
}
예제 #3
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
/* 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;
}
예제 #4
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
static void
ds_setuprch(struct sc_rchinfo *ch)
{
	struct sc_info *sc = ch->parent;
	int stereo, b16, i, sz, pri;
	u_int32_t x, y;
	bus_addr_t addr;

	stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
	b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
	addr = sndbuf_getbufaddr(ch->buffer);
	sz = sndbuf_getsize(ch->buffer);
	pri = (ch->num == DS1_RECPRIMARY)? 1 : 0;

	for (i = 0; i < 2; i++) {
		ch->slot[i].PgBase = addr;
		ch->slot[i].PgLoopEnd = sz;
		ch->slot[i].PgStart = 0;
		ch->slot[i].NumOfLoops = 0;
	}
	x = (b16? 0x00 : 0x01) | (stereo? 0x02 : 0x00);
	y = (48000 * 4096) / ch->spd;
	y--;
	/* printf("pri = %d, x = %d, y = %d\n", pri, x, y); */
	ds_wr(sc, pri? YDSXGR_ADCFORMAT : YDSXGR_RECFORMAT, x, 4);
	ds_wr(sc, pri? YDSXGR_ADCSLOTSR : YDSXGR_RECSLOTSR, y, 4);
}
예제 #5
0
static void
bcm2835_audio_update_params(struct bcm2835_audio_info *sc, struct bcm2835_audio_chinfo *ch)
{
	VC_AUDIO_MSG_T m;
	int ret;

	VCHIQ_VCHI_LOCK(sc);
	if (sc->vchi_handle != VCHIQ_SERVICE_HANDLE_INVALID) {
		vchi_service_use(sc->vchi_handle);

		sc->msg_result = -1;

		m.type = VC_AUDIO_MSG_TYPE_CONFIG;
		m.u.config.channels = AFMT_CHANNEL(ch->fmt);
		m.u.config.samplerate = ch->spd;
		m.u.config.bps = AFMT_BIT(ch->fmt);

		ret = vchi_msg_queue(sc->vchi_handle,
		    &m, sizeof m, VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);

		if (ret != 0)
			printf("%s: vchi_msg_queue failed (err %d)\n", __func__, ret);

		mtx_lock(&sc->msg_avail_lock);
		cv_wait_sig(&sc->msg_avail_cv, &sc->msg_avail_lock);
		if (sc->msg_result)
			printf("%s failed: %d\n", __func__, sc->msg_result);
		mtx_unlock(&sc->msg_avail_lock);

		vchi_service_release(sc->vchi_handle);
	}
	VCHIQ_VCHI_UNLOCK(sc);
}
예제 #6
0
static inline u_int32_t
cs4281_format_to_dmr(u_int32_t format)
{
    u_int32_t dmr = 0;
    if (AFMT_8BIT & format)      dmr |= CS4281PCI_DMR_SIZE8;
    if (AFMT_CHANNEL(format) < 2) dmr |= CS4281PCI_DMR_MONO;
    if (AFMT_BIGENDIAN & format) dmr |= CS4281PCI_DMR_BEND;
    if (!(AFMT_SIGNED & format)) dmr |= CS4281PCI_DMR_USIGN;
    return dmr;
}
예제 #7
0
static int
feed_volume_init(struct pcm_feeder *f)
{
	struct feed_volume_info *info;
	struct pcmchan_matrix *m;
	uint32_t i;
	int ret;

	if (f->desc->in != f->desc->out ||
	    AFMT_CHANNEL(f->desc->in) > SND_CHN_MAX)
		return (EINVAL);

	for (i = 0; i < FEEDVOLUME_TAB_SIZE; i++) {
		if (AFMT_ENCODING(f->desc->in) ==
		    feed_volume_info_tab[i].format) {
			info = malloc(sizeof(*info), M_DEVBUF,
			    M_NOWAIT | M_ZERO);
			if (info == NULL)
				return (ENOMEM);

			info->bps = AFMT_BPS(f->desc->in);
			info->channels = AFMT_CHANNEL(f->desc->in);
			info->apply = feed_volume_info_tab[i].apply;
			info->volume_class = SND_VOL_C_PCM;
			info->state = FEEDVOLUME_ENABLE;

			f->data = info;
			m = feeder_matrix_default_channel_map(info->channels);
			if (m == NULL) {
				free(info, M_DEVBUF);
				return (EINVAL);
			}

			ret = feeder_volume_apply_matrix(f, m);
			if (ret != 0)
				free(info, M_DEVBUF);

			return (ret);
		}
	}

	return (EINVAL);
}
예제 #8
0
static int
ad1816chan_setformat(kobj_t obj, void *data, u_int32_t format)
{
    struct ad1816_chinfo *ch = data;
    struct ad1816_info *ad1816 = ch->parent;
    int fmt = AD1816_U8, reg;

    ad1816_lock(ad1816);
    if (ch->dir == PCMDIR_PLAY) {
        reg = AD1816_PLAY;
        ad1816_write(ad1816, 8, 0x0000);	/* reset base and current counter */
        ad1816_write(ad1816, 9, 0x0000);	/* for playback and capture */
    } else {
        reg = AD1816_CAPT;
        ad1816_write(ad1816, 10, 0x0000);
        ad1816_write(ad1816, 11, 0x0000);
    }
    switch (AFMT_ENCODING(format)) {
    case AFMT_A_LAW:
        fmt = AD1816_ALAW;
        break;

    case AFMT_MU_LAW:
        fmt = AD1816_MULAW;
        break;

    case AFMT_S16_LE:
        fmt = AD1816_S16LE;
        break;

    case AFMT_S16_BE:
        fmt = AD1816_S16BE;
        break;

    case AFMT_U8:
        fmt = AD1816_U8;
        break;
    }
    if (AFMT_CHANNEL(format) > 1) fmt |= AD1816_STEREO;
    io_wr(ad1816, reg, fmt);
    ad1816_unlock(ad1816);
#if 0
    return format;
#else
    return 0;
#endif
}
예제 #9
0
파일: neomagic.c 프로젝트: JabirTech/Source
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;
}
예제 #10
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
static void
ds_setuppch(struct sc_pchinfo *ch)
{
	int stereo, b16, c, sz;
	bus_addr_t addr;

	stereo = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
	b16 = (ch->fmt & AFMT_16BIT)? 1 : 0;
	c = stereo? 1 : 0;
	addr = sndbuf_getbufaddr(ch->buffer);
	sz = sndbuf_getsize(ch->buffer);

	ds_initpbank(ch->lslot, c, stereo, b16, ch->spd, addr, sz);
	ds_initpbank(ch->lslot + 1, c, stereo, b16, ch->spd, addr, sz);
	ds_initpbank(ch->rslot, 2, stereo, b16, ch->spd, addr, sz);
	ds_initpbank(ch->rslot + 1, 2, stereo, b16, ch->spd, addr, sz);
}
예제 #11
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
static u_int32_t
ds1pchan_getptr(kobj_t obj, void *data)
{
	struct sc_pchinfo *ch = data;
	struct sc_info *sc = ch->parent;
	volatile struct pbank *bank;
	int ss;
	u_int32_t ptr;

	ss = (AFMT_CHANNEL(ch->fmt) > 1)? 1 : 0;
	ss += (ch->fmt & AFMT_16BIT)? 1 : 0;

	bank = ch->lslot + sc->currbank;
	/* printf("getptr: %d\n", bank->PgStart << ss); */
	ptr = bank->PgStart;
	ptr <<= ss;
	return ptr;
}
예제 #12
0
static void
bcm2835_audio_update_params(struct bcm2835_audio_info *sc, uint32_t fmt, uint32_t speed)
{
	VC_AUDIO_MSG_T m;
	int ret;

	if (sc->vchi_handle != VCHIQ_SERVICE_HANDLE_INVALID) {
		m.type = VC_AUDIO_MSG_TYPE_CONFIG;
		m.u.config.channels = AFMT_CHANNEL(fmt);
		m.u.config.samplerate = speed;
		m.u.config.bps = AFMT_BIT(fmt);

		ret = vchi_msg_queue(sc->vchi_handle,
		    &m, sizeof m, VCHI_FLAGS_BLOCK_UNTIL_QUEUED, NULL);

		if (ret != 0)
			printf("%s: vchi_msg_queue failed (err %d)\n", __func__, ret);
	}
}
예제 #13
0
파일: via82c686.c 프로젝트: Alkzndr/freebsd
static int
viachan_setformat(kobj_t obj, void *data, u_int32_t format)
{
	struct via_chinfo *ch = data;
	struct via_info *via = ch->parent;
	int mode, mode_set;

	mode_set = 0;
	if (AFMT_CHANNEL(format) > 1)
		mode_set |= VIA_RPMODE_STEREO;
	if (format & AFMT_S16_LE)
		mode_set |= VIA_RPMODE_16BIT;

	DEB(printf("set format: dir = %d, format=%x\n", ch->dir, format));
	snd_mtxlock(via->lock);
	mode = via_rd(via, ch->mode, 1);
	mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO);
	mode |= mode_set;
	via_wr(via, ch->mode, mode, 1);
	snd_mtxunlock(via->lock);

	return 0;
}
예제 #14
0
static inline u_int32_t
cs4281_format_to_bps(u_int32_t format)
{
    return ((AFMT_8BIT & format) ? 1 : 2) *
	((AFMT_CHANNEL(format) > 1) ? 2 : 1);
}