Lines Matching +full:pcm +full:- +full:sync +full:- +full:mode

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
30 * FreeBSD pcm driver for ATI IXP 150/200/250/300 AC97 controllers
34 * * 32bit native playback - yay!
54 * Takashi Iwai (ALSA snd-atiixp), for register definitions and some
62 #include <dev/sound/pcm/sound.h>
63 #include <dev/sound/pcm/ac97.h>
79 #define ATI_IXP_BLK_ALIGN (~(ATI_IXP_BLK_MIN - 1))
138 bus_space_read_4((_sc)->st, (_sc)->sh, _reg)
140 bus_space_write_4((_sc)->st, (_sc)->sh, _reg, _val)
142 #define atiixp_lock(_sc) snd_mtxlock((_sc)->lock)
143 #define atiixp_unlock(_sc) snd_mtxunlock((_sc)->lock)
144 #define atiixp_assert(_sc) snd_mtxassert((_sc)->lock)
288 /* check if the ac-link is working; reset device otherwise */
291 while (!(value & ATI_REG_CMD_ACLINK_ACTIVE) && --timeout) {
293 device_printf(sc->dev, "not up; resetting aclink hardware\n");
315 device_printf(sc->dev, "giving up aclink reset\n");
318 device_printf(sc->dev, "aclink hardware reset successful\n");
321 /* assert reset and sync for safety */
330 atiixp_wr(ch->parent, ATI_REG_FIFO_FLUSH, ch->flush_bit);
338 value = atiixp_rd(ch->parent, ATI_REG_CMD);
339 if (!(value & ch->enable_bit)) {
340 value |= ch->enable_bit;
341 atiixp_wr(ch->parent, ATI_REG_CMD, value);
350 value = atiixp_rd(ch->parent, ATI_REG_CMD);
351 if (value & ch->enable_bit) {
352 value &= ~ch->enable_bit;
353 atiixp_wr(ch->parent, ATI_REG_CMD, value);
370 } while (--timeout);
372 return (-1);
383 return (-1);
386 ATI_REG_PHYS_OUT_ADDR_EN | ATI_REG_PHYS_OUT_RW | sc->codec_idx;
391 return (-1);
399 } while (--timeout);
402 device_printf(sc->dev, "codec read timeout! (reg 0x%x)\n", reg);
404 return (-1);
413 return (-1);
417 ATI_REG_PHYS_OUT_ADDR_EN | sc->codec_idx;
445 ch = &sc->pch;
446 ch->linkptr_bit = ATI_REG_OUT_DMA_LINKPTR;
447 ch->enable_bit = ATI_REG_CMD_OUT_DMA_EN | ATI_REG_CMD_SEND_EN;
448 ch->flush_bit = ATI_REG_FIFO_OUT_FLUSH;
449 ch->dt_cur_bit = ATI_REG_OUT_DMA_DT_CUR;
451 ch->caps_32bit = 1;
453 ch = &sc->rch;
454 ch->linkptr_bit = ATI_REG_IN_DMA_LINKPTR;
455 ch->enable_bit = ATI_REG_CMD_IN_DMA_EN | ATI_REG_CMD_RECEIVE_EN;
456 ch->flush_bit = ATI_REG_FIFO_IN_FLUSH;
457 ch->dt_cur_bit = ATI_REG_IN_DMA_DT_CUR;
459 ch->caps_32bit = 1;
462 ch->buffer = b;
463 ch->parent = sc;
464 ch->channel = c;
465 ch->dir = dir;
466 ch->blkcnt = sc->blkcnt;
467 ch->blksz = sc->bufsz / ch->blkcnt;
471 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) == -1)
475 num = sc->registered_channels++;
476 ch->sgd_table = &sc->sgd_table[num * ATI_IXP_DMA_CHSEGS_MAX];
477 ch->sgd_addr = sc->sgd_addr + (num * ATI_IXP_DMA_CHSEGS_MAX *
489 struct atiixp_info *sc = ch->parent;
493 if (ch->dir == PCMDIR_REC) {
516 ch->fmt = format;
534 struct atiixp_info *sc = ch->parent;
538 if (blksz > (sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN))
539 blksz = sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN;
547 while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
556 if ((sndbuf_getblksz(ch->buffer) != blksz ||
557 sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
558 sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
559 device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
562 ch->blksz = sndbuf_getblksz(ch->buffer);
563 ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
572 struct atiixp_info *sc = ch->parent;
574 atiixp_chan_setfragments(obj, data, blksz, sc->blkcnt);
576 return (ch->blksz);
582 struct atiixp_info *sc = ch->parent;
586 addr = sndbuf_getbufaddr(ch->buffer);
588 if (sc->polling != 0) {
589 blksz = ch->blksz * ch->blkcnt;
592 blksz = ch->blksz;
593 blkcnt = ch->blkcnt;
597 ch->sgd_table[i].addr = htole32(addr + (i * blksz));
598 ch->sgd_table[i].status = htole16(0);
599 ch->sgd_table[i].size = htole16(blksz >> 2);
600 ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr +
608 struct atiixp_info *sc = ch->parent;
612 reg = ch->dt_cur_bit;
613 addr = sndbuf_getbufaddr(ch->buffer);
614 sz = ch->blkcnt * ch->blksz;
621 ptr -= addr;
625 if ((ptr & ~(ch->blksz - 1)) != ch->ptr) {
628 delta = (sz + ptr - ch->prevptr) % sz;
630 if (delta < ch->blksz)
632 device_printf(sc->dev,
638 (ch->dir == PCMDIR_PLAY) ?
640 ch->prevptr, ptr,
641 ch->ptr, ch->blkcnt,
642 delta, ch->blksz,
643 (delta < ch->blksz) ?
645 ch->ptr = ptr & ~(ch->blksz - 1);
647 ch->prevptr = ptr;
652 } while (--retry);
654 device_printf(sc->dev, "PCMDIR_%s: invalid DMA pointer ptr=%u\n",
655 (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr);
666 if (!(ch->flags & ATI_IXP_CHN_RUNNING))
669 sz = ch->blksz * ch->blkcnt;
671 ch->ptr = ptr;
673 ptr &= ~(ch->blksz - 1);
674 delta = (sz + ptr - ch->prevptr) % sz;
676 if (delta < ch->blksz)
679 ch->prevptr = ptr;
684 #define atiixp_chan_active(sc) (((sc)->pch.flags | (sc)->rch.flags) & \
697 if (sc->polling == 0 || atiixp_chan_active(sc) == 0) {
702 trigger |= (atiixp_poll_channel(&sc->pch) != 0) ? 1 : 0;
703 trigger |= (atiixp_poll_channel(&sc->rch) != 0) ? 2 : 0;
706 callout_reset(&sc->poll_timer, 1/*sc->poll_ticks*/,
712 chn_intr(sc->pch.channel);
714 chn_intr(sc->rch.channel);
721 struct atiixp_info *sc = ch->parent;
734 atiixp_wr(sc, ch->linkptr_bit, 0);
736 atiixp_wr(sc, ch->linkptr_bit,
737 (uint32_t)ch->sgd_addr | ATI_REG_LINKPTR_EN);
738 if (sc->polling != 0) {
739 ch->ptr = 0;
740 ch->prevptr = 0;
741 pollticks = ((uint64_t)hz * ch->blksz) /
742 ((uint64_t)sndbuf_getalign(ch->buffer) *
743 sndbuf_getspd(ch->buffer));
750 pollticks < sc->poll_ticks) {
753 device_printf(sc->dev,
757 device_printf(sc->dev,
758 "%s: pollticks %d -> %d\n",
759 __func__, sc->poll_ticks,
762 sc->poll_ticks = pollticks;
763 callout_reset(&sc->poll_timer, 1,
767 ch->flags |= ATI_IXP_CHN_RUNNING;
773 ch->flags &= ~ATI_IXP_CHN_RUNNING;
774 if (sc->polling != 0) {
776 callout_stop(&sc->poll_timer);
777 sc->poll_ticks = 1;
779 if (sc->pch.flags & ATI_IXP_CHN_RUNNING)
780 ch = &sc->pch;
782 ch = &sc->rch;
783 pollticks = ((uint64_t)hz * ch->blksz) /
784 ((uint64_t)sndbuf_getalign(ch->buffer) *
785 sndbuf_getspd(ch->buffer));
791 if (pollticks > sc->poll_ticks) {
793 device_printf(sc->dev,
794 "%s: pollticks %d -> %d\n",
795 __func__, sc->poll_ticks,
797 sc->poll_ticks = pollticks;
798 callout_reset(&sc->poll_timer,
829 struct atiixp_info *sc = ch->parent;
833 if (sc->polling != 0)
834 ptr = ch->ptr;
847 if (ch->caps_32bit)
876 if (sc->polling != 0) {
888 (sc->pch.flags & ATI_IXP_CHN_RUNNING))
891 (sc->rch.flags & ATI_IXP_CHN_RUNNING))
896 device_printf(sc->dev,
900 device_printf(sc->dev,
908 sc->codec_not_ready_bits |= detected_codecs;
922 chn_intr(sc->pch.channel);
924 chn_intr(sc->rch.channel);
931 sc->sgd_addr = bds->ds_addr;
953 sc->codec_not_ready_bits = 0;
968 dev = oidp->oid_arg1;
973 val = sc->polling;
977 if (err || req->newptr == NULL)
983 if (val != sc->polling) {
988 sc->polling = 0;
992 sc->polling = 1;
1011 if (sc->delayed_attach.ich_func) {
1012 config_intrhook_disestablish(&sc->delayed_attach);
1013 sc->delayed_attach.ich_func = NULL;
1016 polling = sc->polling;
1017 sc->polling = 0;
1020 if (sc->codec_not_ready_bits == 0) {
1023 msleep(sc, sc->lock, PWAIT, "ixpslp", max(hz / 10, 1));
1024 if (sc->codec_not_ready_bits != 0)
1026 } while (--timeout);
1029 sc->polling = polling;
1032 if (sc->codec_not_ready_bits == 0 && timeout == 0) {
1033 device_printf(sc->dev,
1046 if (!(sc->codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) {
1048 sc->codec_found++;
1049 sc->codec_idx = 0;
1053 if (!(sc->codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) {
1055 sc->codec_found++;
1058 if (!(sc->codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) {
1060 sc->codec_found++;
1069 sc->codec = AC97_CREATE(sc->dev, sc, atiixp_ac97);
1070 if (sc->codec == NULL)
1073 subdev = (pci_get_subdevice(sc->dev) << 16) |
1074 pci_get_subvendor(sc->dev);
1077 case 0x2043161f: /* Maxselect x710s - http://maxselect.ru/ */
1078 ac97_setflags(sc->codec, ac97_getflags(sc->codec) |
1085 mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
1087 pcm_init(sc->dev, sc);
1090 pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
1092 pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);
1094 SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
1095 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
1096 "polling", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc->dev,
1097 sizeof(sc->dev), sysctl_atiixp_polling, "I", "Enable polling mode");
1100 rman_get_start(sc->reg), rman_get_start(sc->irq),
1101 device_get_nameunit(device_get_parent(sc->dev)));
1103 if (pcm_register(sc->dev, status))
1107 if (sc->polling == 0)
1122 if (sc->registered_channels != 0) {
1124 sc->polling = 0;
1125 callout_stop(&sc->poll_timer);
1127 callout_drain(&sc->poll_timer);
1129 if (sc->codec) {
1130 ac97_destroy(sc->codec);
1131 sc->codec = NULL;
1133 if (sc->ih) {
1134 bus_teardown_intr(sc->dev, sc->irq, sc->ih);
1135 sc->ih = NULL;
1137 if (sc->reg) {
1138 bus_release_resource(sc->dev, sc->regtype, sc->regid, sc->reg);
1139 sc->reg = NULL;
1141 if (sc->irq) {
1142 bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqid, sc->irq);
1143 sc->irq = NULL;
1145 if (sc->parent_dmat) {
1146 bus_dma_tag_destroy(sc->parent_dmat);
1147 sc->parent_dmat = NULL;
1149 if (sc->sgd_addr) {
1150 bus_dmamap_unload(sc->sgd_dmat, sc->sgd_dmamap);
1151 sc->sgd_addr = 0;
1153 if (sc->sgd_table) {
1154 bus_dmamem_free(sc->sgd_dmat, sc->sgd_table, sc->sgd_dmamap);
1155 sc->sgd_table = NULL;
1157 if (sc->sgd_dmat) {
1158 bus_dma_tag_destroy(sc->sgd_dmat);
1159 sc->sgd_dmat = NULL;
1161 if (sc->lock) {
1162 snd_mtxfree(sc->lock);
1163 sc->lock = NULL;
1194 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_atiixp softc");
1195 sc->dev = dev;
1197 callout_init(&sc->poll_timer, 1);
1198 sc->poll_ticks = 1;
1200 if (resource_int_value(device_get_name(sc->dev),
1201 device_get_unit(sc->dev), "polling", &i) == 0 && i != 0)
1202 sc->polling = 1;
1204 sc->polling = 0;
1208 sc->regid = PCIR_BAR(0);
1209 sc->regtype = SYS_RES_MEMORY;
1210 sc->reg = bus_alloc_resource_any(dev, sc->regtype,
1211 &sc->regid, RF_ACTIVE);
1213 if (!sc->reg) {
1218 sc->st = rman_get_bustag(sc->reg);
1219 sc->sh = rman_get_bushandle(sc->reg);
1221 sc->bufsz = pcm_getbuffersize(dev, ATI_IXP_BUFSZ_MIN,
1224 sc->irqid = 0;
1225 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
1227 if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE,
1228 atiixp_intr, sc, &sc->ih)) {
1241 sc->blkcnt = sc->bufsz / i;
1243 while (sc->blkcnt >> i)
1245 sc->blkcnt = 1 << (i - 1);
1246 if (sc->blkcnt < ATI_IXP_DMA_CHSEGS_MIN)
1247 sc->blkcnt = ATI_IXP_DMA_CHSEGS_MIN;
1248 else if (sc->blkcnt > ATI_IXP_DMA_CHSEGS_MAX)
1249 sc->blkcnt = ATI_IXP_DMA_CHSEGS_MAX;
1252 sc->blkcnt = ATI_IXP_DMA_CHSEGS;
1255 * DMA tag for scatter-gather buffers and link pointers
1262 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1264 /*lockarg*/NULL, &sc->parent_dmat) != 0) {
1278 /*lockarg*/NULL, &sc->sgd_dmat) != 0) {
1283 if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table,
1284 BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1)
1287 if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
1294 sc->delayed_attach.ich_func = atiixp_chip_post_init;
1295 sc->delayed_attach.ich_arg = sc;
1297 config_intrhook_establish(&sc->delayed_attach) != 0) {
1298 sc->delayed_attach.ich_func = NULL;
1317 if (sc->codec != NULL) {
1322 sc->codec = NULL;
1323 if (sc->st != 0 && sc->sh != 0)
1341 if (sc->pch.flags & ATI_IXP_CHN_RUNNING) {
1342 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP);
1343 sc->pch.flags |= ATI_IXP_CHN_SUSPEND;
1345 if (sc->rch.flags & ATI_IXP_CHN_RUNNING) {
1346 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP);
1347 sc->rch.flags |= ATI_IXP_CHN_SUSPEND;
1368 if (mixer_reinit(dev) == -1) {
1377 if (sc->pch.channel != NULL) {
1378 if (sc->pch.fmt != 0)
1379 atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
1380 if (sc->pch.flags & ATI_IXP_CHN_SUSPEND) {
1381 sc->pch.flags &= ~ATI_IXP_CHN_SUSPEND;
1382 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START);
1385 if (sc->rch.channel != NULL) {
1386 if (sc->rch.fmt != 0)
1387 atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
1388 if (sc->rch.flags & ATI_IXP_CHN_SUSPEND) {
1389 sc->rch.flags &= ~ATI_IXP_CHN_SUSPEND;
1390 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
1396 if (sc->polling == 0)
1413 "pcm",