/*
 * ep93xx-audio.h
 *
 * Common audio handling for the Cirrus Logic EP93xx
 *
 * Copyright (c) 2003 Cirrus Logic Corp.
 * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
 *
 * Taken from sa1100-audio.h
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License.
 */

/*
 * If this is #defined we will up the number of buffers we allocate so 
 * that if an application requests 2 16K buffers for playing 16 bit audio,
 * we will allocate 4 16K buffers so we have room to expand the 16 bit 
 * samples to 32 bit samples.
 *
 * We also do some scaling in the ioctls that have to do with reporting
 * position and amount of buffer available.
 */
#define I2S_SCALE_BUFFERS

/*
 *  Getting this from the rme96xx driver.  Has same numerical value
 *  as AC3.  Hmmmm.
 */
#ifndef AFMT_S32_BLOCKED
#define AFMT_S32_BLOCKED 0x0000400
#endif

#define EP93XX_DEFAULT_NUM_CHANNELS      2
#define EP93XX_DEFAULT_FORMAT            AFMT_S16_LE
#define EP93XX_DEFAULT_BIT_WIDTH         16

/*
 * Buffer Management
 */

typedef struct {

	int 				size;			/* buffer size 						*/
	int 				sent;			/* indicates that dma has the buf	*/
	char 				*start;			/* points to actual buffer 			*/
	dma_addr_t 			dma_addr;		/* physical buffer address 			*/
	struct semaphore 	sem;			/* down before touching the buffer 	*/
	int 				master;			/* owner for buffer allocation,    	*/
										/* contains size when true 			*/
	struct audio_stream_s 	*stream;	/* owning stream 					*/

} audio_buf_t;

#define MAX_DEVICE_NAME 20

typedef struct audio_stream_s {

	/* dma stuff */
	int				dmahandles[3];		/* handles for dma driver instances */
	char			devicename[MAX_DEVICE_NAME]; /* string - name of device */
	int				NumDmaChannels;		/* 1, 2, or 3 DMA channels 			*/
	
	audio_buf_t 	*buffers;			/* array of audio buffer structures */
	audio_buf_t 	*buf;				/* current buffer used by read/write */
	u_int 			buf_idx;			/* index for the pointer above... 	*/
	u_int 			fragsize;			/* fragment i.e. buffer size 		*/
	u_int 			nbfrags;			/* nbr of fragments i.e. buffers 	*/
	u_int			reportedfrags;		/* # of frags reported to app		*/
	int 			bytecount;			/* nbr of processed bytes 			*/
	int 			getptrCount;		/* value of bytecount last time 	*/
										/* anyone asked via GETxPTR 		*/
	int 			fragcount;			/* nbr of fragment transitions 		*/
	ep93xx_dma_int_t dma_ch;			/* DMA channel ID 					*/
	wait_queue_head_t 	wq;				/* for poll 						*/
	int 			mapped:1;			/* mmap()'ed buffers 				*/
	int 			active:1;			/* actually in progress 			*/
	int 			stopped:1;			/* might be active but stopped 		*/

	/*
	 * Data about the file format that we are configured to play.
	 */
	long 				audio_num_channels;			/* Range: 1 to 6 */
	long 				audio_format;
	long 				audio_stream_bitwidth;		/* Range: 8, 16, 24, 32 */

} audio_stream_t;


/*
 * State structure for one instance
 */
typedef struct {
	audio_stream_t 		*output_stream;
	audio_stream_t 		*input_stream;
	
	ep93xx_dma_dev_t 	output_dma;
	ep93xx_dma_dev_t 	input_dma;
	
	char 				*output_id;
	char 				*input_id;
	
	int 				rd_ref:1;			/* open reference for recording */
	int 				wr_ref:1;			/* open reference for playback */
	
	/*
	 * Pointers to init, shutdown, and ioctl functions.
	 */
	void 				(*hw_enable)(int input_or_output_stream);
	void 				(*hw_disable)(int input_or_output_stream);
	int 				(*client_ioctl)(struct inode *, struct file *, uint, ulong);
	void				(*set_hw_serial_format)( long );

	struct 				semaphore sem;		/* to protect against races in attach() */

	/*
	 * Data about how the audio controller and codec are set up.
	 */
	int					DAC_bit_width;		/* 16, 20, 24 bits */
	int					bCompactMode;		/* set if 32bits = a stereo sample */

} audio_state_t;

/*
 * Functions exported by this module
 */
extern int ep93xx_audio_attach( struct inode *inode, 
								struct file *file,
								audio_state_t *state);
