diff options
-rw-r--r-- | sound/pci/hda/hda_codec.c | 45 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 22 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 133 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 152 |
4 files changed, 208 insertions, 144 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 57b5a0a83c8d..0dbeeaf6113a 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -821,6 +821,51 @@ int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t | |||
821 | } | 821 | } |
822 | 822 | ||
823 | /* | 823 | /* |
824 | * bound volume controls | ||
825 | * | ||
826 | * bind multiple volumes (# indices, from 0) | ||
827 | */ | ||
828 | |||
829 | #define AMP_VAL_IDX_SHIFT 19 | ||
830 | #define AMP_VAL_IDX_MASK (0x0f<<19) | ||
831 | |||
832 | int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
833 | { | ||
834 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
835 | unsigned long pval; | ||
836 | int err; | ||
837 | |||
838 | down(&codec->spdif_mutex); /* reuse spdif_mutex */ | ||
839 | pval = kcontrol->private_value; | ||
840 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
841 | err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
842 | kcontrol->private_value = pval; | ||
843 | up(&codec->spdif_mutex); | ||
844 | return err; | ||
845 | } | ||
846 | |||
847 | int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
848 | { | ||
849 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
850 | unsigned long pval; | ||
851 | int i, indices, err = 0, change = 0; | ||
852 | |||
853 | down(&codec->spdif_mutex); /* reuse spdif_mutex */ | ||
854 | pval = kcontrol->private_value; | ||
855 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | ||
856 | for (i = 0; i < indices; i++) { | ||
857 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); | ||
858 | err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
859 | if (err < 0) | ||
860 | break; | ||
861 | change |= err; | ||
862 | } | ||
863 | kcontrol->private_value = pval; | ||
864 | up(&codec->spdif_mutex); | ||
865 | return err < 0 ? err : change; | ||
866 | } | ||
867 | |||
868 | /* | ||
824 | * SPDIF out controls | 869 | * SPDIF out controls |
825 | */ | 870 | */ |
826 | 871 | ||
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 810cfd2d9bba..f51a56f813c8 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -27,28 +27,36 @@ | |||
27 | * for mixer controls | 27 | * for mixer controls |
28 | */ | 28 | */ |
29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) | 29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) |
30 | /* mono volume with index (index=0,1,...) (channel=1,2) */ | ||
30 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 31 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
31 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 32 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
32 | .info = snd_hda_mixer_amp_volume_info, \ | 33 | .info = snd_hda_mixer_amp_volume_info, \ |
33 | .get = snd_hda_mixer_amp_volume_get, \ | 34 | .get = snd_hda_mixer_amp_volume_get, \ |
34 | .put = snd_hda_mixer_amp_volume_put, \ | 35 | .put = snd_hda_mixer_amp_volume_put, \ |
35 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 36 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
37 | /* stereo volume with index */ | ||
36 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ | 38 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ |
37 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | 39 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) |
40 | /* mono volume */ | ||
38 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ | 41 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ |
39 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) | 42 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) |
43 | /* stereo volume */ | ||
40 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ | 44 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ |
41 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) | 45 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) |
46 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ | ||
42 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 47 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
43 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 48 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
44 | .info = snd_hda_mixer_amp_switch_info, \ | 49 | .info = snd_hda_mixer_amp_switch_info, \ |
45 | .get = snd_hda_mixer_amp_switch_get, \ | 50 | .get = snd_hda_mixer_amp_switch_get, \ |
46 | .put = snd_hda_mixer_amp_switch_put, \ | 51 | .put = snd_hda_mixer_amp_switch_put, \ |
47 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 52 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
53 | /* stereo mute switch with index */ | ||
48 | #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \ | 54 | #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \ |
49 | HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | 55 | HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) |
56 | /* mono mute switch */ | ||
50 | #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \ | 57 | #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \ |
51 | HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction) | 58 | HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction) |
59 | /* stereo mute switch */ | ||
52 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ | 60 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ |
53 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) | 61 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) |
54 | 62 | ||
@@ -59,6 +67,20 @@ int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t | |||
59 | int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | 67 | int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); |
60 | int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | 68 | int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); |
61 | 69 | ||
70 | /* mono switch binding multiple inputs */ | ||
71 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | ||
72 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
73 | .info = snd_hda_mixer_amp_switch_info, \ | ||
74 | .get = snd_hda_mixer_bind_switch_get, \ | ||
75 | .put = snd_hda_mixer_bind_switch_put, \ | ||
76 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | ||
77 | |||
78 | /* stereo switch binding multiple inputs */ | ||
79 | #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) | ||
80 | |||
81 | int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | ||
82 | int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | ||
83 | |||
62 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); | 84 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); |
63 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); | 85 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); |
64 | 86 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index da6874d3988c..d7d636decef8 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -28,15 +28,38 @@ | |||
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | 29 | ||
30 | struct ad198x_spec { | 30 | struct ad198x_spec { |
31 | struct semaphore amp_mutex; /* PCM volume/mute control mutex */ | 31 | snd_kcontrol_new_t *mixers[5]; |
32 | struct hda_multi_out multiout; /* playback */ | 32 | int num_mixers; |
33 | hda_nid_t adc_nid; | 33 | |
34 | const struct hda_verb *init_verbs[3]; /* initialization verbs | ||
35 | * don't forget NULL termination! | ||
36 | */ | ||
37 | unsigned int num_init_verbs; | ||
38 | |||
39 | /* playback */ | ||
40 | struct hda_multi_out multiout; /* playback set-up | ||
41 | * max_channels, dacs must be set | ||
42 | * dig_out_nid and hp_nid are optional | ||
43 | */ | ||
44 | |||
45 | /* capture */ | ||
46 | unsigned int num_adc_nids; | ||
47 | hda_nid_t *adc_nids; | ||
48 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | ||
49 | |||
50 | /* capture source */ | ||
34 | const struct hda_input_mux *input_mux; | 51 | const struct hda_input_mux *input_mux; |
35 | unsigned int cur_mux; /* capture source */ | 52 | unsigned int cur_mux[3]; |
53 | |||
54 | /* channel model */ | ||
55 | const struct alc_channel_mode *channel_mode; | ||
56 | int num_channel_mode; | ||
57 | |||
58 | /* PCM information */ | ||
59 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | ||
60 | |||
61 | struct semaphore amp_mutex; /* PCM volume/mute control mutex */ | ||
36 | unsigned int spdif_route; | 62 | unsigned int spdif_route; |
37 | snd_kcontrol_new_t *mixers; | ||
38 | const struct hda_verb *init_verbs; | ||
39 | struct hda_pcm pcm_rec[2]; /* PCM information */ | ||
40 | }; | 63 | }; |
41 | 64 | ||
42 | /* | 65 | /* |
@@ -54,8 +77,9 @@ static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
54 | { | 77 | { |
55 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 78 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
56 | struct ad198x_spec *spec = codec->spec; | 79 | struct ad198x_spec *spec = codec->spec; |
80 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
57 | 81 | ||
58 | ucontrol->value.enumerated.item[0] = spec->cur_mux; | 82 | ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; |
59 | return 0; | 83 | return 0; |
60 | } | 84 | } |
61 | 85 | ||
@@ -63,9 +87,10 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
63 | { | 87 | { |
64 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 88 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
65 | struct ad198x_spec *spec = codec->spec; | 89 | struct ad198x_spec *spec = codec->spec; |
90 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
66 | 91 | ||
67 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 92 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
68 | spec->adc_nid, &spec->cur_mux); | 93 | spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]); |
69 | } | 94 | } |
70 | 95 | ||
71 | /* | 96 | /* |
@@ -74,22 +99,34 @@ static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
74 | static int ad198x_init(struct hda_codec *codec) | 99 | static int ad198x_init(struct hda_codec *codec) |
75 | { | 100 | { |
76 | struct ad198x_spec *spec = codec->spec; | 101 | struct ad198x_spec *spec = codec->spec; |
77 | snd_hda_sequence_write(codec, spec->init_verbs); | 102 | int i; |
103 | |||
104 | for (i = 0; i < spec->num_init_verbs; i++) | ||
105 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | ||
78 | return 0; | 106 | return 0; |
79 | } | 107 | } |
80 | 108 | ||
81 | static int ad198x_build_controls(struct hda_codec *codec) | 109 | static int ad198x_build_controls(struct hda_codec *codec) |
82 | { | 110 | { |
83 | struct ad198x_spec *spec = codec->spec; | 111 | struct ad198x_spec *spec = codec->spec; |
112 | unsigned int i; | ||
84 | int err; | 113 | int err; |
85 | 114 | ||
86 | err = snd_hda_add_new_ctls(codec, spec->mixers); | 115 | for (i = 0; i < spec->num_mixers; i++) { |
87 | if (err < 0) | 116 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
88 | return err; | 117 | if (err < 0) |
89 | if (spec->multiout.dig_out_nid) | 118 | return err; |
119 | } | ||
120 | if (spec->multiout.dig_out_nid) { | ||
90 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 121 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); |
91 | if (err < 0) | 122 | if (err < 0) |
92 | return err; | 123 | return err; |
124 | } | ||
125 | if (spec->dig_in_nid) { | ||
126 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | ||
127 | if (err < 0) | ||
128 | return err; | ||
129 | } | ||
93 | return 0; | 130 | return 0; |
94 | } | 131 | } |
95 | 132 | ||
@@ -152,7 +189,8 @@ static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
152 | snd_pcm_substream_t *substream) | 189 | snd_pcm_substream_t *substream) |
153 | { | 190 | { |
154 | struct ad198x_spec *spec = codec->spec; | 191 | struct ad198x_spec *spec = codec->spec; |
155 | snd_hda_codec_setup_stream(codec, spec->adc_nid, stream_tag, 0, format); | 192 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
193 | stream_tag, 0, format); | ||
156 | return 0; | 194 | return 0; |
157 | } | 195 | } |
158 | 196 | ||
@@ -161,7 +199,8 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
161 | snd_pcm_substream_t *substream) | 199 | snd_pcm_substream_t *substream) |
162 | { | 200 | { |
163 | struct ad198x_spec *spec = codec->spec; | 201 | struct ad198x_spec *spec = codec->spec; |
164 | snd_hda_codec_setup_stream(codec, spec->adc_nid, 0, 0, 0); | 202 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], |
203 | 0, 0, 0); | ||
165 | return 0; | 204 | return 0; |
166 | } | 205 | } |
167 | 206 | ||
@@ -171,7 +210,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
171 | static struct hda_pcm_stream ad198x_pcm_analog_playback = { | 210 | static struct hda_pcm_stream ad198x_pcm_analog_playback = { |
172 | .substreams = 1, | 211 | .substreams = 1, |
173 | .channels_min = 2, | 212 | .channels_min = 2, |
174 | .channels_max = 6, | 213 | .channels_max = 6, /* changed later */ |
175 | .nid = 0, /* fill later */ | 214 | .nid = 0, /* fill later */ |
176 | .ops = { | 215 | .ops = { |
177 | .open = ad198x_playback_pcm_open, | 216 | .open = ad198x_playback_pcm_open, |
@@ -181,7 +220,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = { | |||
181 | }; | 220 | }; |
182 | 221 | ||
183 | static struct hda_pcm_stream ad198x_pcm_analog_capture = { | 222 | static struct hda_pcm_stream ad198x_pcm_analog_capture = { |
184 | .substreams = 2, | 223 | .substreams = 1, |
185 | .channels_min = 2, | 224 | .channels_min = 2, |
186 | .channels_max = 2, | 225 | .channels_max = 2, |
187 | .nid = 0, /* fill later */ | 226 | .nid = 0, /* fill later */ |
@@ -202,6 +241,13 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { | |||
202 | }, | 241 | }, |
203 | }; | 242 | }; |
204 | 243 | ||
244 | static struct hda_pcm_stream ad198x_pcm_digital_capture = { | ||
245 | .substreams = 1, | ||
246 | .channels_min = 2, | ||
247 | .channels_max = 2, | ||
248 | /* NID is set in alc_build_pcms */ | ||
249 | }; | ||
250 | |||
205 | static int ad198x_build_pcms(struct hda_codec *codec) | 251 | static int ad198x_build_pcms(struct hda_codec *codec) |
206 | { | 252 | { |
207 | struct ad198x_spec *spec = codec->spec; | 253 | struct ad198x_spec *spec = codec->spec; |
@@ -215,7 +261,8 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
215 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; | 261 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; |
216 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; | 262 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; |
217 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; | 263 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; |
218 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nid; | 264 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; |
265 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
219 | 266 | ||
220 | if (spec->multiout.dig_out_nid) { | 267 | if (spec->multiout.dig_out_nid) { |
221 | info++; | 268 | info++; |
@@ -223,6 +270,10 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
223 | info->name = "AD198x Digital"; | 270 | info->name = "AD198x Digital"; |
224 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; | 271 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; |
225 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | 272 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; |
273 | if (spec->dig_in_nid) { | ||
274 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture; | ||
275 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; | ||
276 | } | ||
226 | } | 277 | } |
227 | 278 | ||
228 | return 0; | 279 | return 0; |
@@ -237,10 +288,15 @@ static void ad198x_free(struct hda_codec *codec) | |||
237 | static int ad198x_resume(struct hda_codec *codec) | 288 | static int ad198x_resume(struct hda_codec *codec) |
238 | { | 289 | { |
239 | struct ad198x_spec *spec = codec->spec; | 290 | struct ad198x_spec *spec = codec->spec; |
291 | int i; | ||
240 | 292 | ||
241 | ad198x_init(codec); | 293 | ad198x_init(codec); |
242 | snd_hda_resume_ctls(codec, spec->mixers); | 294 | for (i = 0; i < spec->num_mixers; i++) |
243 | snd_hda_resume_spdif_out(codec); | 295 | snd_hda_resume_ctls(codec, spec->mixers[i]); |
296 | if (spec->multiout.dig_out_nid) | ||
297 | snd_hda_resume_spdif_out(codec); | ||
298 | if (spec->dig_in_nid) | ||
299 | snd_hda_resume_spdif_in(codec); | ||
244 | return 0; | 300 | return 0; |
245 | } | 301 | } |
246 | #endif | 302 | #endif |
@@ -269,6 +325,7 @@ static struct hda_codec_ops ad198x_patch_ops = { | |||
269 | static hda_nid_t ad1986a_dac_nids[3] = { | 325 | static hda_nid_t ad1986a_dac_nids[3] = { |
270 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC | 326 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC |
271 | }; | 327 | }; |
328 | static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; | ||
272 | 329 | ||
273 | static struct hda_input_mux ad1986a_capture_source = { | 330 | static struct hda_input_mux ad1986a_capture_source = { |
274 | .num_items = 7, | 331 | .num_items = 7, |
@@ -476,10 +533,13 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
476 | spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); | 533 | spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); |
477 | spec->multiout.dac_nids = ad1986a_dac_nids; | 534 | spec->multiout.dac_nids = ad1986a_dac_nids; |
478 | spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; | 535 | spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; |
479 | spec->adc_nid = AD1986A_ADC; | 536 | spec->num_adc_nids = 1; |
537 | spec->adc_nids = ad1986a_adc_nids; | ||
480 | spec->input_mux = &ad1986a_capture_source; | 538 | spec->input_mux = &ad1986a_capture_source; |
481 | spec->mixers = ad1986a_mixers; | 539 | spec->num_mixers = 1; |
482 | spec->init_verbs = ad1986a_init_verbs; | 540 | spec->mixers[0] = ad1986a_mixers; |
541 | spec->num_init_verbs = 1; | ||
542 | spec->init_verbs[0] = ad1986a_init_verbs; | ||
483 | 543 | ||
484 | codec->patch_ops = ad198x_patch_ops; | 544 | codec->patch_ops = ad198x_patch_ops; |
485 | 545 | ||
@@ -495,6 +555,7 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
495 | #define AD1983_ADC 0x04 | 555 | #define AD1983_ADC 0x04 |
496 | 556 | ||
497 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; | 557 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; |
558 | static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; | ||
498 | 559 | ||
499 | static struct hda_input_mux ad1983_capture_source = { | 560 | static struct hda_input_mux ad1983_capture_source = { |
500 | .num_items = 4, | 561 | .num_items = 4, |
@@ -619,6 +680,7 @@ static struct hda_verb ad1983_init_verbs[] = { | |||
619 | { } /* end */ | 680 | { } /* end */ |
620 | }; | 681 | }; |
621 | 682 | ||
683 | |||
622 | static int patch_ad1983(struct hda_codec *codec) | 684 | static int patch_ad1983(struct hda_codec *codec) |
623 | { | 685 | { |
624 | struct ad198x_spec *spec; | 686 | struct ad198x_spec *spec; |
@@ -634,10 +696,13 @@ static int patch_ad1983(struct hda_codec *codec) | |||
634 | spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); | 696 | spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); |
635 | spec->multiout.dac_nids = ad1983_dac_nids; | 697 | spec->multiout.dac_nids = ad1983_dac_nids; |
636 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; | 698 | spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; |
637 | spec->adc_nid = AD1983_ADC; | 699 | spec->num_adc_nids = 1; |
700 | spec->adc_nids = ad1983_adc_nids; | ||
638 | spec->input_mux = &ad1983_capture_source; | 701 | spec->input_mux = &ad1983_capture_source; |
639 | spec->mixers = ad1983_mixers; | 702 | spec->num_mixers = 1; |
640 | spec->init_verbs = ad1983_init_verbs; | 703 | spec->mixers[0] = ad1983_mixers; |
704 | spec->num_init_verbs = 1; | ||
705 | spec->init_verbs[0] = ad1983_init_verbs; | ||
641 | spec->spdif_route = 0; | 706 | spec->spdif_route = 0; |
642 | 707 | ||
643 | codec->patch_ops = ad198x_patch_ops; | 708 | codec->patch_ops = ad198x_patch_ops; |
@@ -655,6 +720,7 @@ static int patch_ad1983(struct hda_codec *codec) | |||
655 | #define AD1981_ADC 0x04 | 720 | #define AD1981_ADC 0x04 |
656 | 721 | ||
657 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; | 722 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; |
723 | static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; | ||
658 | 724 | ||
659 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ | 725 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ |
660 | static struct hda_input_mux ad1981_capture_source = { | 726 | static struct hda_input_mux ad1981_capture_source = { |
@@ -775,10 +841,13 @@ static int patch_ad1981(struct hda_codec *codec) | |||
775 | spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); | 841 | spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); |
776 | spec->multiout.dac_nids = ad1981_dac_nids; | 842 | spec->multiout.dac_nids = ad1981_dac_nids; |
777 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; | 843 | spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; |
778 | spec->adc_nid = AD1981_ADC; | 844 | spec->num_adc_nids = 1; |
845 | spec->adc_nids = ad1981_adc_nids; | ||
779 | spec->input_mux = &ad1981_capture_source; | 846 | spec->input_mux = &ad1981_capture_source; |
780 | spec->mixers = ad1981_mixers; | 847 | spec->num_mixers = 1; |
781 | spec->init_verbs = ad1981_init_verbs; | 848 | spec->mixers[0] = ad1981_mixers; |
849 | spec->num_init_verbs = 1; | ||
850 | spec->init_verbs[0] = ad1981_init_verbs; | ||
782 | spec->spdif_route = 0; | 851 | spec->spdif_route = 0; |
783 | 852 | ||
784 | codec->patch_ops = ad198x_patch_ops; | 853 | codec->patch_ops = ad198x_patch_ops; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 48356ab04579..cffb83fdcff7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -115,8 +115,6 @@ struct alc_spec { | |||
115 | /* PCM information */ | 115 | /* PCM information */ |
116 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ | 116 | struct hda_pcm pcm_rec[2]; /* used in alc_build_pcms() */ |
117 | 117 | ||
118 | struct semaphore bind_mutex; /* for bound controls */ | ||
119 | |||
120 | /* dynamic controls, init_verbs and input_mux */ | 118 | /* dynamic controls, init_verbs and input_mux */ |
121 | struct auto_pin_cfg autocfg; | 119 | struct auto_pin_cfg autocfg; |
122 | unsigned int num_kctl_alloc, num_kctl_used; | 120 | unsigned int num_kctl_alloc, num_kctl_used; |
@@ -220,73 +218,6 @@ static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *uc | |||
220 | 218 | ||
221 | 219 | ||
222 | /* | 220 | /* |
223 | * bound volume controls | ||
224 | * | ||
225 | * bind multiple volumes (# indices, from 0) | ||
226 | */ | ||
227 | |||
228 | #define AMP_VAL_IDX_SHIFT 19 | ||
229 | #define AMP_VAL_IDX_MASK (0x0f<<19) | ||
230 | |||
231 | static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | ||
232 | { | ||
233 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
234 | struct alc_spec *spec = codec->spec; | ||
235 | unsigned long pval; | ||
236 | |||
237 | down(&spec->bind_mutex); | ||
238 | pval = kcontrol->private_value; | ||
239 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
240 | snd_hda_mixer_amp_switch_info(kcontrol, uinfo); | ||
241 | kcontrol->private_value = pval; | ||
242 | up(&spec->bind_mutex); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
247 | { | ||
248 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
249 | struct alc_spec *spec = codec->spec; | ||
250 | unsigned long pval; | ||
251 | |||
252 | down(&spec->bind_mutex); | ||
253 | pval = kcontrol->private_value; | ||
254 | kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ | ||
255 | snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
256 | kcontrol->private_value = pval; | ||
257 | up(&spec->bind_mutex); | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
262 | { | ||
263 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
264 | struct alc_spec *spec = codec->spec; | ||
265 | unsigned long pval; | ||
266 | int i, indices, change = 0; | ||
267 | |||
268 | down(&spec->bind_mutex); | ||
269 | pval = kcontrol->private_value; | ||
270 | indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; | ||
271 | for (i = 0; i < indices; i++) { | ||
272 | kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); | ||
273 | change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
274 | } | ||
275 | kcontrol->private_value = pval; | ||
276 | up(&spec->bind_mutex); | ||
277 | return change; | ||
278 | } | ||
279 | |||
280 | #define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | ||
281 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
282 | .info = alc_bind_switch_info, \ | ||
283 | .get = alc_bind_switch_get, \ | ||
284 | .put = alc_bind_switch_put, \ | ||
285 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | ||
286 | |||
287 | #define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir) | ||
288 | |||
289 | /* | ||
290 | * Control of pin widget settings via the mixer. Only boolean settings are | 221 | * Control of pin widget settings via the mixer. Only boolean settings are |
291 | * supported, so VrefEn can't be controlled using these functions as they | 222 | * supported, so VrefEn can't be controlled using these functions as they |
292 | * stand. | 223 | * stand. |
@@ -404,13 +335,13 @@ static struct alc_channel_mode alc880_threestack_modes[2] = { | |||
404 | 335 | ||
405 | static snd_kcontrol_new_t alc880_three_stack_mixer[] = { | 336 | static snd_kcontrol_new_t alc880_three_stack_mixer[] = { |
406 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 337 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
407 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 338 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
408 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 339 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
409 | ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), | 340 | HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), |
410 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 341 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
411 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 342 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
412 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 343 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
413 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 344 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
414 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 345 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
415 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 346 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
416 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 347 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -491,7 +422,7 @@ static snd_kcontrol_new_t alc880_capture_alt_mixer[] = { | |||
491 | /* additional mixers to alc880_three_stack_mixer */ | 422 | /* additional mixers to alc880_three_stack_mixer */ |
492 | static snd_kcontrol_new_t alc880_five_stack_mixer[] = { | 423 | static snd_kcontrol_new_t alc880_five_stack_mixer[] = { |
493 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 424 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
494 | ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), | 425 | HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), |
495 | { } /* end */ | 426 | { } /* end */ |
496 | }; | 427 | }; |
497 | 428 | ||
@@ -548,15 +479,15 @@ static struct alc_channel_mode alc880_sixstack_modes[1] = { | |||
548 | 479 | ||
549 | static snd_kcontrol_new_t alc880_six_stack_mixer[] = { | 480 | static snd_kcontrol_new_t alc880_six_stack_mixer[] = { |
550 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 481 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
551 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 482 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
552 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 483 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
553 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 484 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
554 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 485 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
555 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 486 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
556 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 487 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
557 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 488 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
558 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 489 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
559 | ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 490 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
560 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 491 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
561 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 492 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
562 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 493 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -616,13 +547,13 @@ static struct alc_channel_mode alc880_w810_modes[1] = { | |||
616 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ | 547 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ |
617 | static snd_kcontrol_new_t alc880_w810_base_mixer[] = { | 548 | static snd_kcontrol_new_t alc880_w810_base_mixer[] = { |
618 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 549 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
619 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 550 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
620 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 551 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
621 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 552 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
622 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 553 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
623 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 554 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
624 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 555 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
625 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 556 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
626 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 557 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
627 | { } /* end */ | 558 | { } /* end */ |
628 | }; | 559 | }; |
@@ -647,9 +578,9 @@ static struct alc_channel_mode alc880_2_jack_modes[1] = { | |||
647 | 578 | ||
648 | static snd_kcontrol_new_t alc880_z71v_mixer[] = { | 579 | static snd_kcontrol_new_t alc880_z71v_mixer[] = { |
649 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 580 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
650 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 581 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
651 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 582 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
652 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | 583 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), |
653 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 584 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
654 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 585 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
655 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 586 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -673,9 +604,9 @@ static hda_nid_t alc880_f1734_dac_nids[1] = { | |||
673 | 604 | ||
674 | static snd_kcontrol_new_t alc880_f1734_mixer[] = { | 605 | static snd_kcontrol_new_t alc880_f1734_mixer[] = { |
675 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 606 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
676 | ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 607 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
677 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 608 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
678 | ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | 609 | HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT), |
679 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 610 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
680 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 611 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
681 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 612 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -698,13 +629,13 @@ static snd_kcontrol_new_t alc880_f1734_mixer[] = { | |||
698 | 629 | ||
699 | static snd_kcontrol_new_t alc880_asus_mixer[] = { | 630 | static snd_kcontrol_new_t alc880_asus_mixer[] = { |
700 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 631 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
701 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 632 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
702 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 633 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
703 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 634 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
704 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 635 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
705 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 636 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
706 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 637 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
707 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 638 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
708 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 639 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
709 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 640 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
710 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 641 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -1433,10 +1364,10 @@ static snd_kcontrol_new_t alc880_test_mixer[] = { | |||
1433 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 1364 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
1434 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | 1365 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), |
1435 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 1366 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
1436 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 1367 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
1437 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 1368 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
1438 | ALC_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), | 1369 | HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), |
1439 | ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 1370 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
1440 | PIN_CTL_TEST("Front Pin Mode", 0x14), | 1371 | PIN_CTL_TEST("Front Pin Mode", 0x14), |
1441 | PIN_CTL_TEST("Surround Pin Mode", 0x15), | 1372 | PIN_CTL_TEST("Surround Pin Mode", 0x15), |
1442 | PIN_CTL_TEST("CLFE Pin Mode", 0x16), | 1373 | PIN_CTL_TEST("CLFE Pin Mode", 0x16), |
@@ -1819,7 +1750,7 @@ enum { | |||
1819 | static snd_kcontrol_new_t alc880_control_templates[] = { | 1750 | static snd_kcontrol_new_t alc880_control_templates[] = { |
1820 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 1751 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
1821 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 1752 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
1822 | ALC_BIND_MUTE(NULL, 0, 0, 0), | 1753 | HDA_BIND_MUTE(NULL, 0, 0, 0), |
1823 | }; | 1754 | }; |
1824 | 1755 | ||
1825 | /* add dynamic controls */ | 1756 | /* add dynamic controls */ |
@@ -2137,7 +2068,6 @@ static int patch_alc880(struct hda_codec *codec) | |||
2137 | if (spec == NULL) | 2068 | if (spec == NULL) |
2138 | return -ENOMEM; | 2069 | return -ENOMEM; |
2139 | 2070 | ||
2140 | init_MUTEX(&spec->bind_mutex); | ||
2141 | codec->spec = spec; | 2071 | codec->spec = spec; |
2142 | 2072 | ||
2143 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); | 2073 | board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); |
@@ -2278,7 +2208,7 @@ static struct alc_channel_mode alc260_modes[1] = { | |||
2278 | 2208 | ||
2279 | static snd_kcontrol_new_t alc260_base_mixer[] = { | 2209 | static snd_kcontrol_new_t alc260_base_mixer[] = { |
2280 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2210 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2281 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 2211 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
2282 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2212 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
2283 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 2213 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
2284 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | 2214 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), |
@@ -2290,9 +2220,9 @@ static snd_kcontrol_new_t alc260_base_mixer[] = { | |||
2290 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), | 2220 | HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT), |
2291 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), | 2221 | HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT), |
2292 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 2222 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
2293 | ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | 2223 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), |
2294 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 2224 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
2295 | ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 2225 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
2296 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | 2226 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), |
2297 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), | 2227 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), |
2298 | { | 2228 | { |
@@ -2307,7 +2237,7 @@ static snd_kcontrol_new_t alc260_base_mixer[] = { | |||
2307 | 2237 | ||
2308 | static snd_kcontrol_new_t alc260_hp_mixer[] = { | 2238 | static snd_kcontrol_new_t alc260_hp_mixer[] = { |
2309 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2239 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2310 | ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 2240 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
2311 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2241 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
2312 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 2242 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
2313 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | 2243 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), |
@@ -2317,9 +2247,9 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = { | |||
2317 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), | 2247 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), |
2318 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), | 2248 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), |
2319 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 2249 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
2320 | ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | 2250 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), |
2321 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 2251 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
2322 | ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 2252 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
2323 | HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), | 2253 | HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT), |
2324 | HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), | 2254 | HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT), |
2325 | { | 2255 | { |
@@ -2334,7 +2264,7 @@ static snd_kcontrol_new_t alc260_hp_mixer[] = { | |||
2334 | 2264 | ||
2335 | static snd_kcontrol_new_t alc260_fujitsu_mixer[] = { | 2265 | static snd_kcontrol_new_t alc260_fujitsu_mixer[] = { |
2336 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 2266 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
2337 | ALC_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), | 2267 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), |
2338 | ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP), | 2268 | ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP), |
2339 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 2269 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
2340 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 2270 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
@@ -2343,7 +2273,7 @@ static snd_kcontrol_new_t alc260_fujitsu_mixer[] = { | |||
2343 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), | 2273 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), |
2344 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), | 2274 | HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), |
2345 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 2275 | HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
2346 | ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), | 2276 | HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT), |
2347 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), | 2277 | HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), |
2348 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), | 2278 | HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT), |
2349 | { | 2279 | { |
@@ -2500,7 +2430,6 @@ static int patch_alc260(struct hda_codec *codec) | |||
2500 | if (spec == NULL) | 2430 | if (spec == NULL) |
2501 | return -ENOMEM; | 2431 | return -ENOMEM; |
2502 | 2432 | ||
2503 | init_MUTEX(&spec->bind_mutex); | ||
2504 | codec->spec = spec; | 2433 | codec->spec = spec; |
2505 | 2434 | ||
2506 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); | 2435 | board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); |
@@ -2637,15 +2566,15 @@ static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u | |||
2637 | */ | 2566 | */ |
2638 | static snd_kcontrol_new_t alc882_base_mixer[] = { | 2567 | static snd_kcontrol_new_t alc882_base_mixer[] = { |
2639 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2568 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2640 | ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2569 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2641 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2570 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
2642 | ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | 2571 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), |
2643 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 2572 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
2644 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | 2573 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), |
2645 | ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | 2574 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), |
2646 | ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | 2575 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), |
2647 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 2576 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
2648 | ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 2577 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
2649 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 2578 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
2650 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 2579 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
2651 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 2580 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
@@ -2763,7 +2692,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
2763 | if (spec == NULL) | 2692 | if (spec == NULL) |
2764 | return -ENOMEM; | 2693 | return -ENOMEM; |
2765 | 2694 | ||
2766 | init_MUTEX(&spec->bind_mutex); | ||
2767 | codec->spec = spec; | 2695 | codec->spec = spec; |
2768 | 2696 | ||
2769 | spec->mixers[spec->num_mixers] = alc882_base_mixer; | 2697 | spec->mixers[spec->num_mixers] = alc882_base_mixer; |