/* * PnP soundcard support is not included in this version. * * AESDP16 driver is now included in the lowlevel directory. */ #define DISABLED_OPTIONS (B(OPT_SPNP)|B(OPT_AEDSP16)|B(OPT_UNUSED1)|B(OPT_UNUSED2)|B(OPT_UNUSED3)|B(OPT_UNUSED4)|B(OPT_UNUSED5)|B(OPT_UART6850)) /* * sound/configure.c - Configuration program for the Linux Sound Driver */ /* * Copyright (C) by Hannu Savolainen 1993-1997 * * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ #include #include #include #include #include #define B(x) (1 << (x)) /* * Option numbers */ #define OPT_PAS 0 #define OPT_SB 1 #define OPT_ADLIB 2 #define OPT_LAST_MUTUAL 2 #define OPT_GUS 3 #define OPT_MPU401 4 #define OPT_UART6850 5 #define OPT_PSS 6 #define OPT_GUS16 7 #define OPT_GUSMAX 8 #define OPT_MSS 9 #define OPT_SSCAPE 10 #define OPT_TRIX 11 #define OPT_MAD16 12 #define OPT_CS4232 13 #define OPT_MAUI 14 #define OPT_SPNP 15 #define OPT_OPL3SA1 16 #define OPT_SOFTOSS 17 #define OPT_HIGHLEVEL 18 /* This must be same than the next one */ #define OPT_UNUSED1 18 #define OPT_UNUSED2 19 #define OPT_AEDSP16 20 #define OPT_UNUSED3 21 #define OPT_UNUSED4 22 #define OPT_UNUSED5 23 #define OPT_YM3812_AUTO 24 #define OPT_YM3812 25 #define OPT_LAST 25 /* Last defined OPT number */ #define DUMMY_OPTS (B(OPT_YM3812_AUTO)) #define ANY_DEVS (B(OPT_SB)|B(OPT_PAS)|B(OPT_GUS)| \ B(OPT_MPU401)|B(OPT_PSS)|B(OPT_GUS16)|B(OPT_GUSMAX)| \ B(OPT_MSS)|B(OPT_SSCAPE)|B(OPT_UART6850)|B(OPT_TRIX)| \ B(OPT_MAD16)|B(OPT_CS4232)|B(OPT_MAUI)|B(OPT_ADLIB)| \ B(OPT_SPNP)|B(OPT_OPL3SA1)|B(OPT_SOFTOSS)) #define MPU_DEVS (B(OPT_PSS)|\ B(OPT_CS4232)|B(OPT_SPNP)|B(OPT_MAUI)|B(OPT_SSCAPE)) #define UART401_DEVS (SBDSP_DEVS|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_SPNP)|\ B(OPT_OPL3SA1)) #define NON_AUDIO_CARDS (B(OPT_ADLIB)|B(OPT_MPU401)|B(OPT_UART6850)|B(OPT_MAUI)) #define AUDIO_CARDS (ANY_DEVS & ~NON_AUDIO_CARDS) #define MIDI_CARDS (ANY_DEVS & ~(B(OPT_ADLIB)|B(OPT_MSS))) #define AD1848_DEVS (B(OPT_GUS16)|B(OPT_MSS)|B(OPT_PSS)|B(OPT_GUSMAX)|\ B(OPT_SSCAPE)|B(OPT_TRIX)|B(OPT_MAD16)|B(OPT_CS4232)|\ B(OPT_SPNP)|B(OPT_OPL3SA1)) #define SBDSP_DEVS (B(OPT_SB)|B(OPT_SPNP)|B(OPT_MAD16)|B(OPT_TRIX)) #define SEQUENCER_DEVS 0x7fffffff /* * Options that have been disabled for some reason (incompletely implemented * and/or tested). Don't remove from this list before looking at file * experimental.txt for further info. */ typedef struct { unsigned long conditions; unsigned long exclusive_options; char macro[20]; int verify; int alias; int default_answ; } hw_entry; /* * The rule table for the driver options. The first field defines a set of * options which must be selected before this entry can be selected. The * second field is a set of options which are not allowed with this one. If * the fourth field is zero, the option is selected without asking * confirmation from the user. * * With this version of the rule table it is possible to select just one type of * hardware. * * NOTE! Keep the following table and the questions array in sync with the * option numbering! */ hw_entry hw_table[] = { /* * 0 */ {0, 0, "PAS", 1, 0, 0}, {0, 0, "SB", 1, 0, 0}, {0, B(OPT_PAS) | B(OPT_SB), "ADLIB", 1, 0, 0}, {0, 0, "GUS", 1, 0, 0}, {0, 0, "MPU401", 1, 0, 0}, {0, 0, "UART6850", 1, 0, 0}, {0, 0, "PSS", 1, 0, 0}, {B(OPT_GUS), 0, "GUS16", 1, 0, 0}, {B(OPT_GUS), B(OPT_GUS16), "GUSMAX", 1, 0, 0}, {0, 0, "MSS", 1, 0, 0}, {0, 0, "SSCAPE", 1, 0, 0}, {0, 0, "TRIX", 1, 0, 0}, {0, 0, "MAD16", 1, 0, 0}, {0, 0, "CS4232", 1, 0, 0}, {0, 0, "MAUI", 1, 0, 0}, {0, 0, "SPNP", 1, 0, 0}, {0, 0, "OPL3SA1", 1, 0, 0}, {0, 0, "SOFTOSS", 1, 0, 0}, {B(OPT_SB), B(OPT_PAS), "UNUSED1", 1, 0, 1}, {B(OPT_SB) | B(OPT_UNUSED1), B(OPT_PAS), "UNUSED2", 1, 0, 1}, {B(OPT_UNUSED1) | B(OPT_MSS) | B(OPT_MPU401), 0, "AEDSP16", 1, 0, 0}, {AUDIO_CARDS, 0, "UNUSED3", 1, 0, 1}, {B(OPT_MPU401) | B(OPT_MAUI), 0, "UNUSED4", 0, 0, 0}, {MIDI_CARDS, 0, "UNUSED5", 1, 0, 1}, {B(OPT_ADLIB), 0, "YM3812_AUTO", 0, OPT_YM3812, 0}, {B(OPT_PSS) | B(OPT_SB) | B(OPT_PAS) | B(OPT_ADLIB) | B(OPT_MSS) | B(OPT_PSS), B(OPT_YM3812_AUTO), "YM3812", 1, 0, 1} }; char *questions[] = { "ProAudioSpectrum 16 support", "100%% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support", "Generic OPL2/OPL3 FM synthesizer support", "Gravis Ultrasound support", "MPU-401 support (NOT for SB16)", "6850 UART Midi support", "PSS (ECHO-ADI2111) support", "16 bit sampling option of GUS (_NOT_ GUS MAX)", "GUS MAX support", "Microsoft Sound System support", "Ensoniq SoundScape support", "MediaTrix AudioTrix Pro support", "Support for OPTi MAD16 and/or Mozart based cards", "Support for Crystal CS4232 based (PnP) cards", "Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers", "Support for PnP sound cards (_EXPERIMENTAL_)", "Yamaha OPL3-SA1 audio controller", "SoftOSS software wave table engine", "*** Unused option 1 ***", "*** Unused option 2 ***", "Audio Excel DSP 16 initialization support", "*** Unused option 3 ***", "*** Unused option 4 ***", "*** Unused option 5 ***", "This should not be asked", "FM synthesizer (YM3812/OPL-3) support", "Is the sky really falling" }; /* help text for each option */ char *help[] = { "Enable this option only if you have a Pro Audio Spectrum 16,\n" "Pro Audio Studio 16, or Logitech SoundMan 16. Don't enable this if\n" "you have some other card made by MediaVision or Logitech as\n" "they are not PAS16 compatible.\n", "Enable this if you have an original Sound Blaster card made by\n" "Creative Labs or a 100%% hardware compatible clone. For an\n" "unknown card you may want to try this if it claims to be\n" "Sound Blaster compatible.\n", "Enable this option if your sound card has a Yamaha OPL2 or OPL3\n" "FM synthesizer chip.\n", "Enable this option for any type of Gravis Ultrasound card\n" "including the GUS or GUS MAX.\n", "The MPU401 interface is supported by almost all sound cards. However,\n" "some natively supported cards have their own driver for\n" "MPU401. Enabling the MPU401 option with these cards will cause a\n" "conflict. Also enabling MPU401 on a system that doesn't really have a\n" "MPU401 could cause some trouble. It's safe to enable this if you have a\n" "true MPU401 MIDI interface card.\n", "This option enables support for MIDI interfaces based on the 6850\n" "UART chip. This interface is rarely found on sound cards.\n", "Enable this option if you have an Orchid SW32, Cardinal DSP16 or other\n" "sound card based on the PSS chipset (AD1848 codec, ADSP-2115 DSP chip,\n" "and Echo ESC614 ASIC CHIP).\n", "Enable this if you have installed the 16-bit sampling daughtercard on\n" "your GUS card. Do not use if you have a GUS MAX as enabling this option\n" "disables GUS MAX support.\n", "Enable this option if you have a Gravis Ultrasound MAX sound\n" "card\n", "Enable this option if you have the original Windows Sound System\n" "card made by Microsoft or the Aztech SG 16 Pro or NX16 Pro.\n", "Enable this if you have a sound card based on the Ensoniq\n" "SoundScape chipset. Such cards are being manufactured by Ensoniq,\n" "Spea and Reveal (Reveal makes other cards as well).\n", "Enable this option if you have the AudioTrix Pro sound card\n" "manufactured by MediaTrix.\n", "Enable this if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi\n" "82C928 or 82C929) audio interface chip. These chips are currently\n" "quite common so it's possible that many no-name cards have one of\n" "them. In addition the MAD16 chip is used in some cards made by known\n" "manufacturers such as Turtle Beach (Tropez), Reveal (some models) and\n" "Diamond (latest ones).\n", "Enable this if you have a card based on the Crystal CS4232 chip set.\n", "Enable this option if you have a Turtle Beach Wave Front, Maui,\n" "or Tropez sound card.\n", "Use this option to enable experimental support for cards that\n" "use the Plug and Play protocol.\n", "Use this option with Yamaha OPL3-SA1 (YMF701) chip.\n", "SoftOSS is a virtual wave table engine by 4Front Technologies. It can\n" "be used together with any 16 bit stereo soundcard.\n" "Enable this option if your card is a Sound Blaster Pro or\n" "Sound Blaster 16. It also works with many Sound Blaster Pro clones.\n", "Enable this if you have a Sound Blaster 16, including the AWE32.\n", "Enable this if you have an Audio Excel DSP16 card. See the file\n" "Readme.aedsp16 for more information.\n", "This option enables the A/D and D/A converter (PCM) devices\n" "supported by almost all sound cards.\n", "This should not be asked", "This enables the dev/midixx devices and access to any MIDI ports\n" "using /dev/sequencer and /dev/music. This option also affects any\n" "MPU401 and/or General MIDI compatible devices.\n", "This should not be asked", "This enables the Yamaha FM synthesizer chip used on many sound\n" "cards.\n", "Is the sky really falling" }; struct kludge { char *name; int mask; } extra_options[] = { { "MPU_EMU", MPU_DEVS } , { "AD1848", AD1848_DEVS } , { "SBDSP", SBDSP_DEVS } , { "UART401", UART401_DEVS } , { "GUSHW", B(OPT_GUS) | B(OPT_SPNP) } , { "SSCAPEHW", B(OPT_SSCAPE) | B(OPT_SPNP) } , { "SEQUENCER", SEQUENCER_DEVS } , { "AUDIO", AUDIO_CARDS } , { "MIDI", MIDI_CARDS } , { NULL, 0 } }; char *oldconf = "/etc/soundconf"; int old_config_used = 0; int def_size, sb_base = 0; unsigned long selected_options = 0; int sb_dma = 0; int dump_only = 0; void build_defines(void); #include "hex2hex.h" int bin2hex(char *path, char *target, char *varname); int can_select_option(int nr) { if (hw_table[nr].conditions) if (!(hw_table[nr].conditions & selected_options)) return 0; if (hw_table[nr].exclusive_options) if (hw_table[nr].exclusive_options & selected_options) return 0; if (DISABLED_OPTIONS & B(nr)) return 0; return 1; } int think_positively(char *prompt, int def_answ, char *help) { char answ[512]; int len; response: fprintf(stderr, prompt); if (def_answ) fprintf(stderr, " [Y/n/?] "); else fprintf(stderr, " [N/y/?] "); if ((len = read(0, answ, sizeof(answ))) < 1) { fprintf(stderr, "\n\nERROR! Cannot read stdin\n"); perror("stdin"); printf("invalid_configuration__run_make_config_again\n"); exit(-1); } if (len < 2) /* * There is an additional LF at the end */ return def_answ; if (answ[0] == '?') { /* display help message */ fprintf(stderr, "\n"); fprintf(stderr, help); fprintf(stderr, "\n"); goto response; } answ[len - 1] = 0; if (!strcmp(answ, "y") || !strcmp(answ, "Y")) return 1; return 0; } int ask_value(char *format, int default_answer) { char answ[512]; int len, num; play_it_again_Sam: if ((len = read(0, answ, sizeof(answ))) < 1) { fprintf(stderr, "\n\nERROR! Cannot read stdin\n"); perror("stdin"); printf("invalid_configuration__run_make_config_again\n"); exit(-1); } if (len < 2) /* * There is an additional LF at the end */ return default_answer; answ[len - 1] = 0; if (sscanf(answ, format, &num) != 1) { fprintf(stderr, "Illegal format. Try again: "); goto play_it_again_Sam; } return num; } #define FMT_HEX 1 #define FMT_INT 2 void show_comment(int mask, char *txt) { int i; if (dump_only) { for (i = 0; i < OPT_LAST; i++) if (mask == B(i)) { printf("\n\nif [ \"$CONFIG_%s\" = \"y\" ]; then\n", hw_table[i].macro); printf("comment '%s'\n", txt); printf("fi\n"); } } else { if (!(mask & selected_options)) return; fprintf(stderr, "%s\n", txt); } } void ask_int_choice(int mask, char *macro, char *question, int format, int defa, char *choices) { int num, i; if (dump_only) { for (i = 0; i < OPT_LAST; i++) if (mask == B(i)) { unsigned int j; for (j = 0; j < strlen(choices); j++) if (choices[j] == '\'') choices[j] = '_'; printf("\nif [ \"$CONFIG_%s\" = \"y\" ]; then\n", hw_table[i].macro); if (format == FMT_INT) printf("int '%s %s' %s %d\n", question, choices, macro, defa); else printf("hex '%s %s' %s %x\n", question, choices, macro, defa); printf("fi\n"); } } else { if (!(mask & selected_options)) return; fprintf(stderr, "\n%s\n", question); if (strcmp(choices, "")) fprintf(stderr, "Possible values are: %s\n", choices); if (format == FMT_INT) { if (defa == -1) fprintf(stderr, "\t(-1 disables this feature)\n"); fprintf(stderr, "The default value is %d\n", defa); fprintf(stderr, "Enter the value: "); num = ask_value("%d", defa); if (num == -1) return; fprintf(stderr, "%s set to %d.\n", question, num); printf("#define %s %d\n", macro, num); } else { if (defa == 0) fprintf(stderr, "\t(0 disables this feature)\n"); fprintf(stderr, "The default value is %x\n", defa); fprintf(stderr, "Enter the value: "); num = ask_value("%x", defa); if (num == 0) return; fprintf(stderr, "%s set to %x.\n", question, num); printf("#define %s 0x%x\n", macro, num); } } } void rebuild_file(char *line) { char *method, *next, *old, *var, *p; method = p = line; while (*p && *p != ' ') p++; *p++ = 0; old = p; while (*p && *p != ' ') p++; *p++ = 0; next = p; while (*p && *p != ' ') p++; *p++ = 0; var = p; while (*p && *p != ' ') p++; *p++ = 0; fprintf(stderr, "Rebuilding file `%s' (%s %s)\n", next, method, old); if (strcmp(method, "bin2hex") == 0) { if (!bin2hex(old, next, var)) { fprintf(stderr, "Rebuild failed\n"); exit(-1); } } else if (strcmp(method, "hex2hex") == 0) { if (!hex2hex(old, next, var)) { fprintf(stderr, "Rebuild failed\n"); exit(-1); } } else { fprintf(stderr, "Failed to build `%s' - unknown method %s\n", next, method); exit(-1); } } int use_old_config(char *filename) { char buf[1024]; int i = 0; FILE *oldf; fprintf(stderr, "Copying old configuration from `%s'\n", filename); if ((oldf = fopen(filename, "r")) == NULL) { fprintf(stderr, "Couldn't open previous configuration file\n"); perror(filename); return 0; } while (fgets(buf, 1024, oldf) != NULL) { char tmp[100]; if (buf[0] != '#') { printf("%s", buf); strncpy(tmp, buf, 8); tmp[8] = 0; if (strcmp(tmp, "/*build ") == 0) rebuild_file(&buf[8]); continue; } strncpy(tmp, buf, 8); tmp[8] = 0; if (strcmp(tmp, "#define ") == 0) { char *id = &buf[8]; i = 0; while (id[i] && id[i] != ' ' && id[i] != '\t' && id[i] != '\n') i++; strncpy(tmp, id, i); tmp[i] = 0; if (strcmp(tmp, "SELECTED_SOUND_OPTIONS") == 0) continue; if (strcmp(tmp, "KERNEL_SOUNDCARD") == 0) continue; if (strcmp(tmp, "JAZZ_DMA16") == 0) /* Rename it (hack) */ { printf("#define SB_DMA2 %s\n", &buf[18]); continue; } if (strcmp(tmp, "SB16_DMA") == 0) /* Rename it (hack) */ { printf("#define SB_DMA2 %s\n", &buf[16]); continue; } tmp[8] = 0; /* Truncate the string */ if (strcmp(tmp, "EXCLUDE_") == 0) continue; /* Skip excludes */ strncpy(tmp, id, i); tmp[7] = 0; /* Truncate the string */ if (strcmp(tmp, "CONFIG_") == 0) { strncpy(tmp, &id[7], i - 7); tmp[i - 7] = 0; for (i = 0; i <= OPT_LAST; i++) if (strcmp(hw_table[i].macro, tmp) == 0) { selected_options |= (1 << i); break; } continue; } printf("%s", buf); continue; } if (strcmp(tmp, "#undef ") == 0) { char *id = &buf[8]; i = 0; while (id[i] && id[i] != ' ' && id[i] != '\t' && id[i] != '\n') i++; strncpy(tmp, id, i); tmp[7] = 0; /* Truncate the string */ if (strcmp(tmp, "CONFIG_") == 0) continue; strncpy(tmp, id, i); tmp[8] = 0; /* Truncate the string */ if (strcmp(tmp, "EXCLUDE_") != 0) continue; /* Not a #undef EXCLUDE_ line */ strncpy(tmp, &id[8], i - 8); tmp[i - 8] = 0; for (i = 0; i <= OPT_LAST; i++) if (strcmp(hw_table[i].macro, tmp) == 0) { selected_options |= (1 << i); break; } continue; } printf("%s", buf); } fclose(oldf); for (i = 0; i <= OPT_LAST; i++) if (!hw_table[i].alias) if (selected_options & B(i)) printf("#define CONFIG_%s\n", hw_table[i].macro); else printf("#undef CONFIG_%s\n", hw_table[i].macro); printf("\n"); i = 0; while (extra_options[i].name != NULL) { if (selected_options & extra_options[i].mask) printf("#define CONFIG_%s\n", extra_options[i].name); else printf("#undef CONFIG_%s\n", extra_options[i].name); i++; } printf("\n"); printf("#define SELECTED_SOUND_OPTIONS\t0x%08x\n", selected_options); fprintf(stderr, "Old configuration copied.\n"); build_defines(); old_config_used = 1; return 1; } void build_defines(void) { FILE *optf; int i; if ((optf = fopen(".defines", "w")) == NULL) { perror(".defines"); exit(-1); } for (i = 0; i <= OPT_LAST; i++) if (!hw_table[i].alias) if (selected_options & B(i)) fprintf(optf, "CONFIG_%s=y\n", hw_table[i].macro); fprintf(optf, "\n"); i = 0; while (extra_options[i].name != NULL) { if (selected_options & extra_options[i].mask) fprintf(optf, "CONFIG_%s=y\n", extra_options[i].name); i++; } fprintf(optf, "\n"); fclose(optf); } void ask_parameters(void) { int num; build_defines(); /* * IRQ and DMA settings */ ask_int_choice(B(OPT_AEDSP16), "AEDSP16_BASE", "I/O base for Audio Excel DSP 16", FMT_HEX, 0x220, "220 or 240"); ask_int_choice(B(OPT_SB), "SBC_BASE", "I/O base for SB", FMT_HEX, 0x220, "Check from manual of the card"); ask_int_choice(B(OPT_SB), "SBC_IRQ", "Sound Blaster IRQ", FMT_INT, 7, "Check from manual of the card"); ask_int_choice(B(OPT_SB), "SBC_DMA", "Sound Blaster DMA", FMT_INT, 1, "0, 1 or 3"); ask_int_choice(B(OPT_SB), "SB_DMA2", "Sound Blaster 16 bit DMA (SB16, Jazz16, SMW)", FMT_INT, 5, "5, 6 or 7 (use 1 for 8 bit cards)"); ask_int_choice(B(OPT_SB), "SB_MPU_BASE", "MPU401 I/O base of SB16, Jazz16 and ES1688", FMT_HEX, 0x330, "Check from manual of the card"); show_comment(B(OPT_SB), "MPU401 IRQ is only required with Jazz16, SM Wave and ESS1688."); show_comment(B(OPT_SB), "Enter -1 to the following question if you have something else such as SB16/32."); ask_int_choice(B(OPT_SB), "SB_MPU_IRQ", "SB MPU401 IRQ (Jazz16, SM Wave and ES1688)", FMT_INT, -1, "Check from manual of the card"); ask_int_choice(B(OPT_PAS), "PAS_IRQ", "PAS16 IRQ", FMT_INT, 10, "3, 4, 5, 7, 9, 10, 11, 12, 14 or 15"); ask_int_choice(B(OPT_PAS), "PAS_DMA", "PAS16 DMA", FMT_INT, 3, "0, 1, 3, 5, 6 or 7"); if (selected_options & B(OPT_PAS)) { if (think_positively("Enable Joystick port on ProAudioSpectrum", 0, "Enable this option if you want to use the joystick port provided\n" "on the PAS sound card.\n")) printf("#define PAS_JOYSTICK_ENABLE\n"); if (think_positively("Enable PAS16 bus clock option", 0, "The PAS16 can be noisy with some motherboards. There is a command\n" "line switch (:T?) in the DOS driver for PAS16 which solves this.\n" "Don't enable this feature unless you have problems and have to use\n" "this switch with DOS\n")) printf("#define BROKEN_BUS_CLOCK\n"); if (think_positively("Disable SB mode of PAS16", 0, "You should disable SB emulation of PAS16 if you want to use\n" "Another SB compatible card in the same system\n")) printf("#define DISABLE_SB_EMULATION\n"); } ask_int_choice(B(OPT_GUS), "GUS_BASE", "I/O base for GUS", FMT_HEX, 0x220, "210, 220, 230, 240, 250 or 260"); ask_int_choice(B(OPT_GUS), "GUS_IRQ", "GUS IRQ", FMT_INT, 15, "3, 5, 7, 9, 11, 12 or 15"); ask_int_choice(B(OPT_GUS), "GUS_DMA", "GUS DMA", FMT_INT, 6, "1, 3, 5, 6 or 7"); ask_int_choice(B(OPT_GUS), "GUS_DMA2", "Second DMA channel for GUS", FMT_INT, -1, "1, 3, 5, 6 or 7"); ask_int_choice(B(OPT_GUS16), "GUS16_BASE", "I/O base for the 16 bit daughtercard of GUS", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_GUS16), "GUS16_IRQ", "GUS 16 bit daughtercard IRQ", FMT_INT, 7, "3, 4, 5, 7, or 9"); ask_int_choice(B(OPT_GUS16), "GUS16_DMA", "GUS DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_MPU401), "MPU_BASE", "I/O base for MPU401", FMT_HEX, 0x330, "Check from manual of the card"); ask_int_choice(B(OPT_MPU401), "MPU_IRQ", "MPU401 IRQ", FMT_INT, 9, "Check from manual of the card"); if (dump_only) show_comment(B(OPT_MAUI), "ERROR! You have to use old sound configuration method with Maui."); ask_int_choice(B(OPT_MAUI), "MAUI_BASE", "I/O base for Maui", FMT_HEX, 0x330, "210, 230, 260, 290, 300, 320, 338 or 330"); ask_int_choice(B(OPT_MAUI), "MAUI_IRQ", "Maui IRQ", FMT_INT, 9, "5, 9, 12 or 15"); ask_int_choice(B(OPT_UART6850), "U6850_BASE", "I/O base for UART 6850 MIDI port", FMT_HEX, 0, "(Unknown)"); ask_int_choice(B(OPT_UART6850), "U6850_IRQ", "UART6850 IRQ", FMT_INT, -1, "(Unknown)"); if (dump_only) show_comment(B(OPT_PSS), "ERROR! You have to use old sound configuration method with PSS cards."); ask_int_choice(B(OPT_PSS), "PSS_BASE", "PSS I/O base", FMT_HEX, 0x220, "220 or 240"); ask_int_choice(B(OPT_PSS), "PSS_MSS_BASE", "PSS audio I/O base", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_PSS), "PSS_MSS_IRQ", "PSS audio IRQ", FMT_INT, 11, "7, 9, 10 or 11"); ask_int_choice(B(OPT_PSS), "PSS_MSS_DMA", "PSS audio DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_PSS), "PSS_MPU_BASE", "PSS MIDI I/O base", FMT_HEX, 0x330, ""); ask_int_choice(B(OPT_PSS), "PSS_MPU_IRQ", "PSS MIDI IRQ", FMT_INT, 9, "3, 4, 5, 7 or 9"); ask_int_choice(B(OPT_MSS), "MSS_BASE", "MSS/WSS I/O base", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_MSS), "MSS_IRQ", "MSS/WSS IRQ", FMT_INT, 11, "7, 9, 10 or 11"); ask_int_choice(B(OPT_MSS), "MSS_DMA", "MSS/WSS DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_MSS), "MSS_DMA2", "MSS/WSS second DMA (if possible)", FMT_INT, -1, "0, 1 or 3"); ask_int_choice(B(OPT_SSCAPE), "SSCAPE_BASE", "SoundScape MIDI I/O base", FMT_HEX, 0x330, "320, 330, 340 or 350"); ask_int_choice(B(OPT_SSCAPE), "SSCAPE_IRQ", "SoundScape MIDI IRQ", FMT_INT, 9, ""); ask_int_choice(B(OPT_SSCAPE), "SSCAPE_DMA", "SoundScape initialization DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_SSCAPE), "SSCAPE_MSS_BASE", "SoundScape audio I/O base", FMT_HEX, 0x534, "534, 608, E84 or F44"); ask_int_choice(B(OPT_SSCAPE), "SSCAPE_MSS_IRQ", "SoundScape audio IRQ", FMT_INT, 11, "7, 9, 10 or 11"); if (selected_options & B(OPT_SSCAPE)) { int reveal_spea; reveal_spea = think_positively( "Is your SoundScape card made/marketed by Reveal or Spea", 0, "Enable if you have a SoundScape card with the Reveal or\n" "Spea name on it.\n"); if (reveal_spea) printf("#define REVEAL_SPEA\n"); } if (dump_only) show_comment(B(OPT_TRIX), "ERROR! You have to use old sound configuration method with OPL3-SA1."); ask_int_choice(B(OPT_TRIX), "TRIX_BASE", "OPL3-SA1 audio I/O base", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_TRIX), "TRIX_IRQ", "OPL3-SA1 audio IRQ", FMT_INT, 11, "7, 9, 10 or 11"); ask_int_choice(B(OPT_TRIX), "TRIX_DMA", "OPL3-SA1 audio DMA", FMT_INT, 0, "0, 1 or 3"); ask_int_choice(B(OPT_TRIX), "TRIX_DMA2", "OPL3-SA1 second (duplex) DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_TRIX), "TRIX_MPU_BASE", "OPL3-SA1 MIDI I/O base", FMT_HEX, 0x330, "330, 370, 3B0 or 3F0"); ask_int_choice(B(OPT_TRIX), "TRIX_MPU_IRQ", "OPL3-SA1 MIDI IRQ", FMT_INT, 9, "3, 4, 5, 7 or 9"); ask_int_choice(B(OPT_TRIX), "TRIX_SB_BASE", "OPL3-SA1 SB I/O base", FMT_HEX, 0x220, "220, 210, 230, 240, 250, 260 or 270"); ask_int_choice(B(OPT_TRIX), "TRIX_SB_IRQ", "OPL3-SA1 SB IRQ", FMT_INT, 7, "3, 4, 5 or 7"); ask_int_choice(B(OPT_TRIX), "TRIX_SB_DMA", "OPL3-SA1 SB DMA", FMT_INT, 1, "1 or 3"); ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_BASE", "OPL3-SA1 audio I/O base", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_IRQ", "OPL3-SA1 audio IRQ", FMT_INT, 11, "7, 9, 10 or 11"); ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_DMA", "OPL3-SA1 audio DMA", FMT_INT, 0, "0, 1 or 3"); ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_DMA2", "OPL3-SA1 second (duplex) DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_MPU_BASE", "OPL3-SA1 MIDI I/O base", FMT_HEX, 0x330, "330, 370, 3B0 or 3F0"); ask_int_choice(B(OPT_OPL3SA1), "OPL3SA1_MPU_IRQ", "OPL3-SA1 MIDI IRQ", FMT_INT, 9, "3, 4, 5, 7 or 9"); ask_int_choice(B(OPT_CS4232), "CS4232_BASE", "CS4232 audio I/O base", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_CS4232), "CS4232_IRQ", "CS4232 audio IRQ", FMT_INT, 11, "5, 7, 9, 11, 12 or 15"); ask_int_choice(B(OPT_CS4232), "CS4232_DMA", "CS4232 audio DMA", FMT_INT, 0, "0, 1 or 3"); ask_int_choice(B(OPT_CS4232), "CS4232_DMA2", "CS4232 second (duplex) DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_CS4232), "CS4232_MPU_BASE", "CS4232 MIDI I/O base", FMT_HEX, 0x330, "330, 370, 3B0 or 3F0"); ask_int_choice(B(OPT_CS4232), "CS4232_MPU_IRQ", "CS4232 MIDI IRQ", FMT_INT, 9, "5, 7, 9, 11, 12 or 15"); ask_int_choice(B(OPT_MAD16), "MAD16_BASE", "MAD16 audio I/O base", FMT_HEX, 0x530, "530, 604, E80 or F40"); ask_int_choice(B(OPT_MAD16), "MAD16_IRQ", "MAD16 audio IRQ", FMT_INT, 11, "7, 9, 10 or 11"); ask_int_choice(B(OPT_MAD16), "MAD16_DMA", "MAD16 audio DMA", FMT_INT, 3, "0, 1 or 3"); ask_int_choice(B(OPT_MAD16), "MAD16_DMA2", "MAD16 second (duplex) DMA", FMT_INT, 0, "0, 1 or 3"); ask_int_choice(B(OPT_MAD16), "MAD16_MPU_BASE", "MAD16 MIDI I/O base", FMT_HEX, 0x330, "300, 310, 320 or 330 (0 disables)"); ask_int_choice(B(OPT_MAD16), "MAD16_MPU_IRQ", "MAD16 MIDI IRQ", FMT_INT, 9, "5, 7, 9 or 10"); ask_int_choice(B(OPT_SOFTOSS), "SOFTOSS_RATE", "Sampling rate for SoftOSS", FMT_INT, 22050, "8000 to 48000"); ask_int_choice(B(OPT_SOFTOSS), "SOFTOSS_VOICES", "Max # of concurrent voices for SoftOSS", FMT_INT, 32, "4 to 32"); } void dump_script(void) { int i; for (i = 0; i <= OPT_LAST; i++) if (!(DUMMY_OPTS & B(i))) if (!(DISABLED_OPTIONS & B(i))) { printf("bool '%s' CONFIG_%s\n", questions[i], hw_table[i].macro); } /* * Some "hardcoded" options */ dump_only = 1; selected_options = 0; ask_parameters(); printf("#\n$MAKE -C drivers/sound kernelconfig || exit 1\n"); } void dump_fixed_local(void) { int i = 0; printf("/* Computer generated file. Please don't edit! */\n\n"); printf("#define KERNEL_COMPATIBLE_CONFIG\n\n"); printf("#define SELECTED_SOUND_OPTIONS\t0x%08x\n\n", selected_options); while (extra_options[i].name != NULL) { int n = 0, j; printf("#if "); for (j = 0; j < OPT_LAST; j++) if (!(DISABLED_OPTIONS & B(j))) if (extra_options[i].mask & B(j)) { if (n) printf(" || "); if (!(n++ % 2)) printf("\\\n "); printf("defined(CONFIG_%s)", hw_table[j].macro); } printf("\n"); printf("#\tdefine CONFIG_%s\n", extra_options[i].name); printf("#endif\n\n"); i++; } } void dump_fixed_defines(void) { int i = 0; printf("# Computer generated file. Please don't edit\n\n"); while (extra_options[i].name != NULL) { int j; for (j = 0; j < OPT_LAST; j++) { if (!(DISABLED_OPTIONS & B(j))) { if (extra_options[i].mask & B(j)) { printf("ifdef CONFIG_%s\n", hw_table[j].macro); printf ("ifneq ($(CONFIG_%s),Y)\n", extra_options[i].name); printf("CONFIG_%s=y\n", extra_options[i].name); printf("endif\n"); printf("endif\n\n"); } } } i++; } } int main(int argc, char *argv[]) { int i, full_driver = 1; char old_config_file[200]; if (getuid() != 0) /* Not root */ { char *home; if ((home = getenv("HOME")) != NULL) { sprintf(old_config_file, "%s/.soundconf", home); oldconf = old_config_file; } } if (argc > 1) { if (strcmp(argv[1], "-o") == 0 && use_old_config(oldconf)) exit(0); else if (strcmp(argv[1], "script") == 0) { dump_script(); exit(0); } else if (strcmp(argv[1], "fixedlocal") == 0) { dump_fixed_local(); exit(0); } else if (strcmp(argv[1], "fixeddefines") == 0) { dump_fixed_defines(); exit(0); } } fprintf(stderr, "\nConfiguring Sound Support\n\n"); if (access(oldconf, R_OK) == 0) { char str[255]; sprintf(str, "Old configuration exists in `%s'. Use it", oldconf); if (think_positively(str, 1, "Enable this option to load the previously saved configuration file\n" "for all of the sound driver parameters.\n")) if (use_old_config(oldconf)) exit(0); } printf("/*\tGenerated by configure. Don't edit!!!!\t*/\n"); printf("/*\tMaking changes to this file is not as simple as it may look.\t*/\n\n"); printf("/*\tIf you change the CONFIG_ settings in local.h you\t*/\n"); printf("/*\t_have_ to edit .defines too.\t*/\n\n"); { /* * Partial driver */ full_driver = 0; for (i = 0; i <= OPT_LAST; i++) if (can_select_option(i)) { if (!(selected_options & B(i))) /* * Not selected yet */ if (!hw_table[i].verify) { if (hw_table[i].alias) selected_options |= B(hw_table[i].alias); else selected_options |= B(i); } else { int def_answ = hw_table[i].default_answ; if (think_positively(questions[i], def_answ, help[i])) if (hw_table[i].alias) selected_options |= B(hw_table[i].alias); else selected_options |= B(i); } } } if (selected_options & B(OPT_SB)) { if (think_positively( "Support for the SG NX Pro mixer", 0, "Enable this if you want to support the additional mixer functions\n" "provided on Sound Galaxy NX Pro sound cards.\n")) printf("#define __SGNXPRO__\n"); } if (selected_options & B(OPT_SB)) { if (think_positively("Support for the MV Jazz16 (ProSonic etc.)", 0, "Enable this if you have an MV Jazz16 or ProSonic sound card.\n")) { if (think_positively("Do you have SoundMan Wave", 0, "Enable this option of you have the Logitech SoundMan Wave sound card.\n")) { printf("#define SM_WAVE\n"); midi0001_again: if (think_positively( "Do you have access to the MIDI0001.BIN file", 1, "The Logitech SoundMan Wave has a microcontroller which must be\n" "initialized before MIDI emulation works. This is possible only if the\n" "microcode file is compiled into the driver.\n")) { char path[512]; fprintf(stderr, "Enter full name of the MIDI0001.BIN file (pwd is sound): "); scanf("%s", path); fprintf(stderr, "including microcode file %s\n", path); if (!bin2hex(path, "smw-midi0001.h", "smw_ucode")) { fprintf(stderr, "Couldn't open file %s\n", path); if (think_positively("Try again with correct path", 1, "The specified file could not be opened. Enter the correct path to the\n" "file.\n")) goto midi0001_again; } else { printf("#define SMW_MIDI0001_INCLUDED\n"); printf("/*build bin2hex %s smw-midi0001.h smw_ucode */\n", path); } } } } } if (selected_options & B(OPT_SB)) { if (think_positively("Do you have a Logitech SoundMan Games", 0, "The Logitech SoundMan Games supports 44 kHz in stereo while the\n" "standard SB Pro supports just 22 kHz stereo. You have the option of\n" "enabling SM Games mode. However, enable it only if you are sure that\n" "your card is an SM Games. Enabling this feature with a plain old SB\n" "Pro will cause troubles with stereo mode.\n\n" "DANGER! Read the above once again before answering 'y'\n" "Answer 'n' if you are unsure what to do!\n")) printf("#define SM_GAMES\n"); } if (selected_options & B(OPT_AEDSP16)) { int sel1 = 0; if (selected_options & B(OPT_SB)) { if (think_positively( "Do you want support for the Audio Excel Sound Blaster Pro mode", 1, "Enable this option if you want the Audio Excel sound card to operate\n" "in Sound Blaster Pro mode.\n")) { printf("#define AEDSP16_SBPRO\n"); sel1 = 1; } } if ((selected_options & B(OPT_MSS)) && (sel1 == 0)) { if (think_positively( "Do you want support for the Audio Excel Microsoft Sound System mode", 1, "Enable this option if you want the Audio Excel sound card to operate\n" "in Microsoft Sound System mode.\n")) { printf("#define AEDSP16_MSS\n"); sel1 = 1; } } if (sel1 == 0) { printf("invalid_configuration__run_make_config_again\n"); fprintf(stderr, "ERROR!!!!!\nYou must select at least one mode when using Audio Excel!\n"); exit(-1); } if (selected_options & B(OPT_MPU401)) printf("#define AEDSP16_MPU401\n"); } if (selected_options & B(OPT_PSS)) { genld_again: if (think_positively("Do you wish to include an LD file", 1, "If you want to emulate the Sound Blaster card and you have a DSPxxx.LD\n" "file then you must include the LD in the kernel.\n")) { char path[512]; fprintf(stderr, "Enter the path to your LD file (pwd is sound): "); scanf("%s", path); fprintf(stderr, "including LD file %s\n", path); if (!bin2hex(path, "synth-ld.h", "pss_synth")) { fprintf(stderr, "couldn't open `%s' as the LD file\n", path); if (think_positively("try again with correct path", 1, "The given LD file could not opened.\n")) goto genld_again; } else { printf("#define PSS_HAVE_LD\n"); printf("/*build bin2hex %s synth-ld.h pss_synth */\n", path); } } else { FILE *sf = fopen("synth-ld.h", "w"); fprintf(sf, "/* automatically generated by configure */\n"); fprintf(sf, "unsigned char pss_synth[1];\n" "#define pss_synthLen 0\n"); fclose(sf); } } if (selected_options & B(OPT_TRIX)) { hex2hex_again: if (think_positively("Do you want to include TRXPRO.HEX in your kernel", 1, "The MediaTrix AudioTrix Pro has an on-board microcontroller which\n" "needs to be initialized by downloading the code from the file TRXPRO.HEX\n" "in the DOS driver directory. If you don't have the TRXPRO.HEX file handy\n" "you may skip this step. However, the SB and MPU-401 modes of AudioTrix\n" "Pro will not work without this file!\n")) { char path[512]; fprintf(stderr, "Enter the path to your TRXPRO.HEX file (pwd is sound): "); scanf("%s", path); fprintf(stderr, "including HEX file `%s'\n", path); if (!hex2hex(path, "trix_boot.h", "trix_boot")) goto hex2hex_again; printf("/*build hex2hex %s trix_boot.h trix_boot */\n", path); printf("#define INCLUDE_TRIX_BOOT\n"); } } if (selected_options & B(OPT_MSS)) { if (think_positively("Support for builtin sound of Compaq Deskpro XL", 0, "Enable this if you have Compaq Deskpro XL.\n")) { printf("#define DESKPROXL\n"); } } if (selected_options & B(OPT_MAUI)) { oswf_again: if (think_positively( "Do you have access to the OSWF.MOT file", 1, "TB Maui and Tropez have a microcontroller which needs to be initialized\n" "prior use. OSWF.MOT is a file distributed with card's DOS/Windows drivers\n" "which is required during initialization\n")) { char path[512]; fprintf(stderr, "Enter full name of the OSWF.MOT file (pwd is sound): "); scanf("%s", path); fprintf(stderr, "including microcode file %s\n", path); if (!bin2hex(path, "maui_boot.h", "maui_os")) { fprintf(stderr, "Couldn't open file %s\n", path); if (think_positively("Try again with correct path", 1, "The specified file could not be opened. Enter the correct path to the\n" "file.\n")) goto oswf_again; } else { printf("#define HAVE_MAUI_BOOT\n"); printf("/*build bin2hex %s maui_boot.h maui_os */\n", path); } } } if (!(selected_options & ANY_DEVS)) { printf("invalid_configuration__run_make_config_again\n"); fprintf(stderr, "\n*** This combination is useless. Sound driver disabled!!! ***\n*** You need to enable support for at least one device ***\n\n"); exit(0); } for (i = 0; i <= OPT_LAST; i++) if (!hw_table[i].alias) if (selected_options & B(i)) printf("#define CONFIG_%s\n", hw_table[i].macro); else printf("#undef CONFIG_%s\n", hw_table[i].macro); printf("\n"); i = 0; while (extra_options[i].name != NULL) { if (selected_options & extra_options[i].mask) printf("#define CONFIG_%s\n", extra_options[i].name); else printf("#undef CONFIG_%s\n", extra_options[i].name); i++; } printf("\n"); ask_parameters(); printf("#define SELECTED_SOUND_OPTIONS\t0x%08lx\n", selected_options); fprintf(stderr, "\nThe sound driver is now configured.\n"); if (!old_config_used) { char str[255]; sprintf(str, "Save copy of this configuration to `%s'", oldconf); if (think_positively(str, 1, "If you enable this option then the sound driver configuration is\n" "saved to a file. If you later need to recompile the kernel you have\n" "the option of using the saved configuration.\n")) { char cmd[200]; sprintf(cmd, "cp local.h %s", oldconf); fclose(stdout); if (system(cmd) != 0) perror(cmd); } } exit(0); } int bin2hex(char *path, char *target, char *varname) { int fd; int count; char c; int i = 0; if ((fd = open(path, 0)) > 0) { FILE *sf = fopen(target, "w"); fprintf(sf, "/* automatically generated by configure */\n"); fprintf(sf, "static unsigned char %s[] = {\n", varname); while (1) { count = read(fd, &c, 1); if (count == 0) break; if (i != 0 && (i % 10) == 0) fprintf(sf, "\n"); fprintf(sf, "0x%02lx,", c & 0xFFL); i++; } fprintf(sf, "};\n" "#define %sLen %d\n", varname, i); fclose(sf); close(fd); return 1; } return 0; }