This source file includes following definitions.
- sb_dsp_command01
- dsp_set_speed
- dsp_set_stereo
- dsp_set_bits
- sb16_dsp_ioctl
- sb16_dsp_open
- sb16_dsp_close
- sb16_dsp_output_block
- sb16_dsp_start_input
- sb16_dsp_prepare_for_input
- sb16_dsp_prepare_for_output
- dsp_cleanup
- sb16_dsp_reset
- sb16_dsp_halt
- set_irq_hw
- sb16_dsp_init
- sb16_dsp_detect
- sb16_dsp_interrupt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #define DEB(x)
33 #define DEB1(x)
34
35
36
37 #include "sound_config.h"
38 #include "sb.h"
39 #include "sb_mixer.h"
40
41 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_AUDIO) && !defined(EXCLUDE_SBPRO)
42
43 extern int sbc_base;
44
45 static int sb16_dsp_ok = 0;
46
47
48
49
50 static int dsp_16bit = 0;
51 static int dsp_stereo = 0;
52 static int dsp_current_speed = 8000;
53
54
55
56 static int dsp_busy = 0;
57 static int dma16, dma8;
58 static unsigned long dsp_count = 0;
59
60 static int irq_mode = IMODE_NONE;
61
62
63
64
65 static int my_dev = 0;
66
67 static volatile int intr_active = 0;
68
69 static int sb16_dsp_open (int dev, int mode);
70 static void sb16_dsp_close (int dev);
71 static void sb16_dsp_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
72 static void sb16_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart);
73 static int sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local);
74 static int sb16_dsp_prepare_for_input (int dev, int bsize, int bcount);
75 static int sb16_dsp_prepare_for_output (int dev, int bsize, int bcount);
76 static void sb16_dsp_reset (int dev);
77 static void sb16_dsp_halt (int dev);
78 static int dsp_set_speed (int);
79 static int dsp_set_stereo (int);
80 static void dsp_cleanup (void);
81 int sb_reset_dsp (void);
82
83 static struct audio_operations sb16_dsp_operations =
84 {
85 "SoundBlaster 16",
86 DMA_AUTOMODE,
87 AFMT_U8 | AFMT_S16_LE,
88 NULL,
89 sb16_dsp_open,
90 sb16_dsp_close,
91 sb16_dsp_output_block,
92 sb16_dsp_start_input,
93 sb16_dsp_ioctl,
94 sb16_dsp_prepare_for_input,
95 sb16_dsp_prepare_for_output,
96 sb16_dsp_reset,
97 sb16_dsp_halt,
98 NULL,
99 NULL
100 };
101
102 static int
103 sb_dsp_command01 (unsigned char val)
104 {
105 int i = 1 << 16;
106
107 while (--i & (!INB (DSP_STATUS) & 0x80));
108 if (!i)
109 printk ("SB16 sb_dsp_command01 Timeout\n");
110 return sb_dsp_command (val);
111 }
112
113 static int
114 dsp_set_speed (int mode)
115 {
116 DEB (printk ("dsp_set_speed(%d)\n", mode));
117 if (mode)
118 {
119 if (mode < 5000)
120 mode = 5000;
121 if (mode > 44100)
122 mode = 44100;
123 dsp_current_speed = mode;
124 }
125 return mode;
126 }
127
128 static int
129 dsp_set_stereo (int mode)
130 {
131 DEB (printk ("dsp_set_stereo(%d)\n", mode));
132
133 dsp_stereo = mode;
134
135 return mode;
136 }
137
138 static int
139 dsp_set_bits (int arg)
140 {
141 DEB (printk ("dsp_set_bits(%d)\n", arg));
142
143 if (arg)
144 switch (arg)
145 {
146 case 8:
147 dsp_16bit = 0;
148 break;
149 case 16:
150 dsp_16bit = 1;
151 break;
152 default:
153 dsp_16bit = 0;
154 }
155 return dsp_16bit ? 16 : 8;
156 }
157
158 static int
159 sb16_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
160 {
161 switch (cmd)
162 {
163 case SOUND_PCM_WRITE_RATE:
164 if (local)
165 return dsp_set_speed (arg);
166 return IOCTL_OUT (arg, dsp_set_speed (IOCTL_IN (arg)));
167
168 case SOUND_PCM_READ_RATE:
169 if (local)
170 return dsp_current_speed;
171 return IOCTL_OUT (arg, dsp_current_speed);
172
173 case SNDCTL_DSP_STEREO:
174 if (local)
175 return dsp_set_stereo (arg);
176 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
177
178 case SOUND_PCM_WRITE_CHANNELS:
179 if (local)
180 return dsp_set_stereo (arg - 1) + 1;
181 return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
182
183 case SOUND_PCM_READ_CHANNELS:
184 if (local)
185 return dsp_stereo + 1;
186 return IOCTL_OUT (arg, dsp_stereo + 1);
187
188 case SNDCTL_DSP_SETFMT:
189 if (local)
190 return dsp_set_bits (arg);
191 return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg)));
192
193 case SOUND_PCM_READ_BITS:
194 if (local)
195 return dsp_16bit ? 16 : 8;
196 return IOCTL_OUT (arg, dsp_16bit ? 16 : 8);
197
198 case SOUND_PCM_WRITE_FILTER:
199
200
201 if (IOCTL_IN (arg) > 1)
202 return IOCTL_OUT (arg, RET_ERROR (EINVAL));
203 default:
204 return RET_ERROR (EINVAL);
205 }
206
207 return RET_ERROR (EINVAL);
208 }
209
210 static int
211 sb16_dsp_open (int dev, int mode)
212 {
213 int retval;
214
215 DEB (printk ("sb16_dsp_open()\n"));
216 if (!sb16_dsp_ok)
217 {
218 printk ("SB16 Error: SoundBlaster board not installed\n");
219 return RET_ERROR (ENXIO);
220 }
221
222 if (intr_active)
223 return RET_ERROR (EBUSY);
224
225 retval = sb_get_irq ();
226 if (retval < 0)
227 return retval;
228
229 sb_reset_dsp ();
230
231 if (ALLOC_DMA_CHN (dma8,"sb16 8bit"))
232 {
233 printk ("SB16: Unable to grab DMA%d\n", dma8);
234 sb_free_irq ();
235 return RET_ERROR (EBUSY);
236 }
237
238 if (dma16 != dma8)
239 if (ALLOC_DMA_CHN (dma16,"sb16 16bit"))
240 {
241 printk ("SB16: Unable to grab DMA%d\n", dma16);
242 sb_free_irq ();
243 RELEASE_DMA_CHN (dma8);
244 return RET_ERROR (EBUSY);
245 }
246
247 irq_mode = IMODE_NONE;
248 dsp_busy = 1;
249
250 return 0;
251 }
252
253 static void
254 sb16_dsp_close (int dev)
255 {
256 unsigned long flags;
257
258 DEB (printk ("sb16_dsp_close()\n"));
259 sb_dsp_command01 (0xd9);
260 sb_dsp_command01 (0xd5);
261
262 DISABLE_INTR (flags);
263 RELEASE_DMA_CHN (dma8);
264
265 if (dma16 != dma8)
266 RELEASE_DMA_CHN (dma16);
267 sb_free_irq ();
268 dsp_cleanup ();
269 dsp_busy = 0;
270 RESTORE_INTR (flags);
271 }
272
273 static void
274 sb16_dsp_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
275 {
276 unsigned long flags, cnt;
277
278 cnt = count;
279 if (dsp_16bit)
280 cnt >>= 1;
281 cnt--;
282
283 #ifdef DEB_DMARES
284 printk ("output_block: %x %d %d\n", buf, count, intrflag);
285 if (intrflag)
286 {
287 int pos, chan = audio_devs[dev]->dmachan;
288
289 DISABLE_INTR (flags);
290 clear_dma_ff (chan);
291 disable_dma (chan);
292 pos = get_dma_residue (chan);
293 enable_dma (chan);
294 RESTORE_INTR (flags);
295 printk ("dmapos=%d %x\n", pos, pos);
296 }
297 #endif
298 if (audio_devs[dev]->flags & DMA_AUTOMODE &&
299 intrflag &&
300 cnt == dsp_count)
301 {
302 irq_mode = IMODE_OUTPUT;
303 intr_active = 1;
304 return;
305
306
307 }
308 DISABLE_INTR (flags);
309
310 if (dma_restart)
311 {
312 sb16_dsp_halt (dev);
313 DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
314 }
315 sb_dsp_command (0x41);
316 sb_dsp_command ((unsigned char) ((dsp_current_speed >> 8) & 0xff));
317 sb_dsp_command ((unsigned char) (dsp_current_speed & 0xff));
318 sb_dsp_command ((unsigned char) (dsp_16bit ? 0xb6 : 0xc6));
319 sb_dsp_command ((unsigned char) ((dsp_stereo ? 0x20 : 0) +
320 (dsp_16bit ? 0x10 : 0)));
321 sb_dsp_command01 ((unsigned char) (cnt & 0xff));
322 sb_dsp_command ((unsigned char) (cnt >> 8));
323
324 dsp_count = cnt;
325 irq_mode = IMODE_OUTPUT;
326 intr_active = 1;
327 RESTORE_INTR (flags);
328 }
329
330 static void
331 sb16_dsp_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
332 {
333 unsigned long flags, cnt;
334
335 cnt = count;
336 if (dsp_16bit)
337 cnt >>= 1;
338 cnt--;
339
340 #ifdef DEB_DMARES
341 printk ("start_input: %x %d %d\n", buf, count, intrflag);
342 if (intrflag)
343 {
344 int pos, chan = audio_devs[dev]->dmachan;
345
346 DISABLE_INTR (flags);
347 clear_dma_ff (chan);
348 disable_dma (chan);
349 pos = get_dma_residue (chan);
350 enable_dma (chan);
351 RESTORE_INTR (flags);
352 printk ("dmapos=%d %x\n", pos, pos);
353 }
354 #endif
355 if (audio_devs[dev]->flags & DMA_AUTOMODE &&
356 intrflag &&
357 cnt == dsp_count)
358 {
359 irq_mode = IMODE_INPUT;
360 intr_active = 1;
361 return;
362
363
364 }
365 DISABLE_INTR (flags);
366
367 if (dma_restart)
368 {
369 sb_reset_dsp ();
370 DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
371 }
372
373 sb_dsp_command (0x42);
374 sb_dsp_command ((unsigned char) ((dsp_current_speed >> 8) & 0xff));
375 sb_dsp_command ((unsigned char) (dsp_current_speed & 0xff));
376 sb_dsp_command ((unsigned char) (dsp_16bit ? 0xbe : 0xce));
377 sb_dsp_command ((unsigned char) ((dsp_stereo ? 0x20 : 0) +
378 (dsp_16bit ? 0x10 : 0)));
379 sb_dsp_command01 ((unsigned char) (cnt & 0xff));
380 sb_dsp_command ((unsigned char) (cnt >> 8));
381
382 dsp_count = cnt;
383 irq_mode = IMODE_INPUT;
384 intr_active = 1;
385 RESTORE_INTR (flags);
386 }
387
388 static int
389 sb16_dsp_prepare_for_input (int dev, int bsize, int bcount)
390 {
391 audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
392 dsp_count = 0;
393 dsp_cleanup ();
394 return 0;
395 }
396
397 static int
398 sb16_dsp_prepare_for_output (int dev, int bsize, int bcount)
399 {
400 audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
401 dsp_count = 0;
402 dsp_cleanup ();
403 return 0;
404 }
405
406 static void
407 dsp_cleanup (void)
408 {
409 irq_mode = IMODE_NONE;
410 intr_active = 0;
411 }
412
413 static void
414 sb16_dsp_reset (int dev)
415 {
416 unsigned long flags;
417
418 DISABLE_INTR (flags);
419
420 sb_reset_dsp ();
421 dsp_cleanup ();
422
423 RESTORE_INTR (flags);
424 }
425
426 static void
427 sb16_dsp_halt (int dev)
428 {
429 if (dsp_16bit)
430 {
431 sb_dsp_command01 (0xd9);
432 sb_dsp_command01 (0xd5);
433 }
434 else
435 {
436 sb_dsp_command01 (0xda);
437 sb_dsp_command01 (0xd0);
438 }
439 }
440
441 static void
442 set_irq_hw (int level)
443 {
444 int ival;
445
446 switch (level)
447 {
448 case 5:
449 ival = 2;
450 break;
451 case 7:
452 ival = 4;
453 break;
454 case 9:
455 ival = 1;
456 break;
457 case 10:
458 ival = 8;
459 break;
460 default:
461 printk ("SB16_IRQ_LEVEL %d does not exist\n", level);
462 return;
463 }
464 sb_setmixer (IRQ_NR, ival);
465 }
466
467 long
468 sb16_dsp_init (long mem_start, struct address_info *hw_config)
469 {
470 extern int sbc_major, sbc_minor;
471
472 if (sbc_major < 4)
473 return mem_start;
474
475 #ifndef SCO
476 sprintf (sb16_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
477 #endif
478
479 printk (" <%s>", sb16_dsp_operations.name);
480
481 if (num_audiodevs < MAX_AUDIO_DEV)
482 {
483 audio_devs[my_dev = num_audiodevs++] = &sb16_dsp_operations;
484 audio_devs[my_dev]->dmachan = hw_config->dma;
485 audio_devs[my_dev]->buffcount = 1;
486 audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
487 }
488 else
489 printk ("SB: Too many DSP devices available\n");
490 sb16_dsp_ok = 1;
491 return mem_start;
492 }
493
494 int
495 sb16_dsp_detect (struct address_info *hw_config)
496 {
497 struct address_info *sb_config;
498 extern int sbc_major;
499
500 if (sb16_dsp_ok)
501 return 1;
502
503 if (!(sb_config = sound_getconf (SNDCARD_SB)))
504 {
505 printk ("SB16 Error: Plain SB not configured\n");
506 return 0;
507 }
508
509
510
511
512
513 if (!sb_reset_dsp ())
514 return 0;
515
516 if (sbc_major < 4)
517 return 0;
518
519 if (hw_config->dma < 4)
520 if (hw_config->dma != sb_config->dma)
521 {
522 printk ("SB16 Error: Invalid DMA channel %d/%d\n",
523 sb_config->dma, hw_config->dma);
524 return 0;
525 }
526
527 dma16 = hw_config->dma;
528 dma8 = sb_config->dma;
529 set_irq_hw (sb_config->irq);
530 sb_setmixer (DMA_NR, (1 << hw_config->dma) | (1 << sb_config->dma));
531
532 DEB (printk ("SoundBlaster 16: IRQ %d DMA %d OK\n", sb_config->irq, hw_config->dma));
533
534
535
536
537 sb16_dsp_ok = 1;
538 return 1;
539 }
540
541 void
542 sb16_dsp_interrupt (int unused)
543 {
544 int data;
545
546 data = INB (DSP_DATA_AVL16);
547
548
549
550 if (intr_active)
551 switch (irq_mode)
552 {
553 case IMODE_OUTPUT:
554 intr_active = 0;
555 DMAbuf_outputintr (my_dev, 1);
556 break;
557
558 case IMODE_INPUT:
559 intr_active = 0;
560 DMAbuf_inputintr (my_dev);
561 break;
562
563 default:
564 printk ("SoundBlaster: Unexpected interrupt\n");
565 }
566 }
567
568 #endif