Hi.

There are some problems with the controls on the cs4236+ chips.

1) The same control bit is given two different names:
> CS4236_SINGLEC("S/PDIF Output 3D", 0, 3, 5, 1, 0),
and
> CS4236_SINGLEC("3D Control - S/PDIF", 0, 3, 5, 1, 0)

2) The following control is omitted:
  CS4236_SINGLEC("the name you think appropriate", 0, 4, 7, 1, 0)

If you decide to make revisions to the the control section,
I would ask that you consider the following:

3) The output is not, strictly speaking, S/PDIF but IEC958
and the controls should be named accordingly.

4) It would help greatly if the controls were arranged in a
systematic order within each group, such as:
   master controls, playback controls, capture controls
Presently the controls do not always follow a regular order
and the result is that GUI mixer programs lay the controls
out in a more confusing way than they otherwise would.
I realize that the mixer programs should be written so that
control layout can be customized, but there is nothing wrong
with providing a default order that is, er, orderly.

Please reply with comments if you would like me to submit
a patch that addresses these concerns.

Thanks very much for all your hard work.
Thomas Hood
--- alsa-driver-0.9+0beta4-5/lowlevel/isa/cs4236.c_ORIG Fri Mar 23 16:10:50 2001
+++ alsa-driver-0.9+0beta4-5/lowlevel/isa/cs4236.c      Wed Jul 18 11:18:38 2001
@@ -695,58 +695,56 @@
        return change;
 }
 
-#define CS4236_CONTROLS (sizeof(snd_cs4236_controls)/sizeof(snd_kcontrol_new_t))
-
-static snd_kcontrol_new_t snd_cs4236_controls[] = {
-
-CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, 
CS4236_RIGHT_MASTER, 7, 7, 1, 1),
-CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 
7, 6, 1, 1),
-CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
-
-CS4236_DOUBLE("Capture Boost Volume", 0, CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 
5, 5, 3, 1),
-
-CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 
7, 1, 1),
-CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 
0, 63, 1),
-
-CS4236_DOUBLE("DSP Playback Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 
1),
-CS4236_DOUBLE("DSP Playback Volume", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 
1),
-
-CS4236_DOUBLE("FM Playback Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
-CS4236_DOUBLE("FM Playback Volume", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1),
-
-CS4236_DOUBLE("Wavetable Playback Switch", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 
7, 1, 1),
-CS4236_DOUBLE("Wavetable Playback Volume", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 
0, 63, 1),
-
-CS4231_DOUBLE("Synth Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 
7, 7, 1, 1),
-CS4231_DOUBLE("Synth Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 
1),
-CS4231_DOUBLE("Synth Capture Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 
6, 6, 1, 1),
-CS4231_DOUBLE("Synth Capture Bypass", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 
5, 5, 1, 1),
-
-CS4236_DOUBLE("Mic Playback Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 
1),
-CS4236_DOUBLE("Mic Capture Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
-CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1),
-CS4236_DOUBLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
-
-CS4231_DOUBLE("Line Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, 
CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("Line Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 
0, 31, 1),
-CS4231_DOUBLE("Line Capture Switch", 0, CS4231_AUX1_LEFT_INPUT, 
CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
-CS4231_DOUBLE("Line Capture Bypass", 0, CS4231_AUX1_LEFT_INPUT, 
CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1),
+#define CS4236_SERIAL_ENABLE(xname, xindex) \
+{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex, \
+  info: snd_cs4236_info_single, \
+  get: snd_cs4236_get_serial_switch, put: snd_cs4236_put_serial_switch, \
+  private_value: 1 << 16 }
 
-CS4231_DOUBLE("CD Playback Switch", 0, CS4231_AUX2_LEFT_INPUT, 
CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
-CS4231_DOUBLE("CD Volume", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 
31, 1),
-CS4231_DOUBLE("CD Capture Switch", 0, CS4231_AUX2_LEFT_INPUT, 
CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
+static int snd_cs4236_get_serial_switch(snd_kcontrol_t * kcontrol, 
+snd_ctl_elem_value_t * ucontrol)
+{
+       cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+       unsigned long flags;
+       
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 
+1 : 0;
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       return 0;
+}
 
-CS4236_DOUBLE1("Mono Output Playback Switch", 0, CS4231_MONO_CTRL, 
CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
-CS4236_DOUBLE1("Mono Playback Switch", 0, CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 
7, 1, 1),
-CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
-CS4231_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
+static int snd_cs4236_put_serial_switch(snd_kcontrol_t * kcontrol, 
+snd_ctl_elem_value_t * ucontrol)
+{
+       cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+       unsigned long flags;
+       int change;
+       unsigned short enable, val;
+       
+       enable = ucontrol->value.integer.value[0] & 1;
 
-CS4231_DOUBLE("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 
0),
-CS4231_DOUBLE("Analog Loopback Capture Switch", 0, CS4231_LEFT_INPUT, 
CS4231_RIGHT_INPUT, 7, 7, 1, 0),
+       down(&chip->mce_mutex);
+       snd_cs4231_mce_up(chip);
+       spin_lock_irqsave(&chip->reg_lock, flags);
+       val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x02) | (enable << 1);
+       change = val != chip->image[CS4231_ALT_FEATURE_1];
+       snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, val);
+       val = (snd_cs4236_ctrl_in(chip, 4) & ~0x80) | (enable << 7);
+       change |= snd_cs4236_ctrl_in(chip, 4) != val;
+       snd_cs4236_ctrl_out(chip, 4, val);
+       spin_unlock_irqrestore(&chip->reg_lock, flags);
+       snd_cs4231_mce_down(chip);
+       up(&chip->mce_mutex);
 
-CS4231_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
-CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, CS4231_LOOPBACK, 
CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1)
-};
+#if 0
+       printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 
+= 0x%x\n",
+                       snd_cs4231_in(chip, CS4231_ALT_FEATURE_1),
+                       snd_cs4236_ctrl_in(chip, 3),
+                       snd_cs4236_ctrl_in(chip, 4),
+                       snd_cs4236_ctrl_in(chip, 5),
+                       snd_cs4236_ctrl_in(chip, 6),
+                       snd_cs4236_ctrl_in(chip, 8));
+#endif
+       return change;
+}
 
 #define CS4235_CONTROLS (sizeof(snd_cs4235_controls)/sizeof(snd_kcontrol_new_t))
 
@@ -797,67 +795,72 @@
 CS4231_DOUBLE("Analog Loopback Switch", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 
7, 1, 0),
 };
 
-#define CS4236_IEC958_ENABLE(xname, xindex) \
-{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, index: xindex, \
-  info: snd_cs4236_info_single, \
-  get: snd_cs4236_get_iec958_switch, put: snd_cs4236_put_iec958_switch, \
-  private_value: 1 << 16 }
+#define CS4236_CONTROLS (sizeof(snd_cs4236_controls)/sizeof(snd_kcontrol_new_t))
 
-static int snd_cs4236_get_iec958_switch(snd_kcontrol_t * kcontrol, 
snd_ctl_elem_value_t * ucontrol)
-{
-       cs4231_t *chip = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
-       
-       spin_lock_irqsave(&chip->reg_lock, flags);
-       ucontrol->value.integer.value[0] = chip->image[CS4231_ALT_FEATURE_1] & 0x02 ? 
1 : 0;
-       spin_unlock_irqrestore(&chip->reg_lock, flags);
-       return 0;
-}
+static snd_kcontrol_new_t snd_cs4236_controls[] = {
 
-static int snd_cs4236_put_iec958_switch(snd_kcontrol_t * kcontrol, 
snd_ctl_elem_value_t * ucontrol)
-{
-       cs4231_t *chip = snd_kcontrol_chip(kcontrol);
-       unsigned long flags;
-       int change;
-       unsigned short enable, val;
-       
-       enable = ucontrol->value.integer.value[0] & 1;
+CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 
+7, 1, 1),
+CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 
+0, 63, 1),
 
-       down(&chip->mce_mutex);
-       snd_cs4231_mce_up(chip);
-       spin_lock_irqsave(&chip->reg_lock, flags);
-       val = (chip->image[CS4231_ALT_FEATURE_1] & ~0x02) | (enable << 1);
-       change = val != chip->image[CS4231_ALT_FEATURE_1];
-       snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, val);
-       val = (snd_cs4236_ctrl_in(chip, 4) & ~0x80) | (enable << 7);
-       change |= snd_cs4236_ctrl_in(chip, 4) != val;
-       snd_cs4236_ctrl_out(chip, 4, val);
-       spin_unlock_irqrestore(&chip->reg_lock, flags);
-       snd_cs4231_mce_down(chip);
-       up(&chip->mce_mutex);
+CS4236_DOUBLE("FM Playback Switch", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
+CS4236_DOUBLE("FM Playback Volume", 0, CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1),
 
-#if 0
-       printk("set valid: ALT = 0x%x, C3 = 0x%x, C4 = 0x%x, C5 = 0x%x, C6 = 0x%x, C8 
= 0x%x\n",
-                       snd_cs4231_in(chip, CS4231_ALT_FEATURE_1),
-                       snd_cs4236_ctrl_in(chip, 3),
-                       snd_cs4236_ctrl_in(chip, 4),
-                       snd_cs4236_ctrl_in(chip, 5),
-                       snd_cs4236_ctrl_in(chip, 6),
-                       snd_cs4236_ctrl_in(chip, 8));
-#endif
-       return change;
-}
+CS4236_DOUBLE("Wavetable Playback Switch", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 
+7, 1, 1),
+CS4236_DOUBLE("Wavetable Playback Volume", 0, CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 
+0, 63, 1),
+
+CS4236_SERIAL_ENABLE("Serial Switch", 0),
+CS4236_DOUBLE("Serial Playback Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 
+1, 1),
+CS4236_DOUBLE("Serial Playback Volume", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 
+63, 1),
+
+CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 
+7, 6, 1, 1),
+CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, 
+CS4236_RIGHT_MASTER, 7, 7, 1, 1),
+CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
+
+CS4236_DOUBLE("Mic Capture Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
+CS4236_DOUBLE("Mic Playback Boost 20dB Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 
+5, 5, 1, 0),
+CS4236_DOUBLE("Mic Playback Switch", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 
+1),
+CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1),
+
+CS4231_DOUBLE("Synth Capture Bypass Switch", 0, CS4231_LEFT_LINE_IN, 
+CS4231_RIGHT_LINE_IN, 5, 5, 1, 1),
+CS4231_DOUBLE("Synth Capture Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 
+6, 6, 1, 1),
+CS4231_DOUBLE("Synth Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 
+7, 7, 1, 1),
+CS4231_DOUBLE("Synth Volume", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 
+1),
+
+CS4231_DOUBLE("Aux Capture Bypass Switch", 0, CS4231_AUX1_LEFT_INPUT, 
+CS4231_AUX1_RIGHT_INPUT, 5, 5, 1, 1),
+CS4231_DOUBLE("Aux Capture Switch", 0, CS4231_AUX1_LEFT_INPUT, 
+CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
+CS4231_DOUBLE("Aux Playback Switch", 0, CS4231_AUX1_LEFT_INPUT, 
+CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
+CS4231_DOUBLE("Aux Volume", 0, CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 
+31, 1),
+
+CS4231_DOUBLE("CD Capture Switch", 0, CS4231_AUX2_LEFT_INPUT, 
+CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
+CS4231_DOUBLE("CD Playback Switch", 0, CS4231_AUX2_LEFT_INPUT, 
+CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
+CS4231_DOUBLE("CD Volume", 0, CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 
+31, 1),
+
+CS4236_DOUBLE1("Mono Playback Switch", 0, CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 
+7, 1, 1),
+CS4231_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
+CS4231_SINGLE("Mono Mono Output Switch", 0, CS4231_MONO_CTRL, 5, 1, 0),
+
+CS4231_DOUBLE("Hardware Master Capture Switch", 0, CS4231_LEFT_INPUT, 
+CS4231_RIGHT_INPUT, 7, 7, 1, 0),
+CS4236_DOUBLE1("Hardware Master Mono Output Switch", 0, CS4231_MONO_CTRL, 
+CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
+
+CS4231_SINGLE("ADC Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
+CS4236_DOUBLE1("ADC Playback Volume", 0, CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 
+0, 63, 1),
+CS4236_DOUBLE("ADC Boost Volume", 0, CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 
+5, 3, 1),
+CS4231_DOUBLE("ADC Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0)
+
+};
+
+/* The CS4237B and CS4238B have IEC958 capability */
 
 #define CS4236_IEC958_CONTROLS 
(sizeof(snd_cs4236_iec958_controls)/sizeof(snd_kcontrol_new_t))
 
 static snd_kcontrol_new_t snd_cs4236_iec958_controls[] = {
-CS4236_IEC958_ENABLE("S/PDIF Output Enable", 0),
-CS4236_SINGLEC("S/PDIF Output Validity", 0, 4, 4, 1, 0),
-CS4236_SINGLEC("S/PDIF Output User", 0, 4, 5, 1, 0),
-CS4236_SINGLEC("S/PDIF Output CSBR", 0, 4, 6, 1, 0),
-CS4236_SINGLEC("S/PDIF Output 3D", 0, 3, 5, 1, 0),
-CS4236_SINGLEC("S/PDIF Output Channel Status Low", 0, 5, 1, 127, 0),
-CS4236_SINGLEC("S/PDIF Output Channel Status High", 0, 6, 0, 255, 0)
+CS4236_SINGLEC("IEC958 Serial Switch", 0, 4, 7, 1, 0),
+CS4236_SINGLEC("IEC958 Serial Master-Digital/ADC Select Switch", 0, 3, 5, 1, 0),
+CS4236_SINGLEC("IEC958 Serial Validity Bit", 0, 4, 4, 1, 0),
+CS4236_SINGLEC("IEC958 Serial User Bit", 0, 4, 5, 1, 0),
+CS4236_SINGLEC("IEC958 Serial Channel Status Block Reset", 0, 4, 6, 1, 0),
+CS4236_SINGLEC("IEC958 Serial Channel Status Low", 0, 5, 1, 127, 0),
+CS4236_SINGLEC("IEC958 Serial Channel Status High", 0, 6, 0, 255, 0)
 };
 
 #define CS4236_3D_CONTROLS_CS4235 
(sizeof(snd_cs4236_3d_controls_cs4235)/sizeof(snd_kcontrol_new_t))
@@ -871,10 +874,9 @@
 
 static snd_kcontrol_new_t snd_cs4236_3d_controls_cs4237[] = {
 CS4236_SINGLEC("3D Control - Switch", 0, 3, 7, 1, 0),
+CS4236_SINGLEC("3D Control - Mono-to-Stereo Switch", 0, 3, 6, 1, 0),
 CS4236_SINGLEC("3D Control - Space", 0, 2, 0, 15, 1),
-CS4236_SINGLEC("3D Control - Center", 0, 2, 4, 15, 1),
-CS4236_SINGLEC("3D Control - Mono", 0, 3, 6, 1, 0),
-CS4236_SINGLEC("3D Control - S/PDIF", 0, 3, 5, 1, 0)
+CS4236_SINGLEC("3D Control - Center", 0, 2, 4, 15, 1)
 };
 
 #define CS4236_3D_CONTROLS_CS4238 
(sizeof(snd_cs4236_3d_controls_cs4238)/sizeof(snd_kcontrol_new_t))
@@ -882,8 +884,7 @@
 static snd_kcontrol_new_t snd_cs4236_3d_controls_cs4238[] = {
 CS4236_SINGLEC("3D Control - Switch", 0, 3, 4, 1, 0),
 CS4236_SINGLEC("3D Control - Space", 0, 2, 0, 15, 1),
-CS4236_SINGLEC("3D Control - Volume", 0, 2, 4, 15, 1),
-CS4236_SINGLEC("3D Control - S/PDIF", 0, 3, 5, 1, 0)
+CS4236_SINGLEC("3D Control - Volume", 0, 2, 4, 15, 1)
 };
 
 int snd_cs4236_mixer(cs4231_t *chip)

Reply via email to