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.c217
1 files changed, 211 insertions, 6 deletions
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index a8e4623415d9..cc0cddadd589 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -32,8 +32,8 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
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;
35 info->value.integer.min = 0; 35 info->value.integer.min = chip->model->dac_volume_min;
36 info->value.integer.max = 0xff; 36 info->value.integer.max = chip->model->dac_volume_max;
37 return 0; 37 return 0;
38} 38}
39 39
@@ -446,6 +446,50 @@ static int spdif_loopback_put(struct snd_kcontrol *ctl,
446 return changed; 446 return changed;
447} 447}
448 448
449static int monitor_volume_info(struct snd_kcontrol *ctl,
450 struct snd_ctl_elem_info *info)
451{
452 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
453 info->count = 1;
454 info->value.integer.min = 0;
455 info->value.integer.max = 1;
456 return 0;
457}
458
459static int monitor_get(struct snd_kcontrol *ctl,
460 struct snd_ctl_elem_value *value)
461{
462 struct oxygen *chip = ctl->private_data;
463 u8 bit = ctl->private_value;
464 int invert = ctl->private_value & (1 << 8);
465
466 value->value.integer.value[0] =
467 !!invert ^ !!(oxygen_read8(chip, OXYGEN_ADC_MONITOR) & bit);
468 return 0;
469}
470
471static int monitor_put(struct snd_kcontrol *ctl,
472 struct snd_ctl_elem_value *value)
473{
474 struct oxygen *chip = ctl->private_data;
475 u8 bit = ctl->private_value;
476 int invert = ctl->private_value & (1 << 8);
477 u8 oldreg, newreg;
478 int changed;
479
480 spin_lock_irq(&chip->reg_lock);
481 oldreg = oxygen_read8(chip, OXYGEN_ADC_MONITOR);
482 if ((!!value->value.integer.value[0] ^ !!invert) != 0)
483 newreg = oldreg | bit;
484 else
485 newreg = oldreg & ~bit;
486 changed = newreg != oldreg;
487 if (changed)
488 oxygen_write8(chip, OXYGEN_ADC_MONITOR, newreg);
489 spin_unlock_irq(&chip->reg_lock);
490 return changed;
491}
492
449static int ac97_switch_get(struct snd_kcontrol *ctl, 493static int ac97_switch_get(struct snd_kcontrol *ctl,
450 struct snd_ctl_elem_value *value) 494 struct snd_ctl_elem_value *value)
451{ 495{
@@ -466,6 +510,21 @@ static int ac97_switch_get(struct snd_kcontrol *ctl,
466 return 0; 510 return 0;
467} 511}
468 512
513static void mute_ac97_ctl(struct oxygen *chip, unsigned int control)
514{
515 unsigned int priv_idx = chip->controls[control]->private_value & 0xff;
516 u16 value;
517
518 value = oxygen_read_ac97(chip, 0, priv_idx);
519 if (!(value & 0x8000)) {
520 oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000);
521 if (chip->model->ac97_switch)
522 chip->model->ac97_switch(chip, priv_idx, 0x8000);
523 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
524 &chip->controls[control]->id);
525 }
526}
527
469static int ac97_switch_put(struct snd_kcontrol *ctl, 528static int ac97_switch_put(struct snd_kcontrol *ctl,
470 struct snd_ctl_elem_value *value) 529 struct snd_ctl_elem_value *value)
471{ 530{
@@ -487,9 +546,24 @@ static int ac97_switch_put(struct snd_kcontrol *ctl,
487 change = newreg != oldreg; 546 change = newreg != oldreg;
488 if (change) { 547 if (change) {
489 oxygen_write_ac97(chip, codec, index, newreg); 548 oxygen_write_ac97(chip, codec, index, newreg);
490 if (bitnr == 15 && chip->model->ac97_switch_hook) 549 if (codec == 0 && chip->model->ac97_switch)
491 chip->model->ac97_switch_hook(chip, codec, index, 550 chip->model->ac97_switch(chip, index, newreg & 0x8000);
492 newreg & 0x8000); 551 if (index == AC97_LINE) {
552 oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
553 newreg & 0x8000 ?
554 CM9780_GPO0 : 0, CM9780_GPO0);
555 if (!(newreg & 0x8000)) {
556 mute_ac97_ctl(chip, CONTROL_MIC_CAPTURE_SWITCH);
557 mute_ac97_ctl(chip, CONTROL_CD_CAPTURE_SWITCH);
558 mute_ac97_ctl(chip, CONTROL_AUX_CAPTURE_SWITCH);
559 }
560 } else if ((index == AC97_MIC || index == AC97_CD ||
561 index == AC97_VIDEO || index == AC97_AUX) &&
562 bitnr == 15 && !(newreg & 0x8000)) {
563 mute_ac97_ctl(chip, CONTROL_LINE_CAPTURE_SWITCH);
564 oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS,
565 CM9780_GPO0, CM9780_GPO0);
566 }
493 } 567 }
494 mutex_unlock(&chip->mutex); 568 mutex_unlock(&chip->mutex);
495 return change; 569 return change;
@@ -608,6 +682,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl,
608 .private_value = ((codec) << 24) | (index), \ 682 .private_value = ((codec) << 24) | (index), \
609 } 683 }
610 684
685static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0);
611static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0); 686static DECLARE_TLV_DB_SCALE(ac97_db_scale, -3450, 150, 0);
612static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0); 687static DECLARE_TLV_DB_SCALE(ac97_rec_db_scale, 0, 150, 0);
613 688
@@ -667,6 +742,9 @@ static const struct snd_kcontrol_new controls[] = {
667 .get = spdif_pcm_get, 742 .get = spdif_pcm_get,
668 .put = spdif_pcm_put, 743 .put = spdif_pcm_put,
669 }, 744 },
745};
746
747static const struct snd_kcontrol_new spdif_input_controls[] = {
670 { 748 {
671 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 749 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
672 .device = 1, 750 .device = 1,
@@ -692,11 +770,118 @@ static const struct snd_kcontrol_new controls[] = {
692 }, 770 },
693}; 771};
694 772
773static const struct {
774 unsigned int pcm_dev;
775 struct snd_kcontrol_new controls[2];
776} monitor_controls[] = {
777 {
778 .pcm_dev = CAPTURE_0_FROM_I2S_1,
779 .controls = {
780 {
781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
782 .name = "Analog Input Monitor Switch",
783 .info = snd_ctl_boolean_mono_info,
784 .get = monitor_get,
785 .put = monitor_put,
786 .private_value = OXYGEN_ADC_MONITOR_A,
787 },
788 {
789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
790 .name = "Analog Input Monitor Volume",
791 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
792 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
793 .info = monitor_volume_info,
794 .get = monitor_get,
795 .put = monitor_put,
796 .private_value = OXYGEN_ADC_MONITOR_A_HALF_VOL
797 | (1 << 8),
798 .tlv = { .p = monitor_db_scale, },
799 },
800 },
801 },
802 {
803 .pcm_dev = CAPTURE_0_FROM_I2S_2,
804 .controls = {
805 {
806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807 .name = "Analog Input Monitor Switch",
808 .info = snd_ctl_boolean_mono_info,
809 .get = monitor_get,
810 .put = monitor_put,
811 .private_value = OXYGEN_ADC_MONITOR_B,
812 },
813 {
814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
815 .name = "Analog Input Monitor Volume",
816 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
817 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
818 .info = monitor_volume_info,
819 .get = monitor_get,
820 .put = monitor_put,
821 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
822 | (1 << 8),
823 .tlv = { .p = monitor_db_scale, },
824 },
825 },
826 },
827 {
828 .pcm_dev = CAPTURE_2_FROM_I2S_2,
829 .controls = {
830 {
831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
832 .name = "Analog Input Monitor Switch",
833 .index = 1,
834 .info = snd_ctl_boolean_mono_info,
835 .get = monitor_get,
836 .put = monitor_put,
837 .private_value = OXYGEN_ADC_MONITOR_B,
838 },
839 {
840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
841 .name = "Analog Input Monitor Volume",
842 .index = 1,
843 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
844 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
845 .info = monitor_volume_info,
846 .get = monitor_get,
847 .put = monitor_put,
848 .private_value = OXYGEN_ADC_MONITOR_B_HALF_VOL
849 | (1 << 8),
850 .tlv = { .p = monitor_db_scale, },
851 },
852 },
853 },
854 {
855 .pcm_dev = CAPTURE_1_FROM_SPDIF,
856 .controls = {
857 {
858 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
859 .name = "Digital Input Monitor Switch",
860 .info = snd_ctl_boolean_mono_info,
861 .get = monitor_get,
862 .put = monitor_put,
863 .private_value = OXYGEN_ADC_MONITOR_C,
864 },
865 {
866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
867 .name = "Digital Input Monitor Volume",
868 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
869 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
870 .info = monitor_volume_info,
871 .get = monitor_get,
872 .put = monitor_put,
873 .private_value = OXYGEN_ADC_MONITOR_C_HALF_VOL
874 | (1 << 8),
875 .tlv = { .p = monitor_db_scale, },
876 },
877 },
878 },
879};
880
695static const struct snd_kcontrol_new ac97_controls[] = { 881static const struct snd_kcontrol_new ac97_controls[] = {
696 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC), 882 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC),
697 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), 883 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
698 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), 884 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
699 AC97_VOLUME("Line Capture Volume", 0, AC97_LINE),
700 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), 885 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
701 AC97_VOLUME("CD Capture Volume", 0, AC97_CD), 886 AC97_VOLUME("CD Capture Volume", 0, AC97_CD),
702 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), 887 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -756,6 +941,11 @@ static int add_controls(struct oxygen *chip,
756 return err; 941 return err;
757 if (err == 1) 942 if (err == 1)
758 continue; 943 continue;
944 if (!strcmp(template.name, "Master Playback Volume") &&
945 chip->model->dac_tlv) {
946 template.tlv.p = chip->model->dac_tlv;
947 template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
948 }
759 ctl = snd_ctl_new1(&template, chip); 949 ctl = snd_ctl_new1(&template, chip);
760 if (!ctl) 950 if (!ctl)
761 return -ENOMEM; 951 return -ENOMEM;
@@ -773,11 +963,26 @@ static int add_controls(struct oxygen *chip,
773 963
774int oxygen_mixer_init(struct oxygen *chip) 964int oxygen_mixer_init(struct oxygen *chip)
775{ 965{
966 unsigned int i;
776 int err; 967 int err;
777 968
778 err = add_controls(chip, controls, ARRAY_SIZE(controls)); 969 err = add_controls(chip, controls, ARRAY_SIZE(controls));
779 if (err < 0) 970 if (err < 0)
780 return err; 971 return err;
972 if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) {
973 err = add_controls(chip, spdif_input_controls,
974 ARRAY_SIZE(spdif_input_controls));
975 if (err < 0)
976 return err;
977 }
978 for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) {
979 if (!(chip->model->pcm_dev_cfg & monitor_controls[i].pcm_dev))
980 continue;
981 err = add_controls(chip, monitor_controls[i].controls,
982 ARRAY_SIZE(monitor_controls[i].controls));
983 if (err < 0)
984 return err;
985 }
781 if (chip->has_ac97_0) { 986 if (chip->has_ac97_0) {
782 err = add_controls(chip, ac97_controls, 987 err = add_controls(chip, ac97_controls,
783 ARRAY_SIZE(ac97_controls)); 988 ARRAY_SIZE(ac97_controls));