I've got a set of links on my desktop and thought I should get them written down.
First some resources on Programming kernel modules:
The Broadcom peripherals manual, for what it's worth:
Actually applied in:
http://www.pieter-jan.com/node/15 Uses the low level ports but is still running only one pin of a port at a time using bit shifts. We're going to ignore pretty much ever but shift and rotate and just write a whole 8 bits at a time.
http://xinu.mscs.mu.edu/BCM2835_System_Timer I swear I had a better link, but I can't find it now. Anyway here's some memory addresses for the system's 1mhz timer. To get a 22050hz sampling we'll be putting 45 in C3 and a pointer to our own interrupt routine in the interrupt vector location for IRQ3. This is how it would be done low level: http://xinu.mscs.mu.edu/BCM2835_Interrupt_Controller but it looks like the Kernel may have a system for it anyway: http://www.oreilly.com/openbook/linuxdrive3/book/ch10.pdf a request_irq function. It looks like it's largely function pointer based, kinda like pthread_create().
Here's some charts of various Raspberry Pi GPIO pins named by their chip pins. The order seems to be essentially random, and we might need to shift out byte a few bits if we want to keep a serial console but it looks like there's a pretty continuous block between GPIO2 and GPIO27 scattered around that connector http://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/
Here's a header someone wrote we can canibalize for ideas: https://github.com/thenaterhood/pi-crust
A nice tool we can use to play the audio (may require root in our case) Sound Exchange AKA sox: http://sox.sourceforge.net/
And I've run out of steam for a bit so I'll leave it there.
Refresh 22.050 khz
input 8-bit unsigned integers
written to character device /dev/analog0
last byte written is held until user write more bytes (pre-filtered output is fixed DC)