diff options
author | Steve French <sfrench@us.ibm.com> | 2011-12-16 01:39:20 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2011-12-16 01:39:20 -0500 |
commit | aaf015890754d58dcb71a4aa44ed246bb082bcf6 (patch) | |
tree | 17b51ff707fd1b3efec3a3ab872f0d7a7416aca5 /sound/pci/hda/patch_realtek.c | |
parent | 9c32c63bb70b2fafc3b18bee29959c3bf245ceba (diff) | |
parent | 8def5f51b012efb00e77ba2d04696cc0aadd0609 (diff) |
Merge branch 'master' of git+ssh://git.samba.org/data/git/sfrench/cifs-2.6
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 114 |
1 files changed, 80 insertions, 34 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a24e068a021b..1d07e8fa2433 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -277,6 +277,12 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | |||
277 | return false; | 277 | return false; |
278 | } | 278 | } |
279 | 279 | ||
280 | static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | ||
281 | { | ||
282 | return spec->capsrc_nids ? | ||
283 | spec->capsrc_nids[idx] : spec->adc_nids[idx]; | ||
284 | } | ||
285 | |||
280 | /* select the given imux item; either unmute exclusively or select the route */ | 286 | /* select the given imux item; either unmute exclusively or select the route */ |
281 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | 287 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, |
282 | unsigned int idx, bool force) | 288 | unsigned int idx, bool force) |
@@ -284,13 +290,15 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
284 | struct alc_spec *spec = codec->spec; | 290 | struct alc_spec *spec = codec->spec; |
285 | const struct hda_input_mux *imux; | 291 | const struct hda_input_mux *imux; |
286 | unsigned int mux_idx; | 292 | unsigned int mux_idx; |
287 | int i, type; | 293 | int i, type, num_conns; |
288 | hda_nid_t nid; | 294 | hda_nid_t nid; |
289 | 295 | ||
290 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 296 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
291 | imux = &spec->input_mux[mux_idx]; | 297 | imux = &spec->input_mux[mux_idx]; |
292 | if (!imux->num_items && mux_idx > 0) | 298 | if (!imux->num_items && mux_idx > 0) |
293 | imux = &spec->input_mux[0]; | 299 | imux = &spec->input_mux[0]; |
300 | if (!imux->num_items) | ||
301 | return 0; | ||
294 | 302 | ||
295 | if (idx >= imux->num_items) | 303 | if (idx >= imux->num_items) |
296 | idx = imux->num_items - 1; | 304 | idx = imux->num_items - 1; |
@@ -303,20 +311,20 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
303 | adc_idx = spec->dyn_adc_idx[idx]; | 311 | adc_idx = spec->dyn_adc_idx[idx]; |
304 | } | 312 | } |
305 | 313 | ||
306 | nid = spec->capsrc_nids ? | 314 | nid = get_capsrc(spec, adc_idx); |
307 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | ||
308 | 315 | ||
309 | /* no selection? */ | 316 | /* no selection? */ |
310 | if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) | 317 | num_conns = snd_hda_get_conn_list(codec, nid, NULL); |
318 | if (num_conns <= 1) | ||
311 | return 1; | 319 | return 1; |
312 | 320 | ||
313 | type = get_wcaps_type(get_wcaps(codec, nid)); | 321 | type = get_wcaps_type(get_wcaps(codec, nid)); |
314 | if (type == AC_WID_AUD_MIX) { | 322 | if (type == AC_WID_AUD_MIX) { |
315 | /* Matrix-mixer style (e.g. ALC882) */ | 323 | /* Matrix-mixer style (e.g. ALC882) */ |
316 | for (i = 0; i < imux->num_items; i++) { | 324 | int active = imux->items[idx].index; |
317 | unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; | 325 | for (i = 0; i < num_conns; i++) { |
318 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, | 326 | unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; |
319 | imux->items[i].index, | 327 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, |
320 | HDA_AMP_MUTE, v); | 328 | HDA_AMP_MUTE, v); |
321 | } | 329 | } |
322 | } else { | 330 | } else { |
@@ -1053,8 +1061,19 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) | |||
1053 | spec->imux_pins[2] = spec->dock_mic_pin; | 1061 | spec->imux_pins[2] = spec->dock_mic_pin; |
1054 | for (i = 0; i < 3; i++) { | 1062 | for (i = 0; i < 3; i++) { |
1055 | strcpy(imux->items[i].label, texts[i]); | 1063 | strcpy(imux->items[i].label, texts[i]); |
1056 | if (spec->imux_pins[i]) | 1064 | if (spec->imux_pins[i]) { |
1065 | hda_nid_t pin = spec->imux_pins[i]; | ||
1066 | int c; | ||
1067 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
1068 | hda_nid_t cap = get_capsrc(spec, c); | ||
1069 | int idx = get_connection_index(codec, cap, pin); | ||
1070 | if (idx >= 0) { | ||
1071 | imux->items[i].index = idx; | ||
1072 | break; | ||
1073 | } | ||
1074 | } | ||
1057 | imux->num_items = i + 1; | 1075 | imux->num_items = i + 1; |
1076 | } | ||
1058 | } | 1077 | } |
1059 | spec->num_mux_defs = 1; | 1078 | spec->num_mux_defs = 1; |
1060 | spec->input_mux = imux; | 1079 | spec->input_mux = imux; |
@@ -1451,7 +1470,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) | |||
1451 | switch (fix->type) { | 1470 | switch (fix->type) { |
1452 | case ALC_FIXUP_SKU: | 1471 | case ALC_FIXUP_SKU: |
1453 | if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) | 1472 | if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) |
1454 | break;; | 1473 | break; |
1455 | snd_printdd(KERN_INFO "hda_codec: %s: " | 1474 | snd_printdd(KERN_INFO "hda_codec: %s: " |
1456 | "Apply sku override for %s\n", | 1475 | "Apply sku override for %s\n", |
1457 | codec->chip_name, modelname); | 1476 | codec->chip_name, modelname); |
@@ -1956,10 +1975,8 @@ static int alc_build_controls(struct hda_codec *codec) | |||
1956 | if (!kctl) | 1975 | if (!kctl) |
1957 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | 1976 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); |
1958 | for (i = 0; kctl && i < kctl->count; i++) { | 1977 | for (i = 0; kctl && i < kctl->count; i++) { |
1959 | const hda_nid_t *nids = spec->capsrc_nids; | 1978 | err = snd_hda_add_nid(codec, kctl, i, |
1960 | if (!nids) | 1979 | get_capsrc(spec, i)); |
1961 | nids = spec->adc_nids; | ||
1962 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); | ||
1963 | if (err < 0) | 1980 | if (err < 0) |
1964 | return err; | 1981 | return err; |
1965 | } | 1982 | } |
@@ -2614,6 +2631,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
2614 | case AUTO_PIN_SPEAKER_OUT: | 2631 | case AUTO_PIN_SPEAKER_OUT: |
2615 | if (cfg->line_outs == 1) | 2632 | if (cfg->line_outs == 1) |
2616 | return "Speaker"; | 2633 | return "Speaker"; |
2634 | if (cfg->line_outs == 2) | ||
2635 | return ch ? "Bass Speaker" : "Speaker"; | ||
2617 | break; | 2636 | break; |
2618 | case AUTO_PIN_HP_OUT: | 2637 | case AUTO_PIN_HP_OUT: |
2619 | /* for multi-io case, only the primary out */ | 2638 | /* for multi-io case, only the primary out */ |
@@ -2746,8 +2765,7 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
2746 | } | 2765 | } |
2747 | 2766 | ||
2748 | for (c = 0; c < num_adcs; c++) { | 2767 | for (c = 0; c < num_adcs; c++) { |
2749 | hda_nid_t cap = spec->capsrc_nids ? | 2768 | hda_nid_t cap = get_capsrc(spec, c); |
2750 | spec->capsrc_nids[c] : spec->adc_nids[c]; | ||
2751 | idx = get_connection_index(codec, cap, pin); | 2769 | idx = get_connection_index(codec, cap, pin); |
2752 | if (idx >= 0) { | 2770 | if (idx >= 0) { |
2753 | spec->imux_pins[imux->num_items] = pin; | 2771 | spec->imux_pins[imux->num_items] = pin; |
@@ -2888,7 +2906,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2888 | if (!nid) | 2906 | if (!nid) |
2889 | continue; | 2907 | continue; |
2890 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2908 | if (found_in_nid_list(nid, spec->multiout.dac_nids, |
2891 | spec->multiout.num_dacs)) | 2909 | ARRAY_SIZE(spec->private_dac_nids))) |
2892 | continue; | 2910 | continue; |
2893 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, | 2911 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, |
2894 | ARRAY_SIZE(spec->multiout.hp_out_nid))) | 2912 | ARRAY_SIZE(spec->multiout.hp_out_nid))) |
@@ -2909,6 +2927,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
2909 | return 0; | 2927 | return 0; |
2910 | } | 2928 | } |
2911 | 2929 | ||
2930 | /* return 0 if no possible DAC is found, 1 if one or more found */ | ||
2912 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | 2931 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, |
2913 | const hda_nid_t *pins, hda_nid_t *dacs) | 2932 | const hda_nid_t *pins, hda_nid_t *dacs) |
2914 | { | 2933 | { |
@@ -2926,7 +2945,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | |||
2926 | if (!dacs[i]) | 2945 | if (!dacs[i]) |
2927 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | 2946 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); |
2928 | } | 2947 | } |
2929 | return 0; | 2948 | return 1; |
2930 | } | 2949 | } |
2931 | 2950 | ||
2932 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 2951 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
@@ -2936,7 +2955,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
2936 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 2955 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
2937 | { | 2956 | { |
2938 | struct alc_spec *spec = codec->spec; | 2957 | struct alc_spec *spec = codec->spec; |
2939 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 2958 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2940 | bool redone = false; | 2959 | bool redone = false; |
2941 | int i; | 2960 | int i; |
2942 | 2961 | ||
@@ -2947,6 +2966,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2947 | spec->multiout.extra_out_nid[0] = 0; | 2966 | spec->multiout.extra_out_nid[0] = 0; |
2948 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | 2967 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); |
2949 | spec->multiout.dac_nids = spec->private_dac_nids; | 2968 | spec->multiout.dac_nids = spec->private_dac_nids; |
2969 | spec->multi_ios = 0; | ||
2950 | 2970 | ||
2951 | /* fill hard-wired DACs first */ | 2971 | /* fill hard-wired DACs first */ |
2952 | if (!redone) { | 2972 | if (!redone) { |
@@ -2980,10 +3000,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2980 | for (i = 0; i < cfg->line_outs; i++) { | 3000 | for (i = 0; i < cfg->line_outs; i++) { |
2981 | if (spec->private_dac_nids[i]) | 3001 | if (spec->private_dac_nids[i]) |
2982 | spec->multiout.num_dacs++; | 3002 | spec->multiout.num_dacs++; |
2983 | else | 3003 | else { |
2984 | memmove(spec->private_dac_nids + i, | 3004 | memmove(spec->private_dac_nids + i, |
2985 | spec->private_dac_nids + i + 1, | 3005 | spec->private_dac_nids + i + 1, |
2986 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | 3006 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); |
3007 | spec->private_dac_nids[cfg->line_outs - 1] = 0; | ||
3008 | } | ||
2987 | } | 3009 | } |
2988 | 3010 | ||
2989 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 3011 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
@@ -3005,9 +3027,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3005 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 3027 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
3006 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, | 3028 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
3007 | spec->multiout.hp_out_nid); | 3029 | spec->multiout.hp_out_nid); |
3008 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | 3030 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3009 | alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, | 3031 | int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, |
3010 | spec->multiout.extra_out_nid); | 3032 | cfg->speaker_pins, |
3033 | spec->multiout.extra_out_nid); | ||
3034 | /* if no speaker volume is assigned, try again as the primary | ||
3035 | * output | ||
3036 | */ | ||
3037 | if (!err && cfg->speaker_outs > 0 && | ||
3038 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
3039 | cfg->hp_outs = cfg->line_outs; | ||
3040 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
3041 | sizeof(cfg->hp_pins)); | ||
3042 | cfg->line_outs = cfg->speaker_outs; | ||
3043 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
3044 | sizeof(cfg->speaker_pins)); | ||
3045 | cfg->speaker_outs = 0; | ||
3046 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
3047 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
3048 | redone = false; | ||
3049 | goto again; | ||
3050 | } | ||
3051 | } | ||
3011 | 3052 | ||
3012 | return 0; | 3053 | return 0; |
3013 | } | 3054 | } |
@@ -3157,7 +3198,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3157 | } | 3198 | } |
3158 | 3199 | ||
3159 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | 3200 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
3160 | hda_nid_t dac, const char *pfx) | 3201 | hda_nid_t dac, const char *pfx, |
3202 | int cidx) | ||
3161 | { | 3203 | { |
3162 | struct alc_spec *spec = codec->spec; | 3204 | struct alc_spec *spec = codec->spec; |
3163 | hda_nid_t sw, vol; | 3205 | hda_nid_t sw, vol; |
@@ -3173,15 +3215,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
3173 | if (is_ctl_used(spec->sw_ctls, val)) | 3215 | if (is_ctl_used(spec->sw_ctls, val)) |
3174 | return 0; /* already created */ | 3216 | return 0; /* already created */ |
3175 | mark_ctl_usage(spec->sw_ctls, val); | 3217 | mark_ctl_usage(spec->sw_ctls, val); |
3176 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); | 3218 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); |
3177 | } | 3219 | } |
3178 | 3220 | ||
3179 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3221 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
3180 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3222 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
3181 | err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); | 3223 | err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); |
3182 | if (err < 0) | 3224 | if (err < 0) |
3183 | return err; | 3225 | return err; |
3184 | err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); | 3226 | err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); |
3185 | if (err < 0) | 3227 | if (err < 0) |
3186 | return err; | 3228 | return err; |
3187 | return 0; | 3229 | return 0; |
@@ -3222,16 +3264,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | |||
3222 | hda_nid_t dac = *dacs; | 3264 | hda_nid_t dac = *dacs; |
3223 | if (!dac) | 3265 | if (!dac) |
3224 | dac = spec->multiout.dac_nids[0]; | 3266 | dac = spec->multiout.dac_nids[0]; |
3225 | return alc_auto_create_extra_out(codec, *pins, dac, pfx); | 3267 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
3226 | } | 3268 | } |
3227 | 3269 | ||
3228 | if (dacs[num_pins - 1]) { | 3270 | if (dacs[num_pins - 1]) { |
3229 | /* OK, we have a multi-output system with individual volumes */ | 3271 | /* OK, we have a multi-output system with individual volumes */ |
3230 | for (i = 0; i < num_pins; i++) { | 3272 | for (i = 0; i < num_pins; i++) { |
3231 | snprintf(name, sizeof(name), "%s %s", | 3273 | if (num_pins >= 3) { |
3232 | pfx, channel_name[i]); | 3274 | snprintf(name, sizeof(name), "%s %s", |
3233 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | 3275 | pfx, channel_name[i]); |
3234 | name); | 3276 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], |
3277 | name, 0); | ||
3278 | } else { | ||
3279 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
3280 | pfx, i); | ||
3281 | } | ||
3235 | if (err < 0) | 3282 | if (err < 0) |
3236 | return err; | 3283 | return err; |
3237 | } | 3284 | } |
@@ -3693,8 +3740,7 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | |||
3693 | if (!pin) | 3740 | if (!pin) |
3694 | return 0; | 3741 | return 0; |
3695 | for (i = 0; i < spec->num_adc_nids; i++) { | 3742 | for (i = 0; i < spec->num_adc_nids; i++) { |
3696 | hda_nid_t cap = spec->capsrc_nids ? | 3743 | hda_nid_t cap = get_capsrc(spec, i); |
3697 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
3698 | int idx; | 3744 | int idx; |
3699 | 3745 | ||
3700 | idx = get_connection_index(codec, cap, pin); | 3746 | idx = get_connection_index(codec, cap, pin); |