Some of Toonces' last few posts over in the AppleHDA progress thread got me thinking of a lot of things. As he said, "I'm no programmer," to which I replied, "Neither am I, I'm a reverse engineer." Of course. So if I call myself a reverse engineer, why am I not looking at the source more, I thought.
So I went back to the decompilation I made of the 10.5.5 AppleHDA.kext. First of all, all of the mystery plist settings are actually there and it became evident that we could simply use a disassembly to figure out what MuteGPIO and all that other stuff actually means on Apple's terms.
But before I even did that, I started poking around even deeper into the code. Why does it seem that Apple isn't switching on the EAPD for us on the ALC269? Does the driver not know to do that? Of course not, there's actually a routine for it in the code as well. So why isn't it being called for the nodes that need it?
The answer is in another of Toonces' contentions that the AppleHDA driver is becoming more specialized, as opposed to my theory that they simply should become universal as more and more chips are supported. Sure, in the AppleHDA binary there is reference to a section of code called AppleHDAGenericCodec, but that's because thanks to the Intel HD Audio Spec, the interface to codec itself is generic, but what Apple does with it is totally specific and driver contained.
This is my revised interpretation to what is going on in the code. Please remember that I am not a programmer, have no internal knowledge of what Apple is really doing, and that this is all speculation on my part. Apple has programmed a reusable code block, the GenericCodec, through which it communicates with the Intel HD Audio Codec. On top of that, there are specialized routines, one for each codec chip used, to initiate vendor specific codes for any given codec chip (Realtek, Stac, etc). As far as we are concerned with the Realtek codecs, these would be the 885 and the 262. After this, Apple uses the plist to make implementation or model specific changes to account for how each of their hardware systems actually uses the codec chip and the different modes it can be placed in.
Assuming this is a valid interpretation, why then has the driver been successfully hacked to accommodate other codec chips? I think the answer is luck. Apple didn't intend it, it just so happens that Realtek made it so that most of their chips respond the same way to the same commands. So by hacking AppleHDA.kext and tinkering with the plists, we get the driver to send ALC885 commands to an ALC880 or an 882 or so on, and the 880 just responds because it understands.
So what happens when Realtek puts out a different chip that does not conform in the same way? Or the vendor does something different with it such that you need to issue it other commands before it will work? We know the 269 is different enough that the ALSA driver needed patches to its source code just to work with it. I think that's where we are today with the more advanced AppleHDA.kext. Extra verbs need to be sent, but unlike in Windows, where the UAA driver actually asks the chip, hey what do you need, and then sends it so that it will work, the AppleHDA driver never bothers. It says, hey, if you're not ready after I'm done initializing, well that's your problem. From that point, I think plist manipulation can only bring you so far.
I doubt this is by design; I mean, I don't think Apple is deliberately trying to foil usage of their driver on other hardware. I'm not a fanboy but it just doesn't make sense for a company that produces the only commercial desktop operating system that doesn't require any Activation mess or CD-Key to actively invest in coding countermeasures within the operating system itself. Rather, I think it's just that it would add an extra layer of complexity to their driver code to make UAA style queries, and so they stick with the more stable approach of hard-coding the needed routines. Regardless of Apple's actual intent, we're still no closer to a true driver solution with what they've given us.
Which brings me to my new proposal. The exciting discoveries of verb manipulation show much promise. Of course, we still need to figure out why verb injection doesn't seem to work in the newer AppleHDA kexts while it does in the older kexts and Azalia. In the meantime, the whole mess of needing Reggie and writing scripts and third party sleep routine programs works but it isn't pretty. What we need is a kext.
I propose to code a kext and call it VerbSyringe. What it would do is load up, identify the audio kext loaded, take the correct memory address from the audio kext/IORegistry, and then, based on a documented plist format that we control, injects needed verbs depending on the audio chipset. This way, such a kext could be coded, and it wouldn't matter whether you were using the Azalia driver or the AppleHDA driver — it would be independent, like HDAEnabler is now. Being a kext, we could also stick a routine in there to be included in power management, so that verbs could be sent automatically on wake and reboot, etc. The best part is that if coded properly, we could use a plist to support more than just the ALC269 and basically be future-proof until the ALC300 comes out ;).
A truly useful feature would be to also incorporate HDAEnabler's job, and also make in-memory patches to the HDA Driver so that even the newer ones act like the older Azalia driver with basic, generic routines. If this could be accomplished, then you wouldn't even need to patch AppleHDA kext or its plists, you would only need to install VerbSyringe.
Now, I've never coded a kext before, but I've started reading up and it seems well documented enough, and a kext that simply modifies registers doesn't have to be very complex. What it truly would do is free the end user from having to use scripts or have Reggie installed on their computer or have to enter super user mode for any reason.
Thoughts? Do you think this would be a viable project with practical application? Any pitfalls that I have overlooked? How should we go about doing it? and lastly, volunteers anyone? :)