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