aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/oxygen_mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/oxygen/oxygen_mixer.c')
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c110
1 files changed, 87 insertions, 23 deletions
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2849b36f5f7..9bff14d5895 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,7 +31,7 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
31 struct oxygen *chip = ctl->private_data; 31 struct oxygen *chip = ctl->private_data;
32 32
33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
34 info->count = chip->model.dac_channels; 34 info->count = chip->model.dac_channels_mixer;
35 info->value.integer.min = chip->model.dac_volume_min; 35 info->value.integer.min = chip->model.dac_volume_min;
36 info->value.integer.max = chip->model.dac_volume_max; 36 info->value.integer.max = chip->model.dac_volume_max;
37 return 0; 37 return 0;
@@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
44 unsigned int i; 44 unsigned int i;
45 45
46 mutex_lock(&chip->mutex); 46 mutex_lock(&chip->mutex);
47 for (i = 0; i < chip->model.dac_channels; ++i) 47 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
48 value->value.integer.value[i] = chip->dac_volume[i]; 48 value->value.integer.value[i] = chip->dac_volume[i];
49 mutex_unlock(&chip->mutex); 49 mutex_unlock(&chip->mutex);
50 return 0; 50 return 0;
@@ -59,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
59 59
60 changed = 0; 60 changed = 0;
61 mutex_lock(&chip->mutex); 61 mutex_lock(&chip->mutex);
62 for (i = 0; i < chip->model.dac_channels; ++i) 62 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
63 if (value->value.integer.value[i] != chip->dac_volume[i]) { 63 if (value->value.integer.value[i] != chip->dac_volume[i]) {
64 chip->dac_volume[i] = value->value.integer.value[i]; 64 chip->dac_volume[i] = value->value.integer.value[i];
65 changed = 1; 65 changed = 1;
@@ -97,6 +97,16 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
97 return changed; 97 return changed;
98} 98}
99 99
100static unsigned int upmix_item_count(struct oxygen *chip)
101{
102 if (chip->model.dac_channels_pcm < 8)
103 return 2;
104 else if (chip->model.update_center_lfe_mix)
105 return 5;
106 else
107 return 3;
108}
109
100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 110static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
101{ 111{
102 static const char *const names[5] = { 112 static const char *const names[5] = {
@@ -107,15 +117,9 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
107 "Front+Surround+Center/LFE+Back", 117 "Front+Surround+Center/LFE+Back",
108 }; 118 };
109 struct oxygen *chip = ctl->private_data; 119 struct oxygen *chip = ctl->private_data;
110 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 120 unsigned int count = upmix_item_count(chip);
111 121
112 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 122 return snd_ctl_enum_info(info, 1, count, names);
113 info->count = 1;
114 info->value.enumerated.items = count;
115 if (info->value.enumerated.item >= count)
116 info->value.enumerated.item = count - 1;
117 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
118 return 0;
119} 123}
120 124
121static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 125static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -188,7 +192,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 192static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
189{ 193{
190 struct oxygen *chip = ctl->private_data; 194 struct oxygen *chip = ctl->private_data;
191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 195 unsigned int count = upmix_item_count(chip);
192 int changed; 196 int changed;
193 197
194 if (value->value.enumerated.item[0] >= count) 198 if (value->value.enumerated.item[0] >= count)
@@ -430,30 +434,31 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl,
430 return 0; 434 return 0;
431} 435}
432 436
433static int spdif_loopback_get(struct snd_kcontrol *ctl, 437static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
434 struct snd_ctl_elem_value *value) 438 struct snd_ctl_elem_value *value)
435{ 439{
436 struct oxygen *chip = ctl->private_data; 440 struct oxygen *chip = ctl->private_data;
441 u32 bit = ctl->private_value;
437 442
438 value->value.integer.value[0] = 443 value->value.integer.value[0] =
439 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) 444 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
440 & OXYGEN_SPDIF_LOOPBACK);
441 return 0; 445 return 0;
442} 446}
443 447
444static int spdif_loopback_put(struct snd_kcontrol *ctl, 448static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
445 struct snd_ctl_elem_value *value) 449 struct snd_ctl_elem_value *value)
446{ 450{
447 struct oxygen *chip = ctl->private_data; 451 struct oxygen *chip = ctl->private_data;
452 u32 bit = ctl->private_value;
448 u32 oldreg, newreg; 453 u32 oldreg, newreg;
449 int changed; 454 int changed;
450 455
451 spin_lock_irq(&chip->reg_lock); 456 spin_lock_irq(&chip->reg_lock);
452 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); 457 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
453 if (value->value.integer.value[0]) 458 if (value->value.integer.value[0])
454 newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; 459 newreg = oldreg | bit;
455 else 460 else
456 newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; 461 newreg = oldreg & ~bit;
457 changed = newreg != oldreg; 462 changed = newreg != oldreg;
458 if (changed) 463 if (changed)
459 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); 464 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
@@ -644,6 +649,46 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
644 return change; 649 return change;
645} 650}
646 651
652static int mic_fmic_source_info(struct snd_kcontrol *ctl,
653 struct snd_ctl_elem_info *info)
654{
655 static const char *const names[] = { "Mic Jack", "Front Panel" };
656
657 return snd_ctl_enum_info(info, 1, 2, names);
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{
@@ -791,8 +836,17 @@ static const struct snd_kcontrol_new spdif_input_controls[] = {
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), 837 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
793 .info = snd_ctl_boolean_mono_info, 838 .info = snd_ctl_boolean_mono_info,
794 .get = spdif_loopback_get, 839 .get = spdif_bit_switch_get,
795 .put = spdif_loopback_put, 840 .put = spdif_bit_switch_put,
841 .private_value = OXYGEN_SPDIF_LOOPBACK,
842 },
843 {
844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
845 .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
846 .info = snd_ctl_boolean_mono_info,
847 .get = spdif_bit_switch_get,
848 .put = spdif_bit_switch_put,
849 .private_value = OXYGEN_SPDIF_SPDVALID,
796 }, 850 },
797}; 851};
798 852
@@ -908,6 +962,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
908 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), 962 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
909 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), 963 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
910 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), 964 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
965 {
966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
967 .name = "Mic Source Capture Enum",
968 .info = mic_fmic_source_info,
969 .get = mic_fmic_source_get,
970 .put = mic_fmic_source_put,
971 },
911 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), 972 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
912 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), 973 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
913 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), 974 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -970,7 +1031,10 @@ static int add_controls(struct oxygen *chip,
970 continue; 1031 continue;
971 } 1032 }
972 if (!strcmp(template.name, "Stereo Upmixing") && 1033 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 1034 chip->model.dac_channels_pcm == 2)
1035 continue;
1036 if (!strcmp(template.name, "Mic Source Capture Enum") &&
1037 !(chip->model.device_config & AC97_FMIC_SWITCH))
974 continue; 1038 continue;
975 if (!strncmp(template.name, "CD Capture ", 11) && 1039 if (!strncmp(template.name, "CD Capture ", 11) &&
976 !(chip->model.device_config & AC97_CD_INPUT)) 1040 !(chip->model.device_config & AC97_CD_INPUT))