Deleted Added
full compact
ess.c (67652) ess.c (70134)
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Copyright 1997,1998 Luigi Rizzo.
4 *
5 * Derived from files in the Voxware 3.5 distribution,
6 * Copyright by Hannu Savolainen 1994, under the same copyright
7 * conditions.
8 * All rights reserved.

--- 14 unchanged lines hidden (view full) ---

23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Copyright 1997,1998 Luigi Rizzo.
4 *
5 * Derived from files in the Voxware 3.5 distribution,
6 * Copyright by Hannu Savolainen 1994, under the same copyright
7 * conditions.
8 * All rights reserved.

--- 14 unchanged lines hidden (view full) ---

23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $FreeBSD: head/sys/dev/sound/isa/ess.c 67652 2000-10-26 20:46:58Z cg $
31 * $FreeBSD: head/sys/dev/sound/isa/ess.c 70134 2000-12-18 01:36:41Z cg $
32 */
33
34#include <dev/sound/pcm/sound.h>
35
36#include <dev/sound/isa/sb.h>
37#include <dev/sound/chip.h>
38
32 */
33
34#include <dev/sound/pcm/sound.h>
35
36#include <dev/sound/isa/sb.h>
37#include <dev/sound/chip.h>
38
39#include "mixer_if.h"
40
39#define ESS_BUFFSIZE (4096)
40#define ABS(x) (((x) < 0)? -(x) : (x))
41
42/* audio2 never generates irqs and sounds very noisy */
43#undef ESS18XX_DUPLEX
44
45/* more accurate clocks and split audio1/audio2 rates */
46#define ESS18XX_NEWSPEED
47
41#define ESS_BUFFSIZE (4096)
42#define ABS(x) (((x) < 0)? -(x) : (x))
43
44/* audio2 never generates irqs and sounds very noisy */
45#undef ESS18XX_DUPLEX
46
47/* more accurate clocks and split audio1/audio2 rates */
48#define ESS18XX_NEWSPEED
49
48/* channel interface for ESS */
49static void *esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
50static int esschan_setformat(void *data, u_int32_t format);
51static int esschan_setspeed(void *data, u_int32_t speed);
52static int esschan_setblocksize(void *data, u_int32_t blocksize);
53static int esschan_trigger(void *data, int go);
54static int esschan_getptr(void *data);
55static pcmchan_caps *esschan_getcaps(void *data);
56
57static u_int32_t ess_pfmt[] = {
58 AFMT_U8,
59 AFMT_STEREO | AFMT_U8,
60 AFMT_S8,
61 AFMT_STEREO | AFMT_S8,
62 AFMT_S16_LE,
63 AFMT_STEREO | AFMT_S16_LE,
64 AFMT_U16_LE,

--- 12 unchanged lines hidden (view full) ---

77 AFMT_STEREO | AFMT_S16_LE,
78 AFMT_U16_LE,
79 AFMT_STEREO | AFMT_U16_LE,
80 0
81};
82
83static pcmchan_caps ess_reccaps = {5000, 49000, ess_rfmt, 0};
84
50static u_int32_t ess_pfmt[] = {
51 AFMT_U8,
52 AFMT_STEREO | AFMT_U8,
53 AFMT_S8,
54 AFMT_STEREO | AFMT_S8,
55 AFMT_S16_LE,
56 AFMT_STEREO | AFMT_S16_LE,
57 AFMT_U16_LE,

--- 12 unchanged lines hidden (view full) ---

70 AFMT_STEREO | AFMT_S16_LE,
71 AFMT_U16_LE,
72 AFMT_STEREO | AFMT_U16_LE,
73 0
74};
75
76static pcmchan_caps ess_reccaps = {5000, 49000, ess_rfmt, 0};
77
85static pcm_channel ess_chantemplate = {
86 esschan_init,
87 NULL, /* setdir */
88 esschan_setformat,
89 esschan_setspeed,
90 esschan_setblocksize,
91 esschan_trigger,
92 esschan_getptr,
93 esschan_getcaps,
94 NULL, /* free */
95 NULL, /* nop1 */
96 NULL, /* nop2 */
97 NULL, /* nop3 */
98 NULL, /* nop4 */
99 NULL, /* nop5 */
100 NULL, /* nop6 */
101 NULL, /* nop7 */
102};
103
104struct ess_info;
105
106struct ess_chinfo {
107 struct ess_info *parent;
108 pcm_channel *channel;
109 snd_dbuf *buffer;
78struct ess_info;
79
80struct ess_chinfo {
81 struct ess_info *parent;
82 pcm_channel *channel;
83 snd_dbuf *buffer;
110 int dir, hwch, stopping;
84 int dir, hwch, stopping, run;
111 u_int32_t fmt, spd;
112};
113
114struct ess_info {
115 struct resource *io_base; /* I/O address for the board */
116 struct resource *irq;
117 struct resource *drq1;
118 struct resource *drq2;

--- 18 unchanged lines hidden (view full) ---

137static int ess_write(struct ess_info *sc, u_char reg, int val);
138static int ess_read(struct ess_info *sc, u_char reg);
139
140static void ess_intr(void *arg);
141static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len);
142static int ess_start(struct ess_chinfo *ch);
143static int ess_stop(struct ess_chinfo *ch);
144
85 u_int32_t fmt, spd;
86};
87
88struct ess_info {
89 struct resource *io_base; /* I/O address for the board */
90 struct resource *irq;
91 struct resource *drq1;
92 struct resource *drq2;

--- 18 unchanged lines hidden (view full) ---

111static int ess_write(struct ess_info *sc, u_char reg, int val);
112static int ess_read(struct ess_info *sc, u_char reg);
113
114static void ess_intr(void *arg);
115static int ess_setupch(struct ess_info *sc, int ch, int dir, int spd, u_int32_t fmt, int len);
116static int ess_start(struct ess_chinfo *ch);
117static int ess_stop(struct ess_chinfo *ch);
118
145static int essmix_init(snd_mixer *m);
146static int essmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
147static int essmix_setrecsrc(snd_mixer *m, u_int32_t src);
148
149static snd_mixer ess_mixer = {
150 "ESS mixer",
151 essmix_init,
152 NULL,
153 NULL,
154 essmix_set,
155 essmix_setrecsrc,
156};
157
158static devclass_t pcm_devclass;
159
160/*
161 * Common code for the midi and pcm functions
162 *
163 * ess_cmd write a single byte to the CMD port.
164 * ess_cmd1 write a CMD + 1 byte arg
165 * ess_cmd2 write a CMD + 2 byte arg

--- 206 unchanged lines hidden (view full) ---

372 isa_dma_acquire(rman_get_start(sc->drq2));
373 isa_dmainit(rman_get_start(sc->drq2), ESS_BUFFSIZE);
374 }
375
376 return 0;
377 } else return ENXIO;
378}
379
119static devclass_t pcm_devclass;
120
121/*
122 * Common code for the midi and pcm functions
123 *
124 * ess_cmd write a single byte to the CMD port.
125 * ess_cmd1 write a CMD + 1 byte arg
126 * ess_cmd2 write a CMD + 2 byte arg

--- 206 unchanged lines hidden (view full) ---

333 isa_dma_acquire(rman_get_start(sc->drq2));
334 isa_dmainit(rman_get_start(sc->drq2), ESS_BUFFSIZE);
335 }
336
337 return 0;
338 } else return ENXIO;
339}
340
380static int
381ess_doattach(device_t dev, struct ess_info *sc)
382{
383 char status[SND_STATUSLEN], buf[64];
384 int ver;
385
386 if (ess_alloc_resources(sc, dev))
387 goto no;
388 if (ess_reset_dsp(sc))
389 goto no;
390 mixer_init(dev, &ess_mixer, sc);
391
392 sc->duplex = 0;
393 sc->newspeed = 0;
394 ver = (ess_getmixer(sc, 0x40) << 8) | ess_rd(sc, SB_MIX_DATA);
395 snprintf(buf, sizeof buf, "ESS %x DSP", ver);
396 device_set_desc_copy(dev, buf);
397 if (bootverbose)
398 device_printf(dev, "ESS%x detected", ver);
399
400 switch (ver) {
401 case 0x1869:
402 case 0x1879:
403#ifdef ESS18XX_DUPLEX
404 sc->duplex = sc->drq2? 1 : 0;
405#endif
406#ifdef ESS18XX_NEWSPEED
407 sc->newspeed = 1;
408#endif
409 break;
410 }
411 if (bootverbose)
412 printf("%s%s\n", sc->duplex? ", duplex" : "",
413 sc->newspeed? ", newspeed" : "");
414
415 if (sc->newspeed)
416 ess_setmixer(sc, 0x71, 0x22);
417
418 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih);
419 if (!sc->duplex)
420 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
421
422 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
423 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
424 /*highaddr*/BUS_SPACE_MAXADDR,
425 /*filter*/NULL, /*filterarg*/NULL,
426 /*maxsize*/ESS_BUFFSIZE, /*nsegments*/1,
427 /*maxsegz*/0x3ffff,
428 /*flags*/0, &sc->parent_dmat) != 0) {
429 device_printf(dev, "unable to create dma tag\n");
430 goto no;
431 }
432
433 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld",
434 rman_get_start(sc->io_base), rman_get_start(sc->irq),
435 rman_get_start(sc->drq1));
436 if (sc->drq2)
437 snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
438 ":%ld", rman_get_start(sc->drq2));
439
440 if (pcm_register(dev, sc, 1, 1))
441 goto no;
442 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sc);
443 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sc);
444 pcm_setstatus(dev, status);
445
446 return 0;
447
448no:
449 ess_release_resources(sc, dev);
450 return ENXIO;
451}
452
453static int
454ess_detach(device_t dev)
455{
456 int r;
457 struct ess_info *sc;
458
459 r = pcm_unregister(dev);
460 if (r)
461 return r;
462
463 sc = pcm_getdevinfo(dev);
464 ess_release_resources(sc, dev);
465 return 0;
466}
467
468static void
469ess_intr(void *arg)
470{
471 struct ess_info *sc = (struct ess_info *)arg;
472 int src, pirq, rirq;
473
474 src = 0;
475 if (ess_getmixer(sc, 0x7a) & 0x80)
476 src |= 2;
477 if (ess_rd(sc, 0x0c) & 0x01)
478 src |= 1;
479
480 pirq = (src & sc->pch.hwch)? 1 : 0;
481 rirq = (src & sc->rch.hwch)? 1 : 0;
482
483 if (pirq) {
341static void
342ess_intr(void *arg)
343{
344 struct ess_info *sc = (struct ess_info *)arg;
345 int src, pirq, rirq;
346
347 src = 0;
348 if (ess_getmixer(sc, 0x7a) & 0x80)
349 src |= 2;
350 if (ess_rd(sc, 0x0c) & 0x01)
351 src |= 1;
352
353 pirq = (src & sc->pch.hwch)? 1 : 0;
354 rirq = (src & sc->rch.hwch)? 1 : 0;
355
356 if (pirq) {
357 if (!sc->pch.run)
358 printf("ess: play intr while not running\n");
484 if (sc->pch.stopping) {
359 if (sc->pch.stopping) {
360 sc->pch.run = 0;
485 buf_isadma(sc->pch.buffer, PCMTRIG_STOP);
486 sc->pch.stopping = 0;
487 if (sc->pch.hwch == 1)
488 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01);
489 else
490 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x03);
491 }
492 chn_intr(sc->pch.channel);
493 }
494
495 if (rirq) {
361 buf_isadma(sc->pch.buffer, PCMTRIG_STOP);
362 sc->pch.stopping = 0;
363 if (sc->pch.hwch == 1)
364 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01);
365 else
366 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x03);
367 }
368 chn_intr(sc->pch.channel);
369 }
370
371 if (rirq) {
372 if (!sc->rch.run)
373 printf("ess: record intr while not running\n");
496 if (sc->rch.stopping) {
374 if (sc->rch.stopping) {
375 sc->rch.run = 0;
497 buf_isadma(sc->rch.buffer, PCMTRIG_STOP);
498 sc->rch.stopping = 0;
499 /* XXX: will this stop audio2? */
500 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01);
501 }
502 chn_intr(sc->rch.channel);
503 }
504

--- 147 unchanged lines hidden (view full) ---

652 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x04);
653 else
654 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x10);
655 if (play)
656 ess_cmd(sc, DSP_CMD_SPKOFF);
657 return 0;
658}
659
376 buf_isadma(sc->rch.buffer, PCMTRIG_STOP);
377 sc->rch.stopping = 0;
378 /* XXX: will this stop audio2? */
379 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x01);
380 }
381 chn_intr(sc->rch.channel);
382 }
383

--- 147 unchanged lines hidden (view full) ---

531 ess_write(sc, 0xb8, ess_read(sc, 0xb8) & ~0x04);
532 else
533 ess_setmixer(sc, 0x78, ess_getmixer(sc, 0x78) & ~0x10);
534 if (play)
535 ess_cmd(sc, DSP_CMD_SPKOFF);
536 return 0;
537}
538
539/* -------------------------------------------------------------------- */
660/* channel interface for ESS18xx */
661static void *
540/* channel interface for ESS18xx */
541static void *
662esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
542esschan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
663{
664 struct ess_info *sc = devinfo;
665 struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;
666
667 ch->parent = sc;
668 ch->channel = c;
669 ch->buffer = b;
670 ch->buffer->bufsize = ESS_BUFFSIZE;
671 if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1)
672 return NULL;
673 ch->dir = dir;
674 ch->hwch = 1;
675 if ((dir == PCMDIR_PLAY) && (sc->duplex))
676 ch->hwch = 2;
677 ch->buffer->chan = rman_get_start((ch->hwch == 1)? sc->drq1 : sc->drq2);
678 return ch;
679}
680
681static int
543{
544 struct ess_info *sc = devinfo;
545 struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;
546
547 ch->parent = sc;
548 ch->channel = c;
549 ch->buffer = b;
550 ch->buffer->bufsize = ESS_BUFFSIZE;
551 if (chn_allocbuf(ch->buffer, sc->parent_dmat) == -1)
552 return NULL;
553 ch->dir = dir;
554 ch->hwch = 1;
555 if ((dir == PCMDIR_PLAY) && (sc->duplex))
556 ch->hwch = 2;
557 ch->buffer->chan = rman_get_start((ch->hwch == 1)? sc->drq1 : sc->drq2);
558 return ch;
559}
560
561static int
682esschan_setformat(void *data, u_int32_t format)
562esschan_setformat(kobj_t obj, void *data, u_int32_t format)
683{
684 struct ess_chinfo *ch = data;
685
686 ch->fmt = format;
687 return 0;
688}
689
690static int
563{
564 struct ess_chinfo *ch = data;
565
566 ch->fmt = format;
567 return 0;
568}
569
570static int
691esschan_setspeed(void *data, u_int32_t speed)
571esschan_setspeed(kobj_t obj, void *data, u_int32_t speed)
692{
693 struct ess_chinfo *ch = data;
694 struct ess_info *sc = ch->parent;
695
696 ch->spd = speed;
697 if (sc->newspeed)
698 ess_calcspeed9(&ch->spd);
699 else
700 ess_calcspeed8(&ch->spd);
701 return ch->spd;
702}
703
704static int
572{
573 struct ess_chinfo *ch = data;
574 struct ess_info *sc = ch->parent;
575
576 ch->spd = speed;
577 if (sc->newspeed)
578 ess_calcspeed9(&ch->spd);
579 else
580 ess_calcspeed8(&ch->spd);
581 return ch->spd;
582}
583
584static int
705esschan_setblocksize(void *data, u_int32_t blocksize)
585esschan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
706{
707 return blocksize;
708}
709
710static int
586{
587 return blocksize;
588}
589
590static int
711esschan_trigger(void *data, int go)
591esschan_trigger(kobj_t obj, void *data, int go)
712{
713 struct ess_chinfo *ch = data;
714
715 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
716 return 0;
717
718 switch (go) {
719 case PCMTRIG_START:
592{
593 struct ess_chinfo *ch = data;
594
595 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
596 return 0;
597
598 switch (go) {
599 case PCMTRIG_START:
600 ch->run = 1;
720 buf_isadma(ch->buffer, go);
721 ess_start(ch);
722 break;
723
724 case PCMTRIG_STOP:
725 case PCMTRIG_ABORT:
726 default:
727 ess_stop(ch);
728 break;
729 }
730 return 0;
731}
732
733static int
601 buf_isadma(ch->buffer, go);
602 ess_start(ch);
603 break;
604
605 case PCMTRIG_STOP:
606 case PCMTRIG_ABORT:
607 default:
608 ess_stop(ch);
609 break;
610 }
611 return 0;
612}
613
614static int
734esschan_getptr(void *data)
615esschan_getptr(kobj_t obj, void *data)
735{
736 struct ess_chinfo *ch = data;
737
738 return buf_isadmaptr(ch->buffer);
739}
740
741static pcmchan_caps *
616{
617 struct ess_chinfo *ch = data;
618
619 return buf_isadmaptr(ch->buffer);
620}
621
622static pcmchan_caps *
742esschan_getcaps(void *data)
623esschan_getcaps(kobj_t obj, void *data)
743{
744 struct ess_chinfo *ch = data;
745
746 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps;
747}
748
624{
625 struct ess_chinfo *ch = data;
626
627 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps;
628}
629
630static kobj_method_t esschan_methods[] = {
631 KOBJMETHOD(channel_init, esschan_init),
632 KOBJMETHOD(channel_setformat, esschan_setformat),
633 KOBJMETHOD(channel_setspeed, esschan_setspeed),
634 KOBJMETHOD(channel_setblocksize, esschan_setblocksize),
635 KOBJMETHOD(channel_trigger, esschan_trigger),
636 KOBJMETHOD(channel_getptr, esschan_getptr),
637 KOBJMETHOD(channel_getcaps, esschan_getcaps),
638 { 0, 0 }
639};
640CHANNEL_DECLARE(esschan);
641
749/************************************************************/
750
751static int
752essmix_init(snd_mixer *m)
753{
754 struct ess_info *sc = mix_getdevinfo(m);
755
756 mix_setrecdevs(m, SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE |

--- 94 unchanged lines hidden (view full) ---

851 break;
852 }
853
854 ess_setmixer(sc, 0x1c, recdev);
855
856 return src;
857}
858
642/************************************************************/
643
644static int
645essmix_init(snd_mixer *m)
646{
647 struct ess_info *sc = mix_getdevinfo(m);
648
649 mix_setrecdevs(m, SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE |

--- 94 unchanged lines hidden (view full) ---

744 break;
745 }
746
747 ess_setmixer(sc, 0x1c, recdev);
748
749 return src;
750}
751
752static kobj_method_t essmixer_methods[] = {
753 KOBJMETHOD(mixer_init, essmix_init),
754 KOBJMETHOD(mixer_set, essmix_set),
755 KOBJMETHOD(mixer_setrecsrc, essmix_setrecsrc),
756 { 0, 0 }
757};
758MIXER_DECLARE(essmixer);
759
760/************************************************************/
761
859static int
860ess_probe(device_t dev)
861{
862 uintptr_t func, ver, r, f;
863
864 /* The parent device has already been probed. */
865 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
866 if (func != SCF_PCM)

--- 8 unchanged lines hidden (view full) ---

875
876 return 0;
877}
878
879static int
880ess_attach(device_t dev)
881{
882 struct ess_info *sc;
762static int
763ess_probe(device_t dev)
764{
765 uintptr_t func, ver, r, f;
766
767 /* The parent device has already been probed. */
768 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
769 if (func != SCF_PCM)

--- 8 unchanged lines hidden (view full) ---

778
779 return 0;
780}
781
782static int
783ess_attach(device_t dev)
784{
785 struct ess_info *sc;
786 char status[SND_STATUSLEN], buf[64];
787 int ver;
883
884 sc = (struct ess_info *)malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
885 if (!sc)
886 return ENXIO;
887 bzero(sc, sizeof *sc);
888
788
789 sc = (struct ess_info *)malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
790 if (!sc)
791 return ENXIO;
792 bzero(sc, sizeof *sc);
793
889 return ess_doattach(dev, sc);
794 if (ess_alloc_resources(sc, dev))
795 goto no;
796 if (ess_reset_dsp(sc))
797 goto no;
798 if (mixer_init(dev, &essmixer_class, sc))
799 goto no;
800
801 sc->duplex = 0;
802 sc->newspeed = 0;
803 ver = (ess_getmixer(sc, 0x40) << 8) | ess_rd(sc, SB_MIX_DATA);
804 snprintf(buf, sizeof buf, "ESS %x DSP", ver);
805 device_set_desc_copy(dev, buf);
806 if (bootverbose)
807 device_printf(dev, "ESS%x detected", ver);
808
809 switch (ver) {
810 case 0x1869:
811 case 0x1879:
812#ifdef ESS18XX_DUPLEX
813 sc->duplex = sc->drq2? 1 : 0;
814#endif
815#ifdef ESS18XX_NEWSPEED
816 sc->newspeed = 1;
817#endif
818 break;
819 }
820 if (bootverbose)
821 printf("%s%s\n", sc->duplex? ", duplex" : "",
822 sc->newspeed? ", newspeed" : "");
823
824 if (sc->newspeed)
825 ess_setmixer(sc, 0x71, 0x22);
826
827 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih);
828 if (!sc->duplex)
829 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
830
831 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
832 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
833 /*highaddr*/BUS_SPACE_MAXADDR,
834 /*filter*/NULL, /*filterarg*/NULL,
835 /*maxsize*/ESS_BUFFSIZE, /*nsegments*/1,
836 /*maxsegz*/0x3ffff,
837 /*flags*/0, &sc->parent_dmat) != 0) {
838 device_printf(dev, "unable to create dma tag\n");
839 goto no;
840 }
841
842 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld",
843 rman_get_start(sc->io_base), rman_get_start(sc->irq),
844 rman_get_start(sc->drq1));
845 if (sc->drq2)
846 snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
847 ":%ld", rman_get_start(sc->drq2));
848
849 if (pcm_register(dev, sc, 1, 1))
850 goto no;
851 pcm_addchan(dev, PCMDIR_REC, &esschan_class, sc);
852 pcm_addchan(dev, PCMDIR_PLAY, &esschan_class, sc);
853 pcm_setstatus(dev, status);
854
855 return 0;
856
857no:
858 ess_release_resources(sc, dev);
859 return ENXIO;
890}
891
860}
861
862static int
863ess_detach(device_t dev)
864{
865 int r;
866 struct ess_info *sc;
867
868 r = pcm_unregister(dev);
869 if (r)
870 return r;
871
872 sc = pcm_getdevinfo(dev);
873 ess_release_resources(sc, dev);
874 return 0;
875}
876
892static device_method_t ess_methods[] = {
893 /* Device interface */
894 DEVMETHOD(device_probe, ess_probe),
895 DEVMETHOD(device_attach, ess_attach),
896 DEVMETHOD(device_detach, ess_detach),
897
898 { 0, 0 }
899};
900
901static driver_t ess_driver = {
902 "pcm",
903 ess_methods,
904 sizeof(snddev_info),
905};
906
907DRIVER_MODULE(snd_ess, sbc, ess_driver, pcm_devclass, 0, 0);
908MODULE_DEPEND(snd_ess, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
909MODULE_VERSION(snd_ess, 1);
910
877static device_method_t ess_methods[] = {
878 /* Device interface */
879 DEVMETHOD(device_probe, ess_probe),
880 DEVMETHOD(device_attach, ess_attach),
881 DEVMETHOD(device_detach, ess_detach),
882
883 { 0, 0 }
884};
885
886static driver_t ess_driver = {
887 "pcm",
888 ess_methods,
889 sizeof(snddev_info),
890};
891
892DRIVER_MODULE(snd_ess, sbc, ess_driver, pcm_devclass, 0, 0);
893MODULE_DEPEND(snd_ess, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
894MODULE_VERSION(snd_ess, 1);
895
896/************************************************************/
911
912static devclass_t esscontrol_devclass;
913
914static struct isa_pnp_id essc_ids[] = {
915 {0x06007316, "ESS Control"},
916 {0}
917};
918

--- 55 unchanged lines hidden ---
897
898static devclass_t esscontrol_devclass;
899
900static struct isa_pnp_id essc_ids[] = {
901 {0x06007316, "ESS Control"},
902 {0}
903};
904

--- 55 unchanged lines hidden ---