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#include <linux/config.h>
27#include <linux/delay.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include "sound_config.h"
31
32
33
34
35
36#if defined(CONFIG_SOUND_AEDSP16_SBPRO) && defined(CONFIG_SOUND_AEDSP16_MSS)
37#error You have to enable only one of the MSS and SBPRO emulations.
38#endif
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258#define VERSION "1.3"
259
260#undef AEDSP16_DEBUG
261#undef AEDSP16_DEBUG_MORE
262#undef AEDSP16_INFO
263
264#if defined(AEDSP16_DEBUG)
265# define DBG(x) printk x
266# if defined(AEDSP16_DEBUG_MORE)
267# define DBG1(x) printk x
268# else
269# define DBG1(x)
270# endif
271#else
272# define DBG(x)
273# define DBG1(x)
274#endif
275
276
277
278
279#define TRUE 1
280#define FALSE 0
281
282
283
284
285#define IOBASE_REGION_SIZE 0x10
286
287
288
289
290#define DEF_AEDSP16_IOB 0x220
291#define DEF_AEDSP16_IRQ 7
292#define DEF_AEDSP16_MRQ 0
293#define DEF_AEDSP16_DMA 1
294
295
296
297
298
299#define WRITE_MDIRQ_CFG 0x50
300#define COMMAND_52 0x52
301#define READ_HARD_CFG 0x58
302#define COMMAND_5C 0x5c
303#define COMMAND_60 0x60
304#define COMMAND_66 0x66
305#define COMMAND_6C 0x6c
306#define COMMAND_6E 0x6e
307#define COMMAND_88 0x88
308#define DSP_INIT_MSS 0x8c
309#define COMMAND_C5 0xc5
310#define GET_DSP_VERSION 0xe1
311#define GET_DSP_COPYRIGHT 0xe3
312
313
314
315
316
317
318
319
320
321
322#define DSP_RESET 0x06
323#define DSP_READ 0x0a
324#define DSP_WRITE 0x0c
325#define DSP_COMMAND 0x0c
326#define DSP_STATUS 0x0c
327#define DSP_DATAVAIL 0x0e
328
329
330#define RETRY 10
331#define STATUSRETRY 1000
332#define HARDRETRY 500000
333
334
335
336
337#define CARDNAMELEN 15
338#define CARDVERLEN 2
339
340#if defined(CONFIG_SC6600)
341
342
343
344
345
346
347#define IOBASE(xl) ((xl & 0x01)?0x240:0x220)
348#define JOY(xl) (xl & 0x02)
349#define MPUADDR(xl) ( \
350 (xl & 0x0C)?0x330: \
351 (xl & 0x08)?0x320: \
352 (xl & 0x04)?0x310: \
353 0x300)
354#define WSSADDR(xl) ((xl & 0x10)?0xE80:0x530)
355#define CDROM(xh) (xh & 0x20)
356#define CDROMADDR(xh) (((xh & 0x1F) << 4) + 0x200)
357
358
359
360#define BLDIOBASE(xl, val) { \
361 xl &= ~0x01; \
362 if (val == 0x240) \
363 xl |= 0x01; \
364 }
365#define BLDJOY(xl, val) { \
366 xl &= ~0x02; \
367 if (val == 1) \
368 xl |= 0x02; \
369 }
370#define BLDMPUADDR(xl, val) { \
371 xl &= ~0x0C; \
372 switch (val) { \
373 case 0x330: \
374 xl |= 0x0C; \
375 break; \
376 case 0x320: \
377 xl |= 0x08; \
378 break; \
379 case 0x310: \
380 xl |= 0x04; \
381 break; \
382 case 0x300: \
383 xl |= 0x00; \
384 break; \
385 default: \
386 xl |= 0x00; \
387 break; \
388 } \
389 }
390#define BLDWSSADDR(xl, val) { \
391 xl &= ~0x10; \
392 if (val == 0xE80) \
393 xl |= 0x10; \
394 }
395#define BLDCDROM(xh, val) { \
396 xh &= ~0x20; \
397 if (val == 1) \
398 xh |= 0x20; \
399 }
400#define BLDCDROMADDR(xh, val) { \
401 int tmp = val; \
402 tmp -= 0x200; \
403 tmp >>= 4; \
404 tmp &= 0x1F; \
405 xh |= tmp; \
406 xh &= 0x7F; \
407 xh |= 0x40; \
408 }
409#endif
410
411
412
413
414
415#define INIT_NONE (0 )
416#define INIT_SBPRO (1<<0)
417#define INIT_MSS (1<<1)
418#define INIT_MPU401 (1<<2)
419
420static int soft_cfg __initdata = 0;
421static int soft_cfg_mss __initdata = 0;
422static int ver[CARDVERLEN] __initdata = {0, 0};
423
424
425#if defined(CONFIG_SC6600)
426static int hard_cfg[2]
427 __initdata = { 0, 0};
428#endif
429
430#if defined(CONFIG_SC6600)
431
432struct d_hcfg {
433 int iobase;
434 int joystick;
435 int mpubase;
436 int wssbase;
437 int cdrom;
438 int cdrombase;
439};
440
441struct d_hcfg decoded_hcfg __initdata = {0, };
442
443#endif
444
445
446struct orVals {
447 int val;
448 int or;
449};
450
451
452struct aedsp16_info {
453 int base_io;
454 int irq;
455 int mpu_irq;
456 int dma;
457 int mss_base;
458 int mpu_base;
459 int init;
460};
461
462
463
464
465
466static struct orVals orIRQ[] __initdata = {
467 {0x05, 0x28},
468 {0x07, 0x08},
469 {0x09, 0x10},
470 {0x0a, 0x18},
471 {0x0b, 0x20},
472 {0x00, 0x00}
473};
474
475
476static struct orVals orMIRQ[] __initdata = {
477 {0x05, 0x04},
478 {0x07, 0x44},
479 {0x09, 0x84},
480 {0x0a, 0xc4},
481 {0x00, 0x00}
482};
483
484
485static struct orVals orDMA[] __initdata = {
486 {0x00, 0x01},
487 {0x01, 0x02},
488 {0x03, 0x03},
489 {0x00, 0x00}
490};
491
492static struct aedsp16_info ae_config __initdata = {
493 DEF_AEDSP16_IOB,
494 DEF_AEDSP16_IRQ,
495 DEF_AEDSP16_MRQ,
496 DEF_AEDSP16_DMA,
497 -1,
498 -1,
499 INIT_NONE
500};
501
502
503
504
505static char DSPCopyright[CARDNAMELEN + 1] __initdata = {0, };
506static char DSPVersion[CARDVERLEN + 1] __initdata = {0, };
507
508static int __init aedsp16_wait_data(int port)
509{
510 int loop = STATUSRETRY;
511 unsigned char ret = 0;
512
513 DBG1(("aedsp16_wait_data (0x%x): ", port));
514
515 do {
516 ret = inb(port + DSP_DATAVAIL);
517
518
519
520 } while (!(ret & 0x80) && loop--);
521
522 if (ret & 0x80) {
523 DBG1(("success.\n"));
524 return TRUE;
525 }
526
527 DBG1(("failure.\n"));
528 return FALSE;
529}
530
531static int __init aedsp16_read(int port)
532{
533 int inbyte;
534
535 DBG((" Read DSP Byte (0x%x): ", port));
536
537 if (aedsp16_wait_data(port) == FALSE) {
538 DBG(("failure.\n"));
539 return -1;
540 }
541
542 inbyte = inb(port + DSP_READ);
543
544 DBG(("read [0x%x]/{%c}.\n", inbyte, inbyte));
545
546 return inbyte;
547}
548
549static int __init aedsp16_test_dsp(int port)
550{
551 return ((aedsp16_read(port) == 0xaa) ? TRUE : FALSE);
552}
553
554static int __init aedsp16_dsp_reset(int port)
555{
556
557
558
559
560 DBG(("Reset DSP:\n"));
561
562 outb(1, (port + DSP_RESET));
563 udelay(10);
564 outb(0, (port + DSP_RESET));
565 udelay(10);
566 udelay(10);
567 if (aedsp16_test_dsp(port) == TRUE) {
568 DBG(("success.\n"));
569 return TRUE;
570 } else
571 DBG(("failure.\n"));
572 return FALSE;
573}
574
575static int __init aedsp16_write(int port, int cmd)
576{
577 unsigned char ret;
578 int loop = HARDRETRY;
579
580 DBG((" Write DSP Byte (0x%x) [0x%x]: ", port, cmd));
581
582 do {
583 ret = inb(port + DSP_STATUS);
584
585
586
587 if (!(ret & 0x80)) {
588 outb(cmd, port + DSP_COMMAND);
589 DBG(("success.\n"));
590 return 0;
591 }
592 } while (loop--);
593
594 DBG(("timeout.\n"));
595 printk("[AEDSP16] DSP Command (0x%x) timeout.\n", cmd);
596
597 return -1;
598}
599
600#if defined(CONFIG_SC6600)
601
602#if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
603void __init aedsp16_pinfo(void) {
604 DBG(("\n Base address: %x\n", decoded_hcfg.iobase));
605 DBG((" Joystick : %s present\n", decoded_hcfg.joystick?"":" not"));
606 DBG((" WSS addr : %x\n", decoded_hcfg.wssbase));
607 DBG((" MPU-401 addr: %x\n", decoded_hcfg.mpubase));
608 DBG((" CDROM : %s present\n", (decoded_hcfg.cdrom!=4)?"":" not"));
609 DBG((" CDROMADDR : %x\n\n", decoded_hcfg.cdrombase));
610}
611#endif
612
613void __init aedsp16_hard_decode(void) {
614
615 DBG((" aedsp16_hard_decode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
616
617
618
619
620 decoded_hcfg.iobase = IOBASE(hard_cfg[0]);
621 decoded_hcfg.joystick = JOY(hard_cfg[0]);
622 decoded_hcfg.wssbase = WSSADDR(hard_cfg[0]);
623 decoded_hcfg.mpubase = MPUADDR(hard_cfg[0]);
624 decoded_hcfg.cdrom = CDROM(hard_cfg[1]);
625 decoded_hcfg.cdrombase = CDROMADDR(hard_cfg[1]);
626
627#if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
628 printk(" Original sound card configuration:\n");
629 aedsp16_pinfo();
630#endif
631
632
633
634
635 decoded_hcfg.iobase = ae_config.base_io;
636 decoded_hcfg.wssbase = ae_config.mss_base;
637 decoded_hcfg.mpubase = ae_config.mpu_base;
638
639#if defined(CONFIG_SC6600_JOY)
640 decoded_hcfg.joystick = CONFIG_SC6600_JOY;
641#endif
642#if defined(CONFIG_SC6600_CDROM)
643 decoded_hcfg.cdrom = CONFIG_SC6600_CDROM;
644#endif
645#if defined(CONFIG_SC6600_CDROMBASE)
646 decoded_hcfg.cdrombase = CONFIG_SC6600_CDROMBASE;
647#endif
648
649#if defined(AEDSP16_DEBUG)
650 DBG((" New Values:\n"));
651 aedsp16_pinfo();
652#endif
653
654 DBG(("success.\n"));
655}
656
657void __init aedsp16_hard_encode(void) {
658
659 DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
660
661 hard_cfg[0] = 0;
662 hard_cfg[1] = 0;
663
664 hard_cfg[0] |= 0x20;
665
666 BLDIOBASE (hard_cfg[0], decoded_hcfg.iobase);
667 BLDWSSADDR(hard_cfg[0], decoded_hcfg.wssbase);
668 BLDMPUADDR(hard_cfg[0], decoded_hcfg.mpubase);
669 BLDJOY(hard_cfg[0], decoded_hcfg.joystick);
670 BLDCDROM(hard_cfg[1], decoded_hcfg.cdrom);
671 BLDCDROMADDR(hard_cfg[1], decoded_hcfg.cdrombase);
672
673#if defined(AEDSP16_DEBUG)
674 aedsp16_pinfo();
675#endif
676
677 DBG((" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
678 DBG(("success.\n"));
679
680}
681
682static int __init aedsp16_hard_write(int port) {
683
684 DBG(("aedsp16_hard_write:\n"));
685
686 if (aedsp16_write(port, COMMAND_6C)) {
687 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_6C);
688 DBG(("failure.\n"));
689 return FALSE;
690 }
691 if (aedsp16_write(port, COMMAND_5C)) {
692 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
693 DBG(("failure.\n"));
694 return FALSE;
695 }
696 if (aedsp16_write(port, hard_cfg[0])) {
697 printk("[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[0]);
698 DBG(("failure.\n"));
699 return FALSE;
700 }
701 if (aedsp16_write(port, hard_cfg[1])) {
702 printk("[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[1]);
703 DBG(("failure.\n"));
704 return FALSE;
705 }
706 if (aedsp16_write(port, COMMAND_C5)) {
707 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_C5);
708 DBG(("failure.\n"));
709 return FALSE;
710 }
711
712 DBG(("success.\n"));
713
714 return TRUE;
715}
716
717static int __init aedsp16_hard_read(int port) {
718
719 DBG(("aedsp16_hard_read:\n"));
720
721 if (aedsp16_write(port, READ_HARD_CFG)) {
722 printk("[AEDSP16] CMD 0x%x: failed!\n", READ_HARD_CFG);
723 DBG(("failure.\n"));
724 return FALSE;
725 }
726
727 if ((hard_cfg[0] = aedsp16_read(port)) == -1) {
728 printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
729 READ_HARD_CFG);
730 DBG(("failure.\n"));
731 return FALSE;
732 }
733 if ((hard_cfg[1] = aedsp16_read(port)) == -1) {
734 printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
735 READ_HARD_CFG);
736 DBG(("failure.\n"));
737 return FALSE;
738 }
739 if (aedsp16_read(port) == -1) {
740 printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
741 READ_HARD_CFG);
742 DBG(("failure.\n"));
743 return FALSE;
744 }
745
746 DBG(("success.\n"));
747
748 return TRUE;
749}
750
751static int __init aedsp16_ext_cfg_write(int port) {
752
753 int extcfg, val;
754
755 if (aedsp16_write(port, COMMAND_66)) {
756 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_66);
757 return FALSE;
758 }
759
760 extcfg = 7;
761 if (decoded_hcfg.cdrom != 2)
762 extcfg = 0x0F;
763 if ((decoded_hcfg.cdrom == 4) ||
764 (decoded_hcfg.cdrom == 3))
765 extcfg &= ~2;
766 if (decoded_hcfg.cdrombase == 0)
767 extcfg &= ~2;
768 if (decoded_hcfg.mpubase == 0)
769 extcfg &= ~1;
770
771 if (aedsp16_write(port, extcfg)) {
772 printk("[AEDSP16] Write extcfg: failed!\n");
773 return FALSE;
774 }
775 if (aedsp16_write(port, 0)) {
776 printk("[AEDSP16] Write extcfg: failed!\n");
777 return FALSE;
778 }
779 if (decoded_hcfg.cdrom == 3) {
780 if (aedsp16_write(port, COMMAND_52)) {
781 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_52);
782 return FALSE;
783 }
784 if ((val = aedsp16_read(port)) == -1) {
785 printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n"
786 , COMMAND_52);
787 return FALSE;
788 }
789 val &= 0x7F;
790 if (aedsp16_write(port, COMMAND_60)) {
791 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_60);
792 return FALSE;
793 }
794 if (aedsp16_write(port, val)) {
795 printk("[AEDSP16] Write val: failed!\n");
796 return FALSE;
797 }
798 }
799
800 return TRUE;
801}
802
803#endif
804
805static int __init aedsp16_cfg_write(int port) {
806 if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
807 printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
808 return FALSE;
809 }
810 if (aedsp16_write(port, soft_cfg)) {
811 printk("[AEDSP16] Initialization of (M)IRQ and DMA: failed!\n");
812 return FALSE;
813 }
814 return TRUE;
815}
816
817static int __init aedsp16_init_mss(int port)
818{
819 DBG(("aedsp16_init_mss:\n"));
820
821 mdelay(10);
822
823 if (aedsp16_write(port, DSP_INIT_MSS)) {
824 printk("[AEDSP16] aedsp16_init_mss [0x%x]: failed!\n",
825 DSP_INIT_MSS);
826 DBG(("failure.\n"));
827 return FALSE;
828 }
829
830 mdelay(10);
831
832 if (aedsp16_cfg_write(port) == FALSE)
833 return FALSE;
834
835 outb(soft_cfg_mss, ae_config.mss_base);
836
837 DBG(("success.\n"));
838
839 return TRUE;
840}
841
842static int __init aedsp16_setup_board(int port) {
843 int loop = RETRY;
844
845#if defined(CONFIG_SC6600)
846 int val = 0;
847
848 if (aedsp16_hard_read(port) == FALSE) {
849 printk("[AEDSP16] aedsp16_hard_read: failed!\n");
850 return FALSE;
851 }
852
853 if (aedsp16_write(port, COMMAND_52)) {
854 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_52);
855 return FALSE;
856 }
857
858 if ((val = aedsp16_read(port)) == -1) {
859 printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
860 COMMAND_52);
861 return FALSE;
862 }
863#endif
864
865 do {
866 if (aedsp16_write(port, COMMAND_88)) {
867 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_88);
868 return FALSE;
869 }
870 mdelay(10);
871 } while ((aedsp16_wait_data(port) == FALSE) && loop--);
872
873 if (aedsp16_read(port) == -1) {
874 printk("[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
875 COMMAND_88);
876 return FALSE;
877 }
878
879#if !defined(CONFIG_SC6600)
880 if (aedsp16_write(port, COMMAND_5C)) {
881 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
882 return FALSE;
883 }
884#endif
885
886 if (aedsp16_cfg_write(port) == FALSE)
887 return FALSE;
888
889#if defined(CONFIG_SC6600)
890 if (aedsp16_write(port, COMMAND_60)) {
891 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_60);
892 return FALSE;
893 }
894 if (aedsp16_write(port, val)) {
895 printk("[AEDSP16] DATA 0x%x: failed!\n", val);
896 return FALSE;
897 }
898 if (aedsp16_write(port, COMMAND_6E)) {
899 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_6E);
900 return FALSE;
901 }
902 if (aedsp16_write(port, ver[0])) {
903 printk("[AEDSP16] DATA 0x%x: failed!\n", ver[0]);
904 return FALSE;
905 }
906 if (aedsp16_write(port, ver[1])) {
907 printk("[AEDSP16] DATA 0x%x: failed!\n", ver[1]);
908 return FALSE;
909 }
910
911 if (aedsp16_hard_write(port) == FALSE) {
912 printk("[AEDSP16] aedsp16_hard_write: failed!\n");
913 return FALSE;
914 }
915
916 if (aedsp16_write(port, COMMAND_5C)) {
917 printk("[AEDSP16] CMD 0x%x: failed!\n", COMMAND_5C);
918 return FALSE;
919 }
920
921#if defined(THIS_IS_A_THING_I_HAVE_NOT_TESTED_YET)
922 if (aedsp16_cfg_write(port) == FALSE)
923 return FALSE;
924#endif
925
926#endif
927
928 return TRUE;
929}
930
931static int __init aedsp16_stdcfg(int port) {
932 if (aedsp16_write(port, WRITE_MDIRQ_CFG)) {
933 printk("[AEDSP16] CMD 0x%x: failed!\n", WRITE_MDIRQ_CFG);
934 return FALSE;
935 }
936
937
938
939 if (aedsp16_write(port, 0x0A)) {
940 printk("[AEDSP16] aedsp16_stdcfg: failed!\n");
941 return FALSE;
942 }
943 return TRUE;
944}
945
946static int __init aedsp16_dsp_version(int port)
947{
948 int len = 0;
949 int ret;
950
951 DBG(("Get DSP Version:\n"));
952
953 if (aedsp16_write(ae_config.base_io, GET_DSP_VERSION)) {
954 printk("[AEDSP16] CMD 0x%x: failed!\n", GET_DSP_VERSION);
955 DBG(("failed.\n"));
956 return FALSE;
957 }
958
959 do {
960 if ((ret = aedsp16_read(port)) == -1) {
961 DBG(("failed.\n"));
962 return FALSE;
963 }
964
965
966
967
968 ver[len++] = ret;
969 } while (len < CARDVERLEN);
970 sprintf(DSPVersion, "%d.%d", ver[0], ver[1]);
971
972 DBG(("success.\n"));
973
974 return TRUE;
975}
976
977static int __init aedsp16_dsp_copyright(int port)
978{
979 int len = 0;
980 int ret;
981
982 DBG(("Get DSP Copyright:\n"));
983
984 if (aedsp16_write(ae_config.base_io, GET_DSP_COPYRIGHT)) {
985 printk("[AEDSP16] CMD 0x%x: failed!\n", GET_DSP_COPYRIGHT);
986 DBG(("failed.\n"));
987 return FALSE;
988 }
989
990 do {
991 if ((ret = aedsp16_read(port)) == -1) {
992
993
994
995
996 if (len)
997 break;
998 else {
999 DBG(("failed.\n"));
1000 return FALSE;
1001 }
1002 }
1003
1004 DSPCopyright[len++] = ret;
1005
1006 } while (len < CARDNAMELEN);
1007
1008 DBG(("success.\n"));
1009
1010 return TRUE;
1011}
1012
1013static void __init aedsp16_init_tables(void)
1014{
1015 int i = 0;
1016
1017 memset(DSPCopyright, 0, CARDNAMELEN + 1);
1018 memset(DSPVersion, 0, CARDVERLEN + 1);
1019
1020 for (i = 0; orIRQ[i].or; i++)
1021 if (orIRQ[i].val == ae_config.irq) {
1022 soft_cfg |= orIRQ[i].or;
1023 soft_cfg_mss |= orIRQ[i].or;
1024 }
1025
1026 for (i = 0; orMIRQ[i].or; i++)
1027 if (orMIRQ[i].or == ae_config.mpu_irq)
1028 soft_cfg |= orMIRQ[i].or;
1029
1030 for (i = 0; orDMA[i].or; i++)
1031 if (orDMA[i].val == ae_config.dma) {
1032 soft_cfg |= orDMA[i].or;
1033 soft_cfg_mss |= orDMA[i].or;
1034 }
1035}
1036
1037static int __init aedsp16_init_board(void)
1038{
1039 aedsp16_init_tables();
1040
1041 if (aedsp16_dsp_reset(ae_config.base_io) == FALSE) {
1042 printk("[AEDSP16] aedsp16_dsp_reset: failed!\n");
1043 return FALSE;
1044 }
1045 if (aedsp16_dsp_copyright(ae_config.base_io) == FALSE) {
1046 printk("[AEDSP16] aedsp16_dsp_copyright: failed!\n");
1047 return FALSE;
1048 }
1049
1050
1051
1052
1053
1054 if (strcmp("SC-6000", DSPCopyright))
1055 printk("[AEDSP16] Warning: non SC-6000 audio card!\n");
1056
1057 if (aedsp16_dsp_version(ae_config.base_io) == FALSE) {
1058 printk("[AEDSP16] aedsp16_dsp_version: failed!\n");
1059 return FALSE;
1060 }
1061
1062 if (aedsp16_stdcfg(ae_config.base_io) == FALSE) {
1063 printk("[AEDSP16] aedsp16_stdcfg: failed!\n");
1064 return FALSE;
1065 }
1066
1067#if defined(CONFIG_SC6600)
1068 if (aedsp16_hard_read(ae_config.base_io) == FALSE) {
1069 printk("[AEDSP16] aedsp16_hard_read: failed!\n");
1070 return FALSE;
1071 }
1072
1073 aedsp16_hard_decode();
1074
1075 aedsp16_hard_encode();
1076
1077 if (aedsp16_hard_write(ae_config.base_io) == FALSE) {
1078 printk("[AEDSP16] aedsp16_hard_write: failed!\n");
1079 return FALSE;
1080 }
1081
1082 if (aedsp16_ext_cfg_write(ae_config.base_io) == FALSE) {
1083 printk("[AEDSP16] aedsp16_ext_cfg_write: failed!\n");
1084 return FALSE;
1085 }
1086#endif
1087
1088 if (aedsp16_setup_board(ae_config.base_io) == FALSE) {
1089 printk("[AEDSP16] aedsp16_setup_board: failed!\n");
1090 return FALSE;
1091 }
1092
1093 if (ae_config.mss_base != -1) {
1094 if (ae_config.init & INIT_MSS) {
1095 if (aedsp16_init_mss(ae_config.base_io) == FALSE) {
1096 printk("[AEDSP16] Can not initialize"
1097 "Microsoft Sound System mode.\n");
1098 return FALSE;
1099 }
1100 }
1101 }
1102
1103#if !defined(MODULE) || defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
1104
1105 printk("Audio Excel DSP 16 init v%s (%s %s) [",
1106 VERSION, DSPCopyright,
1107 DSPVersion);
1108
1109 if (ae_config.mpu_base != -1) {
1110 if (ae_config.init & INIT_MPU401) {
1111 printk("MPU401");
1112 if ((ae_config.init & INIT_MSS) ||
1113 (ae_config.init & INIT_SBPRO))
1114 printk(" ");
1115 }
1116 }
1117
1118 if (ae_config.mss_base == -1) {
1119 if (ae_config.init & INIT_SBPRO) {
1120 printk("SBPro");
1121 if (ae_config.init & INIT_MSS)
1122 printk(" ");
1123 }
1124 }
1125
1126 if (ae_config.mss_base != -1)
1127 if (ae_config.init & INIT_MSS)
1128 printk("MSS");
1129
1130 printk("]\n");
1131#endif
1132
1133 mdelay(10);
1134
1135 return TRUE;
1136}
1137
1138static int __init init_aedsp16_sb(void)
1139{
1140 DBG(("init_aedsp16_sb: "));
1141
1142
1143
1144
1145
1146 if (ae_config.init & INIT_MSS)
1147 return FALSE;
1148 if (ae_config.init & INIT_SBPRO)
1149 return FALSE;
1150
1151 ae_config.init |= INIT_SBPRO;
1152
1153 DBG(("done.\n"));
1154
1155 return TRUE;
1156}
1157
1158static void __init uninit_aedsp16_sb(void)
1159{
1160 DBG(("uninit_aedsp16_sb: "));
1161
1162 ae_config.init &= ~INIT_SBPRO;
1163
1164 DBG(("done.\n"));
1165}
1166
1167static int __init init_aedsp16_mss(void)
1168{
1169 DBG(("init_aedsp16_mss: "));
1170
1171
1172
1173
1174
1175 if (ae_config.init & INIT_SBPRO)
1176 return FALSE;
1177 if (ae_config.init & INIT_MSS)
1178 return FALSE;
1179
1180
1181
1182
1183 if (!(ae_config.init & INIT_MPU401)) {
1184 if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
1185 "aedsp16 (base)")) {
1186 printk(
1187 "AEDSP16 BASE I/O port region is already in use.\n");
1188 return FALSE;
1189 }
1190 }
1191
1192 ae_config.init |= INIT_MSS;
1193
1194 DBG(("done.\n"));
1195
1196 return TRUE;
1197}
1198
1199static void __init uninit_aedsp16_mss(void)
1200{
1201 DBG(("uninit_aedsp16_mss: "));
1202
1203 if ((!(ae_config.init & INIT_MPU401)) &&
1204 (ae_config.init & INIT_MSS)) {
1205 release_region(ae_config.base_io, IOBASE_REGION_SIZE);
1206 DBG(("AEDSP16 base region released.\n"));
1207 }
1208
1209 ae_config.init &= ~INIT_MSS;
1210 DBG(("done.\n"));
1211}
1212
1213static int __init init_aedsp16_mpu(void)
1214{
1215 DBG(("init_aedsp16_mpu: "));
1216
1217 if (ae_config.init & INIT_MPU401)
1218 return FALSE;
1219
1220
1221
1222
1223
1224 if (!(ae_config.init & (INIT_MSS | INIT_SBPRO))) {
1225 if (!request_region(ae_config.base_io, IOBASE_REGION_SIZE,
1226 "aedsp16 (base)")) {
1227 printk(
1228 "AEDSP16 BASE I/O port region is already in use.\n");
1229 return FALSE;
1230 }
1231 }
1232
1233 ae_config.init |= INIT_MPU401;
1234
1235 DBG(("done.\n"));
1236
1237 return TRUE;
1238}
1239
1240static void __init uninit_aedsp16_mpu(void)
1241{
1242 DBG(("uninit_aedsp16_mpu: "));
1243
1244 if ((!(ae_config.init & (INIT_MSS | INIT_SBPRO))) &&
1245 (ae_config.init & INIT_MPU401)) {
1246 release_region(ae_config.base_io, IOBASE_REGION_SIZE);
1247 DBG(("AEDSP16 base region released.\n"));
1248 }
1249
1250 ae_config.init &= ~INIT_MPU401;
1251
1252 DBG(("done.\n"));
1253}
1254
1255int __init init_aedsp16(void)
1256{
1257 int initialized = FALSE;
1258
1259 DBG(("Initializing BASE[0x%x] IRQ[%d] DMA[%d] MIRQ[%d]\n",
1260 ae_config.base_io,ae_config.irq,ae_config.dma,ae_config.mpu_irq));
1261
1262 if (ae_config.mss_base == -1) {
1263 if (init_aedsp16_sb() == FALSE) {
1264 uninit_aedsp16_sb();
1265 } else {
1266 initialized = TRUE;
1267 }
1268 }
1269
1270 if (ae_config.mpu_base != -1) {
1271 if (init_aedsp16_mpu() == FALSE) {
1272 uninit_aedsp16_mpu();
1273 } else {
1274 initialized = TRUE;
1275 }
1276 }
1277
1278
1279
1280
1281
1282
1283
1284 if (ae_config.mss_base != -1) {
1285 if (init_aedsp16_mss() == FALSE) {
1286 uninit_aedsp16_mss();
1287 } else {
1288 initialized = TRUE;
1289 }
1290 }
1291
1292 if (initialized)
1293 initialized = aedsp16_init_board();
1294 return initialized;
1295}
1296
1297void __init uninit_aedsp16(void)
1298{
1299 if (ae_config.mss_base != -1)
1300 uninit_aedsp16_mss();
1301 else
1302 uninit_aedsp16_sb();
1303 if (ae_config.mpu_base != -1)
1304 uninit_aedsp16_mpu();
1305}
1306
1307static int __initdata io = -1;
1308static int __initdata irq = -1;
1309static int __initdata dma = -1;
1310static int __initdata mpu_irq = -1;
1311static int __initdata mss_base = -1;
1312static int __initdata mpu_base = -1;
1313
1314MODULE_PARM(io, "i");
1315MODULE_PARM_DESC(io, "I/O base address (0x220 0x240)");
1316MODULE_PARM(irq, "i");
1317MODULE_PARM_DESC(irq, "IRQ line (5 7 9 10 11)");
1318MODULE_PARM(dma, "i");
1319MODULE_PARM_DESC(dma, "dma line (0 1 3)");
1320MODULE_PARM(mpu_irq, "i");
1321MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ line (5 7 9 10 0)");
1322MODULE_PARM(mss_base, "i");
1323MODULE_PARM_DESC(mss_base, "MSS emulation I/O base address (0x530 0xE80)");
1324MODULE_PARM(mpu_base, "i");
1325MODULE_PARM_DESC(mpu_base,"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
1326MODULE_AUTHOR("Riccardo Facchetti <fizban@tin.it>");
1327MODULE_DESCRIPTION("Audio Excel DSP 16 Driver Version " VERSION);
1328MODULE_LICENSE("GPL");
1329
1330static int __init do_init_aedsp16(void) {
1331 printk("Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
1332 if (io == -1 || dma == -1 || irq == -1) {
1333 printk(KERN_INFO "aedsp16: I/O, IRQ and DMA are mandatory\n");
1334 return -EINVAL;
1335 }
1336
1337 ae_config.base_io = io;
1338 ae_config.irq = irq;
1339 ae_config.dma = dma;
1340
1341 ae_config.mss_base = mss_base;
1342 ae_config.mpu_base = mpu_base;
1343 ae_config.mpu_irq = mpu_irq;
1344
1345 if (init_aedsp16() == FALSE) {
1346 printk(KERN_ERR "aedsp16: initialization failed\n");
1347
1348
1349
1350
1351 return -EINVAL;
1352 }
1353 return 0;
1354}
1355
1356static void __exit cleanup_aedsp16(void) {
1357 uninit_aedsp16();
1358}
1359
1360module_init(do_init_aedsp16);
1361module_exit(cleanup_aedsp16);
1362
1363#ifndef MODULE
1364static int __init setup_aedsp16(char *str)
1365{
1366
1367 int ints[7];
1368
1369 str = get_options(str, ARRAY_SIZE(ints), ints);
1370
1371 io = ints[1];
1372 irq = ints[2];
1373 dma = ints[3];
1374 mss_base = ints[4];
1375 mpu_base = ints[5];
1376 mpu_irq = ints[6];
1377 return 1;
1378}
1379
1380__setup("aedsp16=", setup_aedsp16);
1381#endif
1382