* new sound driver
@ 2006-03-22 9:35 Johannes Berg
2006-03-22 21:50 ` Benjamin Herrenschmidt
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Johannes Berg @ 2006-03-22 9:35 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alastair Poole
[-- Attachment #1: Type: text/plain, Size: 4478 bytes --]
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
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: new sound driver
2006-03-22 9:35 new sound driver Johannes Berg
@ 2006-03-22 21:50 ` Benjamin Herrenschmidt
2006-03-23 17:13 ` Johannes Berg
2006-03-23 17:00 ` Johannes Berg
2006-03-24 11:37 ` Johannes Berg
2 siblings, 1 reply; 6+ messages in thread
From: Benjamin Herrenschmidt @ 2006-03-22 21:50 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev, Alastair Poole
On Wed, 2006-03-22 at 10:35 +0100, Johannes Berg wrote:
> 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.
that would make soundbus totally pmac specific, in which case you should
call it aoa-bus or something like that.
Regarding your previous question well... I think the soundbus can create
the pcm streams. Alsa has 2 levels: PCM objects and PCM substreams. We
need the former. Substreams are used when the harware has several
streams that are hw mixed to the same mixers which isn't the case with
apple layout. When we have multiple i2s busses, they are really
independant with separate codecs, frame rates & formats etc.. thus
separate PCM objects.
I think the sound bus should create the PCMs. Now I don't remember from
Alsa API but do we need to know the available rates in advance ? In that
case, we may want to have the bitmask provided by the fabric (from the
layout array for example).
I'm also not sure how Alsa handle changes there. For example, if you
plug a digital input, the entire bus where this input is has to be
clocked from that, thus limiting dynamically what rates/formats are
available. I'm not sure Alsa API can cope with that yet.
> 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.
The problem is that codec objects have to be created asynchronously
since they use asynchronous i2c discovery. Unless you instanciate them
all but simply mark them "offline" and then mark them "online" later
when the hardware actually shows up. That is fine except for .. topaz
where you need to access the hw to know the chip type, thus you can't
really know everything you need early enough (or maybe you can ...)
> 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 :)
Just sleep on it for now :) We definitely need a "core" module that
handles all of the gpio mess. ..
Ben.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: new sound driver
2006-03-22 9:35 new sound driver Johannes Berg
2006-03-22 21:50 ` Benjamin Herrenschmidt
@ 2006-03-23 17:00 ` Johannes Berg
2006-03-24 11:37 ` Johannes Berg
2 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2006-03-23 17:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Alastair Poole
[-- Attachment #1: Type: text/plain, Size: 2454 bytes --]
Obviously, I'm still collecting information. For future reference and
archiving, here's the contents of a file I just added to my code
describing how apple derives i2s clocks. Well, as far as I can see from
their code.
Short description of the i2s clock derivation system Apple uses.
The i2s chip Apple uses has three available clocks: 18432000, 45158400 and
49152000 Hz. These are used to drive the codec's system clock as well as the
i2s transfer bus.
The clocks for these are derived as follows:
First, you need to know the sampling frequency you want to use, and the
system clock the codec requires. The pcm3052 (onyx) for example requires a
system clock of 256*sampling frequency.
Thus, you divide the clock source speed by the sampling frequency and then
the factor the codec chip requires. This is the 'mclk divisor'.
Now you can derive the system clock from the clock source by taking only
every 'mclk divisor' transition of the clock, and thus you get a system
clock of the required speed.
Next, you need to know the i2s bus speed wrt. the sampling frequency. For
Sony and I2S 32x serial formats, this is 32*sampling frequency, for the I2S
64x format it is 64*sampling frequency. Since the i2s wire clock is derived
from the system clock we have already derived from the clock source, you
need to put as 'sclk divisor' the factor between the system clock of the
codec and the bus clock, for example 256/32 (=8) if the codec is driven in
Sony mode.
For the 'sclk divisor' you have to take care that it is an even number or 1
or 3, other values cannot be represented to the i2s chip (see logic in
i2sbus.h).
With a codec system clock (MClk) of 256*sampling frequency, you can have the
following frequencies (in the range from 8KHz to 96KHz) depending on the
clock source you use:
18432000: 9000 12000 14400 18000 24000 36000 72000
45158400: 8820 9800 11025 12600 14700 17640 22050 29400 35280 44100 58800 88200
49152000: 8000 9600 12000 16000 19200 24000 32000 38400 48000 64000 96000
(this is exactly what we can do with the onyx chip)
to create this table use calc (debian package apcalc):
min=8000
max=96000
clock=49152000
factor=256
for (f=min;f<=max;f++) {
if ((clock%f==0) && ((clock/f)%factor == 0)) {
div = clock/f/factor ;
n = ceil(div/2-1) ;
if ((div==1||div==3||div==5||div==14||(2*(n+1)==div && n<0x1f))
&& (1))
print f,
}
}
print ''
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: new sound driver
2006-03-22 21:50 ` Benjamin Herrenschmidt
@ 2006-03-23 17:13 ` Johannes Berg
2006-03-23 21:09 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 6+ messages in thread
From: Johannes Berg @ 2006-03-23 17:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Alastair Poole
[-- Attachment #1: Type: text/plain, Size: 2781 bytes --]
On Thu, 2006-03-23 at 08:50 +1100, Benjamin Herrenschmidt wrote:
> that would make soundbus totally pmac specific, in which case you should
> call it aoa-bus or something like that.
Yeah, well, I just did it differently now with the dbdma stuff done by
the i2sbus objects.
> Regarding your previous question well... I think the soundbus can create
> the pcm streams. Alsa has 2 levels: PCM objects and PCM substreams. We
> need the former. Substreams are used when the harware has several
> streams that are hw mixed to the same mixers which isn't the case with
> apple layout. When we have multiple i2s busses, they are really
> independant with separate codecs, frame rates & formats etc.. thus
> separate PCM objects.
>
> I think the sound bus should create the PCMs. Now I don't remember from
> Alsa API but do we need to know the available rates in advance ? In that
> case, we may want to have the bitmask provided by the fabric (from the
> layout array for example).
Right. I was still confused on the notion of PCM streams vs. objects.
Got that sorted out, and yes, it is creating pcm objects.
> I'm also not sure how Alsa handle changes there. For example, if you
> plug a digital input, the entire bus where this input is has to be
> clocked from that, thus limiting dynamically what rates/formats are
> available. I'm not sure Alsa API can cope with that yet.
Well, if we're unlucky the Alsa API must just return -EINVAL to users
trying to use other bitrates, if we're lucky then it copes better ;)
> > 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.
>
> The problem is that codec objects have to be created asynchronously
> since they use asynchronous i2c discovery. Unless you instanciate them
> all but simply mark them "offline" and then mark them "online" later
> when the hardware actually shows up. That is fine except for .. topaz
> where you need to access the hw to know the chip type, thus you can't
> really know everything you need early enough (or maybe you can ...)
What I'm currently thinking of is creating one PCM per codec, and then
if you can't use them at the same time just forbid access to it.
> Just sleep on it for now :) We definitely need a "core" module that
> handles all of the gpio mess. ..
Yeah. Haven't even opened that can of worms yet...
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: new sound driver
2006-03-23 17:13 ` Johannes Berg
@ 2006-03-23 21:09 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 6+ messages in thread
From: Benjamin Herrenschmidt @ 2006-03-23 21:09 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev, Alastair Poole
> What I'm currently thinking of is creating one PCM per codec, and then
> if you can't use them at the same time just forbid access to it.
No, it should really be one PCM per bus... I don't see why you would
prevent somebody from outputing on both digital and analog outputs at
the same time for example (the same data of course). One PCM = one
stream = one bus carrying the samples. All codecs on that bus whould be
set to the same settings of course. If one can't but the other can, just
mute the one that can't I suppose...
Also, Alsa does have some means of asynchronous notifyication of a state
change on a control (and calls you back later with some locking) though
I'm not too familiar with the details. You should ask on the list once
you have the basic dbdma stuff there :)
> > Just sleep on it for now :) We definitely need a "core" module that
> > handles all of the gpio mess. ..
>
> Yeah. Haven't even opened that can of worms yet...
>
> johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: new sound driver
2006-03-22 9:35 new sound driver Johannes Berg
2006-03-22 21:50 ` Benjamin Herrenschmidt
2006-03-23 17:00 ` Johannes Berg
@ 2006-03-24 11:37 ` Johannes Berg
2 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2006-03-24 11:37 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 428 bytes --]
On Wed, 2006-03-22 at 10:35 +0100, Johannes Berg wrote:
> 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/
It's a bit hacky (but hopefully those hacks can be removed rather
easily) but it works now for the onyx based machines (powermac8,1, quad
powermac, last 15" powerbook and probably more if you add the layout id)
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2006-03-24 11:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-22 9:35 new sound driver Johannes Berg
2006-03-22 21:50 ` Benjamin Herrenschmidt
2006-03-23 17:13 ` Johannes Berg
2006-03-23 21:09 ` Benjamin Herrenschmidt
2006-03-23 17:00 ` Johannes Berg
2006-03-24 11:37 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).