Lines Matching +full:pcm +full:- +full:interface +full:- +full:rate
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
33 #include <dev/sound/pcm/sound.h>
34 #include <dev/sound/pcm/ac97.h>
112 return bus_space_read_1(via->st, via->sh, regno); in via_rd()
114 return bus_space_read_2(via->st, via->sh, regno); in via_rd()
116 return bus_space_read_4(via->st, via->sh, regno); in via_rd()
128 bus_space_write_1(via->st, via->sh, regno, data); in via_wr()
131 bus_space_write_2(via->st, via->sh, regno, data); in via_wr()
134 bus_space_write_4(via->st, via->sh, regno, data); in via_wr()
139 /* -------------------------------------------------------------------- */
140 /* Codec interface */
181 if (via_waitready_codec(via)) return -1; in via_write_codec()
194 return -1; in via_read_codec()
199 return -1; in via_read_codec()
202 return -1; in via_read_codec()
214 /* -------------------------------------------------------------------- */
225 * This creates two half-buffers, one of which is playing; the other in via_buildsgdt()
228 seg_size = ch->blksz; in via_buildsgdt()
229 segs = sndbuf_getsize(ch->buffer) / seg_size; in via_buildsgdt()
230 phys_addr = sndbuf_getbufaddr(ch->buffer); in via_buildsgdt()
233 flag = (i == segs - 1)? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; in via_buildsgdt()
234 ch->sgd_table[i].ptr = phys_addr + (i * seg_size); in via_buildsgdt()
235 ch->sgd_table[i].flags = flag | seg_size; in via_buildsgdt()
241 /* channel interface */
248 snd_mtxlock(via->lock); in viachan_init()
250 ch = &via->pch; in viachan_init()
251 ch->base = VIA_PLAY_DMAOPS_BASE; in viachan_init()
252 ch->count = VIA_PLAY_DMAOPS_COUNT; in viachan_init()
253 ch->ctrl = VIA_PLAY_CONTROL; in viachan_init()
254 ch->mode = VIA_PLAY_MODE; in viachan_init()
255 ch->sgd_addr = via->sgd_addr; in viachan_init()
256 ch->sgd_table = &via->sgd_table[0]; in viachan_init()
258 ch = &via->rch; in viachan_init()
259 ch->base = VIA_RECORD_DMAOPS_BASE; in viachan_init()
260 ch->count = VIA_RECORD_DMAOPS_COUNT; in viachan_init()
261 ch->ctrl = VIA_RECORD_CONTROL; in viachan_init()
262 ch->mode = VIA_RECORD_MODE; in viachan_init()
263 ch->sgd_addr = via->sgd_addr + sizeof(struct via_dma_op) * SEGS_PER_CHAN; in viachan_init()
264 ch->sgd_table = &via->sgd_table[SEGS_PER_CHAN]; in viachan_init()
267 ch->parent = via; in viachan_init()
268 ch->channel = c; in viachan_init()
269 ch->buffer = b; in viachan_init()
270 ch->dir = dir; in viachan_init()
271 snd_mtxunlock(via->lock); in viachan_init()
273 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0) in viachan_init()
283 struct via_info *via = ch->parent; in viachan_setformat()
292 DEB(printf("set format: dir = %d, format=%x\n", ch->dir, format)); in viachan_setformat()
293 snd_mtxlock(via->lock); in viachan_setformat()
294 mode = via_rd(via, ch->mode, 1); in viachan_setformat()
297 via_wr(via, ch->mode, mode, 1); in viachan_setformat()
298 snd_mtxunlock(via->lock); in viachan_setformat()
307 struct via_info *via = ch->parent; in viachan_setspeed()
311 * Basic AC'97 defines a 48 kHz sample rate only. For other rates, in viachan_setspeed()
315 * If the codec supports variable-rate audio (i.e. does the upsampling in viachan_setspeed()
316 * itself), then negotiate the rate with the codec. Otherwise, in viachan_setspeed()
319 if (via->codec_caps & AC97_EXTCAP_VRA) { in viachan_setspeed()
320 reg = (ch->dir == PCMDIR_PLAY)? AC97_REGEXT_FDACRATE : AC97_REGEXT_LADCRATE; in viachan_setspeed()
321 return ac97_setrate(via->codec, reg, speed); in viachan_setspeed()
331 ch->blksz = blocksize; in viachan_setblocksize()
332 sndbuf_resize(ch->buffer, SEGS_PER_CHAN, ch->blksz); in viachan_setblocksize()
334 return ch->blksz; in viachan_setblocksize()
341 struct via_info *via = ch->parent; in viachan_trigger()
342 bus_addr_t sgd_addr = ch->sgd_addr; in viachan_trigger()
347 DEB(printf("ado located at va=%p pa=%x\n", ch->sgd_table, sgd_addr)); in viachan_trigger()
349 snd_mtxlock(via->lock); in viachan_trigger()
352 via_wr(via, ch->base, sgd_addr, 4); in viachan_trigger()
353 via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1); in viachan_trigger()
355 via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1); in viachan_trigger()
356 snd_mtxunlock(via->lock); in viachan_trigger()
366 struct via_info *via = ch->parent; in viachan_getptr()
367 bus_addr_t sgd_addr = ch->sgd_addr; in viachan_getptr()
370 snd_mtxlock(via->lock); in viachan_getptr()
371 base1 = via_rd(via, ch->base, 4); in viachan_getptr()
372 len = via_rd(via, ch->count, 4); in viachan_getptr()
373 base = via_rd(via, ch->base, 4); in viachan_getptr()
375 len = via_rd(via, ch->count, 4); in viachan_getptr()
376 snd_mtxunlock(via->lock); in viachan_getptr()
383 seg = (base - sgd_addr) / sizeof(struct via_dma_op); in viachan_getptr()
388 ptr = (seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN) - len; in viachan_getptr()
389 if (ch->dir == PCMDIR_REC) { in viachan_getptr()
391 /* so don't return any part line - it isn't in RAM yet */ in viachan_getptr()
403 struct via_info *via = ch->parent; in viachan_getcaps()
405 return (via->codec_caps & AC97_EXTCAP_VRA)? &via_vracaps : &via_caps; in viachan_getcaps()
420 /* -------------------------------------------------------------------- */
429 snd_mtxlock(via->lock); in via_intr()
432 snd_mtxunlock(via->lock); in via_intr()
433 chn_intr(via->pch.channel); in via_intr()
434 snd_mtxlock(via->lock); in via_intr()
440 snd_mtxunlock(via->lock); in via_intr()
441 chn_intr(via->rch.channel); in via_intr()
444 snd_mtxunlock(via->lock); in via_intr()
464 via->sgd_addr = bds->ds_addr; in dma_cb()
475 via->lock = snd_mtxcreate(device_get_nameunit(dev), in via_attach()
511 via->regid = PCIR_BAR(0); in via_attach()
512 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, in via_attach()
513 &via->regid, RF_ACTIVE); in via_attach()
514 if (!via->reg) { in via_attach()
518 via->st = rman_get_bustag(via->reg); in via_attach()
519 via->sh = rman_get_bushandle(via->reg); in via_attach()
521 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); in via_attach()
523 via->irqid = 0; in via_attach()
524 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid, in via_attach()
526 if (!via->irq || snd_setup_intr(dev, via->irq, INTR_MPSAFE, via_intr, via, &via->ih)) { in via_attach()
534 via->codec = AC97_CREATE(dev, via, via_ac97); in via_attach()
535 if (!via->codec) in via_attach()
538 if (mixer_init(dev, ac97_getmixerclass(), via->codec)) in via_attach()
541 via->codec_caps = ac97_getextcaps(via->codec); in via_attach()
542 ac97_setextmode(via->codec, in via_attach()
543 via->codec_caps & (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM)); in via_attach()
551 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, in via_attach()
553 /*lockarg*/NULL, &via->parent_dmat) != 0) { in via_attach()
571 /*lockarg*/NULL, &via->sgd_dmat) != 0) { in via_attach()
576 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, in via_attach()
577 BUS_DMA_NOWAIT, &via->sgd_dmamap) != 0) in via_attach()
579 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, in via_attach()
584 rman_get_start(via->reg), rman_get_start(via->irq), in via_attach()
595 if (via->codec) ac97_destroy(via->codec); in via_attach()
596 if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); in via_attach()
597 if (via->ih) bus_teardown_intr(dev, via->irq, via->ih); in via_attach()
598 if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); in via_attach()
599 if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat); in via_attach()
600 if (via->sgd_addr) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); in via_attach()
601 if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); in via_attach()
602 if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); in via_attach()
603 if (via->lock) snd_mtxfree(via->lock); in via_attach()
619 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); in via_detach()
620 bus_teardown_intr(dev, via->irq, via->ih); in via_detach()
621 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); in via_detach()
622 bus_dma_tag_destroy(via->parent_dmat); in via_detach()
623 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); in via_detach()
624 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap); in via_detach()
625 bus_dma_tag_destroy(via->sgd_dmat); in via_detach()
626 snd_mtxfree(via->lock); in via_detach()
639 "pcm",