sb16.c revision 31361
1/*
2 * sound/sb_dsp.c
3 *
4 * driver for the SoundBlaster and clones.
5 *
6 * Copyright 1997 Luigi Rizzo.
7 *
8 * Derived from files in the Voxware 3.5 distribution,
9 * Copyright by Hannu Savolainen 1994, under the same copyright
10 * conditions.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in
19 *    the documentation and/or other materials provided with the
20 *    distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
29 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36
37/*
38 * use this as a template file for board-specific drivers.
39 * The next two lines (and the final #endif) are in all drivers:
40 */
41
42#include <i386/isa/snd/sound.h>
43#if NPCM > 0
44
45/*
46 * Begin with the board-specific include files...
47 */
48
49#define __SB_MIXER_C__	/* XXX warning... */
50#include  <i386/isa/snd/sbcard.h>
51
52/*
53 * then prototypes of functions which go in the snddev_info
54 * (usually static, unless they are shared by other modules)...
55 */
56
57static	int sb_probe(struct isa_device *dev);
58static	int sb_attach(struct isa_device *dev);
59
60static	d_open_t	sb_dsp_open;
61static	d_close_t	sb_dsp_close;
62static	d_ioctl_t	sb_dsp_ioctl;
63static	irq_proc_t	sbintr;
64static	snd_callback_t	sb_callback;
65
66/*
67 * and prototypes for other private functions defined in this module.
68 */
69
70static	void sb_dsp_init(snddev_info *d, struct isa_device *dev);
71static	void sb_mix_init(snddev_info *d);
72static int sb_mixer_set(snddev_info *d, int dev, int value);
73static int dsp_speed(snddev_info *d);
74static void sb_mixer_reset(snddev_info *d);
75
76u_int sb_get_byte(int io_base);
77
78/*
79 * Then put here the descriptors for the various boards supported
80 * by this module, properly initialized.
81 */
82
83snddev_info sb_op_desc = {
84    "basic soundblaster",
85
86    SNDCARD_SB,
87    sb_probe,
88    sb_attach,
89
90    sb_dsp_open,
91    sb_dsp_close /* sb_close */,
92    NULL /* use generic sndread */,
93    NULL /* use generic sndwrite */,
94    sb_dsp_ioctl,
95    sndpoll,
96
97    sbintr,
98    sb_callback,
99
100    DSP_BUFFSIZE,	/* bufsize */
101
102    AFMT_STEREO | AFMT_U8,		/* audio format */
103
104} ;
105
106/*
107 * Then the file continues with the body of all functions
108 * directly referenced in the descriptor.
109 */
110
111/*
112 * the probe routine for the SoundBlaster only consists in
113 * resetting the dsp and testing if it is there.
114 * Version detection etc. will be done at attach time.
115 *
116 * Remember, ISA probe routines are supposed to return the
117 * size of io space used.
118 */
119
120static int
121sb_probe(struct isa_device *dev)
122{
123    bzero(&pcm_info[dev->id_unit], sizeof(pcm_info[dev->id_unit]) );
124    if (dev->id_iobase == -1) {
125	dev->id_iobase = 0x220;
126	printf("sb_probe: no address supplied, try defaults (0x220,0x240)\n");
127        if (snd_conflict(dev->id_iobase))
128	    dev->id_iobase = 0x240;
129    }
130    if (snd_conflict(dev->id_iobase))
131	return 0 ;
132
133    if (sb_reset_dsp(dev->id_iobase))
134	return 16 ; /* the SB uses 16 registers... */
135    else
136	return 0;
137}
138
139static int
140sb_attach(struct isa_device *dev)
141{
142    snddev_info *d = &pcm_info[dev->id_unit] ;
143
144    dev->id_alive = 16 ; /* number of io ports */
145    /* should be already set but just in case... */
146    sb_dsp_init(d, dev);
147    return 0 ;
148}
149
150/*
151 * here are the main routines from the switches.
152 */
153
154static int
155sb_dsp_open(dev_t dev, int flags, int mode, struct proc * p)
156{
157    snddev_info *d;
158    int unit ;
159
160    dev = minor(dev);
161    unit = dev >> 4 ;
162    d = &pcm_info[unit] ;
163
164    DEB(printf("<%s>%d : open\n", d->name, unit));
165
166    if (d->flags & SND_F_BUSY) {
167	printf("<%s>%d open: device busy\n", d->name, unit);
168	return EBUSY ;
169    }
170
171    d->wsel.si_pid = 0;
172    d->wsel.si_flags = 0;
173
174    d->rsel.si_pid = 0;
175    d->rsel.si_flags = 0;
176
177    d->dbuf_out.total = d->dbuf_out.prev_total = 0 ;
178    d->dbuf_in.total = d->dbuf_in.prev_total = 0 ;
179
180    d->flags = 0 ;
181    d->bd_flags &= ~BD_F_HISPEED ;
182
183    switch ( dev & 0xf ) {
184    case SND_DEV_DSP16 :
185	if ((d->audio_fmt & AFMT_S16_LE) == 0) {
186	    printf("sorry, 16-bit not supported on SB %d.%02d\n",
187		(d->bd_id >>8) & 0xff, d->bd_id & 0xff);
188	    return ENXIO;
189	}
190	d->play_fmt = d->rec_fmt = AFMT_S16_LE ;
191	break;
192    case SND_DEV_AUDIO :
193	d->play_fmt = d->rec_fmt = AFMT_MU_LAW ;
194	break ;
195    case SND_DEV_DSP :
196	d->play_fmt = d->rec_fmt = AFMT_U8 ;
197	break ;
198    }
199
200    d->flags |= SND_F_BUSY ;
201    d->play_speed = d->rec_speed = DSP_DEFAULT_SPEED ;
202
203    if (flags & O_NONBLOCK)
204	d->flags |= SND_F_NBIO ;
205
206    sb_reset_dsp(d->io_base);
207    ask_init(d);
208
209    return 0;
210}
211
212static int
213sb_dsp_close(dev_t dev, int flags, int mode, struct proc * p)
214{
215    int unit;
216    snddev_info *d;
217    u_long s;
218
219    dev = minor(dev);
220    unit = dev >> 4 ;
221    d = &pcm_info[unit] ;
222
223    s = spltty();
224    d->flags |= SND_F_CLOSING ;
225    splx(s);
226    snd_flush(d);
227
228    sb_cmd(d->io_base, DSP_CMD_SPKOFF ); /* XXX useless ? */
229
230    d->flags = 0 ;
231    return 0 ;
232}
233
234static int
235sb_dsp_ioctl(dev_t dev, int cmd, caddr_t arg, int mode, struct proc * p)
236{
237    int unit;
238    snddev_info *d;
239
240    dev = minor(dev);
241    unit = dev >> 4 ;
242    d = &pcm_info[unit] ;
243
244    /*
245     * handle mixer calls first. Reads are in the default handler,
246     * so do not bother about them.
247     */
248    if ( (cmd & MIXER_WRITE(0)) == MIXER_WRITE(0) )
249	return sb_mixer_set(d, cmd & 0xff, *(int *)arg) ;
250
251    /*
252     * for the remaining functions, use the default handler.
253     */
254
255    return ENOSYS ;
256}
257
258static void
259sbintr(int unit)
260{
261    snddev_info *d = &pcm_info[unit];
262    int reason = 3, c=1, io_base = d->io_base;
263
264    DEB(printf("got sbintr for unit %d, flags 0x%08lx\n", unit, d->flags));
265
266    /*
267     * SB < 4.0 is half duplex and has only 1 bit for int source,
268     * so we fake it. SB 4.x (SB16) has the int source in a separate
269     * register.
270     */
271again:
272    if (d->bd_flags & BD_F_SB16) {
273	c = sb_getmixer(io_base, IRQ_STAT);
274	/* this tells us if the source is 8-bit or 16-bit dma. We
275	 * have to check the io channel to map it to read or write...
276	 */
277	reason = 0 ;
278	if ( c & 1 ) { /* 8-bit dma */
279	    if (d->dbuf_out.chan < 4)
280		reason |= 1;
281	    if (d->dbuf_in.chan < 4)
282		reason |= 2;
283	}
284	if ( c & 2 ) { /* 16-bit dma */
285	    if (d->dbuf_out.chan >= 4)
286		reason |= 1;
287	    if (d->dbuf_in.chan >= 4)
288		reason |= 2;
289	}
290    }
291    /* XXX previous location of ack... */
292    DEB(printf("sbintr, flags 0x%08lx reason %d\n", d->flags, reason));
293    if ( reason & 1 ) { /* possibly a write interrupt */
294	if ( d->dbuf_out.dl )
295	dsp_wrintr(d);
296	else {
297	    if (d->bd_flags & BD_F_SB16)
298	       printf("WARNING: wrintr but write DMA inactive!\n");
299	}
300    }
301    if ( reason & 2 ) {
302	if ( d->dbuf_in.dl )
303	dsp_rdintr(d);
304	else {
305	    if (d->bd_flags & BD_F_SB16)
306	       printf("WARNING: rdintr but read DMA inactive!\n");
307	}
308    }
309    if ( c & 2 )
310	inb(DSP_DATA_AVL16); /* 16-bit int ack */
311    if (c & 1)
312	inb(DSP_DATA_AVAIL);	/* 8-bit int ack */
313
314    /*
315     * the sb16 might have multiple sources etc.
316     */
317    if (d->bd_flags & BD_F_SB16 && (c & 3) )
318	goto again;
319}
320
321/*
322 * device-specific function called back from the dma module.
323 * The reason of the callback is the second argument.
324 * NOTE: during operations, some ioctl can be called to change
325 * settings (e.g. speed, channels, format), and the default
326 * ioctl handler will just record the change and set the
327 * flag SND_F_INIT. The callback routine is in charge of applying
328 * the changes at the next convenient time (typically, at the
329 * start of operations). For full duplex devices, in some cases the
330 * init requires both channels to be idle.
331 */
332static int
333sb_callback(snddev_info *d, int reason)
334{
335    int rd = reason & SND_CB_RD ;
336    snd_dbuf *b = (rd) ? & (d->dbuf_in) : & (d->dbuf_out) ;
337    int l = b->dl ;
338
339    switch (reason & SND_CB_REASON_MASK) {
340    case SND_CB_INIT : /* called with int enabled and no pending io */
341	dsp_speed(d);
342	snd_set_blocksize(d);
343	if (d->play_fmt & AFMT_MU_LAW)
344	    d->flags |= SND_F_XLAT8 ;
345	else
346	    d->flags &= ~SND_F_XLAT8 ;
347	reset_dbuf(& (d->dbuf_in), SND_CHAN_RD );
348	reset_dbuf(& (d->dbuf_out), SND_CHAN_WR );
349	return 1;
350	break;
351
352    case SND_CB_START : /* called with int disabled */
353	if (d->bd_flags & BD_F_SB16) {
354	    u_char c, c1 ;
355
356	    /* the SB16 can do full duplex using one 16-bit channel
357	     * and one 8-bit channel. It needs to be programmed to
358	     * use split format though.
359	     * We use the following algorithm:
360	     * 1. check which direction(s) are active;
361	     * 2. check if we should swap dma channels
362	     * 3. check if we can do the swap.
363	     */
364	    int swap = 1 ; /* default... */
365
366	    if (rd) {
367		/* need not to swap if channel is already correct */
368		if ( d->rec_fmt == AFMT_S16_LE && b->chan > 4 )
369		    swap = 0;
370		if ( d->rec_fmt != AFMT_S16_LE && b->chan < 4 )
371		    swap = 0;
372		if (swap && (d->flags & SND_F_WRITING || d->dbuf_out.dl)) {
373		    /* cannot swap if writing is already active */
374		    DDB(printf("sorry, DMA channel unavailable\n"));
375		    swap = 0;
376		    break; /* XXX should return an error */
377		}
378	    } else {
379		/* need not to swap if channel is already correct */
380		if ( d->play_fmt == AFMT_S16_LE && b->chan > 4 )
381		    swap = 0;
382		if ( d->play_fmt != AFMT_S16_LE && b->chan < 4 )
383		    swap = 0;
384		if (swap && ( d->flags & SND_F_READING || d->dbuf_in.dl)) {
385		    /* cannot swap if reading is already active */
386		    DDB(printf("sorry, DMA channel unavailable\n"));
387		    swap = 0;
388		    break ; /* XXX should return an error */
389		}
390	    }
391
392	    if (swap) {
393	        int c = d->dbuf_in.chan ;
394		d->dbuf_in.chan = d->dbuf_out.chan;
395		d->dbuf_out.chan = c ;
396		reset_dbuf(& (d->dbuf_in), SND_CHAN_RD );
397		reset_dbuf(& (d->dbuf_out), SND_CHAN_WR );
398		DEB(printf("START dma chan: play %d, rec %d\n",
399		    d->dbuf_out.chan, d->dbuf_in.chan));
400	}
401
402	    /*
403	     * XXX note: c1 and l should be set basing on d->rec_fmt,
404	     * but there is no choice once a 16 or 8-bit channel
405	     * is assigned. This means that if the application
406	     * tries to use a bad format, the sound will not be nice.
407	     */
408	    if ( b->chan > 4 ) {
409		c = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_DMA16 ;
410		c1 = DSP_F16_SIGNED ;
411		    l /= 2 ;
412	    } else {
413		c = DSP_F16_AUTO | DSP_F16_FIFO_ON | DSP_DMA8 ;
414		c1 = 0 ;
415	    }
416	    c |=  (rd) ? DSP_F16_ADC : DSP_F16_DAC ;
417	    if (d->flags & SND_F_STEREO)
418		c1 |= DSP_F16_STEREO ;
419
420	    sb_cmd(d->io_base, c );
421	    sb_cmd3(d->io_base, c1 , l - 1) ;
422	} else if (d->bd_flags & BD_F_ESS) {
423	    /* XXX this code is still incomplete */
424	    sb_cmd2(d->io_base, 0xb8, rd ? 0x0e : 0x04 ); /* auto dma */
425	    sb_cmd2(d->io_base, 0xa8, 2  /* chans */ );
426	    sb_cmd2(d->io_base, 0xb9, 2); /* demand mode */
427	    /*
428	     input: 0xb8 -> 0x0e ;
429		    0xa8 -> channels
430		    0xb9 -> 2
431		    mono,U8: 51, d0
432		    mono,S16 71, f4
433		    st, U8   51, 98
434		    st, S16  71, bc
435	     */
436	} else { /* SBPro */
437	    u_char c ;
438	    if (!rd)
439		sb_cmd(d->io_base, DSP_CMD_SPKON);
440	    /* code for the SB2 and SB3 */
441	    if (d->bd_flags & BD_F_HISPEED)
442		c = (rd) ? DSP_CMD_HSADC_AUTO : DSP_CMD_HSDAC_AUTO ;
443	    else
444		c = (rd) ? DSP_CMD_ADC8_AUTO : DSP_CMD_DAC8_AUTO ;
445	    sb_cmd3(d->io_base, c , l - 1) ;
446	}
447	break;
448
449    case SND_CB_ABORT : /* XXX */
450    case SND_CB_STOP :
451	{
452	    int cmd = DSP_CMD_DMAPAUSE_8 ; /* default: halt 8 bit chan */
453	    if ( d->bd_flags & BD_F_SB16 && b->chan > 4 )
454		    cmd = DSP_CMD_DMAPAUSE_16 ;
455	    if (d->bd_flags & BD_F_HISPEED) {
456		sb_reset_dsp(d->io_base);
457		d->flags |= SND_F_INIT ;
458	    } else {
459		sb_cmd(d->io_base, cmd); /* pause dma. */
460	       /*
461		* The above seems to have the undocumented side effect of
462		* blocking the other side as well. If the other
463		* channel was active (SB16) I have to re-enable it :(
464		*/
465		if ( (rd && d->dbuf_out.dl) ||
466		     (!rd && d->dbuf_in.dl) )
467		    sb_cmd(d->io_base, cmd == DSP_CMD_DMAPAUSE_8 ?
468			0xd6 : 0xd4); /* continue other dma */
469	    }
470	}
471	DEB( sb_cmd(d->io_base, DSP_CMD_SPKOFF) ); /* speaker off */
472	break ;
473
474    }
475    return 0 ;
476}
477
478/*
479 * The second part of the file contains all functions specific to
480 * the board and (usually) not exported to other modules.
481 */
482
483int
484sb_reset_dsp(int io_base)
485{
486    int loopc;
487
488    outb(DSP_RESET, 1);
489    DELAY(100);
490    outb(DSP_RESET, 0);
491    for (loopc = 0; loopc<100 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++)
492	DELAY(30);
493
494    if (inb(DSP_READ) != 0xAA) {
495        DEB(printf("sb_reset_dsp 0x%x failed\n", io_base));
496	return 0;	/* Sorry */
497    }
498    return 1;
499}
500
501/*
502 * only used in sb_attach from here.
503 */
504
505static void
506sb_dsp_init(snddev_info *d, struct isa_device *dev)
507{
508    int i, x;
509    char *fmt = NULL ;
510    int	io_base = dev->id_iobase ;
511
512    d->bd_id = 0 ;
513
514    sb_reset_dsp(io_base);
515    sb_cmd(io_base, DSP_CMD_GETVER);	/* Get version */
516
517    for (i = 10000; i; i--) { /* perhaps wait longer on a fast machine ? */
518	if (inb(DSP_DATA_AVAIL) & 0x80) { /* wait for Data Ready */
519	    if ( (d->bd_id & 0xff00) == 0)
520		d->bd_id = inb(DSP_READ) << 8; /* major */
521	    else {
522		d->bd_id |= inb(DSP_READ); /* minor */
523		break;
524	    }
525	} else
526	    DELAY(20);
527    }
528
529    /*
530     * now do various initializations depending on board id.
531     */
532
533    fmt = "SoundBlaster %d.%d" ; /* default */
534
535    switch ( d->bd_id >> 8 ) {
536    case 0 :
537	printf("\n\nFailed to get SB version (%x) - possible I/O conflict\n\n",
538	       inb(DSP_DATA_AVAIL));
539	d->bd_id = 0x100;
540    case 1 : /* old sound blaster has nothing... */
541	break ;
542
543    case 2 :
544	d->dbuf_in.chan = d->dbuf_out.chan ; /* half duplex */
545	d->bd_flags |= BD_F_DUP_MIDI ;
546
547	if (d->bd_id == 0x200)
548	    break ; /* no mixer on the 2.0 */
549	d->bd_flags &= ~BD_F_MIX_MASK ;
550	d->bd_flags |= BD_F_MIX_CT1335 ;
551
552	break ;
553    case 4 :
554	fmt = "SoundBlaster 16 %d.%d";
555	d->audio_fmt |= AFMT_FULLDUPLEX | AFMT_WEIRD | AFMT_S8 | AFMT_S16_LE;
556	d->bd_flags |= BD_F_SB16;
557	d->bd_flags &= ~BD_F_MIX_MASK ;
558	d->bd_flags |= BD_F_MIX_CT1745 ;
559
560	/* soft irq/dma configuration */
561	x = -1 ;
562	if (d->irq == 5) x = 2;
563	else if (d->irq == 7) x = 4;
564	else if (d->irq == 9) x = 1;
565	else if (d->irq == 10) x = 8;
566	if (x == -1)
567	    printf("<%s>%d: bad irq %d (only 5,7,9,10 allowed)\n",
568		d->name, dev->id_unit, d->irq);
569	else
570	    sb_setmixer(io_base, IRQ_NR, x);
571
572	sb_setmixer(io_base, DMA_NR, (1 << d->dbuf_out.chan) | (1 << d->dbuf_in.chan));
573	break ;
574
575    case 3 :
576	d->dbuf_in.chan = d->dbuf_out.chan ; /* half duplex */
577	fmt = "SoundBlaster Pro %d.%d";
578	d->bd_flags |= BD_F_DUP_MIDI ;
579	d->bd_flags &= ~BD_F_MIX_MASK ;
580	d->bd_flags |= BD_F_MIX_CT1345 ;
581	if (d->bd_id == 0x301) {
582	    int ess_major = 0, ess_minor = 0;
583
584	    /*
585	     * Try to detect ESS chips.
586	     */
587
588	    sb_cmd(io_base, DSP_CMD_GETID);	/* Return ident. bytes. */
589
590	    for (i = 1000; i; i--) {
591		if (inb(DSP_DATA_AVAIL) & 0x80) { /* wait for Data Ready */
592		    if (ess_major == 0)
593			ess_major = inb(DSP_READ);
594		    else {
595			ess_minor = inb(DSP_READ);
596			break;
597		    }
598		} else
599		    DELAY(20);
600	    }
601
602	    if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80)
603		printf("ESS488 (rev %d)\n", ess_minor & 0x0f);
604	    else if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
605		if ( (ess_minor & 0xf) >= 8 )
606		    printf("ESS1688 (rev %d)\n", ess_minor & 0x0f);
607	    else
608		    printf("ESS688 (rev %d)\n", ess_minor & 0x0f);
609	    } else
610		break ;
611	    d->bd_id = (ess_major << 8) | ess_minor ;
612	    d->bd_flags |= BD_F_ESS;
613	    /*
614	     * ESS-specific initialization, taken from OSSFree 3.8
615	     */
616	    {
617		static u_char irqs[16] = {
618		    0,    0, 0x50,    0,    0, 0x54,    0, 0x58,
619		    0, 0x50, 0x5c,    0,    0,    0,    0,    0 };
620		static u_char drqs[8] = {
621		 0x51, 0x52,    0, 0x53,    0,    0,    0,    0 };
622		x = irqs[d->irq & 0xf];
623		if (x == 0)
624		    printf("ESS : invalid IRQ %d\n", d->irq);
625		else {
626		    sb_cmd(io_base, 0xb1 );	/* set IRQ */
627		    sb_cmd(io_base, x );
628
629		    x = drqs[ d->dbuf_out.chan & 0x7 ];
630		    if (x == 0)
631			printf("ESS : invalid DRQ %d\n", d->dbuf_out.chan);
632		    else {
633			sb_cmd(io_base, 0xb2 );	/* set DRQ */
634			sb_cmd(io_base, x );
635	}
636    }
637	    }
638	}
639
640    }
641
642    sprintf(d->name, fmt, (d->bd_id >> 8) &0xff, d->bd_id & 0xff);
643
644    sb_mix_init(d);
645}
646
647static void
648sb_mix_init(snddev_info *d)
649{
650    switch (d->bd_flags & BD_F_MIX_MASK) {
651    case BD_F_MIX_CT1345 : /* SB 3.0 has 1345 mixer */
652
653	d->mix_devs = SBPRO_MIXER_DEVICES ;
654	d->mix_rec_devs = SBPRO_RECORDING_DEVICES ;
655	d->mix_recsrc = SOUND_MASK_MIC ;
656
657	sb_setmixer(d->io_base, 0, 1 ); /* reset mixer */
658	sb_setmixer(d->io_base, MIC_VOL , 0x6 ); /* mic volume max */
659	sb_setmixer(d->io_base, RECORD_SRC , 0x0 ); /* mic source */
660	sb_setmixer(d->io_base, FM_VOL , 0x0 ); /* no midi */
661	break ;
662
663    case BD_F_MIX_CT1745 : /* SB16 mixer ... */
664
665	d->mix_devs = SB16_MIXER_DEVICES ;
666	d->mix_rec_devs = SB16_RECORDING_DEVICES ;
667	d->mix_recsrc = SOUND_MASK_MIC ;
668    }
669    sb_mixer_reset(d);
670}
671
672/*
673 * Common code for the midi and pcm functions
674 */
675
676int
677sb_cmd(int io_base, u_char val)
678{
679    int  i;
680
681    for (i = 0; i < 1000 ; i++) {
682	if ((inb(DSP_STATUS) & 0x80) == 0) {
683	    outb(DSP_COMMAND, val);
684	    return 1;
685	}
686	if (i > 10)
687	    DELAY (i > 100 ? 1000 : 10 );
688    }
689
690    printf("SoundBlaster: DSP Command(0x%02x) timeout. IRQ conflict ?\n", val);
691    return 0;
692}
693
694int
695sb_cmd3(int io_base, u_char cmd, int val)
696{
697    if (sb_cmd(io_base, cmd)) {
698	sb_cmd(io_base, val & 0xff );
699	sb_cmd(io_base, (val>>8) & 0xff );
700	return 1 ;
701    } else
702	return 0;
703}
704
705int
706sb_cmd2(int io_base, u_char cmd, int val)
707{
708    if (sb_cmd(io_base, cmd)) {
709	sb_cmd(io_base, val & 0xff );
710	return 1 ;
711    } else
712	return 0;
713}
714
715void
716sb_setmixer(int io_base, u_int port, u_int value)
717{
718    u_long   flags;
719
720    flags = spltty();
721    outb(MIXER_ADDR, (u_char) (port & 0xff));   /* Select register */
722    DELAY(10);
723    outb(MIXER_DATA, (u_char) (value & 0xff));
724    DELAY(10);
725    splx(flags);
726}
727
728u_int
729sb_get_byte(int io_base)
730{
731    int             i;
732
733    for (i = 1000; i; i--)
734	if (inb(DSP_DATA_AVAIL) & 0x80)
735	    return inb(DSP_READ);
736	else
737	    DELAY(20);
738    return 0xffff;
739}
740
741int
742sb_getmixer(int io_base, u_int port)
743{
744    int             val;
745    u_long   flags;
746
747    flags = spltty();
748    outb(MIXER_ADDR, (u_char) (port & 0xff));   /* Select register */
749    DELAY(10);
750    val = inb(MIXER_DATA);
751    DELAY(10);
752    splx(flags);
753
754    return val;
755}
756
757
758/*
759 * various utility functions for the DSP
760 */
761
762/*
763 * dsp_speed updates the speed setting from the descriptor. make sure
764 * it is called at spltty().
765 * Besides, it takes care of stereo setting.
766 */
767static int
768dsp_speed(snddev_info *d)
769{
770    u_char   tconst;
771    u_long   flags;
772    int max_speed = 44100, speed = d->play_speed ;
773
774    /*
775     * special code for the SB16
776     */
777    if (d->bd_flags & BD_F_SB16) {
778	RANGE (speed, 5000, 45000);
779	d->play_speed = d->rec_speed = speed ;
780	sb_cmd(d->io_base, 0x41);
781	sb_cmd(d->io_base, d->play_speed >> 8 );
782	sb_cmd(d->io_base, d->play_speed & 0xff );
783	sb_cmd(d->io_base, 0x42);
784	sb_cmd(d->io_base, d->rec_speed >> 8 );
785	sb_cmd(d->io_base, d->rec_speed & 0xff );
786	return speed ;
787    }
788
789    /*
790     * special code for the ESS ...
791     */
792    if (d->bd_flags & BD_F_ESS) {
793	int t;
794	RANGE (speed, 4000, 48000);
795	if (speed > 22000) {
796	    t = (795500 + speed / 2) / speed;
797	    speed = (795500 + t / 2) / t ;
798	    t = ( 256 - (795500 + speed / 2) / speed ) | 0x80 ;
799	} else {
800	    t = (397700 + speed / 2) / speed;
801	    speed = (397700 + t / 2) / t ;
802	    t = 128 - (397700 + speed / 2) / speed ;
803	}
804	sb_cmd2(d->io_base, 0xa1, t); /* set time constant */
805	return speed ;
806    }
807
808    /*
809     * only some models can do stereo, and only if not
810     * simultaneously using midi.
811     */
812    if ( (d->bd_id & 0xff00) < 0x300 || d->bd_flags & BD_F_MIDIBUSY)
813	d->flags &= ~SND_F_STEREO;
814
815    /*
816     * here enforce speed limitations.
817     */
818    if (d->bd_id <= 0x200)
819	max_speed = 22050; /* max 22050 on SB 1.X */
820
821    /*
822     * SB models earlier than SB Pro have low limit for the
823     * input rate. Note that this is only for input, but since
824     * we do not support separate values for rec & play....
825     */
826    if (d->bd_id <= 0x200)
827	max_speed = 13000;
828    else if (d->bd_id < 0x300)
829	max_speed = 15000;
830
831    RANGE(speed, 4000, max_speed);
832
833    /*
834     * Logitech SoundMan Games and Jazz16 cards can support 44.1kHz
835     * stereo
836     */
837#if !defined (SM_GAMES)
838    /*
839     * Max. stereo speed is 22050
840     */
841    if (d->flags & SND_F_STEREO && speed > 22050 && !(d->bd_flags & BD_F_JAZZ16))
842	speed = 22050;
843#endif
844
845    if (d->flags & SND_F_STEREO)
846	speed *= 2;
847
848    /*
849     * Now the speed should be valid. Compute the value to be
850     * programmed into the board.
851     *
852     * XXX stereo init is still missing...
853     */
854
855    if (speed > 22050) { /* High speed mode on 2.01/3.xx */
856	int tmp;
857
858	tconst = (u_char) ((65536 - ((256000000 + speed / 2) / speed)) >> 8) ;
859	d->bd_flags |= BD_F_HISPEED ;
860
861	flags = spltty();
862	sb_cmd2(d->io_base, 0x40, tconst); /* set time constant */
863	splx(flags);
864
865	tmp = 65536 - (tconst << 8);
866	speed = (256000000 + tmp / 2) / tmp;
867    } else {
868	int             tmp;
869
870	d->bd_flags &= ~BD_F_HISPEED ;
871	tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
872
873	flags = spltty();
874	sb_cmd2(d->io_base, 0x40, tconst); /* set time constant */
875	splx(flags);
876
877	tmp = 256 - tconst;
878	speed = (1000000 + tmp / 2) / tmp;
879    }
880
881    if (d->flags & SND_F_STEREO)
882	speed /= 2;
883
884    d->play_speed = d->rec_speed = speed;
885    return speed;
886}
887
888/*
889 * mixer support, originally in sb_mixer.c
890 */
891
892static void
893sb_set_recsrc(snddev_info *d, int mask)
894{
895    u_char recdev ;
896
897    mask &= d->mix_rec_devs;
898    switch (d->bd_flags & BD_F_MIX_MASK) {
899    case BD_F_MIX_CT1345 :
900	if (mask == SOUND_MASK_LINE)
901	    recdev = 6 ;
902	else if (mask == SOUND_MASK_CD)
903	    recdev = 2 ;
904	else { /* default: mic */
905	    mask =  SOUND_MASK_MIC ;
906	    recdev = 0 ;
907	}
908	sb_setmixer(d->io_base, RECORD_SRC,
909	    recdev | (sb_getmixer(d->io_base, RECORD_SRC) & ~7 ));
910	break ;
911    case BD_F_MIX_CT1745 : /* sb16 */
912	if (mask == 0)
913	    mask = SOUND_MASK_MIC ; /* XXX For compatibility. Bug ? */
914	recdev = 0 ;
915	if (mask & SOUND_MASK_MIC)
916	    recdev |= 1 ;
917	if (mask & SOUND_MASK_CD)
918	    recdev |= 6 ; /* l+r cd */
919	if (mask & SOUND_MASK_LINE)
920	    recdev |= 0x18 ; /* l+r line */
921	if (mask & SOUND_MASK_SYNTH)
922	    recdev |= 0x60 ; /* l+r midi */
923	sb_setmixer(d->io_base, SB16_IMASK_L, recdev);
924	sb_setmixer(d->io_base, SB16_IMASK_R, recdev);
925	/*
926	 * since the same volume controls apply to the input and
927	 * output sections, the best approach to have a consistent
928	 * behaviour among cards would be to disable the output path
929	 * on devices which are used to record.
930	 * However, since users like to have feedback, we only disable
931	 * the mike -- permanently.
932	 */
933        sb_setmixer(d->io_base, SB16_OMASK, 0x1f & ~1);
934	break ;
935    }
936    d->mix_recsrc = mask;
937}
938
939static void
940sb_mixer_reset(snddev_info *d)
941{
942    int             i;
943
944    for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
945	sb_mixer_set(d, i, levels[i]);
946    if (d->bd_flags & BD_F_SB16) {
947	sb_setmixer(d->io_base, 0x3c, 0x1f); /* make all output active */
948	sb_setmixer(d->io_base, 0x3d, 0); /* make all inputs-l off */
949	sb_setmixer(d->io_base, 0x3e, 0); /* make all inputs-r off */
950    }
951    sb_set_recsrc(d, SOUND_MASK_MIC);
952}
953
954static int
955sb_mixer_set(snddev_info *d, int dev, int value)
956{
957    int left = value & 0x000000ff;
958    int right = (value & 0x0000ff00) >> 8;
959    int regoffs;
960    u_char   val;
961    mixer_tab *iomap;
962
963#ifdef JAZZ16
964    if (d->bd_flags & BD_F_JAZZ16 && d->bd_flags & BD_F_JAZZ16_2)
965        return smw_mixer_set(dev, value);
966#endif
967
968    if (dev == SOUND_MIXER_RECSRC) {
969	sb_set_recsrc(d, value);
970	return 0 ;
971    }
972    if (left > 100)
973        left = 100;
974    if (right > 100)
975        right = 100;
976
977    if (dev > 31)
978        return EINVAL ;
979
980    if (!(d->mix_devs & (1 << dev)))      /* Not supported */
981        return EINVAL;
982
983    switch ( d->bd_flags & BD_F_MIX_MASK ) {
984    default:
985	/* mixer unknown, fail... */
986	return EINVAL ;/* XXX change this */
987    case BD_F_MIX_CT1345 :
988	iomap = &sbpro_mix ;
989	break;
990    case BD_F_MIX_CT1745 :
991	iomap = &sb16_mix ;
992	break;
993    /* XXX how about the SG NX Pro, iomap = sgnxpro_mix */
994    }
995    regoffs = (*iomap)[dev][LEFT_CHN].regno;
996    if (regoffs == 0)
997        return EINVAL;
998
999    val = sb_getmixer(d->io_base, regoffs);
1000
1001    change_bits(iomap, &val, dev, LEFT_CHN, left);
1002
1003    d->mix_levels[dev] = left | (left << 8);
1004
1005    if ((*iomap)[dev][RIGHT_CHN].regno != regoffs) {    /* Change register */
1006        sb_setmixer(d->io_base, regoffs, val);     /* Save the old one */
1007        regoffs = (*iomap)[dev][RIGHT_CHN].regno;
1008
1009        if (regoffs == 0)
1010            return 0 ;  /* Just left channel present */
1011
1012        val = sb_getmixer(d->io_base, regoffs);    /* Read the new one */
1013    }
1014    change_bits(iomap, &val, dev, RIGHT_CHN, right);
1015
1016    sb_setmixer(d->io_base, regoffs, val);
1017
1018    d->mix_levels[dev] = left | (right << 8);
1019    return 0 ; /* ok */
1020}
1021
1022/*
1023 * now support for some PnP boards.
1024 */
1025
1026#if NPNP > 0
1027static char *opti925_probe(u_long csn, u_long vend_id);
1028static void opti925_attach(u_long csn, u_long vend_id, char *name,
1029        struct isa_device *dev);
1030
1031static struct pnp_device opti925 = {
1032        "opti925",
1033        opti925_probe,
1034        opti925_attach,
1035        &nsnd,  /* use this for all sound cards */
1036        &tty_imask      /* imask */
1037};
1038DATA_SET (pnpdevice_set, opti925);
1039
1040static char *
1041opti925_probe(u_long csn, u_long vend_id)
1042{
1043    if (vend_id == 0x2509143e) {
1044	struct pnp_cinfo d ;
1045	read_pnp_parms ( &d , 1 ) ;
1046	if (d.enable == 0) {
1047	    printf("This is an OPTi925, but LDN 1 is disabled\n");
1048	    return NULL;
1049	}
1050        return "OPTi925" ;
1051    }
1052    return NULL ;
1053}
1054
1055static void
1056opti925_attach(u_long csn, u_long vend_id, char *name,
1057        struct isa_device *dev)
1058{
1059    struct pnp_cinfo d ;
1060    snddev_info tmp_d ; /* patched copy of the basic snddev_info */
1061    int the_irq = 0 ;
1062
1063    tmp_d = sb_op_desc;
1064    snddev_last_probed = &tmp_d;
1065
1066    read_pnp_parms ( &d , 3 );  /* disable LDN 3 */
1067    the_irq = d.irq[0];
1068    d.port[0] = 0 ;
1069    d.enable = 0 ;
1070    write_pnp_parms ( &d , 3 );
1071
1072    read_pnp_parms ( &d , 2 ); /* disable LDN 2 */
1073    d.port[0] = 0 ;
1074    d.enable = 0 ;
1075    write_pnp_parms ( &d , 2 );
1076
1077    read_pnp_parms ( &d , 1 ) ;
1078    d.irq[0] = the_irq ;
1079    dev->id_iobase = d.port[0];
1080    write_pnp_parms ( &d , 1 );
1081    enable_pnp_card();
1082
1083    tmp_d.conf_base = d.port[3];
1084
1085    dev->id_drq = d.drq[0] ; /* primary dma */
1086    dev->id_irq = (1 << d.irq[0] ) ;
1087    dev->id_intr = pcmintr ;
1088    dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ;
1089
1090    snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
1091
1092    pcmattach(dev);
1093
1094}
1095
1096/*
1097 * A driver for some SB16pnp and compatibles...
1098 *
1099 * Avance Asound 100 -- 0x01009305
1100 * xxx               -- 0x2b008c0e
1101 *
1102 */
1103
1104static char *sb16pnp_probe(u_long csn, u_long vend_id);
1105static void sb16pnp_attach(u_long csn, u_long vend_id, char *name,
1106        struct isa_device *dev);
1107
1108static struct pnp_device sb16pnp = {
1109        "SB16pnp",
1110        sb16pnp_probe,
1111        sb16pnp_attach,
1112        &nsnd,  /* use this for all sound cards */
1113        &tty_imask      /* imask */
1114};
1115DATA_SET (pnpdevice_set, sb16pnp);
1116
1117static char *
1118sb16pnp_probe(u_long csn, u_long vend_id)
1119{
1120    char *s = NULL ;
1121
1122    /*
1123     * The SB16/AWExx cards seem to differ in the fourth byte of
1124     * the vendor id, so I have just masked it for the time being...
1125     * Reported values are:
1126     * SB16 Value PnP:	0x2b008c0e
1127     * SB AWExx PnP:	0x39008c0e 0x9d008c0e 0xc3008c0e
1128     */
1129    if ( (vend_id & 0xffffff)  == (0x9d008c0e & 0xffffff) )
1130	s = "SB16 PnP";
1131    else if (vend_id == 0x01009305)
1132        s = "Avance Asound 100" ;
1133    if (s) {
1134	struct pnp_cinfo d;
1135	read_pnp_parms(&d, 0);
1136	if (d.enable == 0) {
1137	    printf("This is a %s, but LDN 0 is disabled\n", s);
1138	    return NULL ;
1139	}
1140	return s ;
1141    }
1142    return NULL ;
1143}
1144
1145static void
1146sb16pnp_attach(u_long csn, u_long vend_id, char *name,
1147        struct isa_device *dev)
1148{
1149    struct pnp_cinfo d ;
1150    snddev_info tmp_d ; /* patched copy of the basic snddev_info */
1151
1152    tmp_d = sb_op_desc;
1153    snddev_last_probed = &tmp_d;
1154
1155    read_pnp_parms ( &d , 0 ) ;
1156    d.port[1] = 0 ; /* only the first address is used */
1157    dev->id_iobase = d.port[0];
1158    write_pnp_parms ( &d , 0 );
1159    enable_pnp_card();
1160
1161    dev->id_drq = d.drq[0] ; /* primary dma */
1162    dev->id_irq = (1 << d.irq[0] ) ;
1163    dev->id_intr = pcmintr ;
1164    dev->id_flags = DV_F_DUAL_DMA | (d.drq[1] ) ;
1165
1166    pcm_info[dev->id_unit] = tmp_d;
1167    snddev_last_probed->probe(dev); /* not really necessary but doesn't harm */
1168
1169    pcmattach(dev);
1170}
1171#endif /* NPNP */
1172
1173#endif
1174