aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2007-07-27 13:02:40 -0400
committerJaroslav Kysela <perex@perex.cz>2007-10-16 09:58:11 -0400
commit532d5381793f3c824f8ff68d7067fab8c76bb811 (patch)
tree41a27e08a905c28576167b711ccc2b06ea234a9f /sound/pci/hda/hda_codec.c
parent2807314d467e7dd929c42050031aabbd28e78f0b (diff)
[ALSA] hda-codec - Add a generic bind-control helper
Added callbacks for a generic bind-control of mixer elements. This can be used for creating a mixer element controlling multiple widgets at the same time. Two macros, HDA_BIND_VOL() and HDA_BIND_SW(), are introduced for creating bind-volume and bind-switch, respectively. It taks the mixer element name and struct hda_bind_ctls pointer, which contains the real control callbacks in ops field and long array for private_value of each bound widget. All widgets have to be the same type (i.e. the same amp capability). Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e7843ffeeb2f..36879a93eac4 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1006,6 +1006,93 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1006} 1006}
1007 1007
1008/* 1008/*
1009 * generic bound volume/swtich controls
1010 */
1011int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1012 struct snd_ctl_elem_info *uinfo)
1013{
1014 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1015 struct hda_bind_ctls *c;
1016 int err;
1017
1018 c = (struct hda_bind_ctls *)kcontrol->private_value;
1019 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1020 kcontrol->private_value = *c->values;
1021 err = c->ops->info(kcontrol, uinfo);
1022 kcontrol->private_value = (long)c;
1023 mutex_unlock(&codec->spdif_mutex);
1024 return err;
1025}
1026
1027int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1028 struct snd_ctl_elem_value *ucontrol)
1029{
1030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1031 struct hda_bind_ctls *c;
1032 int err;
1033
1034 c = (struct hda_bind_ctls *)kcontrol->private_value;
1035 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1036 kcontrol->private_value = *c->values;
1037 err = c->ops->get(kcontrol, ucontrol);
1038 kcontrol->private_value = (long)c;
1039 mutex_unlock(&codec->spdif_mutex);
1040 return err;
1041}
1042
1043int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1044 struct snd_ctl_elem_value *ucontrol)
1045{
1046 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1047 struct hda_bind_ctls *c;
1048 unsigned long *vals;
1049 int err = 0, change = 0;
1050
1051 c = (struct hda_bind_ctls *)kcontrol->private_value;
1052 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1053 for (vals = c->values; *vals; vals++) {
1054 kcontrol->private_value = *vals;
1055 err = c->ops->put(kcontrol, ucontrol);
1056 if (err < 0)
1057 break;
1058 change |= err;
1059 }
1060 kcontrol->private_value = (long)c;
1061 mutex_unlock(&codec->spdif_mutex);
1062 return err < 0 ? err : change;
1063}
1064
1065int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1066 unsigned int size, unsigned int __user *tlv)
1067{
1068 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1069 struct hda_bind_ctls *c;
1070 int err;
1071
1072 c = (struct hda_bind_ctls *)kcontrol->private_value;
1073 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1074 kcontrol->private_value = *c->values;
1075 err = c->ops->tlv(kcontrol, op_flag, size, tlv);
1076 kcontrol->private_value = (long)c;
1077 mutex_unlock(&codec->spdif_mutex);
1078 return err;
1079}
1080
1081struct hda_ctl_ops snd_hda_bind_vol = {
1082 .info = snd_hda_mixer_amp_volume_info,
1083 .get = snd_hda_mixer_amp_volume_get,
1084 .put = snd_hda_mixer_amp_volume_put,
1085 .tlv = snd_hda_mixer_amp_tlv
1086};
1087
1088struct hda_ctl_ops snd_hda_bind_sw = {
1089 .info = snd_hda_mixer_amp_switch_info,
1090 .get = snd_hda_mixer_amp_switch_get,
1091 .put = snd_hda_mixer_amp_switch_put,
1092 .tlv = snd_hda_mixer_amp_tlv
1093};
1094
1095/*
1009 * SPDIF out controls 1096 * SPDIF out controls
1010 */ 1097 */
1011 1098