Lines Matching +full:pcm +full:- +full:interface +full:- +full:rate
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
32 #include <dev/sound/pcm/sound.h>
42 #define ABS(x) (((x) < 0)? -(x) : (x))
64 * Recording output is byte-swapped
103 #define ess_lock(_ess) snd_mtxlock((_ess)->lock)
104 #define ess_unlock(_ess) snd_mtxunlock((_ess)->lock)
105 #define ess_lock_assert(_ess) snd_mtxassert((_ess)->lock)
130 * Common code for the midi and pcm functions
181 return port_rd(sc->sb, reg, 1); in ess_rd()
187 port_wr(sc->sb, reg, val, 1); in ess_wr()
256 for (i = 1000; i > 0; i--) { in ess_get_byte()
262 return -1; in ess_get_byte()
274 return (ess_cmd(sc, 0xc0) && ess_cmd(sc, reg))? ess_get_byte(sc) : -1; in ess_read()
287 rman_get_start(d->io_base))); in ess_reset_dsp()
313 if (sc->duplex) { in ess_intr()
314 pirq = (src & sc->pch.hwch)? 1 : 0; in ess_intr()
315 rirq = (src & sc->rch.hwch)? 1 : 0; in ess_intr()
317 if (sc->simplex_dir == PCMDIR_PLAY) in ess_intr()
319 if (sc->simplex_dir == PCMDIR_REC) in ess_intr()
328 if (sc->pch.stopping) { in ess_intr()
329 ess_dmatrigger(sc, sc->pch.hwch, 0); in ess_intr()
330 sc->pch.stopping = 0; in ess_intr()
331 if (sc->pch.hwch == 1) in ess_intr()
337 chn_intr(sc->pch.channel); in ess_intr()
342 if (sc->rch.stopping) { in ess_intr()
343 ess_dmatrigger(sc, sc->rch.hwch, 0); in ess_intr()
344 sc->rch.stopping = 0; in ess_intr()
349 chn_intr(sc->rch.channel); in ess_intr()
371 t = (256 - t) | 0x80; in ess_calcspeed8()
375 t = 128 - t; in ess_calcspeed8()
387 /* rate = source / (256 - divisor) */ in ess_calcspeed9()
388 /* divisor = 256 - (source / rate) */ in ess_calcspeed9()
390 t0 = 128 - (793800 / speed); in ess_calcspeed9()
391 s0 = 793800 / (128 - t0); in ess_calcspeed9()
393 t1 = 128 - (768000 / speed); in ess_calcspeed9()
394 s1 = 768000 / (128 - t1); in ess_calcspeed9()
397 use0 = (ABS(speed - s0) < ABS(speed - s1))? 1 : 0; in ess_calcspeed9()
408 /* cutoff = 7160000 / (256 - divisor) */ in ess_calcfilter()
409 /* divisor = 256 - (7160000 / cutoff) */ in ess_calcfilter()
411 return (256 - (7160000 / cutoff)); in ess_calcfilter()
424 spdval = (sc->newspeed)? ess_calcspeed9(&spd) : ess_calcspeed8(&spd); in ess_setupch()
426 sc->simplex_dir = play ? PCMDIR_PLAY : PCMDIR_REC ; in ess_setupch()
430 len = -len; in ess_setupch()
441 /* sample rate */ in ess_setupch()
465 len = -len; in ess_setupch()
475 if (sc->newspeed) { in ess_setupch()
476 /* sample rate */ in ess_setupch()
487 struct ess_info *sc = ch->parent; in ess_start()
490 ess_setupch(sc, ch->hwch, ch->dir, ch->spd, ch->fmt, ch->blksz); in ess_start()
491 ch->stopping = 0; in ess_start()
492 if (ch->hwch == 1) { in ess_start()
494 if (ch->dir == PCMDIR_PLAY) { in ess_start()
508 struct ess_info *sc = ch->parent; in ess_stop()
511 ch->stopping = 1; in ess_stop()
512 if (ch->hwch == 1) in ess_stop()
520 /* -------------------------------------------------------------------- */
521 /* channel interface for ESS18xx */
526 struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; in esschan_init()
529 ch->parent = sc; in esschan_init()
530 ch->channel = c; in esschan_init()
531 ch->buffer = b; in esschan_init()
532 ch->dir = dir; in esschan_init()
533 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0) in esschan_init()
535 ch->hwch = 1; in esschan_init()
536 if ((dir == PCMDIR_PLAY) && (sc->duplex)) in esschan_init()
537 ch->hwch = 2; in esschan_init()
546 ch->fmt = format; in esschan_setformat()
554 struct ess_info *sc = ch->parent; in esschan_setspeed()
556 ch->spd = speed; in esschan_setspeed()
557 if (sc->newspeed) in esschan_setspeed()
558 ess_calcspeed9(&ch->spd); in esschan_setspeed()
560 ess_calcspeed8(&ch->spd); in esschan_setspeed()
561 return ch->spd; in esschan_setspeed()
569 ch->blksz = blocksize; in esschan_setblocksize()
570 return ch->blksz; in esschan_setblocksize()
577 struct ess_info *sc = ch->parent; in esschan_trigger()
587 ess_dmasetup(sc, ch->hwch, sndbuf_getbufaddr(ch->buffer), sndbuf_getsize(ch->buffer), ch->dir); in esschan_trigger()
588 ess_dmatrigger(sc, ch->hwch, 1); in esschan_trigger()
606 struct ess_info *sc = ch->parent; in esschan_getptr()
610 ret = ess_dmapos(sc, ch->hwch); in esschan_getptr()
620 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps; in esschan_getcaps()
759 sc->dmasz[ch - 1] = cnt; in ess_dmasetup()
761 port_wr(sc->vc, 0x8, 0xc4, 1); /* command */ in ess_dmasetup()
762 port_wr(sc->vc, 0xd, 0xff, 1); /* reset */ in ess_dmasetup()
763 port_wr(sc->vc, 0xf, 0x01, 1); /* mask */ in ess_dmasetup()
764 port_wr(sc->vc, 0xb, dir == PCMDIR_PLAY? 0x58 : 0x54, 1); /* mode */ in ess_dmasetup()
765 port_wr(sc->vc, 0x0, base, 4); in ess_dmasetup()
766 port_wr(sc->vc, 0x4, cnt - 1, 2); in ess_dmasetup()
769 port_wr(sc->io, 0x6, 0x08, 1); /* autoinit */ in ess_dmasetup()
770 port_wr(sc->io, 0x0, base, 4); in ess_dmasetup()
771 port_wr(sc->io, 0x4, cnt, 2); in ess_dmasetup()
797 i = port_rd(sc->vc, 0x4, 2) + 1; in ess_dmapos()
798 p = port_rd(sc->vc, 0x4, 2) + 1; in ess_dmapos()
799 } while ((p > sc->dmasz[ch - 1] || i < p || (p - i) > 0x8) && j++ < 1000); in ess_dmapos()
803 p = port_rd(sc->io, 0x4, 2); in ess_dmapos()
804 return sc->dmasz[ch - 1] - p; in ess_dmapos()
812 port_wr(sc->vc, 0xf, go? 0x00 : 0x01, 1); /* mask */ in ess_dmatrigger()
814 port_wr(sc->io, 0x6, 0x08 | (go? 0x02 : 0x00), 1); /* autoinit */ in ess_dmatrigger()
821 if (sc->irq) { in ess_release_resources()
822 if (sc->ih) in ess_release_resources()
823 bus_teardown_intr(dev, sc->irq, sc->ih); in ess_release_resources()
824 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); in ess_release_resources()
825 sc->irq = NULL; in ess_release_resources()
827 if (sc->io) { in ess_release_resources()
828 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->io); in ess_release_resources()
829 sc->io = NULL; in ess_release_resources()
832 if (sc->sb) { in ess_release_resources()
833 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(1), sc->sb); in ess_release_resources()
834 sc->sb = NULL; in ess_release_resources()
837 if (sc->vc) { in ess_release_resources()
838 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(2), sc->vc); in ess_release_resources()
839 sc->vc = NULL; in ess_release_resources()
842 if (sc->mpu) { in ess_release_resources()
843 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(3), sc->mpu); in ess_release_resources()
844 sc->mpu = NULL; in ess_release_resources()
847 if (sc->gp) { in ess_release_resources()
848 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(4), sc->gp); in ess_release_resources()
849 sc->gp = NULL; in ess_release_resources()
852 if (sc->parent_dmat) { in ess_release_resources()
853 bus_dma_tag_destroy(sc->parent_dmat); in ess_release_resources()
854 sc->parent_dmat = 0; in ess_release_resources()
857 if (sc->lock) { in ess_release_resources()
858 snd_mtxfree(sc->lock); in ess_release_resources()
859 sc->lock = NULL; in ess_release_resources()
871 sc->io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
874 sc->sb = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
877 sc->vc = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
880 sc->mpu = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
883 sc->gp = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
886 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in ess_alloc_resources()
889 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_solo softc"); in ess_alloc_resources()
891 return (sc->irq && sc->io && sc->sb && sc->vc && in ess_alloc_resources()
892 sc->mpu && sc->gp && sc->lock)? 0 : ENXIO; in ess_alloc_resources()
905 s = "ESS Solo-1E"; in ess_probe()
907 s = "ESS Solo-1"; in ess_probe()
909 s = "ESS Solo-1 (unknown vendor)"; in ess_probe()
935 ddma = rman_get_start(sc->vc) | 1; in ess_resume()
948 if (sc->newspeed) in ess_resume()
951 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ in ess_resume()
972 sc->bufsz = pcm_getbuffersize(dev, 4096, SOLO_DEFAULT_BUFSZ, 65536); in ess_attach()
974 ddma = rman_get_start(sc->vc) | 1; in ess_attach()
979 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ in ess_attach()
981 sc->duplex = 1; in ess_attach()
983 sc->duplex = 0; in ess_attach()
987 sc->newspeed = 1; in ess_attach()
989 sc->newspeed = 0; in ess_attach()
991 if (snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ess_intr, sc, &sc->ih)) { in ess_attach()
996 if (!sc->duplex) in ess_attach()
1006 /*maxsize*/sc->bufsz, /*nsegments*/1, in ess_attach()
1010 &sc->parent_dmat) != 0) { in ess_attach()
1018 if (sc->newspeed) in ess_attach()
1025 rman_get_start(sc->io), rman_get_start(sc->sb), rman_get_start(sc->vc), in ess_attach()
1026 rman_get_start(sc->irq), in ess_attach()
1058 /* Device interface */
1068 "pcm",