#undef FKS_LOGGING
#undef FKS_TEST

/*
 * tabs should be 4 spaces, in vi(m): set tabstop=4
 *
 * TODO: 	consistency speed calculations!!
 *			cleanup!
 * ????:	Did I break MIDI support?
 *
 * History:
 *
 * Rolf Fokkens	 (Dec 20 1998):	ES188x recording level support on a per
 * fokkensr@vertis.nl			input basis.
 *				 (Dec 24 1998):	Recognition of ES1788, ES1887, ES1888,
 *								ES1868, ES1869 and ES1878. Could be used for
 *								specific handling in the future. All except
 *								ES1887 and ES1888 and ES688 are handled like
 *								ES1688.
 *				 (Dec 27 1998):	RECLEV for all (?) ES1688+ chips. ES188x now
 *								have the "Dec 20" support + RECLEV
 *				 (Jan  2 1999):	Preparation for Full Duplex. This means
 *								Audio 2 is now used for playback when dma16
 *								is specified. The next step would be to use
 *								Audio 1 and Audio 2 at the same time.
 *				 (Jan  9 1999):	Put all ESS stuff into sb_ess.[ch], this
 *								includes both the ESS stuff that has been in
 *								sb_*[ch] before I touched it and the ESS support
 *								I added later
 *				 (Jan 23 1999):	Full Duplex seems to work. I wrote a small
 *								test proggy which works OK. Haven't found
 *								any applications to test it though. So why did
 *								I bother to create it anyway?? :) Just for
 *								fun.
 *				 (May  2 1999):	I tried to be too smart by "introducing"
 *								ess_calc_best_speed (). The idea was that two
 *								dividers could be used to setup a samplerate,
 *								ess_calc_best_speed () would choose the best.
 *								This works for playback, but results in
 *								recording problems for high samplerates. I
 *								fixed this by removing ess_calc_best_speed ()
 *								and just doing what the documentation says. 
 * Andy Sloane   (Jun  4 1999): Stole some code from ALSA to fix the playback
 * andy@guildsoftware.com		speed on ES1869, ES1879, ES1887, and ES1888.
 * 								1879's were previously ignored by this driver;
 * 								added (untested) support for those.
 * Cvetan Ivanov (Oct 27 1999): Fixed ess_dsp_init to call ess_set_dma_hw for
 * zezo@inet.bg					_ALL_ ESS models, not only ES1887
 *
 * This files contains ESS chip specifics. It's based on the existing ESS
 * handling as it resided in sb_common.c, sb_mixer.c and sb_audio.c. This
 * file adds features like:
 * - Chip Identification (as shown in /proc/sound)
 * - RECLEV support for ES1688 and later
 * - 6 bits playback level support chips later than ES1688
 * - Recording level support on a per-device basis for ES1887
 * - Full-Duplex for ES1887
 *
 * Full duplex is enabled by specifying dma16. While the normal dma must
 * be one of 0, 1 or 3, dma16 can be one of 0, 1, 3 or 5. DMA 5 is a 16 bit
 * DMA channel, while the others are 8 bit..
 *
 * ESS detection isn't full proof (yet). If it fails an additional module
 * parameter esstype can be specified to be one of the following:
 * -1, 0, 688, 1688, 1868, 1869, 1788, 1887, 1888
 * -1 means: mimic 2.0 behaviour, 
 *  0 means: auto detect.
 *   others: explicitly specify chip
 * -1 is default, cause auto detect still doesn't work.
 */

/*
 * About the documentation
 *
 * I don't know if the chips all are OK, but the documentation is buggy. 'cause
 * I don't have all the cips myself, there's a lot I cannot verify. I'll try to
 * keep track of my latest insights about his here. If you have additional info,
 * please enlighten me (fokkensr@vertis.nl)!
 *
 * I had the impression that ES1688 also has 6 bit master volume control. The
 * documentation about ES1888 (rev C, october '95) claims that ES1888 has
 * the following features ES1688 doesn't have:
 * - 6 bit master volume
 * - Full Duplex
 * So ES1688 apparently doesn't have 6 bit master volume control, but the
 * ES1688 does have RECLEV control. Makes me wonder: does ES688 have it too?
 * Without RECLEV ES688 won't be much fun I guess.
 *
 * From the ES1888 (rev C, october '95) documentation I got the impression
 * that registers 0x68 to 0x6e don't exist which means: no recording volume
 * controls. To my surprise the ES888 documentation (1/14/96) claims that
 * ES888 does have these record mixer registers, but that ES1888 doesn't have
 * 0x69 and 0x6b. So the rest should be there.
 *
 * I'm trying to get ES1887 Full Duplex. Audio 2 is playback only, while Audio 2
 * is both record and playback. I think I should use Audio 2 for all playback.
 *
 * The documentation is an adventure: it's close but not fully accurate. I
 * found out that after a reset some registers are *NOT* reset, though the
 * docs say the would be. Interesting ones are 0x7f, 0x7d and 0x7a. They are
 * related to the Audio 2 channel. I also was surprised about the consequences
 * of writing 0x00 to 0x7f (which should be done by reset): The ES1887 moves
 * into ES1888 mode. This means that it claims IRQ 11, which happens to be my
 * ISDN adapter. Needless to say it no longer worked. I now understand why
 * after rebooting 0x7f already was 0x05, the value of my choice: the BIOS
 * did it.
 *
 * Oh, and this is another trap: in ES1887 docs mixer register 0x70 is
 * described as if it's exactly the same as register 0xa1. This is *NOT* true.
 * The description of 0x70 in ES1869 docs is accurate however.
 * Well, the assumption about ES1869 was wrong: register 0x70 is very much
 * like register 0xa1, except that bit 7 is always 1, whatever you want
 * it to be.
 *
 * When using audio 2 mixer register 0x72 seems te be meaningless. Only 0xa2
 * has effect.
 *
 * Software reset not being able to reset all registers is great! Especially
 * the fact that register 0x78 isn't reset is great when you wanna change back
 * to single dma operation (simplex): audio 2 is still operational, and uses
 * the same dma as audio 1: your ess changes into a funny echo machine.
 *
 * Received the news that ES1688 is detected as a ES1788. Did some thinking:
 * the ES1887 detection scheme suggests in step 2 to try if bit 3 of register
 * 0x64 can be changed. This is inaccurate, first I inverted the * check: "If
 * can be modified, it's a 1688", which lead to a correct detection
 * of my ES1887. It resulted however in bad detection of 1688 (reported by mail)
 * and 1868 (if no PnP detection first): they result in a 1788 being detected.
 * I don't have docs on 1688, but I do have docs on 1868: The documentation is
 * probably inaccurate in the fact that I should check bit 2, not bit 3. This
 * is what I do now.
 */

/*
 * About recognition of ESS chips
 *
 * The distinction of ES688, ES1688, ES1788, ES1887 and ES1888 is described in
 * a (preliminary ??) datasheet on ES1887. Its aim is to identify ES1887, but
 * during detection the text claims that "this chip may be ..." when a step
 * fails. This scheme is used to distinct between the above chips.
 * It appears however that some PnP chips like ES1868 are recognized as ES1788
 * by the ES1887 detection scheme. These PnP chips can be detected in another
 * way however: ES1868, ES1869 and ES1878 can be recognized (full proof I think)
 * by repeatedly reading mixer register 0x40. This is done by ess_identify in
 * sb_common.c.
 * This results in the following detection steps:
 * - distinct between ES688 and ES1688+ (as always done in this driver)
 *   if ES688 we're ready
 * - try to detect ES1868, ES1869 or ES1878
 *   if successful we're ready
 * - try to detect ES1888, ES1887 or ES1788
 *   if successful we're ready
 * - Dunno. Must be 1688. Will do in general
 *
 * About RECLEV support:
 *
 * The existing ES1688 support didn't take care of the ES1688+ recording
 * levels very well. Whenever a device was selected (recmask) for recording
 * its recording level was loud, and it couldn't be changed. The fact that
 * internal register 0xb4 could take care of RECLEV, didn't work meaning until
 * its value was restored every time the chip was reset; this reset the
 * value of 0xb4 too. I guess that's what 4front also had (have?) trouble with.
 *
 * About ES1887 support:
 *
 * The ES1887 has separate registers to control the recording levels, for all
 * inputs. The ES1887 specific software makes these levels the same as their
 * corresponding playback levels, unless recmask says they aren't recorded. In
 * the latter case the recording volumes are 0.
 * Now recording levels of inputs can be controlled, by changing the playback
 * levels. Furthermore several devices can be recorded together (which is not
 * possible with the ES1688).
 * Besides the separate recording level control for each input, the common
 * recording level can also be controlled by RECLEV as described above.
 *
 * Not only ES1887 have this recording mixer. I know the following from the
 * documentation:
 * ES688	no
 * ES1688	no
 * ES1868	no
 * ES1869	yes
 * ES1878	no
 * ES1879	yes
 * ES1888	no/yes	Contradicting documentation; most recent: yes
 * ES1946	yes		This is a PCI chip; not handled by this driver
 */

#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>

#include "sound_config.h"
#include "sb_mixer.h"
#include "sb.h"

#include "sb_ess.h"

#define ESSTYPE_LIKE20	-1		/* Mimic 2.0 behaviour					*/
#define ESSTYPE_DETECT	0		/* Mimic 2.0 behaviour					*/

#define SUBMDL_ES1788	0x10	/* Subtype ES1788 for specific handling */
#define SUBMDL_ES1868	0x11	/* Subtype ES1868 for specific handling */
#define SUBMDL_ES1869	0x12	/* Subtype ES1869 for specific handling */
#define SUBMDL_ES1878	0x13	/* Subtype ES1878 for specific handling */
#define SUBMDL_ES1879	0x16    /* ES1879 was initially forgotten */
#define SUBMDL_ES1887	0x14	/* Subtype ES1887 for specific handling */
#define SUBMDL_ES1888	0x15	/* Subtype ES1888 for specific handling */

#define SB_CAP_ES18XX_RATE 0x100

#define ES1688_CLOCK1 795444 /* 128 - div */
#define ES1688_CLOCK2 397722 /* 256 - div */
#define ES18XX_CLOCK1 793800 /* 128 - div */
#define ES18XX_CLOCK2 768000 /* 256 - div */

#ifdef FKS_LOGGING
static void ess_show_mixerregs (sb_devc *devc);
#endif
static int ess_read (sb_devc * devc, unsigned char reg);
static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data);
static void ess_chgmixer
	(sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val);

/****************************************************************************
 *																			*
 *									ESS audio								*
 *																			*
 ****************************************************************************/

struct ess_command {short cmd; short data;};

/*
 * Commands for initializing Audio 1 for input (record)
 */
static struct ess_command ess_i08m[] =		/* input 8 bit mono */
	{ {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
static struct ess_command ess_i16m[] =		/* input 16 bit mono */
	{ {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
static struct ess_command ess_i08s[] =		/* input 8 bit stereo */
	{ {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
static struct ess_command ess_i16s[] =		/* input 16 bit stereo */
	{ {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };

static struct ess_command *ess_inp_cmds[] =
	{ ess_i08m, ess_i16m, ess_i08s, ess_i16s };


/*
 * Commands for initializing Audio 1 for output (playback)
 */
static struct ess_command ess_o08m[] =		/* output 8 bit mono */
	{ {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
static struct ess_command ess_o16m[] =		/* output 16 bit mono */
	{ {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
static struct ess_command ess_o08s[] =		/* output 8 bit stereo */
	{ {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
static struct ess_command ess_o16s[] =		/* output 16 bit stereo */
	{ {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };

static struct ess_command *ess_out_cmds[] =
	{ ess_o08m, ess_o16m, ess_o08s, ess_o16s };

static void ess_exec_commands
	(sb_devc *devc, struct ess_command *cmdtab[])
{
	struct ess_command *cmd;

	cmd = cmdtab [ ((devc->channels != 1) << 1) + (devc->bits != AFMT_U8) ];

	while (cmd->cmd != -1) {
		ess_write (devc, cmd->cmd, cmd->data);
		cmd++;
	}
}

static void ess_change
	(sb_devc *devc, unsigned int reg, unsigned int mask, unsigned int val)
{
	int value;

	value = ess_read (devc, reg);
	value = (value & ~mask) | (val & mask);
	ess_write (devc, reg, value);
}

static void ess_set_output_parms
	(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
	sb_devc *devc = audio_devs[dev]->devc;

	if (devc->duplex) {
		devc->trg_buf_16 = buf;
		devc->trg_bytes_16 = nr_bytes;
		devc->trg_intrflag_16 = intrflag;
		devc->irq_mode_16 = IMODE_OUTPUT;
	} else {
		devc->trg_buf = buf;
		devc->trg_bytes = nr_bytes;
		devc->trg_intrflag = intrflag;
		devc->irq_mode = IMODE_OUTPUT;
	}
}

static void ess_set_input_parms
	(int dev, unsigned long buf, int count, int intrflag)
{
	sb_devc *devc = audio_devs[dev]->devc;

	devc->trg_buf = buf;
	devc->trg_bytes = count;
	devc->trg_intrflag = intrflag;
	devc->irq_mode = IMODE_INPUT;
}

static int ess_calc_div (int clock, int revert, int *speedp, int *diffp)
{
	int divider;
	int speed, diff;
	int retval;

	speed   = *speedp;
	divider = (clock + speed / 2) / speed;
	retval  = revert - divider;
	if (retval > revert - 1) {
		retval  = revert - 1;
		divider = revert - retval;
	}
	/* This line is suggested. Must be wrong I think
	*speedp = (clock + divider / 2) / divider;
	So I chose the next one */

	*speedp	= clock / divider;
	diff	= speed - *speedp;
	if (diff < 0) diff =-diff;
	*diffp  = diff;

	return retval;
}

static int ess_calc_best_speed
	(int clock1, int rev1, int clock2, int rev2, int *divp, int *speedp)
{
	int speed1 = *speedp, speed2 = *speedp;
	int div1, div2;
	int diff1, diff2;
	int retval;

	div1 = ess_calc_div (clock1, rev1, &speed1, &diff1);
	div2 = ess_calc_div (clock2, rev2, &speed2, &diff2);

	if (diff1 < diff2) {
		*divp   = div1;
		*speedp = speed1;
		retval  = 1;
	} else {
	/*	*divp   = div2; */
		*divp   = 0x80 | div2;
		*speedp = speed2;
		retval  = 2;
	}

	return retval;
}

/*
 * Depending on the audiochannel ESS devices can
 * have different clock settings. These are made consistent for duplex
 * however.
 * callers of ess_speed only do an audionum suggestion, which means
 * input suggests 1, output suggests 2. This suggestion is only true
 * however when doing duplex.
 */
static void ess_common_speed (sb_devc *devc, int *speedp, int *divp)
{
	int diff = 0, div;

	if (devc->duplex) {
		/*
		 * The 0x80 is important for the first audio channel
		 */
		if (devc->submodel == SUBMDL_ES1888) {
			div = 0x80 | ess_calc_div (795500, 256, speedp, &diff);
		} else {
			div = 0x80 | ess_calc_div (795500, 128, speedp, &diff);
		}
	} else if(devc->caps & SB_CAP_ES18XX_RATE) {
		if (devc->submodel == SUBMDL_ES1888) {
			ess_calc_best_speed(397700, 128, 795500, 256, 
						&div, speedp);
		} else {
			ess_calc_best_speed(ES18XX_CLOCK1, 128, ES18XX_CLOCK2, 256, 
						&div, speedp);
		}
	} else {
		if (*speedp > 22000) {
			div = 0x80 | ess_calc_div (ES1688_CLOCK1, 256, speedp, &diff);
		} else {
			div = 0x00 | ess_calc_div (ES1688_CLOCK2, 128, speedp, &diff);
		}
	}
	*divp = div;
}

static void ess_speed (sb_devc *devc, int audionum)
{
	int speed;
	int div, div2;

	ess_common_speed (devc, &(devc->speed), &div);

#ifdef FKS_REG_LOGGING
printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, devc->speed, div);
#endif

	/* Set filter roll-off to 90% of speed/2 */
	speed = (devc->speed * 9) / 20;

	div2 = 256 - 7160000 / (speed * 82);

	if (!devc->duplex) audionum = 1;

	if (audionum == 1) {
		/* Change behaviour of register A1 *
		sb_chg_mixer(devc, 0x71, 0x20, 0x20)
		* For ES1869 only??? */
		ess_write (devc, 0xa1, div);
		ess_write (devc, 0xa2, div2);
	} else {
		ess_setmixer (devc, 0x70, div);
		/*
		 * FKS: fascinating: 0x72 doesn't seem to work.
		 */
		ess_write (devc, 0xa2, div2);
		ess_setmixer (devc, 0x72, div2);
	}
}

static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
{
	sb_devc *devc = audio_devs[dev]->devc;

	ess_speed(devc, 1);

	sb_dsp_command(devc, DSP_CMD_SPKOFF);

	ess_write (devc, 0xb8, 0x0e);	/* Auto init DMA mode */
	ess_change (devc, 0xa8, 0x03, 3 - devc->channels);	/* Mono/stereo */
	ess_write (devc, 0xb9, 2);	/* Demand mode (4 bytes/DMA request) */

	ess_exec_commands (devc, ess_inp_cmds);

	ess_change (devc, 0xb1, 0xf0, 0x50);
	ess_change (devc, 0xb2, 0xf0, 0x50);

	devc->trigger_bits = 0;
	return 0;
}

static int ess_audio_prepare_for_output_audio1 (int dev, int bsize, int bcount)
{
	sb_devc *devc = audio_devs[dev]->devc;

	sb_dsp_reset(devc);
	ess_speed(devc, 1);
	ess_write (devc, 0xb8, 4);	/* Auto init DMA mode */
	ess_change (devc, 0xa8, 0x03, 3 - devc->channels);	/* Mono/stereo */
	ess_write (devc, 0xb9, 2);	/* Demand mode (4 bytes/request) */

	ess_exec_commands (devc, ess_out_cmds);

	ess_change (devc, 0xb1, 0xf0, 0x50);	/* Enable DMA */
	ess_change (devc, 0xb2, 0xf0, 0x50);	/* Enable IRQ */

	sb_dsp_command(devc, DSP_CMD_SPKON);	/* There be sound! */

	devc->trigger_bits = 0;
	return 0;
}

static int ess_audio_prepare_for_output_audio2 (int dev, int bsize, int bcount)
{
	sb_devc *devc = audio_devs[dev]->devc;
	unsigned char bits;

/* FKS: qqq
	sb_dsp_reset(devc);
*/

	/*
	 * Auto-Initialize:
	 * DMA mode + demand mode (8 bytes/request, yes I want it all!)
	 * But leave 16-bit DMA bit untouched!
	 */
	ess_chgmixer (devc, 0x78, 0xd0, 0xd0);

	ess_speed(devc, 2);

	/* bits 4:3 on ES1887 represent recording source. Keep them! */
	bits = ess_getmixer (devc, 0x7a) & 0x18;

	/* Set stereo/mono */
	if (devc->channels != 1) bits |= 0x02;

	/* Init DACs; UNSIGNED mode for 8 bit; SIGNED mode for 16 bit */
	if (devc->bits != AFMT_U8) bits |= 0x05;	/* 16 bit */

	/* Enable DMA, IRQ will be shared (hopefully)*/
	bits |= 0x60;

	ess_setmixer (devc, 0x7a, bits);

	ess_mixer_reload (devc, SOUND_MIXER_PCM);	/* There be sound! */

	devc->trigger_bits = 0;
	return 0;
}

static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
{
	sb_devc *devc = audio_devs[dev]->devc;

#ifdef FKS_REG_LOGGING
printk(KERN_INFO "ess_audio_prepare_for_output: dma_out=%d,dma_in=%d\n"
, audio_devs[dev]->dmap_out->dma, audio_devs[dev]->dmap_in->dma);
#endif

	if (devc->duplex) {
		return ess_audio_prepare_for_output_audio2 (dev, bsize, bcount);
	} else {
		return ess_audio_prepare_for_output_audio1 (dev, bsize, bcount);
	}
}

static void ess_audio_halt_xfer(int dev)
{
	unsigned long flags;
	sb_devc *devc = audio_devs[dev]->devc;

	spin_lock_irqsave(&devc->lock, flags);
	sb_dsp_reset(devc);
	spin_unlock_irqrestore(&devc->lock, flags);

	/*
	 * Audio 2 may still be operational! Creates awful sounds!
	 */
	if (devc->duplex) ess_chgmixer(devc, 0x78, 0x03, 0x00);
}

static void ess_audio_start_input
	(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
	int count = nr_bytes;
	sb_devc *devc = audio_devs[dev]->devc;
	short c = -nr_bytes;

	/*
	 * Start a DMA input to the buffer pointed by dmaqtail
	 */

	if (audio_devs[dev]->dmap_in->dma > 3) count >>= 1;
	count--;

	devc->irq_mode = IMODE_INPUT;

	ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
	ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));

	ess_change (devc, 0xb8, 0x0f, 0x0f);	/* Go */
	devc->intr_active = 1;
}

static void ess_audio_output_block_audio1
	(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
	int count = nr_bytes;
	sb_devc *devc = audio_devs[dev]->devc;
	short c = -nr_bytes;

	if (audio_devs[dev]->dmap_out->dma > 3)
		count >>= 1;
	count--;

	devc->irq_mode = IMODE_OUTPUT;

	ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
	ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));

	ess_change (devc, 0xb8, 0x05, 0x05);	/* Go */
	devc->intr_active = 1;
}

static void ess_audio_output_block_audio2
	(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
	int count = nr_bytes;
	sb_devc *devc = audio_devs[dev]->devc;
	short c = -nr_bytes;

	if (audio_devs[dev]->dmap_out->dma > 3) count >>= 1;
	count--;

	ess_setmixer (devc, 0x74, (unsigned char) ((unsigned short) c & 0xff));
	ess_setmixer (devc, 0x76, (unsigned char) (((unsigned short) c >> 8) & 0xff));
	ess_chgmixer (devc, 0x78, 0x03, 0x03);   /* Go */

	devc->irq_mode_16 = IMODE_OUTPUT;
	devc->intr_active_16 = 1;
}

static void ess_audio_output_block
	(int dev, unsigned long buf, int nr_bytes, int intrflag)
{
	sb_devc *devc = audio_devs[dev]->devc;

	if (devc->duplex) {
		ess_audio_output_block_audio2 (dev, buf, nr_bytes, intrflag);
	} else {
		ess_audio_output_block_audio1 (dev, buf, nr_bytes, intrflag);
	}
}

/*
 * FKS: the if-statements for both bits and bits_16 are quite alike.
 * Combine this...
 */
static void ess_audio_trigger(int dev, int bits)
{
	sb_devc *devc = audio_devs[dev]->devc;

	int bits_16 = bits & devc->irq_mode_16;
	bits &= devc->irq_mode;

	if (!bits && !bits_16) {
		/* FKS oh oh.... wrong?? for dma 16? */
		sb_dsp_command(devc, 0xd0);	/* Halt DMA */
	}

	if (bits) {
		switch (devc->irq_mode)
		{
			case IMODE_INPUT:
				ess_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
					devc->trg_intrflag);
				break;

			case IMODE_OUTPUT:
				ess_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
					devc->trg_intrflag);
				break;
		}
	}

	if (bits_16) {
		switch (devc->irq_mode_16) {
		case IMODE_INPUT:
			ess_audio_start_input(dev, devc->trg_buf_16, devc->trg_bytes_16,
					devc->trg_intrflag_16);
			break;

		case IMODE_OUTPUT:
			ess_audio_output_block(dev, devc->trg_buf_16, devc->trg_bytes_16,
					devc->trg_intrflag_16);
			break;
		}
	}

	devc->trigger_bits = bits | bits_16;
}

static int ess_audio_set_speed(int dev, int speed)
{
	sb_devc *devc = audio_devs[dev]->devc;
	int minspeed, maxspeed, dummydiv;

	if (speed > 0) {
		minspeed = (devc->duplex ? 6215  : 5000 );
		maxspeed = (devc->duplex ? 44100 : 48000);
		if (speed < minspeed) speed = minspeed;
		if (speed > maxspeed) speed = maxspeed;

		ess_common_speed (devc, &speed, &dummydiv);

		devc->speed = speed;
	}
	return devc->speed;
}

/*
 * FKS: This is a one-on-one copy of sb1_audio_set_bits
 */
static unsigned int ess_audio_set_bits(int dev, unsigned int bits)
{
	sb_devc *devc = audio_devs[dev]->devc;

	if (bits != 0) {
		if (bits == AFMT_U8 || bits == AFMT_S16_LE) {
			devc->bits = bits;
		} else {
			devc->bits = AFMT_U8;
		}
	}

	return devc->bits;
}

/*
 * FKS: This is a one-on-one copy of sbpro_audio_set_channels
 * (*) Modified it!!
 */
static short ess_audio_set_channels(int dev, short channels)
{
	sb_devc *devc = audio_devs[dev]->devc;

	if (channels == 1 || channels == 2) devc->channels = channels;

	return devc->channels;
}

static struct audio_driver ess_audio_driver =   /* ESS ES688/1688 */
{
	.owner			= THIS_MODULE,
	.open			= sb_audio_open,
	.close			= sb_audio_close,
	.output_block		= ess_set_output_parms,
	.start_input		= ess_set_input_parms,
	.prepare_for_input	= ess_audio_prepare_for_input,
	.prepare_for_output	= ess_audio_prepare_for_output,
	.halt_io		= ess_audio_halt_xfer,
	.trigger		= ess_audio_trigger,
	.set_speed		= ess_audio_set_speed,
	.set_bits		= ess_audio_set_bits,
	.set_channels		= ess_audio_set_channels
};

/*
 * ess_audio_init must be called from sb_audio_init
 */
struct audio_driver *ess_audio_init
		(sb_devc *devc, int *audio_flags, int *format_mask)
{
	*audio_flags = DMA_AUTOMODE;
	*format_mask |= AFMT_S16_LE;

	if (devc->duplex) {
		int tmp_dma;
		/*
		 * sb_audio_init thinks dma8 is for playback and
		 * dma16 is for record. Not now! So swap them.
		 */
		tmp_dma		= devc->dma16;
		devc->dma16	= devc->dma8;
		devc->dma8	= tmp_dma;

		*audio_flags |= DMA_DUPLEX;
	}

	return &ess_audio_driver;
}

/****************************************************************************
 *																			*
 *								ESS common									*
 *																			*
 ****************************************************************************/
static void ess_handle_channel
	(char *channel, int dev, int intr_active, unsigned char flag, int irq_mode)
{
	if (!intr_active || !flag) return;
#ifdef FKS_REG_LOGGING
printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
#endif
	switch (irq_mode) {
		case IMODE_OUTPUT:
			DMAbuf_outputintr (dev, 1);
			break;

		case IMODE_INPUT:
			DMAbuf_inputintr (dev);
			break;

		case IMODE_INIT:
			break;

		default:;
			/* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */
	}
}

/*
 * FKS: TODO!!! Finish this!
 *
 * I think midi stuff uses uart401, without interrupts.
 * So IMODE_MIDI isn't a value for devc->irq_mode.
 */
void ess_intr (sb_devc *devc)
{
	int				status;
	unsigned char	src;

	if (devc->submodel == SUBMDL_ES1887) {
		src = ess_getmixer (devc, 0x7f) >> 4;
	} else {
		src = 0xff;
	}

#ifdef FKS_REG_LOGGING
printk(KERN_INFO "FKS: sbintr src=%x\n",(int)src);
#endif
	ess_handle_channel
		( "Audio 1"
		, devc->dev, devc->intr_active   , src & 0x01, devc->irq_mode   );
	ess_handle_channel
		( "Audio 2"
		, devc->dev, devc->intr_active_16, src & 0x02, devc->irq_mode_16);
	/*
	 * Acknowledge interrupts
	 */
	if (devc->submodel == SUBMDL_ES1887 && (src & 0x02)) {
		ess_chgmixer (devc, 0x7a, 0x80, 0x00);
	}

	if (src & 0x01) {
		status = inb(DSP_DATA_AVAIL);
	}
}

static void ess_extended (sb_devc * devc)
{
	/* Enable extended mode */

	sb_dsp_command(devc, 0xc6);
}

static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data)
{
#ifdef FKS_REG_LOGGING
printk(KERN_INFO "FKS: write reg %x: %x\n", reg, data);
#endif
	/* Write a byte to an extended mode register of ES1688 */

	if (!sb_dsp_command(devc, reg))
		return 0;

	return sb_dsp_command(devc, data);
}

static int ess_read (sb_devc * devc, unsigned char reg)
{
	/* Read a byte from an extended mode register of ES1688 */

	/* Read register command */
	if (!sb_dsp_command(devc, 0xc0)) return -1;

	if (!sb_dsp_command(devc, reg )) return -1;

	return sb_dsp_get_byte(devc);
}

int ess_dsp_reset(sb_devc * devc)
{
	int loopc;

#ifdef FKS_REG_LOGGING
printk(KERN_INFO "FKS: ess_dsp_reset 1\n");
ess_show_mixerregs (devc);
#endif

	outb(3, DSP_RESET); /* Reset FIFO too */

	udelay(10);
	outb(0, DSP_RESET);
	udelay(30);

	for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);

	if (inb(DSP_READ) != 0xAA) {
		DDB(printk("sb: No response to RESET\n"));
		return 0;   /* Sorry */
	}
	ess_extended (devc);

#ifdef FKS_LOGGING
printk(KERN_INFO "FKS: dsp_reset 2\n");
ess_show_mixerregs (devc);
#endif

	return 1;
}

static int ess_irq_bits (int irq)
{
	switch (irq) {
	case 2:
	case 9:
		return 0;

	case 5:
		return 1;

	case 7:
		return 2;

	case 10:
		return 3;

	default:
		printk(KERN_ERR "ESS1688: Invalid IRQ %d\n", irq);
		return -1;
	}
}

/*
 *	Set IRQ configuration register for all ESS models
 */
static int ess_common_set_irq_hw (sb_devc * devc)
{
	int irq_bits;

	if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return 0;

	if (!ess_write (devc, 0xb1, 0x50 | (irq_bits << 2))) {
		printk(KERN_ERR "ES1688: Failed to write to IRQ config register\n");
		return 0;
	}
	return 1;
}

/*
 * I wanna use modern ES1887 mixer irq handling. Funny is the
 * fact that my BIOS wants the same. But suppose someone's BIOS
 * doesn't do this!
 * This is independent of duplex. If there's a 1887 this will
 * prevent it from going into 1888 mode.
 */
static void ess_es1887_set_irq_hw (sb_devc * devc)
{
	int irq_bits;

	if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return;

	ess_chgmixer (devc, 0x7f, 0x0f, 0x01 | ((irq_bits + 1) << 1));
}

static int ess_set_irq_hw (sb_devc * devc)
{
	if (devc->submodel == SUBMDL_ES1887) ess_es1887_set_irq_hw (devc);

	return ess_common_set_irq_hw (devc);
}

#ifdef FKS_TEST

/*
 * FKS_test:
 *	for ES1887: 00, 18, non wr bits: 0001 1000
 *	for ES1868: 00, b8, non wr bits: 1011 1000
 *	for ES1888: 00, f8, non wr bits: 1111 1000
 *	for ES1688: 00, f8, non wr bits: 1111 1000
 *	+   ES968
 */

static void FKS_test (sb_devc * devc)
{
	int val1, val2;
	val1 = ess_getmixer (devc, 0x64);
	ess_setmixer (devc, 0x64, ~val1);
	val2 = ess_getmixer (devc, 0x64) ^ ~val1;
	ess_setmixer (devc, 0x64, val1);
	val1 ^= ess_getmixer (devc, 0x64);
printk (KERN_INFO "FKS: FKS_test %02x, %02x\n", (val1 & 0x0ff), (val2 & 0x0ff));
};
#endif

static unsigned int ess_identify (sb_devc * devc)
{
	unsigned int val;
	unsigned long flags;

	spin_lock_irqsave(&devc->lock, flags);
	outb(((unsigned char) (0x40 & 0xff)), MIXER_ADDR);

	udelay(20);
	val  = inb(MIXER_DATA) << 8;
	udelay(20);
	val |= inb(MIXER_DATA);
	udelay(20);
	spin_unlock_irqrestore(&devc->lock, flags);

	return val;
}

/*
 * ESS technology describes a detection scheme in their docs. It involves
 * fiddling with the bits in certain mixer registers. ess_probe is supposed
 * to help.
 *
 * FKS: tracing shows ess_probe writes wrong value to 0x64. Bit 3 reads 1, but
 * should be written 0 only. Check this.
 */
static int ess_probe (sb_devc * devc, int reg, int xorval)
{
	int  val1, val2, val3;

	val1 = ess_getmixer (devc, reg);
	val2 = val1 ^ xorval;
	ess_setmixer (devc, reg, val2);
	val3 = ess_getmixer (devc, reg);
	ess_setmixer (devc, reg, val1);

	return (val2 == val3);
}

int ess_init(sb_devc * devc, struct address_info *hw_config)
{
	unsigned char cfg;
	int ess_major = 0, ess_minor = 0;
	int i;
	static char name[100], modelname[10];

	/*
	 * Try to detect ESS chips.
	 */

	sb_dsp_command(devc, 0xe7); /* Return identification */

	for (i = 1000; i; i--) {
		if (inb(DSP_DATA_AVAIL) & 0x80) {
			if (ess_major == 0) {
				ess_major = inb(DSP_READ);
			} else {
				ess_minor = inb(DSP_READ);
				break;
			}
		}
	}

	if (ess_major == 0) return 0;

	if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80) {
		sprintf(name, "ESS ES488 AudioDrive (rev %d)",
			ess_minor & 0x0f);
		hw_config->name = name;
		devc->model = MDL_SBPRO;
		return 1;
	}

	/*
	 * This the detection heuristic of ESS technology, though somewhat
	 * changed to actually make it work.
	 * This results in the following detection steps:
	 * - distinct between ES688 and ES1688+ (as always done in this driver)
	 *   if ES688 we're ready
	 * - try to detect ES1868, ES1869 or ES1878 (ess_identify)
	 *   if successful we're ready
	 * - try to detect ES1888, ES1887 or ES1788 (aim: detect ES1887)
	 *   if successful we're ready
	 * - Dunno. Must be 1688. Will do in general
	 *
	 * This is the most BETA part of the software: Will the detection
	 * always work?
	 */
	devc->model = MDL_ESS;
	devc->submodel = ess_minor & 0x0f;

	if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
		char *chip = NULL;
		int submodel = -1;

		switch (devc->sbmo.esstype) {
		case ESSTYPE_DETECT:
		case ESSTYPE_LIKE20:
			break;
		case 688:
			submodel = 0x00;
			break;
		case 1688:
			submodel = 0x08;
			break;
		case 1868:
			submodel = SUBMDL_ES1868;
			break;
		case 1869:
			submodel = SUBMDL_ES1869;
			break;
		case 1788:
			submodel = SUBMDL_ES1788;
			break;
		case 1878:
			submodel = SUBMDL_ES1878;
			break;
		case 1879:
			submodel = SUBMDL_ES1879;
			break;
		case 1887:
			submodel = SUBMDL_ES1887;
			break;
		case 1888:
			submodel = SUBMDL_ES1888;
			break;
		default:
			printk (KERN_ERR "Invalid esstype=%d specified\n", devc->sbmo.esstype);
			return 0;
		}
		if (submodel != -1) {
			devc->submodel = submodel;
			sprintf (modelname, "ES%d", devc->sbmo.esstype);
			chip = modelname;
		}
		if (chip == NULL && (ess_minor & 0x0f) < 8) {
			chip = "ES688";
		}
#ifdef FKS_TEST
FKS_test (devc);
#endif
		/*
		 * If Nothing detected yet, and we want 2.0 behaviour...
		 * Then let's assume it's ES1688.
		 */
		if (chip == NULL && devc->sbmo.esstype == ESSTYPE_LIKE20) {
			chip = "ES1688";
		}

		if (chip == NULL) {
			int type;

			type = ess_identify (devc);

			switch (type) {
			case 0x1868:
				chip = "ES1868";
				devc->submodel = SUBMDL_ES1868;
				break;
			case 0x1869:
				chip = "ES1869";
				devc->submodel = SUBMDL_ES1869;
				break;
			case 0x1878:
				chip = "ES1878";
				devc->submodel = SUBMDL_ES1878;
				break;
			case 0x1879:
				chip = "ES1879";
				devc->submodel = SUBMDL_ES1879;
				break;
			default:
				if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
					printk ("ess_init: Unrecognized %04x\n", type);
				}
			}
		}
#if 0
		/*
		 * this one failed:
		 * the probing of bit 4 is another thought: from ES1788 and up, all
		 * chips seem to have hardware volume control. Bit 4 is readonly to
		 * check if a hardware volume interrupt has fired.
		 * Cause ES688/ES1688 don't have this feature, bit 4 might be writeable
		 * for these chips.
		 */
		if (chip == NULL && !ess_probe(devc, 0x64, (1 << 4))) {
#endif
		/*
		 * the probing of bit 2 is my idea. The ES1887 docs want me to probe
		 * bit 3. This results in ES1688 being detected as ES1788.
		 * Bit 2 is for "Enable HWV IRQE", but as ES(1)688 chips don't have
		 * HardWare Volume, I think they don't have this IRQE.
		 */
		if (chip == NULL && ess_probe(devc, 0x64, (1 << 2))) {
			if (ess_probe (devc, 0x70, 0x7f)) {
				if (ess_probe (devc, 0x64, (1 << 5))) {
					chip = "ES1887";
					devc->submodel = SUBMDL_ES1887;
				} else {
					chip = "ES1888";
					devc->submodel = SUBMDL_ES1888;
				}
			} else {
				chip = "ES1788";
				devc->submodel = SUBMDL_ES1788;
			}
		}
		if (chip == NULL) {
			chip = "ES1688";
		}

		printk(KERN_INFO "ESS chip %s %s%s\n", chip,
		       (devc->sbmo.esstype == ESSTYPE_DETECT ||
			devc->sbmo.esstype == ESSTYPE_LIKE20) ?
				"detected" : "specified",
			devc->sbmo.esstype == ESSTYPE_LIKE20 ?
				" (kernel 2.0 compatible)" : "");

		sprintf(name,"ESS %s AudioDrive (rev %d)", chip, ess_minor & 0x0f);
	} else {
		strcpy(name, "Jazz16");
	}

	/* AAS: info stolen from ALSA: these boards have different clocks */
	switch(devc->submodel) {
/* APPARENTLY NOT 1869 AND 1887
		case SUBMDL_ES1869:
		case SUBMDL_ES1887:
*/		
		case SUBMDL_ES1888:
			devc->caps |= SB_CAP_ES18XX_RATE;
			break;
	}

	hw_config->name = name;
	/* FKS: sb_dsp_reset to enable extended mode???? */
	sb_dsp_reset(devc); /* Turn on extended mode */

	/*
	 *  Enable joystick and OPL3
	 */
	cfg = ess_getmixer (devc, 0x40);
	ess_setmixer (devc, 0x40, cfg | 0x03);
	if (devc->submodel >= 8) {		/* ES1688 */
		devc->caps |= SB_NO_MIDI;   /* ES1688 uses MPU401 MIDI mode */
	}
	sb_dsp_reset (devc);

	/*
	 * This is important! If it's not done, the IRQ probe in sb_dsp_init
	 * may fail.
	 */
	return ess_set_irq_hw (devc);
}

static int ess_set_dma_hw(sb_devc * devc)
{
	unsigned char cfg, dma_bits = 0, dma16_bits;
	int dma;

#ifdef FKS_LOGGING
printk(KERN_INFO "ess_set_dma_hw: dma8=%d,dma16=%d,dup=%d\n"
, devc->dma8, devc->dma16, devc->duplex);
#endif

	/*
	 * FKS: It seems as if this duplex flag isn't set yet. Check it.
	 */
	dma = devc->dma8;

	if (dma > 3 || dma < 0 || dma == 2) {
		dma_bits = 0;
		printk(KERN_ERR "ESS1688: Invalid DMA8 %d\n", dma);
		return 0;
	} else {
		/* Extended mode DMA enable */
		cfg = 0x50;

		if (dma == 3) {
			dma_bits = 3;
		} else {
			dma_bits = dma + 1;
		}
	}

	if (!ess_write (devc, 0xb2, cfg | (dma_bits << 2))) {
		printk(KERN_ERR "ESS1688: Failed to write to DMA config register\n");
		return 0;
	}

	if (devc->duplex) {
		dma = devc->dma16;
		dma16_bits = 0;

		if (dma >= 0) {
			switch (dma) {
			case 0:
				dma_bits = 0x04;
				break;
			case 1:
				dma_bits = 0x05;
				break;
			case 3:
				dma_bits = 0x06;
				break;
			case 5:
				dma_bits   = 0x07;
				dma16_bits = 0x20;
				break;
			default:
				printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
				return 0;
			}
			ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
			ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
		}
	}
	return 1;
}

/*
 * This one is called from sb_dsp_init.
 *
 * Return values:
 *  0: Failed
 *  1: Succeeded or doesn't apply (not SUBMDL_ES1887)
 */
int ess_dsp_init (sb_devc *devc, struct address_info *hw_config)
{
	/*
	 * Caller also checks this, but anyway
	 */
	if (devc->model != MDL_ESS) {
		printk (KERN_INFO "ess_dsp_init for non ESS chip\n");
		return 1;
	}
	/*
	 * This for ES1887 to run Full Duplex. Actually ES1888
	 * is allowed to do so too. I have no idea yet if this
	 * will work for ES1888 however.
	 *
	 * For SB16 having both dma8 and dma16 means enable
	 * Full Duplex. Let's try this for ES1887 too
	 *
	 */
	if (devc->submodel == SUBMDL_ES1887) {
		if (hw_config->dma2 != -1) {
			devc->dma16 = hw_config->dma2;
		}
		/*
		 * devc->duplex initialization is put here, cause
		 * ess_set_dma_hw needs it.
		 */
		if (devc->dma8 != devc->dma16 && devc->dma16 != -1) {
			devc->duplex = 1;
		}
	}
	if (!ess_set_dma_hw (devc)) {
		free_irq(devc->irq, devc);
		return 0;
	}
	return 1;
}

/****************************************************************************
 *																			*
 *									ESS mixer								*
 *																			*
 ****************************************************************************/

#define ES688_RECORDING_DEVICES	\
			( SOUND_MASK_LINE	| SOUND_MASK_MIC	| SOUND_MASK_CD		)
#define ES688_MIXER_DEVICES		\
			( SOUND_MASK_SYNTH	| SOUND_MASK_PCM	| SOUND_MASK_LINE	\
			| SOUND_MASK_MIC	| SOUND_MASK_CD		| SOUND_MASK_VOLUME	\
			| SOUND_MASK_LINE2	| SOUND_MASK_SPEAKER					)

#define ES1688_RECORDING_DEVICES	\
			( ES688_RECORDING_DEVICES					)
#define ES1688_MIXER_DEVICES		\
			( ES688_MIXER_DEVICES | SOUND_MASK_RECLEV	)

#define ES1887_RECORDING_DEVICES	\
			( ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 | SOUND_MASK_SYNTH)
#define ES1887_MIXER_DEVICES		\
			( ES1688_MIXER_DEVICES											)

/*
 * Mixer registers of ES1887
 *
 * These registers specifically take care of recording levels. To make the
 * mapping from playback devices to recording devices every recording
 * devices = playback device + ES_REC_MIXER_RECDIFF
 */
#define ES_REC_MIXER_RECBASE	(SOUND_MIXER_LINE3 + 1)
#define ES_REC_MIXER_RECDIFF	(ES_REC_MIXER_RECBASE - SOUND_MIXER_SYNTH)

#define ES_REC_MIXER_RECSYNTH	(SOUND_MIXER_SYNTH	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECPCM		(SOUND_MIXER_PCM	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECSPEAKER	(SOUND_MIXER_SPEAKER + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECLINE	(SOUND_MIXER_LINE	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECMIC		(SOUND_MIXER_MIC	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECCD		(SOUND_MIXER_CD		 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECIMIX	(SOUND_MIXER_IMIX	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECALTPCM	(SOUND_MIXER_ALTPCM	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECRECLEV	(SOUND_MIXER_RECLEV	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECIGAIN	(SOUND_MIXER_IGAIN	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECOGAIN	(SOUND_MIXER_OGAIN	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECLINE1	(SOUND_MIXER_LINE1	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECLINE2	(SOUND_MIXER_LINE2	 + ES_REC_MIXER_RECDIFF)
#define ES_REC_MIXER_RECLINE3	(SOUND_MIXER_LINE3	 + ES_REC_MIXER_RECDIFF)

static mixer_tab es688_mix = {
MIX_ENT(SOUND_MIXER_VOLUME,			0x32, 7, 4, 0x32, 3, 4),
MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),
MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),
MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),
MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),
MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),
MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_RECLEV,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),
MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0)
};

/*
 * The ES1688 specifics... hopefully correct...
 * - 6 bit master volume
 *   I was wrong, ES1888 docs say ES1688 didn't have it.
 * - RECLEV control
 * These may apply to ES688 too. I have no idea.
 */
static mixer_tab es1688_mix = {
MIX_ENT(SOUND_MIXER_VOLUME,			0x32, 7, 4, 0x32, 3, 4),
MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),
MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),
MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),
MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),
MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),
MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),
MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),
MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0)
};

static mixer_tab es1688later_mix = {
MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),
MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),
MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),
MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),
MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),
MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),
MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),
MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),
MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0)
};

/*
 * This one is for all ESS chips with a record mixer.
 * It's not used (yet) however
 */
static mixer_tab es_rec_mix = {
MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),
MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),
MIX_ENT(SOUND_MIXER_PCM,			0x14, 7, 4, 0x14, 3, 4),
MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),
MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),
MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),
MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),
MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),
MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECSYNTH,		0x6b, 7, 4, 0x6b, 3, 4),
MIX_ENT(ES_REC_MIXER_RECPCM,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECSPEAKER,	0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECLINE,		0x6e, 7, 4, 0x6e, 3, 4),
MIX_ENT(ES_REC_MIXER_RECMIC,		0x68, 7, 4, 0x68, 3, 4),
MIX_ENT(ES_REC_MIXER_RECCD,			0x6a, 7, 4, 0x6a, 3, 4),
MIX_ENT(ES_REC_MIXER_RECIMIX,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECALTPCM,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECRECLEV,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECIGAIN,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECOGAIN,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECLINE1,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECLINE2,		0x6c, 7, 4, 0x6c, 3, 4),
MIX_ENT(ES_REC_MIXER_RECLINE3,		0x00, 0, 0, 0x00, 0, 0)
};

/*
 * This one is for ES1887. It's little different from es_rec_mix: it
 * has 0x7c for PCM playback level. This is because ES1887 uses
 * Audio 2 for playback.
 */
static mixer_tab es1887_mix = {
MIX_ENT(SOUND_MIXER_VOLUME,			0x60, 5, 6, 0x62, 5, 6),
MIX_ENT(SOUND_MIXER_BASS,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_TREBLE,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_SYNTH,			0x36, 7, 4, 0x36, 3, 4),
MIX_ENT(SOUND_MIXER_PCM,			0x7c, 7, 4, 0x7c, 3, 4),
MIX_ENT(SOUND_MIXER_SPEAKER,		0x3c, 2, 3, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE,			0x3e, 7, 4, 0x3e, 3, 4),
MIX_ENT(SOUND_MIXER_MIC,			0x1a, 7, 4, 0x1a, 3, 4),
MIX_ENT(SOUND_MIXER_CD,				0x38, 7, 4, 0x38, 3, 4),
MIX_ENT(SOUND_MIXER_IMIX,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_ALTPCM,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_RECLEV,			0xb4, 7, 4, 0xb4, 3, 4),
MIX_ENT(SOUND_MIXER_IGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_OGAIN,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE1,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(SOUND_MIXER_LINE2,			0x3a, 7, 4, 0x3a, 3, 4),
MIX_ENT(SOUND_MIXER_LINE3,			0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECSYNTH,		0x6b, 7, 4, 0x6b, 3, 4),
MIX_ENT(ES_REC_MIXER_RECPCM,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECSPEAKER,	0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECLINE,		0x6e, 7, 4, 0x6e, 3, 4),
MIX_ENT(ES_REC_MIXER_RECMIC,		0x68, 7, 4, 0x68, 3, 4),
MIX_ENT(ES_REC_MIXER_RECCD,			0x6a, 7, 4, 0x6a, 3, 4),
MIX_ENT(ES_REC_MIXER_RECIMIX,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECALTPCM,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECRECLEV,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECIGAIN,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECOGAIN,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECLINE1,		0x00, 0, 0, 0x00, 0, 0),
MIX_ENT(ES_REC_MIXER_RECLINE2,		0x6c, 7, 4, 0x6c, 3, 4),
MIX_ENT(ES_REC_MIXER_RECLINE3,		0x00, 0, 0, 0x00, 0, 0)
};

static int ess_has_rec_mixer (int submodel)
{
	switch (submodel) {
	case SUBMDL_ES1887:
		return 1;
	default:
		return 0;
	}
};

#ifdef FKS_LOGGING
static int ess_mixer_mon_regs[]
	= { 0x70, 0x71, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7d, 0x7f
	  , 0xa1, 0xa2, 0xa4, 0xa5, 0xa8, 0xa9
	  , 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb9
	  , 0x00};

static void ess_show_mixerregs (sb_devc *devc)
{
	int *mp = ess_mixer_mon_regs;

return;

	while (*mp != 0) {
		printk (KERN_INFO "res (%x)=%x\n", *mp, (int)(ess_getmixer (devc, *mp)));
		mp++;
	}
}
#endif

void ess_setmixer (sb_devc * devc, unsigned int port, unsigned int value)
{
	unsigned long flags;

#ifdef FKS_LOGGING
printk(KERN_INFO "FKS: write mixer %x: %x\n", port, value);
#endif

	spin_lock_irqsave(&devc->lock, flags);
	if (port >= 0xa0) {
		ess_write (devc, port, value);
	} else {
		outb(((unsigned char) (port & 0xff)), MIXER_ADDR);

		udelay(20);
		outb(((unsigned char) (value & 0xff)), MIXER_DATA);
		udelay(20);
	}
	spin_unlock_irqrestore(&devc->lock, flags);
}

unsigned int ess_getmixer (sb_devc * devc, unsigned int port)
{
	unsigned int val;
	unsigned long flags;

	spin_lock_irqsave(&devc->lock, flags);

	if (port >= 0xa0) {
		val = ess_read (devc, port);
	} else {
		outb(((unsigned char) (port & 0xff)), MIXER_ADDR);

		udelay(20);
		val = inb(MIXER_DATA);
		udelay(20);
	}
	spin_unlock_irqrestore(&devc->lock, flags);

	return val;
}

static void ess_chgmixer
	(sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
{
	int value;

	value = ess_getmixer (devc, reg);
	value = (value & ~mask) | (val & mask);
	ess_setmixer (devc, reg, value);
}

/*
 * ess_mixer_init must be called from sb_mixer_init
 */
void ess_mixer_init (sb_devc * devc)
{
	devc->mixer_caps = SOUND_CAP_EXCL_INPUT;

	/*
	* Take care of ES1887 specifics...
	*/
	switch (devc->submodel) {
	case SUBMDL_ES1887:
		devc->supported_devices		= ES1887_MIXER_DEVICES;
		devc->supported_rec_devices	= ES1887_RECORDING_DEVICES;
#ifdef FKS_LOGGING
printk (KERN_INFO "FKS: ess_mixer_init dup = %d\n", devc->duplex);
#endif
		if (devc->duplex) {
			devc->iomap				= &es1887_mix;
			devc->iomap_sz                          = ARRAY_SIZE(es1887_mix);
		} else {
			devc->iomap				= &es_rec_mix;
			devc->iomap_sz                          = ARRAY_SIZE(es_rec_mix);
		}
		break;
	default:
		if (devc->submodel < 8) {
			devc->supported_devices		= ES688_MIXER_DEVICES;
			devc->supported_rec_devices	= ES688_RECORDING_DEVICES;
			devc->iomap					= &es688_mix;
			devc->iomap_sz                                  = ARRAY_SIZE(es688_mix);
		} else {
			/*
			 * es1688 has 4 bits master vol.
			 * later chips have 6 bits (?)
			 */
			devc->supported_devices		= ES1688_MIXER_DEVICES;
			devc->supported_rec_devices	= ES1688_RECORDING_DEVICES;
			if (devc->submodel < 0x10) {
				devc->iomap				= &es1688_mix;
				devc->iomap_sz                          = ARRAY_SIZE(es688_mix);
			} else {
				devc->iomap				= &es1688later_mix;
				devc->iomap_sz                          = ARRAY_SIZE(es1688later_mix);
			}
		}
	}
}

/*
 * Changing playback levels at an ESS chip with record mixer means having to
 * take care of recording levels of recorded inputs (devc->recmask) too!
 */
int ess_mixer_set(sb_devc *devc, int dev, int left, int right)
{
	if (ess_has_rec_mixer (devc->submodel) && (devc->recmask & (1 << dev))) {
		sb_common_mixer_set (devc, dev + ES_REC_MIXER_RECDIFF, left, right);
	}
	return sb_common_mixer_set (devc, dev, left, right);
}

/*
 * After a sb_dsp_reset extended register 0xb4 (RECLEV) is reset too. After
 * sb_dsp_reset RECLEV has to be restored. This is where ess_mixer_reload
 * helps.
 */
void ess_mixer_reload (sb_devc *devc, int dev)
{
	int left, right, value;

	value = devc->levels[dev];
	left  = value & 0x000000ff;
	right = (value & 0x0000ff00) >> 8;

	sb_common_mixer_set(devc, dev, left, right);
}

static int es_rec_set_recmask(sb_devc * devc, int mask)
{
	int i, i_mask, cur_mask, diff_mask;
	int value, left, right;

#ifdef FKS_LOGGING
printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);
#endif
	/*
	 * Changing the recmask on an ESS chip with recording mixer means:
	 * (1) Find the differences
	 * (2) For "turned-on"  inputs: make the recording level the playback level
	 * (3) For "turned-off" inputs: make the recording level zero
	 */
	cur_mask  = devc->recmask;
	diff_mask = (cur_mask ^ mask);

	for (i = 0; i < 32; i++) {
		i_mask = (1 << i);
		if (diff_mask & i_mask) {	/* Difference? (1)  */
			if (mask & i_mask) {	/* Turn it on  (2)  */
				value = devc->levels[i];
				left  = value & 0x000000ff;
				right = (value & 0x0000ff00) >> 8;
			} else {				/* Turn it off (3)  */
				left  = 0;
				right = 0;
			}
			sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);
		}
	}
	return mask;
}

int ess_set_recmask(sb_devc * devc, int *mask)
{
	/* This applies to ESS chips with record mixers only! */

	if (ess_has_rec_mixer (devc->submodel)) {
		*mask	= es_rec_set_recmask (devc, *mask);
		return 1;									/* Applied		*/
	} else {
		return 0;									/* Not applied	*/
	}
}

/*
 * ess_mixer_reset must be called from sb_mixer_reset
 */
int ess_mixer_reset (sb_devc * devc)
{
	/*
	 * Separate actions for ESS chips with a record mixer:
	 */
	if (ess_has_rec_mixer (devc->submodel)) {
		switch (devc->submodel) {
		case SUBMDL_ES1887:
			/*
			 * Separate actions for ES1887:
			 * Change registers 7a and 1c to make the record mixer the
			 * actual recording source.
			 */
			ess_chgmixer(devc, 0x7a, 0x18, 0x08);
			ess_chgmixer(devc, 0x1c, 0x07, 0x07);
			break;
		}
		/*
		 * Call set_recmask for proper initialization
		 */
		devc->recmask = devc->supported_rec_devices;
		es_rec_set_recmask(devc, 0);
		devc->recmask = 0;

		return 1;	/* We took care of recmask.				*/
	} else {
		return 0;	/* We didn't take care; caller do it	*/
	}
}

/****************************************************************************
 *																			*
 *								ESS midi									*
 *																			*
 ****************************************************************************/

/*
 * FKS: IRQ may be shared. Hm. And if so? Then What?
 */
int ess_midi_init(sb_devc * devc, struct address_info *hw_config)
{
	unsigned char   cfg, tmp;

	cfg = ess_getmixer (devc, 0x40) & 0x03;

	if (devc->submodel < 8) {
		ess_setmixer (devc, 0x40, cfg | 0x03);	/* Enable OPL3 & joystick */
		return 0;  					 /* ES688 doesn't support MPU401 mode */
	}
	tmp = (hw_config->io_base & 0x0f0) >> 4;

	if (tmp > 3) {
		ess_setmixer (devc, 0x40, cfg);
		return 0;
	}
	cfg |= tmp << 3;

	tmp = 1;		/* MPU enabled without interrupts */

	/* May be shared: if so the value is -ve */

	switch (abs(hw_config->irq)) {
		case 9:
			tmp = 0x4;
			break;
		case 5:
			tmp = 0x5;
			break;
		case 7:
			tmp = 0x6;
			break;
		case 10:
			tmp = 0x7;
			break;
		default:
			return 0;
	}

	cfg |= tmp << 5;
	ess_setmixer (devc, 0x40, cfg | 0x03);

	return 1;
}

