lkml.org 
[lkml]   [2016]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 031/163] ALSA: hda - Keep powering up ADCs on Cirrus codecs
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Takashi Iwai <tiwai@suse.de>

    commit de3df8a986b635082a1d94bae2c361d043c57106 upstream.

    Although one weird behavior about the input path (inconsistent D0/D3
    switch) on Cirrus CS420x codecs was fixed in the previous commit,
    there is still an issue on some Mac machines: the capture stream
    stalls when switching the ADCs on the fly. More badly, this keeps
    stuck until the next reboot.

    The dynamic ADC switching is already a bit fragile and assuming
    optimistically that the chip accepts the frequent power changes. On
    Cirrus codecs, this doesn't seem applicable.

    As a quick workaround, we pin down the ADCs to keep up in D0 when
    spec->dyn_adc_switch is set. In this way, the ADCs are kept up only
    for the system that were confirmed to be broken.

    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=116171
    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    sound/pci/hda/patch_cirrus.c | 14 ++++++++++++++
    1 file changed, 14 insertions(+)

    --- a/sound/pci/hda/patch_cirrus.c
    +++ b/sound/pci/hda/patch_cirrus.c
    @@ -361,6 +361,7 @@ static int cs_parse_auto_config(struct h
    {
    struct cs_spec *spec = codec->spec;
    int err;
    + int i;

    err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
    if (err < 0)
    @@ -370,6 +371,19 @@ static int cs_parse_auto_config(struct h
    if (err < 0)
    return err;

    + /* keep the ADCs powered up when it's dynamically switchable */
    + if (spec->gen.dyn_adc_switch) {
    + unsigned int done = 0;
    + for (i = 0; i < spec->gen.input_mux.num_items; i++) {
    + int idx = spec->gen.dyn_adc_idx[i];
    + if (done & (1 << idx))
    + continue;
    + snd_hda_gen_fix_pin_power(codec,
    + spec->gen.adc_nids[idx]);
    + done |= 1 << idx;
    + }
    + }
    +
    return 0;
    }


    \
     
     \ /
      Last update: 2016-05-03 04:21    [W:2.262 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site