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