#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. Interresting ones are 0x7f, 0x7d and 0x7a. They are
 * related to the Audio 2 channel. I also was suprised about the consequenses
 * 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 decribed
 * 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 allways 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 operation, and uses the
 * same dma as audio 1: your ess changes into a funny echo machine.
 *
 * Received the new 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. It's 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
 * it's 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
 * it's 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. Futhermore several devices can be recorded together (which is not
 * possible with the ES1688.
 * Besides the separate recording level control for each input, the common
 * recordig 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_WARN "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

	DEB(printk("Entered ess_dsp_reset()\n"));

	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);

	DEB(printk("sb_dsp_reset() OK\n"));

#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;
				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;
}

