27 #include <linux/module.h>
249 #define VERSION "1.3"
252 #undef AEDSP16_DEBUG_MORE
255 #if defined(AEDSP16_DEBUG)
256 # define DBG(x) printk x
257 # if defined(AEDSP16_DEBUG_MORE)
258 # define DBG1(x) printk x
276 #define IOBASE_REGION_SIZE 0x10
281 #define DEF_AEDSP16_IOB 0x220
282 #define DEF_AEDSP16_IRQ 7
283 #define DEF_AEDSP16_MRQ 0
284 #define DEF_AEDSP16_DMA 1
290 #define WRITE_MDIRQ_CFG 0x50
291 #define COMMAND_52 0x52
292 #define READ_HARD_CFG 0x58
293 #define COMMAND_5C 0x5c
294 #define COMMAND_60 0x60
295 #define COMMAND_66 0x66
296 #define COMMAND_6C 0x6c
297 #define COMMAND_6E 0x6e
298 #define COMMAND_88 0x88
299 #define DSP_INIT_MSS 0x8c
300 #define COMMAND_C5 0xc5
301 #define GET_DSP_VERSION 0xe1
302 #define GET_DSP_COPYRIGHT 0xe3
313 #define DSP_RESET 0x06
314 #define DSP_READ 0x0a
315 #define DSP_WRITE 0x0c
316 #define DSP_COMMAND 0x0c
317 #define DSP_STATUS 0x0c
318 #define DSP_DATAVAIL 0x0e
322 #define STATUSRETRY 1000
323 #define HARDRETRY 500000
328 #define CARDNAMELEN 15
329 #define CARDVERLEN 10
330 #define CARDVERDIGITS 2
332 #if defined(CONFIG_SC6600)
339 #define IOBASE(xl) ((xl & 0x01)?0x240:0x220)
340 #define JOY(xl) (xl & 0x02)
341 #define MPUADDR(xl) ( \
346 #define WSSADDR(xl) ((xl & 0x10)?0xE80:0x530)
347 #define CDROM(xh) (xh & 0x20)
348 #define CDROMADDR(xh) (((xh & 0x1F) << 4) + 0x200)
352 #define BLDIOBASE(xl, val) { \
357 #define BLDJOY(xl, val) { \
362 #define BLDMPUADDR(xl, val) { \
382 #define BLDWSSADDR(xl, val) { \
387 #define BLDCDROM(xh, val) { \
392 #define BLDCDROMADDR(xh, val) { \
407 #define INIT_NONE (0 )
408 #define INIT_SBPRO (1<<0)
409 #define INIT_MSS (1<<1)
410 #define INIT_MPU401 (1<<2)
417 #if defined(CONFIG_SC6600)
418 static int hard_cfg[2]
422 #if defined(CONFIG_SC6600)
433 static struct d_hcfg decoded_hcfg
__initdata = {0, };
458 static struct orVals orIRQ[] __initdata = {
468 static struct orVals orMIRQ[] __initdata = {
477 static struct orVals orDMA[] __initdata = {
497 static char DSPCopyright[
CARDNAMELEN + 1] __initdata = {0, };
498 static char DSPVersion[
CARDVERLEN + 1] __initdata = {0, };
503 unsigned char ret = 0;
505 DBG1((
"aedsp16_wait_data (0x%x): ", port));
512 }
while (!(ret & 0x80) && loop--);
515 DBG1((
"success.\n"));
519 DBG1((
"failure.\n"));
523 static int __init aedsp16_read(
int port)
527 DBG((
" Read DSP Byte (0x%x): ", port));
529 if (aedsp16_wait_data(port) ==
FALSE) {
536 DBG((
"read [0x%x]/{%c}.\n", inbyte, inbyte));
541 static int __init aedsp16_test_dsp(
int port)
543 return ((aedsp16_read(port) == 0xaa) ?
TRUE :
FALSE);
546 static int __init aedsp16_dsp_reset(
int port)
552 DBG((
"Reset DSP:\n"));
559 if (aedsp16_test_dsp(port) ==
TRUE) {
567 static int __init aedsp16_write(
int port,
int cmd)
572 DBG((
" Write DSP Byte (0x%x) [0x%x]: ", port, cmd));
587 printk(
"[AEDSP16] DSP Command (0x%x) timeout.\n", cmd);
592 #if defined(CONFIG_SC6600)
594 #if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
595 void __init aedsp16_pinfo(
void) {
596 DBG((
"\n Base address: %x\n", decoded_hcfg.iobase));
597 DBG((
" Joystick : %s present\n", decoded_hcfg.joystick?
"":
" not"));
598 DBG((
" WSS addr : %x\n", decoded_hcfg.wssbase));
599 DBG((
" MPU-401 addr: %x\n", decoded_hcfg.mpubase));
600 DBG((
" CDROM : %s present\n", (decoded_hcfg.cdrom!=4)?
"":
" not"));
601 DBG((
" CDROMADDR : %x\n\n", decoded_hcfg.cdrombase));
605 static void __init aedsp16_hard_decode(
void) {
607 DBG((
" aedsp16_hard_decode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
612 decoded_hcfg.iobase =
IOBASE(hard_cfg[0]);
613 decoded_hcfg.joystick = JOY(hard_cfg[0]);
614 decoded_hcfg.wssbase = WSSADDR(hard_cfg[0]);
615 decoded_hcfg.mpubase = MPUADDR(hard_cfg[0]);
616 decoded_hcfg.cdrom = CDROM(hard_cfg[1]);
617 decoded_hcfg.cdrombase = CDROMADDR(hard_cfg[1]);
619 #if defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
620 printk(
" Original sound card configuration:\n");
627 decoded_hcfg.iobase = ae_config.
base_io;
628 decoded_hcfg.wssbase = ae_config.
mss_base;
629 decoded_hcfg.mpubase = ae_config.
mpu_base;
631 #if defined(CONFIG_SC6600_JOY)
632 decoded_hcfg.joystick = CONFIG_SC6600_JOY;
634 #if defined(CONFIG_SC6600_CDROM)
635 decoded_hcfg.cdrom = CONFIG_SC6600_CDROM;
637 #if defined(CONFIG_SC6600_CDROMBASE)
638 decoded_hcfg.cdrombase = CONFIG_SC6600_CDROMBASE;
641 #if defined(AEDSP16_DEBUG)
642 DBG((
" New Values:\n"));
649 static void __init aedsp16_hard_encode(
void) {
651 DBG((
" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
658 BLDIOBASE (hard_cfg[0], decoded_hcfg.iobase);
659 BLDWSSADDR(hard_cfg[0], decoded_hcfg.wssbase);
660 BLDMPUADDR(hard_cfg[0], decoded_hcfg.mpubase);
661 BLDJOY(hard_cfg[0], decoded_hcfg.joystick);
662 BLDCDROM(hard_cfg[1], decoded_hcfg.cdrom);
663 BLDCDROMADDR(hard_cfg[1], decoded_hcfg.cdrombase);
665 #if defined(AEDSP16_DEBUG)
669 DBG((
" aedsp16_hard_encode: 0x%x, 0x%x\n", hard_cfg[0], hard_cfg[1]));
674 static int __init aedsp16_hard_write(
int port) {
676 DBG((
"aedsp16_hard_write:\n"));
688 if (aedsp16_write(port, hard_cfg[0])) {
689 printk(
"[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[0]);
693 if (aedsp16_write(port, hard_cfg[1])) {
694 printk(
"[AEDSP16] DATA 0x%x: failed!\n", hard_cfg[1]);
709 static int __init aedsp16_hard_read(
int port) {
711 DBG((
"aedsp16_hard_read:\n"));
719 if ((hard_cfg[0] = aedsp16_read(port)) == -1) {
720 printk(
"[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
725 if ((hard_cfg[1] = aedsp16_read(port)) == -1) {
726 printk(
"[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
731 if (aedsp16_read(port) == -1) {
732 printk(
"[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
743 static int __init aedsp16_ext_cfg_write(
int port) {
753 if (decoded_hcfg.cdrom != 2)
755 if ((decoded_hcfg.cdrom == 4) ||
756 (decoded_hcfg.cdrom == 3))
758 if (decoded_hcfg.cdrombase == 0)
760 if (decoded_hcfg.mpubase == 0)
763 if (aedsp16_write(port, extcfg)) {
764 printk(
"[AEDSP16] Write extcfg: failed!\n");
767 if (aedsp16_write(port, 0)) {
768 printk(
"[AEDSP16] Write extcfg: failed!\n");
771 if (decoded_hcfg.cdrom == 3) {
776 if ((val = aedsp16_read(port)) == -1) {
777 printk(
"[AEDSP16] aedsp16_read after CMD 0x%x: failed\n"
786 if (aedsp16_write(port, val)) {
787 printk(
"[AEDSP16] Write val: failed!\n");
797 static int __init aedsp16_cfg_write(
int port) {
802 if (aedsp16_write(port, soft_cfg)) {
803 printk(
"[AEDSP16] Initialization of (M)IRQ and DMA: failed!\n");
809 static int __init aedsp16_init_mss(
int port)
811 DBG((
"aedsp16_init_mss:\n"));
816 printk(
"[AEDSP16] aedsp16_init_mss [0x%x]: failed!\n",
824 if (aedsp16_cfg_write(port) ==
FALSE)
834 static int __init aedsp16_setup_board(
int port) {
837 #if defined(CONFIG_SC6600)
840 if (aedsp16_hard_read(port) ==
FALSE) {
841 printk(
"[AEDSP16] aedsp16_hard_read: failed!\n");
850 if ((val = aedsp16_read(port)) == -1) {
851 printk(
"[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
863 }
while ((aedsp16_wait_data(port) ==
FALSE) && loop--);
865 if (aedsp16_read(port) == -1) {
866 printk(
"[AEDSP16] aedsp16_read after CMD 0x%x: failed\n",
871 #if !defined(CONFIG_SC6600)
878 if (aedsp16_cfg_write(port) ==
FALSE)
881 #if defined(CONFIG_SC6600)
886 if (aedsp16_write(port, val)) {
887 printk(
"[AEDSP16] DATA 0x%x: failed!\n", val);
894 if (aedsp16_write(port,
ver[0])) {
895 printk(
"[AEDSP16] DATA 0x%x: failed!\n",
ver[0]);
898 if (aedsp16_write(port,
ver[1])) {
899 printk(
"[AEDSP16] DATA 0x%x: failed!\n",
ver[1]);
903 if (aedsp16_hard_write(port) ==
FALSE) {
904 printk(
"[AEDSP16] aedsp16_hard_write: failed!\n");
913 #if defined(THIS_IS_A_THING_I_HAVE_NOT_TESTED_YET)
914 if (aedsp16_cfg_write(port) ==
FALSE)
923 static int __init aedsp16_stdcfg(
int port) {
931 if (aedsp16_write(port, 0x0A)) {
932 printk(
"[AEDSP16] aedsp16_stdcfg: failed!\n");
938 static int __init aedsp16_dsp_version(
int port)
943 DBG((
"Get DSP Version:\n"));
952 if ((ret = aedsp16_read(port)) == -1) {
969 static int __init aedsp16_dsp_copyright(
int port)
974 DBG((
"Get DSP Copyright:\n"));
983 if ((ret = aedsp16_read(port)) == -1) {
996 DSPCopyright[len++] =
ret;
1000 DBG((
"success.\n"));
1005 static void __init aedsp16_init_tables(
void)
1012 for (i = 0; orIRQ[
i].or; i++)
1013 if (orIRQ[i].val == ae_config.
irq) {
1014 soft_cfg |= orIRQ[
i].or;
1015 soft_cfg_mss |= orIRQ[
i].or;
1018 for (i = 0; orMIRQ[
i].or; i++)
1020 soft_cfg |= orMIRQ[
i].or;
1022 for (i = 0; orDMA[
i].or; i++)
1023 if (orDMA[i].val == ae_config.
dma) {
1024 soft_cfg |= orDMA[
i].or;
1025 soft_cfg_mss |= orDMA[
i].or;
1029 static int __init aedsp16_init_board(
void)
1031 aedsp16_init_tables();
1034 printk(
"[AEDSP16] aedsp16_dsp_reset: failed!\n");
1037 if (aedsp16_dsp_copyright(ae_config.
base_io) ==
FALSE) {
1038 printk(
"[AEDSP16] aedsp16_dsp_copyright: failed!\n");
1046 if (
strcmp(
"SC-6000", DSPCopyright))
1047 printk(
"[AEDSP16] Warning: non SC-6000 audio card!\n");
1050 printk(
"[AEDSP16] aedsp16_dsp_version: failed!\n");
1055 printk(
"[AEDSP16] aedsp16_stdcfg: failed!\n");
1059 #if defined(CONFIG_SC6600)
1061 printk(
"[AEDSP16] aedsp16_hard_read: failed!\n");
1065 aedsp16_hard_decode();
1067 aedsp16_hard_encode();
1070 printk(
"[AEDSP16] aedsp16_hard_write: failed!\n");
1074 if (aedsp16_ext_cfg_write(ae_config.
base_io) ==
FALSE) {
1075 printk(
"[AEDSP16] aedsp16_ext_cfg_write: failed!\n");
1081 printk(
"[AEDSP16] aedsp16_setup_board: failed!\n");
1088 printk(
"[AEDSP16] Can not initialize"
1089 "Microsoft Sound System mode.\n");
1095 #if !defined(MODULE) || defined(AEDSP16_INFO) || defined(AEDSP16_DEBUG)
1097 printk(
"Audio Excel DSP 16 init v%s (%s %s) [",
1130 static int __init init_aedsp16_sb(
void)
1132 DBG((
"init_aedsp16_sb: "));
1150 static void uninit_aedsp16_sb(
void)
1152 DBG((
"uninit_aedsp16_sb: "));
1159 static int __init init_aedsp16_mss(
void)
1161 DBG((
"init_aedsp16_mss: "));
1177 "aedsp16 (base)")) {
1179 "AEDSP16 BASE I/O port region is already in use.\n");
1191 static void uninit_aedsp16_mss(
void)
1193 DBG((
"uninit_aedsp16_mss: "));
1198 DBG((
"AEDSP16 base region released.\n"));
1205 static int __init init_aedsp16_mpu(
void)
1207 DBG((
"init_aedsp16_mpu: "));
1218 "aedsp16 (base)")) {
1220 "AEDSP16 BASE I/O port region is already in use.\n");
1232 static void uninit_aedsp16_mpu(
void)
1234 DBG((
"uninit_aedsp16_mpu: "));
1239 DBG((
"AEDSP16 base region released.\n"));
1247 static int __init init_aedsp16(
void)
1251 DBG((
"Initializing BASE[0x%x] IRQ[%d] DMA[%d] MIRQ[%d]\n",
1255 if (init_aedsp16_sb() ==
FALSE) {
1256 uninit_aedsp16_sb();
1263 if (init_aedsp16_mpu() ==
FALSE) {
1264 uninit_aedsp16_mpu();
1277 if (init_aedsp16_mss() ==
FALSE) {
1278 uninit_aedsp16_mss();
1285 initialized = aedsp16_init_board();
1289 static void __exit uninit_aedsp16(
void)
1292 uninit_aedsp16_mss();
1294 uninit_aedsp16_sb();
1296 uninit_aedsp16_mpu();
1299 static int __initdata
io = -1;
1300 static int __initdata
irq = -1;
1301 static int __initdata
dma = -1;
1302 static int __initdata
mpu_irq = -1;
1303 static int __initdata
mss_base = -1;
1304 static int __initdata
mpu_base = -1;
1315 MODULE_PARM_DESC(mss_base,
"MSS emulation I/O base address (0x530 0xE80)");
1317 MODULE_PARM_DESC(mpu_base,
"MPU-401 I/O base address (0x300 0x310 0x320 0x330)");
1322 static int __init do_init_aedsp16(
void) {
1323 printk(
"Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98\n");
1324 if (io == -1 || dma == -1 || irq == -1) {
1337 if (init_aedsp16() ==
FALSE) {
1348 static void __exit cleanup_aedsp16(
void) {
1356 static int __init setup_aedsp16(
char *
str)
1372 __setup(
"aedsp16=", setup_aedsp16);