I'm writing a HAL for LPCs at present, I have a flat model of "logical" pins from 0 to N (where N varies depending on the chip being used), it has atomic access to any number of pins up to 32 by creating "pin groups", simple and adjustable debouncing on all pins with almost no CPU overhead, even "virtual pins" where the call is trapped and a handler can get data from a network or wherever etc.
The analogRead() func just accepts a pin # like all the other funcs, only you get an error if the pin is not connected to the ADC, but soon the ADC reading will happen in the background and analogRead() will just return the value from an array, that makes it independent of the hardware but of course you still need the low-level background task.
Above the "logical pin" level there is what I call the "application pin", which is really just a lookup mapping from one to the other.
I've not really looked at how this would all port to a different architecture because I was really just interested in having an Arduino-compatible environment on my LPCs, but it's pretty modular so it might.
Rob