Deleted Added
full compact
sb8.c (57973) sb8.c (58756)
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/sb8.c 57973 2000-03-13 10:19:32Z phk $
31 * $FreeBSD: head/sys/dev/sound/isa/sb8.c 58756 2000-03-28 18:31:01Z 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>
40#include <dev/sound/chip.h>
41
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>
40#include <dev/sound/chip.h>
41
42#define ESS_BUFFSIZE (65536 - 256)
43#define PLAIN_SB16(x) ((((x)->bd_flags) & (BD_F_SB16|BD_F_SB16X)) == BD_F_SB16)
44
45/* channel interface */
46static void *sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
47static int sbchan_setdir(void *data, int dir);
48static int sbchan_setformat(void *data, u_int32_t format);
49static int sbchan_setspeed(void *data, u_int32_t speed);
50static int sbchan_setblocksize(void *data, u_int32_t blocksize);
51static int sbchan_trigger(void *data, int go);
52static int sbchan_getptr(void *data);
53static pcmchan_caps *sbchan_getcaps(void *data);
54
42#define PLAIN_SB16(x) ((((x)->bd_flags) & (BD_F_SB16|BD_F_SB16X)) == BD_F_SB16)
43
44/* channel interface */
45static void *sbchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
46static int sbchan_setdir(void *data, int dir);
47static int sbchan_setformat(void *data, u_int32_t format);
48static int sbchan_setspeed(void *data, u_int32_t speed);
49static int sbchan_setblocksize(void *data, u_int32_t blocksize);
50static int sbchan_trigger(void *data, int go);
51static int sbchan_getptr(void *data);
52static pcmchan_caps *sbchan_getcaps(void *data);
53
55/* channel interface for ESS */
56static void *esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
57static int esschan_setdir(void *data, int dir);
58static int esschan_setformat(void *data, u_int32_t format);
59static int esschan_setspeed(void *data, u_int32_t speed);
60static int esschan_setblocksize(void *data, u_int32_t blocksize);
61static int esschan_trigger(void *data, int go);
62static int esschan_getptr(void *data);
63static pcmchan_caps *esschan_getcaps(void *data);
64
65static pcmchan_caps sb_playcaps = {
66 4000, 22050,
67 AFMT_U8,
68 AFMT_U8
69};
70
71static pcmchan_caps sb_reccaps = {
72 4000, 13000,

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

99};
100
101static pcmchan_caps sb16x_caps = {
102 5000, 49000,
103 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
104 AFMT_STEREO | AFMT_S16_LE
105};
106
54static pcmchan_caps sb_playcaps = {
55 4000, 22050,
56 AFMT_U8,
57 AFMT_U8
58};
59
60static pcmchan_caps sb_reccaps = {
61 4000, 13000,

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

88};
89
90static pcmchan_caps sb16x_caps = {
91 5000, 49000,
92 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
93 AFMT_STEREO | AFMT_S16_LE
94};
95
107static pcmchan_caps ess_playcaps = {
108 5000, 49000,
109 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
110 AFMT_STEREO | AFMT_S16_LE
111};
112
113static pcmchan_caps ess_reccaps = {
114 5000, 49000,
115 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
116 AFMT_STEREO | AFMT_S16_LE
117};
118
119static pcm_channel sb_chantemplate = {
120 sbchan_init,
121 sbchan_setdir,
122 sbchan_setformat,
123 sbchan_setspeed,
124 sbchan_setblocksize,
125 sbchan_trigger,
126 sbchan_getptr,
127 sbchan_getcaps,
128};
129
96static pcm_channel sb_chantemplate = {
97 sbchan_init,
98 sbchan_setdir,
99 sbchan_setformat,
100 sbchan_setspeed,
101 sbchan_setblocksize,
102 sbchan_trigger,
103 sbchan_getptr,
104 sbchan_getcaps,
105};
106
130static pcm_channel ess_chantemplate = {
131 esschan_init,
132 esschan_setdir,
133 esschan_setformat,
134 esschan_setspeed,
135 esschan_setblocksize,
136 esschan_trigger,
137 esschan_getptr,
138 esschan_getcaps,
139};
140
141struct sb_info;
142
143struct sb_chinfo {
144 struct sb_info *parent;
145 pcm_channel *channel;
146 snd_dbuf *buffer;
147 int dir;
148 u_int32_t fmt, spd;
107struct sb_info;
108
109struct sb_chinfo {
110 struct sb_info *parent;
111 pcm_channel *channel;
112 snd_dbuf *buffer;
113 int dir;
114 u_int32_t fmt, spd;
149 int ess_dma_started;
150};
151
152struct sb_info {
153 struct resource *io_base; /* I/O address for the board */
154 struct resource *irq;
155 struct resource *drq1;
156 struct resource *drq2;
157 bus_dma_tag_t parent_dmat;

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

172static int sb_getmixer(struct sb_info *sb, u_int port);
173static int sb_reset_dsp(struct sb_info *sb);
174
175static void sb_intr(void *arg);
176static int sb_speed(struct sb_chinfo *ch);
177static int sb_start(struct sb_chinfo *ch);
178static int sb_stop(struct sb_chinfo *ch);
179
115};
116
117struct sb_info {
118 struct resource *io_base; /* I/O address for the board */
119 struct resource *irq;
120 struct resource *drq1;
121 struct resource *drq2;
122 bus_dma_tag_t parent_dmat;

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

137static int sb_getmixer(struct sb_info *sb, u_int port);
138static int sb_reset_dsp(struct sb_info *sb);
139
140static void sb_intr(void *arg);
141static int sb_speed(struct sb_chinfo *ch);
142static int sb_start(struct sb_chinfo *ch);
143static int sb_stop(struct sb_chinfo *ch);
144
180static int ess_write(struct sb_info *sb, u_char reg, int val);
181static int ess_read(struct sb_info *sb, u_char reg);
182static void ess_intr(void *arg);
183static int ess_format(struct sb_chinfo *ch, u_int32_t format);
184static int ess_speed(struct sb_chinfo *ch, int speed);
185static int ess_start(struct sb_chinfo *ch);
186static int ess_stop(struct sb_chinfo *ch);
187static int ess_abort(struct sb_chinfo *ch);
188
189static int sbmix_init(snd_mixer *m);
190static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
191static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
192
193static snd_mixer sb_mixer = {
194 "SoundBlaster mixer",
195 sbmix_init,
196 sbmix_set,

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

336 return sb_rd(sb, DSP_READ);
337 else
338 DELAY(20);
339 }
340 return 0xffff;
341}
342
343static int
145static int sbmix_init(snd_mixer *m);
146static int sbmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right);
147static int sbmix_setrecsrc(snd_mixer *m, u_int32_t src);
148
149static snd_mixer sb_mixer = {
150 "SoundBlaster mixer",
151 sbmix_init,
152 sbmix_set,

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

292 return sb_rd(sb, DSP_READ);
293 else
294 DELAY(20);
295 }
296 return 0xffff;
297}
298
299static int
344ess_write(struct sb_info *sb, u_char reg, int val)
345{
346 return sb_cmd1(sb, reg, val);
347}
348
349static int
350ess_read(struct sb_info *sb, u_char reg)
351{
352 return (sb_cmd(sb, 0xc0) && sb_cmd(sb, reg))? sb_get_byte(sb) : 0xffff;
353}
354
355static int
356sb_reset_dsp(struct sb_info *sb)
357{
358 sb_wr(sb, SBDSP_RST, 3);
359 DELAY(100);
360 sb_wr(sb, SBDSP_RST, 0);
361 if (sb_get_byte(sb) != 0xAA) {
362 DEB(printf("sb_reset_dsp 0x%lx failed\n",
363 rman_get_start(d->io_base)));

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

407 &rid, 0, ~0, 1,
408 RF_ACTIVE);
409 rid = 0;
410 if (!sb->drq1)
411 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
412 &rid, 0, ~0, 1,
413 RF_ACTIVE);
414 rid = 1;
300sb_reset_dsp(struct sb_info *sb)
301{
302 sb_wr(sb, SBDSP_RST, 3);
303 DELAY(100);
304 sb_wr(sb, SBDSP_RST, 0);
305 if (sb_get_byte(sb) != 0xAA) {
306 DEB(printf("sb_reset_dsp 0x%lx failed\n",
307 rman_get_start(d->io_base)));

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

351 &rid, 0, ~0, 1,
352 RF_ACTIVE);
353 rid = 0;
354 if (!sb->drq1)
355 sb->drq1 = bus_alloc_resource(dev, SYS_RES_DRQ,
356 &rid, 0, ~0, 1,
357 RF_ACTIVE);
358 rid = 1;
415 if (!sb->drq2 && !(sb->bd_flags & BD_F_ESS))
359 if (!sb->drq2)
416 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
417 &rid, 0, ~0, 1,
418 RF_ACTIVE);
419
420 if (sb->io_base && sb->drq1 && sb->irq) {
360 sb->drq2 = bus_alloc_resource(dev, SYS_RES_DRQ,
361 &rid, 0, ~0, 1,
362 RF_ACTIVE);
363
364 if (sb->io_base && sb->drq1 && sb->irq) {
421 int bs = (sb->bd_flags & BD_F_ESS)? ESS_BUFFSIZE : DSP_BUFFSIZE;
365 int bs = DSP_BUFFSIZE;
422
423 isa_dma_acquire(rman_get_start(sb->drq1));
424 isa_dmainit(rman_get_start(sb->drq1), bs);
425
426 if (sb->drq2) {
427 isa_dma_acquire(rman_get_start(sb->drq2));
428 isa_dmainit(rman_get_start(sb->drq2), bs);
429 }

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

443 int swp = 0;
444
445 if (!pb && !rb) {
446 if (dir == PCMDIR_PLAY && pc < 4)
447 swp = 1;
448 else
449 if (dir == PCMDIR_REC && rc < 4)
450 swp = 1;
366
367 isa_dma_acquire(rman_get_start(sb->drq1));
368 isa_dmainit(rman_get_start(sb->drq1), bs);
369
370 if (sb->drq2) {
371 isa_dma_acquire(rman_get_start(sb->drq2));
372 isa_dmainit(rman_get_start(sb->drq2), bs);
373 }

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

387 int swp = 0;
388
389 if (!pb && !rb) {
390 if (dir == PCMDIR_PLAY && pc < 4)
391 swp = 1;
392 else
393 if (dir == PCMDIR_REC && rc < 4)
394 swp = 1;
451 if (sb->bd_flags & BD_F_SB16X)
452 swp = !swp;
453 if (swp) {
395 if (swp) {
454 int t;
455
456 t = sb->pch.buffer->chan;
457 sb->pch.buffer->chan = sb->rch.buffer->chan;
458 sb->rch.buffer->chan = t;
459 sb->pch.buffer->dir = ISADMA_WRITE;
460 sb->rch.buffer->dir = ISADMA_READ;
461 }
462 }
463}
464
465static int
466sb_doattach(device_t dev, struct sb_info *sb)
467{
468 snddev_info *d = device_get_softc(dev);
469 void *ih;
470 char status[SND_STATUSLEN];
396 int t;
397
398 t = sb->pch.buffer->chan;
399 sb->pch.buffer->chan = sb->rch.buffer->chan;
400 sb->rch.buffer->chan = t;
401 sb->pch.buffer->dir = ISADMA_WRITE;
402 sb->rch.buffer->dir = ISADMA_READ;
403 }
404 }
405}
406
407static int
408sb_doattach(device_t dev, struct sb_info *sb)
409{
410 snddev_info *d = device_get_softc(dev);
411 void *ih;
412 char status[SND_STATUSLEN];
471 int bs = (sb->bd_flags & BD_F_ESS)? ESS_BUFFSIZE : DSP_BUFFSIZE;
413 int bs = DSP_BUFFSIZE;
472
473 if (sb_alloc_resources(sb, dev))
474 goto no;
475 if (sb_reset_dsp(sb))
476 goto no;
477 mixer_init(d, &sb_mixer, sb);
478
414
415 if (sb_alloc_resources(sb, dev))
416 goto no;
417 if (sb_reset_dsp(sb))
418 goto no;
419 mixer_init(d, &sb_mixer, sb);
420
479 if (sb->bd_flags & BD_F_ESS)
480 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, ess_intr, sb, &ih);
481 else
482 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
421 bus_setup_intr(dev, sb->irq, INTR_TYPE_TTY, sb_intr, sb, &ih);
483 if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
484 pcm_setswap(dev, sb16_swap);
485 if (!sb->drq2)
486 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
487
488 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
489 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
490 /*highaddr*/BUS_SPACE_MAXADDR,

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

500 rman_get_start(sb->io_base), rman_get_start(sb->irq),
501 rman_get_start(sb->drq1));
502 if (sb->drq2)
503 snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
504 ":%ld", rman_get_start(sb->drq2));
505
506 if (pcm_register(dev, sb, 1, 1))
507 goto no;
422 if ((sb->bd_flags & BD_F_SB16) && !(sb->bd_flags & BD_F_SB16X))
423 pcm_setswap(dev, sb16_swap);
424 if (!sb->drq2)
425 pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
426
427 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
428 /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
429 /*highaddr*/BUS_SPACE_MAXADDR,

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

439 rman_get_start(sb->io_base), rman_get_start(sb->irq),
440 rman_get_start(sb->drq1));
441 if (sb->drq2)
442 snprintf(status + strlen(status), SND_STATUSLEN - strlen(status),
443 ":%ld", rman_get_start(sb->drq2));
444
445 if (pcm_register(dev, sb, 1, 1))
446 goto no;
508 if (sb->bd_flags & BD_F_ESS) {
509 pcm_addchan(dev, PCMDIR_REC, &ess_chantemplate, sb);
510 pcm_addchan(dev, PCMDIR_PLAY, &ess_chantemplate, sb);
511 } else {
512 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb);
513 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb);
514 }
447 pcm_addchan(dev, PCMDIR_REC, &sb_chantemplate, sb);
448 pcm_addchan(dev, PCMDIR_PLAY, &sb_chantemplate, sb);
515 pcm_setstatus(dev, status);
516
517 return 0;
518
519no:
520 sb_release_resources(sb, dev);
521 return ENXIO;
522}

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

561 if ((reason & 2) && (sb->rch.buffer->dl > 0))
562 chn_intr(sb->rch.channel);
563 if (c & 1)
564 sb_rd(sb, DSP_DATA_AVAIL); /* 8-bit int ack */
565 if (c & 2)
566 sb_rd(sb, DSP_DATA_AVL16); /* 16-bit int ack */
567}
568
449 pcm_setstatus(dev, status);
450
451 return 0;
452
453no:
454 sb_release_resources(sb, dev);
455 return ENXIO;
456}

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

495 if ((reason & 2) && (sb->rch.buffer->dl > 0))
496 chn_intr(sb->rch.channel);
497 if (c & 1)
498 sb_rd(sb, DSP_DATA_AVAIL); /* 8-bit int ack */
499 if (c & 2)
500 sb_rd(sb, DSP_DATA_AVL16); /* 16-bit int ack */
501}
502
569static void
570ess_intr(void *arg)
571{
572 struct sb_info *sb = (struct sb_info *)arg;
573
574 sb_rd(sb, DSP_DATA_AVAIL); /* int ack */
575#ifdef notyet
576 /*
577 * XXX
578 * for full-duplex mode:
579 * should read port 0x6 to identify where interrupt came from.
580 */
581#endif
582 /*
583 * We are transferring data in DSP normal mode,
584 * so clear the dl to indicate the DMA is stopped.
585 */
586 if (sb->pch.buffer->dl > 0)
587 chn_intr(sb->pch.channel);
588 if (sb->rch.buffer->dl > 0)
589 chn_intr(sb->rch.channel);
590}
591
592static int
593sb_speed(struct sb_chinfo *ch)
594{
595 struct sb_info *sb = ch->parent;
596 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
597 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
598 int speed = ch->spd;
599

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

808 else if (ch->parent->bd_id < 0x400)
809 return p? &sbpro_playcaps : &sbpro_reccaps;
810 else if (ch->parent->bd_flags & BD_F_SB16X)
811 return &sb16x_caps;
812 else
813 return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps;
814}
815
503static int
504sb_speed(struct sb_chinfo *ch)
505{
506 struct sb_info *sb = ch->parent;
507 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
508 int stereo = (ch->fmt & AFMT_STEREO)? 1 : 0;
509 int speed = ch->spd;
510

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

719 else if (ch->parent->bd_id < 0x400)
720 return p? &sbpro_playcaps : &sbpro_reccaps;
721 else if (ch->parent->bd_flags & BD_F_SB16X)
722 return &sb16x_caps;
723 else
724 return (ch->buffer->chan >= 4)? &sb16_hcaps : &sb16_lcaps;
725}
726
816/* utility functions for ESS */
817static int
818ess_format(struct sb_chinfo *ch, u_int32_t format)
819{
820 struct sb_info *sb = ch->parent;
821 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
822 int b16 = (format & AFMT_S16_LE)? 1 : 0;
823 int stereo = (format & AFMT_STEREO)? 1 : 0;
824 u_char c;
825
826 ch->fmt = format;
827 sb_reset_dsp(sb);
828 /* auto-init DMA mode */
829 ess_write(sb, 0xb8, play ? 0x04 : 0x0e);
830 /* mono/stereo */
831 c = (ess_read(sb, 0xa8) & ~0x03) | 1;
832 if (!stereo)
833 c++;
834 ess_write(sb, 0xa8, c);
835 /* demand mode, 4 bytes/xfer */
836 ess_write(sb, 0xb9, 2);
837 /* setup dac/adc */
838 if (play)
839 ess_write(sb, 0xb6, b16? 0x00 : 0x80);
840 ess_write(sb, 0xb7, 0x51 | (b16? 0x20 : 0x00));
841 ess_write(sb, 0xb7, 0x98 + (b16? 0x24 : 0x00) + (stereo? 0x00 : 0x38));
842 /* irq/drq control */
843 ess_write(sb, 0xb1, (ess_read(sb, 0xb1) & 0x0f) | 0x50);
844 ess_write(sb, 0xb2, (ess_read(sb, 0xb2) & 0x0f) | 0x50);
845 return 0;
846}
847
848static int
849ess_speed(struct sb_chinfo *ch, int speed)
850{
851 struct sb_info *sb = ch->parent;
852 int t;
853
854 RANGE (speed, 5000, 49000);
855 if (speed > 22000) {
856 t = (795500 + speed / 2) / speed;
857 speed = (795500 + t / 2) / t;
858 t = (256 - t ) | 0x80;
859 } else {
860 t = (397700 + speed / 2) / speed;
861 speed = (397700 + t / 2) / t;
862 t = 128 - t;
863 }
864 ess_write(sb, 0xa1, t); /* set time constant */
865#if 0
866 d->play_speed = d->rec_speed = speed;
867 speed = (speed * 9 ) / 20;
868#endif
869 t = 256 - 7160000 / ((speed * 9 / 20) * 82);
870 ess_write(sb, 0xa2, t);
871 return speed;
872}
873
874static int
875ess_start(struct sb_chinfo *ch)
876{
877 struct sb_info *sb = ch->parent;
878 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
879 short c = - ch->buffer->dl;
880 u_char c1;
881
882 /*
883 * clear bit 0 of register B8h
884 */
885#if 1
886 c1 = play ? 0x04 : 0x0e;
887 ess_write(sb, 0xb8, c1++);
888#else
889 c1 = ess_read(sb, 0xb8) & 0xfe;
890 ess_write(sb, 0xb8, c1++);
891#endif
892 /*
893 * update ESS Transfer Count Register
894 */
895 ess_write(sb, 0xa4, (u_char)((u_short)c & 0xff));
896 ess_write(sb, 0xa5, (u_char)(((u_short)c >> 8) & 0xff));
897 /*
898 * set bit 0 of register B8h
899 */
900 ess_write(sb, 0xb8, c1);
901 if (play)
902 sb_cmd(sb, DSP_CMD_SPKON);
903 return 0;
904}
905
906static int
907ess_stop(struct sb_chinfo *ch)
908{
909 struct sb_info *sb = ch->parent;
910 /*
911 * no need to send a stop command if the DMA has already stopped.
912 */
913 if (ch->buffer->dl > 0) {
914 sb_cmd(sb, DSP_CMD_DMAPAUSE_8); /* pause dma. */
915 }
916 return 0;
917}
918
919static int
920ess_abort(struct sb_chinfo *ch)
921{
922 struct sb_info *sb = ch->parent;
923 int play = (ch->dir == PCMDIR_PLAY)? 1 : 0;
924
925 if (play)
926 sb_cmd(sb, DSP_CMD_SPKOFF); /* speaker off */
927 sb_reset_dsp(sb);
928 ess_format(ch, ch->fmt);
929 ess_speed(ch, ch->channel->speed);
930 return 0;
931}
932
933/* channel interface for ESS18xx */
934static void *
935esschan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
936{
937 struct sb_info *sb = devinfo;
938 struct sb_chinfo *ch = (dir == PCMDIR_PLAY)? &sb->pch : &sb->rch;
939
940 ch->parent = sb;
941 ch->channel = c;
942 ch->buffer = b;
943 ch->buffer->bufsize = ESS_BUFFSIZE;
944 if (chn_allocbuf(ch->buffer, sb->parent_dmat) == -1)
945 return NULL;
946 ch->buffer->chan = rman_get_start(sb->drq1);
947 return ch;
948}
949
950static int
951esschan_setdir(void *data, int dir)
952{
953 struct sb_chinfo *ch = data;
954
955 ch->dir = dir;
956 return 0;
957}
958
959static int
960esschan_setformat(void *data, u_int32_t format)
961{
962 struct sb_chinfo *ch = data;
963
964 ess_format(ch, format);
965 return 0;
966}
967
968static int
969esschan_setspeed(void *data, u_int32_t speed)
970{
971 struct sb_chinfo *ch = data;
972
973 return ess_speed(ch, speed);
974}
975
976static int
977esschan_setblocksize(void *data, u_int32_t blocksize)
978{
979 return blocksize;
980}
981
982static int
983esschan_trigger(void *data, int go)
984{
985 struct sb_chinfo *ch = data;
986
987 if (go == PCMTRIG_EMLDMAWR)
988 return 0;
989 switch (go) {
990 case PCMTRIG_START:
991 if (!ch->ess_dma_started)
992 buf_isadma(ch->buffer, go);
993 ch->ess_dma_started = 1;
994 ess_start(ch);
995 break;
996 case PCMTRIG_STOP:
997 if (ch->buffer->dl >= 0) {
998 buf_isadma(ch->buffer, go);
999 ch->ess_dma_started = 0;
1000 ess_stop(ch);
1001 }
1002 break;
1003 case PCMTRIG_ABORT:
1004 default:
1005 ch->ess_dma_started = 0;
1006 ess_abort(ch);
1007 buf_isadma(ch->buffer, go);
1008 break;
1009 }
1010 return 0;
1011}
1012
1013static int
1014esschan_getptr(void *data)
1015{
1016 struct sb_chinfo *ch = data;
1017
1018 return buf_isadmaptr(ch->buffer);
1019}
1020
1021static pcmchan_caps *
1022esschan_getcaps(void *data)
1023{
1024 struct sb_chinfo *ch = data;
1025
1026 return (ch->dir == PCMDIR_PLAY)? &ess_playcaps : &ess_reccaps;
1027}
1028
1029/************************************************************/
1030
1031static int
1032sbmix_init(snd_mixer *m)
1033{
1034 struct sb_info *sb = mix_getdevinfo(m);
1035
1036 switch (sb->bd_flags & BD_F_MIX_MASK) {
1037 case BD_F_MIX_CT1345: /* SB 3.0 has 1345 mixer */
1038 mix_setdevs(m, SBPRO_MIXER_DEVICES);
1039 mix_setrecdevs(m, SBPRO_RECORDING_DEVICES);
1040 sb_setmixer(sb, 0, 1); /* reset mixer */
727/************************************************************/
728
729static int
730sbmix_init(snd_mixer *m)
731{
732 struct sb_info *sb = mix_getdevinfo(m);
733
734 switch (sb->bd_flags & BD_F_MIX_MASK) {
735 case BD_F_MIX_CT1345: /* SB 3.0 has 1345 mixer */
736 mix_setdevs(m, SBPRO_MIXER_DEVICES);
737 mix_setrecdevs(m, SBPRO_RECORDING_DEVICES);
738 sb_setmixer(sb, 0, 1); /* reset mixer */
1041 if (!(sb->bd_flags & BD_F_ESS))
1042 sb_setmixer(sb, MIC_VOL, 0x6); /* mic volume max */
739 sb_setmixer(sb, MIC_VOL, 0x6); /* mic volume max */
1043 sb_setmixer(sb, RECORD_SRC, 0x0); /* mic source */
1044 sb_setmixer(sb, FM_VOL, 0x0); /* no midi */
1045 break;
1046
1047 case BD_F_MIX_CT1745: /* SB16 mixer ... */
1048 mix_setdevs(m, SB16_MIXER_DEVICES);
1049 mix_setrecdevs(m, SB16_RECORDING_DEVICES);
1050 sb_setmixer(sb, 0x3c, 0x1f); /* make all output active */

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

1059{
1060 struct sb_info *sb = mix_getdevinfo(m);
1061 int regoffs;
1062 u_char val;
1063 mixer_tab *iomap;
1064
1065 switch (sb->bd_flags & BD_F_MIX_MASK) {
1066 case BD_F_MIX_CT1345:
740 sb_setmixer(sb, RECORD_SRC, 0x0); /* mic source */
741 sb_setmixer(sb, FM_VOL, 0x0); /* no midi */
742 break;
743
744 case BD_F_MIX_CT1745: /* SB16 mixer ... */
745 mix_setdevs(m, SB16_MIXER_DEVICES);
746 mix_setrecdevs(m, SB16_RECORDING_DEVICES);
747 sb_setmixer(sb, 0x3c, 0x1f); /* make all output active */

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

756{
757 struct sb_info *sb = mix_getdevinfo(m);
758 int regoffs;
759 u_char val;
760 mixer_tab *iomap;
761
762 switch (sb->bd_flags & BD_F_MIX_MASK) {
763 case BD_F_MIX_CT1345:
1067 if (sb->bd_flags & BD_F_ESS)
1068 iomap = &ess_mix;
1069 else
1070 iomap = &sbpro_mix;
764 iomap = &sbpro_mix;
1071 break;
1072
1073 case BD_F_MIX_CT1745:
1074 iomap = &sb16_mix;
1075 break;
1076
1077 default:
1078 return -1;

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

1153 /* The parent device has already been probed. */
1154 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
1155 if (func != SCF_PCM)
1156 return (ENXIO);
1157
1158 r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
1159 f = (ver & 0xffff0000) >> 16;
1160 ver &= 0x0000ffff;
765 break;
766
767 case BD_F_MIX_CT1745:
768 iomap = &sb16_mix;
769 break;
770
771 default:
772 return -1;

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

847 /* The parent device has already been probed. */
848 r = BUS_READ_IVAR(device_get_parent(dev), dev, 0, &func);
849 if (func != SCF_PCM)
850 return (ENXIO);
851
852 r = BUS_READ_IVAR(device_get_parent(dev), dev, 1, &ver);
853 f = (ver & 0xffff0000) >> 16;
854 ver &= 0x0000ffff;
1161 snprintf(buf, sizeof buf, "SB DSP %d.%02d%s%s", (int) ver >> 8, (int) ver & 0xff,
1162 (f & BD_F_ESS)? " (ESS mode)" : "",
855 if (f & BD_F_ESS)
856 return (ENXIO);
857
858 snprintf(buf, sizeof buf, "SB DSP %d.%02d%s", (int) ver >> 8, (int) ver & 0xff,
1163 (f & BD_F_SB16X)? " (ViBRA16X)" : "");
1164 device_set_desc_copy(dev, buf);
1165
1166 return 0;
1167}
1168
1169static int
1170sbsbc_attach(device_t dev)

--- 34 unchanged lines hidden ---
859 (f & BD_F_SB16X)? " (ViBRA16X)" : "");
860 device_set_desc_copy(dev, buf);
861
862 return 0;
863}
864
865static int
866sbsbc_attach(device_t dev)

--- 34 unchanged lines hidden ---