/***************************************************************************
*	NAME:  CODEC.H $Revision: 1.12 $
**	COPYRIGHT:
**	"Copyright (c) 1994,1995 by e-Tek Labs"
**
**       "This software is furnished under a license and may be used,
**       copied, or disclosed only in accordance with the terms of such
**       license and with the inclusion of the above copyright notice.
**       This software or any other copies thereof may not be provided or
**       otherwise made available to any other person. No title to and
**       ownership of the software is hereby transfered."
****************************************************************************
* $Log: codec.h $
* Revision 1.12  1995/10/26 14:58:54  mleibow
* Added mutes for software mixer controls.
* Revision 1.11  1995/10/13 17:16:47  mleibow
* Added effects slider to mixer, and changed code for dynamic resizing of mixer.
* Revision 1.10  1995/07/07 16:01:30  sdsmith
* Added mixer version and checksum to mixer string
* Revision 1.9  1995/06/28 08:46:53  sdsmith
* Added support for removing nodes based on module inclusion
* Revision 1.8  1995/06/08 11:52:56  mleibow
* Added MLS_INFO to mix
* Added multiple language support for mixer labels
* Revision 1.7  1995/04/28 12:16:51  sdsmith
* Bumped number of nodes by one
* Revision 1.6  1995/04/26 16:26:39  sdsmith
* Revision 1.5  1995/04/14 09:19:58  sdsmith
* Added support for B0 silicon
* Revision 1.4  1995/03/27 07:59:28  sdsmith
* New mixer node stuff
* Revision 1.3  1995/03/08 13:42:20  sdsmith
* Fixed default for Record Interrupt Enable
* Revision 1.2  1995/02/24 13:50:37  mleibow
* Revision 1.1  1995/02/23 11:06:57  unknown
* Initial revision
***************************************************************************/

#ifndef _CODEC_H
#define _CODEC_H

/************************************************************************/
/* Indirect register definitions for CODEC_ADDR register */
/* Bits 0-3. Select an internal register to read/write */
#define LEFT_ADC_INPUT      0x00	/* Left input control register */
#define RIGHT_ADC_INPUT     0x01	/* RIght input control register */
#define LEFT_AUX1_INPUT     0x02	/* Left Aux #1 input control */
#define RIGHT_AUX1_INPUT    0x03	/* Right Aux #1 input control */
#define LEFT_SYNTH_INPUT    0x02	/* Left Aux #1 input control */
#define RIGHT_SYNTH_INPUT   0x03	/* Right Aux #1 input control */
#define LEFT_AUX2_INPUT     0x04	/* Left Aux #2 input control */
#define RIGHT_AUX2_INPUT    0x05	/* Right Aux #2 input control */
#define LEFT_CD_INPUT       0x04	/* Left Aux #2 input control */
#define RIGHT_CD_INPUT      0x05	/* Right Aux #2 input control */
#define LEFT_DAC_OUTPUT     0x06	/* Left output control */
#define RIGHT_DAC_OUTPUT    0x07	/* Right output control */
#define PLAYBACK_FORMAT     0x08	/* Clock and data format */
#define CONFIG_1            0x09	/* Interface control */
#define EXTERNAL_CONTROL    0x0a	/* Pin control */
#define STATUS_2            0x0b	/* Test and initialization */
#define MODE_SELECT_ID      0x0c	/* Miscellaneaous information */
#define LOOPBACK            0x0d	/* Digital Mix */
#define UPPER_PLAY_COUNT    0x0e	/* Playback Upper Base Count */
#define LOWER_PLAY_COUNT    0x0f	/* Playback Lower Base Count */
#define CONFIG_2            0x10	/* alternate #1 feature enable */
#define CONFIG_3            0x11	/* alternate #2 feature enable */
#define LEFT_LINE_INPUT     0x12	/* left line input control */
#define RIGHT_LINE_INPUT    0x13	/* right line input control */
#define UPPER_TIMER         0x14	/* timer low byte */
#define LOWER_TIMER         0x15	/* timer high byte */
#define LEFT_MIC_INPUT      0x16
#define RIGHT_MIC_INPUT     0x17
#define STATUS_3            0x18	/* irq status register */
#define LEFT_MASTER_OUTPUT  0x19	/* irq status register */
#define MONO_IO_CTRL        0x1a	/* mono input/output control */
#define RIGHT_MASTER_OUTPUT 0x1b	/* irq status register */
#define RECORD_FORMAT       0x1c	/* record format */
#define PLAYBACK_FREQ       0x1d
#define UPPER_RECORD_COUNT  0x1e	/* record upper count */
#define LOWER_RECORD_COUNT  0x1f	/* record lower count */

#define DIG_AUDIO_MASTER    0x20
#define DIG_MUSIC_MASTER    0x21
#define MIDI_MASTER         0x22
#define EFFECTS_MASTER	    0x23
#define EFFECTS_MUTE	    0x24
#define DIG_AUDIO_MUTE	    0x25
#define DIG_MUSIC_MUTE	    0x26
#define MIDI_MUTE	    0x27

/************************************************************************/
/* Control bit definitions for CODEC_ADDR register */
#define CODEC_INIT	0x80		/* CODEC is initializing */
#define CODEC_MCE	0x40		/* Mode change enable */
#define CODEC_DTD	0x20		/* Transfer Request Disable */
/************************************************************************/

/************************************************************************/
/* Definitions for CODEC_STATUS (STATUS_1) register */
#define CODEC_RULB	0x80		/* Capture data upper/lower byte */
#define CODEC_RLR	0x40		/* Capture left/right sample */
#define CODDEC_RDA	0x20		/* Capture data read */
#define CODEC_SE	0x10		/* Playback over/under run error */
#define CODEC_PULB	0x08		/* Playback upper/lower byte */
#define CODEC_PLR	0x04		/* Playback left/right sample */
#define CODEC_PBA	0x02		/* Playback data register read */
#define CODEC_GINT	0x01		/* interrupt status */
/************************************************************************/

/************************************************************************/
/* Definitions for STATUS_2 register                                    */
#define CODEC_STATUS2_RFO 0x80  /* Record FIFO overrun */
#define CODEC_STATUS2_PFU 0x40  /* Playback FIFO underrun */
#define CODEC_CACT        0x20  /* Calibration Active */
#define CODEC_DMA_ACTIVE  0x10  /* DMA Request line status */
#define CODEC_RADO_MASK   0x0C  /* Right Overrange Detect */
#define CODEC_LADO_MASK   0x03  /* Left Overrange Detect */
/************************************************************************/

/************************************************************************/
/* Definitions for STATUS_3 register                                    */
#define CODEC_TIR          0x40   /* Timer Interrupt Request */
#define CODEC_RFDI         0x20   /* Record FIFO Interrupt Request */
#define CODEC_PFDI         0x10   /* Playback FIFO Interrupt Request */
#define CODEC_RFU          0x08   /* Record FIFO underrun */
#define CODEC_STATUS3_RFO  0x04   /* Record FIFO overrun */
#define CODEC_PFO          0x02   /* Playback FIFO overrun */
#define CODEC_STATUS3_PFU  0x01   /* Playback FIFO underrun */
#define CODEC_STAT_MASK    0x70
/************************************************************************/

/************************************************************************/
/* Definitions for LEFT_ADC_INPUT and RIGHT_ADC_INPUT register */
#define SOURCE_LINE	  0x00		/* Line source selected */
#define SOURCE_AUX1	  0x40		/* Auxiliary 1 source selected */
#define SOURCE_MIC	  0x80		/* Microphone source selected */
#define SOURCE_MIXER      0xC0		/* Post-mixed DAC output selected */
/************************************************************************/

/************************************************************************/
/* Mute enable for AUX1, AUX2, LINE, MIC, DAC, MASTER Control registers */
#define CODEC_MUTE_ENABLE	0x80
/************************************************************************/

/************************************************************************/
/* Definition for LOOPBACK register                                     */
#define CODEC_LBE	0x01
/************************************************************************/

/************************************************************************/
/* Playback and record data formats                                     */
#define CODEC_STEREO	              0x10
#define CODEC_16BIT_SIGNED_BIG_END    0xC0
#define CODEC_IMA_ADPCM		      0xA0
#define CODEC_8BIT_ALAW		      0x60
#define CODEC_16BIT_SIGNED_LITTLE_END 0x40
#define CODEC_8BIT_ULAW		      0x20
#define CODEC_8BIT_UNSIGNED	      0x00

/* Clock Divisor             Sample Rate in KHz  
                              (24.576 MHz / 16.9344 MHz ) */
#define CODEC_CLOCK_0 0x00   /*  8.0      / 5.51   */
#define CODEC_CLOCK_1 0x02   /*  16.0     / 11.025 */
#define CODEC_CLOCK_2 0x04   /*  27.42    / 18.9   */
#define CODEC_CLOCK_3 0x06   /*  32.0     / 22.05  */
#define CODEC_CLOCK_4 0x08   /*           / 37.8   */
#define CODEC_CLOCK_5 0x0A   /*           / 44.1   */
#define CODEC_CLOCK_6 0x0C   /*  48.0     / 33.075 */
#define CODEC_CLOCK_7 0x0E   /*  9.6      / 6.62   */

/* Crystal Select */
#define CODEC_XTAL2			0x01	/* 16.9344 crystal */
#define CODEC_XTAL1			0x00	/* 24.576 crystal */
/************************************************************************/

/************************************************************************/
/* Definitions for CONFIG_1 register                                    */
#define CODEC_CFIG1I_DEFAULT    0x00
#define CODEC_CAPTURE_PIO	0x80	/* Capture PIO enable */
#define CODEC_PLAYBACK_PIO	0x40	/* Playback PIO enable */
#define CODEC_AUTOCALIB		0x08	/* auto calibrate */
#define CODEC_SINGLE_DMA	0x04	/* Use single DMA channel */
#define CODEC_RE		0x02	/* Capture enable */
#define CODEC_PE		0x01	/* playback enable */
/************************************************************************/

/************************************************************************/
/* Definitions for CONFIG_2 register                                    */
#define CODEC_CFIG2I_DEFAULT    0x81
#define CODEC_OFVS 0x80  /* Output Full Scale Voltage */
#define CODEC_TE   0x40  /* Timer Enable */
#define CODEC_RSCD 0x20  /* Recors Sample Counter Disable */
#define CODEC_PSCD 0x10  /* Playback Sample Counter Disable */
#define CODEC_DAOF 0x01  /* D/A Ouput Force Enable */
/************************************************************************/

/************************************************************************/
/* Definitions for CONFIG_3 register                                    */
#define CODEC_CFIG3I_DEFAULT    0xC2 // 0x02 when synth DACs are working
#define CODEC_RPIE    0x80  /* Record FIFO IRQ Enable */
#define CODEC_PPIE    0x40  /* Playback FIFO IRQ Enable */
#define CODEC_FT_MASK 0x30  /* FIFO Threshold Select */
#define CODEC_PVFM    0x04  /* Playback Variable Frequency Mode */
#define CODEC_SYNA    0x02  /* AUX1/Synth Signal Select */
/************************************************************************/

/************************************************************************/
/* Definitions for EXTERNAL_CONTROL register                            */  
#define CODEC_CEXTI_DEFAULT     0x00
#define CODEC_IRQ_ENABLE	0x02	/* interrupt enable */
#define CODEC_GPOUT1		0x80	/* external control #1 */
#define CODEC_GPOUT0		0x40	/* external control #0 */
/************************************************************************/

/************************************************************************/
/* Definitions for MODE_SELECT_ID register                              */
#define CODEC_MODE_DEFAULT 0x40
#define CODEC_MODE_MASK  0x60
#define CODEC_ID_BIT4    0x80
#define CODEC_ID_BIT3_0  0x0F
/************************************************************************/

/***************************************************************************

GLOBAL DEFINITION:
CODEC_IMAGE - structure to track CODEC registers

DESCRIPTION:
The CODEC_IMAGE structure is used to track information about the current
state of the codec.  The information includes the base port, irq', dma
channels, and register values.

*/
/* Direct Codec Registers */
#ifdef CODEC_GLOBALS
#define IWEXT
#define IWINIT(a,b) a = b;
#else
#define IWEXT extern
#define IWINIT(a,b) a;
#endif
IWEXT unsigned int iwl_codec_play_chan; /* codec playback DMA channel */
IWEXT unsigned int iwl_codec_rec_chan;  /* codec record DMA channel */
IWEXT unsigned int iwl_codec_irq_num;   /* current codec IRQ number */
IWEXT unsigned int iwl_codec_setup;   /* CODEC/SCSI register on the UltraMAX */
IWEXT unsigned  char iwl_codec_shared_irq;
IWEXT OS_PINTERRUPT	iwl_old_codec_vec;
IWEXT void (*iwl_codec_playback_func)();
IWEXT void (*iwl_codec_capture_func)();
IWEXT void (*iwl_codec_timer_func)();
IWEXT unsigned int iwl_codec_playfreq;   /* playback freqency in hertz ... */
IWEXT unsigned int iwl_codec_recfreq;    /* record freqency in hertz ... */

extern unsigned char iwl_clici;      /* left ADC input control register */
extern unsigned char iwl_crici;      /* right ADC input control register */
extern unsigned char iwl_clax1i;     /* left AUX1 input control register */
extern unsigned char iwl_crax1i;     /* left AUX1 input control register */
extern unsigned char iwl_clax2i;     /* left AUX2 input control register */
extern unsigned char iwl_crax2i;     /* left AUX2 input control register */
extern unsigned char iwl_cldaci;     /* left DAC output control register */
extern unsigned char iwl_crdaci;     /* right DAC output control register */
extern unsigned char iwl_cpdfi;      /* playback data format */
extern unsigned char iwl_crdfi;      /* record data format */
extern unsigned char iwl_cfig1i;     /* configuration register 1 */
extern unsigned char iwl_cfig2i;     /* configuration register 2 */
extern unsigned char iwl_cfig3i;     /* configuration register 3 */
extern unsigned char iwl_cexti;      /* external control */
extern unsigned char iwl_csr2i;      /* status register 2 */
extern unsigned char iwl_csr3i;      /* status register 3 */
extern unsigned char iwl_cmodei;     /* mode and ID register */
extern unsigned char iwl_clci;       /* loopback control register */
extern unsigned char iwl_cupcti;     /* playback upper base register */
extern unsigned char iwl_clpcti;     /* playback lower base register */
extern unsigned char iwl_curcti;     /* record upper base register */
extern unsigned char iwl_clrcti;     /* record lower base register */
extern unsigned char iwl_cllici;     /* left line input control register */
extern unsigned char iwl_crlici;     /* right line input control register */
extern unsigned char iwl_cltimi;     /* timer low byte */
extern unsigned char iwl_cutimi;     /* timer high byte */
extern unsigned char iwl_clmici;     /* left mic input */
extern unsigned char iwl_crmici;     /* right mic input */
extern unsigned char iwl_cloai;      /* left output attenuation */
extern unsigned char iwl_croai;      /* right output attentuation */
extern unsigned char iwl_cmonoi;     /* mono I/O control */
extern unsigned char iwl_cpvfi;      /* playback variable frequency */

/***************************************************************************

GLOBAL DEFINITION:
CODEC_FREQ - structure to map a frequency in hertz to bit mask

DESCRIPTION:
The CODEC_FREQ structure is used to map the record and playback 
frequencies that are supported by the codec into bit values for the
various codec control registers.

SEE ALSO: vars16.c

*/
#define NUM_CODEC_FREQS 14
typedef struct {
  unsigned int hertz;
  unsigned char bits;
} CODEC_FREQ;
extern CODEC_FREQ codec_freq[NUM_CODEC_FREQS];

/* Mixer specific stuff */
#define MIXER_VERSION   1
#define MLS_MIXER_BASE	500
#define IW_MIX_ATTR_STEREO       0x0001
#define IW_MIX_ATTR_MASTER       0x0002
#define IW_MIX_ATTR_INTERMEDIATE 0x0004
#define IW_MIX_ATTR_SIGNED       0x0008
#define IW_MIX_ATTR_UNSIGNED     0x0010
#define IW_MIX_ATTR_LINEAR       0x0020
#define IW_MIX_ATTR_LOG          0x0040
#define IW_MIX_ATTR_SWAPLR       0x0080
#define IW_MIX_ATTR_MONOLEFT     0x0100
#define IW_MIX_ATTR_MONORIGHT    0x0200

struct iw_mixer_node {
	unsigned short id;
	unsigned short parent_id;
	unsigned short owner_id;
	iw_mixer_node_type type;
	iw_mixer_node_subtype subtype;
	unsigned short ordinal;
	unsigned short subordinal;
	unsigned short attributes;
	struct {int min; int max; int inc_integer; int inc_fraction;} range;
	union {
		struct {
			int left;
			int right;
		} stereo;
		int value;
	} current;
	unsigned short mls_info;
	unsigned char RFAR *description;
	unsigned char RFAR *name;
};

struct iw_mix_register_map {
	int left;
	int right;
	unsigned char bit_mask;
	unsigned char shift;
};
extern struct iw_mix_register_map iw_mix_register_map[];
extern struct iw_mixer_node iw_mixer_nodes[];

/* Irq functions */
extern void iwl_codec_enable_irqs(void);
extern void iwl_codec_disable_irqs(void);

extern int iwl_codec_probe(void);
extern void iwl_codec_data_format( struct dig_voice_status *, unsigned char);
extern void iwl_codec_auto_calibrate(void);
extern void iwl_codec_set_freq(unsigned int, unsigned char RFAR *format);
extern void iwl_codec_play_format(int,int,int);
extern void iwl_codec_record_format(int,int,int);
extern int iwl_codec_prime_play(int, struct dig_voice_status RFAR*);
extern void iwl_init_codec_voice(struct dig_voice_status RFAR*);
extern void iwl_codec_start_play_dma(void);
extern void iwl_codec_stop_play_dma(void);
extern unsigned int iwl_codec_program_play_count(unsigned int);
extern int iwl_codec_prime_record(int, struct dig_voice_status RFAR*);
extern void iwl_codec_start_record_dma(void);
extern void iwl_codec_stop_record_dma(void);
extern unsigned int iwl_codec_program_record_count(unsigned int);
extern void iwl_codec_transparent(void);

extern unsigned char iwl_db_to_reg(int, int);
extern int iwl_reg_to_db(int, int);
extern unsigned char iwl_linear_to_reg(int, unsigned short);
extern int iwl_reg_to_linear(int, unsigned short);
extern int iwl_get_node_index(int);
extern void iwl_init_mixer_nodes(void);
extern void iwl_mixer_set_mux( int, int, int);
extern void iwl_mixer_set_mute( int, int, int);
extern void iwl_mixer_set_level( int, int, int);
#endif
