Lines Matching +full:pcm +full:- +full:sync +full:- +full:mode
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
44 #include <dev/sound/pcm/sound.h>
45 #include <dev/sound/pcm/ac97.h>
73 #define VIA_BLK_ALIGN (~(VIA_BLK_MIN - 1))
149 ret += via->pch[i].active;
152 ret += via->rch[i].active;
165 dev = oidp->oid_arg1;
167 snd_mtxlock(via->lock);
169 snd_mtxunlock(via->lock);
173 if (err || req->newptr == NULL)
182 snd_mtxlock(via->lock);
184 snd_mtxunlock(via->lock);
196 dev = oidp->oid_arg1;
198 snd_mtxlock(via->lock);
199 val = via->dxs_src;
200 snd_mtxunlock(via->lock);
203 if (err || req->newptr == NULL)
208 snd_mtxlock(via->lock);
209 via->dxs_src = val;
210 snd_mtxunlock(via->lock);
222 dev = oidp->oid_arg1;
226 snd_mtxlock(via->lock);
227 val = via->polling;
228 snd_mtxunlock(via->lock);
231 if (err || req->newptr == NULL)
236 snd_mtxlock(via->lock);
237 if (val != via->polling) {
241 via->polling = 0;
243 via->polling = 1;
245 snd_mtxunlock(via->lock);
254 if not done before 7.0-RELEASE, this needs to be converted to
255 a device specific sysctl "dev.pcm.X.yyy" via device_get_sysctl_*()
256 as discussed on multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */
270 dev, sizeof(dev), sysctl_via_polling, "I", "Enable polling mode");
278 return (bus_space_read_1(via->st, via->sh, regno));
280 return (bus_space_read_2(via->st, via->sh, regno));
282 return (bus_space_read_4(via->st, via->sh, regno));
294 bus_space_write_1(via->st, via->sh, regno, data);
297 bus_space_write_2(via->st, via->sh, regno, data);
300 bus_space_write_4(via->st, via->sh, regno, data);
305 /* -------------------------------------------------------------------- */
319 device_printf(via->dev, "%s: codec busy\n", __func__);
334 device_printf(via->dev, "%s: codec invalid\n", __func__);
344 return (-1);
359 return (-1);
365 return (-1);
368 return (-1);
380 /* -------------------------------------------------------------------- */
388 phys_addr = sndbuf_getbufaddr(ch->buffer);
390 for (i = 0; i < ch->blkcnt; i++) {
391 flag = (i == ch->blkcnt - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
392 ch->sgd_table[i].ptr = phys_addr + (i * ch->blksz);
393 ch->sgd_table[i].flags = flag | ch->blksz;
399 /* -------------------------------------------------------------------- */
406 struct via_info *via = ch->parent;
414 snd_mtxlock(via->lock);
416 snd_mtxunlock(via->lock);
425 struct via_info *via = ch->parent;
428 r = ch->rbase + VIA8233_RP_DXS_RATEFMT;
429 snd_mtxlock(via->lock);
438 snd_mtxunlock(via->lock);
447 struct via_info *via = ch->parent;
460 snd_mtxlock(via->lock);
463 snd_mtxunlock(via->lock);
468 /* -------------------------------------------------------------------- */
475 struct via_info *via = ch->parent;
477 if (via->codec_caps & AC97_EXTCAP_VRA)
478 return (ac97_setrate(via->codec, AC97_REGEXT_LADCRATE, speed));
487 struct via_info *via = ch->parent;
490 r = ch->rbase + VIA8233_RP_DXS_RATEFMT;
491 snd_mtxlock(via->lock);
498 snd_mtxunlock(via->lock);
507 struct via_info *via = ch->parent;
509 if (via->codec_caps & AC97_EXTCAP_VRA)
510 return (ac97_setrate(via->codec, AC97_REGEXT_FDACRATE, speed));
515 /* -------------------------------------------------------------------- */
522 struct via_info *via = ch->parent;
525 if (via->codec_caps & AC97_EXTCAP_VRA)
534 struct via_info *via = ch->parent;
542 if (via->dxs_src)
551 struct via_info *via = ch->parent;
554 if (via->codec_caps & AC97_EXTCAP_VRA)
559 /* -------------------------------------------------------------------- */
567 struct via_info *via = ch->parent;
571 if (blksz > (sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN))
572 blksz = sndbuf_getmaxsize(ch->buffer) / VIA_SEGS_MIN;
580 while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
589 if ((sndbuf_getblksz(ch->buffer) != blksz ||
590 sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
591 sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
592 device_printf(via->dev, "%s: failed blksz=%u blkcnt=%u\n",
595 ch->blksz = sndbuf_getblksz(ch->buffer);
596 ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
605 struct via_info *via = ch->parent;
607 via8233chan_setfragments(obj, data, blksz, via->blkcnt);
609 return (ch->blksz);
616 struct via_info *via = ch->parent;
619 snd_mtxlock(via->lock);
620 if (via->polling != 0) {
621 ptr = ch->ptr;
622 snd_mtxunlock(via->lock);
624 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4);
625 snd_mtxunlock(via->lock);
628 ptr = (index + 1) * ch->blksz - count;
629 ptr %= ch->blkcnt * ch->blksz; /* Wrap to available space */
638 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1);
639 via_wr(via, ch->rbase + VIA_RP_CONTROL, 0x00, 1);
640 via_wr(via, ch->rbase + VIA_RP_STATUS,
644 /* -------------------------------------------------------------------- */
650 ch->sgd_table = &via->sgd_table[chnum * VIA_SEGS_MAX];
651 ch->sgd_addr = via->sgd_addr + chnum * VIA_SEGS_MAX *
663 snd_mtxlock(via->lock);
664 num = via->rec_num++;
665 ch = &via->rch[num];
666 ch->parent = via;
667 ch->channel = c;
668 ch->buffer = b;
669 ch->dir = dir;
670 ch->blkcnt = via->blkcnt;
671 ch->rbase = VIA_WR_BASE(num);
672 via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1);
673 snd_mtxunlock(via->lock);
675 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0)
678 snd_mtxlock(via->lock);
681 snd_mtxunlock(via->lock);
694 snd_mtxlock(via->lock);
695 num = via->play_num++;
696 ch = &via->pch[num];
697 ch->parent = via;
698 ch->channel = c;
699 ch->buffer = b;
700 ch->dir = dir;
701 ch->blkcnt = via->blkcnt;
708 ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered);
709 via->n_dxs_registered++;
710 snd_mtxunlock(via->lock);
712 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0)
715 snd_mtxlock(via->lock);
718 snd_mtxunlock(via->lock);
731 snd_mtxlock(via->lock);
732 num = via->play_num++;
733 ch = &via->pch[num];
734 ch->parent = via;
735 ch->channel = c;
736 ch->buffer = b;
737 ch->dir = dir;
738 ch->rbase = VIA_MC_SGD_STATUS;
739 ch->blkcnt = via->blkcnt;
740 snd_mtxunlock(via->lock);
742 if (sndbuf_alloc(ch->buffer, via->parent_dmat, 0, via->bufsz) != 0)
745 snd_mtxlock(via->lock);
748 snd_mtxunlock(via->lock);
756 if (BASE_IS_VIA_DXS_REG(ch->rbase)) {
759 via_wr(via, ch->rbase + VIA8233_RP_DXS_LVOL, muted, 1);
760 via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1);
761 r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) &
764 device_printf(via->dev,
766 "(dxs base 0x%02x).\n", __func__, ch->rbase);
778 if (ch == NULL || ch->channel == NULL || ch->active == 0)
781 via = ch->parent;
782 sz = ch->blksz * ch->blkcnt;
783 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4);
786 ptr = ((index + 1) * ch->blksz) - count;
788 ptr &= ~(ch->blksz - 1);
789 ch->ptr = ptr;
790 delta = (sz + ptr - ch->prevptr) % sz;
792 if (delta < ch->blksz)
795 ch->prevptr = ptr;
810 snd_mtxlock(via->lock);
811 if (via->polling == 0 || via_chan_active(via) == 0) {
812 snd_mtxunlock(via->lock);
817 ptrigger |= (via_poll_channel(&via->pch[i]) != 0) ?
821 rtrigger |= (via_poll_channel(&via->rch[i]) != 0) ?
825 callout_reset(&via->poll_timer, 1/*via->poll_ticks*/,
828 snd_mtxunlock(via->lock);
832 chn_intr(via->pch[i].channel);
836 chn_intr(via->rch[i].channel);
849 ch = &via->pch[i];
850 if (ch->channel == NULL || ch->active == 0)
852 pollticks = ((uint64_t)hz * ch->blksz) /
853 ((uint64_t)sndbuf_getalign(ch->buffer) *
854 sndbuf_getspd(ch->buffer));
865 ch = &via->rch[i];
866 if (ch->channel == NULL || ch->active == 0)
868 pollticks = ((uint64_t)hz * ch->blksz) /
869 ((uint64_t)sndbuf_getalign(ch->buffer) *
870 sndbuf_getspd(ch->buffer));
887 struct via_info *via = ch->parent;
893 snd_mtxlock(via->lock);
898 via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4);
899 if (via->polling != 0) {
900 ch->ptr = 0;
901 ch->prevptr = 0;
902 pollticks = ((uint64_t)hz * ch->blksz) /
903 ((uint64_t)sndbuf_getalign(ch->buffer) *
904 sndbuf_getspd(ch->buffer));
911 pollticks < via->poll_ticks) {
918 "pollticks %d -> %d\n",
919 __func__, via->poll_ticks,
922 via->poll_ticks = pollticks;
923 callout_reset(&via->poll_timer, 1,
927 via_wr(via, ch->rbase + VIA_RP_CONTROL,
929 ((via->polling == 0) ?
931 ch->active = 1;
935 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1);
938 ch->active = 0;
939 if (via->polling != 0) {
941 callout_stop(&via->poll_timer);
942 via->poll_ticks = 1;
945 if (pollticks > via->poll_ticks) {
948 "%d -> %d\n",
949 __func__, via->poll_ticks,
951 via->poll_ticks = pollticks;
952 callout_reset(&via->poll_timer,
962 snd_mtxunlock(via->lock);
1005 /* -------------------------------------------------------------------- */
1014 snd_mtxlock(via->lock);
1015 if (via->polling != 0) {
1016 snd_mtxunlock(via->lock);
1021 if (via->pch[i].channel == NULL || via->pch[i].active == 0)
1023 reg = via->pch[i].rbase + VIA_RP_STATUS;
1026 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) ||
1028 via_wr(via, via->pch[i].rbase + VIA_RP_CONTROL,
1037 if (via->rch[i].channel == NULL || via->rch[i].active == 0)
1039 reg = via->rch[i].rbase + VIA_RP_STATUS;
1042 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) ||
1044 via_wr(via, via->rch[i].rbase + VIA_RP_CONTROL,
1051 snd_mtxunlock(via->lock);
1055 chn_intr(via->pch[i].channel);
1059 chn_intr(via->rch[i].channel);
1105 via->sgd_addr = bds->ds_addr;
1133 /* Force no sync */
1137 /* Sync */
1142 /* Force no sync */
1173 via->lock = snd_mtxcreate(device_get_nameunit(dev),
1175 via->dev = dev;
1177 callout_init(&via->poll_timer, 1);
1178 via->poll_ticks = 1;
1182 via->polling = 1;
1184 via->polling = 0;
1189 via->regid = PCIR_BAR(0);
1190 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid,
1192 if (!via->reg) {
1196 via->st = rman_get_bustag(via->reg);
1197 via->sh = rman_get_bushandle(via->reg);
1199 via->irqid = 0;
1200 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid,
1202 if (!via->irq ||
1203 snd_setup_intr(dev, via->irq, INTR_MPSAFE,
1204 via_intr, via, &via->ih)) {
1209 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536);
1215 via->blkcnt = via->bufsz / i;
1217 while (via->blkcnt >> i)
1219 via->blkcnt = 1 << (i - 1);
1220 if (via->blkcnt < VIA_SEGS_MIN)
1221 via->blkcnt = VIA_SEGS_MIN;
1222 else if (via->blkcnt > VIA_SEGS_MAX)
1223 via->blkcnt = VIA_SEGS_MAX;
1226 via->blkcnt = VIA_SEGS_DEFAULT;
1235 via->dma_eol_wake = 1;
1237 via->dma_eol_wake = 0;
1245 * that it plays at half-speed. Do not see this behaviour
1285 via->dxs_src = (via_dxs_src > 0) ? 1 : 0;
1287 via->dxs_src = 0;
1297 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1299 /*lockarg*/NULL, &via->parent_dmat) != 0) {
1317 /*lockarg*/NULL, &via->sgd_dmat) != 0) {
1322 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table,
1323 BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
1325 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table,
1332 via->codec = AC97_CREATE(dev, via, via_ac97);
1333 if (!via->codec)
1336 mixer_init(dev, ac97_getmixerclass(), via->codec);
1338 via->codec_caps = ac97_getextcaps(via->codec);
1341 if (via->codec_caps &
1343 uint16_t ext = ac97_getextmode(via->codec);
1344 ext |= (via->codec_caps &
1347 ac97_setextmode(via->codec, ext);
1351 rman_get_start(via->reg), rman_get_start(via->irq),
1365 (via_dxs_chnum > 0) ? "En" : "Dis", (via->dxs_src) ? "(SRC)" : "",
1373 if (via->codec)
1374 ac97_destroy(via->codec);
1375 if (via->reg)
1376 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
1377 if (via->ih)
1378 bus_teardown_intr(dev, via->irq, via->ih);
1379 if (via->irq)
1380 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
1381 if (via->parent_dmat)
1382 bus_dma_tag_destroy(via->parent_dmat);
1383 if (via->sgd_addr)
1384 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
1385 if (via->sgd_table)
1386 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
1387 if (via->sgd_dmat)
1388 bus_dma_tag_destroy(via->sgd_dmat);
1389 if (via->lock)
1390 snd_mtxfree(via->lock);
1408 if (via != NULL && (via->play_num != 0 || via->rec_num != 0)) {
1409 snd_mtxlock(via->lock);
1410 via->polling = 0;
1411 callout_stop(&via->poll_timer);
1412 snd_mtxunlock(via->lock);
1413 callout_drain(&via->poll_timer);
1416 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
1417 bus_teardown_intr(dev, via->irq, via->ih);
1418 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
1419 bus_dma_tag_destroy(via->parent_dmat);
1420 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
1421 bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
1422 bus_dma_tag_destroy(via->sgd_dmat);
1423 snd_mtxfree(via->lock);
1436 "pcm",