diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cbde019d3d52..1d07e8fa2433 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -297,6 +297,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
297 | imux = &spec->input_mux[mux_idx]; | 297 | imux = &spec->input_mux[mux_idx]; |
298 | if (!imux->num_items && mux_idx > 0) | 298 | if (!imux->num_items && mux_idx > 0) |
299 | imux = &spec->input_mux[0]; | 299 | imux = &spec->input_mux[0]; |
300 | if (!imux->num_items) | ||
301 | return 0; | ||
300 | 302 | ||
301 | if (idx >= imux->num_items) | 303 | if (idx >= imux->num_items) |
302 | idx = imux->num_items - 1; | 304 | idx = imux->num_items - 1; |
@@ -2629,6 +2631,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
2629 | case AUTO_PIN_SPEAKER_OUT: | 2631 | case AUTO_PIN_SPEAKER_OUT: |
2630 | if (cfg->line_outs == 1) | 2632 | if (cfg->line_outs == 1) |
2631 | return "Speaker"; | 2633 | return "Speaker"; |
2634 | if (cfg->line_outs == 2) | ||
2635 | return ch ? "Bass Speaker" : "Speaker"; | ||
2632 | break; | 2636 | break; |
2633 | case AUTO_PIN_HP_OUT: | 2637 | case AUTO_PIN_HP_OUT: |
2634 | /* for multi-io case, only the primary out */ | 2638 | /* for multi-io case, only the primary out */ |
@@ -2902,7 +2906,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2902 | if (!nid) | 2906 | if (!nid) |
2903 | continue; | 2907 | continue; |
2904 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2908 | if (found_in_nid_list(nid, spec->multiout.dac_nids, |
2905 | spec->multiout.num_dacs)) | 2909 | ARRAY_SIZE(spec->private_dac_nids))) |
2906 | continue; | 2910 | continue; |
2907 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, | 2911 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, |
2908 | ARRAY_SIZE(spec->multiout.hp_out_nid))) | 2912 | ARRAY_SIZE(spec->multiout.hp_out_nid))) |
@@ -2923,6 +2927,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
2923 | return 0; | 2927 | return 0; |
2924 | } | 2928 | } |
2925 | 2929 | ||
2930 | /* return 0 if no possible DAC is found, 1 if one or more found */ | ||
2926 | 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, |
2927 | const hda_nid_t *pins, hda_nid_t *dacs) | 2932 | const hda_nid_t *pins, hda_nid_t *dacs) |
2928 | { | 2933 | { |
@@ -2940,7 +2945,7 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | |||
2940 | if (!dacs[i]) | 2945 | if (!dacs[i]) |
2941 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | 2946 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); |
2942 | } | 2947 | } |
2943 | return 0; | 2948 | return 1; |
2944 | } | 2949 | } |
2945 | 2950 | ||
2946 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 2951 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
@@ -2950,7 +2955,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
2950 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 2955 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
2951 | { | 2956 | { |
2952 | struct alc_spec *spec = codec->spec; | 2957 | struct alc_spec *spec = codec->spec; |
2953 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 2958 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2954 | bool redone = false; | 2959 | bool redone = false; |
2955 | int i; | 2960 | int i; |
2956 | 2961 | ||
@@ -2961,6 +2966,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2961 | spec->multiout.extra_out_nid[0] = 0; | 2966 | spec->multiout.extra_out_nid[0] = 0; |
2962 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | 2967 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); |
2963 | spec->multiout.dac_nids = spec->private_dac_nids; | 2968 | spec->multiout.dac_nids = spec->private_dac_nids; |
2969 | spec->multi_ios = 0; | ||
2964 | 2970 | ||
2965 | /* fill hard-wired DACs first */ | 2971 | /* fill hard-wired DACs first */ |
2966 | if (!redone) { | 2972 | if (!redone) { |
@@ -2994,10 +3000,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2994 | for (i = 0; i < cfg->line_outs; i++) { | 3000 | for (i = 0; i < cfg->line_outs; i++) { |
2995 | if (spec->private_dac_nids[i]) | 3001 | if (spec->private_dac_nids[i]) |
2996 | spec->multiout.num_dacs++; | 3002 | spec->multiout.num_dacs++; |
2997 | else | 3003 | else { |
2998 | memmove(spec->private_dac_nids + i, | 3004 | memmove(spec->private_dac_nids + i, |
2999 | spec->private_dac_nids + i + 1, | 3005 | spec->private_dac_nids + i + 1, |
3000 | 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 | } | ||
3001 | } | 3009 | } |
3002 | 3010 | ||
3003 | 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) { |
@@ -3019,9 +3027,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3019 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 3027 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
3020 | 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, |
3021 | spec->multiout.hp_out_nid); | 3029 | spec->multiout.hp_out_nid); |
3022 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | 3030 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3023 | alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, | 3031 | int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, |
3024 | 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 | } | ||
3025 | 3052 | ||
3026 | return 0; | 3053 | return 0; |
3027 | } | 3054 | } |
@@ -3171,7 +3198,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3171 | } | 3198 | } |
3172 | 3199 | ||
3173 | 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, |
3174 | hda_nid_t dac, const char *pfx) | 3201 | hda_nid_t dac, const char *pfx, |
3202 | int cidx) | ||
3175 | { | 3203 | { |
3176 | struct alc_spec *spec = codec->spec; | 3204 | struct alc_spec *spec = codec->spec; |
3177 | hda_nid_t sw, vol; | 3205 | hda_nid_t sw, vol; |
@@ -3187,15 +3215,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
3187 | if (is_ctl_used(spec->sw_ctls, val)) | 3215 | if (is_ctl_used(spec->sw_ctls, val)) |
3188 | return 0; /* already created */ | 3216 | return 0; /* already created */ |
3189 | mark_ctl_usage(spec->sw_ctls, val); | 3217 | mark_ctl_usage(spec->sw_ctls, val); |
3190 | 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); |
3191 | } | 3219 | } |
3192 | 3220 | ||
3193 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3221 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
3194 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3222 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
3195 | err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); | 3223 | err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); |
3196 | if (err < 0) | 3224 | if (err < 0) |
3197 | return err; | 3225 | return err; |
3198 | err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); | 3226 | err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); |
3199 | if (err < 0) | 3227 | if (err < 0) |
3200 | return err; | 3228 | return err; |
3201 | return 0; | 3229 | return 0; |
@@ -3236,16 +3264,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | |||
3236 | hda_nid_t dac = *dacs; | 3264 | hda_nid_t dac = *dacs; |
3237 | if (!dac) | 3265 | if (!dac) |
3238 | dac = spec->multiout.dac_nids[0]; | 3266 | dac = spec->multiout.dac_nids[0]; |
3239 | return alc_auto_create_extra_out(codec, *pins, dac, pfx); | 3267 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
3240 | } | 3268 | } |
3241 | 3269 | ||
3242 | if (dacs[num_pins - 1]) { | 3270 | if (dacs[num_pins - 1]) { |
3243 | /* OK, we have a multi-output system with individual volumes */ | 3271 | /* OK, we have a multi-output system with individual volumes */ |
3244 | for (i = 0; i < num_pins; i++) { | 3272 | for (i = 0; i < num_pins; i++) { |
3245 | snprintf(name, sizeof(name), "%s %s", | 3273 | if (num_pins >= 3) { |
3246 | pfx, channel_name[i]); | 3274 | snprintf(name, sizeof(name), "%s %s", |
3247 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | 3275 | pfx, channel_name[i]); |
3248 | 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 | } | ||
3249 | if (err < 0) | 3282 | if (err < 0) |
3250 | return err; | 3283 | return err; |
3251 | } | 3284 | } |