Subject: Re: macppc audio (was Re: autoconf(9) tree in an odd hardware arrangement )
To: Michael Lorenz <macallan@netbsd.org>
From: Marco Trillo <marcotrillo@gmail.com>
List: tech-kern
Date: 12/07/2007 15:06:48
Hi,

On 12/7/07, Michael Lorenz <macallan@netbsd.org> wrote:
> On Dec 6, 2007, at 17:45, Marco Trillo wrote:
>
> > On 12/6/07, Michael Lorenz <macallan@netbsd.org> wrote:
> >> On Dec 6, 2007, at 11:10, Marco Trillo wrote:
> >>> I have a first version of the parser which uses the sound-objects
> >>> property to get a list of available objects and detect the active
> >>> devices. The parser itself is general and should work with any
> >>> device,
> >>> but the problem is that the driver (awacs or i2s, or even the codec)
> >>> has to have support for the devices to mute/unmute them (or
> >>> configure
> >>> their volumes).
> >>> So I've made it use a callback, so the driver registers callbacks
> >>> only
> >>> for the devices it cares about.
> >>
> >> Why not put them into device properties? So we just call the parser
> >> and then whoever needs information can look them up without caring
> >> where it came from. That way we can also provide information for
> >> models without sound-objects property.
> >
> > The problem is that the sound-objects parser uses these callbacks
> > to inform
> > the driver that a device has changed its state (for example when
> > updating the
> > state as a result of a port change interrupt). So the driver
> > registers a callback
> > for each device it cares about. This callback is called when the
> > device changes
> > its state.
>
> So, it registers an interrupt handler? I don't know, my gut feeling
> is that the parser should just parse the property, nothing else. But
> that's just a gut feeling.

It registers an interrupt handler if the property contains references
to extint-gpio detect nodes. In the case of the screamer, the awacs
driver calls the aoa_cintr() handler from its port change interrupt
handler (these type of detects have a 'model' attribute with the value
'InSenseBitsDetect' which differences them of the gpio detects which
have the value 'GPIODetect' or 'GenericGPIODetect').

Since the property contains all the necessary masks/match values, the
intention was for the 'aoa' module to take care of all of this.

By the way, my original plan of making the codec drivers
machine-independent files in sys/dev/i2c/ is starting to being botched
by the 'daca' setups requiring some configuration for the output
device selection: instead of using gpio mutes like the other codecs,
they use a control in the codec to switch the polarity of the output
depending on what device is being used, the internal mono speaker or
headphones.

But I think this can be solved by just providing a method in the
'codec' interface to select output. The 'daca' driver will implement
this method by switching the control to the correct value. Other
codecs will not need to implement this method.

> > Using properties would work to see the list of available devices,
> > but will not allow
> > the parser to take care of the device state changes (but I may be
> > missing something).
>
> Shouldn't individual drivers take care of that?

Maybe instead of making the 'aoa' module take care of the interrupt,
the driver can register the handler based on the data from the
property, read the sense bits and then pass the sense bits to an aoa
function.

This way may be cleaner especially for the awacs driver.

> >>> At the moment I've tested it with the awacs driver in a screamer-
> >>> based
> >>> G4 (which is also a plain screamer with only an internal speaker
> >>> and a
> >>> headphones port). The good thing about the sound-objects property is
> >>> that it eliminates the need to hardcode different GPIO wirings for
> >>> different machines.
> >>
> >> Neither the PB3400c nor the beige G3 have sound-objects but both need
> >> special wiring for their gpios ( it's reversed on the powerbook and
> >> uses a different pin on the G3 as you probably saw in awacs.c )
> >
> > Yeah, I forgot about these especial cases. Well, at least we don't
> > need more
> > special cases for some G4s or some other screamer-based models.
>
> I wouldn't bet on it. Actually I'm pretty sure some more *Books will
> need special attention.

Hmm... with Apple's inconsistency it will not be a surprise. But
looking at the Darwin's screamer driver the only special case I can
see is the 'init operation' I commented (the programmable outputs).
This apparently only affects G4's.
The other stuff (speaker, headphones, volumes, etc.) is handled in the
same way by our awacs driver and by the Darwin driver.

Hmm... I see that Darwin has three awacs drivers:
'AppleScreamerAudio', 'AppleOWScreamerAudio' and 'AppleBurgundyAudio'.

The AppleScreamerAudio driver uses the sound-objects property. All
that is supported by this driver should be supported by our awacs
driver with the parser, at least for a basic speaker and headphones
setup.

The AppleOWScreamerAudio seems to be for old-world machines, and the
AppleBurgundyAudio seems to be for machines using the 'burgundy'
variation of the awacs.

I don't have any machines that have this 'burgundy'. Apparently it's
used on B&W G3s, non-AGP G4s and some AVs. I don't know how well our
awacs driver handles these machines. However I found a 'burgundy'
driver for NetBSD in the 'cvsweb.ki.nu' CVS repository that seems to
be written in 2005 or so.

> > By the way, are you able to use the headphones port in the G4 with the
> > awacs?
>
> Yes. I remember there was a logic botch in awacs.c but probably that
> wasn't related to my G4.
>
> > In my screamer G4 it didn't work and I had to patch the driver like
> > this:
> >
> > [patch]
> >
> > I got the hint about this 'programmable output' looking at the Darwin
> > driver. This info is also available in the sound-objects property
> > as a 'init' line,
> > instead of using the device-id for matching.
>
> My G4 doesn't need that. I wonder what those bits do on the beige G3...

The machines that need this have a line at the beginning of the
'sound-objects' property:

init operation 2 param 0x00000001

However, it seems that these machines are only G4s whose device ID is
5, so I used the device id instead.

It should do no harm on other machines: either they have different
device IDs or they don't have a device-id property (or a sound node)
at all.


> >>> awacs0: object[1]: direction:output, type:<hdpn>, mask:0x2, match:
> >>> 0x2,
> >>> enabled:false
> >>> awacs0: detect[0]: type:sense, mask:0x2, match:0x2
> >>> awacs0: detect[1]: type:sense, mask:0x4, match:0x4
> >>> awacs0: detect[2]: type:sense, mask:0x1, match:0x0
> >>> awacs0: interrupting at (cirq, oirq, iirq) = (24, 9, 10)
> >>> awacs0: object[0]: direction:output, type:<ispk>, mask:0x2, match:
> >>> 0x0,
> >>> enabled:false
> >>> awacs0: object[1]: direction:output, type:<hdpn>, mask:0x2, match:
> >>> 0x2,
> >>> enabled:true
> >>> I booted it with the headphones plugged, so it prints 'enabled:true'
> >>> on the 'hdpn' device. If I unplug the headphones it enables the
> >>> speaker:
> >>>
> >>> awacs0: object[0]: direction:output, type:<ispk>, mask:0x2, match:
> >>> 0x0,
> >>> enabled:true
> >>> awacs0: object[1]: direction:output, type:<hdpn>, mask:0x2, match:
> >>> 0x2,
> >>> enabled:false
> >>>
> >>>>> Another problem I've found with such models is that neither the
> >>>>> device
> >>>>> tree nor the `sound-objects' proprety mention any interrupt for
> >>>>> detecting the port change. I looked at the Darwin driver but it's
> >>>>> weird since it uses polling... however it does mention in a
> >>>>> comment
> >>>>> that it should use an interrupt, so I suspect that it does
> >>>>> generate an
> >>>>> interrupt.
> >>>>> What do you think?
> >>>>
> >>>> Hmm, maybe it's always the same interrupt so we can guess ( and
> >>>> print
> >>>> a warning ) if there's no other information available?
> >>>
> >>> In models which have 'gpio' nodes, the sound-objects references the
> >>> node via its name (extint-gpioXX) and the node contains an
> >>> 'interrupts' property.
> >>>
> >>> However, in this case there are no gpio nodes. Oddly enough, the
> >>> sound-objects still references the gpio via a name, which is
> >>> 'extint-gpio12' (but it also provides the address, which other
> >>> machines with gpio nodes don't do).
> >>>
> >>> Other machines also use different extint-gpios (for example my
> >>> snapper-equipped eMac uses 'extint-gpio15' for output detection and
> >>> 'extint-gpio4' for input detection).
> >>
> >> What I meant is - is it always the same IRQ line? Or at least on a
> >> majority of devices so we can guess if there's no other information
> >> available?
> >
> > Looking at other machines with gpio nodes, for example the G4
> > Digital Audio
> > (PowerMac3,4):
> >  extint-gpio15 -> irq 61
> >  extint-gpio16 -> irq 62
> >  extint-gpio1 -> irq 47
> > Looking at my eMac (PowerMac6,4), it has the same as the
> > PowerMac3,4 plus
> >  extint-gpio4 -> irq 50
> >  extint-gpio1 -> irq 47
> >
> > So it looks like the irq for extint-gpioX is 46 + X. Since in these
> > iBooks the
> > detect gpio is reported as 'extint-gpio12', my guess would be 46 +
> > 12 = 58.
> >
> > But this may be a coincidence between the 3,4 and the 6,4.
>
> On my iBook G4 ( PowerBook6,3 ) it's
> extint-gpio1 -> irq 47 ( that's the PMU interrupt )
> extint-gpio15 -> irq 61 ( that's headphone detect )
>
> So, from these exhaustive data we can guess 61?

All machines except these first without-gpio-nodes variants seem to be
using extint-gpio15 for headphone detection, with irq 61.

However these variants use extint-gpio12 and not 15 for headphone
detection, so irq 58 seems to be the matching irq.

> The G4 Digital Audio has a Tumbler, doesn't it? Mine's a PowerMac3,3
> with a plain Screamer with in- and outputs wired as expected. I guess
> Tumbler uses different outputs for the digital stuff?

It seems to use extint-gpio15 for headphones and gpio16 is labeled as
'DallasDriver'. My eMac doesn't have this Dallas stuff and so it
doesn't use gpio16. It only has speakers plus headphone port.

My G4 with screamer, which requires the 'programmable outputs' patch,
is a PowerMac3,1 not a PowerMac3,4.

> > I can try hardcoding irq 58 for daca-based machines... and if the
> > testing succeeds, then fine.
>
> Hmm, the headphone detect gpio probably doesn't have much to do with
> the codec, more with the mac-io model? My iBook has:
> model                   4141504c 2c4b6579 6c617267 6f00....
> "AAPL,Keylargo"
> probably too generic to be useful.

Yeah... the tress I know that have this 'extint-gpio12' stuff are the
PowerBook2,1 and the PowerBook2,2 daca-based iBook G3's.
But of course the parser should handle this automatically, so no
special cases are required -- except for this 'irq 58' thing.

I don't know what other machines use 'daca'. Maybe other newer iBook
G3's ... all iBook G4s seem to have snapper, earlier PowerBooks have
screamer and later snapper, PowerMacs have screamer, tumbler and
perhaps snapper.

The other i2s codecs are 'toonie', 'onyx' and 'topaz'. The toonie is
only used on the Mac Mini as far as I know and it's just a DAC with no
i2c interface, so it should just work with the i2s driver and the
software volume filter that's already written.
The 'onyx' and 'topaz' codecs are used in newer G5-based models. There
also seem to be machines with two codecs, for example PowerMac G5s
which have a TAS3004 for analog output and a 'topaz' for digital
output.

Greetings,
Marco.