// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Routines for Gravis UltraSound soundcards
 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
 */

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

#include <asm/dma.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@perex.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);

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);
	int change;
	unsigned char nval;
	
	nval = ucontrol->value.integer.value[0] & 31;
	guard(spinlock_irqsave)(&gus->reg_lock);
	change = gus->joystick_dac != nval;
	gus->joystick_dac = nval;
	snd_gf1_write8(gus, SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL, gus->joystick_dac);
	return change;
}

static const 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;
	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 const struct snd_device_ops ops = {
		.dev_free =	snd_gus_dev_free,
	};

	*rgus = NULL;
	gus = kzalloc(sizeof(*gus), GFP_KERNEL);
	if (gus == NULL)
		return -ENOMEM;
	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);
	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 */
	gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)");
	if (!gus->gf1.res_port1) {
		dev_err(card->dev, "gus: can't grab SB port 0x%lx\n", port);
		snd_gus_free(gus);
		return -EBUSY;
	}
	gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)");
	if (!gus->gf1.res_port2) {
		dev_err(card->dev, "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, 0, "GUS GF1", (void *) gus)) {
		dev_err(card->dev, "gus: can't grab irq %d\n", irq);
		snd_gus_free(gus);
		return -EBUSY;
	}
	gus->gf1.irq = irq;
	card->sync_irq = irq;
	if (request_dma(dma1, "GUS - 1")) {
		dev_err(card->dev, "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")) {
			dev_err(card->dev, "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;
	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops);
	if (err < 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) {
		dev_err(gus->card->dev,
			"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;
	int irq, dma1, dma2;
	static const unsigned char irqs[16] =
		{0, 0, 1, 3, 0, 2, 0, 4, 0, 1, 0, 5, 6, 0, 0, 7};
	static const unsigned char dmas[8] =
		{6, 1, 0, 2, 0, 3, 4, 5};

	if (snd_BUG_ON(!gus))
		return -EINVAL;
	card = gus->card;
	if (snd_BUG_ON(!card))
		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 = abs(dma1);
	dma1 = dmas[dma1 & 7];
	dma2 = gus->gf1.dma2;
	dma2 = abs(dma2);
	dma2 = dmas[dma2 & 7];
	dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);

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

	scoped_guard(spinlock_irqsave, &gus->reg_lock) {
		outb(5, GUSP(gus, REGCNTRLS));
		outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
		outb(0x00, GUSP(gus, IRQDMACNTRLREG));
		outb(0, GUSP(gus, REGCNTRLS));
	}

	udelay(100);

	scoped_guard(spinlock_irqsave, &gus->reg_lock) {
		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));
		}
	}

	udelay(100);

	scoped_guard(spinlock_irqsave, &gus->reg_lock) {
		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));
		}
	}

	snd_gf1_delay(gus);

	if (latches)
		gus->mix_cntrl_reg |= 0x08;	/* enable latches */
	else
		gus->mix_cntrl_reg &= ~0x08;	/* disable latches */
	scoped_guard(spinlock_irqsave, &gus->reg_lock) {
		outb(gus->mix_cntrl_reg, GUSP(gus, MIXCNTRLREG));
		outb(0, GUSP(gus, GF1PAGE));
	}

	return 0;
}

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

	card = gus->card;
	scoped_guard(spinlock_irqsave, &gus->reg_lock) {
		outb(0x20, GUSP(gus, REGCNTRLS));
		val = inb(GUSP(gus, REGCNTRLS));
		rev = inb(GUSP(gus, BOARDVERSION));
	}
	dev_dbg(card->dev, "GF1 [0x%lx] init - val = 0x%x, rev = 0x%x\n", gus->gf1.port, val, rev);
	strscpy(card->driver, "GUS");
	strscpy(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) {
				strscpy(card->driver, "GUS MAX");
				strscpy(card->longname, "Gravis UltraSound MAX");
				gus->max_flag = 1;
			} else if (rev == 0x30) {
				strscpy(card->driver, "GUS ACE");
				strscpy(card->longname, "Gravis UltraSound Ace");
				gus->ace_flag = 1;
			} else if (rev == 0x50) {
				strscpy(card->driver, "GUS Extreme");
				strscpy(card->longname, "Gravis UltraSound Extreme");
				gus->ess_flag = 1;
			} else {
				dev_err(card->dev,
					"unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n",
					gus->gf1.port, rev, val);
				dev_err(card->dev,
					"  please - report to <perex@perex.cz>\n");
			}
		}
	}
	strscpy(card->shortname, card->longname, sizeof(card->shortname));
	gus->uart_enable = 1;	/* standard GUSes doesn't have midi uart trouble */
	snd_gus_init_control(gus);
	return 0;
}

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

	if (!gus->interwave) {
		err = snd_gus_check_version(gus);
		if (err < 0) {
			dev_err(gus->card->dev, "version check failed\n");
			return err;
		}
		err = snd_gus_detect_memory(gus);
		if (err < 0)
			return err;
	}
	err = snd_gus_init_dma_irq(gus, 1);
	if (err < 0)
		return err;
	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_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);
