lkml.org 
[lkml]   [2011]   [Oct]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: ALSA: HDA: conexant support for Lenovo T520/W520
    At Tue, 18 Oct 2011 11:00:01 +0200,
    Daniel Suchy wrote:
    >
    > Hello,
    > thanks for information.
    >
    > My output from alsa-info is available at
    > http://www.alsa-project.org/db/?f=94efb9fda4bcf6771ca4868c62b11994dc4dc776
    >
    > Internal microphone works fine for me, but I don't have external one for
    > testing at this time. FYI, T520 also doesn't have external microphone
    > input, it's available only over docking station (Minidock 3). I'll
    > perform more tests in upcoming days (generally, I don't use audio inputs
    > too much), also with your patch.

    Wait, did you test "Internal Mic" or "Mic" volume?
    In your case, only the former volume should affect the recording level
    from the built-in mic, not the latter. If the latter changes the
    recording level, it's a bug. And the patch I attached in the previous
    mail should fix it.

    > There's another issue I observed related to audio outputs, but I'm not
    > sure about the reason. With docking station, audio isn't working over
    > audio output on the Minidock 3. Internal speakers are cutted off
    > properly, but there's no sound output on the connector. Audio output on
    > T520 directly works as expected, only output on minidock has this
    > problem. If you have any hints, let me know. This happens even with
    > autodetection enabled (this was my initial motivation for looking into
    > the driver source, and also CXT5066_THINKPAD quirk, which I tested
    > previously has this problem).

    Might be an EAPD issue? There is another pending patch. Attached
    below.


    thanks,

    Takashi

    ---
    From: Takashi Iwai <tiwai@suse.de>
    Subject: [PATCH] ALSA: hda - Keep EAPD turned on for old Conexant chips

    In the old Conexant chips (5045, 5047, 5051 and 5066), a single EAPD
    may handle both headphone and speaker outputs while it's assigned only
    to one of them. Turning off dynamically leads to the unexpected silent
    output in such a configuration with the auto-mute function.

    Since it's difficult to know how the EAPD is handled in the actual h/w
    implementation, better to keep EAPD on while running for such codecs.

    Cc: <stable@kernel.org>
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    ---
    sound/pci/hda/patch_conexant.c | 43 ++++++++++++++++++++-------------------
    1 files changed, 22 insertions(+), 21 deletions(-)

    diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
    index aa0e4b9..feef775 100644
    --- a/sound/pci/hda/patch_conexant.c
    +++ b/sound/pci/hda/patch_conexant.c
    @@ -136,6 +136,7 @@ struct conexant_spec {
    unsigned int thinkpad:1;
    unsigned int hp_laptop:1;
    unsigned int asus:1;
    + unsigned int pin_eapd_ctrls:1;

    unsigned int adc_switching:1;

    @@ -3429,12 +3430,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
    static void do_automute(struct hda_codec *codec, int num_pins,
    hda_nid_t *pins, bool on)
    {
    + struct conexant_spec *spec = codec->spec;
    int i;
    for (i = 0; i < num_pins; i++)
    snd_hda_codec_write(codec, pins[i], 0,
    AC_VERB_SET_PIN_WIDGET_CONTROL,
    on ? PIN_OUT : 0);
    - cx_auto_turn_eapd(codec, num_pins, pins, on);
    + if (spec->pin_eapd_ctrls)
    + cx_auto_turn_eapd(codec, num_pins, pins, on);
    }

    static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
    @@ -3459,9 +3462,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
    int on = 1;

    /* turn on HP EAPD when HP jacks are present */
    - if (spec->auto_mute)
    - on = spec->hp_present;
    - cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
    + if (spec->pin_eapd_ctrls) {
    + if (spec->auto_mute)
    + on = spec->hp_present;
    + cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
    + }
    +
    /* mute speakers in auto-mode if HP or LO jacks are plugged */
    if (spec->auto_mute)
    on = !(spec->hp_present ||
    @@ -3888,20 +3894,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
    #define cx_auto_parse_beep(codec)
    #endif

    -static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
    -{
    - int i;
    - for (i = 0; i < nums; i++)
    - if (list[i] == nid)
    - return true;
    - return false;
    -}
    -
    -/* parse extra-EAPD that aren't assigned to any pins */
    +/* parse EAPDs */
    static void cx_auto_parse_eapd(struct hda_codec *codec)
    {
    struct conexant_spec *spec = codec->spec;
    - struct auto_pin_cfg *cfg = &spec->autocfg;
    hda_nid_t nid, end_nid;

    end_nid = codec->start_nid + codec->num_nodes;
    @@ -3910,14 +3906,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
    continue;
    if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
    continue;
    - if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
    - found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
    - found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
    - continue;
    spec->eapds[spec->num_eapds++] = nid;
    if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
    break;
    }
    +
    + /* NOTE: below is a wild guess; if we have more than two EAPDs,
    + * it's a new chip, where EAPDs are supposed to be associated to
    + * pins, and we can control EAPD per pin.
    + * OTOH, if only one or two EAPDs are found, it's an old chip,
    + * thus it might control over all pins.
    + */
    + spec->pin_eapd_ctrls = spec->num_eapds > 2;
    }

    static int cx_auto_parse_auto_config(struct hda_codec *codec)
    @@ -4023,8 +4023,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
    }
    }
    cx_auto_update_speakers(codec);
    - /* turn on/off extra EAPDs, too */
    - cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
    + /* turn on all EAPDs if no individual EAPD control is available */
    + if (!spec->pin_eapd_ctrls)
    + cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
    }

    static void cx_auto_init_input(struct hda_codec *codec)
    --
    1.7.7


    \
     
     \ /
      Last update: 2011-10-18 11:07    [W:0.027 / U:33.384 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site