Lines Matching refs:sc

107 static int ess_rd(struct ess_info *sc, int reg);
108 static void ess_wr(struct ess_info *sc, int reg, u_int8_t val);
109 static int ess_dspready(struct ess_info *sc);
110 static int ess_cmd(struct ess_info *sc, u_char val);
111 static int ess_cmd1(struct ess_info *sc, u_char cmd, int val);
112 static int ess_get_byte(struct ess_info *sc);
113 static void ess_setmixer(struct ess_info *sc, u_int port, u_int value);
114 static int ess_getmixer(struct ess_info *sc, u_int port);
115 static int ess_reset_dsp(struct ess_info *sc);
117 static int ess_write(struct ess_info *sc, u_char reg, int val);
118 static int ess_read(struct ess_info *sc, u_char reg);
121 static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len);
125 static int ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir);
126 static int ess_dmapos(struct ess_info *sc, int ch);
127 static int ess_dmatrigger(struct ess_info *sc, int ch, int go);
179 ess_rd(struct ess_info *sc, int reg)
181 return port_rd(sc->sb, reg, 1);
185 ess_wr(struct ess_info *sc, int reg, u_int8_t val)
187 port_wr(sc->sb, reg, val, 1);
191 ess_dspready(struct ess_info *sc)
193 return ((ess_rd(sc, SBDSP_STATUS) & 0x80) == 0);
197 ess_dspwr(struct ess_info *sc, u_char val)
202 if (ess_dspready(sc)) {
203 ess_wr(sc, SBDSP_CMD, val);
213 ess_cmd(struct ess_info *sc, u_char val)
216 return ess_dspwr(sc, val);
220 ess_cmd1(struct ess_info *sc, u_char cmd, int val)
223 if (ess_dspwr(sc, cmd)) {
224 return ess_dspwr(sc, val & 0xff);
229 ess_setmixer(struct ess_info *sc, u_int port, u_int value)
232 ess_wr(sc, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */
234 ess_wr(sc, SB_MIX_DATA, (u_char) (value & 0xff));
239 ess_getmixer(struct ess_info *sc, u_int port)
243 ess_wr(sc, SB_MIX_ADDR, (u_char) (port & 0xff)); /* Select register */
245 val = ess_rd(sc, SB_MIX_DATA);
252 ess_get_byte(struct ess_info *sc)
257 if (ess_rd(sc, 0xc) & 0x40)
258 return ess_rd(sc, DSP_READ);
266 ess_write(struct ess_info *sc, u_char reg, int val)
268 return ess_cmd1(sc, reg, val);
272 ess_read(struct ess_info *sc, u_char reg)
274 return (ess_cmd(sc, 0xc0) && ess_cmd(sc, reg))? ess_get_byte(sc) : -1;
278 ess_reset_dsp(struct ess_info *sc)
281 ess_wr(sc, SBDSP_RST, 3);
283 ess_wr(sc, SBDSP_RST, 0);
284 if (ess_get_byte(sc) != 0xAA) {
291 ess_cmd(sc, 0xc6);
298 struct ess_info *sc = (struct ess_info *)arg;
301 ess_lock(sc);
303 if (ess_getmixer(sc, 0x7a) & 0x80)
305 if (ess_rd(sc, 0x0c) & 0x01)
309 ess_unlock(sc);
313 if (sc->duplex) {
314 pirq = (src & sc->pch.hwch)? 1 : 0;
315 rirq = (src & sc->rch.hwch)? 1 : 0;
317 if (sc->simplex_dir == PCMDIR_PLAY)
319 if (sc->simplex_dir == PCMDIR_REC)
328 if (sc->pch.stopping) {
329 ess_dmatrigger(sc, sc->pch.hwch, 0);
330 sc->pch.stopping = 0;
331 if (sc->pch.hwch == 1)
332 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01);
334 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x03);
336 ess_unlock(sc);
337 chn_intr(sc->pch.channel);
338 ess_lock(sc);
342 if (sc->rch.stopping) {
343 ess_dmatrigger(sc, sc->rch.hwch, 0);
344 sc->rch.stopping = 0;
346 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01);
348 ess_unlock(sc);
349 chn_intr(sc->rch.channel);
350 ess_lock(sc);
354 ess_setmixer(sc, 0x7a, ess_getmixer(sc, 0x7a) & ~0x80);
356 ess_rd(sc, DSP_DATA_AVAIL);
358 ess_unlock(sc);
415 ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len)
424 spdval = (sc->newspeed)? ess_calcspeed9(&spd) : ess_calcspeed8(&spd);
426 sc->simplex_dir = play ? PCMDIR_PLAY : PCMDIR_REC ;
432 ess_write(sc, 0xa4, len & 0x00ff);
434 ess_write(sc, 0xa5, (len & 0xff00) >> 8);
436 ess_write(sc, 0xb8, 0x04 | (play? 0x00 : 0x0a));
438 ess_write(sc, 0xa8, (ess_read(sc, 0xa8) & ~0x03) | (stereo? 0x01 : 0x02));
440 ess_write(sc, 0xb9, 0x02);
442 ess_write(sc, 0xa1, spdval);
444 ess_write(sc, 0xa2, ess_calcfilter(spd));
448 ess_write(sc, 0xb6, unsign? 0x80 : 0x00);
452 ess_write(sc, 0xb7, 0x51 | (unsign? 0x00 : 0x20));
455 ess_write(sc, 0xb7, 0x91 | (unsign? 0x00 : 0x20) |
459 ess_write(sc, 0xb1, (ess_read(sc, 0xb1) & 0x0f) | 0x50);
461 ess_write(sc, 0xb2, (ess_read(sc, 0xb2) & 0x0f) | 0x50);
467 ess_setmixer(sc, 0x74, len & 0x00ff);
469 ess_setmixer(sc, 0x76, (len & 0xff00) >> 8);
471 ess_setmixer(sc, 0x78, 0x10);
474 ess_setmixer(sc, 0x7a, 0x40 | fmtval);
475 if (sc->newspeed) {
477 ess_setmixer(sc, 0x70, spdval);
479 ess_setmixer(sc, 0x72, ess_calcfilter(spd));
487 struct ess_info *sc = ch->parent;
490 ess_setupch(sc, ch->hwch, ch->dir, ch->spd, ch->fmt, ch->blksz);
493 ess_write(sc, 0xb8, ess_read(sc, 0xb8) | 0x01);
498 ess_cmd(sc, 0xd1);
501 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) | 0x03);
508 struct ess_info *sc = ch->parent;
513 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x04);
515 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x10);
525 struct ess_info *sc = devinfo;
526 struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;
529 ch->parent = sc;
533 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0)
536 if ((dir == PCMDIR_PLAY) && (sc->duplex))
554 struct ess_info *sc = ch->parent;
557 if (sc->newspeed)
577 struct ess_info *sc = ch->parent;
584 ess_lock(sc);
587 ess_dmasetup(sc, ch->hwch, sndbuf_getbufaddr(ch->buffer), sndbuf_getsize(ch->buffer), ch->dir);
588 ess_dmatrigger(sc, ch->hwch, 1);
598 ess_unlock(sc);
606 struct ess_info *sc = ch->parent;
609 ess_lock(sc);
610 ret = ess_dmapos(sc, ch->hwch);
611 ess_unlock(sc);
640 struct ess_info *sc = mix_getdevinfo(m);
649 ess_setmixer(sc, 0, 0); /* reset */
657 struct ess_info *sc = mix_getdevinfo(m);
696 ess_setmixer(sc, 0x60, l);
697 ess_setmixer(sc, 0x62, r);
704 ess_setmixer(sc, preg, (l << 4) | r);
706 ess_setmixer(sc, rreg, (l << 4) | r);
717 struct ess_info *sc = mix_getdevinfo(m);
740 ess_setmixer(sc, 0x1c, recdev);
756 ess_dmasetup(struct ess_info *sc, int ch, u_int32_t base, u_int16_t cnt, int dir)
759 sc->dmasz[ch - 1] = cnt;
761 port_wr(sc->vc, 0x8, 0xc4, 1); /* command */
762 port_wr(sc->vc, 0xd, 0xff, 1); /* reset */
763 port_wr(sc->vc, 0xf, 0x01, 1); /* mask */
764 port_wr(sc->vc, 0xb, dir == PCMDIR_PLAY? 0x58 : 0x54, 1); /* mode */
765 port_wr(sc->vc, 0x0, base, 4);
766 port_wr(sc->vc, 0x4, cnt - 1, 2);
769 port_wr(sc->io, 0x6, 0x08, 1); /* autoinit */
770 port_wr(sc->io, 0x0, base, 4);
771 port_wr(sc->io, 0x4, cnt, 2);
777 ess_dmapos(struct ess_info *sc, int ch)
790 ess_dmatrigger(sc, ch, 0);
797 i = port_rd(sc->vc, 0x4, 2) + 1;
798 p = port_rd(sc->vc, 0x4, 2) + 1;
799 } while ((p > sc->dmasz[ch - 1] || i < p || (p - i) > 0x8) && j++ < 1000);
800 ess_dmatrigger(sc, ch, 1);
803 p = port_rd(sc->io, 0x4, 2);
804 return sc->dmasz[ch - 1] - p;
808 ess_dmatrigger(struct ess_info *sc, int ch, int go)
812 port_wr(sc->vc, 0xf, go? 0x00 : 0x01, 1); /* mask */
814 port_wr(sc->io, 0x6, 0x08 | (go? 0x02 : 0x00), 1); /* autoinit */
819 ess_release_resources(struct ess_info *sc, device_t dev)
821 if (sc->irq) {
822 if (sc->ih)
823 bus_teardown_intr(dev, sc->irq, sc->ih);
824 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
825 sc->irq = NULL;
827 if (sc->io) {
828 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->io);
829 sc->io = NULL;
832 if (sc->sb) {
833 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(1), sc->sb);
834 sc->sb = NULL;
837 if (sc->vc) {
838 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(2), sc->vc);
839 sc->vc = NULL;
842 if (sc->mpu) {
843 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(3), sc->mpu);
844 sc->mpu = NULL;
847 if (sc->gp) {
848 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(4), sc->gp);
849 sc->gp = NULL;
852 if (sc->parent_dmat) {
853 bus_dma_tag_destroy(sc->parent_dmat);
854 sc->parent_dmat = 0;
857 if (sc->lock) {
858 snd_mtxfree(sc->lock);
859 sc->lock = NULL;
862 free(sc, M_DEVBUF);
866 ess_alloc_resources(struct ess_info *sc, device_t dev)
871 sc->io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
874 sc->sb = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
877 sc->vc = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
880 sc->mpu = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
883 sc->gp = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
886 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
889 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_solo softc");
891 return (sc->irq && sc->io && sc->sb && sc->vc &&
892 sc->mpu && sc->gp && sc->lock)? 0 : ENXIO;
932 struct ess_info *sc = pcm_getdevinfo(dev);
934 ess_lock(sc);
935 ddma = rman_get_start(sc->vc) | 1;
940 if (ess_reset_dsp(sc)) {
941 ess_unlock(sc);
944 ess_unlock(sc);
947 ess_lock(sc);
948 if (sc->newspeed)
949 ess_setmixer(sc, 0x71, 0x2a);
951 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */
952 ess_unlock(sc);
962 struct ess_info *sc;
966 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
969 if (ess_alloc_resources(sc, dev))
972 sc->bufsz = pcm_getbuffersize(dev, 4096, SOLO_DEFAULT_BUFSZ, 65536);
974 ddma = rman_get_start(sc->vc) | 1;
979 port_wr(sc->io, 0x7, 0xb0, 1); /* enable irqs */
981 sc->duplex = 1;
983 sc->duplex = 0;
987 sc->newspeed = 1;
989 sc->newspeed = 0;
991 if (snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ess_intr, sc, &sc->ih)) {
996 if (!sc->duplex)
1006 /*maxsize*/sc->bufsz, /*nsegments*/1,
1010 &sc->parent_dmat) != 0) {
1015 if (ess_reset_dsp(sc))
1018 if (sc->newspeed)
1019 ess_setmixer(sc, 0x71, 0x2a);
1021 if (mixer_init(dev, &solomixer_class, sc))
1025 rman_get_start(sc->io), rman_get_start(sc->sb), rman_get_start(sc->vc),
1026 rman_get_start(sc->irq),
1029 if (pcm_register(dev, sc, 1, 1))
1031 pcm_addchan(dev, PCMDIR_REC, &esschan_class, sc);
1032 pcm_addchan(dev, PCMDIR_PLAY, &esschan_class, sc);
1038 ess_release_resources(sc, dev);
1046 struct ess_info *sc;
1052 sc = pcm_getdevinfo(dev);
1053 ess_release_resources(sc, dev);