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