diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-06-20 08:05:46 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-06-20 10:24:13 -0400 |
commit | 13af8e77ea3e0dff80db9b2e0007535c21d49094 (patch) | |
tree | d8b010b0814b39eec39008a67872a22ecbefacd4 /sound/pci | |
parent | e3d7a1431f1d8851d11b2262dda5bb67158450eb (diff) |
ALSA: hda - Create loopback-list dynamically in patch_via.c
Create loopback list dynamically from the parsed input pins for VIA
codecs instead of the fixed arrays.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_via.c | 164 |
1 files changed, 25 insertions, 139 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index c3be9f124b68..bd6ffa602f22 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -186,6 +186,8 @@ struct via_spec { | |||
186 | 186 | ||
187 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 187 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
188 | struct hda_loopback_check loopback; | 188 | struct hda_loopback_check loopback; |
189 | int num_loopbacks; | ||
190 | struct hda_amp_list loopback_list[8]; | ||
189 | #endif | 191 | #endif |
190 | }; | 192 | }; |
191 | 193 | ||
@@ -1895,6 +1897,24 @@ static const struct snd_kcontrol_new via_input_src_ctl = { | |||
1895 | .put = via_mux_enum_put, | 1897 | .put = via_mux_enum_put, |
1896 | }; | 1898 | }; |
1897 | 1899 | ||
1900 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
1901 | static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx) | ||
1902 | { | ||
1903 | struct hda_amp_list *list; | ||
1904 | |||
1905 | if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1) | ||
1906 | return; | ||
1907 | list = spec->loopback_list + spec->num_loopbacks; | ||
1908 | list->nid = mix; | ||
1909 | list->dir = HDA_INPUT; | ||
1910 | list->idx = idx; | ||
1911 | spec->num_loopbacks++; | ||
1912 | spec->loopback.amplist = spec->loopback_list; | ||
1913 | } | ||
1914 | #else | ||
1915 | #define add_loopback_list(spec, mix, idx) /* NOP */ | ||
1916 | #endif | ||
1917 | |||
1898 | /* create playback/capture controls for input pins */ | 1918 | /* create playback/capture controls for input pins */ |
1899 | static int via_auto_create_analog_input_ctls(struct hda_codec *codec, | 1919 | static int via_auto_create_analog_input_ctls(struct hda_codec *codec, |
1900 | const struct auto_pin_cfg *cfg) | 1920 | const struct auto_pin_cfg *cfg) |
@@ -1942,11 +1962,13 @@ static int via_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
1942 | label = hda_get_autocfg_input_label(codec, cfg, i); | 1962 | label = hda_get_autocfg_input_label(codec, cfg, i); |
1943 | idx2 = get_connection_index(codec, spec->aa_mix_nid, | 1963 | idx2 = get_connection_index(codec, spec->aa_mix_nid, |
1944 | pin_idxs[idx]); | 1964 | pin_idxs[idx]); |
1945 | if (idx2 >= 0) | 1965 | if (idx2 >= 0) { |
1946 | err = via_new_analog_input(spec, label, type_idx, | 1966 | err = via_new_analog_input(spec, label, type_idx, |
1947 | idx2, spec->aa_mix_nid); | 1967 | idx2, spec->aa_mix_nid); |
1948 | if (err < 0) | 1968 | if (err < 0) |
1949 | return err; | 1969 | return err; |
1970 | add_loopback_list(spec, spec->aa_mix_nid, idx2); | ||
1971 | } | ||
1950 | snd_hda_add_imux_item(imux, label, idx, NULL); | 1972 | snd_hda_add_imux_item(imux, label, idx, NULL); |
1951 | 1973 | ||
1952 | /* remember the label for smart51 control */ | 1974 | /* remember the label for smart51 control */ |
@@ -2011,16 +2033,6 @@ static int via_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
2011 | return 0; | 2033 | return 0; |
2012 | } | 2034 | } |
2013 | 2035 | ||
2014 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2015 | static const struct hda_amp_list vt1708_loopbacks[] = { | ||
2016 | { 0x17, HDA_INPUT, 1 }, | ||
2017 | { 0x17, HDA_INPUT, 2 }, | ||
2018 | { 0x17, HDA_INPUT, 3 }, | ||
2019 | { 0x17, HDA_INPUT, 4 }, | ||
2020 | { } /* end */ | ||
2021 | }; | ||
2022 | #endif | ||
2023 | |||
2024 | static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) | 2036 | static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) |
2025 | { | 2037 | { |
2026 | unsigned int def_conf; | 2038 | unsigned int def_conf; |
@@ -2285,26 +2297,10 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2285 | 2297 | ||
2286 | codec->patch_ops = via_patch_ops; | 2298 | codec->patch_ops = via_patch_ops; |
2287 | 2299 | ||
2288 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2289 | spec->loopback.amplist = vt1708_loopbacks; | ||
2290 | #endif | ||
2291 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); | 2300 | INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); |
2292 | return 0; | 2301 | return 0; |
2293 | } | 2302 | } |
2294 | 2303 | ||
2295 | /* | ||
2296 | * generic initialization of ADC, input mixers and output mixers | ||
2297 | */ | ||
2298 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2299 | static const struct hda_amp_list vt1709_loopbacks[] = { | ||
2300 | { 0x18, HDA_INPUT, 1 }, | ||
2301 | { 0x18, HDA_INPUT, 2 }, | ||
2302 | { 0x18, HDA_INPUT, 3 }, | ||
2303 | { 0x18, HDA_INPUT, 4 }, | ||
2304 | { } /* end */ | ||
2305 | }; | ||
2306 | #endif | ||
2307 | |||
2308 | static int patch_vt1709_10ch(struct hda_codec *codec) | 2304 | static int patch_vt1709_10ch(struct hda_codec *codec) |
2309 | { | 2305 | { |
2310 | struct via_spec *spec; | 2306 | struct via_spec *spec; |
@@ -2325,10 +2321,6 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
2325 | 2321 | ||
2326 | codec->patch_ops = via_patch_ops; | 2322 | codec->patch_ops = via_patch_ops; |
2327 | 2323 | ||
2328 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2329 | spec->loopback.amplist = vt1709_loopbacks; | ||
2330 | #endif | ||
2331 | |||
2332 | return 0; | 2324 | return 0; |
2333 | } | 2325 | } |
2334 | /* | 2326 | /* |
@@ -2354,25 +2346,9 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
2354 | 2346 | ||
2355 | codec->patch_ops = via_patch_ops; | 2347 | codec->patch_ops = via_patch_ops; |
2356 | 2348 | ||
2357 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2358 | spec->loopback.amplist = vt1709_loopbacks; | ||
2359 | #endif | ||
2360 | return 0; | 2349 | return 0; |
2361 | } | 2350 | } |
2362 | 2351 | ||
2363 | /* | ||
2364 | * generic initialization of ADC, input mixers and output mixers | ||
2365 | */ | ||
2366 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2367 | static const struct hda_amp_list vt1708B_loopbacks[] = { | ||
2368 | { 0x16, HDA_INPUT, 1 }, | ||
2369 | { 0x16, HDA_INPUT, 2 }, | ||
2370 | { 0x16, HDA_INPUT, 3 }, | ||
2371 | { 0x16, HDA_INPUT, 4 }, | ||
2372 | { } /* end */ | ||
2373 | }; | ||
2374 | #endif | ||
2375 | |||
2376 | static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | 2352 | static void set_widgets_power_state_vt1708B(struct hda_codec *codec) |
2377 | { | 2353 | { |
2378 | struct via_spec *spec = codec->spec; | 2354 | struct via_spec *spec = codec->spec; |
@@ -2477,10 +2453,6 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
2477 | 2453 | ||
2478 | codec->patch_ops = via_patch_ops; | 2454 | codec->patch_ops = via_patch_ops; |
2479 | 2455 | ||
2480 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2481 | spec->loopback.amplist = vt1708B_loopbacks; | ||
2482 | #endif | ||
2483 | |||
2484 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; | 2456 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; |
2485 | 2457 | ||
2486 | return 0; | 2458 | return 0; |
@@ -2505,10 +2477,6 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
2505 | 2477 | ||
2506 | codec->patch_ops = via_patch_ops; | 2478 | codec->patch_ops = via_patch_ops; |
2507 | 2479 | ||
2508 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2509 | spec->loopback.amplist = vt1708B_loopbacks; | ||
2510 | #endif | ||
2511 | |||
2512 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; | 2480 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; |
2513 | 2481 | ||
2514 | return 0; | 2482 | return 0; |
@@ -2575,16 +2543,6 @@ static void fill_dig_in(struct hda_codec *codec) | |||
2575 | } | 2543 | } |
2576 | } | 2544 | } |
2577 | 2545 | ||
2578 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2579 | static const struct hda_amp_list vt1708S_loopbacks[] = { | ||
2580 | { 0x16, HDA_INPUT, 1 }, | ||
2581 | { 0x16, HDA_INPUT, 2 }, | ||
2582 | { 0x16, HDA_INPUT, 3 }, | ||
2583 | { 0x16, HDA_INPUT, 4 }, | ||
2584 | { } /* end */ | ||
2585 | }; | ||
2586 | #endif | ||
2587 | |||
2588 | static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, | 2546 | static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, |
2589 | int offset, int num_steps, int step_size) | 2547 | int offset, int num_steps, int step_size) |
2590 | { | 2548 | { |
@@ -2620,10 +2578,6 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
2620 | 2578 | ||
2621 | codec->patch_ops = via_patch_ops; | 2579 | codec->patch_ops = via_patch_ops; |
2622 | 2580 | ||
2623 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2624 | spec->loopback.amplist = vt1708S_loopbacks; | ||
2625 | #endif | ||
2626 | |||
2627 | /* correct names for VT1708BCE */ | 2581 | /* correct names for VT1708BCE */ |
2628 | if (get_codec_type(codec) == VT1708BCE) { | 2582 | if (get_codec_type(codec) == VT1708BCE) { |
2629 | kfree(codec->chip_name); | 2583 | kfree(codec->chip_name); |
@@ -2654,16 +2608,6 @@ static const struct hda_verb vt1702_init_verbs[] = { | |||
2654 | { } | 2608 | { } |
2655 | }; | 2609 | }; |
2656 | 2610 | ||
2657 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2658 | static const struct hda_amp_list vt1702_loopbacks[] = { | ||
2659 | { 0x1A, HDA_INPUT, 1 }, | ||
2660 | { 0x1A, HDA_INPUT, 2 }, | ||
2661 | { 0x1A, HDA_INPUT, 3 }, | ||
2662 | { 0x1A, HDA_INPUT, 4 }, | ||
2663 | { } /* end */ | ||
2664 | }; | ||
2665 | #endif | ||
2666 | |||
2667 | static void set_widgets_power_state_vt1702(struct hda_codec *codec) | 2611 | static void set_widgets_power_state_vt1702(struct hda_codec *codec) |
2668 | { | 2612 | { |
2669 | int imux_is_smixer = | 2613 | int imux_is_smixer = |
@@ -2725,10 +2669,6 @@ static int patch_vt1702(struct hda_codec *codec) | |||
2725 | 2669 | ||
2726 | codec->patch_ops = via_patch_ops; | 2670 | codec->patch_ops = via_patch_ops; |
2727 | 2671 | ||
2728 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2729 | spec->loopback.amplist = vt1702_loopbacks; | ||
2730 | #endif | ||
2731 | |||
2732 | spec->set_widgets_power_state = set_widgets_power_state_vt1702; | 2672 | spec->set_widgets_power_state = set_widgets_power_state_vt1702; |
2733 | return 0; | 2673 | return 0; |
2734 | } | 2674 | } |
@@ -2744,16 +2684,6 @@ static const struct hda_verb vt1718S_init_verbs[] = { | |||
2744 | { } | 2684 | { } |
2745 | }; | 2685 | }; |
2746 | 2686 | ||
2747 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2748 | static const struct hda_amp_list vt1718S_loopbacks[] = { | ||
2749 | { 0x21, HDA_INPUT, 1 }, | ||
2750 | { 0x21, HDA_INPUT, 2 }, | ||
2751 | { 0x21, HDA_INPUT, 3 }, | ||
2752 | { 0x21, HDA_INPUT, 4 }, | ||
2753 | { } /* end */ | ||
2754 | }; | ||
2755 | #endif | ||
2756 | |||
2757 | static void set_widgets_power_state_vt1718S(struct hda_codec *codec) | 2687 | static void set_widgets_power_state_vt1718S(struct hda_codec *codec) |
2758 | { | 2688 | { |
2759 | struct via_spec *spec = codec->spec; | 2689 | struct via_spec *spec = codec->spec; |
@@ -2845,10 +2775,6 @@ static int patch_vt1718S(struct hda_codec *codec) | |||
2845 | 2775 | ||
2846 | codec->patch_ops = via_patch_ops; | 2776 | codec->patch_ops = via_patch_ops; |
2847 | 2777 | ||
2848 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2849 | spec->loopback.amplist = vt1718S_loopbacks; | ||
2850 | #endif | ||
2851 | |||
2852 | spec->set_widgets_power_state = set_widgets_power_state_vt1718S; | 2778 | spec->set_widgets_power_state = set_widgets_power_state_vt1718S; |
2853 | 2779 | ||
2854 | return 0; | 2780 | return 0; |
@@ -2925,16 +2851,6 @@ static const struct hda_verb vt1716S_init_verbs[] = { | |||
2925 | { } | 2851 | { } |
2926 | }; | 2852 | }; |
2927 | 2853 | ||
2928 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2929 | static const struct hda_amp_list vt1716S_loopbacks[] = { | ||
2930 | { 0x16, HDA_INPUT, 1 }, | ||
2931 | { 0x16, HDA_INPUT, 2 }, | ||
2932 | { 0x16, HDA_INPUT, 3 }, | ||
2933 | { 0x16, HDA_INPUT, 4 }, | ||
2934 | { } /* end */ | ||
2935 | }; | ||
2936 | #endif | ||
2937 | |||
2938 | static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | 2854 | static void set_widgets_power_state_vt1716S(struct hda_codec *codec) |
2939 | { | 2855 | { |
2940 | struct via_spec *spec = codec->spec; | 2856 | struct via_spec *spec = codec->spec; |
@@ -3058,10 +2974,6 @@ static int patch_vt1716S(struct hda_codec *codec) | |||
3058 | 2974 | ||
3059 | codec->patch_ops = via_patch_ops; | 2975 | codec->patch_ops = via_patch_ops; |
3060 | 2976 | ||
3061 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3062 | spec->loopback.amplist = vt1716S_loopbacks; | ||
3063 | #endif | ||
3064 | |||
3065 | spec->set_widgets_power_state = set_widgets_power_state_vt1716S; | 2977 | spec->set_widgets_power_state = set_widgets_power_state_vt1716S; |
3066 | return 0; | 2978 | return 0; |
3067 | } | 2979 | } |
@@ -3088,15 +3000,6 @@ static const struct hda_verb vt1802_init_verbs[] = { | |||
3088 | { } | 3000 | { } |
3089 | }; | 3001 | }; |
3090 | 3002 | ||
3091 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3092 | static const struct hda_amp_list vt2002P_loopbacks[] = { | ||
3093 | { 0x21, HDA_INPUT, 0 }, | ||
3094 | { 0x21, HDA_INPUT, 1 }, | ||
3095 | { 0x21, HDA_INPUT, 2 }, | ||
3096 | { } /* end */ | ||
3097 | }; | ||
3098 | #endif | ||
3099 | |||
3100 | static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | 3003 | static void set_widgets_power_state_vt2002P(struct hda_codec *codec) |
3101 | { | 3004 | { |
3102 | struct via_spec *spec = codec->spec; | 3005 | struct via_spec *spec = codec->spec; |
@@ -3237,10 +3140,6 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
3237 | 3140 | ||
3238 | codec->patch_ops = via_patch_ops; | 3141 | codec->patch_ops = via_patch_ops; |
3239 | 3142 | ||
3240 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3241 | spec->loopback.amplist = vt2002P_loopbacks; | ||
3242 | #endif | ||
3243 | |||
3244 | spec->set_widgets_power_state = set_widgets_power_state_vt2002P; | 3143 | spec->set_widgets_power_state = set_widgets_power_state_vt2002P; |
3245 | return 0; | 3144 | return 0; |
3246 | } | 3145 | } |
@@ -3255,15 +3154,6 @@ static const struct hda_verb vt1812_init_verbs[] = { | |||
3255 | { } | 3154 | { } |
3256 | }; | 3155 | }; |
3257 | 3156 | ||
3258 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3259 | static const struct hda_amp_list vt1812_loopbacks[] = { | ||
3260 | { 0x21, HDA_INPUT, 0 }, | ||
3261 | { 0x21, HDA_INPUT, 1 }, | ||
3262 | { 0x21, HDA_INPUT, 2 }, | ||
3263 | { } /* end */ | ||
3264 | }; | ||
3265 | #endif | ||
3266 | |||
3267 | static void set_widgets_power_state_vt1812(struct hda_codec *codec) | 3157 | static void set_widgets_power_state_vt1812(struct hda_codec *codec) |
3268 | { | 3158 | { |
3269 | struct via_spec *spec = codec->spec; | 3159 | struct via_spec *spec = codec->spec; |
@@ -3382,10 +3272,6 @@ static int patch_vt1812(struct hda_codec *codec) | |||
3382 | 3272 | ||
3383 | codec->patch_ops = via_patch_ops; | 3273 | codec->patch_ops = via_patch_ops; |
3384 | 3274 | ||
3385 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
3386 | spec->loopback.amplist = vt1812_loopbacks; | ||
3387 | #endif | ||
3388 | |||
3389 | spec->set_widgets_power_state = set_widgets_power_state_vt1812; | 3275 | spec->set_widgets_power_state = set_widgets_power_state_vt1812; |
3390 | return 0; | 3276 | return 0; |
3391 | } | 3277 | } |