Deleted Added
full compact
sb16.c (54237) sb16.c (54462)
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/sb16.c 54237 1999-12-07 01:53:24Z billf $
31 * $FreeBSD: head/sys/dev/sound/isa/sb16.c 54462 1999-12-12 02:30:19Z cg $
32 */
33
34#include <dev/sound/pcm/sound.h>
35
36#include "sbc.h"
37
38#define __SB_MIXER_C__ /* XXX warning... */
39#include <dev/sound/isa/sb.h>

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

55#endif
56static int esschan_setdir(void *data, int dir);
57static int esschan_setformat(void *data, u_int32_t format);
58static int esschan_setspeed(void *data, u_int32_t speed);
59static int esschan_setblocksize(void *data, u_int32_t blocksize);
60static int esschan_trigger(void *data, int go);
61static int esschan_getptr(void *data);
62static pcmchan_caps *esschan_getcaps(void *data);
32 */
33
34#include <dev/sound/pcm/sound.h>
35
36#include "sbc.h"
37
38#define __SB_MIXER_C__ /* XXX warning... */
39#include <dev/sound/isa/sb.h>

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

55#endif
56static int esschan_setdir(void *data, int dir);
57static int esschan_setformat(void *data, u_int32_t format);
58static int esschan_setspeed(void *data, u_int32_t speed);
59static int esschan_setblocksize(void *data, u_int32_t blocksize);
60static int esschan_trigger(void *data, int go);
61static int esschan_getptr(void *data);
62static pcmchan_caps *esschan_getcaps(void *data);
63
63static pcmchan_caps sb_playcaps = {
64 4000, 22050,
65 AFMT_U8,
66 AFMT_U8
67};
68
69static pcmchan_caps sb_reccaps = {
70 4000, 13000,

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

79};
80
81static pcmchan_caps sbpro_reccaps = {
82 4000, 15000,
83 AFMT_STEREO | AFMT_U8,
84 AFMT_STEREO | AFMT_U8
85};
86
64static pcmchan_caps sb_playcaps = {
65 4000, 22050,
66 AFMT_U8,
67 AFMT_U8
68};
69
70static pcmchan_caps sb_reccaps = {
71 4000, 13000,

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

80};
81
82static pcmchan_caps sbpro_reccaps = {
83 4000, 15000,
84 AFMT_STEREO | AFMT_U8,
85 AFMT_STEREO | AFMT_U8
86};
87
87static pcmchan_caps sb16_playcaps = {
88static pcmchan_caps sb16_hcaps = {
88 5000, 45000,
89 AFMT_STEREO | AFMT_S16_LE,
90 AFMT_STEREO | AFMT_S16_LE
91};
92
89 5000, 45000,
90 AFMT_STEREO | AFMT_S16_LE,
91 AFMT_STEREO | AFMT_S16_LE
92};
93
93static pcmchan_caps sb16_reccaps = {
94static pcmchan_caps sb16_lcaps = {
94 5000, 45000,
95 AFMT_STEREO | AFMT_U8,
96 AFMT_STEREO | AFMT_U8
97};
98
95 5000, 45000,
96 AFMT_STEREO | AFMT_U8,
97 AFMT_STEREO | AFMT_U8
98};
99
100static pcmchan_caps sb16x_caps = {
101 5000, 49000,
102 AFMT_STEREO | AFMT_U8 /* | AFMT_S16_LE */,
103 AFMT_STEREO | AFMT_U8 /* AFMT_S16_LE */
104};
105
99static pcmchan_caps ess_playcaps = {
100 5000, 49000,
101 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
102 AFMT_STEREO | AFMT_S16_LE
103};
104
105static pcmchan_caps ess_reccaps = {
106 5000, 49000,

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

139 snd_dbuf *buffer;
140 int dir;
141 u_int32_t fmt;
142 int ess_dma_started;
143};
144
145struct sb_info {
146 struct resource *io_base; /* I/O address for the board */
106static pcmchan_caps ess_playcaps = {
107 5000, 49000,
108 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
109 AFMT_STEREO | AFMT_S16_LE
110};
111
112static pcmchan_caps ess_reccaps = {
113 5000, 49000,

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

146 snd_dbuf *buffer;
147 int dir;
148 u_int32_t fmt;
149 int ess_dma_started;
150};
151
152struct sb_info {
153 struct resource *io_base; /* I/O address for the board */
147 int io_rid;
148 struct resource *irq;
154 struct resource *irq;
149 int irq_rid;
150 struct resource *drq1; /* play */
151 int drq1_rid;
152 struct resource *drq2; /* rec */
153 int drq2_rid;
155 struct resource *drq1;
156 struct resource *drq2;
154 bus_dma_tag_t parent_dmat;
155
157 bus_dma_tag_t parent_dmat;
158
156 int dma16, dma8;
157 int bd_id;
158 u_long bd_flags; /* board-specific flags */
159 struct sb_chinfo pch, rch;
160};
161
162static int sb_rd(struct sb_info *sb, int reg);
163static void sb_wr(struct sb_info *sb, int reg, u_int8_t val);
164static int sb_dspready(struct sb_info *sb);
165static int sb_cmd(struct sb_info *sb, u_char val);
166static int sb_cmd1(struct sb_info *sb, u_char cmd, int val);
167static int sb_cmd2(struct sb_info *sb, u_char cmd, int val);
168static u_int sb_get_byte(struct sb_info *sb);
159 int bd_id;
160 u_long bd_flags; /* board-specific flags */
161 struct sb_chinfo pch, rch;
162};
163
164static int sb_rd(struct sb_info *sb, int reg);
165static void sb_wr(struct sb_info *sb, int reg, u_int8_t val);
166static int sb_dspready(struct sb_info *sb);
167static int sb_cmd(struct sb_info *sb, u_char val);
168static int sb_cmd1(struct sb_info *sb, u_char cmd, int val);
169static int sb_cmd2(struct sb_info *sb, u_char cmd, int val);
170static u_int sb_get_byte(struct sb_info *sb);
169static int ess_write(struct sb_info *sb, u_char reg, int val);
170static int ess_read(struct sb_info *sb, u_char reg);
171
172/*
173 * in the SB, there is a set of indirect "mixer" registers with
174 * address at offset 4, data at offset 5
175 */
176static void sb_setmixer(struct sb_info *sb, u_int port, u_int value);
177static int sb_getmixer(struct sb_info *sb, u_int port);
171static void sb_setmixer(struct sb_info *sb, u_int port, u_int value);
172static int sb_getmixer(struct sb_info *sb, u_int port);
178
179static void sb_intr(void *arg);
180static void ess_intr(void *arg);
181static int sb_init(device_t dev, struct sb_info *sb);
182static int sb_reset_dsp(struct sb_info *sb);
183
173static int sb_reset_dsp(struct sb_info *sb);
174
175static void sb_intr(void *arg);
184static int sb_format(struct sb_chinfo *ch, u_int32_t format);
185static int sb_speed(struct sb_chinfo *ch, int speed);
186static int sb_start(struct sb_chinfo *ch);
187static int sb_stop(struct sb_chinfo *ch);
188
176static int sb_format(struct sb_chinfo *ch, u_int32_t format);
177static int sb_speed(struct sb_chinfo *ch, int speed);
178static int sb_start(struct sb_chinfo *ch);
179static int sb_stop(struct sb_chinfo *ch);
180
181static int ess_write(struct sb_info *sb, u_char reg, int val);
182static int ess_read(struct sb_info *sb, u_char reg);
183static void ess_intr(void *arg);
189static int ess_format(struct sb_chinfo *ch, u_int32_t format);
190static int ess_speed(struct sb_chinfo *ch, int speed);
191static int ess_start(struct sb_chinfo *ch);
192static int ess_stop(struct sb_chinfo *ch);
193static int ess_abort(struct sb_chinfo *ch);
184static int ess_format(struct sb_chinfo *ch, u_int32_t format);
185static int ess_speed(struct sb_chinfo *ch, int speed);
186static int ess_start(struct sb_chinfo *ch);
187static int ess_stop(struct sb_chinfo *ch);
188static int ess_abort(struct sb_chinfo *ch);
189
194static int sbmix_init(snd_mixer *m);
195static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
196static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
197
198static snd_mixer sb_mixer = {
199 "SoundBlaster mixer",
200 sbmix_init,
201 sbmix_set,

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

372 return 0;
373}
374
375static void
376sb_release_resources(struct sb_info *sb, device_t dev)
377{
378 /* should we bus_teardown_intr here? */
379 if (sb->irq) {
190static int sbmix_init(snd_mixer *m);
191static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
192static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
193
194static snd_mixer sb_mixer = {
195 "SoundBlaster mixer",
196 sbmix_init,
197 sbmix_set,

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

368 return 0;
369}
370
371static void
372sb_release_resources(struct sb_info *sb, device_t dev)
373{
374 /* should we bus_teardown_intr here? */
375 if (sb->irq) {
380 bus_release_resource(dev, SYS_RES_IRQ, sb->irq_rid, sb->irq);
376 bus_release_resource(dev, SYS_RES_IRQ, 0, sb->irq);
381 sb->irq = 0;
382 }
383 if (sb->drq1) {
377 sb->irq = 0;
378 }
379 if (sb->drq1) {
384 bus_release_resource(dev, SYS_RES_DRQ, sb->drq1_rid, sb->drq1);
380 bus_release_resource(dev, SYS_RES_DRQ, 0, sb->drq1);
385 sb->drq1 = 0;
386 }
387 if (sb->drq2) {
381 sb->drq1 = 0;
382 }
383 if (sb->drq2) {
388 bus_release_resource(dev, SYS_RES_DRQ, sb->drq2_rid, sb->drq2);
384 bus_release_resource(dev, SYS_RES_DRQ, 1, sb->drq2);
389 sb->drq2 = 0;
390 }
391 if (sb->io_base) {
385 sb->drq2 = 0;
386 }
387 if (sb->io_base) {
392 bus_release_resource(dev, SYS_RES_IOPORT, sb->io_rid,
393 sb->io_base);
388 bus_release_resource(dev, SYS_RES_IOPORT, 0, sb->io_base);
394 sb->io_base = 0;
395 }
396 free(sb, M_DEVBUF);
397}
398
399static int
400sb_alloc_resources(struct sb_info *sb, device_t dev)
401{
389 sb->io_base = 0;
390 }
391 free(sb, M_DEVBUF);
392}
393
394static int
395sb_alloc_resources(struct sb_info *sb, device_t dev)
396{
397 int rid;
398
399 rid = 0;
402 if (!sb->io_base)
403 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
400 if (!sb->io_base)
401 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
404 &sb->io_rid, 0, ~0, 1,
402 &rid, 0, ~0, 1,
405 RF_ACTIVE);
403 RF_ACTIVE);
404 rid = 0;
406 if (!sb->irq)
407 sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
405 if (!sb->irq)
406 sb->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
408 &sb->irq_rid, 0, ~0, 1,
407 &rid, 0, ~0, 1,
409 RF_ACTIVE);
408 RF_ACTIVE);
409 rid = 0;
410 if (!sb->drq1)
411 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
410 if (!sb->drq1)
411 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
412 &sb->drq1_rid, 0, ~0, 1,
412 &rid, 0, ~0, 1,
413 RF_ACTIVE);
413 RF_ACTIVE);
414 if (!sb->drq2 && sb->drq2_rid > 0)
414 rid = 1;
415 if (!sb->drq2)
415 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
416 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
416 &sb->drq2_rid, 0, ~0, 1,
417 &rid, 0, ~0, 1,
417 RF_ACTIVE);
418
419 if (sb->io_base && sb->drq1 && sb->irq) {
418 RF_ACTIVE);
419
420 if (sb->io_base && sb->drq1 && sb->irq) {
420 sb->dma8 = rman_get_start(sb->drq1);
421 isa_dma_acquire(sb->dma8);
422 isa_dmainit(sb->dma8, DSP_BUFFSIZE);
421 isa_dma_acquire(rman_get_start(sb->drq1));
422 isa_dmainit(rman_get_start(sb->drq1), DSP_BUFFSIZE);
423
424 if (sb->drq2) {
423
424 if (sb->drq2) {
425 sb->dma16 = rman_get_start(sb->drq2);
426 isa_dma_acquire(sb->dma16);
427 isa_dmainit(sb->dma16, DSP_BUFFSIZE);
428 } else sb->dma16 = sb->dma8;
429
430 if (sb->dma8 > sb->dma16) {
431 int tmp = sb->dma16;
432 sb->dma16 = sb->dma8;
433 sb->dma8 = tmp;
425 isa_dma_acquire(rman_get_start(sb->drq2));
426 isa_dmainit(rman_get_start(sb->drq2), DSP_BUFFSIZE);
434 }
427 }
428
435 return 0;
436 } else return ENXIO;
437}
438
429 return 0;
430 } else return ENXIO;
431}
432
439static int
440sb_identify_board(device_t dev, struct sb_info *sb)
433static void
434sb16_swap(void *v, int dir)
441{
435{
442 char *fmt = NULL;
443 static char buf[64];
444 int essver = 0;
436 struct sb_info *sb = v;
437 int pb = sb->pch.buffer->dl;
438 int rb = sb->rch.buffer->dl;
439 int pc = sb->pch.buffer->chan;
440 int rc = sb->rch.buffer->chan;
441 int swp = 0;
445
442
446 sb_cmd(sb, DSP_CMD_GETVER); /* Get version */
447 sb->bd_id = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
443 if (!pb && !rb) {
444 if (dir == PCMDIR_PLAY && pc < 4) swp = 1;
445 else if (dir == PCMDIR_REC && rc < 4) swp = 1;
446 if (sb->bd_flags & BD_F_SB16X) swp = !swp;
447 if (swp) {
448 int t;
448
449
449 switch (sb->bd_id >> 8) {
450 case 1: /* old sound blaster has nothing... */
451 case 2:
452 fmt = "SoundBlaster %d.%d" ; /* default */
453 break;
454
455 case 3:
456 fmt = "SoundBlaster Pro %d.%d";
457 if (sb->bd_id == 0x301) {
458 int rev;
459
460 /* Try to detect ESS chips. */
461 sb_cmd(sb, DSP_CMD_GETID); /* Return ident. bytes. */
462 essver = (sb_get_byte(sb) << 8) | sb_get_byte(sb);
463 rev = essver & 0x000f;
464 essver &= 0xfff0;
465 if (essver == 0x4880) {
466 /* the ESS488 can be treated as an SBPRO */
467 fmt = "SoundBlaster Pro (ESS488 rev %d)";
468 } else if (essver == 0x6880) {
469 if (rev < 8) fmt = "ESS688 rev %d";
470 else fmt = "ESS1868 rev %d";
471 sb->bd_flags |= BD_F_ESS;
472 } else return ENXIO;
473 sb->bd_id &= 0xff00;
474 sb->bd_id |= ((essver & 0xf000) >> 8) | rev;
450 t = sb->pch.buffer->chan;
451 sb->pch.buffer->chan = sb->rch.buffer->chan;
452 sb->rch.buffer->chan = t;
453 sb->pch.buffer->dir = B_WRITE;
454 sb->rch.buffer->dir = B_READ;
475 }
455 }
476 break;
477
478 case 4:
479 sb->bd_flags |= BD_F_SB16;
480 if (sb->bd_flags & BD_F_SB16X) fmt = "SB16 ViBRA16X %d.%d";
481 else fmt = "SoundBlaster 16 %d.%d";
482 break;
483
484 default:
485 device_printf(dev, "failed to get SB version (%x)\n",
486 sb->bd_id);
487 return ENXIO;
488 }
489 if (essver) snprintf(buf, sizeof buf, fmt, sb->bd_id & 0x000f);
490 else snprintf(buf, sizeof buf, fmt, sb->bd_id >> 8, sb->bd_id & 0xff);
491 device_set_desc_copy(dev, buf);
492 return sb_reset_dsp(sb);
456 }
493}
494
495static int
457}
458
459static int
496sb_init(device_t dev, struct sb_info *sb)
497{
498 int x, irq;
499
500 sb->bd_flags &= ~BD_F_MIX_MASK;
501 /* do various initializations depending on board id. */
502 switch (sb->bd_id >> 8) {
503 case 1: /* old sound blaster has nothing... */
504 break;
505
506 case 2:
507 sb->bd_flags |= BD_F_DUP_MIDI;
508 if (sb->bd_id > 0x200) sb->bd_flags |= BD_F_MIX_CT1335;
509 break;
510
511 case 3:
512 sb->bd_flags |= BD_F_DUP_MIDI | BD_F_MIX_CT1345;
513 break;
514
515 case 4:
516 sb->bd_flags |= BD_F_SB16 | BD_F_MIX_CT1745;
517 if (sb->dma16 != sb->dma8) sb->bd_flags |= BD_F_DUPLEX;
518
519 /* soft irq/dma configuration */
520 x = -1;
521 irq = rman_get_start(sb->irq);
522 if (irq == 5) x = 2;
523 else if (irq == 7) x = 4;
524 else if (irq == 9) x = 1;
525 else if (irq == 10) x = 8;
526 if (x == -1) device_printf(dev,
527 "bad irq %d (5/7/9/10 valid)\n",
528 irq);
529 else sb_setmixer(sb, IRQ_NR, x);
530 sb_setmixer(sb, DMA_NR, (1 << sb->dma16) | (1 << sb->dma8));
531 break;
532 }
533 return 0;
534}
535
536static int
537sb_probe(device_t dev)
538{
539 snddev_info *d = device_get_softc(dev);
540 struct sb_info *sb;
541 int allocated, i;
542 int error;
543
544 if (isa_get_vendorid(dev)) return ENXIO; /* not yet */
545
546 device_set_desc(dev, "SoundBlaster");
547 bzero(d, sizeof *d);
548 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
549 if (!sb) return ENXIO;
550 bzero(sb, sizeof *sb);
551
552 allocated = 0;
553 sb->io_rid = 0;
554 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
555 0, ~0, 16, RF_ACTIVE);
556 if (!sb->io_base) {
557 BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
558 allocated = 1;
559 sb->io_rid = 0;
560 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
561 &sb->io_rid, 0x220, 0x22f,
562 16, RF_ACTIVE);
563 if (!sb->io_base) {
564 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
565 &sb->io_rid, 0x240,
566 0x24f, 16, RF_ACTIVE);
567 }
568 }
569 if (!sb->io_base) return ENXIO;
570
571 error = sb_reset_dsp(sb);
572 if (error) goto no;
573 error = sb_identify_board(dev, sb);
574 if (error) goto no;
575no:
576 i = sb->io_rid;
577 sb_release_resources(sb, dev);
578 if (allocated) bus_delete_resource(dev, SYS_RES_IOPORT, i);
579 return error;
580}
581
582static int
583sb_doattach(device_t dev, struct sb_info *sb)
584{
585 snddev_info *d = device_get_softc(dev);
586 void *ih;
460sb_doattach(device_t dev, struct sb_info *sb)
461{
462 snddev_info *d = device_get_softc(dev);
463 void *ih;
587 int error;
588 char status[SND_STATUSLEN];
589
464 char status[SND_STATUSLEN];
465
590 sb->irq_rid = 0;
591 sb->drq1_rid = 0;
592 sb->drq2_rid = 1;
593 if (sb_alloc_resources(sb, dev)) goto no;
466 if (sb_alloc_resources(sb, dev)) goto no;
594 error = sb_reset_dsp(sb);
595 if (error) goto no;
596 error = sb_identify_board(dev, sb);
597 if (error) goto no;
598
599 sb_init(dev, sb);
467 if (sb_reset_dsp(sb)) goto no;
600 mixer_init(d, &sb_mixer, sb);
468 mixer_init(d, &sb_mixer, sb);
469
601 if (sb->bd_flags & BD_F_ESS)
602 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih);
603 else
604 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
470 if (sb->bd_flags & BD_F_ESS)
471 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih);
472 else
473 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
605
606 if (sb->bd_flags & BD_F_SB16)
607 pcm_setflags(dev, pcm_getflags(dev) | SD_F_EVILSB16);
608 if (sb->dma16 == sb->dma8)
474 if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
475 pcm_setswap(dev, sb16_swap);
476 if (!sb->drq2)
609 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
477 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
478
610 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
611 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
612 /*highaddr*/BUS_SPACE_MAXADDR,
613 /*filter*/NULL, /*filterarg*/NULL,
614 /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1,
615 /*maxsegz*/0x3ffff,
616 /*flags*/0, &sb->parent_dmat) != 0) {
617 device_printf(dev, "unable to create dma tag\n");
618 goto no;
619 }
620
479 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
480 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
481 /*highaddr*/BUS_SPACE_MAXADDR,
482 /*filter*/NULL, /*filterarg*/NULL,
483 /*maxsize*/DSP_BUFFSIZE, /*nsegments*/1,
484 /*maxsegz*/0x3ffff,
485 /*flags*/0, &sb->parent_dmat) != 0) {
486 device_printf(dev, "unable to create dma tag\n");
487 goto no;
488 }
489
621 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %d",
490 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld",
622 rman_get_start(sb->io_base), rman_get_start(sb->irq),
491 rman_get_start(sb->io_base), rman_get_start(sb->irq),
623 sb->dma8);
624 if (sb->dma16 != sb->dma8) snprintf(status + strlen(status),
625 SND_STATUSLEN - strlen(status), ":%d", sb->dma16);
492 rman_get_start(sb->drq1));
493 if (sb->drq2) snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
494 ":%ld", rman_get_start(sb->drq2));
626
627 if (pcm_register(dev, sb, 1, 1)) goto no;
628 if (sb->bd_flags & BD_F_ESS) {
629 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sb);
630 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sb);
631 } else {
632 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb);
633 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb);
634 }
635 pcm_setstatus(dev, status);
636
637 return 0;
638
639no:
640 sb_release_resources(sb, dev);
641 return ENXIO;
642}
643
495
496 if (pcm_register(dev, sb, 1, 1)) goto no;
497 if (sb->bd_flags & BD_F_ESS) {
498 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sb);
499 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sb);
500 } else {
501 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb);
502 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb);
503 }
504 pcm_setstatus(dev, status);
505
506 return 0;
507
508no:
509 sb_release_resources(sb, dev);
510 return ENXIO;
511}
512
644static int
645sb_attach(device_t dev)
646{
647 struct sb_info *sb;
648 int flags = device_get_flags(dev);
649
650 if (flags & DV_F_DUAL_DMA) {
651 bus_set_resource(dev, SYS_RES_DRQ, 1,
652 flags & DV_F_DRQ_MASK, 1);
653 }
654 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
655 if (!sb) return ENXIO;
656 bzero(sb, sizeof *sb);
657
658 /* XXX in probe should set io resource to right val instead of this */
659 sb->io_rid = 0;
660 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT, &sb->io_rid,
661 0, ~0, 16, RF_ACTIVE);
662 if (!sb->io_base) {
663 BVDDB(printf("sb_probe: no addr, trying (0x220, 0x240)\n"));
664 sb->io_rid = 0;
665 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
666 &sb->io_rid, 0x220, 0x22f,
667 16, RF_ACTIVE);
668 if (!sb->io_base) {
669 sb->io_base = bus_alloc_resource(dev, SYS_RES_IOPORT,
670 &sb->io_rid, 0x240,
671 0x24f, 16, RF_ACTIVE);
672 }
673 }
674 if (!sb->io_base) return ENXIO;
675
676 return sb_doattach(dev, sb);
677}
678
679static device_method_t sb_methods[] = {
680 /* Device interface */
681 DEVMETHOD(device_probe, sb_probe),
682 DEVMETHOD(device_attach, sb_attach),
683
684 { 0, 0 }
685};
686
687static driver_t sb_driver = {
688 "pcm",
689 sb_methods,
690 sizeof(snddev_info),
691};
692
693DRIVER_MODULE(sb, isa, sb_driver, pcm_devclass, 0, 0);
694
695static void
696sb_intr(void *arg)
697{
698 struct sb_info *sb = (struct sb_info *)arg;
699 int reason = 3, c;
700
701 /*
702 * SB < 4.0 is half duplex and has only 1 bit for int source,

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

824static int
825sb_start(struct sb_chinfo *ch)
826{
827 struct sb_info *sb = ch->parent;
828 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
829 int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0;
830 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
831 int l = ch->buffer->dl;
513static void
514sb_intr(void *arg)
515{
516 struct sb_info *sb = (struct sb_info *)arg;
517 int reason = 3, c;
518
519 /*
520 * SB < 4.0 is half duplex and has only 1 bit for int source,

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

642static int
643sb_start(struct sb_chinfo *ch)
644{
645 struct sb_info *sb = ch->parent;
646 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
647 int b16 = (ch->fmt & AFMT_S16_LE)? 1 : 0;
648 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
649 int l = ch->buffer->dl;
650 int dh = ch->buffer->chan > 3;
832 u_char i1, i2 = 0;
833
834 if (b16) l >>= 1;
835 l--;
836 if (play) sb_cmd(sb, DSP_CMD_SPKON);
837 if (sb->bd_flags & BD_F_SB16) {
838 i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON |
839 (play? DSP_F16_DAC : DSP_F16_ADC);
651 u_char i1, i2 = 0;
652
653 if (b16) l >>= 1;
654 l--;
655 if (play) sb_cmd(sb, DSP_CMD_SPKON);
656 if (sb->bd_flags & BD_F_SB16) {
657 i1 = DSP_F16_AUTO | DSP_F16_FIFO_ON |
658 (play? DSP_F16_DAC : DSP_F16_ADC);
840 i1 |= (b16 && (sb->bd_flags & BD_F_DUPLEX))? DSP_DMA16 : DSP_DMA8;
659 i1 |= (b16 || dh)? DSP_DMA16 : DSP_DMA8;
841 i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0);
842 sb_cmd(sb, i1);
843 sb_cmd2(sb, i2, l);
844 } else {
845 if (sb->bd_flags & BD_F_HISPEED) i1 = play? 0x90 : 0x98;
846 else i1 = play? 0x1c : 0x2c;
847 sb_setmixer(sb, 0x0e, stereo? 2 : 0);
848 /* an ESS extension -- they can do 16 bits */

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

994 struct sb_info *sb = devinfo;
995 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch;
996
997 ch->parent = sb;
998 ch->channel = c;
999 ch->buffer = b;
1000 ch->buffer->bufsize = DSP_BUFFSIZE;
1001 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL;
660 i2 = (stereo? DSP_F16_STEREO : 0) | (b16? DSP_F16_SIGNED : 0);
661 sb_cmd(sb, i1);
662 sb_cmd2(sb, i2, l);
663 } else {
664 if (sb->bd_flags & BD_F_HISPEED) i1 = play? 0x90 : 0x98;
665 else i1 = play? 0x1c : 0x2c;
666 sb_setmixer(sb, 0x0e, stereo? 2 : 0);
667 /* an ESS extension -- they can do 16 bits */

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

813 struct sb_info *sb = devinfo;
814 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch;
815
816 ch->parent = sb;
817 ch->channel = c;
818 ch->buffer = b;
819 ch->buffer->bufsize = DSP_BUFFSIZE;
820 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1) return NULL;
1002 ch->buffer->chan = (dir == PCMDIR_PLAY)? sb->dma16 : sb->dma8;
821 ch->buffer->chan = (dir == PCMDIR_PLAY)? rman_get_start(sb->drq2)
822 : rman_get_start(sb->drq1);
1003 return ch;
1004}
1005
1006static int
1007sbchan_setdir(void *data, int dir)
1008{
1009 struct sb_chinfo *ch = data;
1010 ch->dir = dir;

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

1048 return buf_isadmaptr(ch->buffer);
1049}
1050
1051static pcmchan_caps *
1052sbchan_getcaps(void *data)
1053{
1054 struct sb_chinfo *ch = data;
1055 int p = (ch->dir == PCMDIR_PLAY)? 1 : 0;
823 return ch;
824}
825
826static int
827sbchan_setdir(void *data, int dir)
828{
829 struct sb_chinfo *ch = data;
830 ch->dir = dir;

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

868 return buf_isadmaptr(ch->buffer);
869}
870
871static pcmchan_caps *
872sbchan_getcaps(void *data)
873{
874 struct sb_chinfo *ch = data;
875 int p = (ch->dir == PCMDIR_PLAY)? 1 : 0;
1056 if (ch->parent->bd_id <= 0x200)
876 if (ch->parent->bd_id < 0x300)
1057 return p? &sb_playcaps : &sb_reccaps;
877 return p? &sb_playcaps : &sb_reccaps;
1058 else if (ch->parent->bd_id >= 0x400)
1059 return p? &sb16_playcaps : &sb16_reccaps;
1060 else
878 else if (ch->parent->bd_id < 0x400)
1061 return p? &sbpro_playcaps : &sbpro_reccaps;
879 return p? &sbpro_playcaps : &sbpro_reccaps;
880 else if (ch->parent->bd_flags & BD_F_SB16X)
881 return &sb16x_caps;
882 else
883 return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps;
1062}
1063/* channel interface for ESS18xx */
1064#ifdef notyet
1065static void *
1066esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
1067{
1068 /* the same as sbchan_init()? */
1069}

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

1248 */
1249 sb_setmixer(sb, SB16_OMASK, 0x1f & ~1);
1250 break;
1251 }
1252 return src;
1253}
1254
1255static int
884}
885/* channel interface for ESS18xx */
886#ifdef notyet
887static void *
888esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
889{
890 /* the same as sbchan_init()? */
891}

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

1070 */
1071 sb_setmixer(sb, SB16_OMASK, 0x1f & ~1);
1072 break;
1073 }
1074 return src;
1075}
1076
1077static int
1256sbpnp_probe(device_t dev)
1257{
1258 char *s = NULL;
1259 u_int32_t logical_id = isa_get_logicalid(dev);
1260
1261 switch(logical_id) {
1262 case 0x01000000: /* @@@0001 */
1263 s = "Avance Asound 100";
1264 break;
1265
1266 case 0x01100000: /* @@@1001 */
1267 s = "Avance Asound 110";
1268 break;
1269
1270 case 0x01200000: /* @@@2001 */
1271 s = "Avance Logic ALS120";
1272 break;
1273
1274 case 0x68187316: /* ESS1868 */
1275 s = "ESS1868";
1276 break;
1277
1278 case 0x69187316: /* ESS1869 */
1279 case 0xacb0110e: /* Compaq's Presario 1621 ESS1869 */
1280 s = "ESS1869";
1281 break;
1282
1283 case 0x79187316: /* ESS1879 */
1284 s = "ESS1879";
1285 break;
1286
1287 case 0x88187316: /* ESS1888 */
1288 s = "ESS1888";
1289 break;
1290 }
1291 if (s) {
1292 device_set_desc(dev, s);
1293 return (0);
1294 }
1295 return ENXIO;
1296}
1297
1298static int
1299sbpnp_attach(device_t dev)
1300{
1301 struct sb_info *sb;
1302 u_int32_t vend_id = isa_get_vendorid(dev);
1303
1304 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
1305 if (!sb) return ENXIO;
1306 bzero(sb, sizeof *sb);
1307
1308 switch(vend_id) {
1309 case 0xf0008c0e:
1310 case 0x10019305:
1311 case 0x20019305:
1312 /* XXX add here the vend_id for other vibra16X cards... */
1313 sb->bd_flags = BD_F_SB16X;
1314 }
1315 return sb_doattach(dev, sb);
1316}
1317
1318static device_method_t sbpnp_methods[] = {
1319 /* Device interface */
1320 DEVMETHOD(device_probe, sbpnp_probe),
1321 DEVMETHOD(device_attach, sbpnp_attach),
1322
1323 { 0, 0 }
1324};
1325
1326static driver_t sbpnp_driver = {
1327 "pcm",
1328 sbpnp_methods,
1329 sizeof(snddev_info),
1330};
1331
1332DRIVER_MODULE(sbpnp, isa, sbpnp_driver, pcm_devclass, 0, 0);
1333
1334#if NSBC > 0
1335#define DESCSTR " PCM Audio"
1336static int
1337sbsbc_probe(device_t dev)
1338{
1078sbsbc_probe(device_t dev)
1079{
1339 char *s = NULL;
1340 struct sndcard_func *func;
1080 char buf[64];
1081 u_int32_t func, ver, r;
1341
1342 /* The parent device has already been probed. */
1082
1083 /* The parent device has already been probed. */
1343
1344 func = device_get_ivars(dev);
1345 if (func == NULL || func->func != SCF_PCM)
1084 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
1085 if (func != SCF_PCM)
1346 return (ENXIO);
1347
1086 return (ENXIO);
1087
1348 s = "SB PCM Audio";
1088 r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
1089 ver &= 0x0000ffff;
1090 snprintf(buf, sizeof buf, "SB DSP %d.%02d", ver >> 8, ver & 0xff);
1091 device_set_desc_copy(dev, buf);
1349
1092
1350 device_set_desc(dev, s);
1351 return 0;
1352}
1353
1354static int
1355sbsbc_attach(device_t dev)
1356{
1357 struct sb_info *sb;
1093 return 0;
1094}
1095
1096static int
1097sbsbc_attach(device_t dev)
1098{
1099 struct sb_info *sb;
1358 u_int32_t vend_id;
1359 device_t sbc;
1100 u_int32_t ver;
1360
1101
1361 sbc = device_get_parent(dev);
1362 vend_id = isa_get_vendorid(sbc);
1363 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
1364 if (!sb) return ENXIO;
1365 bzero(sb, sizeof *sb);
1366
1102 sb = (struct sb_info *)malloc(sizeof *sb, M_DEVBUF, M_NOWAIT);
1103 if (!sb) return ENXIO;
1104 bzero(sb, sizeof *sb);
1105
1367 switch(vend_id) {
1368 case 0xf0008c0e:
1369 case 0x10019305:
1370 case 0x20019305:
1371 /* XXX add here the vend_id for other vibra16X cards... */
1372 sb->bd_flags = BD_F_SB16X;
1373 }
1106 BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
1107 sb->bd_id = ver & 0x0000ffff;
1108 sb->bd_flags = (ver & 0xffff0000) >> 16;
1109
1374 return sb_doattach(dev, sb);
1375}
1376
1377static device_method_t sbsbc_methods[] = {
1378 /* Device interface */
1379 DEVMETHOD(device_probe, sbsbc_probe),
1380 DEVMETHOD(device_attach, sbsbc_attach),
1381
1382 { 0, 0 }
1383};
1384
1385static driver_t sbsbc_driver = {
1386 "pcm",
1387 sbsbc_methods,
1388 sizeof(snddev_info),
1389};
1390
1391DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0);
1392
1110 return sb_doattach(dev, sb);
1111}
1112
1113static device_method_t sbsbc_methods[] = {
1114 /* Device interface */
1115 DEVMETHOD(device_probe, sbsbc_probe),
1116 DEVMETHOD(device_attach, sbsbc_attach),
1117
1118 { 0, 0 }
1119};
1120
1121static driver_t sbsbc_driver = {
1122 "pcm",
1123 sbsbc_methods,
1124 sizeof(snddev_info),
1125};
1126
1127DRIVER_MODULE(sbsbc, sbc, sbsbc_driver, pcm_devclass, 0, 0);
1128
1393#endif /* NSBC > 0 */
1129
1130