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