Support Functions for the Cirrus Logic ep93xx Internal DMA controller.
==============================================================================

State diagram

States:
Uninitialized (!pause & !xfer_enable)
Stopped (pause & !xfer_enable)
Transferring (!pause & xfer_enable)
Stopped by starvation (pause & xfer_enable)

                                    _______________
               request ----------> |               | <------- free -----------                          
                                   | Uninitialized |                        /\
                                   |_______________|                        ||
                                                                            ||
                                        ||                                  ||
                                  init  ||   ------------------------------>||
                                        ||   /\                             ||
                                        \/   ||                             ||
                                      _________                             ||
  ||<-- start && new_buffers <= 1 -- |         | <----- flush <---------    ||   
  ||                                 | Stopped |                      /\    ||   
  ||         ---------> pause------> |_________| -------------------->||    ||   
  ||         /\                                                             ||   
  ||         ||                        ||                                   ||   
  ||         ||                        || start && new_buffers > 1          ||   
  ||         ||                        ||                                   ||   
  ||         ||                        \/                                   ||   
  ||         ||                   ______________                            ||   
  ||         ||                  |              | ------------------------->||
  ||         ||<---------------- | Transferring | ------------------->||    ||
  ||         ||                  |______________|                     ||    ||
  ||         ||                                                       ||    ||
  ||         ||                             ||                        ||    ||
  ||         ||                             || new_buffers = 0        ||    ||
  ||         ||                       /\    ||                        ||    ||
  ||         ||                       ||    \/                        ||    ||
  ||         ||       new_buffers > 1 ||                              ||    ||
  ||         ||                       ||                              ||    ||
  ||         ||                 _______________________               ||    ||
  ||         ||<-------------- |                       |              ||    ||
  \/                           | Stopped by starvation | ------------>||    ||
  ---------------------------> |_______________________|              ||    ||
                                                                      ||    ||
                                ||    /\                              ||    ||
                                ||    ||                              ||    ||
                                ||    ||<-------- flush <---------------    ||
                                ||                                          ||
                                ------------------------------------------->||


------------------------------------------------------------------------------
EP93XX DMA API Functions
------------------------------------------------------------------------------

    int ep93xx_dma_request(int * handle, const char * device_id,
                           ep93xx_dma_dev_t device)

This function will allocate a DMA channel for a particular hardware
peripheral.  Before initiating  a transfer on the allocated channel, the
channel has to be setup, and buffers have to be added to the channel.

Parameters:
    int * handle                A pointer which is filled in with a unique
                                integer value, or handle. The handle is used 
                                to verify the validity of each call to  
                                access the dma channel.
                            
    const char * device_id      string which is the name of the device
                                attached to the dma channel.

    ep93xx_dma_dev_t device     hardware port to attach to the dma channel

------------------------------------------------------------------------------

    int ep93xx_dma_free(int handle)

This function disables and powers down the dma channel, and releases it
for future requests. Buffers queued up for the specified channel are 
released without transferring.
        
Parameters:
    int handle              A unique integer value, assigned 
                            during open, used to verify the validity of
                            this call to access a DMA channel.

------------------------------------------------------------------------------

    int ep93xx_dma_add_buffer(int handle, unsigned int source,
                              unsigned int dest, unsigned int size
                              unsigned int last, unsigned int buf_id)
        
This function adds a buffer entry to the DMA buffer queue.  If the channel is
in the active transfer state, the buffer is immediately transferred,
otherwise the buffer is not transferred until a start or resume
command is issued. A -1 is returned if an error occurs, otherwise
a 0 is returned.
         
Parameter:
    int handle                  A unique integer value, assigned 
                                during open, used to verify the validity of
                                this call to access a dma channel.
    
    unsigned int source         physical address for the start of this
                                buffer.

    unsigned int source         physical address destination of the data.

    unsigned int size           buffer size in bytes

    unsigned int last           1 if this is the last buffer in the transfer.
                                If 1, disable the NFBint so we aren't
                                interrupted for another buffer
                                when we know there won't be another.

    unsigned int buf_id         Unique value used to identify this buffer.

------------------------------------------------------------------------------

    int ep93xx_dma_remove_buffer(int handle, unsigned int * address,
                                 unsigned int * size) 

This function removes a buffer entry from the DMA buffer queue. If a buffer
was removed successfully, a 0 is returned, otherwise -1 is returned.

Parameter:
    int handle                  A unique integer value, assigned 
                                during open, used to verify the validity of
                                this call to access a dma channel.

    unsigned int * buf_id       Pointer to an integer which is filled in
                                with the buffer id..

------------------------------------------------------------------------------

    int ep93xx_dma_queue_full(int handle) 

This function queries to determine if the buffer queue for the specified
channel is full. A return value of 1 indicates the queue is not full, and a
0 indicates the queue is full.

Parameters:
    int handle              A unique integer value, assigned 
                            during open, used to verify the validity of
                            this call to access a dma channel. 

------------------------------------------------------------------------------

	int ep93xx_dma_get_position(int handle, unsigned int * buf_id,
                                unsigned int * total)

This function fills in the buffer ID of the current buffer and fills in the
total bytes transferred on the channel. If no buffer is active on the channel,
buf_id is filled in with a -1, otherwise it is the active buffer.
        
Parameter:
    int handle              A unique integer value, assigned 
                            during open, used to verify the validity of
                            this call to access a dma channel.

    unsigned int * buf_id   pointer to an integer which is filled in with
                            buffer ID of the buffer currently
                            transferring.
                                                        
    unsigned int * total    pointer to an integer which is filled in
                            with the total bytes transferred on the channel.

------------------------------------------------------------------------------

    int ep93xx_dma_config(int handle, unsigned int flags_m2m,
                          unsigned int flags_m2p, dma_callback callback,
                          unsigned int user_data)

This function configures the DMA channel registers and installs a dma
callback function into the DMA instance.  The DMA callback function is
defined by the driver which is using this DMA channel. It is called in
response to DMA interrupts, at the end of the DMA channel's interrupt
handler.  A -1 is returned if an error occurs, otherwise a 0 is returned.

Parameter:
    int handle              A unique integer value, assigned 
                            during open, used to verify the validity of
                            this call to access a dma channel.              

    unsigned int flags_m2m  Flags used for M2M channel configuration.

    unsigned int flags_m2p  Flags used for M2P/P2M channel
                            configuration.

    dma_callback callback   Pointer to the callback function which will
                            be called at the end of the dma interrupt
                            service routine.

    unsigned int user_data  Data defined by the driver installing the
                            callback function.  This piece of data will
                            be returned to the driver when the callback 
                            function is called.

Callback function prototype:
            
    void (* dma_callback)(ep93xx_dma_int_t interrupt,
                          ep93xx_dma_dev_t device, unsigned int user_data)
                                         
    Parameters:
        ep93xx_dma_int_t interrupt
            used by the DMA driver to inform the DMA callback  
            function of the type of DMA interrupt that happened.

        ep93xx_dma_dev_t device
            hardware port attached to the dma channel.

        unsigned int user_data
            is a value defined and passed in by the driver which 
            registered the callback function.
    
------------------------------------------------------------------------------

    int ep93xx_dma_start(int handle, unsigned int channels,
                         unsigned int * handles
        
This function enables the DMA channel, and initiates the transfer.  If the 
peripheral interface calls for it, multiple DMA channels can be started
with one call to this IOCTL.    A -1 is returned if an error occurs,
otherwise a 0 is returned.

Parameter:
    int handle              A unique integer value, assigned 
                            during open, used to verify the validity of
                            this call to access a dma channel.  For a start
                            multiple, this handle can be the handle 
                            for any of the channels to be started.

    unsigned int channels   Number of channels to start for this transfer.
                            Specifically this applies to an audio interface
                            where you can have up to 3 dma channels
                            servicing a 6 audio channel output, in which case
                            you need to initiate transfers on all 3 dma
                            channels as closely together as possible. For
                            the case of only one channel to be started, this 
                            field should be a 1.

    unsigned int * handles  Pointer to an array of handles, one for
                            each channel which is to be started.  If only one
                            channel is to be started, this field should be
                            NULL.
        
------------------------------------------------------------------------------

    int ep93xx_dma_pause(int handle, unsigned int channels,
                         unsigned int * handles)

This function disables the DMA channel, pausing the transfer.  The
position within the currently transferring buffer is saved, and restored upon
restarting the transfer on this channel. If the peripheral interface calls
for it, multiple DMA channels can be paused with one call to this IOCTL.
A -1 is returned if an error occurs, otherwise a 0 is returned.

Parameter:
    int handle              A unique integer value, assigned 
                            during open, used to verify the validity of
                            this call to access a dma channel.

    unsigned int channels   Number of channels to pause for this
                            transfer.  Specifically this applies to
                            an audio interface where you can have 
                            up to 3 dma channels servicing a 6
                            audio channel output, in which case you
                            need to pause transfers on all 3 dma
                            channels as closely together as possible.

    unsigned int * handles  Pointer to an array of handles, one for
                            each channel which is to be paused.
                                
NOTE: There is another way to pause the DMA channel - starve it.
When the dma channel reaches the point where there are no buffers in
the queue, but the interface has not been paused, then the dma instance
will indicate that the channel is in the transfer state, but the
channel itself is disabled until a new buffer is added to the queue
If the channel is stopped via this method, a resume command is not
required to restart a transfer.  A transfer is started immediately
after two new buffers are added to the queue.  The reason for two is
so that both channel buffer descriptors can be programmed with valid 
buffers

------------------------------------------------------------------------------

    int ep93xx_dma_flush(int handle)

This function completely flushes all queued buffers and any on going
DMA transfers on a given channel.  If the dma channel is in the
active transfer state, once two buffers are added to the queue, the 
channel will begin transferring data right away.  If in the stop
state, a start command must be issued before any new buffers are 
processed. A -1 is returned if an error occurs, otherwise a 0 is returned.

Parameters:
    int handle      A unique integer value, assigned 
                    during open, used to verify the validity of
                    this call to access a dma channel.
    