/*
 * linux/drivers/sound/waveartist.c
 *
 * The low level driver for the RWA010 Rockwell Wave Artist
 * codec chip used in the Rebel.com NetWinder.
 *
 * Cleaned up and integrated into 2.1 by Russell King (rmk@arm.linux.org.uk)
 * and Pat Beirne (patb@corel.ca)
 *
 *
 * Copyright (C) by Rebel.com 1998-1999
 *
 * RWA010 specs received under NDA from Rockwell
 *
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 *
 * Changes:
 * 11-10-2000	Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
 *		Added __init to waveartist_init()
 */

/* Debugging */
#define DEBUG_CMD	1
#define DEBUG_OUT	2
#define DEBUG_IN	4
#define DEBUG_INTR	8
#define DEBUG_MIXER	16
#define DEBUG_TRIGGER	32

#define debug_flg (0)

#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>

#include <asm/system.h>

#include "sound_config.h"
#include "waveartist.h"

#ifdef CONFIG_ARM
#include <asm/hardware.h>
#include <asm/mach-types.h>
#endif

#ifndef NO_DMA
#define NO_DMA	255
#endif

#define SUPPORTED_MIXER_DEVICES		(SOUND_MASK_SYNTH      |\
					 SOUND_MASK_PCM        |\
					 SOUND_MASK_LINE       |\
					 SOUND_MASK_MIC        |\
					 SOUND_MASK_LINE1      |\
					 SOUND_MASK_RECLEV     |\
					 SOUND_MASK_VOLUME     |\
					 SOUND_MASK_IMIX)

static unsigned short levels[SOUND_MIXER_NRDEVICES] = {
	0x5555,		/* Master Volume	 */
	0x0000,		/* Bass			 */
	0x0000,		/* Treble		 */
	0x2323,		/* Synth (FM)		 */
	0x4b4b,		/* PCM			 */
	0x6464,		/* PC Speaker		 */
	0x0000,		/* Ext Line		 */
	0x0000,		/* Mic			 */
	0x0000,		/* CD			 */
	0x6464,		/* Recording monitor	 */
	0x0000,		/* SB PCM (ALT PCM)	 */
	0x0000,		/* Recording level	 */
	0x6464,		/* Input gain		 */
	0x6464,		/* Output gain		 */
	0x0000,		/* Line1 (Aux1)		 */
	0x0000,		/* Line2 (Aux2)		 */
	0x0000,		/* Line3 (Aux3)		 */
	0x0000,		/* Digital1		 */
	0x0000,		/* Digital2		 */
	0x0000,		/* Digital3		 */
	0x0000,		/* Phone In		 */
	0x6464,		/* Phone Out		 */
	0x0000,		/* Video		 */
	0x0000,		/* Radio		 */
	0x0000		/* Monitor		 */
};

typedef struct {
	struct address_info  hw;	/* hardware */
	char		*chip_name;

	int		xfer_count;
	int		audio_mode;
	int		open_mode;
	int		audio_flags;
	int		record_dev;
	int		playback_dev;
	int		dev_no;

	/* Mixer parameters */
	const struct waveartist_mixer_info *mix;

	unsigned short	*levels;	   /* cache of volume settings   */
	int		recmask;	   /* currently enabled recording device! */

#ifdef CONFIG_ARCH_NETWINDER
	signed int	slider_vol;	   /* hardware slider volume     */
	unsigned int	handset_detect	:1;
	unsigned int	telephone_detect:1;
	unsigned int	no_autoselect	:1;/* handset/telephone autoselects a path */
	unsigned int	spkr_mute_state	:1;/* set by ioctl or autoselect */
	unsigned int	line_mute_state	:1;/* set by ioctl or autoselect */
	unsigned int	use_slider	:1;/* use slider setting for o/p vol */
#endif
} wavnc_info;

/*
 * This is the implementation specific mixer information.
 */
struct waveartist_mixer_info {
	unsigned int	supported_devs;	   /* Supported devices */
	unsigned int	recording_devs;	   /* Recordable devies */
	unsigned int	stereo_devs;	   /* Stereo devices	*/

	unsigned int	(*select_input)(wavnc_info *, unsigned int,
					unsigned char *, unsigned char *);
	int		(*decode_mixer)(wavnc_info *, int,
					unsigned char, unsigned char);
	int		(*get_mixer)(wavnc_info *, int);
};

typedef struct wavnc_port_info {
	int		open_mode;
	int		speed;
	int		channels;
	int		audio_format;
} wavnc_port_info;

static int		nr_waveartist_devs;
static wavnc_info	adev_info[MAX_AUDIO_DEV];
static DEFINE_SPINLOCK(waveartist_lock);

#ifndef CONFIG_ARCH_NETWINDER
#define machine_is_netwinder() 0
#else
static struct timer_list vnc_timer;
static void vnc_configure_mixer(wavnc_info *devc, unsigned int input_mask);
static int vnc_private_ioctl(int dev, unsigned int cmd, int __user *arg);
static void vnc_slider_tick(unsigned long data);
#endif

static inline void
waveartist_set_ctlr(struct address_info *hw, unsigned char clear, unsigned char set)
{
	unsigned int ctlr_port = hw->io_base + CTLR;

	clear = ~clear & inb(ctlr_port);

	outb(clear | set, ctlr_port);
}

/* Toggle IRQ acknowledge line
 */
static inline void
waveartist_iack(wavnc_info *devc)
{
	unsigned int ctlr_port = devc->hw.io_base + CTLR;
	int old_ctlr;

	old_ctlr = inb(ctlr_port) & ~IRQ_ACK;

	outb(old_ctlr | IRQ_ACK, ctlr_port);
	outb(old_ctlr, ctlr_port);
}

static inline int
waveartist_sleep(int timeout_ms)
{
	unsigned int timeout = timeout_ms * 10 * HZ / 100;

	do {
		set_current_state(TASK_INTERRUPTIBLE);
		timeout = schedule_timeout(timeout);
	} while (timeout);

	return 0;
}

static int
waveartist_reset(wavnc_info *devc)
{
	struct address_info *hw = &devc->hw;
	unsigned int timeout, res = -1;

	waveartist_set_ctlr(hw, -1, RESET);
	waveartist_sleep(2);
	waveartist_set_ctlr(hw, RESET, 0);

	timeout = 500;
	do {
		mdelay(2);

		if (inb(hw->io_base + STATR) & CMD_RF) {
			res = inw(hw->io_base + CMDR);
			if (res == 0x55aa)
				break;
		}
	} while (--timeout);

	if (timeout == 0) {
		printk(KERN_WARNING "WaveArtist: reset timeout ");
		if (res != (unsigned int)-1)
			printk("(res=%04X)", res);
		printk("\n");
		return 1;
	}
	return 0;
}

/* Helper function to send and receive words
 * from WaveArtist.  It handles all the handshaking
 * and can send or receive multiple words.
 */
static int
waveartist_cmd(wavnc_info *devc,
		int nr_cmd, unsigned int *cmd,
		int nr_resp, unsigned int *resp)
{
	unsigned int io_base = devc->hw.io_base;
	unsigned int timed_out = 0;
	unsigned int i;

	if (debug_flg & DEBUG_CMD) {
		printk("waveartist_cmd: cmd=");

		for (i = 0; i < nr_cmd; i++)
			printk("%04X ", cmd[i]);

		printk("\n");
	}

	if (inb(io_base + STATR) & CMD_RF) {
		int old_data;

		/* flush the port
		 */

		old_data = inw(io_base + CMDR);

		if (debug_flg & DEBUG_CMD)
			printk("flushed %04X...", old_data);

		udelay(10);
	}

	for (i = 0; !timed_out && i < nr_cmd; i++) {
		int count;

		for (count = 5000; count; count--)
			if (inb(io_base + STATR) & CMD_WE)
				break;

		if (!count)
			timed_out = 1;
		else
			outw(cmd[i], io_base + CMDR);
	}

	for (i = 0; !timed_out && i < nr_resp; i++) {
		int count;

		for (count = 5000; count; count--)
			if (inb(io_base + STATR) & CMD_RF)
				break;

		if (!count)
			timed_out = 1;
		else
			resp[i] = inw(io_base + CMDR);
	}

	if (debug_flg & DEBUG_CMD) {
		if (!timed_out) {
			printk("waveartist_cmd: resp=");

			for (i = 0; i < nr_resp; i++)
				printk("%04X ", resp[i]);

			printk("\n");
		} else
			printk("waveartist_cmd: timed out\n");
	}

	return timed_out ? 1 : 0;
}

/*
 * Send one command word
 */
static inline int
waveartist_cmd1(wavnc_info *devc, unsigned int cmd)
{
	return waveartist_cmd(devc, 1, &cmd, 0, NULL);
}

/*
 * Send one command, receive one word
 */
static inline unsigned int
waveartist_cmd1_r(wavnc_info *devc, unsigned int cmd)
{
	unsigned int ret;

	waveartist_cmd(devc, 1, &cmd, 1, &ret);

	return ret;
}

/*
 * Send a double command, receive one
 * word (and throw it away)
 */
static inline int
waveartist_cmd2(wavnc_info *devc, unsigned int cmd, unsigned int arg)
{
	unsigned int vals[2];

	vals[0] = cmd;
	vals[1] = arg;

	return waveartist_cmd(devc, 2, vals, 1, vals);
}

/*
 * Send a triple command
 */
static inline int
waveartist_cmd3(wavnc_info *devc, unsigned int cmd,
		unsigned int arg1, unsigned int arg2)
{
	unsigned int vals[3];

	vals[0] = cmd;
	vals[1] = arg1;
	vals[2] = arg2;

	return waveartist_cmd(devc, 3, vals, 0, NULL);
}

static int
waveartist_getrev(wavnc_info *devc, char *rev)
{
	unsigned int temp[2];
	unsigned int cmd = WACMD_GETREV;

	waveartist_cmd(devc, 1, &cmd, 2, temp);

	rev[0] = temp[0] >> 8;
	rev[1] = temp[0] & 255;
	rev[2] = '\0';

	return temp[0];
}

static void waveartist_halt_output(int dev);
static void waveartist_halt_input(int dev);
static void waveartist_halt(int dev);
static void waveartist_trigger(int dev, int state);

static int
waveartist_open(int dev, int mode)
{
	wavnc_info	*devc;
	wavnc_port_info	*portc;
	unsigned long	flags;

	if (dev < 0 || dev >= num_audiodevs)
		return -ENXIO;

	devc  = (wavnc_info *) audio_devs[dev]->devc;
	portc = (wavnc_port_info *) audio_devs[dev]->portc;

	spin_lock_irqsave(&waveartist_lock, flags);
	if (portc->open_mode || (devc->open_mode & mode)) {
		spin_unlock_irqrestore(&waveartist_lock, flags);
		return -EBUSY;
	}

	devc->audio_mode  = 0;
	devc->open_mode  |= mode;
	portc->open_mode  = mode;
	waveartist_trigger(dev, 0);

	if (mode & OPEN_READ)
		devc->record_dev = dev;
	if (mode & OPEN_WRITE)
		devc->playback_dev = dev;
	spin_unlock_irqrestore(&waveartist_lock, flags);

	return 0;
}

static void
waveartist_close(int dev)
{
	wavnc_info	*devc = (wavnc_info *) audio_devs[dev]->devc;
	wavnc_port_info	*portc = (wavnc_port_info *) audio_devs[dev]->portc;
	unsigned long	flags;

	spin_lock_irqsave(&waveartist_lock, flags);

	waveartist_halt(dev);

	devc->audio_mode = 0;
	devc->open_mode &= ~portc->open_mode;
	portc->open_mode = 0;

	spin_unlock_irqrestore(&waveartist_lock, flags);
}

static void
waveartist_output_block(int dev, unsigned long buf, int __count, int intrflag)
{
	wavnc_port_info	*portc = (wavnc_port_info *) audio_devs[dev]->portc;
	wavnc_info	*devc = (wavnc_info *) audio_devs[dev]->devc;
	unsigned long	flags;
	unsigned int	count = __count; 

	if (debug_flg & DEBUG_OUT)
		printk("waveartist: output block, buf=0x%lx, count=0x%x...\n",
			buf, count);
	/*
	 * 16 bit data
	 */
	if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))
		count >>= 1;

	if (portc->channels > 1)
		count >>= 1;

	count -= 1;

	if (devc->audio_mode & PCM_ENABLE_OUTPUT &&
	    audio_devs[dev]->flags & DMA_AUTOMODE &&
	    intrflag &&
	    count == devc->xfer_count) {
		devc->audio_mode |= PCM_ENABLE_OUTPUT;
		return;	/*
			 * Auto DMA mode on. No need to react
			 */
	}

	spin_lock_irqsave(&waveartist_lock, flags);

	/*
	 * set sample count
	 */
	waveartist_cmd2(devc, WACMD_OUTPUTSIZE, count);

	devc->xfer_count = count;
	devc->audio_mode |= PCM_ENABLE_OUTPUT;

	spin_unlock_irqrestore(&waveartist_lock, flags);
}

static void
waveartist_start_input(int dev, unsigned long buf, int __count, int intrflag)
{
	wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
	wavnc_info	*devc = (wavnc_info *) audio_devs[dev]->devc;
	unsigned long	flags;
	unsigned int	count = __count;

	if (debug_flg & DEBUG_IN)
		printk("waveartist: start input, buf=0x%lx, count=0x%x...\n",
			buf, count);

	if (portc->audio_format & (AFMT_S16_LE | AFMT_S16_BE))	/* 16 bit data */
		count >>= 1;

	if (portc->channels > 1)
		count >>= 1;

	count -= 1;

	if (devc->audio_mode & PCM_ENABLE_INPUT &&
	    audio_devs[dev]->flags & DMA_AUTOMODE &&
	    intrflag &&
	    count == devc->xfer_count) {
		devc->audio_mode |= PCM_ENABLE_INPUT;
		return;	/*
			 * Auto DMA mode on. No need to react
			 */
	}

	spin_lock_irqsave(&waveartist_lock, flags);

	/*
	 * set sample count
	 */
	waveartist_cmd2(devc, WACMD_INPUTSIZE, count);

	devc->xfer_count = count;
	devc->audio_mode |= PCM_ENABLE_INPUT;

	spin_unlock_irqrestore(&waveartist_lock, flags);
}

static int
waveartist_ioctl(int dev, unsigned int cmd, void __user * arg)
{
	return -EINVAL;
}

static unsigned int
waveartist_get_speed(wavnc_port_info *portc)
{
	unsigned int speed;

	/*
	 * program the speed, channels, bits
	 */
	if (portc->speed == 8000)
		speed = 0x2E71;
	else if (portc->speed == 11025)
		speed = 0x4000;
	else if (portc->speed == 22050)
		speed = 0x8000;
	else if (portc->speed == 44100)
		speed = 0x0;
	else {
		/*
		 * non-standard - just calculate
		 */
		speed = portc->speed << 16;

		speed = (speed / 44100) & 65535;
	}

	return speed;
}

static unsigned int
waveartist_get_bits(wavnc_port_info *portc)
{
	unsigned int bits;

	if (portc->audio_format == AFMT_S16_LE)
		bits = 1;
	else if (portc->audio_format == AFMT_S8)
		bits = 0;
	else
		bits = 2;	//default AFMT_U8

	return bits;
}

static int
waveartist_prepare_for_input(int dev, int bsize, int bcount)
{
	unsigned long	flags;
	wavnc_info	*devc = (wavnc_info *) audio_devs[dev]->devc;
	wavnc_port_info	*portc = (wavnc_port_info *) audio_devs[dev]->portc;
	unsigned int	speed, bits;

	if (devc->audio_mode)
		return 0;

	speed = waveartist_get_speed(portc);
	bits  = waveartist_get_bits(portc);

	spin_lock_irqsave(&waveartist_lock, flags);

	if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
		printk(KERN_WARNING "waveartist: error setting the "
		       "record format to %d\n", portc->audio_format);

	if (waveartist_cmd2(devc, WACMD_INPUTCHANNELS, portc->channels))
		printk(KERN_WARNING "waveartist: error setting record "
		       "to %d channels\n", portc->channels);

	/*
	 * write cmd SetSampleSpeedTimeConstant
	 */
	if (waveartist_cmd2(devc, WACMD_INPUTSPEED, speed))
		printk(KERN_WARNING "waveartist: error setting the record "
		       "speed to %dHz.\n", portc->speed);

	if (waveartist_cmd2(devc, WACMD_INPUTDMA, 1))
		printk(KERN_WARNING "waveartist: error setting the record "
		       "data path to 0x%X\n", 1);

	if (waveartist_cmd2(devc, WACMD_INPUTFORMAT, bits))
		printk(KERN_WARNING "waveartist: error setting the record "
		       "format to %d\n", portc->audio_format);

	devc->xfer_count = 0;
	spin_unlock_irqrestore(&waveartist_lock, flags);
	waveartist_halt_input(dev);

	if (debug_flg & DEBUG_INTR) {
		printk("WA CTLR reg: 0x%02X.\n",
		       inb(devc->hw.io_base + CTLR));
		printk("WA STAT reg: 0x%02X.\n",
		       inb(devc->hw.io_base + STATR));
		printk("WA IRQS reg: 0x%02X.\n",
		       inb(devc->hw.io_base + IRQSTAT));
	}

	return 0;
}

static int
waveartist_prepare_for_output(int dev, int bsize, int bcount)
{
	unsigned long	flags;
	wavnc_info	*devc = (wavnc_info *) audio_devs[dev]->devc;
	wavnc_port_info	*portc = (wavnc_port_info *) audio_devs[dev]->portc;
	unsigned int	speed, bits;

	/*
	 * program the speed, channels, bits
	 */
	speed = waveartist_get_speed(portc);
	bits  = waveartist_get_bits(portc);

	spin_lock_irqsave(&waveartist_lock, flags);

	if (waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed) &&
	    waveartist_cmd2(devc, WACMD_OUTPUTSPEED, speed))
		printk(KERN_WARNING "waveartist: error setting the playback "
		       "speed to %dHz.\n", portc->speed);

	if (waveartist_cmd2(devc, WACMD_OUTPUTCHANNELS, portc->channels))
		printk(KERN_WARNING "waveartist: error setting the playback "
		       "to %d channels\n", portc->channels);

	if (waveartist_cmd2(devc, WACMD_OUTPUTDMA, 0))
		printk(KERN_WARNING "waveartist: error setting the playback "
		       "data path to 0x%X\n", 0);

	if (waveartist_cmd2(devc, WACMD_OUTPUTFORMAT, bits))
		printk(KERN_WARNING "waveartist: error setting the playback "
		       "format to %d\n", portc->audio_format);

	devc->xfer_count = 0;
	spin_unlock_irqrestore(&waveartist_lock, flags);
	waveartist_halt_output(dev);

	if (debug_flg & DEBUG_INTR) {
		printk("WA CTLR reg: 0x%02X.\n",inb(devc->hw.io_base + CTLR));
		printk("WA STAT reg: 0x%02X.\n",inb(devc->hw.io_base + STATR));
		printk("WA IRQS reg: 0x%02X.\n",inb(devc->hw.io_base + IRQSTAT));
	}

	return 0;
}

static void
waveartist_halt(int dev)
{
	wavnc_port_info	*portc = (wavnc_port_info *) audio_devs[dev]->portc;
	wavnc_info	*devc;

	if (portc->open_mode & OPEN_WRITE)
		waveartist_halt_output(dev);

	if (portc->open_mode & OPEN_READ)
		waveartist_halt_input(dev);

	devc = (wavnc_info *) audio_devs[dev]->devc;
	devc->audio_mode = 0;
}

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

	spin_lock_irqsave(&waveartist_lock, flags);

	/*
	 * Stop capture
	 */
	waveartist_cmd1(devc, WACMD_INPUTSTOP);

	devc->audio_mode &= ~PCM_ENABLE_INPUT;

	/*
	 * Clear interrupt by toggling
	 * the IRQ_ACK bit in CTRL
	 */
	if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
		waveartist_iack(devc);

//	devc->audio_mode &= ~PCM_ENABLE_INPUT;

	spin_unlock_irqrestore(&waveartist_lock, flags);
}

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

	spin_lock_irqsave(&waveartist_lock, flags);

	waveartist_cmd1(devc, WACMD_OUTPUTSTOP);

	devc->audio_mode &= ~PCM_ENABLE_OUTPUT;

	/*
	 * Clear interrupt by toggling
	 * the IRQ_ACK bit in CTRL
	 */
	if (inb(devc->hw.io_base + STATR) & IRQ_REQ)
		waveartist_iack(devc);

//	devc->audio_mode &= ~PCM_ENABLE_OUTPUT;

	spin_unlock_irqrestore(&waveartist_lock, flags);
}

static void
waveartist_trigger(int dev, int state)
{
	wavnc_info	*devc = (wavnc_info *) audio_devs[dev]->devc;
	wavnc_port_info	*portc = (wavnc_port_info *) audio_devs[dev]->portc;
	unsigned long	flags;

	if (debug_flg & DEBUG_TRIGGER) {
		printk("wavnc: audio trigger ");
		if (state & PCM_ENABLE_INPUT)
			printk("in ");
		if (state & PCM_ENABLE_OUTPUT)
			printk("out");
		printk("\n");
	}

	spin_lock_irqsave(&waveartist_lock, flags);

	state &= devc->audio_mode;

	if (portc->open_mode & OPEN_READ &&
	    state & PCM_ENABLE_INPUT)
		/*
		 * enable ADC Data Transfer to PC
		 */
		waveartist_cmd1(devc, WACMD_INPUTSTART);

	if (portc->open_mode & OPEN_WRITE &&
	    state & PCM_ENABLE_OUTPUT)
		/*
		 * enable DAC data transfer from PC
		 */
		waveartist_cmd1(devc, WACMD_OUTPUTSTART);

	spin_unlock_irqrestore(&waveartist_lock, flags);
}

static int
waveartist_set_speed(int dev, int arg)
{
	wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;

	if (arg <= 0)
		return portc->speed;

	if (arg < 5000)
		arg = 5000;
	if (arg > 44100)
		arg = 44100;

	portc->speed = arg;
	return portc->speed;

}

static short
waveartist_set_channels(int dev, short arg)
{
	wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;

	if (arg != 1 && arg != 2)
		return portc->channels;

	portc->channels = arg;
	return arg;
}

static unsigned int
waveartist_set_bits(int dev, unsigned int arg)
{
	wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;

	if (arg == 0)
		return portc->audio_format;

	if ((arg != AFMT_U8) && (arg != AFMT_S16_LE) && (arg != AFMT_S8))
		arg = AFMT_U8;

	portc->audio_format = arg;

	return arg;
}

static struct audio_driver waveartist_audio_driver = {
	.owner			= THIS_MODULE,
	.open			= waveartist_open,
	.close			= waveartist_close,
	.output_block		= waveartist_output_block,
	.start_input		= waveartist_start_input,
	.ioctl			= waveartist_ioctl,
	.prepare_for_input	= waveartist_prepare_for_input,
	.prepare_for_output	= waveartist_prepare_for_output,
	.halt_io		= waveartist_halt,
	.halt_input		= waveartist_halt_input,
	.halt_output		= waveartist_halt_output,
	.trigger		= waveartist_trigger,
	.set_speed		= waveartist_set_speed,
	.set_bits		= waveartist_set_bits,
	.set_channels		= waveartist_set_channels
};


static irqreturn_t
waveartist_intr(int irq, void *dev_id, struct pt_regs *regs)
{
	wavnc_info *devc = (wavnc_info *)dev_id;
	int	   irqstatus, status;

	spin_lock(&waveartist_lock);
	irqstatus = inb(devc->hw.io_base + IRQSTAT);
	status    = inb(devc->hw.io_base + STATR);

	if (debug_flg & DEBUG_INTR)
		printk("waveartist_intr: stat=%02x, irqstat=%02x\n",
		       status, irqstatus);

	if (status & IRQ_REQ)	/* Clear interrupt */
		waveartist_iack(devc);
	else
		printk(KERN_WARNING "waveartist: unexpected interrupt\n");

	if (irqstatus & 0x01) {
		int temp = 1;

		/* PCM buffer done
		 */
		if ((status & DMA0) && (devc->audio_mode & PCM_ENABLE_OUTPUT)) {
			DMAbuf_outputintr(devc->playback_dev, 1);
			temp = 0;
		}
		if ((status & DMA1) && (devc->audio_mode & PCM_ENABLE_INPUT)) {
			DMAbuf_inputintr(devc->record_dev);
			temp = 0;
		}
		if (temp)	//default:
			printk(KERN_WARNING "waveartist: Unknown interrupt\n");
	}
	if (irqstatus & 0x2)
		// We do not use SB mode natively...
		printk(KERN_WARNING "waveartist: Unexpected SB interrupt...\n");
	spin_unlock(&waveartist_lock);
	return IRQ_HANDLED;
}

/* -------------------------------------------------------------------------
 * Mixer stuff
 */
struct mix_ent {
	unsigned char	reg_l;
	unsigned char	reg_r;
	unsigned char	shift;
	unsigned char	max;
};

static const struct mix_ent mix_devs[SOUND_MIXER_NRDEVICES] = {
	{ 2, 6, 1,  7 }, /* SOUND_MIXER_VOLUME   */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_BASS     */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_TREBLE   */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_SYNTH    */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_PCM      */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_SPEAKER  */
	{ 0, 4, 6, 31 }, /* SOUND_MIXER_LINE     */
	{ 2, 6, 4,  3 }, /* SOUND_MIXER_MIC      */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_CD       */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_IMIX     */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_ALTPCM   */
#if 0
	{ 3, 7, 0, 10 }, /* SOUND_MIXER_RECLEV   */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_IGAIN    */
#else
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_RECLEV   */
	{ 3, 7, 0,  7 }, /* SOUND_MIXER_IGAIN    */
#endif
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_OGAIN    */
	{ 0, 4, 1, 31 }, /* SOUND_MIXER_LINE1    */
	{ 1, 5, 6, 31 }, /* SOUND_MIXER_LINE2    */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_LINE3    */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_DIGITAL1 */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_DIGITAL2 */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_DIGITAL3 */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_PHONEIN  */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_PHONEOUT */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_VIDEO    */
	{ 0, 0, 0,  0 }, /* SOUND_MIXER_RADIO    */
	{ 0, 0, 0,  0 }  /* SOUND_MIXER_MONITOR  */
};

static void
waveartist_mixer_update(wavnc_info *devc, int whichDev)
{
	unsigned int lev_left, lev_right;

	lev_left  = devc->levels[whichDev] & 0xff;
	lev_right = devc->levels[whichDev] >> 8;

	if (lev_left > 100)
		lev_left = 100;
	if (lev_right > 100)
		lev_right = 100;

#define SCALE(lev,max)	((lev) * (max) / 100)

	if (machine_is_netwinder() && whichDev == SOUND_MIXER_PHONEOUT)
		whichDev = SOUND_MIXER_VOLUME;

	if (mix_devs[whichDev].reg_l || mix_devs[whichDev].reg_r) {
		const struct mix_ent *mix = mix_devs + whichDev;
		unsigned int mask, left, right;

		mask = mix->max << mix->shift;
		lev_left  = SCALE(lev_left,  mix->max) << mix->shift;
		lev_right = SCALE(lev_right, mix->max) << mix->shift;

		/* read left setting */
		left  = waveartist_cmd1_r(devc, WACMD_GET_LEVEL |
					       mix->reg_l << 8);

		/* read right setting */
		right = waveartist_cmd1_r(devc, WACMD_GET_LEVEL |
						mix->reg_r << 8);

		left  = (left  & ~mask) | (lev_left  & mask);
		right = (right & ~mask) | (lev_right & mask);

		/* write left,right back */
		waveartist_cmd3(devc, WACMD_SET_MIXER, left, right);
	} else {
		switch(whichDev) {
		case SOUND_MIXER_PCM:
			waveartist_cmd3(devc, WACMD_SET_LEVEL,
					SCALE(lev_left,  32767),
					SCALE(lev_right, 32767));
			break;

		case SOUND_MIXER_SYNTH:
			waveartist_cmd3(devc, 0x0100 | WACMD_SET_LEVEL,
					SCALE(lev_left,  32767),
					SCALE(lev_right, 32767));
			break;
		}
	}
}

/*
 * Set the ADC MUX to the specified values.  We do NOT do any
 * checking of the values passed, since we assume that the
 * relevant *_select_input function has done that for us.
 */
static void
waveartist_set_adc_mux(wavnc_info *devc, char left_dev, char right_dev)
{
	unsigned int reg_08, reg_09;

	reg_08 = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x0800);
	reg_09 = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x0900);

	reg_08 = (reg_08 & ~0x3f) | right_dev << 3 | left_dev;

	waveartist_cmd3(devc, WACMD_SET_MIXER, reg_08, reg_09);
}

/*
 * Decode a recording mask into a mixer selection as follows:
 *
 *     OSS Source	WA Source	Actual source
 *  SOUND_MASK_IMIX	Mixer		Mixer output (same as AD1848)
 *  SOUND_MASK_LINE	Line		Line in
 *  SOUND_MASK_LINE1	Aux 1		Aux 1 in
 *  SOUND_MASK_LINE2	Aux 2		Aux 2 in
 *  SOUND_MASK_MIC	Mic		Microphone
 */
static unsigned int
waveartist_select_input(wavnc_info *devc, unsigned int recmask,
			unsigned char *dev_l, unsigned char *dev_r)
{
	unsigned int recdev = ADC_MUX_NONE;

	if (recmask & SOUND_MASK_IMIX) {
		recmask = SOUND_MASK_IMIX;
		recdev = ADC_MUX_MIXER;
	} else if (recmask & SOUND_MASK_LINE2) {
		recmask = SOUND_MASK_LINE2;
		recdev = ADC_MUX_AUX2;
	} else if (recmask & SOUND_MASK_LINE1) {
		recmask = SOUND_MASK_LINE1;
		recdev = ADC_MUX_AUX1;
	} else if (recmask & SOUND_MASK_LINE) {
		recmask = SOUND_MASK_LINE;
		recdev = ADC_MUX_LINE;
	} else if (recmask & SOUND_MASK_MIC) {
		recmask = SOUND_MASK_MIC;
		recdev = ADC_MUX_MIC;
	}

	*dev_l = *dev_r = recdev;

	return recmask;
}

static int
waveartist_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l,
			unsigned char lev_r)
{
	switch (dev) {
	case SOUND_MIXER_VOLUME:
	case SOUND_MIXER_SYNTH:
	case SOUND_MIXER_PCM:
	case SOUND_MIXER_LINE:
	case SOUND_MIXER_MIC:
	case SOUND_MIXER_IGAIN:
	case SOUND_MIXER_LINE1:
	case SOUND_MIXER_LINE2:
		devc->levels[dev] = lev_l | lev_r << 8;
		break;

	case SOUND_MIXER_IMIX:
		break;

	default:
		dev = -EINVAL;
		break;
	}

	return dev;
}

static int waveartist_get_mixer(wavnc_info *devc, int dev)
{
	return devc->levels[dev];
}

static const struct waveartist_mixer_info waveartist_mixer = {
	.supported_devs	= SUPPORTED_MIXER_DEVICES | SOUND_MASK_IGAIN,
	.recording_devs	= SOUND_MASK_LINE  | SOUND_MASK_MIC   |
			SOUND_MASK_LINE1 | SOUND_MASK_LINE2 |
			SOUND_MASK_IMIX,
	.stereo_devs	= (SUPPORTED_MIXER_DEVICES | SOUND_MASK_IGAIN) & ~
			(SOUND_MASK_SPEAKER | SOUND_MASK_IMIX),
	.select_input	= waveartist_select_input,
	.decode_mixer	= waveartist_decode_mixer,
	.get_mixer	= waveartist_get_mixer,
};

static void
waveartist_set_recmask(wavnc_info *devc, unsigned int recmask)
{
	unsigned char dev_l, dev_r;

	recmask &= devc->mix->recording_devs;

	/*
	 * If more than one recording device selected,
	 * disable the device that is currently in use.
	 */
	if (hweight32(recmask) > 1)
		recmask &= ~devc->recmask;

	/*
	 * Translate the recording device mask into
	 * the ADC multiplexer settings.
	 */
	devc->recmask = devc->mix->select_input(devc, recmask,
						&dev_l, &dev_r);

	waveartist_set_adc_mux(devc, dev_l, dev_r);
}

static int
waveartist_set_mixer(wavnc_info *devc, int dev, unsigned int level)
{
	unsigned int lev_left  = level & 0x00ff;
	unsigned int lev_right = (level & 0xff00) >> 8;

	if (lev_left > 100)
		lev_left = 100;
	if (lev_right > 100)
		lev_right = 100;

	/*
	 * Mono devices have their right volume forced to their
	 * left volume.  (from ALSA driver OSS emulation).
	 */
	if (!(devc->mix->stereo_devs & (1 << dev)))
		lev_right = lev_left;

	dev = devc->mix->decode_mixer(devc, dev, lev_left, lev_right);

	if (dev >= 0)
		waveartist_mixer_update(devc, dev);

	return dev < 0 ? dev : 0;
}

static int
waveartist_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
{
	wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
	int ret = 0, val, nr;

	/*
	 * All SOUND_MIXER_* ioctls use type 'M'
	 */
	if (((cmd >> 8) & 255) != 'M')
		return -ENOIOCTLCMD;

#ifdef CONFIG_ARCH_NETWINDER
	if (machine_is_netwinder()) {
		ret = vnc_private_ioctl(dev, cmd, arg);
		if (ret != -ENOIOCTLCMD)
			return ret;
		else
			ret = 0;
	}
#endif

	nr = cmd & 0xff;

	if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
		if (get_user(val, (int __user *)arg))
			return -EFAULT;

		switch (nr) {
		case SOUND_MIXER_RECSRC:
			waveartist_set_recmask(devc, val);
			break;

		default:
			ret = -EINVAL;
			if (nr < SOUND_MIXER_NRDEVICES &&
			    devc->mix->supported_devs & (1 << nr))
				ret = waveartist_set_mixer(devc, nr, val);
		}
	}

	if (ret == 0 && _SIOC_DIR(cmd) & _SIOC_READ) {
		ret = -EINVAL;

		switch (nr) {
		case SOUND_MIXER_RECSRC:
			ret = devc->recmask;
			break;

		case SOUND_MIXER_DEVMASK:
			ret = devc->mix->supported_devs;
			break;

		case SOUND_MIXER_STEREODEVS:
			ret = devc->mix->stereo_devs;
			break;

		case SOUND_MIXER_RECMASK:
			ret = devc->mix->recording_devs;
			break;

		case SOUND_MIXER_CAPS:
			ret = SOUND_CAP_EXCL_INPUT;
			break;

		default:
			if (nr < SOUND_MIXER_NRDEVICES)
				ret = devc->mix->get_mixer(devc, nr);
			break;
		}

		if (ret >= 0)
			ret = put_user(ret, (int __user *)arg) ? -EFAULT : 0;
	}

	return ret;
}

static struct mixer_operations waveartist_mixer_operations =
{
	.owner	= THIS_MODULE,
	.id	= "WaveArtist",
	.name	= "WaveArtist",
	.ioctl	= waveartist_mixer_ioctl
};

static void
waveartist_mixer_reset(wavnc_info *devc)
{
	int i;

	if (debug_flg & DEBUG_MIXER)
		printk("%s: mixer_reset\n", devc->hw.name);

	/*
	 * reset mixer cmd
	 */
	waveartist_cmd1(devc, WACMD_RST_MIXER);

	/*
	 * set input for ADC to come from 'quiet'
	 * turn on default modes
	 */
	waveartist_cmd3(devc, WACMD_SET_MIXER, 0x9800, 0xa836);

	/*
	 * set mixer input select to none, RX filter gains 0 dB
	 */
	waveartist_cmd3(devc, WACMD_SET_MIXER, 0x4c00, 0x8c00);

	/*
	 * set bit 0 reg 2 to 1 - unmute MonoOut
	 */
	waveartist_cmd3(devc, WACMD_SET_MIXER, 0x2801, 0x6800);

	/* set default input device = internal mic
	 * current recording device = none
	 */
	waveartist_set_recmask(devc, 0);

	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
		waveartist_mixer_update(devc, i);
}

static int __init waveartist_init(wavnc_info *devc)
{
	wavnc_port_info *portc;
	char rev[3], dev_name[64];
	int my_dev;

	if (waveartist_reset(devc))
		return -ENODEV;

	sprintf(dev_name, "%s (%s", devc->hw.name, devc->chip_name);

	if (waveartist_getrev(devc, rev)) {
		strcat(dev_name, " rev. ");
		strcat(dev_name, rev);
	}
	strcat(dev_name, ")");

	conf_printf2(dev_name, devc->hw.io_base, devc->hw.irq,
		     devc->hw.dma, devc->hw.dma2);

	portc = (wavnc_port_info *)kmalloc(sizeof(wavnc_port_info), GFP_KERNEL);
	if (portc == NULL)
		goto nomem;

	memset(portc, 0, sizeof(wavnc_port_info));

	my_dev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, dev_name,
			&waveartist_audio_driver, sizeof(struct audio_driver),
			devc->audio_flags, AFMT_U8 | AFMT_S16_LE | AFMT_S8,
			devc, devc->hw.dma, devc->hw.dma2);

	if (my_dev < 0)
		goto free;

	audio_devs[my_dev]->portc = portc;

	waveartist_mixer_reset(devc);

	/*
	 * clear any pending interrupt
	 */
	waveartist_iack(devc);

	if (request_irq(devc->hw.irq, waveartist_intr, 0, devc->hw.name, devc) < 0) {
		printk(KERN_ERR "%s: IRQ %d in use\n",
			devc->hw.name, devc->hw.irq);
		goto uninstall;
	}

	if (sound_alloc_dma(devc->hw.dma, devc->hw.name)) {
		printk(KERN_ERR "%s: Can't allocate DMA%d\n",
			devc->hw.name, devc->hw.dma);
		goto uninstall_irq;
	}

	if (devc->hw.dma != devc->hw.dma2 && devc->hw.dma2 != NO_DMA)
		if (sound_alloc_dma(devc->hw.dma2, devc->hw.name)) {
			printk(KERN_ERR "%s: can't allocate DMA%d\n",
				devc->hw.name, devc->hw.dma2);
			goto uninstall_dma;
		}

	waveartist_set_ctlr(&devc->hw, 0, DMA1_IE | DMA0_IE);

	audio_devs[my_dev]->mixer_dev =
		sound_install_mixer(MIXER_DRIVER_VERSION,
				dev_name,
				&waveartist_mixer_operations,
				sizeof(struct mixer_operations),
				devc);

	return my_dev;

uninstall_dma:
	sound_free_dma(devc->hw.dma);

uninstall_irq:
	free_irq(devc->hw.irq, devc);

uninstall:
	sound_unload_audiodev(my_dev);

free:
	kfree(portc);

nomem:
	return -1;
}

static int __init probe_waveartist(struct address_info *hw_config)
{
	wavnc_info *devc = &adev_info[nr_waveartist_devs];

	if (nr_waveartist_devs >= MAX_AUDIO_DEV) {
		printk(KERN_WARNING "waveartist: too many audio devices\n");
		return 0;
	}

	if (!request_region(hw_config->io_base, 15, hw_config->name))  {
		printk(KERN_WARNING "WaveArtist: I/O port conflict\n");
		return 0;
	}

	if (hw_config->irq > 15 || hw_config->irq < 0) {
		release_region(hw_config->io_base, 15);
		printk(KERN_WARNING "WaveArtist: Bad IRQ %d\n",
		       hw_config->irq);
		return 0;
	}

	if (hw_config->dma != 3) {
		release_region(hw_config->io_base, 15);
		printk(KERN_WARNING "WaveArtist: Bad DMA %d\n",
		       hw_config->dma);
		return 0;
	}

	hw_config->name = "WaveArtist";
	devc->hw = *hw_config;
	devc->open_mode = 0;
	devc->chip_name = "RWA-010";

	return 1;
}

static void __init
attach_waveartist(struct address_info *hw, const struct waveartist_mixer_info *mix)
{
	wavnc_info *devc = &adev_info[nr_waveartist_devs];

	/*
	 * NOTE! If irq < 0, there is another driver which has allocated the
	 *   IRQ so that this driver doesn't need to allocate/deallocate it.
	 *   The actually used IRQ is ABS(irq).
	 */
	devc->hw = *hw;
	devc->hw.irq = (hw->irq > 0) ? hw->irq : 0;
	devc->open_mode = 0;
	devc->playback_dev = 0;
	devc->record_dev = 0;
	devc->audio_flags = DMA_AUTOMODE;
	devc->levels = levels;

	if (hw->dma != hw->dma2 && hw->dma2 != NO_DMA)
		devc->audio_flags |= DMA_DUPLEX;

	devc->mix = mix;
	devc->dev_no = waveartist_init(devc);

	if (devc->dev_no < 0)
		release_region(hw->io_base, 15);
	else {
#ifdef CONFIG_ARCH_NETWINDER
		if (machine_is_netwinder()) {
			init_timer(&vnc_timer);
			vnc_timer.function = vnc_slider_tick;
			vnc_timer.expires  = jiffies;
			vnc_timer.data     = nr_waveartist_devs;
			add_timer(&vnc_timer);

			vnc_configure_mixer(devc, 0);

			devc->no_autoselect = 1;
		}
#endif
		nr_waveartist_devs += 1;
	}
}

static void __exit unload_waveartist(struct address_info *hw)
{
	wavnc_info *devc = NULL;
	int i;

	for (i = 0; i < nr_waveartist_devs; i++)
		if (hw->io_base == adev_info[i].hw.io_base) {
			devc = adev_info + i;
			break;
		}

	if (devc != NULL) {
		int mixer;

#ifdef CONFIG_ARCH_NETWINDER
		if (machine_is_netwinder())
			del_timer(&vnc_timer);
#endif

		release_region(devc->hw.io_base, 15);

		waveartist_set_ctlr(&devc->hw, DMA1_IE|DMA0_IE, 0);

		if (devc->hw.irq >= 0)
			free_irq(devc->hw.irq, devc);

		sound_free_dma(devc->hw.dma);

		if (devc->hw.dma != devc->hw.dma2 &&
		    devc->hw.dma2 != NO_DMA)
			sound_free_dma(devc->hw.dma2);

		mixer = audio_devs[devc->dev_no]->mixer_dev;

		if (mixer >= 0)
			sound_unload_mixerdev(mixer);

		if (devc->dev_no >= 0)
			sound_unload_audiodev(devc->dev_no);

		nr_waveartist_devs -= 1;

		for (; i < nr_waveartist_devs; i++)
			adev_info[i] = adev_info[i + 1];
	} else
		printk(KERN_WARNING "waveartist: can't find device "
		       "to unload\n");
}

#ifdef CONFIG_ARCH_NETWINDER

/*
 * Rebel.com Netwinder specifics...
 */

#include <asm/hardware/dec21285.h>
 
#define	VNC_TIMER_PERIOD (HZ/4)	//check slider 4 times/sec

#define	MIXER_PRIVATE3_RESET	0x53570000
#define	MIXER_PRIVATE3_READ	0x53570001
#define	MIXER_PRIVATE3_WRITE	0x53570002

#define	VNC_MUTE_INTERNAL_SPKR	0x01	//the sw mute on/off control bit
#define	VNC_MUTE_LINE_OUT	0x10
#define VNC_PHONE_DETECT	0x20
#define VNC_HANDSET_DETECT	0x40
#define VNC_DISABLE_AUTOSWITCH	0x80

extern spinlock_t gpio_lock;

static inline void
vnc_mute_spkr(wavnc_info *devc)
{
	unsigned long flags;

	spin_lock_irqsave(&gpio_lock, flags);
	cpld_modify(CPLD_UNMUTE, devc->spkr_mute_state ? 0 : CPLD_UNMUTE);
	spin_unlock_irqrestore(&gpio_lock, flags);
}

static void
vnc_mute_lout(wavnc_info *devc)
{
	unsigned int left, right;

	left  = waveartist_cmd1_r(devc, WACMD_GET_LEVEL);
	right = waveartist_cmd1_r(devc, WACMD_GET_LEVEL | 0x400);

	if (devc->line_mute_state) {
		left &= ~1;
		right &= ~1;
	} else {
		left |= 1;
		right |= 1;
	}
	waveartist_cmd3(devc, WACMD_SET_MIXER, left, right);
		
}

static int
vnc_volume_slider(wavnc_info *devc)
{
	static signed int old_slider_volume;
	unsigned long flags;
	signed int volume = 255;

	*CSR_TIMER1_LOAD = 0x00ffffff;

	spin_lock_irqsave(&waveartist_lock, flags);

	outb(0xFF, 0x201);
	*CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_DIV1;

	while (volume && (inb(0x201) & 0x01))
		volume--;

	*CSR_TIMER1_CNTL = 0;

	spin_unlock_irqrestore(&waveartist_lock,flags);
	
	volume = 0x00ffffff - *CSR_TIMER1_VALUE;


#ifndef REVERSE
	volume = 150 - (volume >> 5);
#else
	volume = (volume >> 6) - 25;
#endif

	if (volume < 0)
		volume = 0;

	if (volume > 100)
		volume = 100;

	/*
	 * slider quite often reads +-8, so debounce this random noise
	 */
	if (abs(volume - old_slider_volume) > 7) {
		old_slider_volume = volume;

		if (debug_flg & DEBUG_MIXER)
			printk(KERN_DEBUG "Slider volume: %d.\n", volume);
	}

	return old_slider_volume;
}

/*
 * Decode a recording mask into a mixer selection on the NetWinder
 * as follows:
 *
 *     OSS Source	WA Source	Actual source
 *  SOUND_MASK_IMIX	Mixer		Mixer output (same as AD1848)
 *  SOUND_MASK_LINE	Line		Line in
 *  SOUND_MASK_LINE1	Left Mic	Handset
 *  SOUND_MASK_PHONEIN	Left Aux	Telephone microphone
 *  SOUND_MASK_MIC	Right Mic	Builtin microphone
 */
static unsigned int
netwinder_select_input(wavnc_info *devc, unsigned int recmask,
		       unsigned char *dev_l, unsigned char *dev_r)
{
	unsigned int recdev_l = ADC_MUX_NONE, recdev_r = ADC_MUX_NONE;

	if (recmask & SOUND_MASK_IMIX) {
		recmask = SOUND_MASK_IMIX;
		recdev_l = ADC_MUX_MIXER;
		recdev_r = ADC_MUX_MIXER;
	} else if (recmask & SOUND_MASK_LINE) {
		recmask = SOUND_MASK_LINE;
		recdev_l = ADC_MUX_LINE;
		recdev_r = ADC_MUX_LINE;
	} else if (recmask & SOUND_MASK_LINE1) {
		recmask = SOUND_MASK_LINE1;
		waveartist_cmd1(devc, WACMD_SET_MONO); /* left */
		recdev_l = ADC_MUX_MIC;
		recdev_r = ADC_MUX_NONE;
	} else if (recmask & SOUND_MASK_PHONEIN) {
		recmask = SOUND_MASK_PHONEIN;
		waveartist_cmd1(devc, WACMD_SET_MONO); /* left */
		recdev_l = ADC_MUX_AUX1;
		recdev_r = ADC_MUX_NONE;
	} else if (recmask & SOUND_MASK_MIC) {
		recmask = SOUND_MASK_MIC;
		waveartist_cmd1(devc, WACMD_SET_MONO | 0x100);	/* right */
		recdev_l = ADC_MUX_NONE;
		recdev_r = ADC_MUX_MIC;
	}

	*dev_l = recdev_l;
	*dev_r = recdev_r;

	return recmask;
}

static int
netwinder_decode_mixer(wavnc_info *devc, int dev, unsigned char lev_l,
		       unsigned char lev_r)
{
	switch (dev) {
	case SOUND_MIXER_VOLUME:
	case SOUND_MIXER_SYNTH:
	case SOUND_MIXER_PCM:
	case SOUND_MIXER_LINE:
	case SOUND_MIXER_IGAIN:
		devc->levels[dev] = lev_l | lev_r << 8;
		break;

	case SOUND_MIXER_MIC:		/* right mic only */
		devc->levels[SOUND_MIXER_MIC] &= 0xff;
		devc->levels[SOUND_MIXER_MIC] |= lev_l << 8;
		break;

	case SOUND_MIXER_LINE1:		/* left mic only  */
		devc->levels[SOUND_MIXER_MIC] &= 0xff00;
		devc->levels[SOUND_MIXER_MIC] |= lev_l;
		dev = SOUND_MIXER_MIC;
		break;

	case SOUND_MIXER_PHONEIN:	/* left aux only  */
		devc->levels[SOUND_MIXER_LINE1] = lev_l;
		dev = SOUND_MIXER_LINE1;
		break;

	case SOUND_MIXER_IMIX:
	case SOUND_MIXER_PHONEOUT:
		break;

	default:
		dev = -EINVAL;
		break;
	}
	return dev;
}

static int netwinder_get_mixer(wavnc_info *devc, int dev)
{
	int levels;

	switch (dev) {
	case SOUND_MIXER_VOLUME:
	case SOUND_MIXER_SYNTH:
	case SOUND_MIXER_PCM:
	case SOUND_MIXER_LINE:
	case SOUND_MIXER_IGAIN:
		levels = devc->levels[dev];
		break;

	case SOUND_MIXER_MIC:		/* builtin mic: right mic only */
		levels = devc->levels[SOUND_MIXER_MIC] >> 8;
		levels |= levels << 8;
		break;

	case SOUND_MIXER_LINE1:		/* handset mic: left mic only */
		levels = devc->levels[SOUND_MIXER_MIC] & 0xff;
		levels |= levels << 8;
		break;

	case SOUND_MIXER_PHONEIN:	/* phone mic: left aux1 only */
		levels = devc->levels[SOUND_MIXER_LINE1] & 0xff;
		levels |= levels << 8;
		break;

	default:
		levels = 0;
	}

	return levels;
}

/*
 * Waveartist specific mixer information.
 */
static const struct waveartist_mixer_info netwinder_mixer = {
	.supported_devs	= SOUND_MASK_VOLUME  | SOUND_MASK_SYNTH   |
			SOUND_MASK_PCM     | SOUND_MASK_SPEAKER |
			SOUND_MASK_LINE    | SOUND_MASK_MIC     |
			SOUND_MASK_IMIX    | SOUND_MASK_LINE1   |
			SOUND_MASK_PHONEIN | SOUND_MASK_PHONEOUT|
			SOUND_MASK_IGAIN,

	.recording_devs	= SOUND_MASK_LINE    | SOUND_MASK_MIC     |
			SOUND_MASK_IMIX    | SOUND_MASK_LINE1   |
			SOUND_MASK_PHONEIN,

	.stereo_devs	= SOUND_MASK_VOLUME  | SOUND_MASK_SYNTH   |
			SOUND_MASK_PCM     | SOUND_MASK_LINE    |
			SOUND_MASK_IMIX    | SOUND_MASK_IGAIN,

	.select_input	= netwinder_select_input,
	.decode_mixer	= netwinder_decode_mixer,
	.get_mixer	= netwinder_get_mixer,
};

static void
vnc_configure_mixer(wavnc_info *devc, unsigned int recmask)
{
	if (!devc->no_autoselect) {
		if (devc->handset_detect) {
			recmask = SOUND_MASK_LINE1;
			devc->spkr_mute_state = devc->line_mute_state = 1;
		} else if (devc->telephone_detect) {
			recmask = SOUND_MASK_PHONEIN;
			devc->spkr_mute_state = devc->line_mute_state = 1;
		} else {
			/* unless someone has asked for LINE-IN,
			 * we default to MIC
			 */
			if ((devc->recmask & SOUND_MASK_LINE) == 0)
				devc->recmask = SOUND_MASK_MIC;
			devc->spkr_mute_state = devc->line_mute_state = 0;
		}
		vnc_mute_spkr(devc);
		vnc_mute_lout(devc);

		if (recmask != devc->recmask)
			waveartist_set_recmask(devc, recmask);
	}
}

static int
vnc_slider(wavnc_info *devc)
{
	signed int slider_volume;
	unsigned int temp, old_hs, old_td;

	/*
	 * read the "buttons" state.
	 *  Bit 4 = 0 means handset present
	 *  Bit 5 = 1 means phone offhook
	 */
	temp = inb(0x201);

	old_hs = devc->handset_detect;
	old_td = devc->telephone_detect;

	devc->handset_detect = !(temp & 0x10);
	devc->telephone_detect = !!(temp & 0x20);

	if (!devc->no_autoselect &&
	    (old_hs != devc->handset_detect ||
	     old_td != devc->telephone_detect))
		vnc_configure_mixer(devc, devc->recmask);

	slider_volume = vnc_volume_slider(devc);

	/*
	 * If we're using software controlled volume, and
	 * the slider moves by more than 20%, then we
	 * switch back to slider controlled volume.
	 */
	if (abs(devc->slider_vol - slider_volume) > 20)
		devc->use_slider = 1;

	/*
	 * use only left channel
	 */
	temp = levels[SOUND_MIXER_VOLUME] & 0xFF;

	if (slider_volume != temp && devc->use_slider) {
		devc->slider_vol = slider_volume;

		waveartist_set_mixer(devc, SOUND_MIXER_VOLUME,
			slider_volume | slider_volume << 8);

		return 1;
	}

	return 0;
}

static void
vnc_slider_tick(unsigned long data)
{
	int next_timeout;

	if (vnc_slider(adev_info + data))
		next_timeout = 5;	// mixer reported change
	else
		next_timeout = VNC_TIMER_PERIOD;

	mod_timer(&vnc_timer, jiffies + next_timeout);
}

static int
vnc_private_ioctl(int dev, unsigned int cmd, int __user * arg)
{
	wavnc_info *devc = (wavnc_info *)audio_devs[dev]->devc;
	int val;

	switch (cmd) {
	case SOUND_MIXER_PRIVATE1:
	{
		u_int prev_spkr_mute, prev_line_mute, prev_auto_state;
		int val;

		if (get_user(val, arg))
			return -EFAULT;

		/* check if parameter is logical */
		if (val & ~(VNC_MUTE_INTERNAL_SPKR |
			    VNC_MUTE_LINE_OUT |
			    VNC_DISABLE_AUTOSWITCH))
			return -EINVAL;

		prev_auto_state = devc->no_autoselect;
		prev_spkr_mute  = devc->spkr_mute_state;
		prev_line_mute  = devc->line_mute_state;

		devc->no_autoselect   = (val & VNC_DISABLE_AUTOSWITCH) ? 1 : 0;
		devc->spkr_mute_state = (val & VNC_MUTE_INTERNAL_SPKR) ? 1 : 0;
		devc->line_mute_state = (val & VNC_MUTE_LINE_OUT) ? 1 : 0;

		if (prev_spkr_mute != devc->spkr_mute_state)
			vnc_mute_spkr(devc);

		if (prev_line_mute != devc->line_mute_state)
			vnc_mute_lout(devc);

		if (prev_auto_state != devc->no_autoselect)
			vnc_configure_mixer(devc, devc->recmask);

		return 0;
	}

	case SOUND_MIXER_PRIVATE2:
		if (get_user(val, arg))
			return -EFAULT;

		switch (val) {
#define VNC_SOUND_PAUSE         0x53    //to pause the DSP
#define VNC_SOUND_RESUME        0x57    //to unpause the DSP
		case VNC_SOUND_PAUSE:
			waveartist_cmd1(devc, 0x16);
			break;

		case VNC_SOUND_RESUME:
			waveartist_cmd1(devc, 0x18);
			break;

		default:
			return -EINVAL;
		}
		return 0;

	/* private ioctl to allow bulk access to waveartist */
	case SOUND_MIXER_PRIVATE3:
	{
		unsigned long	flags;
		int		mixer_reg[15], i, val;

		if (get_user(val, arg))
			return -EFAULT;
		if (copy_from_user(mixer_reg, (void *)val, sizeof(mixer_reg)))
			return -EFAULT;

		switch (mixer_reg[14]) {
		case MIXER_PRIVATE3_RESET:
			waveartist_mixer_reset(devc);
			break;

		case MIXER_PRIVATE3_WRITE:
			waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[0], mixer_reg[4]);
			waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[1], mixer_reg[5]);
			waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[2], mixer_reg[6]);
			waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[3], mixer_reg[7]);
			waveartist_cmd3(devc, WACMD_SET_MIXER, mixer_reg[8], mixer_reg[9]);

			waveartist_cmd3(devc, WACMD_SET_LEVEL, mixer_reg[10], mixer_reg[11]);
			waveartist_cmd3(devc, WACMD_SET_LEVEL, mixer_reg[12], mixer_reg[13]);
			break;

		case MIXER_PRIVATE3_READ:
			spin_lock_irqsave(&waveartist_lock, flags);

			for (i = 0x30; i < 14 << 8; i += 1 << 8)
				waveartist_cmd(devc, 1, &i, 1, mixer_reg + (i >> 8));

			spin_unlock_irqrestore(&waveartist_lock, flags);

			if (copy_to_user((void *)val, mixer_reg, sizeof(mixer_reg)))
				return -EFAULT;
			break;

		default:
			return -EINVAL;
		}
		return 0;
	}

	/* read back the state from PRIVATE1 */
	case SOUND_MIXER_PRIVATE4:
		val = (devc->spkr_mute_state  ? VNC_MUTE_INTERNAL_SPKR : 0) |
		      (devc->line_mute_state  ? VNC_MUTE_LINE_OUT      : 0) |
		      (devc->handset_detect   ? VNC_HANDSET_DETECT     : 0) |
		      (devc->telephone_detect ? VNC_PHONE_DETECT       : 0) |
		      (devc->no_autoselect    ? VNC_DISABLE_AUTOSWITCH : 0);

		return put_user(val, arg) ? -EFAULT : 0;
	}

	if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
		/*
		 * special case for master volume: if we
		 * received this call - switch from hw
		 * volume control to a software volume
		 * control, till the hw volume is modified
		 * to signal that user wants to be back in
		 * hardware...
		 */
		if ((cmd & 0xff) == SOUND_MIXER_VOLUME)
			devc->use_slider = 0;

		/* speaker output            */
		if ((cmd & 0xff) == SOUND_MIXER_SPEAKER) {
			unsigned int val, l, r;

			if (get_user(val, arg))
				return -EFAULT;

			l = val & 0x7f;
			r = (val & 0x7f00) >> 8;
			val = (l + r) / 2;
			devc->levels[SOUND_MIXER_SPEAKER] = val | (val << 8);
			devc->spkr_mute_state = (val <= 50);
			vnc_mute_spkr(devc);
			return 0;
		}
	}

	return -ENOIOCTLCMD;
}

#endif

static struct address_info cfg;

static int attached;

static int __initdata io = 0;
static int __initdata irq = 0;
static int __initdata dma = 0;
static int __initdata dma2 = 0;


static int __init init_waveartist(void)
{
	const struct waveartist_mixer_info *mix;

	if (!io && machine_is_netwinder()) {
		/*
		 * The NetWinder WaveArtist is at a fixed address.
		 * If the user does not supply an address, use the
		 * well-known parameters.
		 */
		io   = 0x250;
		irq  = 12;
		dma  = 3;
		dma2 = 7;
	}

	mix = &waveartist_mixer;
#ifdef CONFIG_ARCH_NETWINDER
	if (machine_is_netwinder())
		mix = &netwinder_mixer;
#endif

	cfg.io_base = io;
	cfg.irq = irq;
	cfg.dma = dma;
	cfg.dma2 = dma2;

	if (!probe_waveartist(&cfg))
		return -ENODEV;

	attach_waveartist(&cfg, mix);
	attached = 1;

	return 0;
}

static void __exit cleanup_waveartist(void)
{
	if (attached)
		unload_waveartist(&cfg);
}

module_init(init_waveartist);
module_exit(cleanup_waveartist);

#ifndef MODULE
static int __init setup_waveartist(char *str)
{
	/* io, irq, dma, dma2 */
	int ints[5];
	
	str = get_options(str, ARRAY_SIZE(ints), ints);
	
	io	= ints[1];
	irq	= ints[2];
	dma	= ints[3];
	dma2	= ints[4];

	return 1;
}
__setup("waveartist=", setup_waveartist);
#endif

MODULE_DESCRIPTION("Rockwell WaveArtist RWA-010 sound driver");
module_param(io, int, 0);		/* IO base */
module_param(irq, int, 0);		/* IRQ */
module_param(dma, int, 0);		/* DMA */
module_param(dma2, int, 0);		/* DMA2 */
MODULE_LICENSE("GPL");
