static int via8233dxs_setformat(kobj_t obj, void *data, u_int32_t format) { struct via_chinfo *ch = data; struct via_info *via = ch->parent; u_int32_t r, v; r = ch->rbase + VIA8233_RP_DXS_RATEFMT; snd_mtxlock(via->lock); v = via_rd(via, r, 4); v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); if (format & AFMT_STEREO) v |= VIA8233_DXS_RATEFMT_STEREO; if (format & AFMT_16BIT) v |= VIA8233_DXS_RATEFMT_16BIT; via_wr(via, r, v, 4); snd_mtxunlock(via->lock); return 0; }
static int viachan_getptr(kobj_t obj, void *data) { struct via_chinfo *ch = data; struct via_info *via = ch->parent; struct via_dma_op *ado; bus_addr_t sgd_addr = ch->sgd_addr; int ptr, base, base1, len, seg; ado = ch->sgd_table; snd_mtxlock(via->lock); base1 = via_rd(via, ch->base, 4); len = via_rd(via, ch->count, 4); base = via_rd(via, ch->base, 4); if (base != base1) /* Avoid race hazard */ len = via_rd(via, ch->count, 4); snd_mtxunlock(via->lock); DEB(kprintf("viachan_getptr: len / base = %x / %x\n", len, base)); /* Base points to SGD segment to do, one past current */ /* Determine how many segments have been done */ seg = (base - sgd_addr) / sizeof(struct via_dma_op); if (seg == 0) seg = SEGS_PER_CHAN; /* Now work out offset: seg less count */ ptr = (seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN) - len; if (ch->dir == PCMDIR_REC) { /* DMA appears to operate on memory 'lines' of 32 bytes */ /* so don't return any part line - it isn't in RAM yet */ ptr = ptr & ~0x1f; } DEB(kprintf("return ptr=%d\n", ptr)); return ptr; }
static void* via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct via_info *via = devinfo; struct via_chinfo *ch = &via->pch[c->num]; ch->parent = via; ch->channel = c; ch->buffer = b; ch->dir = dir; ch->rbase = VIA_MC_SGD_STATUS; if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) return NULL; snd_mtxlock(via->lock); via8233chan_sgdinit(via, ch, NWRCHANS + c->num); via8233chan_reset(via, ch); snd_mtxunlock(via->lock); return ch; }
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 (format & AFMT_STEREO) mode_set |= VIA_RPMODE_STEREO; if (format & AFMT_S16_LE) mode_set |= VIA_RPMODE_16BIT; DEB(kprintf("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 int via8233msgd_setformat(kobj_t obj, void *data, u_int32_t format) { struct via_chinfo *ch = data; struct via_info *via = ch->parent; u_int32_t s = 0xff000000; u_int8_t v = (format & AFMT_S16_LE) ? MC_SGD_16BIT : MC_SGD_8BIT; if (format & AFMT_STEREO) { v |= MC_SGD_CHANNELS(2); s |= SLOT3(1) | SLOT4(2); } else { v |= MC_SGD_CHANNELS(1); s |= SLOT3(1) | SLOT4(1); } snd_mtxlock(via->lock); via_wr(via, VIA_MC_SLOT_SELECT, s, 4); via_wr(via, VIA_MC_SGD_FORMAT, v, 1); snd_mtxunlock(via->lock); return 0; }
/* channel interface */ static void * viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir) { struct via_info *via = devinfo; struct via_chinfo *ch; snd_mtxlock(via->lock); if (dir == PCMDIR_PLAY) { ch = &via->pch; ch->base = VIA_PLAY_DMAOPS_BASE; ch->count = VIA_PLAY_DMAOPS_COUNT; ch->ctrl = VIA_PLAY_CONTROL; ch->mode = VIA_PLAY_MODE; ch->sgd_addr = via->sgd_addr; ch->sgd_table = &via->sgd_table[0]; } else { ch = &via->rch; ch->base = VIA_RECORD_DMAOPS_BASE; ch->count = VIA_RECORD_DMAOPS_COUNT; ch->ctrl = VIA_RECORD_CONTROL; ch->mode = VIA_RECORD_MODE; ch->sgd_addr = via->sgd_addr + sizeof(struct via_dma_op) * SEGS_PER_CHAN; ch->sgd_table = &via->sgd_table[SEGS_PER_CHAN]; } ch->parent = via; ch->channel = c; ch->buffer = b; ch->dir = dir; snd_mtxunlock(via->lock); if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) return NULL; return ch; }
static void ad1816_lock(struct ad1816_info *ad1816) { snd_mtxlock(ad1816->lock); }
void sbc_lock(struct sbc_softc *scp) { snd_mtxlock(scp->lock); }