Common subdirectories: sound_v3s86/lowlevel and sound/lowlevel diff -u sound_v3s86/sb.h sound/sb.h --- sound_v3s86/sb.h Wed Oct 1 01:16:45 1997 +++ sound/sb.h Sun Feb 8 17:46:20 1998 @@ -45,6 +45,8 @@ #define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */ #define MDL_AEDSP 15 /* Audio Excel DSP 16 */ +#define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */ + /* register assignment */ /* * Config flags */ diff -u sound_v3s86/sb_audio.c sound/sb_audio.c --- sound_v3s86/sb_audio.c Sat Dec 6 03:12:44 1997 +++ sound/sb_audio.c Sun Mar 8 14:27:09 1998 @@ -61,6 +61,20 @@ devc->irq_mode = IMODE_NONE; sb_dsp_reset (devc); + /* The ALS007 seems to require that the DSP be removed from the output */ + /* in order for recording to be activated properly. This is done by */ + /* setting the appropriate bits of the output control register 4ch to */ + /* zero. This code assumes that the output control registers are not */ + /* used anywhere else and therefore the DSP bits are *always* ON for */ + /* output and OFF for sampling. */ + if (devc->submodel == SUBMDL_ALS007) + if (mode & OPEN_READ) { + sb_setmixer(devc,ALS007_OUTPUT_CTRL2, + sb_getmixer(devc,ALS007_OUTPUT_CTRL2) & 0xf9); + } else { + sb_setmixer(devc,ALS007_OUTPUT_CTRL2, + sb_getmixer(devc,ALS007_OUTPUT_CTRL2) | 0x06); + } return 0; } @@ -75,6 +89,12 @@ if (devc->dma16 != -1 && devc->dma16 != devc->dma8) sound_close_dma (devc->dma16); + + /* For ALS007, turn DSP output back on if closing the device for read */ + if ((devc->submodel == SUBMDL_ALS007) && (devc->opened & OPEN_READ)) { + sb_setmixer(devc,ALS007_OUTPUT_CTRL2, + sb_getmixer(devc,ALS007_OUTPUT_CTRL2) | 0x06); + } devc->opened = 0; } diff -u sound_v3s86/sb_common.c sound/sb_common.c --- sound_v3s86/sb_common.c Wed Oct 1 01:16:54 1997 +++ sound/sb_common.c Sat Feb 21 21:28:13 1998 @@ -728,7 +728,8 @@ sb_devc *devc; char name[100]; extern int sb_be_quiet; - + int mixer22, mixer30; + /* * Check if we had detected a SB device earlier */ @@ -847,6 +848,30 @@ case 4: devc->model = hw_config->card_subtype = MDL_SB16; + /* ALS007 and ALS100 return DSP version 4.2 and have 2 post-reset !=0 */ + /* registers at 0x3c and 0x4c (output ctrl registers on ALS007) whereas*/ + /* a "standard" SB16 doesn't have a register at 0x4c. ALS100 actively */ + /* updates register 0x22 whenever 0x30 changes, as per the SB16 spec. */ + /* Since ALS007 doesn't, this can be used to differentiate the 2 cards.*/ + if ((devc->minor == 2) && sb_getmixer(devc,0x3c) && sb_getmixer(devc,0x4c)) { + mixer30 = sb_getmixer(devc,0x30); + sb_setmixer(devc,0x22,(mixer22=sb_getmixer(devc,0x22)) & 0x0f); + sb_setmixer(devc,0x30,0xff); + /* ALS100 will force 0x30 to 0xf8 like SB16; ALS007 will allow 0xff. */ + /* Register 0x22 & 0xf0 on ALS100 == 0xf0; on ALS007 it == 0x10. */ + if ((sb_getmixer(devc,0x30) != 0xff) || ((sb_getmixer(devc,0x22) & 0xf0) != 0x10)) { + if (hw_config->name == NULL) + hw_config->name = "Sound Blaster 16 (ALS-100)"; + } else { + sb_setmixer(devc,0x3c,0x1f); /* Enable all inputs */ + sb_setmixer(devc,0x4c,0x1f); + sb_setmixer(devc,0x22,mixer22); /* Restore 0x22 to original value */ + devc->submodel = SUBMDL_ALS007; + if (hw_config->name == NULL) + hw_config->name = "Sound Blaster 16 (ALS-007)"; + } + sb_setmixer(devc,0x30,mixer30); + } else if (hw_config->name == NULL) hw_config->name = "Sound Blaster 16"; diff -u sound_v3s86/sb_mixer.c sound/sb_mixer.c --- sound_v3s86/sb_mixer.c Wed Oct 1 01:16:55 1997 +++ sound/sb_mixer.c Sat Feb 21 17:23:21 1998 @@ -270,15 +270,32 @@ if (!devmask) devmask = SOUND_MASK_MIC; - regimageL = regimageR = 0; - for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) - if ((1 << i) & devmask) - { - regimageL |= sb16_recmasks_L[i]; - regimageR |= sb16_recmasks_R[i]; - } - sb_setmixer (devc, SB16_IMASK_L, regimageL); - sb_setmixer (devc, SB16_IMASK_R, regimageR); + if (devc->submodel == SUBMDL_ALS007) { + switch (devmask) { + case SOUND_MASK_LINE: + sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_LINE); + break; + case SOUND_MASK_CD: + sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_CD); + break; + case SOUND_MASK_SYNTH: + sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_SYNTH); + break; + default: /* Also takes care of SOUND_MASK_MIC case */ + sb_setmixer(devc, ALS007_RECORD_SRC, ALS007_MIC); + break; + } + } else { + regimageL = regimageR = 0; + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) + if ((1 << i) & devmask) + { + regimageL |= sb16_recmasks_L[i]; + regimageR |= sb16_recmasks_R[i]; + } + sb_setmixer (devc, SB16_IMASK_L, regimageL); + sb_setmixer (devc, SB16_IMASK_R, regimageR); + } break; } @@ -362,6 +379,13 @@ sb_mixer_ioctl }; +static struct mixer_operations als007_mixer_operations = +{ + "ALS007", + "Avance ALS-007", + sb_mixer_ioctl +}; + static void sb_mixer_reset (sb_devc * devc) { @@ -419,9 +443,14 @@ case MDL_SB16: devc->mixer_caps = 0; - devc->supported_devices = SB16_MIXER_DEVICES; devc->supported_rec_devices = SB16_RECORDING_DEVICES; - devc->iomap = &sb16_mix; + if (devc->submodel != SUBMDL_ALS007) { + devc->supported_devices = SB16_MIXER_DEVICES; + devc->iomap = &sb16_mix; + } else { + devc->supported_devices = ALS007_MIXER_DEVICES; + devc->iomap = &als007_mix; + } break; default: @@ -444,7 +473,11 @@ return 0; } - memcpy ((char *) mixer_devs[num_mixers], (char *) &sb_mixer_operations, + if (devc->submodel != SUBMDL_ALS007) + memcpy ((char *) mixer_devs[num_mixers], (char *) &sb_mixer_operations, + sizeof (struct mixer_operations)); + else + memcpy ((char *) mixer_devs[num_mixers], (char *) &als007_mixer_operations, sizeof (struct mixer_operations)); mixer_devs[num_mixers]->devc = devc; diff -u sound_v3s86/sb_mixer.h sound/sb_mixer.h --- sound_v3s86/sb_mixer.h Wed Oct 1 01:16:45 1997 +++ sound/sb_mixer.h Fri Feb 20 22:49:22 1998 @@ -47,6 +47,13 @@ SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | \ SOUND_MASK_IMIX) +/* These are the only devices that are working at the moment. Others could + * be added once they are identified and a method is found to control them. + */ +#define ALS007_MIXER_DEVICES (SOUND_MASK_SYNTH | SOUND_MASK_LINE | \ + SOUND_MASK_PCM | SOUND_MASK_MIC | \ + SOUND_MASK_CD | \ + SOUND_MASK_VOLUME) /* * Mixer registers * @@ -95,6 +102,13 @@ #define LEFT_CHN 0 #define RIGHT_CHN 1 +/* + * Mixer registers of ALS007 + */ +#define ALS007_RECORD_SRC 0x6c +#define ALS007_OUTPUT_CTRL1 0x3c +#define ALS007_OUTPUT_CTRL2 0x4c + #define MIX_ENT(name, reg_l, bit_l, len_l, reg_r, bit_r, len_r) \ {{reg_l, bit_l, len_l}, {reg_r, bit_r, len_r}} @@ -169,6 +183,23 @@ MIX_ENT(SOUND_MIXER_OGAIN, 0x41, 7, 2, 0x42, 7, 2) }; +static mixer_tab als007_mix = { +MIX_ENT(SOUND_MIXER_VOLUME, 0x62, 7, 4, 0x62, 3, 4), +MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_SYNTH, 0x66, 7, 4, 0x66, 3, 4), +MIX_ENT(SOUND_MIXER_PCM, 0x64, 7, 4, 0x64, 3, 4), +MIX_ENT(SOUND_MIXER_SPEAKER, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_LINE, 0x6e, 7, 4, 0x6e, 3, 4), +MIX_ENT(SOUND_MIXER_MIC, 0x6a, 2, 3, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_CD, 0x68, 7, 4, 0x68, 3, 4), +MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0), /* Obsolete. Use IGAIN */ +MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0), +MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0) +}; + #ifdef SM_GAMES /* Master volume is lower and PCM & FM volumes higher than with SB Pro. This improves the sound quality */ @@ -282,6 +313,15 @@ #define SRC__MIC 1 /* Select Microphone recording source */ #define SRC__CD 3 /* Select CD recording source */ #define SRC__LINE 7 /* Use Line-in for recording source */ + +/* + * Recording sources for ALS-007 + */ + +#define ALS007_MIC 4 +#define ALS007_LINE 6 +#define ALS007_CD 2 +#define ALS007_SYNTH 7 #endif #endif