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.c112
1 files changed, 89 insertions, 23 deletions
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2849b36f5f7e..26c7e8bcb229 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)
@@ -176,6 +180,8 @@ void oxygen_update_dac_routing(struct oxygen *chip)
176 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) | 180 (1 << OXYGEN_PLAY_DAC1_SOURCE_SHIFT) |
177 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) | 181 (2 << OXYGEN_PLAY_DAC2_SOURCE_SHIFT) |
178 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT); 182 (3 << OXYGEN_PLAY_DAC3_SOURCE_SHIFT);
183 if (chip->model.adjust_dac_routing)
184 reg_value = chip->model.adjust_dac_routing(chip, reg_value);
179 oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value, 185 oxygen_write16_masked(chip, OXYGEN_PLAY_ROUTING, reg_value,
180 OXYGEN_PLAY_DAC0_SOURCE_MASK | 186 OXYGEN_PLAY_DAC0_SOURCE_MASK |
181 OXYGEN_PLAY_DAC1_SOURCE_MASK | 187 OXYGEN_PLAY_DAC1_SOURCE_MASK |
@@ -188,7 +194,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 194static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
189{ 195{
190 struct oxygen *chip = ctl->private_data; 196 struct oxygen *chip = ctl->private_data;
191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 197 unsigned int count = upmix_item_count(chip);
192 int changed; 198 int changed;
193 199
194 if (value->value.enumerated.item[0] >= count) 200 if (value->value.enumerated.item[0] >= count)
@@ -430,30 +436,31 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl,
430 return 0; 436 return 0;
431} 437}
432 438
433static int spdif_loopback_get(struct snd_kcontrol *ctl, 439static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
434 struct snd_ctl_elem_value *value) 440 struct snd_ctl_elem_value *value)
435{ 441{
436 struct oxygen *chip = ctl->private_data; 442 struct oxygen *chip = ctl->private_data;
443 u32 bit = ctl->private_value;
437 444
438 value->value.integer.value[0] = 445 value->value.integer.value[0] =
439 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) 446 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
440 & OXYGEN_SPDIF_LOOPBACK);
441 return 0; 447 return 0;
442} 448}
443 449
444static int spdif_loopback_put(struct snd_kcontrol *ctl, 450static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
445 struct snd_ctl_elem_value *value) 451 struct snd_ctl_elem_value *value)
446{ 452{
447 struct oxygen *chip = ctl->private_data; 453 struct oxygen *chip = ctl->private_data;
454 u32 bit = ctl->private_value;
448 u32 oldreg, newreg; 455 u32 oldreg, newreg;
449 int changed; 456 int changed;
450 457
451 spin_lock_irq(&chip->reg_lock); 458 spin_lock_irq(&chip->reg_lock);
452 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); 459 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
453 if (value->value.integer.value[0]) 460 if (value->value.integer.value[0])
454 newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; 461 newreg = oldreg | bit;
455 else 462 else
456 newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; 463 newreg = oldreg & ~bit;
457 changed = newreg != oldreg; 464 changed = newreg != oldreg;
458 if (changed) 465 if (changed)
459 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); 466 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
@@ -644,6 +651,46 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
644 return change; 651 return change;
645} 652}
646 653
654static int mic_fmic_source_info(struct snd_kcontrol *ctl,
655 struct snd_ctl_elem_info *info)
656{
657 static const char *const names[] = { "Mic Jack", "Front Panel" };
658
659 return snd_ctl_enum_info(info, 1, 2, names);
660}
661
662static int mic_fmic_source_get(struct snd_kcontrol *ctl,
663 struct snd_ctl_elem_value *value)
664{
665 struct oxygen *chip = ctl->private_data;
666
667 mutex_lock(&chip->mutex);
668 value->value.enumerated.item[0] =
669 !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
670 mutex_unlock(&chip->mutex);
671 return 0;
672}
673
674static int mic_fmic_source_put(struct snd_kcontrol *ctl,
675 struct snd_ctl_elem_value *value)
676{
677 struct oxygen *chip = ctl->private_data;
678 u16 oldreg, newreg;
679 int change;
680
681 mutex_lock(&chip->mutex);
682 oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
683 if (value->value.enumerated.item[0])
684 newreg = oldreg | CM9780_FMIC2MIC;
685 else
686 newreg = oldreg & ~CM9780_FMIC2MIC;
687 change = newreg != oldreg;
688 if (change)
689 oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
690 mutex_unlock(&chip->mutex);
691 return change;
692}
693
647static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, 694static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
648 struct snd_ctl_elem_info *info) 695 struct snd_ctl_elem_info *info)
649{ 696{
@@ -791,8 +838,17 @@ static const struct snd_kcontrol_new spdif_input_controls[] = {
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 838 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), 839 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
793 .info = snd_ctl_boolean_mono_info, 840 .info = snd_ctl_boolean_mono_info,
794 .get = spdif_loopback_get, 841 .get = spdif_bit_switch_get,
795 .put = spdif_loopback_put, 842 .put = spdif_bit_switch_put,
843 .private_value = OXYGEN_SPDIF_LOOPBACK,
844 },
845 {
846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
847 .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
848 .info = snd_ctl_boolean_mono_info,
849 .get = spdif_bit_switch_get,
850 .put = spdif_bit_switch_put,
851 .private_value = OXYGEN_SPDIF_SPDVALID,
796 }, 852 },
797}; 853};
798 854
@@ -908,6 +964,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
908 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), 964 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
909 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), 965 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
910 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), 966 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
967 {
968 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
969 .name = "Mic Source Capture Enum",
970 .info = mic_fmic_source_info,
971 .get = mic_fmic_source_get,
972 .put = mic_fmic_source_put,
973 },
911 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), 974 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
912 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), 975 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
913 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), 976 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -970,7 +1033,10 @@ static int add_controls(struct oxygen *chip,
970 continue; 1033 continue;
971 } 1034 }
972 if (!strcmp(template.name, "Stereo Upmixing") && 1035 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 1036 chip->model.dac_channels_pcm == 2)
1037 continue;
1038 if (!strcmp(template.name, "Mic Source Capture Enum") &&
1039 !(chip->model.device_config & AC97_FMIC_SWITCH))
974 continue; 1040 continue;
975 if (!strncmp(template.name, "CD Capture ", 11) && 1041 if (!strncmp(template.name, "CD Capture ", 11) &&
976 !(chip->model.device_config & AC97_CD_INPUT)) 1042 !(chip->model.device_config & AC97_CD_INPUT))