/*
 *  Routines for Gravis UltraSound soundcards
 *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
 *
 *
 *   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <sound/driver.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <sound/core.h>
#include <sound/gus.h>
#include <sound/control.h>

#include <asm/dma.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards");
MODULE_LICENSE("GPL");

static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches);

int snd_gus_use_inc(struct snd_gus_card * gus)
{
	if (!try_module_get(gus->card->module))
		return 0;
	return 1;
}

void snd_gus_use_dec(struct snd_gus_card * gus)
{
	module_put(gus->card->module);
}

static int snd_gus_joystick_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 1;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 31;
	return 0;
}

static int snd_gus_joystick_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
	
	ucontrol->value.integer.value[0] = gus->joystick_dac & 31;
	return 0;
}

static int snd_gus_joystick_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
	unsigned long flags;
	int change;
	unsigned char nval;
	
	nval = ucontrol->value.integer.value[0] & 31;
	spin_lock_irqsave(&gus->reg_lock, flags);
	change = gus->joystick_dac != nval;
	gus->joystick_dac = nval;
	snd_gf1_write8(gus, SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL, gus->joystick_dac);
	spin_unlock_irqrestore(&gus->reg_lock, flags);
	return change;
}

static struct snd_kcontrol_new snd_gus_joystick_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
	.name = "Joystick Speed",
	.info = snd_gus_joystick_info,
	.get = snd_gus_joystick_get,
	.put = snd_gus_joystick_put
};

static void snd_gus_init_control(struct snd_gus_card *gus)
{
	if (!gus->ace_flag)
		snd_ctl_add(gus->card, snd_ctl_new1(&snd_gus_joystick_control, gus));
}

/*
 *
 */

static int snd_gus_free(struct snd_gus_card *gus)
{
	if (gus->gf1.res_port2 == NULL)
		goto __hw_end;
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	if (gus->seq_dev) {
		snd_device_free(gus->card, gus->seq_dev);
		gus->seq_dev = NULL;
	}
#endif
	snd_gf1_stop(gus);
	snd_gus_init_dma_irq(gus, 0);
      __hw_end:
	release_and_free_resource(gus->gf1.res_port1);
	release_and_free_resource(gus->gf1.res_port2);
	if (gus->gf1.irq >= 0)
		free_irq(gus->gf1.irq, (void *) gus);
	if (gus->gf1.dma1 >= 0) {
		disable_dma(gus->gf1.dma1);
		free_dma(gus->gf1.dma1);
	}
	if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
		disable_dma(gus->gf1.dma2);
		free_dma(gus->gf1.dma2);
	}
	kfree(gus);
	return 0;
}

static int snd_gus_dev_free(struct snd_device *device)
{
	struct snd_gus_card *gus = device->device_data;
	return snd_gus_free(gus);
}

int snd_gus_create(struct snd_card *card,
		   unsigned long port,
		   int irq, int dma1, int dma2,
		   int timer_dev,
		   int voices,
		   int pcm_channels,
		   int effect,
		   struct snd_gus_card **rgus)
{
	struct snd_gus_card *gus;
	int err;
	static struct snd_device_ops ops = {
		.dev_free =	snd_gus_dev_free,
	};

	*rgus = NULL;
	gus = kzalloc(sizeof(*gus), GFP_KERNEL);
	if (gus == NULL)
		return -ENOMEM;
	gus->gf1.irq = -1;
	gus->gf1.dma1 = -1;
	gus->gf1.dma2 = -1;
	gus->card = card;
	gus->gf1.port = port;
	/* fill register variables for speedup */
	gus->gf1.reg_page = GUSP(gus, GF1PAGE);
	gus->gf1.reg_regsel = GUSP(gus, GF1REGSEL);
	gus->gf1.reg_data8 = GUSP(gus, GF1DATAHIGH);
	gus->gf1.reg_data16 = GUSP(gus, GF1DATALOW);
	gus->gf1.reg_irqstat = GUSP(gus, IRQSTAT);
	gus->gf1.reg_dram = GUSP(gus, DRAM);
	gus->gf1.reg_timerctrl = GUSP(gus, TIMERCNTRL);
	gus->gf1.reg_timerdata = GUSP(gus, TIMERDATA);
	/* allocate resources */
	if ((gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)")) == NULL) {
		snd_printk(KERN_ERR "gus: can't grab SB port 0x%lx\n", port);
		snd_gus_free(gus);
		return -EBUSY;
	}
	if ((gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)")) == NULL) {
		snd_printk(KERN_ERR "gus: can't grab synth port 0x%lx\n", port + 0x100);
		snd_gus_free(gus);
		return -EBUSY;
	}
	if (irq >= 0 && request_irq(irq, snd_gus_interrupt, SA_INTERRUPT, "GUS GF1", (void *) gus)) {
		snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq);
		snd_gus_free(gus);
		return -EBUSY;
	}
	gus->gf1.irq = irq;
	if (request_dma(dma1, "GUS - 1")) {
		snd_printk(KERN_ERR "gus: can't grab DMA1 %d\n", dma1);
		snd_gus_free(gus);
		return -EBUSY;
	}
	gus->gf1.dma1 = dma1;
	if (dma2 >= 0 && dma1 != dma2) {
		if (request_dma(dma2, "GUS - 2")) {
			snd_printk(KERN_ERR "gus: can't grab DMA2 %d\n", dma2);
			snd_gus_free(gus);
			return -EBUSY;
		}
		gus->gf1.dma2 = dma2;
	} else {
		gus->gf1.dma2 = gus->gf1.dma1;
		gus->equal_dma = 1;
	}
	gus->timer_dev = timer_dev;
	if (voices < 14)
		voices = 14;
	if (voices > 32)
		voices = 32;
	if (pcm_channels < 0)
		pcm_channels = 0;
	if (pcm_channels > 8)
		pcm_channels = 8;
	pcm_channels++;
	pcm_channels &= ~1;
	gus->gf1.effect = effect ? 1 : 0;
	gus->gf1.active_voices = voices;
	gus->gf1.pcm_channels = pcm_channels;
	gus->gf1.volume_ramp = 25;
	gus->gf1.smooth_pan = 1;
	spin_lock_init(&gus->reg_lock);
	spin_lock_init(&gus->voice_alloc);
	spin_lock_init(&gus->active_voice_lock);
	spin_lock_init(&gus->event_lock);
	spin_lock_init(&gus->dma_lock);
	spin_lock_init(&gus->pcm_volume_level_lock);
	spin_lock_init(&gus->uart_cmd_lock);
	mutex_init(&gus->dma_mutex);
	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops)) < 0) {
		snd_gus_free(gus);
		return err;
	}
	*rgus = gus;
	return 0;
}

/*
 *  Memory detection routine for plain GF1 soundcards
 */

static int snd_gus_detect_memory(struct snd_gus_card * gus)
{
	int l, idx, local;
	unsigned char d;

	snd_gf1_poke(gus, 0L, 0xaa);
	snd_gf1_poke(gus, 1L, 0x55);
	if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) {
		snd_printk(KERN_ERR "plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
		return -ENOMEM;
	}
	for (idx = 1, d = 0xab; idx < 4; idx++, d++) {
		local = idx << 18;
		snd_gf1_poke(gus, local, d);
		snd_gf1_poke(gus, local + 1, d + 1);
		if (snd_gf1_peek(gus, local) != d ||
		    snd_gf1_peek(gus, local + 1) != d + 1 ||
		    snd_gf1_peek(gus, 0L) != 0xaa)
			break;
	}
#if 1
	gus->gf1.memory = idx << 18;
#else
	gus->gf1.memory = 256 * 1024;
#endif
	for (l = 0, local = gus->gf1.memory; l < 4; l++, local -= 256 * 1024) {
		gus->gf1.mem_alloc.banks_8[l].address =
		    gus->gf1.mem_alloc.banks_8[l].size = 0;
		gus->gf1.mem_alloc.banks_16[l].address = l << 18;
		gus->gf1.mem_alloc.banks_16[l].size = local > 0 ? 256 * 1024 : 0;
	}
	gus->gf1.mem_alloc.banks_8[0].size = gus->gf1.memory;
	return 0;		/* some memory were detected */
}

static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
{
	struct snd_card *card;
	unsigned long flags;
	int irq, dma1, dma2;
	static unsigned char irqs[16] =
		{0, 0, 1, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
	static unsigned char dmas[8] =
		{6, 1, 0, 2, 0, 3, 4, 5};

	snd_assert(gus != NULL, return -EINVAL);
	card = gus->card;
	snd_assert(card != NULL, return -EINVAL);

	gus->mix_cntrl_reg &= 0xf8;
	gus->mix_cntrl_reg |= 0x01;	/* disable MIC, LINE IN, enable LINE OUT */
	if (gus->codec_flag || gus->ess_flag) {
		gus->mix_cntrl_reg &= ~1;	/* enable LINE IN */
		gus->mix_cntrl_reg |= 4;	/* enable MIC */
	}
	dma1 = gus->gf1.dma1;
	dma1 = dma1 < 0 ? -dma1 : dma1;
	dma1 = dmas[dma1 & 7];
	dma2 = gus->gf1.dma2;
	dma2 = dma2 < 0 ? -dma2 : dma2;
	dma2 = dmas[dma2 & 7];
	dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);

	if ((dma1 & 7) == 0 || (dma2 & 7) == 0) {
		snd_printk(KERN_ERR "Error! DMA isn't defined.\n");
		return -EINVAL;
	}
	irq = gus->gf1.irq;
	irq = irq < 0 ? -irq : irq;
	irq = irqs[irq & 0x0f];
	if (irq == 0) {
		snd_printk(KERN_ERR "Error! IRQ isn't defined.\n");
		return -EINVAL;
	}
	irq |= 0x40;
#if 0
	card->mixer.mix_ctrl_reg |= 0x10;
#endif

	spin_lock_irqsave(&gus->reg_lock, flags);
	outb(5, GUSP(gus, REGCNTRLS));
	outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
	outb(0x00, GUSP(gus, IRQDMACNTRLREG));
	outb(0, GUSP(gus, REGCNTRLS));
	spin_unlock_irqrestore(&gus->reg_lock, flags);

	udelay(100);

	spin_lock_irqsave(&gus->reg_lock, flags);
	outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
	outb(dma1, GUSP(gus, IRQDMACNTRLREG));
	if (latches) {
		outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
		outb(irq, GUSP(gus, IRQDMACNTRLREG));
	}
	spin_unlock_irqrestore(&gus->reg_lock, flags);

	udelay(100);

	spin_lock_irqsave(&gus->reg_lock, flags);
	outb(0x00 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
	outb(dma1, GUSP(gus, IRQDMACNTRLREG));
	if (latches) {
		outb(0x40 | gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
		outb(irq, GUSP(gus, IRQDMACNTRLREG));
	}
	spin_unlock_irqrestore(&gus->reg_lock, flags);

	snd_gf1_delay(gus);

	if (latches)
		gus->mix_cntrl_reg |= 0x08;	/* enable latches */
	else
		gus->mix_cntrl_reg &= ~0x08;	/* disable latches */
	spin_lock_irqsave(&gus->reg_lock, flags);
	outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
	outb(0, GUSP(gus, GF1PAGE));
	spin_unlock_irqrestore(&gus->reg_lock, flags);

	return 0;
}

static int snd_gus_check_version(struct snd_gus_card * gus)
{
	unsigned long flags;
	unsigned char val, rev;
	struct snd_card *card;

	card = gus->card;
	spin_lock_irqsave(&gus->reg_lock, flags);
	outb(0x20, GUSP(gus, REGCNTRLS));
	val = inb(GUSP(gus, REGCNTRLS));
	rev = inb(GUSP(gus, BOARDVERSION));
	spin_unlock_irqrestore(&gus->reg_lock, flags);
	snd_printdd("GF1 [0x%lx] init - val = 0x%x, rev = 0x%x\n", gus->gf1.port, val, rev);
	strcpy(card->driver, "GUS");
	strcpy(card->longname, "Gravis UltraSound Classic (2.4)");
	if ((val != 255 && (val & 0x06)) || (rev >= 5 && rev != 255)) {
		if (rev >= 5 && rev <= 9) {
			gus->ics_flag = 1;
			if (rev == 5)
				gus->ics_flipped = 1;
			card->longname[27] = '3';
			card->longname[29] = rev == 5 ? '5' : '7';
		}
		if (rev >= 10 && rev != 255) {
			if (rev >= 10 && rev <= 11) {
				strcpy(card->driver, "GUS MAX");
				strcpy(card->longname, "Gravis UltraSound MAX");
				gus->max_flag = 1;
			} else if (rev == 0x30) {
				strcpy(card->driver, "GUS ACE");
				strcpy(card->longname, "Gravis UltraSound Ace");
				gus->ace_flag = 1;
			} else if (rev == 0x50) {
				strcpy(card->driver, "GUS Extreme");
				strcpy(card->longname, "Gravis UltraSound Extreme");
				gus->ess_flag = 1;
			} else {
				snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
				snd_printk(KERN_ERR "  please - report to <perex@suse.cz>\n");
			}
		}
	}
	strcpy(card->shortname, card->longname);
	gus->uart_enable = 1;	/* standard GUSes doesn't have midi uart trouble */
	snd_gus_init_control(gus);
	return 0;
}

#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
static void snd_gus_seq_dev_free(struct snd_seq_device *seq_dev)
{
	struct snd_gus_card *gus = seq_dev->private_data;
	gus->seq_dev = NULL;
}
#endif

int snd_gus_initialize(struct snd_gus_card *gus)
{
	int err;

	if (!gus->interwave) {
		if ((err = snd_gus_check_version(gus)) < 0) {
			snd_printk(KERN_ERR "version check failed\n");
			return err;
		}
		if ((err = snd_gus_detect_memory(gus)) < 0)
			return err;
	}
	if ((err = snd_gus_init_dma_irq(gus, 1)) < 0)
		return err;
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	if (snd_seq_device_new(gus->card, 1, SNDRV_SEQ_DEV_ID_GUS,
			       sizeof(struct snd_gus_card *), &gus->seq_dev) >= 0) {
		strcpy(gus->seq_dev->name, "GUS");
		*(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(gus->seq_dev) = gus;
		gus->seq_dev->private_data = gus;
		gus->seq_dev->private_free = snd_gus_seq_dev_free;
	}
#endif
	snd_gf1_start(gus);
	gus->initialized = 1;
	return 0;
}

  /* gus_io.c */
EXPORT_SYMBOL(snd_gf1_delay);
EXPORT_SYMBOL(snd_gf1_write8);
EXPORT_SYMBOL(snd_gf1_look8);
EXPORT_SYMBOL(snd_gf1_write16);
EXPORT_SYMBOL(snd_gf1_look16);
EXPORT_SYMBOL(snd_gf1_i_write8);
EXPORT_SYMBOL(snd_gf1_i_look8);
EXPORT_SYMBOL(snd_gf1_i_look16);
EXPORT_SYMBOL(snd_gf1_dram_addr);
EXPORT_SYMBOL(snd_gf1_write_addr);
EXPORT_SYMBOL(snd_gf1_poke);
EXPORT_SYMBOL(snd_gf1_peek);
  /* gus_reset.c */
EXPORT_SYMBOL(snd_gf1_alloc_voice);
EXPORT_SYMBOL(snd_gf1_free_voice);
EXPORT_SYMBOL(snd_gf1_ctrl_stop);
EXPORT_SYMBOL(snd_gf1_stop_voice);
  /* gus_mixer.c */
EXPORT_SYMBOL(snd_gf1_new_mixer);
  /* gus_pcm.c */
EXPORT_SYMBOL(snd_gf1_pcm_new);
  /* gus.c */
EXPORT_SYMBOL(snd_gus_use_inc);
EXPORT_SYMBOL(snd_gus_use_dec);
EXPORT_SYMBOL(snd_gus_create);
EXPORT_SYMBOL(snd_gus_initialize);
  /* gus_irq.c */
EXPORT_SYMBOL(snd_gus_interrupt);
  /* gus_uart.c */
EXPORT_SYMBOL(snd_gf1_rawmidi_new);
  /* gus_dram.c */
EXPORT_SYMBOL(snd_gus_dram_write);
EXPORT_SYMBOL(snd_gus_dram_read);
  /* gus_volume.c */
EXPORT_SYMBOL(snd_gf1_lvol_to_gvol_raw);
EXPORT_SYMBOL(snd_gf1_translate_freq);
  /* gus_mem.c */
EXPORT_SYMBOL(snd_gf1_mem_alloc);
EXPORT_SYMBOL(snd_gf1_mem_xfree);
EXPORT_SYMBOL(snd_gf1_mem_free);
EXPORT_SYMBOL(snd_gf1_mem_lock);

/*
 *  INIT part
 */

static int __init alsa_gus_init(void)
{
	return 0;
}

static void __exit alsa_gus_exit(void)
{
}

module_init(alsa_gus_init)
module_exit(alsa_gus_exit)
