From 8d88bc3d361bdd81a214eb9c5d06b291d06c603a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 17 Nov 2005 11:09:23 +0100 Subject: [PATCH] [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: Takashi Iwai --- sound/pci/hda/hda_codec.c | 4 ++- sound/pci/hda/hda_local.h | 15 +++++++++++ sound/pci/hda/patch_cmedia.c | 13 ---------- sound/pci/hda/patch_realtek.c | 47 ++++++++++++++++------------------- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index cfd50b56187b..2e9f5877386e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.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); switch (get_defcfg_device(def_conf)) { case AC_JACK_LINE_OUT: - case AC_JACK_SPEAKER: seq = get_defcfg_sequence(def_conf); assoc = get_defcfg_association(def_conf); if (! assoc) @@ -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; cfg->line_outs++; break; + case AC_JACK_SPEAKER: + cfg->speaker_pin = nid; + break; case AC_JACK_HP_OUT: cfg->hp_pin = nid; break; diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 05a88fb1d652..31d3c7ef5842 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -214,6 +214,7 @@ enum { struct auto_pin_cfg { int line_outs; 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 input_pins[AUTO_PIN_LAST]; hda_nid_t dig_out_pin; @@ -228,4 +229,18 @@ struct auto_pin_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 */ diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 6e0fd92a2be3..37ee1246b2dd 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -76,19 +76,6 @@ struct cmi_spec { 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 */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a213c19ab06c..3ff72c49cd26 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -61,20 +61,6 @@ enum { 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 { /* codec parameterization */ 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 return err; } } - return 0; } -/* add playback controls for HP output */ -static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) +/* add playback controls for speaker and HP outputs */ +static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, + const char *pfx) { hda_nid_t nid; int err; + char name[32]; if (! pin) return 0; @@ -1854,14 +1841,16 @@ static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) if (! spec->multiout.num_dacs) spec->multiout.num_dacs = 1; } else - /* specify the DAC as the extra HP output */ + /* specify the DAC as the extra output */ spec->multiout.hp_nid = nid; /* control HP volume/switch on the output mixer amp */ 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) 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) return err; } 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) spec->multiout.num_dacs = 1; } /* 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) return err; } @@ -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; 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; if (pin) /* connect to front */ 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) return err; if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0) 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 */ 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) return err; @@ -2014,7 +2011,7 @@ static int alc880_auto_init(struct hda_codec *codec) { alc_init(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); return 0; }