lkml.org 
[lkml]   [2008]   [Nov]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[GIT PULL] ALSA fixes
    Linus,

    please pull ALSA updates for 2.6.28-rc5 from:

    git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git for-linus

    This contains fixes for bugs with STAC/IDT HD-audio codecs, typically
    hitting Dell laptops.


    Thanks!

    Takashi

    ===

    Takashi Iwai (3):
    ALSA: hda - Add missing analog-mux mixer creation for STAC9200
    ALSA: hda - Fix input pin initialization for STAC/IDT codecs
    ALSA: hda - Fix IDT/STAC multiple HP detection

    ---
    sound/pci/hda/patch_sigmatel.c | 85 +++++++++++++++++++++++++++++----------
    1 files changed, 63 insertions(+), 22 deletions(-)

    diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
    index e608591..4300a67 100644
    --- a/sound/pci/hda/patch_sigmatel.c
    +++ b/sound/pci/hda/patch_sigmatel.c
    @@ -212,7 +212,7 @@ struct sigmatel_spec {
    /* i/o switches */
    unsigned int io_switch[2];
    unsigned int clfe_swap;
    - unsigned int hp_switch;
    + unsigned int hp_switch; /* NID of HP as line-out */
    unsigned int aloopback;

    struct hda_pcm pcm_rec[2]; /* PCM information */
    @@ -2443,7 +2443,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
    struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
    struct sigmatel_spec *spec = codec->spec;

    - ucontrol->value.integer.value[0] = spec->hp_switch;
    + ucontrol->value.integer.value[0] = !!spec->hp_switch;
    return 0;
    }

    @@ -2452,8 +2452,9 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
    {
    struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
    struct sigmatel_spec *spec = codec->spec;
    -
    - spec->hp_switch = ucontrol->value.integer.value[0];
    + int nid = kcontrol->private_value;
    +
    + spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0;

    /* check to be sure that the ports are upto date with
    * switch changes
    @@ -2862,7 +2863,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
    if (cfg->hp_outs > 1) {
    err = stac92xx_add_control(spec,
    STAC_CTL_WIDGET_HP_SWITCH,
    - "Headphone as Line Out Switch", 0);
    + "Headphone as Line Out Switch",
    + cfg->hp_pins[cfg->hp_outs - 1]);
    if (err < 0)
    return err;
    }
    @@ -3530,6 +3532,12 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
    if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0)
    return err;

    + if (spec->num_muxes > 0) {
    + err = stac92xx_auto_create_mux_input_ctls(codec);
    + if (err < 0)
    + return err;
    + }
    +
    if (spec->autocfg.dig_out_pin)
    spec->multiout.dig_out_nid = 0x05;
    if (spec->autocfg.dig_in_pin)
    @@ -3647,14 +3655,18 @@ static int stac92xx_init(struct hda_codec *codec)
    for (i = 0; i < AUTO_PIN_LAST; i++) {
    hda_nid_t nid = cfg->input_pins[i];
    if (nid) {
    - unsigned int pinctl = snd_hda_codec_read(codec, nid,
    - 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
    - /* if PINCTL already set then skip */
    - if (pinctl & AC_PINCAP_IN)
    - continue;
    - pinctl = AC_PINCTL_IN_EN;
    - if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC)
    - pinctl |= stac92xx_get_vref(codec, nid);
    + unsigned int pinctl;
    + if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
    + /* for mic pins, force to initialize */
    + pinctl = stac92xx_get_vref(codec, nid);
    + } else {
    + pinctl = snd_hda_codec_read(codec, nid, 0,
    + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
    + /* if PINCTL already set then skip */
    + if (pinctl & AC_PINCTL_IN_EN)
    + continue;
    + }
    + pinctl |= AC_PINCTL_IN_EN;
    stac92xx_auto_set_pinctl(codec, nid, pinctl);
    }
    }
    @@ -3776,11 +3788,30 @@ static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid)
    return 0;
    }

    +/* return non-zero if the hp-pin of the given array index isn't
    + * a jack-detection target
    + */
    +static int no_hp_sensing(struct sigmatel_spec *spec, int i)
    +{
    + struct auto_pin_cfg *cfg = &spec->autocfg;
    +
    + /* ignore sensing of shared line and mic jacks */
    + if (spec->line_switch &&
    + cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
    + return 1;
    + if (spec->mic_switch &&
    + cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
    + return 1;
    + /* ignore if the pin is set as line-out */
    + if (cfg->hp_pins[i] == spec->hp_switch)
    + return 1;
    + return 0;
    +}
    +
    static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
    {
    struct sigmatel_spec *spec = codec->spec;
    struct auto_pin_cfg *cfg = &spec->autocfg;
    - int nid = cfg->hp_pins[cfg->hp_outs - 1];
    int i, presence;

    presence = 0;
    @@ -3791,15 +3822,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
    for (i = 0; i < cfg->hp_outs; i++) {
    if (presence)
    break;
    - if (spec->hp_switch && cfg->hp_pins[i] == nid)
    - break;
    + if (no_hp_sensing(spec, i))
    + continue;
    presence = get_hp_pin_presence(codec, cfg->hp_pins[i]);
    }

    if (presence) {
    - /* disable lineouts, enable hp */
    + /* disable lineouts */
    if (spec->hp_switch)
    - stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN);
    + stac92xx_reset_pinctl(codec, spec->hp_switch,
    + AC_PINCTL_OUT_EN);
    for (i = 0; i < cfg->line_outs; i++)
    stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
    AC_PINCTL_OUT_EN);
    @@ -3811,9 +3843,10 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
    spec->gpio_dir, spec->gpio_data &
    ~spec->eapd_mask);
    } else {
    - /* enable lineouts, disable hp */
    + /* enable lineouts */
    if (spec->hp_switch)
    - stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
    + stac92xx_set_pinctl(codec, spec->hp_switch,
    + AC_PINCTL_OUT_EN);
    for (i = 0; i < cfg->line_outs; i++)
    stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
    AC_PINCTL_OUT_EN);
    @@ -3825,8 +3858,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
    spec->gpio_dir, spec->gpio_data |
    spec->eapd_mask);
    }
    - if (!spec->hp_switch && cfg->hp_outs > 1 && presence)
    - stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
    + /* toggle hp outs */
    + for (i = 0; i < cfg->hp_outs; i++) {
    + unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
    + if (no_hp_sensing(spec, i))
    + continue;
    + if (presence)
    + stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
    + else
    + stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val);
    + }
    }

    static void stac92xx_pin_sense(struct hda_codec *codec, int idx)

    \
     
     \ /
      Last update: 2008-11-12 16:59    [W:0.028 / U:29.444 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site