]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From 667067d8980249a71ccf82a55202fff2cd1cd54f Mon Sep 17 00:00:00 2001 |
2 | From: Takashi Iwai <tiwai@suse.de> | |
3 | Date: Thu, 13 Aug 2009 18:14:42 +0200 | |
4 | Subject: ALSA: hda - Fix / clean up IDT92HD83xxx codec parser | |
5 | Patch-mainline: | |
6 | References: bnc#531533 | |
7 | ||
8 | A few improvements for IDT 92HD83xxx codec pareser: | |
9 | - Remove unused / deprecated mixer-amp controls | |
10 | - Handle d-mics as normal inputs since this codec has no separate | |
11 | MUXes for analog and digital | |
12 | - Don't create duplicated controls for capture volumes with Mux | |
13 | capture volumes | |
14 | ||
15 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
16 | ||
17 | --- | |
18 | sound/pci/hda/patch_sigmatel.c | 150 +++++++++++++++++++---------------------- | |
19 | 1 file changed, 70 insertions(+), 80 deletions(-) | |
20 | ||
21 | --- a/sound/pci/hda/patch_sigmatel.c | |
22 | +++ b/sound/pci/hda/patch_sigmatel.c | |
23 | @@ -349,14 +349,9 @@ | |
24 | }; | |
25 | #define stac92hd73xx_capsws stac92hd73xx_capvols | |
26 | ||
27 | -#define STAC92HD83XXX_NUM_DMICS 2 | |
28 | -static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | |
29 | - 0x11, 0x12, 0 | |
30 | -}; | |
31 | - | |
32 | #define STAC92HD83_DAC_COUNT 3 | |
33 | ||
34 | -static hda_nid_t stac92hd83xxx_dmux_nids[2] = { | |
35 | +static hda_nid_t stac92hd83xxx_mux_nids[2] = { | |
36 | 0x17, 0x18, | |
37 | }; | |
38 | ||
39 | @@ -376,10 +371,6 @@ | |
40 | 0x03, 0x0c, 0x20, 0x40, | |
41 | }; | |
42 | ||
43 | -static hda_nid_t stac92hd83xxx_amp_nids[1] = { | |
44 | - 0xc, | |
45 | -}; | |
46 | - | |
47 | #define STAC92HD83XXX_NUM_CAPS 2 | |
48 | static unsigned long stac92hd83xxx_capvols[] = { | |
49 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | |
50 | @@ -1092,26 +1083,6 @@ | |
51 | }; | |
52 | ||
53 | ||
54 | -static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |
55 | - HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), | |
56 | - HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT), | |
57 | - | |
58 | - HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT), | |
59 | - HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT), | |
60 | - | |
61 | - HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT), | |
62 | - HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT), | |
63 | - | |
64 | - HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT), | |
65 | - HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT), | |
66 | - | |
67 | - /* | |
68 | - HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT), | |
69 | - HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT), | |
70 | - */ | |
71 | - { } /* end */ | |
72 | -}; | |
73 | - | |
74 | static struct snd_kcontrol_new stac925x_mixer[] = { | |
75 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | |
76 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | |
77 | @@ -3380,19 +3351,33 @@ | |
78 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) | |
79 | { | |
80 | struct sigmatel_spec *spec = codec->spec; | |
81 | - int wcaps, nid, i, err = 0; | |
82 | + int i, j, err = 0; | |
83 | ||
84 | for (i = 0; i < spec->num_muxes; i++) { | |
85 | + hda_nid_t nid; | |
86 | + unsigned int wcaps; | |
87 | + unsigned long val; | |
88 | + | |
89 | nid = spec->mux_nids[i]; | |
90 | wcaps = get_wcaps(codec, nid); | |
91 | + if (!(wcaps & AC_WCAP_OUT_AMP)) | |
92 | + continue; | |
93 | ||
94 | - if (wcaps & AC_WCAP_OUT_AMP) { | |
95 | - err = stac92xx_add_control_idx(spec, | |
96 | - STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", | |
97 | - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | |
98 | - if (err < 0) | |
99 | - return err; | |
100 | + /* check whether already the same control was created as | |
101 | + * normal Capture Volume. | |
102 | + */ | |
103 | + val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | |
104 | + for (j = 0; j < spec->num_caps; j++) { | |
105 | + if (spec->capvols[j] == val) | |
106 | + break; | |
107 | } | |
108 | + if (j < spec->num_caps) | |
109 | + continue; | |
110 | + | |
111 | + err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i, | |
112 | + "Mux Capture Volume", val); | |
113 | + if (err < 0) | |
114 | + return err; | |
115 | } | |
116 | return 0; | |
117 | }; | |
118 | @@ -3447,6 +3432,24 @@ | |
119 | return -1; | |
120 | } | |
121 | ||
122 | +/* create a volume assigned to the given pin (only if supported) */ | |
123 | +static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid, | |
124 | + const char *label) | |
125 | +{ | |
126 | + unsigned int caps, nums; | |
127 | + char name[32]; | |
128 | + | |
129 | + if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) | |
130 | + return 0; | |
131 | + caps = query_amp_caps(codec, nid, HDA_OUTPUT); | |
132 | + nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; | |
133 | + if (!nums) | |
134 | + return 0; | |
135 | + snprintf(name, sizeof(name), "%s Capture Volume", label); | |
136 | + return stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name, | |
137 | + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | |
138 | +} | |
139 | + | |
140 | /* create playback/capture controls for input pins on dmic capable codecs */ | |
141 | static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |
142 | const struct auto_pin_cfg *cfg) | |
143 | @@ -3456,7 +3459,6 @@ | |
144 | struct hda_input_mux *dimux = &spec->private_dimux; | |
145 | int err, i, active_mics; | |
146 | unsigned int def_conf; | |
147 | - char name[32]; | |
148 | ||
149 | dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; | |
150 | dimux->items[dimux->num_items].index = 0; | |
151 | @@ -3464,6 +3466,10 @@ | |
152 | ||
153 | active_mics = 0; | |
154 | for (i = 0; i < spec->num_dmics; i++) { | |
155 | + /* check the validity: sometimes it's a dead vendor-spec node */ | |
156 | + if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i])) | |
157 | + != AC_WID_PIN) | |
158 | + continue; | |
159 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | |
160 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) | |
161 | active_mics++; | |
162 | @@ -3472,14 +3478,15 @@ | |
163 | for (i = 0; i < spec->num_dmics; i++) { | |
164 | hda_nid_t nid; | |
165 | int index; | |
166 | - unsigned int wcaps; | |
167 | const char *label; | |
168 | ||
169 | - def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); | |
170 | + nid = spec->dmic_nids[i]; | |
171 | + if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | |
172 | + continue; | |
173 | + def_conf = snd_hda_codec_get_pincfg(codec, nid); | |
174 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | |
175 | continue; | |
176 | ||
177 | - nid = spec->dmic_nids[i]; | |
178 | index = get_connection_index(codec, spec->dmux_nids[0], nid); | |
179 | if (index < 0) | |
180 | continue; | |
181 | @@ -3489,21 +3496,9 @@ | |
182 | else | |
183 | label = stac92xx_dmic_labels[dimux->num_items]; | |
184 | ||
185 | - wcaps = get_wcaps(codec, nid) & | |
186 | - (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | |
187 | - | |
188 | - if (wcaps) { | |
189 | - sprintf(name, "%s Capture Volume", label); | |
190 | - | |
191 | - err = stac92xx_add_control(spec, | |
192 | - STAC_CTL_WIDGET_VOL, | |
193 | - name, | |
194 | - HDA_COMPOSE_AMP_VAL(nid, 3, 0, | |
195 | - (wcaps & AC_WCAP_OUT_AMP) ? | |
196 | - HDA_OUTPUT : HDA_INPUT)); | |
197 | - if (err < 0) | |
198 | - return err; | |
199 | - } | |
200 | + err = create_elem_capture_vol(codec, nid, label); | |
201 | + if (err < 0) | |
202 | + return err; | |
203 | ||
204 | dimux->items[dimux->num_items].label = label; | |
205 | dimux->items[dimux->num_items].index = index; | |
206 | @@ -3604,29 +3599,29 @@ | |
207 | { | |
208 | struct sigmatel_spec *spec = codec->spec; | |
209 | struct hda_input_mux *imux = &spec->private_imux; | |
210 | - hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | |
211 | - int i, j, k; | |
212 | + int i, j; | |
213 | ||
214 | for (i = 0; i < AUTO_PIN_LAST; i++) { | |
215 | - int index; | |
216 | + hda_nid_t nid = cfg->input_pins[i]; | |
217 | + int index, err; | |
218 | ||
219 | - if (!cfg->input_pins[i]) | |
220 | + if (!nid) | |
221 | continue; | |
222 | index = -1; | |
223 | for (j = 0; j < spec->num_muxes; j++) { | |
224 | - int num_cons; | |
225 | - num_cons = snd_hda_get_connections(codec, | |
226 | - spec->mux_nids[j], | |
227 | - con_lst, | |
228 | - HDA_MAX_NUM_INPUTS); | |
229 | - for (k = 0; k < num_cons; k++) | |
230 | - if (con_lst[k] == cfg->input_pins[i]) { | |
231 | - index = k; | |
232 | - goto found; | |
233 | - } | |
234 | + index = get_connection_index(codec, spec->mux_nids[j], | |
235 | + nid); | |
236 | + if (index >= 0) | |
237 | + break; | |
238 | } | |
239 | - continue; | |
240 | - found: | |
241 | + if (index < 0) | |
242 | + continue; | |
243 | + | |
244 | + err = create_elem_capture_vol(codec, nid, | |
245 | + auto_pin_cfg_labels[i]); | |
246 | + if (err < 0) | |
247 | + return err; | |
248 | + | |
249 | imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; | |
250 | imux->items[imux->num_items].index = index; | |
251 | imux->num_items++; | |
252 | @@ -4998,22 +4993,17 @@ | |
253 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | |
254 | spec->mono_nid = 0x19; | |
255 | spec->digbeep_nid = 0x21; | |
256 | - spec->dmic_nids = stac92hd83xxx_dmic_nids; | |
257 | - spec->dmux_nids = stac92hd83xxx_dmux_nids; | |
258 | + spec->mux_nids = stac92hd83xxx_mux_nids; | |
259 | + spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids); | |
260 | spec->adc_nids = stac92hd83xxx_adc_nids; | |
261 | + spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | |
262 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | |
263 | - spec->amp_nids = stac92hd83xxx_amp_nids; | |
264 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | |
265 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | |
266 | spec->multiout.dac_nids = spec->dac_nids; | |
267 | ||
268 | spec->init = stac92hd83xxx_core_init; | |
269 | - spec->mixer = stac92hd83xxx_mixer; | |
270 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | |
271 | - spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); | |
272 | - spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | |
273 | - spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids); | |
274 | - spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | |
275 | spec->pin_nids = stac92hd83xxx_pin_nids; | |
276 | spec->num_caps = STAC92HD83XXX_NUM_CAPS; | |
277 | spec->capvols = stac92hd83xxx_capvols; |