diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
new file mode 100644
index 0000000..99d04ad
--- /dev/null
+++ b/sound/oss/waveartist.c
@@ -0,0 +1,2035 @@
+/*
+ * 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/config.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_PARM(io, "i");		/* IO base */
+MODULE_PARM(irq, "i");		/* IRQ */
+MODULE_PARM(dma, "i");		/* DMA */
+MODULE_PARM(dma2, "i");		/* DMA2 */
+MODULE_LICENSE("GPL");
