Subject: Re: macppc audio (was Re: autoconf(9) tree in an odd hardware arrangement )
To: Marco Trillo <>
From: Michael Lorenz <>
List: tech-kern
Date: 12/06/2007 19:01:26
Hash: SHA1


On Dec 6, 2007, at 17:45, Marco Trillo wrote:

> On 12/6/07, Michael Lorenz <> 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.

> 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?

>>> 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.

> 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:
>  #define AWACS_MUTE_SPEAKER	0x00000080
>  #define AWACS_MUTE_HEADPHONE	0x00000200
>  #define AWACS_PARALLEL_OUTPUT	0x00000c00
> +#define AWACS_PROG_OUTPUT0	0x00000400
> +#define AWACS_PROG_OUTPUT1	0x00000800
> +	
> +	if (sound_node != 0) {
> +		int device_id;
> +		
> +		/*
> +		 * Configure programmable outputs
> +		 */
> +		if (OF_getprop(sound_node, "device-id", &device_id,
> +		               sizeof(device_id)) == sizeof(device_id)) {
> +			printf("%s: device id = %d\n", device_xname(self),
> +			       device_id);
> +
> +			if (device_id == 5)
> +				sc->sc_codecctl1 |= AWACS_PROG_OUTPUT0;
> +
> +		}
> +	}
> +
>  	awacs_write_codec(sc, sc->sc_codecctl0);
>  	awacs_write_codec(sc, sc->sc_codecctl1);
>  	awacs_write_codec(sc, sc->sc_codecctl2);
> 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...

>>> 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
>>> Currently it only supports output devices, but it should be easy to
>>> support input devices too.
>> Very nice :)
>> I'm not sure if we should automatically switch the input channel when
>> something's plugged into line in or microphone - some models have CD
>> input and a built-in microphone.
> Hmm.. this could be done by not registering callbacks for these  
> devices.
> I have to look at the sound objects to see if there is a difference  
> between
> an external mic port and an internal mic (like the difference  
> between 'ispk'
> and 'espk').

If the sound-objects stuff is just translated to properties we could  
take care of all the special cases outside of codec drivers ( like  
adding the right properties for models that don't have sound-objects )

>>>>> 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?

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?

> 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....    
probably too generic to be useful.

have fun
Version: GnuPG v1.4.7 (Darwin)