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; }
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; }
/* 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; }
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); }
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); }
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; }
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); }
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 }
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; }
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); }
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; }
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); } }
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; }
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); }