Subject: Re: Multiple AC'97 codecs
To: Jared D. McNeill <>
From: Quentin Garnier <>
List: tech-kern
Date: 04/08/2005 18:36:32
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Apr 08, 2005 at 12:33:38PM -0300, Jared D. McNeill wrote:
> Currently our AC'97 code assumes that we're only talking to the first=20
> codec. The spec allows for multiple codecs, and they don't have to be in=
> any particular order. So far we've been safe with assuming that audio=20
> codecs are the first, but I don't want to build the assumption into the=
> low-level hardware drivers that modem codecs are always the second.

That's not correct.  AC'97 itself (from the driver POV) doesn't deal
with multiple codecs.  Our AC'97 code is currently fine.  auich(4) and
friends are the one making dubious assumptions.

What can happen is that a controller may be connected to several AC'97
codecs (which is indeed covered in the spec).  This is a controller-
dependent situation.  There can be 3 audio codecs, or two with a modem
codec, or even a single audio codec.

In the ICH case, which we probably know better, the controller doesn't
tell which codec(s) should be used by a given controller (either the
audio one or the modem one, which appear as two distinct PCI functions).
Therefore we need a way to probe the codecs instead of hard-wiring a
(albeit very common) configuration.

> What I'm proposing is adding the ability to pass a hint to ac97_attach,=
> AC97_CODEC_AUDIO or AC97_CODEC_MODEM, that on attach will search for a=20
> codec of a specific type to use. We can speed up the search for=20

No, ac97_attach will not search.  The controller driver will, and the
flag tells ac97_attach to return an error if the codec is not of the
specified type.

> known-codecs by marking them as AC97_CODEC_TYPE_AUDIO or=20
> AC97_CODEC_TYPE_MODEM in struct ac97_codecid. For unknown codecs, there=
> are other ways to determine whether a codec is a modem or audio codec=20
> (looking at ext_id and ext_mid for 2.x codecs; if we determine that we're=
> not dealing with a 2.x codec we can look at the AC97_CAPS_MODEMLINECODEC=
> bit in AC97_REG_RESET).

I think the safest is to do the probe in that order:
  o read ext_id.  If non-zero, we have a 2.x audio codec.  Done.
  o If ext_id is zero, read ext_mid.  If bit 0 is set, we have a 2.x
    modem codec.  Done.
  o we have a 1.x codec.  Bit 1 in the reset register tells if it is
    a modem codec (bit set) or an audio codec.

Of course, I agree that we can safely tag all the already known codecs
as audio codecs, and in case we stumble upon a, say, modem codec that
doesn't like ext_id to be read, or return garbage in it, we add it to
the list as a modem codec.

Once we have that, auich_attach will do something like the following in
the modem case (the modem codec is either 0 or 1, per ICH4

  sc->codecnum =3D 0;
  if ((error =3D ac97_attach(..., AC97_CODEC_TYPE_MODEM)) !=3D 0 &&
      error =3D=3D ENXIO) {
          sc->codecnum =3D 1;
          error =3D ac97_attach(..., AC97_CODEC_TYPE_MODEM);
  if (error) {
          /* printf a complaint */

Well, I guess it could start with codecnum =3D 1 to directly fall into
the most common situation :)

One last thing, it should be defined what an audio controller driver
should do with multiple audio codecs.  I must say I don't know how
such a system is supposed to work.

Quentin Garnier - -
"When I find the controls, I'll go where I like, I'll know where I want
to be, but maybe for now I'll stay right here on a silent sea."
KT Tunstall, Silent Sea, Eye to the Telescope, 2004.

Content-Type: application/pgp-signature
Content-Disposition: inline

Version: GnuPG v1.2.6 (NetBSD)