diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2010-12-02 05:39:34 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-12-06 08:48:08 -0500 |
commit | e96f38f732d24515792296b3738842934c985539 (patch) | |
tree | 627b4c03b4f1b12e903a265f97ba98767af0c0aa /sound/pci/oxygen | |
parent | 2509ec623d44320419d44d4060dbedf91b8d192d (diff) |
ALSA: virtuoso: fix front panel routing for D1/DX/ST(X)
The "Front Panel" switch on the Xonar D1/DX actually switches only the
output direction, so mark it appropriately.
The front panel microphone is controlled by the FMIC2MIC bit of the
CM9780. It was unconditionally enabled on the D1/DX and never set on
the ST(X); add a control for it. Selecting the front panel microphone
as source does not actually disable the microphone jack, but this is
bug-compatible with the Windows driver, and users rely on it.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen')
-rw-r--r-- | sound/pci/oxygen/oxygen.h | 1 | ||||
-rw-r--r-- | sound/pci/oxygen/oxygen_mixer.c | 55 | ||||
-rw-r--r-- | sound/pci/oxygen/xonar_cs43xx.c | 9 | ||||
-rw-r--r-- | sound/pci/oxygen/xonar_pcm179x.c | 3 |
4 files changed, 62 insertions, 6 deletions
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 7d5222caa0a9..cf9054ecb97b 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #define MIDI_OUTPUT 0x0800 | 35 | #define MIDI_OUTPUT 0x0800 |
36 | #define MIDI_INPUT 0x1000 | 36 | #define MIDI_INPUT 0x1000 |
37 | #define AC97_CD_INPUT 0x2000 | 37 | #define AC97_CD_INPUT 0x2000 |
38 | #define AC97_FMIC_SWITCH 0x4000 | ||
38 | 39 | ||
39 | enum { | 40 | enum { |
40 | CONTROL_SPDIF_PCM, | 41 | CONTROL_SPDIF_PCM, |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 2849b36f5f7e..605e84b9e1ec 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -644,6 +644,51 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, | |||
644 | return change; | 644 | return change; |
645 | } | 645 | } |
646 | 646 | ||
647 | static int mic_fmic_source_info(struct snd_kcontrol *ctl, | ||
648 | struct snd_ctl_elem_info *info) | ||
649 | { | ||
650 | static const char *const names[] = { "Mic Jack", "Front Panel" }; | ||
651 | |||
652 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
653 | info->count = 1; | ||
654 | info->value.enumerated.items = 2; | ||
655 | info->value.enumerated.item &= 1; | ||
656 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static int mic_fmic_source_get(struct snd_kcontrol *ctl, | ||
661 | struct snd_ctl_elem_value *value) | ||
662 | { | ||
663 | struct oxygen *chip = ctl->private_data; | ||
664 | |||
665 | mutex_lock(&chip->mutex); | ||
666 | value->value.enumerated.item[0] = | ||
667 | !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC); | ||
668 | mutex_unlock(&chip->mutex); | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int mic_fmic_source_put(struct snd_kcontrol *ctl, | ||
673 | struct snd_ctl_elem_value *value) | ||
674 | { | ||
675 | struct oxygen *chip = ctl->private_data; | ||
676 | u16 oldreg, newreg; | ||
677 | int change; | ||
678 | |||
679 | mutex_lock(&chip->mutex); | ||
680 | oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK); | ||
681 | if (value->value.enumerated.item[0]) | ||
682 | newreg = oldreg | CM9780_FMIC2MIC; | ||
683 | else | ||
684 | newreg = oldreg & ~CM9780_FMIC2MIC; | ||
685 | change = newreg != oldreg; | ||
686 | if (change) | ||
687 | oxygen_write_ac97(chip, 0, CM9780_JACK, newreg); | ||
688 | mutex_unlock(&chip->mutex); | ||
689 | return change; | ||
690 | } | ||
691 | |||
647 | static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, | 692 | static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, |
648 | struct snd_ctl_elem_info *info) | 693 | struct snd_ctl_elem_info *info) |
649 | { | 694 | { |
@@ -908,6 +953,13 @@ static const struct snd_kcontrol_new ac97_controls[] = { | |||
908 | AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), | 953 | AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), |
909 | AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), | 954 | AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), |
910 | AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), | 955 | AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), |
956 | { | ||
957 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
958 | .name = "Mic Source Capture Enum", | ||
959 | .info = mic_fmic_source_info, | ||
960 | .get = mic_fmic_source_get, | ||
961 | .put = mic_fmic_source_put, | ||
962 | }, | ||
911 | AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), | 963 | AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), |
912 | AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), | 964 | AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), |
913 | AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), | 965 | AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), |
@@ -972,6 +1024,9 @@ static int add_controls(struct oxygen *chip, | |||
972 | if (!strcmp(template.name, "Stereo Upmixing") && | 1024 | if (!strcmp(template.name, "Stereo Upmixing") && |
973 | chip->model.dac_channels == 2) | 1025 | chip->model.dac_channels == 2) |
974 | continue; | 1026 | continue; |
1027 | if (!strcmp(template.name, "Mic Source Capture Enum") && | ||
1028 | !(chip->model.device_config & AC97_FMIC_SWITCH)) | ||
1029 | continue; | ||
975 | if (!strncmp(template.name, "CD Capture ", 11) && | 1030 | if (!strncmp(template.name, "CD Capture ", 11) && |
976 | !(chip->model.device_config & AC97_CD_INPUT)) | 1031 | !(chip->model.device_config & AC97_CD_INPUT)) |
977 | continue; | 1032 | continue; |
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index ae4e5b512483..501fe45bbdce 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * GPI 0 <- external power present (DX only) | 28 | * GPI 0 <- external power present (DX only) |
29 | * | 29 | * |
30 | * GPIO 0 -> enable output to speakers | 30 | * GPIO 0 -> enable output to speakers |
31 | * GPIO 1 -> enable front panel I/O | 31 | * GPIO 1 -> route output to front panel |
32 | * GPIO 2 -> M0 of CS5361 | 32 | * GPIO 2 -> M0 of CS5361 |
33 | * GPIO 3 -> M1 of CS5361 | 33 | * GPIO 3 -> M1 of CS5361 |
34 | * GPIO 8 -> route input jack to line-in (0) or mic-in (1) | 34 | * GPIO 8 -> route input jack to line-in (0) or mic-in (1) |
@@ -176,8 +176,6 @@ static void xonar_d1_init(struct oxygen *chip) | |||
176 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, | 176 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, |
177 | GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); | 177 | GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); |
178 | 178 | ||
179 | oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); | ||
180 | |||
181 | xonar_init_cs53x1(chip); | 179 | xonar_init_cs53x1(chip); |
182 | xonar_enable_output(chip); | 180 | xonar_enable_output(chip); |
183 | 181 | ||
@@ -287,7 +285,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed) | |||
287 | 285 | ||
288 | static const struct snd_kcontrol_new front_panel_switch = { | 286 | static const struct snd_kcontrol_new front_panel_switch = { |
289 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 287 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
290 | .name = "Front Panel Switch", | 288 | .name = "Front Panel Playback Switch", |
291 | .info = snd_ctl_boolean_mono_info, | 289 | .info = snd_ctl_boolean_mono_info, |
292 | .get = xonar_gpio_bit_switch_get, | 290 | .get = xonar_gpio_bit_switch_get, |
293 | .put = xonar_gpio_bit_switch_put, | 291 | .put = xonar_gpio_bit_switch_put, |
@@ -402,7 +400,8 @@ static const struct oxygen_model model_xonar_d1 = { | |||
402 | .model_data_size = sizeof(struct xonar_cs43xx), | 400 | .model_data_size = sizeof(struct xonar_cs43xx), |
403 | .device_config = PLAYBACK_0_TO_I2S | | 401 | .device_config = PLAYBACK_0_TO_I2S | |
404 | PLAYBACK_1_TO_SPDIF | | 402 | PLAYBACK_1_TO_SPDIF | |
405 | CAPTURE_0_FROM_I2S_2, | 403 | CAPTURE_0_FROM_I2S_2 | |
404 | AC97_FMIC_SWITCH, | ||
406 | .dac_channels = 8, | 405 | .dac_channels = 8, |
407 | .dac_volume_min = 127 - 60, | 406 | .dac_volume_min = 127 - 60, |
408 | .dac_volume_max = 127, | 407 | .dac_volume_max = 127, |
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 3850834f989c..5193d73a916d 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c | |||
@@ -1079,7 +1079,8 @@ static const struct oxygen_model model_xonar_st = { | |||
1079 | .model_data_size = sizeof(struct xonar_pcm179x), | 1079 | .model_data_size = sizeof(struct xonar_pcm179x), |
1080 | .device_config = PLAYBACK_0_TO_I2S | | 1080 | .device_config = PLAYBACK_0_TO_I2S | |
1081 | PLAYBACK_1_TO_SPDIF | | 1081 | PLAYBACK_1_TO_SPDIF | |
1082 | CAPTURE_0_FROM_I2S_2, | 1082 | CAPTURE_0_FROM_I2S_2 | |
1083 | AC97_FMIC_SWITCH, | ||
1083 | .dac_channels = 2, | 1084 | .dac_channels = 2, |
1084 | .dac_volume_min = 255 - 2*60, | 1085 | .dac_volume_min = 255 - 2*60, |
1085 | .dac_volume_max = 255, | 1086 | .dac_volume_max = 255, |