Hi all,
- make snd_kcontrol_new_t arrays in sb_mixer.c arrays of *pointers*
to snd_kcontrol_new_t in order to have way more flexibility in
implementing "close but not quite" matches in SB-like mixer interfaces
(assembling new clone card SB mixers from *preexisting* controls)
- added 3D sound controls and many more controls to ALS4000, also some
fixes to other cards (SB16 etc.)
- tried to fix ALS4000 open/close clicking and popping but failed (documented
failure)
- added hint about official ALS4000 chip specs
- some cleanup
Greetings,
Andreas Mohr
Index: alsa-kernel/include/sb.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/include/sb.h,v
retrieving revision 1.7
diff -u -r1.7 sb.h
--- alsa-kernel/include/sb.h 23 Oct 2002 19:07:44 -0000 1.7
+++ alsa-kernel/include/sb.h 10 Nov 2002 13:48:44 -0000
@@ -225,7 +225,6 @@
#define SB_DT019X_MIC_DEV 0x6a
#define SB_DT019X_SPKR_DEV 0x6a
#define SB_DT019X_LINE_DEV 0x6e
-#define SB_DT019X_OUTPUT_SW1 0x3c
#define SB_DT019X_OUTPUT_SW2 0x4c
#define SB_DT019X_CAPTURE_SW 0x6c
@@ -234,6 +233,14 @@
#define SB_DT019X_CAP_LINE 0x06
#define SB_DT019X_CAP_SYNTH 0x07
#define SB_DT019X_CAP_MAIN 0x07
+
+#define SB_ALS4000_MONO_IO_CTRL 0x4b
+#define SB_ALS4000_MIC_IN_GAIN 0x4d
+#define SB_ALS4000_FMDAC 0x4f
+#define SB_ALS4000_3D_SND_FX 0x50
+#define SB_ALS4000_3D_TIME_DELAY 0x51
+#define SB_ALS4000_3D_AUTO_MUTE 0x52
+#define SB_ALS4000_QSOUND 0xdb
/* IRQ setting bitmap */
#define SB_IRQSETUP_IRQ9 0x01
Index: alsa-kernel/isa/sb/sb_mixer.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/isa/sb/sb_mixer.c,v
retrieving revision 1.9
diff -u -r1.9 sb_mixer.c
--- alsa-kernel/isa/sb/sb_mixer.c 15 Aug 2002 12:13:07 -0000 1.9
+++ alsa-kernel/isa/sb/sb_mixer.c 10 Nov 2002 13:48:45 -0000
@@ -428,13 +428,22 @@
return change;
}
-#define SB20_CONTROLS (sizeof(snd_sb20_controls)/sizeof(snd_kcontrol_new_t))
+#define SB20_CONTROLS (sizeof(snd_sb20_controls)/sizeof(snd_kcontrol_new_t *))
-static snd_kcontrol_new_t snd_sb20_controls[] = {
-SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7),
-SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3),
-SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7),
-SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7)
+static snd_kcontrol_new_t snd_sb20_ctl_master_play_vol =
+ SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7);
+static snd_kcontrol_new_t snd_sb20_ctl_pcm_play_vol =
+ SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3);
+static snd_kcontrol_new_t snd_sb20_ctl_synth_play_vol =
+ SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7);
+static snd_kcontrol_new_t snd_sb20_ctl_cd_play_vol =
+ SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7);
+
+static snd_kcontrol_new_t *snd_sb20_controls[] = {
+ &snd_sb20_ctl_master_play_vol,
+ &snd_sb20_ctl_pcm_play_vol,
+ &snd_sb20_ctl_synth_play_vol,
+ &snd_sb20_ctl_cd_play_vol
};
#define SB20_INIT_VALUES (sizeof(snd_sb20_init_values)/sizeof(unsigned char)/2)
@@ -444,25 +453,46 @@
{ SB_DSP20_FM_DEV, 0 },
};
-#define SBPRO_CONTROLS (sizeof(snd_sbpro_controls)/sizeof(snd_kcontrol_new_t))
+#define SBPRO_CONTROLS (sizeof(snd_sbpro_controls)/sizeof(snd_kcontrol_new_t *))
-static snd_kcontrol_new_t snd_sbpro_controls[] = {
-SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7),
-SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7),
-SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1),
-SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7),
-SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7),
-SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7),
-SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_sb8mixer_info_mux,
- .get = snd_sb8mixer_get_mux,
- .put = snd_sb8mixer_put_mux,
-},
-SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1),
-SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1)
+static snd_kcontrol_new_t snd_sbpro_ctl_master_play_vol =
+ SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5,
+1, 7);
+static snd_kcontrol_new_t snd_sbpro_ctl_pcm_play_vol =
+ SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7);
+static snd_kcontrol_new_t snd_sbpro_ctl_pcm_play_filter =
+ SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1);
+static snd_kcontrol_new_t snd_sbpro_ctl_synth_play_vol =
+ SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7);
+static snd_kcontrol_new_t snd_sbpro_ctl_cd_play_vol =
+ SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7);
+static snd_kcontrol_new_t snd_sbpro_ctl_line_play_vol =
+ SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7);
+static snd_kcontrol_new_t snd_sbpro_ctl_mic_play_vol =
+ SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3);
+static snd_kcontrol_new_t snd_sbpro_ctl_capture_source =
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = snd_sb8mixer_info_mux,
+ .get = snd_sb8mixer_get_mux,
+ .put = snd_sb8mixer_put_mux,
+ };
+static snd_kcontrol_new_t snd_sbpro_ctl_capture_filter =
+ SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1);
+static snd_kcontrol_new_t snd_sbpro_ctl_capture_low_filter =
+ SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1);
+
+static snd_kcontrol_new_t *snd_sbpro_controls[] = {
+ &snd_sbpro_ctl_master_play_vol,
+ &snd_sbpro_ctl_pcm_play_vol,
+ &snd_sbpro_ctl_pcm_play_filter,
+ &snd_sbpro_ctl_synth_play_vol,
+ &snd_sbpro_ctl_cd_play_vol,
+ &snd_sbpro_ctl_line_play_vol,
+ &snd_sbpro_ctl_mic_play_vol,
+ &snd_sbpro_ctl_capture_source,
+ &snd_sbpro_ctl_capture_filter,
+ &snd_sbpro_ctl_capture_low_filter
};
#define SBPRO_INIT_VALUES (sizeof(snd_sbpro_init_values)/sizeof(unsigned char)/2)
@@ -473,29 +503,70 @@
{ SB_DSP_FM_DEV, 0 },
};
-#define SB16_CONTROLS (sizeof(snd_sb16_controls)/sizeof(snd_kcontrol_new_t))
+#define SB16_CONTROLS (sizeof(snd_sb16_controls)/sizeof(snd_kcontrol_new_t *))
-static snd_kcontrol_new_t snd_sb16_controls[] = {
-SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3,
3, 31),
-SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1),
-SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
-SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4,
4, 15),
-SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
-SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5),
-SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3,
31),
-SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1),
-SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
-SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
-SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3),
-SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
-SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
-SB_DOUBLE("Mic Capture Switch", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0, 1),
-SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
-SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
-SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
-SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
-SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
-SB_SINGLE("Auto Mic Gain", SB_DSP4_MIC_AGC, 0, 1)
+static snd_kcontrol_new_t snd_sb16_ctl_master_play_vol =
+ SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV +
+1), 3, 3, 31);
+static snd_kcontrol_new_t snd_sb16_ctl_3d_enhance_switch =
+ SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1);
+static snd_kcontrol_new_t snd_sb16_ctl_tone_bass =
+ SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4,
+4, 15);
+static snd_kcontrol_new_t snd_sb16_ctl_tone_treble =
+ SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV +
+1), 4, 4, 15);
+static snd_kcontrol_new_t snd_sb16_ctl_pcm_play_vol =
+ SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3,
+31);
+static snd_kcontrol_new_t snd_sb16_ctl_synth_capture_route =
+ SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
+6, 5);
+static snd_kcontrol_new_t snd_sb16_ctl_synth_play_vol =
+ SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1),
+3, 3, 31);
+static snd_kcontrol_new_t snd_sb16_ctl_cd_capture_route =
+ SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2,
+1);
+static snd_kcontrol_new_t snd_sb16_ctl_cd_play_switch =
+ SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1);
+static snd_kcontrol_new_t snd_sb16_ctl_cd_play_vol =
+ SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3,
+31);
+static snd_kcontrol_new_t snd_sb16_ctl_line_capture_route =
+ SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
+4, 3);
+static snd_kcontrol_new_t snd_sb16_ctl_line_play_switch =
+ SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3,
+1);
+static snd_kcontrol_new_t snd_sb16_ctl_line_play_vol =
+ SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3,
+3, 31);
+static snd_kcontrol_new_t snd_sb16_ctl_mic_capture_route =
+ SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0,
+0);
+static snd_kcontrol_new_t snd_sb16_ctl_mic_play_switch =
+ SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1);
+static snd_kcontrol_new_t snd_sb16_ctl_mic_play_vol =
+ SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31);
+static snd_kcontrol_new_t snd_sb16_ctl_pc_speaker_vol =
+ SB_SINGLE("PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3);
+static snd_kcontrol_new_t snd_sb16_ctl_capture_vol =
+ SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6,
+3);
+static snd_kcontrol_new_t snd_sb16_ctl_play_vol =
+ SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6,
+3);
+static snd_kcontrol_new_t snd_sb16_ctl_auto_mic_gain =
+ SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1);
+
+static snd_kcontrol_new_t *snd_sb16_controls[] = {
+ &snd_sb16_ctl_master_play_vol,
+ &snd_sb16_ctl_3d_enhance_switch,
+ &snd_sb16_ctl_tone_bass,
+ &snd_sb16_ctl_tone_treble,
+ &snd_sb16_ctl_pcm_play_vol,
+ &snd_sb16_ctl_synth_capture_route,
+ &snd_sb16_ctl_synth_play_vol,
+ &snd_sb16_ctl_cd_capture_route,
+ &snd_sb16_ctl_cd_play_switch,
+ &snd_sb16_ctl_cd_play_vol,
+ &snd_sb16_ctl_line_capture_route,
+ &snd_sb16_ctl_line_play_switch,
+ &snd_sb16_ctl_line_play_vol,
+ &snd_sb16_ctl_mic_capture_route,
+ &snd_sb16_ctl_mic_play_switch,
+ &snd_sb16_ctl_mic_play_vol,
+ &snd_sb16_ctl_pc_speaker_vol,
+ &snd_sb16_ctl_capture_vol,
+ &snd_sb16_ctl_play_vol,
+ &snd_sb16_ctl_auto_mic_gain
};
#define SB16_INIT_VALUES (sizeof(snd_sb16_init_values)/sizeof(unsigned char)/2)
@@ -513,28 +584,50 @@
{ SB_DSP4_SPEAKER_DEV, 0 },
};
-#define DT019X_CONTROLS (sizeof(snd_dt019x_controls)/sizeof(snd_kcontrol_new_t))
+#define DT019X_CONTROLS (sizeof(snd_dt019x_controls)/sizeof(snd_kcontrol_new_t *))
-static snd_kcontrol_new_t snd_dt019x_controls[] = {
-SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0,
15),
-SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15),
-SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15),
-SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15),
-SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7),
-SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0, 7),
-SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15),
-SB_SINGLE("Mic Playback Switch", SB_DT019X_OUTPUT_SW1, 0, 1),
-SB_DOUBLE("CD Playback Switch", SB_DT019X_OUTPUT_SW1, SB_DT019X_OUTPUT_SW1, 2,1, 1),
-SB_DOUBLE("Line Playback Switch", SB_DT019X_OUTPUT_SW1, SB_DT019X_OUTPUT_SW1, 4,3, 1),
-SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1),
-SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3,
1),
-{
- .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Source",
- .info = snd_dt019x_input_sw_info,
- .get = snd_dt019x_input_sw_get,
- .put = snd_dt019x_input_sw_put,
-},
+
+static snd_kcontrol_new_t snd_dt019x_ctl_master_play_vol =
+ SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV,
+SB_DT019X_MASTER_DEV, 4,0, 15);
+static snd_kcontrol_new_t snd_dt019x_ctl_pcm_play_vol =
+ SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0,
+15);
+static snd_kcontrol_new_t snd_dt019x_ctl_synth_play_vol =
+ SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV,
+4,0, 15);
+static snd_kcontrol_new_t snd_dt019x_ctl_cd_play_vol =
+ SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15);
+static snd_kcontrol_new_t snd_dt019x_ctl_mic_play_vol =
+ SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7);
+static snd_kcontrol_new_t snd_dt019x_ctl_pc_speaker_vol =
+ SB_SINGLE("PC Speaker Volume", SB_DT019X_SPKR_DEV, 0, 7);
+static snd_kcontrol_new_t snd_dt019x_ctl_line_play_vol =
+ SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0,
+15);
+static snd_kcontrol_new_t snd_dt019x_ctl_pcm_play_switch =
+ SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2,
+2,1, 1);
+static snd_kcontrol_new_t snd_dt019x_ctl_synth_play_switch =
+ SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2,
+4,3, 1);
+static snd_kcontrol_new_t snd_dt019x_ctl_capture_source =
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Source",
+ .info = snd_dt019x_input_sw_info,
+ .get = snd_dt019x_input_sw_get,
+ .put = snd_dt019x_input_sw_put,
+ };
+
+static snd_kcontrol_new_t *snd_dt019x_controls[] = {
+ &snd_dt019x_ctl_master_play_vol,
+ &snd_dt019x_ctl_pcm_play_vol,
+ &snd_dt019x_ctl_synth_play_vol,
+ &snd_dt019x_ctl_cd_play_vol,
+ &snd_dt019x_ctl_mic_play_vol,
+ &snd_dt019x_ctl_pc_speaker_vol,
+ &snd_dt019x_ctl_line_play_vol,
+ &snd_sb16_ctl_mic_play_switch,
+ &snd_sb16_ctl_cd_play_switch,
+ &snd_sb16_ctl_line_play_switch,
+ &snd_dt019x_ctl_pcm_play_switch,
+ &snd_dt019x_ctl_synth_play_switch,
+ &snd_dt019x_ctl_capture_source
};
#define DT019X_INIT_VALUES (sizeof(snd_dt019x_init_values)/sizeof(unsigned char)/2)
@@ -546,13 +639,92 @@
{ SB_DT019X_CD_DEV, 0 },
{ SB_DT019X_MIC_DEV, 0 }, /* Includes PC-speaker in high nibble */
{ SB_DT019X_LINE_DEV, 0 },
- { SB_DT019X_OUTPUT_SW1, 0 },
+ { SB_DSP4_OUTPUT_SW, 0 },
{ SB_DT019X_OUTPUT_SW2, 0 },
{ SB_DT019X_CAPTURE_SW, 0x06 },
};
+/* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl ! */
+static snd_kcontrol_new_t snd_als4000_ctl_mono_output_switch =
+ SB_SINGLE("Mono Output Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1);
+/* FIXME: mono input switch also available on DT019X ? */
+static snd_kcontrol_new_t snd_als4000_ctl_mono_input_switch =
+ SB_SINGLE("Mono Input Switch", SB_DT019X_OUTPUT_SW2, 0, 1);
+static snd_kcontrol_new_t snd_als4000_ctl_mic_20db_boost =
+ SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
+static snd_kcontrol_new_t snd_als4000_ctl_mixer_out_to_in =
+ SB_SINGLE("Mixer Out To In", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
+/* FIXME: 3D needs much more sophisticated controls, many more features ! */
+static snd_kcontrol_new_t snd_als4000_ctl_3d_output_switch =
+ SB_SINGLE("3D Output Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
+static snd_kcontrol_new_t snd_als4000_ctl_3d_output_ratio =
+ SB_SINGLE("3D Output Ratio", SB_ALS4000_3D_SND_FX, 0, 0x07);
+static snd_kcontrol_new_t snd_als4000_ctl_3d_poweroff_switch =
+ SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
+static snd_kcontrol_new_t snd_als4000_ctl_3d_delay =
+ SB_SINGLE("3D Delay", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
+#if NOT_AVAILABLE
+static snd_kcontrol_new_t snd_als4000_ctl_fmdac =
+ SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01);
+static snd_kcontrol_new_t snd_als4000_ctl_qsound =
+ SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f);
+#endif
+
+#define ALS4000_CONTROLS (sizeof(snd_als4000_controls)/sizeof(snd_kcontrol_new_t *))
+
+static snd_kcontrol_new_t *snd_als4000_controls[] = {
+ &snd_sb16_ctl_master_play_vol,
+ &snd_dt019x_ctl_pcm_play_switch,
+ &snd_sb16_ctl_pcm_play_vol,
+ &snd_sb16_ctl_synth_capture_route,
+ &snd_dt019x_ctl_synth_play_switch,
+ &snd_sb16_ctl_synth_play_vol,
+ &snd_sb16_ctl_cd_capture_route,
+ &snd_sb16_ctl_cd_play_switch,
+ &snd_sb16_ctl_cd_play_vol,
+ &snd_sb16_ctl_line_capture_route,
+ &snd_sb16_ctl_line_play_switch,
+ &snd_sb16_ctl_line_play_vol,
+ &snd_sb16_ctl_mic_capture_route,
+ &snd_als4000_ctl_mic_20db_boost,
+ &snd_sb16_ctl_auto_mic_gain,
+ &snd_sb16_ctl_mic_play_switch,
+ &snd_sb16_ctl_mic_play_vol,
+ &snd_sb16_ctl_pc_speaker_vol,
+ &snd_sb16_ctl_capture_vol,
+ &snd_sb16_ctl_play_vol,
+ &snd_als4000_ctl_mono_output_switch,
+ &snd_als4000_ctl_mono_input_switch,
+ &snd_als4000_ctl_mixer_out_to_in,
+ &snd_als4000_ctl_3d_output_switch,
+ &snd_als4000_ctl_3d_output_ratio,
+ &snd_als4000_ctl_3d_delay,
+ &snd_als4000_ctl_3d_poweroff_switch,
+#if NOT_AVAILABLE
+ &snd_als4000_ctl_fmdac,
+ &snd_als4000_ctl_qsound,
+#endif
+};
+
+#define ALS4000_INIT_VALUES (sizeof(snd_als4000_init_values)/sizeof(unsigned char)/2)
+
+static unsigned char snd_als4000_init_values[][2] = {
+ { SB_DSP4_MASTER_DEV + 0, 0 },
+ { SB_DSP4_MASTER_DEV + 1, 0 },
+ { SB_DSP4_PCM_DEV + 0, 0 },
+ { SB_DSP4_PCM_DEV + 1, 0 },
+ { SB_DSP4_SYNTH_DEV + 0, 0 },
+ { SB_DSP4_SYNTH_DEV + 1, 0 },
+ { SB_DSP4_SPEAKER_DEV, 0 },
+ { SB_DSP4_OUTPUT_SW, 0 },
+ { SB_DSP4_INPUT_LEFT, 0 },
+ { SB_DSP4_INPUT_RIGHT, 0 },
+ { SB_DT019X_OUTPUT_SW2, 0 },
+ { SB_ALS4000_MIC_IN_GAIN, 0 },
+};
+
static int snd_sbmixer_init(sb_t *chip,
- snd_kcontrol_new_t *controls,
+ snd_kcontrol_new_t **controls,
int controls_count,
unsigned char map[][2],
int map_count,
@@ -575,7 +747,7 @@
}
for (idx = 0; idx < controls_count; idx++) {
- if ((err = snd_ctl_add(card, snd_ctl_new1(&controls[idx], chip))) < 0)
+ if ((err = snd_ctl_add(card, snd_ctl_new1(controls[idx], chip))) < 0)
return err;
}
snd_component_add(card, name);
@@ -612,11 +784,17 @@
break;
case SB_HW_16:
case SB_HW_ALS100:
- case SB_HW_ALS4000:
if ((err = snd_sbmixer_init(chip,
snd_sb16_controls, SB16_CONTROLS,
snd_sb16_init_values, SB16_INIT_VALUES,
"CTL1745")) < 0)
+ return err;
+ break;
+ case SB_HW_ALS4000:
+ if ((err = snd_sbmixer_init(chip,
+ snd_als4000_controls, ALS4000_CONTROLS,
+ snd_als4000_init_values,
+ALS4000_INIT_VALUES,
+ "ALS4000")) < 0)
return err;
break;
case SB_HW_DT019X:
Index: alsa-kernel/pci/als4000.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/als4000.c,v
retrieving revision 1.17
diff -u -r1.17 als4000.c
--- alsa-kernel/pci/als4000.c 21 Oct 2002 18:28:23 -0000 1.17
+++ alsa-kernel/pci/als4000.c 10 Nov 2002 13:48:46 -0000
@@ -2,6 +2,7 @@
* card-als4000.c - driver for Avance Logic ALS4000 based soundcards.
* Copyright (C) 2000 by Bart Hartgers <[EMAIL PROTECTED]>,
* Jaroslav Kysela <[EMAIL PROTECTED]>
+ * Copyright (C) 2002 by Andreas Mohr <[EMAIL PROTECTED]>
*
* Framework borrowed from Massimo Piccioni's card-als100.c.
*
@@ -11,6 +12,9 @@
* bought an ALS4000 based soundcard, I was forced to base this driver
* on reverse engineering.
*
+ * Note: this is no longer true. Pretty verbose chip docu (ALS4000a.PDF)
+ * can be found on the ALSA web site.
+ *
* The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an
* ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport
* interface. These subsystems can be mapped into ISA io-port space,
@@ -23,11 +27,21 @@
*
* The ALS4000 can do real full duplex playback/capture.
*
- * BUGS
- * The box suggests there is some support for 3D sound, but I did not
- * investigate this yet.
- *
+ * FMDAC:
+ * - 0x4f -> port 0x14
+ * - port 0x15 |= 1
+ *
+ * Enable/disable 3D sound:
+ * - 0x50 -> port 0x14
+ * - change bit 6 (0x40) of port 0x15
+ *
+ * Set QSound:
+ * - 0xdb -> port 0x14
+ * - set port 0x15:
+ * 0x3e (mode 3), 0x3c (mode 2), 0x3a (mode 1), 0x38 (mode 0)
*
+ * Set KSound:
+ * - value -> some port 0x0c0d
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -256,11 +270,18 @@
count >>=1;
count--;
+ /* FIXME: from second playback on, there's a lot more clicks and pops
+ * involved here than on first playback. Fiddling with
+ * tons of different settings didn't help (DMA, speaker on/off,
+ * reordering, ...). Something seems to get enabled on playback
+ * that I haven't found out how to disable again, which then causes
+ * the switching pops to reach the speakers the next time here. */
spin_lock_irqsave(&chip->reg_lock, flags);
snd_als4000_set_rate(chip, runtime->rate);
snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
- snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
+ /* SPEAKER_ON not needed, since dma_on seems to also enable speaker */
+ /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */
snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd);
snd_sbdsp_command(chip, playback_cmd(chip).format);
snd_sbdsp_command(chip, count);
@@ -359,9 +380,9 @@
spin_unlock_irqrestore(&chip->mixer_lock, flags);
if (sb_status & SB_IRQTYPE_8BIT)
- inb(SBP(chip, DATA_AVAIL));
+ snd_sb_ack_8bit(chip);
if (sb_status & SB_IRQTYPE_16BIT)
- inb(SBP(chip, DATA_AVAIL_16));
+ snd_sb_ack_16bit(chip);
if (sb_status & SB_IRQTYPE_MPUIN)
inb(chip->mpu_port);
if (sb_status & 0x20)
@@ -547,14 +568,14 @@
spin_unlock_irqrestore(&chip->reg_lock,flags);
}
-static void snd_card_als4k_free( snd_card_t *card )
+static void snd_card_als4000_free( snd_card_t *card )
{
snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
/* make sure that interrupts are disabled */
snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
}
-static int __devinit snd_card_als4k_probe(struct pci_dev *pci,
+static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
static int dev;
@@ -608,7 +629,7 @@
acard = (snd_card_als4000_t *)card->private_data;
acard->gcr = gcr;
- card->private_free = snd_card_als4k_free;
+ card->private_free = snd_card_als4000_free;
if ((err = snd_sbdsp_create(card,
gcr + 0x10,
@@ -672,7 +693,7 @@
return 0;
}
-static void __devexit snd_card_als4k_remove(struct pci_dev *pci)
+static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
pci_set_drvdata(pci, NULL);
@@ -681,11 +702,11 @@
static struct pci_driver driver = {
.name = "ALS4000",
.id_table = snd_als4000_ids,
- .probe = snd_card_als4k_probe,
- .remove = __devexit_p(snd_card_als4k_remove),
+ .probe = snd_card_als4000_probe,
+ .remove = __devexit_p(snd_card_als4000_remove),
};
-static int __init alsa_card_als4k_init(void)
+static int __init alsa_card_als4000_init(void)
{
int err;
@@ -698,13 +719,13 @@
return 0;
}
-static void __exit alsa_card_als4k_exit(void)
+static void __exit alsa_card_als4000_exit(void)
{
pci_unregister_driver(&driver);
}
-module_init(alsa_card_als4k_init)
-module_exit(alsa_card_als4k_exit)
+module_init(alsa_card_als4000_init)
+module_exit(alsa_card_als4000_exit)
#ifndef MODULE
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel