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