// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
 *                   Hannu Savolainen 1993-1996,
 *                   Rob Hooft
 *                   
 *  Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)
 *
 *  Most if code is ported from OSS/Lite.
 */

#include <sound/opl3.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <sound/minors.h>
#include "opl3_voice.h"

MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
MODULE_LICENSE("GPL");

static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
{
	unsigned long flags;
	unsigned long port;

	/*
	 * The original 2-OP synth requires a quite long delay
	 * after writing to a register.
	 */

	port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;

	spin_lock_irqsave(&opl3->reg_lock, flags);

	outb((unsigned char) cmd, port);
	udelay(10);

	outb((unsigned char) val, port + 1);
	udelay(30);

	spin_unlock_irqrestore(&opl3->reg_lock, flags);
}

static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
{
	unsigned long flags;
	unsigned long port;

	/*
	 * The OPL-3 survives with just two INBs
	 * after writing to a register.
	 */

	port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;

	spin_lock_irqsave(&opl3->reg_lock, flags);

	outb((unsigned char) cmd, port);
	inb(opl3->l_port);
	inb(opl3->l_port);

	outb((unsigned char) val, port + 1);
	inb(opl3->l_port);
	inb(opl3->l_port);

	spin_unlock_irqrestore(&opl3->reg_lock, flags);
}

static int snd_opl3_detect(struct snd_opl3 * opl3)
{
	/*
	 * This function returns 1 if the FM chip is present at the given I/O port
	 * The detection algorithm plays with the timer built in the FM chip and
	 * looks for a change in the status register.
	 *
	 * Note! The timers of the FM chip are not connected to AdLib (and compatible)
	 * boards.
	 *
	 * Note2! The chip is initialized if detected.
	 */

	unsigned char stat1, stat2, signature;

	/* Reset timers 1 and 2 */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
	/* Reset the IRQ of the FM chip */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
	signature = stat1 = inb(opl3->l_port);	/* Status register */
	if ((stat1 & 0xe0) != 0x00) {	/* Should be 0x00 */
		dev_dbg(opl3->card->dev, "OPL3: stat1 = 0x%x\n", stat1);
		return -ENODEV;
	}
	/* Set timer1 to 0xff */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
	/* Unmask and start timer 1 */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
	/* Now we have to delay at least 80us */
	udelay(200);
	/* Read status after timers have expired */
	stat2 = inb(opl3->l_port);
	/* Stop the timers */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
	/* Reset the IRQ of the FM chip */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
	if ((stat2 & 0xe0) != 0xc0) {	/* There is no YM3812 */
		dev_dbg(opl3->card->dev, "OPL3: stat2 = 0x%x\n", stat2);
		return -ENODEV;
	}

	/* If the toplevel code knows exactly the type of chip, don't try
	   to detect it. */
	if (opl3->hardware != OPL3_HW_AUTO)
		return 0;

	/* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
	if (signature == 0x06) {	/* OPL2 */
		opl3->hardware = OPL3_HW_OPL2;
	} else {
		/*
		 * If we had an OPL4 chip, opl3->hardware would have been set
		 * by the OPL4 driver; so we can assume OPL3 here.
		 */
		if (snd_BUG_ON(!opl3->r_port))
			return -ENODEV;
		opl3->hardware = OPL3_HW_OPL3;
	}
	return 0;
}

/*
 *  AdLib timers
 */

/*
 *  Timer 1 - 80us
 */

static int snd_opl3_timer1_start(struct snd_timer * timer)
{
	unsigned long flags;
	unsigned char tmp;
	unsigned int ticks;
	struct snd_opl3 *opl3;

	opl3 = snd_timer_chip(timer);
	spin_lock_irqsave(&opl3->timer_lock, flags);
	ticks = timer->sticks;
	tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
	opl3->timer_enable = tmp;
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks);	/* timer 1 count */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);	/* enable timer 1 IRQ */
	spin_unlock_irqrestore(&opl3->timer_lock, flags);
	return 0;
}

static int snd_opl3_timer1_stop(struct snd_timer * timer)
{
	unsigned long flags;
	unsigned char tmp;
	struct snd_opl3 *opl3;

	opl3 = snd_timer_chip(timer);
	spin_lock_irqsave(&opl3->timer_lock, flags);
	tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
	opl3->timer_enable = tmp;
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);	/* disable timer #1 */
	spin_unlock_irqrestore(&opl3->timer_lock, flags);
	return 0;
}

/*
 *  Timer 2 - 320us
 */

static int snd_opl3_timer2_start(struct snd_timer * timer)
{
	unsigned long flags;
	unsigned char tmp;
	unsigned int ticks;
	struct snd_opl3 *opl3;

	opl3 = snd_timer_chip(timer);
	spin_lock_irqsave(&opl3->timer_lock, flags);
	ticks = timer->sticks;
	tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
	opl3->timer_enable = tmp;
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks);	/* timer 1 count */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);	/* enable timer 1 IRQ */
	spin_unlock_irqrestore(&opl3->timer_lock, flags);
	return 0;
}

static int snd_opl3_timer2_stop(struct snd_timer * timer)
{
	unsigned long flags;
	unsigned char tmp;
	struct snd_opl3 *opl3;

	opl3 = snd_timer_chip(timer);
	spin_lock_irqsave(&opl3->timer_lock, flags);
	tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
	opl3->timer_enable = tmp;
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);	/* disable timer #1 */
	spin_unlock_irqrestore(&opl3->timer_lock, flags);
	return 0;
}

/*

 */

static const struct snd_timer_hardware snd_opl3_timer1 =
{
	.flags =	SNDRV_TIMER_HW_STOP,
	.resolution =	80000,
	.ticks =	256,
	.start =	snd_opl3_timer1_start,
	.stop =		snd_opl3_timer1_stop,
};

static const struct snd_timer_hardware snd_opl3_timer2 =
{
	.flags =	SNDRV_TIMER_HW_STOP,
	.resolution =	320000,
	.ticks =	256,
	.start =	snd_opl3_timer2_start,
	.stop =		snd_opl3_timer2_stop,
};

static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
{
	struct snd_timer *timer = NULL;
	struct snd_timer_id tid;
	int err;

	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
	tid.card = opl3->card->number;
	tid.device = timer_no;
	tid.subdevice = 0;
	err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer);
	if (err >= 0) {
		strcpy(timer->name, "AdLib timer #1");
		timer->private_data = opl3;
		timer->hw = snd_opl3_timer1;
	}
	opl3->timer1 = timer;
	return err;
}

static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
{
	struct snd_timer *timer = NULL;
	struct snd_timer_id tid;
	int err;

	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
	tid.card = opl3->card->number;
	tid.device = timer_no;
	tid.subdevice = 0;
	err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer);
	if (err >= 0) {
		strcpy(timer->name, "AdLib timer #2");
		timer->private_data = opl3;
		timer->hw = snd_opl3_timer2;
	}
	opl3->timer2 = timer;
	return err;
}

/*

 */

void snd_opl3_interrupt(struct snd_hwdep * hw)
{
	unsigned char status;
	struct snd_opl3 *opl3;
	struct snd_timer *timer;

	if (hw == NULL)
		return;

	opl3 = hw->private_data;
	status = inb(opl3->l_port);
	if (!(status & 0x80))
		return;

	if (status & 0x40) {
		timer = opl3->timer1;
		snd_timer_interrupt(timer, timer->sticks);
	}
	if (status & 0x20) {
		timer = opl3->timer2;
		snd_timer_interrupt(timer, timer->sticks);
	}
}

EXPORT_SYMBOL(snd_opl3_interrupt);

/*

 */

static int snd_opl3_free(struct snd_opl3 *opl3)
{
	if (snd_BUG_ON(!opl3))
		return -ENXIO;
	if (opl3->private_free)
		opl3->private_free(opl3);
	snd_opl3_clear_patches(opl3);
	release_and_free_resource(opl3->res_l_port);
	release_and_free_resource(opl3->res_r_port);
	kfree(opl3);
	return 0;
}

static int snd_opl3_dev_free(struct snd_device *device)
{
	struct snd_opl3 *opl3 = device->device_data;
	return snd_opl3_free(opl3);
}

int snd_opl3_new(struct snd_card *card,
		 unsigned short hardware,
		 struct snd_opl3 **ropl3)
{
	static const struct snd_device_ops ops = {
		.dev_free = snd_opl3_dev_free,
	};
	struct snd_opl3 *opl3;
	int err;

	*ropl3 = NULL;
	opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
	if (!opl3)
		return -ENOMEM;

	opl3->card = card;
	opl3->hardware = hardware;
	spin_lock_init(&opl3->reg_lock);
	spin_lock_init(&opl3->timer_lock);

	err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops);
	if (err < 0) {
		snd_opl3_free(opl3);
		return err;
	}

	*ropl3 = opl3;
	return 0;
}

EXPORT_SYMBOL(snd_opl3_new);

int snd_opl3_init(struct snd_opl3 *opl3)
{
	if (! opl3->command) {
		dev_err(opl3->card->dev,
			"snd_opl3_init: command not defined!\n");
		return -EINVAL;
	}

	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
	/* Melodic mode */
	opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);

	switch (opl3->hardware & OPL3_HW_MASK) {
	case OPL3_HW_OPL2:
		opl3->max_voices = MAX_OPL2_VOICES;
		break;
	case OPL3_HW_OPL3:
	case OPL3_HW_OPL4:
		opl3->max_voices = MAX_OPL3_VOICES;
		/* Enter OPL3 mode */
		opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
	}
	return 0;
}

EXPORT_SYMBOL(snd_opl3_init);

int snd_opl3_create(struct snd_card *card,
		    unsigned long l_port,
		    unsigned long r_port,
		    unsigned short hardware,
		    int integrated,
		    struct snd_opl3 ** ropl3)
{
	struct snd_opl3 *opl3;
	int err;

	*ropl3 = NULL;
	err = snd_opl3_new(card, hardware, &opl3);
	if (err < 0)
		return err;
	if (! integrated) {
		opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)");
		if (!opl3->res_l_port) {
			dev_err(card->dev, "opl3: can't grab left port 0x%lx\n", l_port);
			snd_device_free(card, opl3);
			return -EBUSY;
		}
		if (r_port != 0) {
			opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)");
			if (!opl3->res_r_port) {
				dev_err(card->dev, "opl3: can't grab right port 0x%lx\n", r_port);
				snd_device_free(card, opl3);
				return -EBUSY;
			}
		}
	}
	opl3->l_port = l_port;
	opl3->r_port = r_port;

	switch (opl3->hardware) {
	/* some hardware doesn't support timers */
	case OPL3_HW_OPL3_SV:
	case OPL3_HW_OPL3_CS:
	case OPL3_HW_OPL3_FM801:
		opl3->command = &snd_opl3_command;
		break;
	default:
		opl3->command = &snd_opl2_command;
		err = snd_opl3_detect(opl3);
		if (err < 0) {
			dev_dbg(card->dev, "OPL2/3 chip not detected at 0x%lx/0x%lx\n",
				opl3->l_port, opl3->r_port);
			snd_device_free(card, opl3);
			return err;
		}
		/* detect routine returns correct hardware type */
		switch (opl3->hardware & OPL3_HW_MASK) {
		case OPL3_HW_OPL3:
		case OPL3_HW_OPL4:
			opl3->command = &snd_opl3_command;
		}
	}

	snd_opl3_init(opl3);

	*ropl3 = opl3;
	return 0;
}

EXPORT_SYMBOL(snd_opl3_create);

int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
{
	int err;

	if (timer1_dev >= 0) {
		err = snd_opl3_timer1_init(opl3, timer1_dev);
		if (err < 0)
			return err;
	}
	if (timer2_dev >= 0) {
		err = snd_opl3_timer2_init(opl3, timer2_dev);
		if (err < 0) {
			snd_device_free(opl3->card, opl3->timer1);
			opl3->timer1 = NULL;
			return err;
		}
	}
	return 0;
}

EXPORT_SYMBOL(snd_opl3_timer_new);

int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
		       int device, int seq_device,
		       struct snd_hwdep ** rhwdep)
{
	struct snd_hwdep *hw;
	struct snd_card *card = opl3->card;
	int err;

	if (rhwdep)
		*rhwdep = NULL;

	/* create hardware dependent device (direct FM) */

	err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw);
	if (err < 0) {
		snd_device_free(card, opl3);
		return err;
	}
	hw->private_data = opl3;
	hw->exclusive = 1;
#ifdef CONFIG_SND_OSSEMUL
	if (device == 0)
		hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
#endif
	strcpy(hw->name, hw->id);
	switch (opl3->hardware & OPL3_HW_MASK) {
	case OPL3_HW_OPL2:
		strcpy(hw->name, "OPL2 FM");
		hw->iface = SNDRV_HWDEP_IFACE_OPL2;
		break;
	case OPL3_HW_OPL3:
		strcpy(hw->name, "OPL3 FM");
		hw->iface = SNDRV_HWDEP_IFACE_OPL3;
		break;
	case OPL3_HW_OPL4:
		strcpy(hw->name, "OPL4 FM");
		hw->iface = SNDRV_HWDEP_IFACE_OPL4;
		break;
	}

	/* operators - only ioctl */
	hw->ops.open = snd_opl3_open;
	hw->ops.ioctl = snd_opl3_ioctl;
	hw->ops.write = snd_opl3_write;
	hw->ops.release = snd_opl3_release;

	opl3->hwdep = hw;
	opl3->seq_dev_num = seq_device;
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
	if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
			       sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
		strcpy(opl3->seq_dev->name, hw->name);
		*(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
	}
#endif
	if (rhwdep)
		*rhwdep = hw;
	return 0;
}

EXPORT_SYMBOL(snd_opl3_hwdep_new);
