lkml.org 
[lkml]   [2008]   [Feb]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [ALSA] HDA: no sound in headphone-out caused by commit f889fa91ad47e (2.6.25-rc1 regression)
    At Tue, 12 Feb 2008 13:06:08 +0100,
    Matej Laitl wrote:
    >
    > Takashi Iwai wrote:
    > > I wrote:
    > > > Thanks.  It seems that your device has two headphone jacks according
    > > > to the BIOS setup, and this seems to be the problem.
    > > >
    > > > Could you show the kernel messages like "autoconfig: line_outs..." for
    > > > both cases?  This appears when build with CONFIG_SND_DEBUG=y.
    > >
    > > And the patch below may fix your problem.  Give it a try.
    >
    > With your patch, the sound in headphone-out is working again, but surprisingly
    > the integrated loudspeakers stopped working! ;)
    >
    > Also, new on/of control appeared in alsamixer - "Speaker", but unmuting it
    > (and unmuting all playback controls, plugging-out headphones) didn't have an
    > effect on non-working integrated loudspeakers.
    >
    > Some kernel mesgs with your patch:
    > hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...
    > autoconfig: line_outs=1 (0x1b/0x0/0x0/0x0/0x0)
    > speaker_outs=1 (0x14/0x0/0x0/0x0/0x0)
    > hp_outs=1 (0x15/0x1b/0x0/0x0/0x0)
    > mono: mono_out=0x0
    > inputs: mic=0x18, fmic=0x19, line=0x0, fline=0x0, cd=0x0, aux=0x0
    >
    > alsa-info.sh output:
    > http://pastebin.ca/901089

    Thanks. There seems a couple of bugs in this auto-configuration
    code. Try the additional patch below. This will unmute the
    speaker-pin.

    BTW, if the subsystem id were properly set by BIOS, you would have
    also the speaker auto-mute feature, but yours doesn't have it. Blame
    HP :)


    Takashi

    ---

    diff -r e84ee72676f0 sound/pci/hda/patch_realtek.c
    --- a/sound/pci/hda/patch_realtek.c Tue Feb 12 12:11:36 2008 +0100
    +++ b/sound/pci/hda/patch_realtek.c Tue Feb 12 14:54:51 2008 +0100
    @@ -746,7 +746,6 @@ static void alc_sku_automute(struct hda_
    static void alc_sku_automute(struct hda_codec *codec)
    {
    struct alc_spec *spec = codec->spec;
    - unsigned int mute;
    unsigned int present;
    unsigned int hp_nid = spec->autocfg.hp_pins[0];
    unsigned int sp_nid = spec->autocfg.speaker_pins[0];
    @@ -756,16 +755,8 @@ static void alc_sku_automute(struct hda_
    present = snd_hda_codec_read(codec, hp_nid, 0,
    AC_VERB_GET_PIN_SENSE, 0);
    spec->jack_present = (present & 0x80000000) != 0;
    - if (spec->jack_present) {
    - /* mute internal speaker */
    - snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
    - HDA_AMP_MUTE, HDA_AMP_MUTE);
    - } else {
    - /* unmute internal speaker if necessary */
    - mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
    - snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
    - HDA_AMP_MUTE, mute);
    - }
    + snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
    + spec->jack_present ? 0 : PIN_OUT);
    }

    /* unsolicited event for HP jack sensing */
    @@ -3486,15 +3477,20 @@ static int alc880_auto_create_analog_inp
    return 0;
    }

    -static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
    - hda_nid_t nid, int pin_type,
    - int dac_idx)
    -{
    - /* set as output */
    +static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
    + unsigned int pin_type)
    +{
    snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
    pin_type);
    snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
    AMP_OUT_UNMUTE);
    +}
    +
    +static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
    + hda_nid_t nid, int pin_type,
    + int dac_idx)
    +{
    + alc_set_pin_output(codec, nid, pin_type);
    /* need the manual connection? */
    if (alc880_is_multi_pin(nid)) {
    struct alc_spec *spec = codec->spec;
    @@ -3616,9 +3612,12 @@ static int alc880_parse_auto_config(stru
    /* additional initialization for auto-configuration model */
    static void alc880_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc880_auto_init_multi_out(codec);
    alc880_auto_init_extra_out(codec);
    alc880_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    /*
    @@ -4814,11 +4813,7 @@ static void alc260_auto_set_output_and_u
    hda_nid_t nid, int pin_type,
    int sel_idx)
    {
    - /* set as output */
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
    - pin_type);
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
    - AMP_OUT_UNMUTE);
    + alc_set_pin_output(codec, nid, pin_type);
    /* need the manual connection? */
    if (nid >= 0x12) {
    int idx = nid - 0x12;
    @@ -4965,8 +4960,11 @@ static int alc260_parse_auto_config(stru
    /* additional initialization for auto-configuration model */
    static void alc260_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc260_auto_init_multi_out(codec);
    alc260_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    #ifdef CONFIG_SND_HDA_POWER_SAVE
    @@ -6201,15 +6199,11 @@ static void alc882_auto_set_output_and_u
    struct alc_spec *spec = codec->spec;
    int idx;

    + alc_set_pin_output(codec, nid, pin_type);
    if (spec->multiout.dac_nids[dac_idx] == 0x25)
    idx = 4;
    else
    idx = spec->multiout.dac_nids[dac_idx] - 2;
    -
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
    - pin_type);
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
    - AMP_OUT_UNMUTE);
    snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);

    }
    @@ -6238,6 +6232,9 @@ static void alc882_auto_init_hp_out(stru
    if (pin) /* connect to front */
    /* use dac 0 */
    alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
    + pin = spec->autocfg.speaker_pins[0];
    + if (pin)
    + alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
    }

    #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
    @@ -6313,9 +6310,12 @@ static int alc882_parse_auto_config(stru
    /* additional initialization for auto-configuration model */
    static void alc882_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc882_auto_init_multi_out(codec);
    alc882_auto_init_hp_out(codec);
    alc882_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    static int patch_alc882(struct hda_codec *codec)
    @@ -7878,15 +7878,11 @@ static void alc883_auto_set_output_and_u
    struct alc_spec *spec = codec->spec;
    int idx;

    + alc_set_pin_output(codec, nid, pin_type);
    if (spec->multiout.dac_nids[dac_idx] == 0x25)
    idx = 4;
    else
    idx = spec->multiout.dac_nids[dac_idx] - 2;
    -
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
    - pin_type);
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
    - AMP_OUT_UNMUTE);
    snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);

    }
    @@ -7915,6 +7911,9 @@ static void alc883_auto_init_hp_out(stru
    if (pin) /* connect to front */
    /* use dac 0 */
    alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
    + pin = spec->autocfg.speaker_pins[0];
    + if (pin)
    + alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
    }

    #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
    @@ -7966,9 +7965,12 @@ static int alc883_parse_auto_config(stru
    /* additional initialization for auto-configuration model */
    static void alc883_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc883_auto_init_multi_out(codec);
    alc883_auto_init_hp_out(codec);
    alc883_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    static int patch_alc883(struct hda_codec *codec)
    @@ -9144,9 +9146,12 @@ static int alc262_parse_auto_config(stru
    /* init callback for auto-configuration model -- overriding the default init */
    static void alc262_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc262_auto_init_multi_out(codec);
    alc262_auto_init_hp_out(codec);
    alc262_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    /*
    @@ -10032,10 +10037,13 @@ static int alc268_parse_auto_config(stru
    /* init callback for auto-configuration model -- overriding the default init */
    static void alc268_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc268_auto_init_multi_out(codec);
    alc268_auto_init_hp_out(codec);
    alc268_auto_init_mono_speaker_out(codec);
    alc268_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    /*
    @@ -10504,9 +10512,12 @@ static int alc269_parse_auto_config(stru
    /* init callback for auto-configuration model -- overriding the default init */
    static void alc269_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc269_auto_init_multi_out(codec);
    alc269_auto_init_hp_out(codec);
    alc269_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    /*
    @@ -11428,13 +11439,7 @@ static void alc861_auto_set_output_and_u
    hda_nid_t nid,
    int pin_type, int dac_idx)
    {
    - /* set as output */
    -
    - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
    - pin_type);
    - snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
    - AMP_OUT_UNMUTE);
    -
    + alc_set_pin_output(codec, nid, pin_type);
    }

    static void alc861_auto_init_multi_out(struct hda_codec *codec)
    @@ -11461,6 +11466,9 @@ static void alc861_auto_init_hp_out(stru
    if (pin) /* connect to front */
    alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
    spec->multiout.dac_nids[0]);
    + pin = spec->autocfg.speaker_pins[0];
    + if (pin)
    + alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
    }

    static void alc861_auto_init_analog_input(struct hda_codec *codec)
    @@ -11533,9 +11541,12 @@ static int alc861_parse_auto_config(stru
    /* additional initialization for auto-configuration model */
    static void alc861_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc861_auto_init_multi_out(codec);
    alc861_auto_init_hp_out(codec);
    alc861_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    #ifdef CONFIG_SND_HDA_POWER_SAVE
    @@ -12396,11 +12407,7 @@ static void alc861vd_auto_set_output_and
    static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
    hda_nid_t nid, int pin_type, int dac_idx)
    {
    - /* set as output */
    - snd_hda_codec_write(codec, nid, 0,
    - AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
    - snd_hda_codec_write(codec, nid, 0,
    - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
    + alc_set_pin_output(codec, nid, pin_type);
    }

    static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
    @@ -12427,6 +12434,9 @@ static void alc861vd_auto_init_hp_out(st
    pin = spec->autocfg.hp_pins[0];
    if (pin) /* connect to front and use dac 0 */
    alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
    + pin = spec->autocfg.speaker_pins[0];
    + if (pin)
    + alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
    }

    #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
    @@ -12630,9 +12640,12 @@ static int alc861vd_parse_auto_config(st
    /* additional initialization for auto-configuration model */
    static void alc861vd_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc861vd_auto_init_multi_out(codec);
    alc861vd_auto_init_hp_out(codec);
    alc861vd_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    static int patch_alc861vd(struct hda_codec *codec)
    @@ -13452,11 +13465,7 @@ static void alc662_auto_set_output_and_u
    hda_nid_t nid, int pin_type,
    int dac_idx)
    {
    - /* set as output */
    - snd_hda_codec_write(codec, nid, 0,
    - AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
    - snd_hda_codec_write(codec, nid, 0,
    - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
    + alc_set_pin_output(codec, nid, pin_type);
    /* need the manual connection? */
    if (alc880_is_multi_pin(nid)) {
    struct alc_spec *spec = codec->spec;
    @@ -13491,6 +13500,9 @@ static void alc662_auto_init_hp_out(stru
    if (pin) /* connect to front */
    /* use dac 0 */
    alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
    + pin = spec->autocfg.speaker_pins[0];
    + if (pin)
    + alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
    }

    #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
    @@ -13568,9 +13580,12 @@ static int alc662_parse_auto_config(stru
    /* additional initialization for auto-configuration model */
    static void alc662_auto_init(struct hda_codec *codec)
    {
    + struct alc_spec *spec = codec->spec;
    alc662_auto_init_multi_out(codec);
    alc662_auto_init_hp_out(codec);
    alc662_auto_init_analog_input(codec);
    + if (spec->unsol_event)
    + alc_sku_automute(codec);
    }

    static int patch_alc662(struct hda_codec *codec)
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2008-02-12 15:05    [W:0.058 / U:29.936 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site