浏览代码

ALSA: oxygen: modify adjust_dg_dac_routing function

When selecting the audio output destinations (headphones,
FP headphones, multichannel output), the channel routing
should be changed depending on what destination selected.
Also unnecessary I2S channels are digitally muted. This
function called when the user selects the destination
in the ALSA mixer.

Signed-off-by: Roman Volkov <v1ron@mail.ru>
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Roman Volkov 11 年之前
父节点
当前提交
1f91ecc14d
共有 2 个文件被更改,包括 22 次插入24 次删除
  1. 20 24
      sound/pci/oxygen/xonar_dg.c
  2. 2 0
      sound/pci/oxygen/xonar_dg.h

+ 20 - 24
sound/pci/oxygen/xonar_dg.c

@@ -262,33 +262,29 @@ static void set_cs4245_adc_params(struct oxygen *chip,
 	cs4245_write_spi(chip, CS4245_MCLK_FREQ);
 	cs4245_write_spi(chip, CS4245_MCLK_FREQ);
 }
 }
 
 
-static inline unsigned int shift_bits(unsigned int value,
-				      unsigned int shift_from,
-				      unsigned int shift_to,
-				      unsigned int mask)
-{
-	if (shift_from < shift_to)
-		return (value << (shift_to - shift_from)) & mask;
-	else
-		return (value >> (shift_from - shift_to)) & mask;
-}
-
 static unsigned int adjust_dg_dac_routing(struct oxygen *chip,
 static unsigned int adjust_dg_dac_routing(struct oxygen *chip,
 					  unsigned int play_routing)
 					  unsigned int play_routing)
 {
 {
-	return (play_routing & OXYGEN_PLAY_DAC0_SOURCE_MASK) |
-	       shift_bits(play_routing,
-			  OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
-			  OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
-			  OXYGEN_PLAY_DAC1_SOURCE_MASK) |
-	       shift_bits(play_routing,
-			  OXYGEN_PLAY_DAC1_SOURCE_SHIFT,
-			  OXYGEN_PLAY_DAC2_SOURCE_SHIFT,
-			  OXYGEN_PLAY_DAC2_SOURCE_MASK) |
-	       shift_bits(play_routing,
-			  OXYGEN_PLAY_DAC0_SOURCE_SHIFT,
-			  OXYGEN_PLAY_DAC3_SOURCE_SHIFT,
-			  OXYGEN_PLAY_DAC3_SOURCE_MASK);
+	struct dg *data = chip->model_data;
+	unsigned int routing = 0;
+
+	switch (data->pcm_output) {
+	case PLAYBACK_DST_HP:
+	case PLAYBACK_DST_HP_FP:
+		oxygen_write8_masked(chip, OXYGEN_PLAY_ROUTING,
+			OXYGEN_PLAY_MUTE23 | OXYGEN_PLAY_MUTE45 |
+			OXYGEN_PLAY_MUTE67, OXYGEN_PLAY_MUTE_MASK);
+		break;
+	case PLAYBACK_DST_MULTICH:
+		routing = (0 << OXYGEN_PLAY_DAC0_SOURCE_SHIFT) |
+			  (2 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
+			  (1 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
+			  (0 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
+		oxygen_write8_masked(chip, OXYGEN_PLAY_ROUTING,
+			OXYGEN_PLAY_MUTE01, OXYGEN_PLAY_MUTE_MASK);
+		break;
+	}
+	return routing;
 }
 }
 
 
 static int output_switch_info(struct snd_kcontrol *ctl,
 static int output_switch_info(struct snd_kcontrol *ctl,

+ 2 - 0
sound/pci/oxygen/xonar_dg.h

@@ -26,6 +26,8 @@ enum cs4245_shadow_operation {
 struct dg {
 struct dg {
 	/* shadow copy of the CS4245 register space */
 	/* shadow copy of the CS4245 register space */
 	unsigned char cs4245_shadow[17];
 	unsigned char cs4245_shadow[17];
+	/* output select: headphone/speakers */
+	unsigned char pcm_output;
 	unsigned int output_sel;
 	unsigned int output_sel;
 	s8 input_vol[4][2];
 	s8 input_vol[4][2];
 	unsigned int input_sel;
 	unsigned int input_sel;