[alsa-devel] Acer Ferrari 5000

Takashi Iwai tiwai at suse.de
Wed Mar 25 12:15:57 CET 2009


At Wed, 25 Mar 2009 01:47:16 -0700,
Russ Dill wrote:
> 
> The patch is causing breakage for me (no audio):
> 
> [37998.770034] HDA Intel 0000:00:14.2: PCI INT A disabled
> [38019.228311] HDA Intel 0000:00:14.2: PCI INT A -> GSI 16 (level,
> low) -> IRQ 16
> [38019.360994] input: HDA Digital PCBeep as
> /devices/pci0000:00/0000:00:14.2/input/input9
> [38019.389307] hda_codec: formats == 0 (nid=0x2, val=0xe0560, ovrd=1,
> streams=0xe0560)
> [38019.389318] hda_codec: cannot attach PCM stream 0 for codec #1
> [38019.389367] hda_codec: formats == 0 (nid=0x6, val=0x1e0560, ovrd=1,
> streams=0x1e0560)
> [38019.389373] hda_codec: cannot attach PCM stream 1 for codec #1
> [38019.389435] hda_codec: formats == 0 (nid=0x9, val=0x60160, ovrd=1,
> streams=0x60160)
> [38019.389440] hda_codec: cannot attach PCM stream 2 for codec #1

Looks like something wrong in my caching code, likely a wrong hash key
generation or so.  Will take a look after returning from the vacation.


thanks,

Takashi

> 
> 
> On Mon, Mar 23, 2009 at 4:27 PM, Takashi Iwai <tiwai at suse.de> wrote:
> > At Mon, 23 Mar 2009 16:12:38 -0700,
> > Russ Dill wrote:
> >>
> >> On Mon, Mar 23, 2009 at 3:55 PM, Takashi Iwai <tiwai at suse.de> wrote:
> >> > At Mon, 23 Mar 2009 15:48:19 -0700,
> >> > Russ Dill wrote:
> >> >>
> >> >> On Mon, Mar 23, 2009 at 3:45 PM, Takashi Iwai <tiwai at suse.de> wrote:
> >> >> > At Mon, 23 Mar 2009 15:28:57 -0700,
> >> >> > Russ Dill wrote:
> >> >> >>
> >> >> >> >> > BTW, I found why model=auto doesn't work well on your machine.
> >> >> >> >> > It's because (again) of BIOS.  It doesn't set the codec SSID properly
> >> >> >> >> > so the driver doesn't accept the HP auto-toggle and other features.
> >> >> >> >> >
> >> >> >> >> > So, in your case, using model=acer-aspire would be likely the best
> >> >> >> >> > choice (supposing it matches with most functionality).  If you have no
> >> >> >> >> > problem (at least regressions) with this model, I'll add the entry to
> >> >> >> >> > point to model=acer-aspire
> >> >> >> >>
> >> >> >> >> Add Acer Ferrar 5000 Quirk to Intel HDA driver
> >> >> >> >
> >> >> >> > Thanks, a similar fix was already merged now.
> >> >> >>
> >> >> >> It all works for a while, but eventually I'll get a "azx_get_response
> >> >> >> timeout, switching to polling mode: last cmd=0x10bb2001" and it no
> >> >> >> longer responds to headphone plug events without an unload/reload of
> >> >> >> the module.
> >> >> >
> >> >> > Did you try my test patch?
> >> >>
> >> >> It is with the patch:
> >> >>
> >> >> [16877.337044] hda_intel: azx_get_response timeout, switching to
> >> >> polling mode: last cmd=0x106f000a
> >> >> [16878.341056] hda_intel: azx_get_response timeout (ERROR): last cmd=0x106f000a
> >> >> [16879.345036] hda_intel: azx_get_response timeout (ERROR): last cmd=0x106f000a
> >> >> [16880.380016] hda_intel: azx_get_response timeout (ERROR): last cmd=0x106f000a
> >> >> [16881.384022] hda_intel: azx_get_response timeout (ERROR): last cmd=0x106f000a
> >> >
> >> > Interesting, this is again the same verb.
> >> > So, there seems something unstable regarding the digital PCM...
> >> >
> >> > And do you still have the problem with HP plugging?
> >> >
> >>
> >> There seems to be some confusion. All I'm doing right now is playing
> >> audio through the analog PCM. After a while, I get that dmesg output
> >> and HP plugging stops working.
> >
> > Yes, that's what I understood, too.  The driver still queries the PCM
> > parameter for the digital output widget because you turn on "IEC958
> > Default PCM" switch, thus the signal is still routed to the digital,
> > too.
> >
> >
> > The below is another test patch to reduce this problem (hopefully).
> > It basically caches the parameter values to avoid superfluous
> > queries.  It's against the very latest alsa-driver snapshot.
> > Apply it in addition to the previous test patch.
> >
> >
> > thanks,
> >
> > Takashi
> >
> > ---
> >
> > diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
> > index a4e5e59..1d88e2f 100644
> > --- a/sound/pci/hda/hda_codec.c
> > +++ b/sound/pci/hda/hda_codec.c
> > @@ -1053,6 +1053,8 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
> >  /* FIXME: more better hash key? */
> >  #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
> >  #define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
> > +#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
> > +#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
> >  #define INFO_AMP_CAPS  (1<<0)
> >  #define INFO_AMP_VOL(ch)       (1 << (1 + (ch)))
> >
> > @@ -1143,7 +1145,9 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
> >  }
> >  EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
> >
> > -u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
> > +static unsigned int
> > +query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key,
> > +               unsigned int (*func)(struct hda_codec *, hda_nid_t))
> >  {
> >        struct hda_amp_info *info;
> >
> > @@ -1151,11 +1155,22 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
> >        if (!info)
> >                return 0;
> >        if (!info->head.val) {
> > -               info->amp_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
> >                info->head.val |= INFO_AMP_CAPS;
> > +               info->amp_caps = func(codec, nid);
> >        }
> >        return info->amp_caps;
> >  }
> > +
> > +static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid)
> > +{
> > +       return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
> > +}
> > +
> > +u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
> > +{
> > +       return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),
> > +                              read_pin_cap);
> > +}
> >  EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
> >
> >  /*
> > @@ -2538,6 +2553,41 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
> >  }
> >  EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
> >
> > +static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid)
> > +{
> > +       unsigned int val = 0;
> > +       if (nid != codec->afg &&
> > +           (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
> > +               val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
> > +       if (!val || val == -1)
> > +               val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
> > +       if (!val || val == -1)
> > +               return 0;
> > +       return val;
> > +}
> > +
> > +static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
> > +{
> > +       return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid),
> > +                              get_pcm_param);
> > +}
> > +
> > +static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid)
> > +{
> > +       unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
> > +       if (!streams || streams == -1)
> > +               streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
> > +       if (!streams || streams == -1)
> > +               return 0;
> > +       return streams;
> > +}
> > +
> > +static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
> > +{
> > +       return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid),
> > +                              get_stream_param);
> > +}
> > +
> >  /**
> >  * snd_hda_query_supported_pcm - query the supported PCM rates and formats
> >  * @codec: the HDA codec
> > @@ -2556,15 +2606,8 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
> >  {
> >        unsigned int i, val, wcaps;
> >
> > -       val = 0;
> >        wcaps = get_wcaps(codec, nid);
> > -       if (nid != codec->afg && (wcaps & AC_WCAP_FORMAT_OVRD)) {
> > -               val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
> > -               if (val == -1)
> > -                       return -EIO;
> > -       }
> > -       if (!val)
> > -               val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
> > +       val = query_pcm_param(codec, nid);
> >
> >        if (ratesp) {
> >                u32 rates = 0;
> > @@ -2586,15 +2629,9 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
> >                u64 formats = 0;
> >                unsigned int streams, bps;
> >
> > -               streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
> > -               if (streams == -1)
> > +               streams = query_stream_param(codec, nid);
> > +               if (!streams)
> >                        return -EIO;
> > -               if (!streams) {
> > -                       streams = snd_hda_param_read(codec, codec->afg,
> > -                                                    AC_PAR_STREAM);
> > -                       if (streams == -1)
> > -                               return -EIO;
> > -               }
> >
> >                bps = 0;
> >                if (streams & AC_SUPFMT_PCM) {
> > @@ -2668,17 +2705,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
> >        int i;
> >        unsigned int val = 0, rate, stream;
> >
> > -       if (nid != codec->afg &&
> > -           (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) {
> > -               val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
> > -               if (val == -1)
> > -                       return 0;
> > -       }
> > -       if (!val) {
> > -               val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
> > -               if (val == -1)
> > -                       return 0;
> > -       }
> > +       val = query_pcm_param(codec, nid);
> > +       if (!val)
> > +               return 0;
> >
> >        rate = format & 0xff00;
> >        for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
> > @@ -2690,12 +2719,8 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
> >        if (i >= AC_PAR_PCM_RATE_BITS)
> >                return 0;
> >
> > -       stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
> > -       if (stream == -1)
> > -               return 0;
> > -       if (!stream && nid != codec->afg)
> > -               stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
> > -       if (!stream || stream == -1)
> > +       stream = query_stream_param(codec, nid);
> > +       if (!stream)
> >                return 0;
> >
> >        if (stream & AC_SUPFMT_PCM) {
> >
> 


More information about the Alsa-devel mailing list