Subject: new sound driver

From: Johannes Berg <[email-masked]>
Date: Wed, 22 Mar 2006 10:35:19 +0100

Hi,

After considering the code a while I decided that snd-powermac needs to
be rewritten. Ok, kidding, I didn't need to look at the source for
long :)

So I started to rewrite snd-powermac as snd-aoa, which I currently keep
in a git tree at http://johannes.sipsolutions.net/snd-aoa.git/

I will need a bit of help, so this email is intended to solicit that,
and to get some input on what everyone else thinks about what I've been
doing in that code.

Let me start with a brief layout. To those I've talked about this
before: please read again -- I significantly changed what I'm doing.

Since Ben says that he wants to be able to handle really old stuff with
the new driver too, I first created a virtual 'soundbus'. This is in the
module 'soundbus', and doesn't yet have any functionality in itself but
providing the driver model bus object.
I then created an i2sbus module that grabs all i2s devices from the
macio bus, enumerates their children (i2s-a, i2s-b etc) and adds them to
the soundbus.
Obviously, we'll need to add more bus backends there.

Now enter snd-aoa: snd-aoa has a rather generic architecture where the
core just initialises plugin code for different ways to find sound codec
chips. Currently, only one way is implemented -- that is going off the
layout-id property. This part (snd-aoa-fabric-layout.c) is a soundbus
driver and attaches to all soundbus nodes that have a 'sound' child with
a 'layout-id' property that it knows about. The list is encoded in
snd-aoa-layouts.c.
Plan is to make the fabrics and the codecs into modules too, but this
isn't done at the moment. Shouldn't be too hard, and should probably be
done before writing any more fabrics or codecs.

Anyway, back to what happens. Now the fabric module detects a layout-id
that it can handle, so it then goes to instantiate the codecs. Right now
I only have an onyx codec there. It tries to attach to the i2c control
interface (using two methods, but for that refer to the code). Then the
codec creates the alsa mixer devices that it can handle, using some alsa
helper code (snd-aoa-alsa) that manages the alsa card object.

That's about it. It can mute/unmute and control the left/right volume,
so it might work if you use both this and snd-powermac...

I had planned to actually get sound output working last night, but that
didn't turn out since I ended up rewriting all the lower levels.

So let me just say what the immediate plan is:

Firstly, the soundbus objects need to be able to handle data
transmission. What I'm not too sure about is how the API should look
like. I'm thinking that since all objects there are actually sound
objects (well, there's the modem too, but it can get an alsa interface
too), the soundbus objects actually get to create the alsa pcm
interfaces, somehow helped by the codecs to select the valid rates and
formats. Or the codecs create the alsa pcm streams, but refer to
soundbus object functions for handling the actual data transfer. I'd
like to push as much of the interface into the soundbus object as
possible. At this point also the question of how to program the dbdma
engine best comes up. I really don't know, because I don't quite
understand the alsa pcm api.
In any case, I'm thinking of putting dbdma register stuff into the
soundbus module and adding dbdma data to struct soundbus_dev.

Actually, this isn't quite possible. On the newer machines where you
have two codecs on the same i2s bus, we need to have the layout fabric
create the one pcm stream and have it ask the codecs what it should
advertise. Then it needs to advertise the lowest common denominator of
the multiple codecs... (Or can alsa handle pcms that change their
supported rates/formats?) Then it refers to the soundbus functions for
actual data transmission.

Another thing that needs to be done is teach the layout-id fabric module
how to handle all the dozens of platform functions and publish those to
alsa that make sense to be set by the user (like line out select etc.).
Then also register the interrupt ones and handle them appropriately. The
codecs will need to be notified on changes/interrupts though, since in
some cases things need to be switched around there too. This is just a
matter of inventing the right way to find all of the functions...

Whee. I was going to write more but for one it is already long enough,
and I also forgot what I wanted to write :)

johannes