diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-07-07 12:18:59 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-07-07 12:20:23 -0400 |
commit | 337b9d02b4873ceac91565272545fb6fd446d939 (patch) | |
tree | 8cc097ca994c244e2af61f31666dbba0f9a2dfde /sound/pci | |
parent | d3a11e601a51291fbdd40c47f6af6769b6e905ef (diff) |
ALSA: hda - Fix capture source selection in patch_via.c
The fixed widget NIDs in patch_via.c seem wrong for some codecs,
and it resulted in the invalid capture source selection.
This patch adds the code to parse the topology instead of using
fixed numbers in order to get the right MUX widget id corresponding
to the ADCs.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_via.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 322e10272474..38db45964228 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -210,6 +210,7 @@ struct via_spec { | |||
210 | /* capture */ | 210 | /* capture */ |
211 | unsigned int num_adc_nids; | 211 | unsigned int num_adc_nids; |
212 | hda_nid_t *adc_nids; | 212 | hda_nid_t *adc_nids; |
213 | hda_nid_t mux_nids[3]; | ||
213 | hda_nid_t dig_in_nid; | 214 | hda_nid_t dig_in_nid; |
214 | hda_nid_t dig_in_pin; | 215 | hda_nid_t dig_in_pin; |
215 | 216 | ||
@@ -393,25 +394,11 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
393 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 394 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
394 | unsigned int vendor_id = codec->vendor_id; | 395 | unsigned int vendor_id = codec->vendor_id; |
395 | 396 | ||
396 | /* AIW0 lydia 060801 add for correct sw0 input select */ | 397 | if (!spec->mux_nids[adc_idx]) |
397 | if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0)) | 398 | return -EINVAL; |
398 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 399 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
399 | 0x18, &spec->cur_mux[adc_idx]); | 400 | spec->mux_nids[adc_idx], |
400 | else if ((IS_VT1709_10CH_VENDORID(vendor_id) || | 401 | &spec->cur_mux[adc_idx]); |
401 | IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0)) | ||
402 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
403 | 0x19, &spec->cur_mux[adc_idx]); | ||
404 | else if ((IS_VT1708B_8CH_VENDORID(vendor_id) || | ||
405 | IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0)) | ||
406 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
407 | 0x17, &spec->cur_mux[adc_idx]); | ||
408 | else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0)) | ||
409 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
410 | 0x13, &spec->cur_mux[adc_idx]); | ||
411 | else | ||
412 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
413 | spec->adc_nids[adc_idx], | ||
414 | &spec->cur_mux[adc_idx]); | ||
415 | } | 402 | } |
416 | 403 | ||
417 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, | 404 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, |
@@ -1343,6 +1330,29 @@ static int via_auto_init(struct hda_codec *codec) | |||
1343 | return 0; | 1330 | return 0; |
1344 | } | 1331 | } |
1345 | 1332 | ||
1333 | static int get_mux_nids(struct hda_codec *codec) | ||
1334 | { | ||
1335 | struct via_spec *spec = codec->spec; | ||
1336 | hda_nid_t nid, conn[8]; | ||
1337 | unsigned int type; | ||
1338 | int i, n; | ||
1339 | |||
1340 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
1341 | nid = spec->adc_nids[i]; | ||
1342 | while (nid) { | ||
1343 | n = snd_hda_get_connections(codec, nid, conn, | ||
1344 | ARRAY_SIZE(conn)); | ||
1345 | if (n <= 0) | ||
1346 | break; | ||
1347 | if (n > 1) { | ||
1348 | spec->mux_nids[i] = nid; | ||
1349 | break; | ||
1350 | } | ||
1351 | nid = conn[0]; | ||
1352 | } | ||
1353 | } | ||
1354 | } | ||
1355 | |||
1346 | static int patch_vt1708(struct hda_codec *codec) | 1356 | static int patch_vt1708(struct hda_codec *codec) |
1347 | { | 1357 | { |
1348 | struct via_spec *spec; | 1358 | struct via_spec *spec; |
@@ -1851,6 +1861,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
1851 | if (!spec->adc_nids && spec->input_mux) { | 1861 | if (!spec->adc_nids && spec->input_mux) { |
1852 | spec->adc_nids = vt1709_adc_nids; | 1862 | spec->adc_nids = vt1709_adc_nids; |
1853 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); | 1863 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); |
1864 | get_mux_nids(codec); | ||
1854 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; | 1865 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; |
1855 | spec->num_mixers++; | 1866 | spec->num_mixers++; |
1856 | } | 1867 | } |
@@ -1944,6 +1955,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
1944 | if (!spec->adc_nids && spec->input_mux) { | 1955 | if (!spec->adc_nids && spec->input_mux) { |
1945 | spec->adc_nids = vt1709_adc_nids; | 1956 | spec->adc_nids = vt1709_adc_nids; |
1946 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); | 1957 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); |
1958 | get_mux_nids(codec); | ||
1947 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; | 1959 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; |
1948 | spec->num_mixers++; | 1960 | spec->num_mixers++; |
1949 | } | 1961 | } |
@@ -2397,6 +2409,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
2397 | if (!spec->adc_nids && spec->input_mux) { | 2409 | if (!spec->adc_nids && spec->input_mux) { |
2398 | spec->adc_nids = vt1708B_adc_nids; | 2410 | spec->adc_nids = vt1708B_adc_nids; |
2399 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); | 2411 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); |
2412 | get_mux_nids(codec); | ||
2400 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; | 2413 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; |
2401 | spec->num_mixers++; | 2414 | spec->num_mixers++; |
2402 | } | 2415 | } |
@@ -2448,6 +2461,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
2448 | if (!spec->adc_nids && spec->input_mux) { | 2461 | if (!spec->adc_nids && spec->input_mux) { |
2449 | spec->adc_nids = vt1708B_adc_nids; | 2462 | spec->adc_nids = vt1708B_adc_nids; |
2450 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); | 2463 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); |
2464 | get_mux_nids(codec); | ||
2451 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; | 2465 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; |
2452 | spec->num_mixers++; | 2466 | spec->num_mixers++; |
2453 | } | 2467 | } |
@@ -2882,6 +2896,7 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
2882 | if (!spec->adc_nids && spec->input_mux) { | 2896 | if (!spec->adc_nids && spec->input_mux) { |
2883 | spec->adc_nids = vt1708S_adc_nids; | 2897 | spec->adc_nids = vt1708S_adc_nids; |
2884 | spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); | 2898 | spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); |
2899 | get_mux_nids(codec); | ||
2885 | spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; | 2900 | spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; |
2886 | spec->num_mixers++; | 2901 | spec->num_mixers++; |
2887 | } | 2902 | } |
@@ -3199,6 +3214,7 @@ static int patch_vt1702(struct hda_codec *codec) | |||
3199 | if (!spec->adc_nids && spec->input_mux) { | 3214 | if (!spec->adc_nids && spec->input_mux) { |
3200 | spec->adc_nids = vt1702_adc_nids; | 3215 | spec->adc_nids = vt1702_adc_nids; |
3201 | spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); | 3216 | spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); |
3217 | get_mux_nids(codec); | ||
3202 | spec->mixers[spec->num_mixers] = vt1702_capture_mixer; | 3218 | spec->mixers[spec->num_mixers] = vt1702_capture_mixer; |
3203 | spec->num_mixers++; | 3219 | spec->num_mixers++; |
3204 | } | 3220 | } |