Source files
============

Source files are separated to:

/include	all header files which are included from more sources
/kernel		kernel (abstract layers)
/lowlevel	generic lowlevel code for chip(set)s
/cards		upper level for soundcards + specific lowlevel code
/detect		detection layer (to make installation easy)

Devices
=======

Devices should use abstract code from sound kernel, but it should use
own code and register minors separetely (with snd_minor_register and
snd_minor_unregister functions). This method totaly bypass all abstract
code, so code for these soundcards must handle all things.

Memory allocation
=================

void *snd_malloc( unsigned long size )
void snd_free( void *ptr, unsigned long size )

Routines uses it's own memory allocation algoritm. It should be removed
in future and replaced with kmalloc and kfree calls, but I need trace
all allocation problems to make code clean...

Note: ALSA driver heavy uses dynamic allocation for most things.

For debugging you should use command './configure --with-debug=full' for
configuration. This enables trace of allocated memory with above functions
and this makes debugging a little bit easier.

Basic coding
============

All things are made as object and are referenced in this way. I don't preferer
pass index to some array of structures or something this. Pointer to object
which contains data should be passed rather.

All main structures should have snd_xxxx_new, snd_xxxx_free, snd_xxxx_register,
snd_xxxx_unregister functions.

snd_card_t
  - basic structure which contains info about soundcard, index and
    resource tracking variables

include/driver.h contains all things related to this structure

snd_pcm_t
  - basic structure for PCM device
snd_pcm_channel_t
  - structure for PCM channel (direction)
struct snd_stru_pcm_hardware
  - structure which must be filled by lowlevel code

include/pcm.h contains all things related to these structures

snd_kmixer_t
  - basic structure for MIXER device
snd_kmixer_channel_t
  - basic structure for MIXER channel
struct snd_stru_mixer_channel_hw
  - structure which must be filled by lowlevel code

include/mixer.h contains all things related to these structures

Upper level (/cards)
====================

Code for soundcards should contains these things:

1) Support for more same soundcards (up to SND_CARDS)...
   - it isn't really possible due to HW limitations
2) Autodetection/autoconfiguration feature (if it's possible)...
   - if lowlevel code is specific for soundcard type - it should be here, too..
3) Initialization code for soundcard
   - snd_card_new
   - snd_card_free (frees all hardware resources)
4) Allocate/free hardware resources for soundcard
   - snd_register_ioport
   - snd_unregister_ioports (frees all ioports)
   - snd_register_interrupt
   - snd_unregister_interrupts (frees all interrupts)
   - snd_register_dma_channel
   - snd_unregister_dma_channels (frees all DMA channels)
5) Initialize other layers (PCMs, Mixers etc.)
   - snd_pcm_new
   - snd_pcm_free
   - snd_pcm_register
   - snd_pcm_unregister (calls snd_pcm_free)
   - snd_mixer_new
   - snd_mixer_free
   - snd_mixer_register
   - snd_mixer_unregister (calls snd_mixer_free)
6) Register soundcard
   - snd_card_register
   - snd_card_unregister (doesn't calls snd_card_free)

Note: Due to module dependency you should separate code for soundcards
      from same manufacture which have slightly different hardware.
      Example: GUS Extreme have ESS ES-1688 chip. This chip isn't in GUS
      Classic. For GUS Classic isn't generic code in snd-es1688.o module
      needed, so there is two upper level modules (snd-gusextreme.o and
      snd-gusclassic.o).

Private data/values:
====================

Some structures have pointers on private data and values. These variables
aren't used with abstract layers and use is intended for low-level code. 

snd_card_t -> private_data
snd_card_t -> private_free (called from snd_card_free if not NULL)

struct snd_stru_pcm_hardware -> private_data
struct snd_stru_pcm_hardware -> private_free (called from snd_pcm_free if not NULL)
snd_pcm_t -> private_data
snd_pcm_t -> private_free (called from snd_pcm_free if not NULL)

struct snd_stru_mixer_channel_hw -> private_value
snd_kmixer_channel_t -> private_data
snd_kmixer_channel_t -> private_free (called from snd_mixer_free if not NULL)
snd_kmixer_t -> private_value
snd_kmixer_t -> private_data
snd_kmixer_t -> private_free (called from snd_mixer_free if not NULL)

CLI/STI & spin locking
======================

Good code shouldn't contains snd_cli()/snd_sti() calls. Use rather spin locks
snd_spin_lock()/snd_spin_unlock() for locking some code. This code is much
better for SMP machines.

Note: Debugging code is available and it should be enabled in sndspinlock.h.

Examples
========

You should look to code for GUS soundcards how can be things done...

Note: Code should be compiled cleanly under 2.0.X kernels and under
      latest 2.1.X kernels...
