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
|