Commit 8d88bc3d authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[ALSA] hda-codec - Fix assignment of speaker pin

Modules: HDA Codec driver,HDA generic driver

Fix the auto-assignment of speaker pin.  Handle it independently from
line-out pins.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent a2a20939
...@@ -1889,7 +1889,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c ...@@ -1889,7 +1889,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
loc = get_defcfg_location(def_conf); loc = get_defcfg_location(def_conf);
switch (get_defcfg_device(def_conf)) { switch (get_defcfg_device(def_conf)) {
case AC_JACK_LINE_OUT: case AC_JACK_LINE_OUT:
case AC_JACK_SPEAKER:
seq = get_defcfg_sequence(def_conf); seq = get_defcfg_sequence(def_conf);
assoc = get_defcfg_association(def_conf); assoc = get_defcfg_association(def_conf);
if (! assoc) if (! assoc)
...@@ -1904,6 +1903,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c ...@@ -1904,6 +1903,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c
sequences[cfg->line_outs] = seq; sequences[cfg->line_outs] = seq;
cfg->line_outs++; cfg->line_outs++;
break; break;
case AC_JACK_SPEAKER:
cfg->speaker_pin = nid;
break;
case AC_JACK_HP_OUT: case AC_JACK_HP_OUT:
cfg->hp_pin = nid; cfg->hp_pin = nid;
break; break;
......
...@@ -214,6 +214,7 @@ enum { ...@@ -214,6 +214,7 @@ enum {
struct auto_pin_cfg { struct auto_pin_cfg {
int line_outs; int line_outs;
hda_nid_t line_out_pins[4]; /* sorted in the order of Front/Surr/CLFE/Side */ hda_nid_t line_out_pins[4]; /* sorted in the order of Front/Surr/CLFE/Side */
hda_nid_t speaker_pin;
hda_nid_t hp_pin; hda_nid_t hp_pin;
hda_nid_t input_pins[AUTO_PIN_LAST]; hda_nid_t input_pins[AUTO_PIN_LAST];
hda_nid_t dig_out_pin; hda_nid_t dig_out_pin;
...@@ -228,4 +229,18 @@ struct auto_pin_cfg { ...@@ -228,4 +229,18 @@ struct auto_pin_cfg {
int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg); int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg);
/* amp values */
#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
#define AMP_OUT_MUTE 0xb080
#define AMP_OUT_UNMUTE 0xb000
#define AMP_OUT_ZERO 0xb000
/* pinctl values */
#define PIN_IN 0x20
#define PIN_VREF80 0x24
#define PIN_VREF50 0x21
#define PIN_OUT 0x40
#define PIN_HP 0xc0
#define PIN_HP_AMP 0x80
#endif /* __SOUND_HDA_LOCAL_H */ #endif /* __SOUND_HDA_LOCAL_H */
...@@ -76,19 +76,6 @@ struct cmi_spec { ...@@ -76,19 +76,6 @@ struct cmi_spec {
struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */ struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */
}; };
/* amp values */
#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
#define AMP_OUT_MUTE 0xb080
#define AMP_OUT_UNMUTE 0xb000
#define AMP_OUT_ZERO 0xb000
/* pinctl values */
#define PIN_IN 0x20
#define PIN_VREF80 0x24
#define PIN_VREF50 0x21
#define PIN_OUT 0x40
#define PIN_HP 0xc0
/* /*
* input MUX * input MUX
*/ */
......
...@@ -61,20 +61,6 @@ enum { ...@@ -61,20 +61,6 @@ enum {
ALC260_MODEL_LAST /* last tag */ ALC260_MODEL_LAST /* last tag */
}; };
/* amp values */
#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
#define AMP_OUT_MUTE 0xb080
#define AMP_OUT_UNMUTE 0xb000
#define AMP_OUT_ZERO 0xb000
/* pinctl values */
#define PIN_IN 0x20
#define PIN_VREF80 0x24
#define PIN_VREF50 0x21
#define PIN_OUT 0x40
#define PIN_HP 0xc0
#define PIN_HP_AMP 0x80
struct alc_spec { struct alc_spec {
/* codec parameterization */ /* codec parameterization */
snd_kcontrol_new_t *mixers[3]; /* mixer arrays */ snd_kcontrol_new_t *mixers[3]; /* mixer arrays */
...@@ -1833,15 +1819,16 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct ...@@ -1833,15 +1819,16 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct
return err; return err;
} }
} }
return 0; return 0;
} }
/* add playback controls for HP output */ /* add playback controls for speaker and HP outputs */
static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
const char *pfx)
{ {
hda_nid_t nid; hda_nid_t nid;
int err; int err;
char name[32];
if (! pin) if (! pin)
return 0; return 0;
...@@ -1854,14 +1841,16 @@ static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) ...@@ -1854,14 +1841,16 @@ static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
if (! spec->multiout.num_dacs) if (! spec->multiout.num_dacs)
spec->multiout.num_dacs = 1; spec->multiout.num_dacs = 1;
} else } else
/* specify the DAC as the extra HP output */ /* specify the DAC as the extra output */
spec->multiout.hp_nid = nid; spec->multiout.hp_nid = nid;
/* control HP volume/switch on the output mixer amp */ /* control HP volume/switch on the output mixer amp */
nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", sprintf(name, "%s Playback Volume", pfx);
if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
return err; return err;
if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Headphone Playback Switch", sprintf(name, "%s Playback Switch", pfx);
if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
return err; return err;
} else if (alc880_is_multi_pin(pin)) { } else if (alc880_is_multi_pin(pin)) {
...@@ -1873,7 +1862,8 @@ static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) ...@@ -1873,7 +1862,8 @@ static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
spec->multiout.num_dacs = 1; spec->multiout.num_dacs = 1;
} }
/* we have only a switch on HP-out PIN */ /* we have only a switch on HP-out PIN */
if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", sprintf(name, "%s Playback Switch", pfx);
if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
return err; return err;
} }
...@@ -1947,11 +1937,14 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec) ...@@ -1947,11 +1937,14 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
} }
} }
static void alc880_auto_init_hp_out(struct hda_codec *codec) static void alc880_auto_init_extra_out(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
hda_nid_t pin; hda_nid_t pin;
pin = spec->autocfg.speaker_pin;
if (pin) /* connect to front */
alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
pin = spec->autocfg.hp_pin; pin = spec->autocfg.hp_pin;
if (pin) /* connect to front */ if (pin) /* connect to front */
alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
...@@ -1985,10 +1978,14 @@ static int alc880_parse_auto_config(struct hda_codec *codec) ...@@ -1985,10 +1978,14 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
return err; return err;
if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0) if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0)
return err; return err;
if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
! spec->autocfg.hp_pin)
return 0; /* can't find valid BIOS pin config */ return 0; /* can't find valid BIOS pin config */
if ((err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || if ((err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
(err = alc880_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 || (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
"Speaker")) < 0 ||
(err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
"Headphone")) < 0 ||
(err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
return err; return err;
...@@ -2014,7 +2011,7 @@ static int alc880_auto_init(struct hda_codec *codec) ...@@ -2014,7 +2011,7 @@ static int alc880_auto_init(struct hda_codec *codec)
{ {
alc_init(codec); alc_init(codec);
alc880_auto_init_multi_out(codec); alc880_auto_init_multi_out(codec);
alc880_auto_init_hp_out(codec); alc880_auto_init_extra_out(codec);
alc880_auto_init_analog_input(codec); alc880_auto_init_analog_input(codec);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment