aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-12-02 05:39:34 -0500
committerTakashi Iwai <tiwai@suse.de>2010-12-06 08:48:08 -0500
commite96f38f732d24515792296b3738842934c985539 (patch)
tree627b4c03b4f1b12e903a265f97ba98767af0c0aa /sound/pci/oxygen
parent2509ec623d44320419d44d4060dbedf91b8d192d (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.h1
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c55
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c9
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c3
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
39enum { 40enum {
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
647static 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
660static 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
672static 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
647static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, 692static 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
288static const struct snd_kcontrol_new front_panel_switch = { 286static 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,