diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2012-10-20 06:21:36 -0400 |
---|---|---|
committer | Clemens Ladisch <clemens@ladisch.de> | 2012-10-20 17:46:13 -0400 |
commit | 16e434670e95398e22cd54b87e4eebe44ae6c179 (patch) | |
tree | 73b9c8c5a7ad9612be614ba894cfe5b30eacc166 /sound/drivers | |
parent | a0d271cbfed1dd50278c6b06bead3d00ba0a88f9 (diff) |
ALSA: dummy: allow disabling mixer controls
To make the testing of deactivated mixer controls easier (and for people
with common hardware, possible), add a control that deactivates some
other controls.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/drivers')
-rw-r--r-- | sound/drivers/dummy.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 54bb6644a598..4f522cf48455 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -134,6 +134,9 @@ struct snd_dummy { | |||
134 | spinlock_t mixer_lock; | 134 | spinlock_t mixer_lock; |
135 | int mixer_volume[MIXER_ADDR_LAST+1][2]; | 135 | int mixer_volume[MIXER_ADDR_LAST+1][2]; |
136 | int capture_source[MIXER_ADDR_LAST+1][2]; | 136 | int capture_source[MIXER_ADDR_LAST+1][2]; |
137 | int iobox; | ||
138 | struct snd_kcontrol *cd_volume_ctl; | ||
139 | struct snd_kcontrol *cd_switch_ctl; | ||
137 | const struct dummy_timer_ops *timer_ops; | 140 | const struct dummy_timer_ops *timer_ops; |
138 | }; | 141 | }; |
139 | 142 | ||
@@ -817,6 +820,57 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
817 | return change; | 820 | return change; |
818 | } | 821 | } |
819 | 822 | ||
823 | static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol, | ||
824 | struct snd_ctl_elem_info *info) | ||
825 | { | ||
826 | const char *const names[] = { "None", "CD Player" }; | ||
827 | |||
828 | return snd_ctl_enum_info(info, 1, 2, names); | ||
829 | } | ||
830 | |||
831 | static int snd_dummy_iobox_get(struct snd_kcontrol *kcontrol, | ||
832 | struct snd_ctl_elem_value *value) | ||
833 | { | ||
834 | struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol); | ||
835 | |||
836 | value->value.enumerated.item[0] = dummy->iobox; | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | static int snd_dummy_iobox_put(struct snd_kcontrol *kcontrol, | ||
841 | struct snd_ctl_elem_value *value) | ||
842 | { | ||
843 | struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol); | ||
844 | int changed; | ||
845 | |||
846 | if (value->value.enumerated.item[0] > 1) | ||
847 | return -EINVAL; | ||
848 | |||
849 | changed = value->value.enumerated.item[0] != dummy->iobox; | ||
850 | if (changed) { | ||
851 | dummy->iobox = value->value.enumerated.item[0]; | ||
852 | |||
853 | if (dummy->iobox) { | ||
854 | dummy->cd_volume_ctl->vd[0].access &= | ||
855 | ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
856 | dummy->cd_switch_ctl->vd[0].access &= | ||
857 | ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
858 | } else { | ||
859 | dummy->cd_volume_ctl->vd[0].access |= | ||
860 | SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
861 | dummy->cd_switch_ctl->vd[0].access |= | ||
862 | SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
863 | } | ||
864 | |||
865 | snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO, | ||
866 | &dummy->cd_volume_ctl->id); | ||
867 | snd_ctl_notify(dummy->card, SNDRV_CTL_EVENT_MASK_INFO, | ||
868 | &dummy->cd_switch_ctl->id); | ||
869 | } | ||
870 | |||
871 | return changed; | ||
872 | } | ||
873 | |||
820 | static struct snd_kcontrol_new snd_dummy_controls[] = { | 874 | static struct snd_kcontrol_new snd_dummy_controls[] = { |
821 | DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER), | 875 | DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER), |
822 | DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER), | 876 | DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER), |
@@ -827,22 +881,37 @@ DUMMY_CAPSRC("Line Capture Switch", 0, MIXER_ADDR_LINE), | |||
827 | DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC), | 881 | DUMMY_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC), |
828 | DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC), | 882 | DUMMY_CAPSRC("Mic Capture Switch", 0, MIXER_ADDR_MIC), |
829 | DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD), | 883 | DUMMY_VOLUME("CD Volume", 0, MIXER_ADDR_CD), |
830 | DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD) | 884 | DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_CD), |
885 | { | ||
886 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
887 | .name = "External I/O Box", | ||
888 | .info = snd_dummy_iobox_info, | ||
889 | .get = snd_dummy_iobox_get, | ||
890 | .put = snd_dummy_iobox_put, | ||
891 | }, | ||
831 | }; | 892 | }; |
832 | 893 | ||
833 | static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy) | 894 | static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy) |
834 | { | 895 | { |
835 | struct snd_card *card = dummy->card; | 896 | struct snd_card *card = dummy->card; |
897 | struct snd_kcontrol *kcontrol; | ||
836 | unsigned int idx; | 898 | unsigned int idx; |
837 | int err; | 899 | int err; |
838 | 900 | ||
839 | spin_lock_init(&dummy->mixer_lock); | 901 | spin_lock_init(&dummy->mixer_lock); |
840 | strcpy(card->mixername, "Dummy Mixer"); | 902 | strcpy(card->mixername, "Dummy Mixer"); |
903 | dummy->iobox = 1; | ||
841 | 904 | ||
842 | for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) { | 905 | for (idx = 0; idx < ARRAY_SIZE(snd_dummy_controls); idx++) { |
843 | err = snd_ctl_add(card, snd_ctl_new1(&snd_dummy_controls[idx], dummy)); | 906 | kcontrol = snd_ctl_new1(&snd_dummy_controls[idx], dummy); |
907 | err = snd_ctl_add(card, kcontrol); | ||
844 | if (err < 0) | 908 | if (err < 0) |
845 | return err; | 909 | return err; |
910 | if (!strcmp(kcontrol->id.name, "CD Volume")) | ||
911 | dummy->cd_volume_ctl = kcontrol; | ||
912 | else if (!strcmp(kcontrol->id.name, "CD Capture Switch")) | ||
913 | dummy->cd_switch_ctl = kcontrol; | ||
914 | |||
846 | } | 915 | } |
847 | return 0; | 916 | return 0; |
848 | } | 917 | } |