// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
 *                   Creative Labs, Inc.
 *  Routines for control of EMU10K1 chips
 *
 *  BUGS:
 *    --
 *
 *  TODO:
 *    --
 */

#include <linux/time.h>
#include <sound/core.h>
#include <sound/emu10k1.h>
#include <linux/delay.h>
#include <linux/export.h>
#include "p17v.h"

static inline bool check_ptr_reg(struct snd_emu10k1 *emu, unsigned int reg)
{
	if (snd_BUG_ON(!emu))
		return false;
	if (snd_BUG_ON(reg & (emu->audigy ? (0xffff0000 & ~A_PTR_ADDRESS_MASK)
					  : (0xffff0000 & ~PTR_ADDRESS_MASK))))
		return false;
	if (snd_BUG_ON(reg & 0x0000ffff & ~PTR_CHANNELNUM_MASK))
		return false;
	return true;
}

unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
{
	unsigned long flags;
	unsigned int regptr, val;
	unsigned int mask;

	regptr = (reg << 16) | chn;
	if (!check_ptr_reg(emu, regptr))
		return 0;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outl(regptr, emu->port + PTR);
	val = inl(emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);

	if (reg & 0xff000000) {
		unsigned char size, offset;
		
		size = (reg >> 24) & 0x3f;
		offset = (reg >> 16) & 0x1f;
		mask = (1 << size) - 1;
		
		return (val >> offset) & mask;
	} else {
		return val;
	}
}

EXPORT_SYMBOL(snd_emu10k1_ptr_read);

void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
{
	unsigned int regptr;
	unsigned long flags;
	unsigned int mask;

	regptr = (reg << 16) | chn;
	if (!check_ptr_reg(emu, regptr))
		return;

	if (reg & 0xff000000) {
		unsigned char size, offset;

		size = (reg >> 24) & 0x3f;
		offset = (reg >> 16) & 0x1f;
		mask = (1 << size) - 1;
		if (snd_BUG_ON(data & ~mask))
			return;
		mask <<= offset;
		data <<= offset;

		spin_lock_irqsave(&emu->emu_lock, flags);
		outl(regptr, emu->port + PTR);
		data |= inl(emu->port + DATA) & ~mask;
	} else {
		spin_lock_irqsave(&emu->emu_lock, flags);
		outl(regptr, emu->port + PTR);
	}
	outl(data, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

EXPORT_SYMBOL(snd_emu10k1_ptr_write);

void snd_emu10k1_ptr_write_multiple(struct snd_emu10k1 *emu, unsigned int chn, ...)
{
	va_list va;
	u32 addr_mask;
	unsigned long flags;

	if (snd_BUG_ON(!emu))
		return;
	if (snd_BUG_ON(chn & ~PTR_CHANNELNUM_MASK))
		return;
	addr_mask = ~((emu->audigy ? A_PTR_ADDRESS_MASK : PTR_ADDRESS_MASK) >> 16);

	va_start(va, chn);
	spin_lock_irqsave(&emu->emu_lock, flags);
	for (;;) {
		u32 data;
		u32 reg = va_arg(va, u32);
		if (reg == REGLIST_END)
			break;
		data = va_arg(va, u32);
		if (snd_BUG_ON(reg & addr_mask))  // Only raw registers supported here
			continue;
		outl((reg << 16) | chn, emu->port + PTR);
		outl(data, emu->port + DATA);
	}
	spin_unlock_irqrestore(&emu->emu_lock, flags);
	va_end(va);
}

EXPORT_SYMBOL(snd_emu10k1_ptr_write_multiple);

unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, 
					  unsigned int reg, 
					  unsigned int chn)
{
	unsigned long flags;
	unsigned int regptr, val;
  
	regptr = (reg << 16) | chn;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outl(regptr, emu->port + PTR2);
	val = inl(emu->port + DATA2);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
	return val;
}

void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, 
				   unsigned int reg, 
				   unsigned int chn, 
				   unsigned int data)
{
	unsigned int regptr;
	unsigned long flags;

	regptr = (reg << 16) | chn;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outl(regptr, emu->port + PTR2);
	outl(data, emu->port + DATA2);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
				   unsigned int data)
{
	unsigned int reset, set;
	unsigned int reg, tmp;
	int n, result;
	int err = 0;

	/* This function is not re-entrant, so protect against it. */
	spin_lock(&emu->spi_lock);
	if (emu->card_capabilities->ca0108_chip)
		reg = P17V_SPI;
	else {
		/* For other chip types the SPI register
		 * is currently unknown. */
		err = 1;
		goto spi_write_exit;
	}
	if (data > 0xffff) {
		/* Only 16bit values allowed */
		err = 1;
		goto spi_write_exit;
	}

	tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
	reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
	set = reset | 0x10000; /* Set xxx1xxxx */
	snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
	tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
	snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
	result = 1;
	/* Wait for status bit to return to 0 */
	for (n = 0; n < 100; n++) {
		udelay(10);
		tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
		if (!(tmp & 0x10000)) {
			result = 0;
			break;
		}
	}
	if (result) {
		/* Timed out */
		err = 1;
		goto spi_write_exit;
	}
	snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
	tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
	err = 0;
spi_write_exit:
	spin_unlock(&emu->spi_lock);
	return err;
}

/* The ADC does not support i2c read, so only write is implemented */
int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
				u32 reg,
				u32 value)
{
	u32 tmp;
	int timeout = 0;
	int status;
	int retry;
	int err = 0;

	if ((reg > 0x7f) || (value > 0x1ff)) {
		dev_err(emu->card->dev, "i2c_write: invalid values.\n");
		return -EINVAL;
	}

	/* This function is not re-entrant, so protect against it. */
	spin_lock(&emu->i2c_lock);

	tmp = reg << 25 | value << 16;

	/* This controls the I2C connected to the WM8775 ADC Codec */
	snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
	tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */

	for (retry = 0; retry < 10; retry++) {
		/* Send the data to i2c */
		tmp = 0;
		tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
		snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);

		/* Wait till the transaction ends */
		while (1) {
			mdelay(1);
			status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
			timeout++;
			if ((status & I2C_A_ADC_START) == 0)
				break;

			if (timeout > 1000) {
				dev_warn(emu->card->dev,
					   "emu10k1:I2C:timeout status=0x%x\n",
					   status);
				break;
			}
		}
		//Read back and see if the transaction is successful
		if ((status & I2C_A_ADC_ABORT) == 0)
			break;
	}

	if (retry == 10) {
		dev_err(emu->card->dev, "Writing to ADC failed!\n");
		dev_err(emu->card->dev, "status=0x%x, reg=%d, value=%d\n",
			status, reg, value);
		/* dump_stack(); */
		err = -EINVAL;
	}
    
	spin_unlock(&emu->i2c_lock);
	return err;
}

static void snd_emu1010_fpga_write_locked(struct snd_emu10k1 *emu, u32 reg, u32 value)
{
	if (snd_BUG_ON(reg > 0x3f))
		return;
	reg += 0x40; /* 0x40 upwards are registers. */
	if (snd_BUG_ON(value > 0x3f)) /* 0 to 0x3f are values */
		return;
	outw(reg, emu->port + A_GPIO);
	udelay(10);
	outw(reg | 0x80, emu->port + A_GPIO);  /* High bit clocks the value into the fpga. */
	udelay(10);
	outw(value, emu->port + A_GPIO);
	udelay(10);
	outw(value | 0x80 , emu->port + A_GPIO);  /* High bit clocks the value into the fpga. */
}

void snd_emu1010_fpga_write(struct snd_emu10k1 *emu, u32 reg, u32 value)
{
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	snd_emu1010_fpga_write_locked(emu, reg, value);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

static void snd_emu1010_fpga_read_locked(struct snd_emu10k1 *emu, u32 reg, u32 *value)
{
	// The higest input pin is used as the designated interrupt trigger,
	// so it needs to be masked out.
	u32 mask = emu->card_capabilities->ca0108_chip ? 0x1f : 0x7f;
	if (snd_BUG_ON(reg > 0x3f))
		return;
	reg += 0x40; /* 0x40 upwards are registers. */
	outw(reg, emu->port + A_GPIO);
	udelay(10);
	outw(reg | 0x80, emu->port + A_GPIO);  /* High bit clocks the value into the fpga. */
	udelay(10);
	*value = ((inw(emu->port + A_GPIO) >> 8) & mask);
}

void snd_emu1010_fpga_read(struct snd_emu10k1 *emu, u32 reg, u32 *value)
{
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	snd_emu1010_fpga_read_locked(emu, reg, value);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

/* Each Destination has one and only one Source,
 * but one Source can feed any number of Destinations simultaneously.
 */
void snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 *emu, u32 dst, u32 src)
{
	unsigned long flags;

	if (snd_BUG_ON(dst & ~0x71f))
		return;
	if (snd_BUG_ON(src & ~0x71f))
		return;
	spin_lock_irqsave(&emu->emu_lock, flags);
	snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);
	snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);
	snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCHI, src >> 8);
	snd_emu1010_fpga_write_locked(emu, EMU_HANA_SRCLO, src & 0x1f);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

u32 snd_emu1010_fpga_link_dst_src_read(struct snd_emu10k1 *emu, u32 dst)
{
	unsigned long flags;
	u32 hi, lo;

	if (snd_BUG_ON(dst & ~0x71f))
		return 0;
	spin_lock_irqsave(&emu->emu_lock, flags);
	snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTHI, dst >> 8);
	snd_emu1010_fpga_write_locked(emu, EMU_HANA_DESTLO, dst & 0x1f);
	snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCHI, &hi);
	snd_emu1010_fpga_read_locked(emu, EMU_HANA_SRCLO, &lo);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
	return (hi << 8) | lo;
}

int snd_emu1010_get_raw_rate(struct snd_emu10k1 *emu, u8 src)
{
	u32 reg_lo, reg_hi, value, value2;

	switch (src) {
	case EMU_HANA_WCLOCK_HANA_SPDIF_IN:
		snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &value);
		if (value & EMU_HANA_SPDIF_MODE_RX_INVALID)
			return 0;
		reg_lo = EMU_HANA_WC_SPDIF_LO;
		reg_hi = EMU_HANA_WC_SPDIF_HI;
		break;
	case EMU_HANA_WCLOCK_HANA_ADAT_IN:
		reg_lo = EMU_HANA_WC_ADAT_LO;
		reg_hi = EMU_HANA_WC_ADAT_HI;
		break;
	case EMU_HANA_WCLOCK_SYNC_BNC:
		reg_lo = EMU_HANA_WC_BNC_LO;
		reg_hi = EMU_HANA_WC_BNC_HI;
		break;
	case EMU_HANA_WCLOCK_2ND_HANA:
		reg_lo = EMU_HANA2_WC_SPDIF_LO;
		reg_hi = EMU_HANA2_WC_SPDIF_HI;
		break;
	default:
		return 0;
	}
	snd_emu1010_fpga_read(emu, reg_hi, &value);
	snd_emu1010_fpga_read(emu, reg_lo, &value2);
	// FIXME: The /4 is valid for 0404b, but contradicts all other info.
	return 0x1770000 / 4 / (((value << 5) | value2) + 1);
}

void snd_emu1010_update_clock(struct snd_emu10k1 *emu)
{
	int clock;
	u32 leds;

	switch (emu->emu1010.wclock) {
	case EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X:
		clock = 44100;
		leds = EMU_HANA_DOCK_LEDS_2_44K;
		break;
	case EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X:
		clock = 48000;
		leds = EMU_HANA_DOCK_LEDS_2_48K;
		break;
	default:
		clock = snd_emu1010_get_raw_rate(
				emu, emu->emu1010.wclock & EMU_HANA_WCLOCK_SRC_MASK);
		// The raw rate reading is rather coarse (it cannot accurately
		// represent 44.1 kHz) and fluctuates slightly. Luckily, the
		// clock comes from digital inputs, which use standardized rates.
		// So we round to the closest standard rate and ignore discrepancies.
		if (clock < 46000) {
			clock = 44100;
			leds = EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_44K;
		} else {
			clock = 48000;
			leds = EMU_HANA_DOCK_LEDS_2_EXT | EMU_HANA_DOCK_LEDS_2_48K;
		}
		break;
	}
	emu->emu1010.word_clock = clock;

	// FIXME: this should probably represent the AND of all currently
	// used sources' lock status. But we don't know how to get that ...
	leds |= EMU_HANA_DOCK_LEDS_2_LOCK;

	snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, leds);
}

void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
	unsigned long flags;
	unsigned int enable;

	spin_lock_irqsave(&emu->emu_lock, flags);
	enable = inl(emu->port + INTE) | intrenb;
	outl(enable, emu->port + INTE);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
{
	unsigned long flags;
	unsigned int enable;

	spin_lock_irqsave(&emu->emu_lock, flags);
	enable = inl(emu->port + INTE) & ~intrenb;
	outl(enable, emu->port + INTE);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;
	unsigned int val;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(CLIEH << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val |= 1 << (voicenum - 32);
	} else {
		outl(CLIEL << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val |= 1 << voicenum;
	}
	outl(val, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;
	unsigned int val;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(CLIEH << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val &= ~(1 << (voicenum - 32));
	} else {
		outl(CLIEL << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val &= ~(1 << voicenum);
	}
	outl(val, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(CLIPH << 16, emu->port + PTR);
		voicenum = 1 << (voicenum - 32);
	} else {
		outl(CLIPL << 16, emu->port + PTR);
		voicenum = 1 << voicenum;
	}
	outl(voicenum, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;
	unsigned int val;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(HLIEH << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val |= 1 << (voicenum - 32);
	} else {
		outl(HLIEL << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val |= 1 << voicenum;
	}
	outl(val, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;
	unsigned int val;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(HLIEH << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val &= ~(1 << (voicenum - 32));
	} else {
		outl(HLIEL << 16, emu->port + PTR);
		val = inl(emu->port + DATA);
		val &= ~(1 << voicenum);
	}
	outl(val, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(HLIPH << 16, emu->port + PTR);
		voicenum = 1 << (voicenum - 32);
	} else {
		outl(HLIPL << 16, emu->port + PTR);
		voicenum = 1 << voicenum;
	}
	outl(voicenum, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

#if 0
void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;
	unsigned int sol;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(SOLEH << 16, emu->port + PTR);
		sol = inl(emu->port + DATA);
		sol |= 1 << (voicenum - 32);
	} else {
		outl(SOLEL << 16, emu->port + PTR);
		sol = inl(emu->port + DATA);
		sol |= 1 << voicenum;
	}
	outl(sol, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
{
	unsigned long flags;
	unsigned int sol;

	spin_lock_irqsave(&emu->emu_lock, flags);
	if (voicenum >= 32) {
		outl(SOLEH << 16, emu->port + PTR);
		sol = inl(emu->port + DATA);
		sol &= ~(1 << (voicenum - 32));
	} else {
		outl(SOLEL << 16, emu->port + PTR);
		sol = inl(emu->port + DATA);
		sol &= ~(1 << voicenum);
	}
	outl(sol, emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}
#endif

void snd_emu10k1_voice_set_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices)
{
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outl(SOLEL << 16, emu->port + PTR);
	outl(inl(emu->port + DATA) | (u32)voices, emu->port + DATA);
	outl(SOLEH << 16, emu->port + PTR);
	outl(inl(emu->port + DATA) | (u32)(voices >> 32), emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

void snd_emu10k1_voice_clear_loop_stop_multiple(struct snd_emu10k1 *emu, u64 voices)
{
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outl(SOLEL << 16, emu->port + PTR);
	outl(inl(emu->port + DATA) & (u32)~voices, emu->port + DATA);
	outl(SOLEH << 16, emu->port + PTR);
	outl(inl(emu->port + DATA) & (u32)(~voices >> 32), emu->port + DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}

int snd_emu10k1_voice_clear_loop_stop_multiple_atomic(struct snd_emu10k1 *emu, u64 voices)
{
	unsigned long flags;
	u32 soll, solh;
	int ret = -EIO;

	spin_lock_irqsave(&emu->emu_lock, flags);

	outl(SOLEL << 16, emu->port + PTR);
	soll = inl(emu->port + DATA);
	outl(SOLEH << 16, emu->port + PTR);
	solh = inl(emu->port + DATA);

	soll &= (u32)~voices;
	solh &= (u32)(~voices >> 32);

	for (int tries = 0; tries < 1000; tries++) {
		const u32 quart = 1U << (REG_SIZE(WC_CURRENTCHANNEL) - 2);
		// First we wait for the third quarter of the sample cycle ...
		u32 wc = inl(emu->port + WC);
		u32 cc = REG_VAL_GET(WC_CURRENTCHANNEL, wc);
		if (cc >= quart * 2 && cc < quart * 3) {
			// ... and release the low voices, while the high ones are serviced.
			outl(SOLEL << 16, emu->port + PTR);
			outl(soll, emu->port + DATA);
			// Then we wait for the first quarter of the next sample cycle ...
			for (; tries < 1000; tries++) {
				cc = REG_VAL_GET(WC_CURRENTCHANNEL, inl(emu->port + WC));
				if (cc < quart)
					goto good;
				// We will block for 10+ us with interrupts disabled. This is
				// not nice at all, but necessary for reasonable reliability.
				udelay(1);
			}
			break;
		good:
			// ... and release the high voices, while the low ones are serviced.
			outl(SOLEH << 16, emu->port + PTR);
			outl(solh, emu->port + DATA);
			// Finally we verify that nothing interfered in fact.
			if (REG_VAL_GET(WC_SAMPLECOUNTER, inl(emu->port + WC)) ==
			    ((REG_VAL_GET(WC_SAMPLECOUNTER, wc) + 1) & REG_MASK0(WC_SAMPLECOUNTER))) {
				ret = 0;
			} else {
				ret = -EAGAIN;
			}
			break;
		}
		// Don't block for too long
		spin_unlock_irqrestore(&emu->emu_lock, flags);
		udelay(1);
		spin_lock_irqsave(&emu->emu_lock, flags);
	}

	spin_unlock_irqrestore(&emu->emu_lock, flags);
	return ret;
}

void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
{
	volatile unsigned count;
	unsigned int newtime = 0, curtime;

	curtime = inl(emu->port + WC) >> 6;
	while (wait-- > 0) {
		count = 0;
		while (count++ < 16384) {
			newtime = inl(emu->port + WC) >> 6;
			if (newtime != curtime)
				break;
		}
		if (count > 16384)
			break;
		curtime = newtime;
	}
}

unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
	struct snd_emu10k1 *emu = ac97->private_data;
	unsigned long flags;
	unsigned short val;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outb(reg, emu->port + AC97ADDRESS);
	val = inw(emu->port + AC97DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
	return val;
}

void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data)
{
	struct snd_emu10k1 *emu = ac97->private_data;
	unsigned long flags;

	spin_lock_irqsave(&emu->emu_lock, flags);
	outb(reg, emu->port + AC97ADDRESS);
	outw(data, emu->port + AC97DATA);
	spin_unlock_irqrestore(&emu->emu_lock, flags);
}
