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