aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c65
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 */
2926static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, 2931static 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
2946static int alc_auto_fill_multi_ios(struct hda_codec *codec, 2951static 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,
2950static int alc_auto_fill_dac_nids(struct hda_codec *codec) 2955static 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
3173static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, 3200static 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 }