lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <AANLkTik6qSuPdZJ2Ziq-GUHuXfKOBO8154Uv1NsQK=Zc@mail.gmail.com>
Date:	Mon, 10 Jan 2011 23:31:19 +0530
From:	Nirbheek Chauhan <nirbheek.chauhan@...il.com>
To:	Takashi Iwai <tiwai@...e.de>
Cc:	Jaroslav Kysela <perex@...ex.cz>,
	Kailang Yang <kailang@...ltek.com>,
	linux-kernel@...r.kernel.org, alsa-devel@...a-project.org,
	arun@...osted.net
Subject: Re: [bisected] snd_hda_intel, 2.6.37: automuting on headphone connect
 broken; headphone connecter no longer shown in userspace

On Mon, Jan 10, 2011 at 8:19 PM, Takashi Iwai <tiwai@...e.de> wrote:
> At Mon, 10 Jan 2011 14:54:25 +0100,
> Takashi Iwai wrote:
>>
>> At Wed, 5 Jan 2011 13:07:41 +0530,
>> Nirbheek Chauhan wrote:
>> >
>> > Hello,
>> >
>> > Upon upgrading to 2.6.37,
>> > auto-muting-laptop-speakers-on-headphone-connect stopped working, and
>> > the headphone connector completely disappeared from alsamixer as well
>> > as the pulseaudio volume control panel. The headphone jack was still
>> > transmitting sound, though.
>> >
>> > I bisected the problem, with 'good' being v2.6.36, and found the
>> > commit below as the first bad commit. Reverting it on v2.6.37 fixes
>> > the problem. I also tried the latest alsa-kernel master git tree,
>> > which had the same problem.
>> >
>> > alsa-info when 'good':
>> >
>> > http://www.alsa-project.org/db/?f=a0b5c95f764a0b01746be46f989685996e1f9210
>> >
>> > alsa-info when 'bad':
>> >
>> > http://www.alsa-project.org/db/?f=30f30ca5461f03b98ab6c7c611cf24ea4526f537
>> >
>> > Note: both were taken without X running, before pulseaudio came up.
>> >
>> > ================
>> > 03642c9a444079aa13f0864383a8f9ca04bfd198 is the first bad commit
>> > commit 03642c9a444079aa13f0864383a8f9ca04bfd198
>> > Author: Takashi Iwai <tiwai@...e.de>
>> > Date:   Wed Sep 8 15:28:19 2010 +0200
>> >
>> >     ALSA: hda - Clear left-over hp_pins in snd_hda_parse_pin_def_config()
>> >
>> >     In snd_hda_parse_def_config(), some unused values may remain in hp_pins[]
>> >     array during the headphone-reassignment workaround.  This patch clears
>> >     the unused array members.
>> >
>> >     Signed-off-by: Takashi Iwai <tiwai@...e.de>
>> >
>> > :040000 040000 34724336a75f74263423f28d64450d65e5ed948d
>> > 8d136fce8661ad2df35ac3c4a9ca1c712c9833ed M  sound
>> >
>> > ================
>>
>> It seems that the driver worked casually in the earlier versions :)
>> Does the patch below fix your problem?
>>
>> Note that the "Headphone" control will still not appear even with this
>> patch, but these two outputs are controlled by "Front" and "Surround"
>> controls.  The lack of "Headphone" is no regression but simply it
>> shouldn't have been there.
>>
>> I'll work on 2.6.38 tree for better handling of multi headphone
>> cases.
>
> The patch is below.  Give it a try.
>

This patch made the jacks and their alsamixer controls function
exactly as I expected them to!

(I have to admit, at first I applied only this patch without the
previous one, and that made things really weird. I had fully
documented the weirdness before I realised that the first patch might
not have been *just* for stable)

alsamixer layout:
[Master] [Headphone] [Headphone 1] [Speaker] [PCM] [Mic 1] [Mic Boost 1]

alsa-info:
http://www.alsa-project.org/db/?f=34790490c2d70f019b14b22f8e94289425b1bcd6

* `Speaker` is only toggle-mute
* `PCM` has no toggle-mute
* `Master` affects audio in all outputs
* Inserting a jack into either headphone socket mutes the laptop speakers
* `Headphone` and `Headphone 1` control their respective headphones
(maybe they should be named Headphone 1, Headphone 2?)
* `Speaker` mutes the laptop speakers
* `PCM` affects audio in all outputs

All this is without pulseaudio running. Pulseaudio doesn't seem to be
able to handle multiple headphones nicely, and I can't control which
connector an audio stream goes to at all (not a regression, I would
note). But I guess this one is for the PA devs :-)

I'll be using both these patches, and will report any bugs I find.

Thanks a lot!

>
> Takashi
>
> ===
> From bcb2f0f517ebae7350526bbde8912ad187147e2d Mon Sep 17 00:00:00 2001
> From: Takashi Iwai <tiwai@...e.de>
> Date: Mon, 10 Jan 2011 15:45:23 +0100
> Subject: [PATCH] ALSA: hda - Add support for multiple headphone/speaker controls for Realtek
>
> So far, Realtek auto-parser assumed that the multiple pins are only for
> line-outs, and assigned the channel names like Front, Surround, etc for
> the multiple outputs.  But, there are devices that have multiple
> headphones, and these can be better controlled with the corresponding
> control-name like "Headphone" with indicies.
>
> Signed-off-by: Takashi Iwai <tiwai@...e.de>
> ---
>  sound/pci/hda/patch_realtek.c |  137 ++++++++++++++++++++---------------------
>  1 files changed, 68 insertions(+), 69 deletions(-)
>
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index b4f7895..0ecd75e 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -5068,6 +5068,25 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
>        return 0;
>  }
>
> +static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
> +                                       bool can_be_master)
> +{
> +       if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
> +               return "Master";
> +
> +       switch (cfg->line_out_type) {
> +       case AUTO_PIN_SPEAKER_OUT:
> +               return "Speaker";
> +       case AUTO_PIN_HP_OUT:
> +               return "Headphone";
> +       default:
> +               if (cfg->line_outs == 1)
> +                       return "PCM";
> +               break;
> +       }
> +       return NULL;
> +}
> +
>  /* add playback controls from the parsed DAC table */
>  static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
>                                             const struct auto_pin_cfg *cfg)
> @@ -5075,6 +5094,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
>        static const char *chname[4] = {
>                "Front", "Surround", NULL /*CLFE*/, "Side"
>        };
> +       const char *pfx = alc_get_line_out_pfx(cfg, false);
>        hda_nid_t nid;
>        int i, err;
>
> @@ -5082,7 +5102,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
>                if (!spec->multiout.dac_nids[i])
>                        continue;
>                nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
> -               if (i == 2) {
> +               if (!pfx && i == 2) {
>                        /* Center/LFE */
>                        err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
>                                              "Center",
> @@ -5109,18 +5129,17 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
>                        if (err < 0)
>                                return err;
>                } else {
> -                       const char *pfx;
> -                       if (cfg->line_outs == 1 &&
> -                           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
> -                               pfx = "Speaker";
> -                       else
> -                               pfx = chname[i];
> -                       err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
> +                       const char *name = pfx;
> +                       if (!name)
> +                               name = chname[i];
> +                       err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
> +                                               name, i,
>                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
>                                                              HDA_OUTPUT));
>                        if (err < 0)
>                                return err;
> -                       err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
> +                       err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
> +                                              name, i,
>                                          HDA_COMPOSE_AMP_VAL(nid, 3, 2,
>                                                              HDA_INPUT));
>                        if (err < 0)
> @@ -12085,13 +12104,8 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
>        spec->multiout.dac_nids = spec->private_dac_nids;
>        spec->multiout.dac_nids[0] = 2;
>
> -       if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
> -               pfx = "Master";
> -       else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
> -               pfx = "Speaker";
> -       else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
> -               pfx = "Headphone";
> -       else
> +       pfx = alc_get_line_out_pfx(cfg, true);
> +       if (!pfx)
>                pfx = "Front";
>        for (i = 0; i < 2; i++) {
>                err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
> @@ -15885,13 +15899,16 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
>        return 0;
>  }
>
> -static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
> -                               hda_nid_t nid, unsigned int chs)
> +static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
> +                                 hda_nid_t nid, int idx, unsigned int chs)
>  {
> -       return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
> +       return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
>                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
>  }
>
> +#define alc861_create_out_sw(codec, pfx, nid, chs) \
> +       __alc861_create_out_sw(codec, pfx, nid, 0, chs)
> +
>  /* add playback controls from the parsed DAC table */
>  static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
>                                             const struct auto_pin_cfg *cfg)
> @@ -15900,26 +15917,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
>        static const char *chname[4] = {
>                "Front", "Surround", NULL /*CLFE*/, "Side"
>        };
> +       const char *pfx = alc_get_line_out_pfx(cfg, true);
>        hda_nid_t nid;
>        int i, err;
>
> -       if (cfg->line_outs == 1) {
> -               const char *pfx = NULL;
> -               if (!cfg->hp_outs)
> -                       pfx = "Master";
> -               else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
> -                       pfx = "Speaker";
> -               if (pfx) {
> -                       nid = spec->multiout.dac_nids[0];
> -                       return alc861_create_out_sw(codec, pfx, nid, 3);
> -               }
> -       }
> -
>        for (i = 0; i < cfg->line_outs; i++) {
>                nid = spec->multiout.dac_nids[i];
>                if (!nid)
>                        continue;
> -               if (i == 2) {
> +               if (!pfx && i == 2) {
>                        /* Center/LFE */
>                        err = alc861_create_out_sw(codec, "Center", nid, 1);
>                        if (err < 0)
> @@ -15928,7 +15934,10 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
>                        if (err < 0)
>                                return err;
>                } else {
> -                       err = alc861_create_out_sw(codec, chname[i], nid, 3);
> +                       const char *name = pfx;
> +                       if (!name)
> +                               name = chname[i];
> +                       err = __alc861_create_out_sw(codec, name, nid, i, 3);
>                        if (err < 0)
>                                return err;
>                }
> @@ -17033,6 +17042,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
>                                             const struct auto_pin_cfg *cfg)
>  {
>        static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
> +       const char *pfx = alc_get_line_out_pfx(cfg, true);
>        hda_nid_t nid_v, nid_s;
>        int i, err;
>
> @@ -17046,7 +17056,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
>                                alc880_dac_to_idx(
>                                        spec->multiout.dac_nids[i]));
>
> -               if (i == 2) {
> +               if (!pfx && i == 2) {
>                        /* Center/LFE */
>                        err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
>                                              "Center",
> @@ -17073,24 +17083,17 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
>                        if (err < 0)
>                                return err;
>                } else {
> -                       const char *pfx;
> -                       if (cfg->line_outs == 1 &&
> -                           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
> -                               if (!cfg->hp_pins)
> -                                       pfx = "Speaker";
> -                               else
> -                                       pfx = "PCM";
> -                       } else
> -                               pfx = chname[i];
> -                       err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
> +                       const char *name = pfx;
> +                       if (!name)
> +                               name = chname[i];
> +                       err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
> +                                               name, i,
>                                          HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
>                                                              HDA_OUTPUT));
>                        if (err < 0)
>                                return err;
> -                       if (cfg->line_outs == 1 &&
> -                           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
> -                               pfx = "Speaker";
> -                       err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
> +                       err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
> +                                              name, i,
>                                          HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
>                                                              HDA_INPUT));
>                        if (err < 0)
> @@ -19078,20 +19081,24 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
>        return 0;
>  }
>
> -static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
> -                             hda_nid_t nid, unsigned int chs)
> +static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
> +                                      hda_nid_t nid, int idx, unsigned int chs)
>  {
> -       return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
> +       return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
>                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
>  }
>
> -static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
> -                            hda_nid_t nid, unsigned int chs)
> +static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
> +                                     hda_nid_t nid, int idx, unsigned int chs)
>  {
> -       return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
> +       return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
>                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
>  }
>
> +#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
> +       __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
> +#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
> +       __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
>  #define alc662_add_stereo_vol(spec, pfx, nid) \
>        alc662_add_vol_ctl(spec, pfx, nid, 3)
>  #define alc662_add_stereo_sw(spec, pfx, nid) \
> @@ -19105,6 +19112,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
>        static const char *chname[4] = {
>                "Front", "Surround", NULL /*CLFE*/, "Side"
>        };
> +       const char *pfx = alc_get_line_out_pfx(cfg, true);
>        hda_nid_t nid, mix;
>        int i, err;
>
> @@ -19115,7 +19123,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
>                mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
>                if (!mix)
>                        continue;
> -               if (i == 2) {
> +               if (!pfx && i == 2) {
>                        /* Center/LFE */
>                        err = alc662_add_vol_ctl(spec, "Center", nid, 1);
>                        if (err < 0)
> @@ -19130,22 +19138,13 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
>                        if (err < 0)
>                                return err;
>                } else {
> -                       const char *pfx;
> -                       if (cfg->line_outs == 1 &&
> -                           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
> -                               if (cfg->hp_outs)
> -                                       pfx = "Speaker";
> -                               else
> -                                       pfx = "PCM";
> -                       } else
> -                               pfx = chname[i];
> -                       err = alc662_add_vol_ctl(spec, pfx, nid, 3);
> +                       const char *name = pfx;
> +                       if (!name)
> +                               name = chname[i];
> +                       err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
>                        if (err < 0)
>                                return err;
> -                       if (cfg->line_outs == 1 &&
> -                           cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
> -                               pfx = "Speaker";
> -                       err = alc662_add_sw_ctl(spec, pfx, mix, 3);
> +                       err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
>                        if (err < 0)
>                                return err;
>                }
> --
> 1.7.3.4
>
>



-- 
~Nirbheek Chauhan

Gentoo GNOME+Mozilla Team

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ