Lines Matching +full:mono +full:- +full:channel
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
42 #define ABS(x) (((x) < 0)? -(x) : (x))
44 /* if defined, playback always uses the 2nd channel and full duplex works */
64 * Recording output is byte-swapped
83 struct pcm_channel *channel; member
103 #define ess_lock(_ess) mtx_lock(&(_ess)->lock)
104 #define ess_unlock(_ess) mtx_unlock(&(_ess)->lock)
105 #define ess_lock_assert(_ess) mtx_assert(&(_ess)->lock, MA_OWNED)
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()
437 /* mono/stereo */ in ess_setupch()
450 /* mono, b16: signed, load signal */ in ess_setupch()
465 len = -len; in ess_setupch()
475 if (sc->newspeed) { 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, ch->buffer->buf_addr, in esschan_trigger()
588 ch->buffer->bufsize, ch->dir); in esschan_trigger()
589 ess_dmatrigger(sc, ch->hwch, 1); in esschan_trigger()
607 struct ess_info *sc = ch->parent; in esschan_getptr()
611 ret = ess_dmapos(sc, ch->hwch); in esschan_getptr()
621 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps; in esschan_getcaps()
760 sc->dmasz[ch - 1] = cnt; in ess_dmasetup()
762 port_wr(sc->vc, 0x8, 0xc4, 1); /* command */ in ess_dmasetup()
763 port_wr(sc->vc, 0xd, 0xff, 1); /* reset */ in ess_dmasetup()
764 port_wr(sc->vc, 0xf, 0x01, 1); /* mask */ in ess_dmasetup()
765 port_wr(sc->vc, 0xb, dir == PCMDIR_PLAY? 0x58 : 0x54, 1); /* mode */ in ess_dmasetup()
766 port_wr(sc->vc, 0x0, base, 4); in ess_dmasetup()
767 port_wr(sc->vc, 0x4, cnt - 1, 2); in ess_dmasetup()
770 port_wr(sc->io, 0x6, 0x08, 1); /* autoinit */ in ess_dmasetup()
771 port_wr(sc->io, 0x0, base, 4); in ess_dmasetup()
772 port_wr(sc->io, 0x4, cnt, 2); in ess_dmasetup()
798 i = port_rd(sc->vc, 0x4, 2) + 1; in ess_dmapos()
799 p = port_rd(sc->vc, 0x4, 2) + 1; in ess_dmapos()
800 } while ((p > sc->dmasz[ch - 1] || i < p || (p - i) > 0x8) && j++ < 1000); in ess_dmapos()
804 p = port_rd(sc->io, 0x4, 2); in ess_dmapos()
805 return sc->dmasz[ch - 1] - p; in ess_dmapos()
813 port_wr(sc->vc, 0xf, go? 0x00 : 0x01, 1); /* mask */ in ess_dmatrigger()
815 port_wr(sc->io, 0x6, 0x08 | (go? 0x02 : 0x00), 1); /* autoinit */ in ess_dmatrigger()
822 if (sc->irq) { in ess_release_resources()
823 if (sc->ih) in ess_release_resources()
824 bus_teardown_intr(dev, sc->irq, sc->ih); in ess_release_resources()
825 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); in ess_release_resources()
826 sc->irq = NULL; in ess_release_resources()
828 if (sc->io) { in ess_release_resources()
829 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->io); in ess_release_resources()
830 sc->io = NULL; in ess_release_resources()
833 if (sc->sb) { in ess_release_resources()
834 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(1), sc->sb); in ess_release_resources()
835 sc->sb = NULL; in ess_release_resources()
838 if (sc->vc) { in ess_release_resources()
839 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(2), sc->vc); in ess_release_resources()
840 sc->vc = NULL; in ess_release_resources()
843 if (sc->mpu) { in ess_release_resources()
844 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(3), sc->mpu); in ess_release_resources()
845 sc->mpu = NULL; in ess_release_resources()
848 if (sc->gp) { in ess_release_resources()
849 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(4), sc->gp); in ess_release_resources()
850 sc->gp = NULL; in ess_release_resources()
853 if (sc->parent_dmat) { in ess_release_resources()
854 bus_dma_tag_destroy(sc->parent_dmat); in ess_release_resources()
855 sc->parent_dmat = 0; in ess_release_resources()
858 mtx_destroy(&sc->lock); in ess_release_resources()
869 sc->io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
872 sc->sb = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
875 sc->vc = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
878 sc->mpu = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
881 sc->gp = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE); in ess_alloc_resources()
884 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in ess_alloc_resources()
887 mtx_init(&sc->lock, device_get_nameunit(dev), "snd_solo softc", in ess_alloc_resources()
890 return (sc->irq && sc->io && sc->sb && sc->vc && in ess_alloc_resources()
891 sc->mpu && sc->gp)? 0 : ENXIO; in ess_alloc_resources()
904 s = "ESS Solo-1E"; in ess_probe()
906 s = "ESS Solo-1"; in ess_probe()
908 s = "ESS Solo-1 (unknown vendor)"; in ess_probe()
934 ddma = rman_get_start(sc->vc) | 1; in ess_resume()
947 if (sc->newspeed) in ess_resume()
950 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ in ess_resume()
971 sc->bufsz = pcm_getbuffersize(dev, 4096, SOLO_DEFAULT_BUFSZ, 65536); in ess_attach()
973 ddma = rman_get_start(sc->vc) | 1; in ess_attach()
978 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */ in ess_attach()
980 sc->duplex = 1; in ess_attach()
982 sc->duplex = 0; in ess_attach()
986 sc->newspeed = 1; in ess_attach()
988 sc->newspeed = 0; in ess_attach()
990 if (snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ess_intr, sc, &sc->ih)) { in ess_attach()
995 if (!sc->duplex) in ess_attach()
1005 /*maxsize*/sc->bufsz, /*nsegments*/1, in ess_attach()
1009 &sc->parent_dmat) != 0) { in ess_attach()
1017 if (sc->newspeed) in ess_attach()
1024 rman_get_start(sc->io), rman_get_start(sc->sb), rman_get_start(sc->vc), in ess_attach()
1025 rman_get_start(sc->irq), in ess_attach()