/*
 *  Copyright 2001-2004 Randolph Chung <tausq@debian.org>
 *
 *  Analog Devices 1889 PCI audio driver (AD1819 AC97-compatible codec)
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *   Notes:
 *   1. Only flat DMA is supported; s-g is not supported right now
 *
 *
<jsm> tausq: Anyway, to set up sample rates for D to A, you just use the sample rate on the codec. For A to D, you need to set the codec always to 48K (using the split sample rate feature on the codec) and then set the resampler on the AD1889 to the sample rate you want.
<jsm> Also, when changing the sample rate on the codec you need to power it down and re power it up for the change to take effect!
 *
 * $Id: ad1889.c,v 1.3 2002/10/19 21:31:44 grundler Exp $
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/soundcard.h>
#include <linux/ac97_codec.h>
#include <linux/sound.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>

#include <asm/delay.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>

#include "ad1889.h"

#define DBG(fmt, arg...) printk(fmt, ##arg)
#define DEVNAME "ad1889"

#define NR_HW_CH	4
#define DAC_RUNNING	1
#define ADC_RUNNING	2

#define UNDERRUN(dev)	(0)

#define AD1889_READW(dev,reg) readw(dev->regbase + reg)
#define AD1889_WRITEW(dev,reg,val) writew((val), dev->regbase + reg)
#define AD1889_READL(dev,reg) readl(dev->regbase + reg)
#define AD1889_WRITEL(dev,reg,val) writel((val), dev->regbase + reg)

//now 100ms
/* #define WAIT_10MS()	schedule_timeout(HZ/10) */
#define WAIT_10MS()	do { int __i; for (__i = 0; __i < 100; __i++) udelay(1000); } while(0)

/* currently only support a single device */
static ad1889_dev_t *ad1889_dev = NULL;

/************************* helper routines ***************************** */
static inline void ad1889_set_wav_rate(ad1889_dev_t *dev, int rate)
{
	struct ac97_codec *ac97_codec = dev->ac97_codec;

	DBG("Setting WAV rate to %d\n", rate);
	dev->state[AD_WAV_STATE].dmabuf.rate = rate;
	AD1889_WRITEW(dev, AD_DS_WAS, rate);

	/* Cycle the DAC to enable the new rate */
	ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200);
	WAIT_10MS();
	ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0);
}

static inline void ad1889_set_wav_fmt(ad1889_dev_t *dev, int fmt)
{
	u16 tmp;

	DBG("Setting WAV format to 0x%x\n", fmt);

	tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC);
	if (fmt & AFMT_S16_LE) {
		//tmp |= 0x0100; /* set WA16 */
		tmp |= 0x0300; /* set WA16 stereo */
	} else if (fmt & AFMT_U8) {
		tmp &= ~0x0100; /* clear WA16 */
	} 
	AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp);
}

static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt)
{
	u16 tmp;

	DBG("Setting ADC format to 0x%x\n", fmt);

	tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC);
	if (fmt & AFMT_S16_LE) {
		tmp |= 0x0100; /* set WA16 */
	} else if (fmt & AFMT_U8) {
		tmp &= ~0x0100; /* clear WA16 */
	} 
	AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp);
}

static void ad1889_start_wav(ad1889_state_t *state)
{
	unsigned long flags;
	struct dmabuf *dmabuf = &state->dmabuf;
	int cnt;
	u16 tmp;

	spin_lock_irqsave(&state->card->lock, flags);

	if (dmabuf->dma_len)	/* DMA already in flight */
		goto skip_dma;

	/* setup dma */
	cnt = dmabuf->wr_ptr - dmabuf->rd_ptr;
	if (cnt == 0)		/* done - don't need to do anything */
		goto skip_dma;

	/* If the wr_ptr has wrapped, only map to the end */
	if (cnt < 0)
		cnt = DMA_SIZE - dmabuf->rd_ptr;

	dmabuf->dma_handle = pci_map_single(ad1889_dev->pci,
					dmabuf->rawbuf + dmabuf->rd_ptr,
					cnt, PCI_DMA_TODEVICE);
	dmabuf->dma_len = cnt;
	dmabuf->ready = 1;

	DBG("Starting playback at 0x%p for %ld bytes\n", dmabuf->rawbuf +
	    dmabuf->rd_ptr, dmabuf->dma_len);

        /* load up the current register set */
	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVICC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCA, dmabuf->dma_handle);

	/* TODO: for now we load the base registers with the same thing */
	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVIBC, cnt);
	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBA, dmabuf->dma_handle);

	/* and we're off to the races... */
	AD1889_WRITEL(ad1889_dev, AD_DMA_CHSS, 0x8);
	tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC);
	tmp |= 0x0400; /* set WAEN */
	AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp);
	(void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */

	dmabuf->enable |= DAC_RUNNING;

skip_dma:
	spin_unlock_irqrestore(&state->card->lock, flags);
}


static void ad1889_stop_wav(ad1889_state_t *state)
{
	unsigned long flags;
	struct dmabuf *dmabuf = &state->dmabuf;

	spin_lock_irqsave(&state->card->lock, flags);

	if (dmabuf->enable & DAC_RUNNING) {
		u16 tmp;
		unsigned long cnt = dmabuf->dma_len;

		tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC);
		tmp &= ~0x0400; /* clear WAEN */
		AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp);
		(void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */
		pci_unmap_single(ad1889_dev->pci, dmabuf->dma_handle, 
				cnt, PCI_DMA_TODEVICE);

		dmabuf->enable &= ~DAC_RUNNING;

		/* update dma pointers */
		dmabuf->rd_ptr += cnt;
		dmabuf->rd_ptr &= (DMA_SIZE - 1);

		dmabuf->dma_handle = 0;
		dmabuf->dma_len = 0;
		dmabuf->ready = 0;

		wake_up(&dmabuf->wait);
	}

	spin_unlock_irqrestore(&state->card->lock, flags);
}


#if 0
static void ad1889_startstop_adc(ad1889_state_t *state, int start)
{
	u16 tmp;
	unsigned long flags;

	spin_lock_irqsave(&state->card->lock, flags);
	
	tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC);
	if (start) {
		state->dmabuf.enable |= ADC_RUNNING;
		tmp |= 0x0004; /* set ADEN */
	} else {
		state->dmabuf.enable &= ~ADC_RUNNING;
		tmp &= ~0x0004; /* clear ADEN */
	}
	AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp);

	spin_unlock_irqrestore(&state->card->lock, flags);
}
#endif

static ad1889_dev_t *ad1889_alloc_dev(struct pci_dev *pci)
{
	ad1889_dev_t *dev;
	struct dmabuf *dmabuf;
	int i;

	if ((dev = kmalloc(sizeof(ad1889_dev_t), GFP_KERNEL)) == NULL) 
		return NULL;
	memset(dev, 0, sizeof(ad1889_dev_t));
	spin_lock_init(&dev->lock);
	dev->pci = pci;

	for (i = 0; i < AD_MAX_STATES; i++) {
		dev->state[i].card = dev;
		mutex_init(&dev->state[i].mutex);
		init_waitqueue_head(&dev->state[i].dmabuf.wait);
	}

	/* allocate dma buffer */

	for (i = 0; i < AD_MAX_STATES; i++) {
		dmabuf = &dev->state[i].dmabuf;
		dmabuf->rawbuf = kmalloc(DMA_SIZE, GFP_KERNEL|GFP_DMA);
		if (!dmabuf->rawbuf)
			goto err_free_dmabuf;
		dmabuf->rawbuf_size = DMA_SIZE;
		dmabuf->dma_handle = 0;
		dmabuf->rd_ptr = dmabuf->wr_ptr = dmabuf->dma_len = 0UL;
		dmabuf->ready = 0;
		dmabuf->rate = 48000;
	}
	return dev;

err_free_dmabuf:
	while (--i >= 0)
		kfree(dev->state[i].dmabuf.rawbuf);
	kfree(dev);
	return NULL;
}

static void ad1889_free_dev(ad1889_dev_t *dev)
{
	int j;
	struct dmabuf *dmabuf;

	if (dev == NULL) 
		return;

	if (dev->ac97_codec)
		ac97_release_codec(dev->ac97_codec);

	for (j = 0; j < AD_MAX_STATES; j++) {
		dmabuf = &dev->state[j].dmabuf;
		kfree(dmabuf->rawbuf);
	}

	kfree(dev);
}

static inline void ad1889_trigger_playback(ad1889_dev_t *dev)
{
#if 0
	u32 val;
	struct dmabuf *dmabuf = &dev->state[AD_WAV_STATE].dmabuf;
#endif

	ad1889_start_wav(&dev->state[AD_WAV_STATE]);
}

static int ad1889_read_proc (char *page, char **start, off_t off,
			     int count, int *eof, void *data)
{
	char *out = page;
	int len, i;
	ad1889_dev_t *dev = data;
	ad1889_reg_t regs[] = {
		{ "WSMC", AD_DS_WSMC, 16 },
		{ "RAMC", AD_DS_RAMC, 16 },
		{ "WADA", AD_DS_WADA, 16 },
		{ "SYDA", AD_DS_SYDA, 16 },
		{ "WAS", AD_DS_WAS, 16 },
		{ "RES", AD_DS_RES, 16 },
		{ "CCS", AD_DS_CCS, 16 },
		{ "ADCBA", AD_DMA_ADCBA, 32 },
		{ "ADCCA", AD_DMA_ADCCA, 32 },
		{ "ADCBC", AD_DMA_ADCBC, 32 },
		{ "ADCCC", AD_DMA_ADCCC, 32 },
		{ "ADCIBC", AD_DMA_ADCIBC, 32 },
		{ "ADCICC", AD_DMA_ADCICC, 32 },
		{ "ADCCTRL", AD_DMA_ADCCTRL, 16 },
		{ "WAVBA", AD_DMA_WAVBA, 32 },
		{ "WAVCA", AD_DMA_WAVCA, 32 },
		{ "WAVBC", AD_DMA_WAVBC, 32 },
		{ "WAVCC", AD_DMA_WAVCC, 32 },
		{ "WAVIBC", AD_DMA_WAVIBC, 32 },
		{ "WAVICC", AD_DMA_WAVICC, 32 },
		{ "WAVCTRL", AD_DMA_WAVCTRL, 16 },
		{ "DISR", AD_DMA_DISR, 32 },
		{ "CHSS", AD_DMA_CHSS, 32 },
		{ "IPC", AD_GPIO_IPC, 16 },
		{ "OP", AD_GPIO_OP, 16 },
		{ "IP", AD_GPIO_IP, 16 },
		{ "ACIC", AD_AC97_ACIC, 16 },
		{ "AC97_RESET", AD_AC97_BASE + AC97_RESET, 16 },
		{ "AC97_MASTER_VOL_STEREO", AD_AC97_BASE + AC97_MASTER_VOL_STEREO, 16 },
		{ "AC97_HEADPHONE_VOL", AD_AC97_BASE + AC97_HEADPHONE_VOL, 16 },
		{ "AC97_MASTER_VOL_MONO", AD_AC97_BASE + AC97_MASTER_VOL_MONO, 16 },
		{ "AC97_MASTER_TONE", AD_AC97_BASE + AC97_MASTER_TONE, 16 },
		{ "AC97_PCBEEP_VOL", AD_AC97_BASE + AC97_PCBEEP_VOL, 16 },
		{ "AC97_PHONE_VOL", AD_AC97_BASE + AC97_PHONE_VOL, 16 },
		{ "AC97_MIC_VOL", AD_AC97_BASE + AC97_MIC_VOL, 16 },
		{ "AC97_LINEIN_VOL", AD_AC97_BASE + AC97_LINEIN_VOL, 16 },
		{ "AC97_CD_VOL", AD_AC97_BASE + AC97_CD_VOL, 16 },
		{ "AC97_VIDEO_VOL", AD_AC97_BASE + AC97_VIDEO_VOL, 16 },
		{ "AC97_AUX_VOL", AD_AC97_BASE + AC97_AUX_VOL, 16 },
		{ "AC97_PCMOUT_VOL", AD_AC97_BASE + AC97_PCMOUT_VOL, 16 },
		{ "AC97_RECORD_SELECT", AD_AC97_BASE + AC97_RECORD_SELECT, 16 },
		{ "AC97_RECORD_GAIN", AD_AC97_BASE + AC97_RECORD_GAIN, 16 },
		{ "AC97_RECORD_GAIN_MIC", AD_AC97_BASE + AC97_RECORD_GAIN_MIC, 16 },
		{ "AC97_GENERAL_PURPOSE", AD_AC97_BASE + AC97_GENERAL_PURPOSE, 16 },
		{ "AC97_3D_CONTROL", AD_AC97_BASE + AC97_3D_CONTROL, 16 },
		{ "AC97_MODEM_RATE", AD_AC97_BASE + AC97_MODEM_RATE, 16 },
		{ "AC97_POWER_CONTROL", AD_AC97_BASE + AC97_POWER_CONTROL, 16 },
		{ NULL }
	};

	if (dev == NULL)
		return -ENODEV;

	for (i = 0; regs[i].name != 0; i++)
		out += sprintf(out, "%s: 0x%0*x\n", regs[i].name, 
			regs[i].width >> 2, 
			(regs[i].width == 16 
			 	? AD1889_READW(dev, regs[i].offset)
				: AD1889_READL(dev, regs[i].offset)));

	for (i = 0; i < AD_MAX_STATES; i++) {
		out += sprintf(out, "DMA status for %s:\n", 
			(i == AD_WAV_STATE ? "WAV" : "ADC")); 
		out += sprintf(out, "\t\t0x%p (IOVA: 0x%llu)\n",
			dev->state[i].dmabuf.rawbuf,
			(unsigned long long)dev->state[i].dmabuf.dma_handle);

		out += sprintf(out, "\tread ptr: offset %u\n", 
			(unsigned int)dev->state[i].dmabuf.rd_ptr);
		out += sprintf(out, "\twrite ptr: offset %u\n", 
			(unsigned int)dev->state[i].dmabuf.wr_ptr);
		out += sprintf(out, "\tdma len: offset %u\n", 
			(unsigned int)dev->state[i].dmabuf.dma_len);
	}

	len = out - page - off;
	if (len < count) {
		*eof = 1;
		if (len <= 0) return 0;
	} else {
		len = count;
	}
	*start = page + off;
	return len;
}

/***************************** DMA interfaces ************************** */
#if 0
static inline unsigned long ad1889_get_dma_addr(ad1889_state_t *state)
{
	struct dmabuf *dmabuf = &state->dmabuf;
	u32 offset;

	if (!(dmabuf->enable & (DAC_RUNNING | ADC_RUNNING))) {
		printk(KERN_ERR DEVNAME ": get_dma_addr called without dma enabled\n");
		return 0;
	}
	
	if (dmabuf->enable & DAC_RUNNING)
		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_WAVBA));
	else
		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_ADCBA));

	return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf;
}

static void ad1889_update_ptr(ad1889_dev_t *dev, int wake)
{
	ad1889_state_t *state;
	struct dmabuf *dmabuf;
	unsigned long hwptr;
	int diff;

	/* check ADC first */
	state = &dev->adc_state;
	dmabuf = &state->dmabuf;
	if (dmabuf->enable & ADC_RUNNING) {
		hwptr = ad1889_get_dma_addr(state);
		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;

		dmabuf->hwptr = hwptr;
		dmabuf->total_bytes += diff;
		dmabuf->count += diff;
		if (dmabuf->count > dmabuf->dmasize)
			dmabuf->count = dmabuf->dmasize;

		if (dmabuf->mapped) {
			if (wake & dmabuf->count >= dmabuf->fragsize)
				wake_up(&dmabuf->wait);
		} else {
			if (wake & dmabuf->count > 0)
				wake_up(&dmabuf->wait);
		}
	}

	/* check DAC */
	state = &dev->wav_state;
	dmabuf = &state->dmabuf;
	if (dmabuf->enable & DAC_RUNNING) {
XXX

}
#endif

/************************* /dev/dsp interfaces ************************* */

static ssize_t ad1889_read(struct file *file, char __user *buffer, size_t count,
	loff_t *ppos)
{
	return 0;
}

static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t count,
	loff_t *ppos)
{
	ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
	ad1889_state_t *state = &dev->state[AD_WAV_STATE];
	volatile struct dmabuf *dmabuf = &state->dmabuf;
	ssize_t ret = 0;
	DECLARE_WAITQUEUE(wait, current);

	mutex_lock(&state->mutex);
#if 0
	if (dmabuf->mapped) {
		ret = -ENXIO;
		goto err1;
	}
#endif
	if (!access_ok(VERIFY_READ, buffer, count)) {
		ret = -EFAULT;
		goto err1;
	}

	add_wait_queue(&state->dmabuf.wait, &wait);

	/* start filling dma buffer.... */
	while (count > 0) {
		long rem;
		long cnt = count;
		unsigned long flags;

		for (;;) {
			long used_bytes;
			long timeout;	/* max time for DMA in jiffies */

			/* buffer is full if wr catches up to rd */
			spin_lock_irqsave(&state->card->lock, flags);
			used_bytes = dmabuf->wr_ptr - dmabuf->rd_ptr;
			timeout = (dmabuf->dma_len * HZ) / dmabuf->rate;
			spin_unlock_irqrestore(&state->card->lock, flags);

			/* adjust for buffer wrap around */
			used_bytes = (used_bytes + DMA_SIZE) & (DMA_SIZE - 1);

			/* If at least one page unused */
			if (used_bytes < (DMA_SIZE - 0x1000))
				break;

			/* dma buffer full */

			if (file->f_flags & O_NONBLOCK) {
				ret = -EAGAIN;
				goto err2;
			}

			set_current_state(TASK_INTERRUPTIBLE);
			schedule_timeout(timeout + 1);
			if (signal_pending(current)) {
				ret = -ERESTARTSYS;
				goto err2;
			}
		}

		/* watch out for wrapping around static buffer */
		spin_lock_irqsave(&state->card->lock, flags);
		rem = DMA_SIZE - dmabuf->wr_ptr;
		if (cnt > rem)
			cnt = rem;

		rem = dmabuf->wr_ptr;

		/* update dma pointers */
		dmabuf->wr_ptr += cnt;
		dmabuf->wr_ptr &= DMA_SIZE - 1;	/* wrap ptr if necessary */
		spin_unlock_irqrestore(&state->card->lock, flags);

		/* transfer unwrapped chunk */
		if (copy_from_user(dmabuf->rawbuf + rem, buffer, cnt)) {
			ret = -EFAULT;
			goto err2;
		}

		DBG("Writing 0x%lx bytes to +0x%lx\n", cnt, rem);

		/* update counters */
		count -= cnt;
		buffer += cnt;
		ret += cnt;

		/* we have something to play - go play it! */
		ad1889_trigger_playback(dev);
	}

err2:
	remove_wait_queue(&state->dmabuf.wait, &wait);
err1:
	mutex_unlock(&state->mutex);
	return ret;
}

static unsigned int ad1889_poll(struct file *file, struct poll_table_struct *wait)
{
	unsigned int mask = 0;
#if 0
	ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
	ad1889_state_t *state = NULL;
	struct dmabuf *dmabuf;
	unsigned long flags;
	
	if (!(file->f_mode & (FMODE_READ | FMODE_WRITE)))
		return -EINVAL;

	if (file->f_mode & FMODE_WRITE) {
		state = &dev->state[AD_WAV_STATE];
		if (!state) return 0;
		dmabuf = &state->dmabuf;
		poll_wait(file, &dmabuf->wait, wait);
	}

	if (file->f_mode & FMODE_READ) {
		state = &dev->state[AD_ADC_STATE];
		if (!state) return 0;
		dmabuf = &state->dmabuf;
		poll_wait(file, &dmabuf->wait, wait);
	}

	spin_lock_irqsave(&dev->lock, flags);
	ad1889_update_ptr(dev, 0);

	if (file->f_mode & FMODE_WRITE) {
		state = &dev->state[WAV_STATE];
		dmabuf = &state->dmabuf;
		if (dmabuf->mapped) {
			if (dmabuf->count >= (int)dmabuf->fragsize)
				mask |= POLLOUT | POLLWRNORM;
		} else {
			if ((int)dmabuf->dmasize >= dmabuf->count + 
				(int)dmabuf->fragsize)
				mask |= POLLOUT | POLLWRNORM;
		}
	}

	if (file ->f_mode & FMODE_READ) {
		state = &dev->state[AD_ADC_STATE];
		dmabuf = &state->dmabuf;
		if (dmabuf->count >= (int)dmabuf->fragsize)
			mask |= POLLIN | POLLRDNORM;
	}
	spin_unlock_irqrestore(&dev->lock, flags);

#endif
	return mask;
}

static int ad1889_mmap(struct file *file, struct vm_area_struct *vma)
{
	return 0;
}

static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
	unsigned long arg)
{
	int val = 0;
	ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
	struct dmabuf *dmabuf;
	audio_buf_info abinfo;
	int __user *p = (int __user *)arg;

	DBG("ad1889_ioctl cmd 0x%x arg %lu\n", cmd, arg);

	switch (cmd)
	{
	case OSS_GETVERSION:
		return put_user(SOUND_VERSION, p);

	case SNDCTL_DSP_RESET:
		break;

	case SNDCTL_DSP_SYNC:
		break;

	case SNDCTL_DSP_SPEED:
		/* set sampling rate */
		if (get_user(val, p))
			return -EFAULT;
		if (val > 5400 && val < 48000)
		{
			if (file->f_mode & FMODE_WRITE)
				AD1889_WRITEW(ad1889_dev, AD_DS_WAS, val);
			if (file->f_mode & FMODE_READ)
				AD1889_WRITEW(ad1889_dev, AD_DS_RES, val);
		}
		return 0;

	case SNDCTL_DSP_STEREO: /* undocumented? */
		if (get_user(val, p))
			return -EFAULT;
		if (file->f_mode & FMODE_READ) {
			val = AD1889_READW(ad1889_dev, AD_DS_WSMC);
			if (val) {
				val |= 0x0200;  /* set WAST */
			} else {
				val &= ~0x0200; /* clear WAST */
			}
			AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, val);
		}
		if (file->f_mode & FMODE_WRITE) {
			val = AD1889_READW(ad1889_dev, AD_DS_RAMC);
			if (val) {
				val |= 0x0002;  /* set ADST */
			} else {
				val &= ~0x0002; /* clear ADST */
			}
			AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, val);
		}

		return 0;

	case SNDCTL_DSP_GETBLKSIZE:
		return put_user(DMA_SIZE, p);

	case SNDCTL_DSP_GETFMTS:
		return put_user(AFMT_S16_LE|AFMT_U8, p);

	case SNDCTL_DSP_SETFMT:
		if (get_user(val, p))
			return -EFAULT;

		if (val == 0) {
			if (file->f_mode & FMODE_READ) 
				ad1889_set_adc_fmt(dev, val);

			if (file->f_mode & FMODE_WRITE) 
				ad1889_set_wav_fmt(dev, val);
		} else {
			val = AFMT_S16_LE | AFMT_U8;
		}

		return put_user(val, p);

	case SNDCTL_DSP_CHANNELS:
		break;

	case SNDCTL_DSP_POST:
		/* send all data to device */
		break;

	case SNDCTL_DSP_SUBDIVIDE:
		break;

	case SNDCTL_DSP_SETFRAGMENT:
		/* not supported; uses fixed fragment sizes */
		return put_user(DMA_SIZE, p);

	case SNDCTL_DSP_GETOSPACE:
	case SNDCTL_DSP_GETISPACE:
		/* space left in dma buffers */
		if (cmd == SNDCTL_DSP_GETOSPACE)
			dmabuf = &dev->state[AD_WAV_STATE].dmabuf;
		else
			dmabuf = &dev->state[AD_ADC_STATE].dmabuf;
		abinfo.fragments = 1;
		abinfo.fragstotal = 1;
		abinfo.fragsize = DMA_SIZE;
		abinfo.bytes = DMA_SIZE;
		return copy_to_user(p, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
	case SNDCTL_DSP_NONBLOCK:
		file->f_flags |= O_NONBLOCK;
		return 0;

	case SNDCTL_DSP_GETCAPS:
		return put_user(0, p);

	case SNDCTL_DSP_GETTRIGGER:
	case SNDCTL_DSP_SETTRIGGER:
		break;

	case SNDCTL_DSP_GETIPTR:
	case SNDCTL_DSP_GETOPTR:
		break;

	case SNDCTL_DSP_SETDUPLEX:
		break;
	
	case SNDCTL_DSP_GETODELAY:
		break;

	case SOUND_PCM_READ_RATE:
		return put_user(AD1889_READW(ad1889_dev, AD_DS_WAS), p);

	case SOUND_PCM_READ_CHANNELS:
	case SOUND_PCM_READ_BITS:
		break;

	case SNDCTL_DSP_MAPINBUF:
	case SNDCTL_DSP_MAPOUTBUF:
	case SNDCTL_DSP_SETSYNCRO:
	case SOUND_PCM_WRITE_FILTER:
	case SOUND_PCM_READ_FILTER:
		break;

	default:
		break;
	}

	return -ENOTTY;
}

static int ad1889_open(struct inode *inode, struct file *file)
{
	/* check minor; only support /dev/dsp atm */
	if (iminor(inode) != 3)
		return -ENXIO;
	
	file->private_data = ad1889_dev;

	ad1889_set_wav_rate(ad1889_dev, 48000);
	ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE);
	AD1889_WRITEW(ad1889_dev, AD_DS_WADA, 0x0404); /* attenuation */
	return nonseekable_open(inode, file);
}

static int ad1889_release(struct inode *inode, struct file *file)
{
	/* if we have state free it here */
	return 0;
}

static struct file_operations ad1889_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.read		= ad1889_read,
	.write		= ad1889_write,
	.poll		= ad1889_poll,
	.ioctl		= ad1889_ioctl,
	.mmap		= ad1889_mmap,
	.open		= ad1889_open,
	.release	= ad1889_release,
};

/************************* /dev/mixer interfaces ************************ */
static int ad1889_mixer_open(struct inode *inode, struct file *file)
{
	if (ad1889_dev->ac97_codec->dev_mixer != iminor(inode))
		return -ENODEV;

	file->private_data = ad1889_dev->ac97_codec;
	return 0;
}

static int ad1889_mixer_release(struct inode *inode, struct file *file)
{
	return 0;
}

static int ad1889_mixer_ioctl(struct inode *inode, struct file *file,
	unsigned int cmd, unsigned long arg)
{
	struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
	return codec->mixer_ioctl(codec, cmd, arg);
}

static struct file_operations ad1889_mixer_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.ioctl		= ad1889_mixer_ioctl,
	.open		= ad1889_mixer_open,
	.release	= ad1889_mixer_release,
};

/************************* AC97 interfaces ****************************** */
static void ad1889_codec_write(struct ac97_codec *ac97, u8 reg, u16 val)
{
	ad1889_dev_t *dev = ac97->private_data;

	//DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + AD_AC97_BASE + reg);
	AD1889_WRITEW(dev, AD_AC97_BASE + reg, val);
}

static u16 ad1889_codec_read(struct ac97_codec *ac97, u8 reg)
{
	ad1889_dev_t *dev = ac97->private_data;
	//DBG("Reading from 0x%lx\n", dev->regbase + AD_AC97_BASE + reg);
	return AD1889_READW(dev, AD_AC97_BASE + reg);
}	

static int ad1889_ac97_init(ad1889_dev_t *dev, int id)
{
	struct ac97_codec *ac97;
	u16 eid;

	if ((ac97 = ac97_alloc_codec()) == NULL) 
		return -ENOMEM;

	ac97->private_data = dev;
	ac97->id = id;

	ac97->codec_read = ad1889_codec_read;
	ac97->codec_write = ad1889_codec_write;

	if (ac97_probe_codec(ac97) == 0) {
		printk(DEVNAME ": ac97_probe_codec failed\n");
		goto out_free;
	}

	eid = ad1889_codec_read(ac97, AC97_EXTENDED_ID);
	if (eid == 0xffff) {
		printk(KERN_WARNING DEVNAME ": no codec attached?\n");
		goto out_free;
	}

	dev->ac97_features = eid;

	if ((ac97->dev_mixer = register_sound_mixer(&ad1889_mixer_fops, -1)) < 0) {
		printk(KERN_ERR DEVNAME ": cannot register mixer\n");
		goto out_free;
	}

	dev->ac97_codec = ac97;
	return 0;

out_free:
	ac97_release_codec(ac97);
	return -ENODEV;
}

static int ad1889_aclink_reset(struct pci_dev * pcidev)
{
	u16 stat;
	int retry = 200;
	ad1889_dev_t *dev = pci_get_drvdata(pcidev);

	AD1889_WRITEW(dev, AD_DS_CCS, 0x8000); /* turn on clock */
	AD1889_READW(dev, AD_DS_CCS);

	WAIT_10MS();

	stat = AD1889_READW(dev, AD_AC97_ACIC);
	stat |= 0x0002;				/* Reset Disable */
	AD1889_WRITEW(dev, AD_AC97_ACIC, stat);
	(void) AD1889_READW(dev, AD_AC97_ACIC);	/* flush posted write */

	udelay(10);

	stat = AD1889_READW(dev, AD_AC97_ACIC);
	stat |= 0x0001;				/* Interface Enable */
	AD1889_WRITEW(dev, AD_AC97_ACIC, stat);

	do {
		if (AD1889_READW(dev, AD_AC97_ACIC) & 0x8000)	/* Ready */
			break;
		WAIT_10MS();
		retry--;
	} while (retry > 0);

	if (!retry) {
		printk(KERN_ERR "ad1889_aclink_reset: codec is not ready [0x%x]\n",
			    AD1889_READW(dev, AD_AC97_ACIC));
		return -EBUSY;
	}

	/* TODO reset AC97 codec */
	/* TODO set wave/adc pci ctrl status */

	stat = AD1889_READW(dev, AD_AC97_ACIC);
	stat |= 0x0004;				/* Audio Stream Output Enable */
	AD1889_WRITEW(dev, AD_AC97_ACIC, stat);
	return 0;
}

/************************* PCI interfaces ****************************** */
/* PCI device table */
static struct pci_device_id ad1889_id_tbl[] = {
	{ PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS, PCI_ANY_ID, 
	  PCI_ANY_ID, 0, 0, (unsigned long)DEVNAME },
	{ },
};
MODULE_DEVICE_TABLE(pci, ad1889_id_tbl);

static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	u32 stat;
	ad1889_dev_t *dev = (ad1889_dev_t *)dev_id;

	stat = AD1889_READL(dev, AD_DMA_DISR);

	/* clear ISR */
	AD1889_WRITEL(dev, AD_DMA_DISR, stat);

	if (stat & 0x8) {		/* WAVI */
		DBG("WAV interrupt\n");
		dev->stats.wav_intrs++;
		if (dev->state[AD_WAV_STATE].dmabuf.ready) {
			ad1889_stop_wav(&dev->state[AD_WAV_STATE]);	/* clean up */
			ad1889_start_wav(&dev->state[AD_WAV_STATE]);	/* start new */
		}
	}

	if ((stat & 0x2) && dev->state[AD_ADC_STATE].dmabuf.ready) { /* ADCI */
		DBG("ADC interrupt\n");
		dev->stats.adc_intrs++;
	}
	if(stat)
		return IRQ_HANDLED;
	return IRQ_NONE;
}

static void ad1889_initcfg(ad1889_dev_t *dev)
{
	u16 tmp16;
	u32 tmp32;

	/* make sure the interrupt bits are setup the way we want */
	tmp32 = AD1889_READL(dev, AD_DMA_WAVCTRL);
	tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */
	tmp32 |= 0x6;  /* intr on count, loop */
	AD1889_WRITEL(dev, AD_DMA_WAVCTRL, tmp32);

	/* unmute... */
	tmp16 = AD1889_READW(dev, AD_DS_WADA);
	tmp16 &= ~0x8080;
	AD1889_WRITEW(dev, AD_DS_WADA, tmp16);
}

static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
{
	int err;
	ad1889_dev_t *dev;
	unsigned long bar;
	struct proc_dir_entry *proc_root = NULL;

	if ((err = pci_enable_device(pcidev)) != 0) {
		printk(KERN_ERR DEVNAME ": pci_enable_device failed\n");
		return err;
	}

	pci_set_master(pcidev);
	if ((dev = ad1889_alloc_dev(pcidev)) == NULL) {
		printk(KERN_ERR DEVNAME ": cannot allocate memory for device\n");
		return -ENOMEM;
	}
	pci_set_drvdata(pcidev, dev);
	bar = pci_resource_start(pcidev, 0);
	
        if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) {
		printk(KERN_ERR DEVNAME ": memory region not assigned\n");
		goto out1;
	}

	if (pci_request_region(pcidev, 0, DEVNAME)) {
		printk(KERN_ERR DEVNAME ": unable to request memory region\n");
		goto out1;
	}

	dev->regbase = ioremap_nocache(bar, AD_DS_IOMEMSIZE);
	if (!dev->regbase) {
		printk(KERN_ERR DEVNAME ": unable to remap iomem\n");
		goto out2;
	}

	if (request_irq(pcidev->irq, ad1889_interrupt, SA_SHIRQ, DEVNAME, dev) != 0) {
		printk(KERN_ERR DEVNAME ": unable to request interrupt\n");
		goto out3;
	}

	printk(KERN_INFO DEVNAME ": %s at %p IRQ %d\n",
		(char *)ent->driver_data, dev->regbase, pcidev->irq);

	if (ad1889_aclink_reset(pcidev) != 0)
		goto out4;

	/* register /dev/dsp */
	if ((dev->dev_audio = register_sound_dsp(&ad1889_fops, -1)) < 0) {
		printk(KERN_ERR DEVNAME ": cannot register /dev/dsp\n");
		goto out4;
	}

	if ((err = ad1889_ac97_init(dev, 0)) != 0)
		goto out5;

	/* XXX: cleanups */
	if (((proc_root = proc_mkdir("driver/ad1889", NULL)) == NULL) ||
	    create_proc_read_entry("ac97", S_IFREG|S_IRUGO, proc_root, ac97_read_proc, dev->ac97_codec) == NULL ||
	    create_proc_read_entry("info", S_IFREG|S_IRUGO, proc_root, ad1889_read_proc, dev) == NULL) 
		goto out5;
	
	ad1889_initcfg(dev);

	//DBG(DEVNAME ": Driver initialization done!\n");

	ad1889_dev = dev;

	return 0;

out5:
	unregister_sound_dsp(dev->dev_audio);
out4:
	free_irq(pcidev->irq, dev);
out3:
	iounmap(dev->regbase);
out2:
	pci_release_region(pcidev, 0);
out1:
	ad1889_free_dev(dev);
	pci_set_drvdata(pcidev, NULL);

	return -ENODEV;
}

static void __devexit ad1889_remove(struct pci_dev *pcidev)
{
	ad1889_dev_t *dev = pci_get_drvdata(pcidev);

	if (dev == NULL) return;
	
	unregister_sound_mixer(dev->ac97_codec->dev_mixer);
	unregister_sound_dsp(dev->dev_audio);
	free_irq(pcidev->irq, dev);
	iounmap(dev->regbase);
	pci_release_region(pcidev, 0);

	/* any hw programming needed? */
	ad1889_free_dev(dev);
	pci_set_drvdata(pcidev, NULL);
}

MODULE_AUTHOR("Randolph Chung");
MODULE_DESCRIPTION("Analog Devices AD1889 PCI Audio");
MODULE_LICENSE("GPL");

static struct pci_driver ad1889_driver = {
	.name		= DEVNAME,
	.id_table	= ad1889_id_tbl,
	.probe		= ad1889_probe,
	.remove		= __devexit_p(ad1889_remove),
};

static int __init ad1889_init_module(void)
{
	return pci_register_driver(&ad1889_driver);
}

static void ad1889_exit_module(void)
{
	pci_unregister_driver(&ad1889_driver);
	return;
}

module_init(ad1889_init_module);
module_exit(ad1889_exit_module);
