This source file includes following definitions.
- probe_pss
- set_irq
- set_io_base
- set_dma
- pss_reset_dsp
- pss_put_dspword
- pss_get_dspword
- pss_download_boot
- attach_pss
- probe_pss_mpu
- pss_coproc_open
- pss_coproc_close
- pss_coproc_reset
- download_boot_block
- pss_coproc_ioctl
- attach_pss_mpu
- probe_pss_mss
- attach_pss_mss
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 #include "sound_config.h"
31
32 #if defined (CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PSS) && !defined(EXCLUDE_AUDIO)
33
34
35
36
37 #define REG(x) (devc->base+x)
38 #define PSS_DATA 0
39 #define PSS_STATUS 2
40 #define PSS_CONTROL 2
41 #define PSS_ID 4
42 #define PSS_IRQACK 4
43 #define PSS_PIO 0x1a
44
45
46
47
48 #define CONF_PSS 0x10
49 #define CONF_WSS 0x12
50 #define CONF_SB 0x13
51 #define CONF_CDROM 0x16
52 #define CONF_MIDI 0x18
53
54
55
56
57 #define PSS_FLAG3 0x0800
58 #define PSS_FLAG2 0x0400
59 #define PSS_FLAG1 0x1000
60 #define PSS_FLAG0 0x0800
61 #define PSS_WRITE_EMPTY 0x8000
62 #define PSS_READ_FULL 0x4000
63
64 #include "coproc.h"
65 #include "synth-ld.h"
66
67 typedef struct pss_config
68 {
69 int base;
70 int irq;
71 int dma;
72 }
73
74 pss_config;
75
76 static pss_config pss_data;
77 static pss_config *devc = &pss_data;
78
79 static int pss_initialized = 0;
80 static int nonstandard_microcode = 0;
81
82 int
83 probe_pss (struct address_info *hw_config)
84 {
85 unsigned short id;
86 int irq, dma;
87
88 devc->base = hw_config->io_base;
89 irq = devc->irq = hw_config->irq;
90 dma = devc->dma = hw_config->dma;
91
92 if (devc->base != 0x220 && devc->base != 0x240)
93 if (devc->base != 0x230 && devc->base != 0x250)
94 return 0;
95
96 if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
97 irq != 10 && irq != 11 && irq != 12)
98 return 0;
99
100 if (dma != 5 && dma != 6 && dma != 7)
101 return 0;
102
103 id = INW (REG (PSS_ID));
104 if ((id >> 8) != 'E')
105 {
106 printk ("No PSS signature detected at 0x%x (0x%x)\n", devc->base, id);
107 return 0;
108 }
109
110 return 1;
111 }
112
113 static int
114 set_irq (pss_config * devc, int dev, int irq)
115 {
116 static unsigned short irq_bits[16] =
117 {
118 0x0000, 0x0000, 0x0000, 0x0008,
119 0x0000, 0x0010, 0x0000, 0x0018,
120 0x0000, 0x0020, 0x0028, 0x0030,
121 0x0038, 0x0000, 0x0000, 0x0000
122 };
123
124 unsigned short tmp, bits;
125
126 if (irq < 1 || irq > 15)
127 return 0;
128
129 tmp = INW (REG (dev)) & ~0x38;
130
131 if ((bits = irq_bits[irq]) == 0)
132 {
133 printk ("PSS: Invalid IRQ %d\n", irq);
134 return 0;
135 }
136
137 OUTW (tmp | bits, REG (dev));
138 return 1;
139 }
140
141 static int
142 set_io_base (pss_config * devc, int dev, int base)
143 {
144 unsigned short tmp = INW (REG (dev)) & 0x003f;
145 unsigned short bits = (base & 0x0ffc) << 4;
146
147 OUTW (bits | tmp, REG (dev));
148
149 return 1;
150 }
151
152 static int
153 set_dma (pss_config * devc, int dev, int dma)
154 {
155 static unsigned short dma_bits[8] =
156 {
157 0x0001, 0x0002, 0x0000, 0x0003,
158 0x0000, 0x0005, 0x0006, 0x0007
159 };
160
161 unsigned short tmp, bits;
162
163 if (dma < 0 || dma > 7)
164 return 0;
165
166 tmp = INW (REG (dev)) & ~0x07;
167
168 if ((bits = dma_bits[dma]) == 0)
169 {
170 printk ("PSS: Invalid DMA %d\n", dma);
171 return 0;
172 }
173
174 OUTW (tmp | bits, REG (dev));
175 return 1;
176 }
177
178 static int
179 pss_reset_dsp (pss_config * devc)
180 {
181 unsigned long i, limit = GET_TIME () + 10;
182
183 OUTW (0x2000, REG (PSS_CONTROL));
184
185 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
186 INW (REG (PSS_CONTROL));
187
188 OUTW (0x0000, REG (PSS_CONTROL));
189
190 return 1;
191 }
192
193 static int
194 pss_put_dspword (pss_config * devc, unsigned short word)
195 {
196 int i, val;
197
198 for (i = 0; i < 327680; i++)
199 {
200 val = INW (REG (PSS_STATUS));
201 if (val & PSS_WRITE_EMPTY)
202 {
203 OUTW (word, REG (PSS_DATA));
204 return 1;
205 }
206 }
207 return 0;
208 }
209
210 static int
211 pss_get_dspword (pss_config * devc, unsigned short *word)
212 {
213 int i, val;
214
215 for (i = 0; i < 327680; i++)
216 {
217 val = INW (REG (PSS_STATUS));
218 if (val & PSS_READ_FULL)
219 {
220 *word = INW (REG (PSS_DATA));
221 return 1;
222 }
223 }
224
225 return 0;
226 }
227
228 static int
229 pss_download_boot (pss_config * devc, unsigned char *block, int size, int flags)
230 {
231 int i, limit, val, count;
232
233 if (flags & CPF_FIRST)
234 {
235
236 OUTW (0x00fe, REG (PSS_DATA));
237
238 limit = GET_TIME () + 10;
239
240 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
241 if (INW (REG (PSS_DATA)) == 0x5500)
242 break;
243
244 OUTW (*block++, REG (PSS_DATA));
245
246 pss_reset_dsp (devc);
247 }
248
249 count = 1;
250 while (1)
251 {
252 int j;
253
254 for (j = 0; j < 327670; j++)
255 {
256
257 if (INW (REG (PSS_STATUS)) & PSS_FLAG3)
258 break;
259 }
260
261 if (j == 327670)
262 {
263
264 if (count >= size && flags & CPF_LAST)
265 break;
266 else
267 {
268 printk ("\nPSS: DownLoad timeout problems, byte %d=%d\n",
269 count, size);
270 return 0;
271 }
272 }
273
274 OUTW (*block++, REG (PSS_DATA));
275 count++;
276 }
277
278 if (flags & CPF_LAST)
279 {
280
281 OUTW (0, REG (PSS_DATA));
282
283 limit = GET_TIME () + 10;
284 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
285 val = INW (REG (PSS_STATUS));
286
287 limit = GET_TIME () + 10;
288 for (i = 0; i < 32768 && GET_TIME () < limit; i++)
289 {
290 val = INW (REG (PSS_STATUS));
291 if (val & 0x4000)
292 break;
293 }
294
295
296 for (i = 0; i < 32000; i++)
297 {
298 val = INW (REG (PSS_STATUS));
299 if (val & PSS_READ_FULL)
300 break;
301 }
302 if (i == 32000)
303 return 0;
304
305 val = INW (REG (PSS_DATA));
306
307 }
308
309 return 1;
310 }
311
312 long
313 attach_pss (long mem_start, struct address_info *hw_config)
314 {
315 unsigned short id;
316
317 devc->base = hw_config->io_base;
318 devc->irq = hw_config->irq;
319 devc->dma = hw_config->dma;
320
321 if (!probe_pss (hw_config))
322 return mem_start;
323
324 id = INW (REG (PSS_ID)) & 0x00ff;
325
326
327
328
329 OUTW (0x0000, REG (CONF_PSS));
330 OUTW (0x0000, REG (CONF_WSS));
331 OUTW (0x0000, REG (CONF_SB));
332 OUTW (0x0000, REG (CONF_MIDI));
333 OUTW (0x0000, REG (CONF_CDROM));
334
335 if (!set_irq (devc, CONF_PSS, devc->irq))
336 {
337 printk ("PSS: IRQ error\n");
338 return mem_start;
339 }
340
341 if (!set_dma (devc, CONF_PSS, devc->dma))
342 {
343 printk ("PSS: DRQ error\n");
344 return mem_start;
345 }
346
347 pss_initialized = 1;
348 printk (" <ECHO-PSS Rev. %d>", id);
349
350 return mem_start;
351 }
352
353 int
354 probe_pss_mpu (struct address_info *hw_config)
355 {
356 int timeout;
357
358 if (!pss_initialized)
359 return 0;
360
361 if (!set_io_base (devc, CONF_MIDI, hw_config->io_base))
362 {
363 printk ("PSS: MIDI base error.\n");
364 return 0;
365 }
366
367 if (!set_irq (devc, CONF_MIDI, hw_config->irq))
368 {
369 printk ("PSS: MIDI IRQ error.\n");
370 return 0;
371 }
372
373 if (!pss_synthLen)
374 {
375 printk ("PSS: Can't enable MPU. MIDI synth microcode not available.\n");
376 return 0;
377 }
378
379 if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
380 {
381 printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
382 return 0;
383 }
384
385
386
387
388
389
390 for (timeout = 900000; timeout > 0; timeout--)
391 {
392 if ((INB (hw_config->io_base + 1) & 0x80) == 0)
393 INB (hw_config->io_base);
394 else
395 break;
396 }
397
398 #ifdef EXCLUDE_MIDI
399 return 0
400 #else
401 return probe_mpu401 (hw_config);
402 #endif
403 }
404
405 static int
406 pss_coproc_open (void *dev_info, int sub_device)
407 {
408 switch (sub_device)
409 {
410 case COPR_MIDI:
411
412 if (pss_synthLen == 0)
413 {
414 printk ("PSS: MIDI synth microcode not available.\n");
415 return RET_ERROR (EIO);
416 }
417
418 if (nonstandard_microcode)
419 if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
420 {
421 printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
422 return RET_ERROR (EIO);
423 }
424 nonstandard_microcode = 0;
425 break;
426
427 default:;
428 }
429 return 0;
430 }
431
432 static void
433 pss_coproc_close (void *dev_info, int sub_device)
434 {
435 return;
436 }
437
438 static void
439 pss_coproc_reset (void *dev_info)
440 {
441 if (pss_synthLen)
442 if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
443 {
444 printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
445 }
446 nonstandard_microcode = 0;
447 }
448
449 static int
450 download_boot_block (void *dev_info, copr_buffer * buf)
451 {
452 if (buf->len <= 0 || buf->len > sizeof (buf->data))
453 return RET_ERROR (EINVAL);
454
455 if (!pss_download_boot (devc, buf->data, buf->len, buf->flags))
456 {
457 printk ("PSS: Unable to load microcode block to DSP.\n");
458 return RET_ERROR (EIO);
459 }
460 nonstandard_microcode = 1;
461
462 return 0;
463 }
464
465 static int
466 pss_coproc_ioctl (void *dev_info, unsigned int cmd, unsigned int arg, int local)
467 {
468
469
470 switch (cmd)
471 {
472 case SNDCTL_COPR_RESET:
473 pss_coproc_reset (dev_info);
474 return 0;
475 break;
476
477 case SNDCTL_COPR_LOAD:
478 {
479 copr_buffer *buf;
480 int err;
481
482 buf = (copr_buffer *) KERNEL_MALLOC (sizeof (copr_buffer));
483 IOCTL_FROM_USER ((char *) buf, (char *) arg, 0, sizeof (*buf));
484 err = download_boot_block (dev_info, buf);
485 KERNEL_FREE (buf);
486 return err;
487 }
488 break;
489
490 case SNDCTL_COPR_RDATA:
491 {
492 copr_debug_buf buf;
493 unsigned long flags;
494 unsigned short tmp;
495
496 IOCTL_FROM_USER ((char *) &buf, (char *) arg, 0, sizeof (buf));
497
498 DISABLE_INTR (flags);
499 if (!pss_put_dspword (devc, 0x00d0))
500 {
501 RESTORE_INTR (flags);
502 return RET_ERROR (EIO);
503 }
504
505 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
506 {
507 RESTORE_INTR (flags);
508 return RET_ERROR (EIO);
509 }
510
511 if (!pss_get_dspword (devc, &tmp))
512 {
513 RESTORE_INTR (flags);
514 return RET_ERROR (EIO);
515 }
516
517 buf.parm1 = tmp;
518 RESTORE_INTR (flags);
519
520 IOCTL_TO_USER ((char *) arg, 0, &buf, sizeof (buf));
521 return 0;
522 }
523 break;
524
525 case SNDCTL_COPR_WDATA:
526 {
527 copr_debug_buf buf;
528 unsigned long flags;
529 unsigned short tmp;
530
531 IOCTL_FROM_USER ((char *) &buf, (char *) arg, 0, sizeof (buf));
532
533 DISABLE_INTR (flags);
534 if (!pss_put_dspword (devc, 0x00d1))
535 {
536 RESTORE_INTR (flags);
537 return RET_ERROR (EIO);
538 }
539
540 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
541 {
542 RESTORE_INTR (flags);
543 return RET_ERROR (EIO);
544 }
545
546 tmp = (unsigned int) buf.parm2 & 0xffff;
547 if (!pss_put_dspword (devc, tmp))
548 {
549 RESTORE_INTR (flags);
550 return RET_ERROR (EIO);
551 }
552
553 RESTORE_INTR (flags);
554 return 0;
555 }
556 break;
557
558 case SNDCTL_COPR_WCODE:
559 {
560 copr_debug_buf buf;
561 unsigned long flags;
562 unsigned short tmp;
563
564 IOCTL_FROM_USER ((char *) &buf, (char *) arg, 0, sizeof (buf));
565
566 DISABLE_INTR (flags);
567 if (!pss_put_dspword (devc, 0x00d3))
568 {
569 RESTORE_INTR (flags);
570 return RET_ERROR (EIO);
571 }
572
573 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
574 {
575 RESTORE_INTR (flags);
576 return RET_ERROR (EIO);
577 }
578
579 tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
580 if (!pss_put_dspword (devc, tmp))
581 {
582 RESTORE_INTR (flags);
583 return RET_ERROR (EIO);
584 }
585
586 tmp = (unsigned int) buf.parm2 & 0x00ff;
587 if (!pss_put_dspword (devc, tmp))
588 {
589 RESTORE_INTR (flags);
590 return RET_ERROR (EIO);
591 }
592
593 RESTORE_INTR (flags);
594 return 0;
595 }
596 break;
597
598 case SNDCTL_COPR_RCODE:
599 {
600 copr_debug_buf buf;
601 unsigned long flags;
602 unsigned short tmp;
603
604 IOCTL_FROM_USER ((char *) &buf, (char *) arg, 0, sizeof (buf));
605
606 DISABLE_INTR (flags);
607 if (!pss_put_dspword (devc, 0x00d2))
608 {
609 RESTORE_INTR (flags);
610 return RET_ERROR (EIO);
611 }
612
613 if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
614 {
615 RESTORE_INTR (flags);
616 return RET_ERROR (EIO);
617 }
618
619 if (!pss_get_dspword (devc, &tmp))
620 {
621 RESTORE_INTR (flags);
622 return RET_ERROR (EIO);
623 }
624
625 buf.parm1 = tmp << 8;
626
627 if (!pss_get_dspword (devc, &tmp))
628 {
629 RESTORE_INTR (flags);
630 return RET_ERROR (EIO);
631 }
632
633 buf.parm1 |= tmp & 0x00ff;
634
635 RESTORE_INTR (flags);
636
637 IOCTL_TO_USER ((char *) arg, 0, &buf, sizeof (buf));
638 return 0;
639 }
640 break;
641
642 default:
643 return RET_ERROR (EINVAL);
644 }
645
646 return RET_ERROR (EINVAL);
647 }
648
649 static coproc_operations pss_coproc_operations =
650 {
651 "ADSP-2115",
652 pss_coproc_open,
653 pss_coproc_close,
654 pss_coproc_ioctl,
655 pss_coproc_reset,
656 &pss_data
657 };
658
659 long
660 attach_pss_mpu (long mem_start, struct address_info *hw_config)
661 {
662 int prev_devs;
663 long ret;
664
665 #ifndef EXCLUDE_MIDI
666 prev_devs = num_midis;
667 ret = attach_mpu401 (mem_start, hw_config);
668
669 if (num_midis == (prev_devs + 1))
670 midi_devs[prev_devs]->coproc = &pss_coproc_operations;
671 #endif
672 return ret;
673 }
674
675 int
676 probe_pss_mss (struct address_info *hw_config)
677 {
678 int timeout;
679
680 if (!pss_initialized)
681 return 0;
682
683 if (!set_io_base (devc, CONF_WSS, hw_config->io_base))
684 {
685 printk ("PSS: WSS base error.\n");
686 return 0;
687 }
688
689 if (!set_irq (devc, CONF_WSS, hw_config->irq))
690 {
691 printk ("PSS: WSS IRQ error.\n");
692 return 0;
693 }
694
695 if (!set_dma (devc, CONF_WSS, hw_config->dma))
696 {
697 printk ("PSS: WSS DRQ error\n");
698 return 0;
699 }
700
701
702
703
704
705
706
707 for (timeout = 0;
708 timeout < 100000 && (INB (hw_config->io_base + 3) & 0x3f) != 0x04;
709 timeout++);
710
711 return probe_ms_sound (hw_config);
712 }
713
714 long
715 attach_pss_mss (long mem_start, struct address_info *hw_config)
716 {
717 int prev_devs;
718 long ret;
719
720 prev_devs = num_audiodevs;
721 ret = attach_ms_sound (mem_start, hw_config);
722
723 if (num_audiodevs == (prev_devs + 1))
724 audio_devs[prev_devs]->coproc = &pss_coproc_operations;
725
726 return ret;
727 }
728
729 #endif