/*
 * Aztech AZT1605/AZT2316 Driver
 * Copyright (C) 2007,2010  Rene Herman
 *
 * 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, see <http://www.gnu.org/licenses/>.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/isa.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <asm/processor.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/wss.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>

MODULE_DESCRIPTION(CRD_NAME);
MODULE_AUTHOR("Rene Herman");
MODULE_LICENSE("GPL");

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");

static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;

module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
module_param_array(wss_port, long, NULL, 0444);
MODULE_PARM_DESC(wss_port, "WSS port # for " CRD_NAME " driver.");
module_param_array(mpu_port, long, NULL, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver.");
module_param_array(fm_port, long, NULL, 0444);
MODULE_PARM_DESC(fm_port, "FM port # for " CRD_NAME " driver.");
module_param_array(irq, int, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver.");
module_param_array(mpu_irq, int, NULL, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param_array(dma1, int, NULL, 0444);
MODULE_PARM_DESC(dma1, "Playback DMA # for " CRD_NAME " driver.");
module_param_array(dma2, int, NULL, 0444);
MODULE_PARM_DESC(dma2, "Capture DMA # for " CRD_NAME " driver.");

/*
 * Generic SB DSP support routines
 */

#define DSP_PORT_RESET		0x6
#define DSP_PORT_READ		0xa
#define DSP_PORT_COMMAND	0xc
#define DSP_PORT_STATUS		0xc
#define DSP_PORT_DATA_AVAIL	0xe

#define DSP_SIGNATURE		0xaa

#define DSP_COMMAND_GET_VERSION	0xe1

static int dsp_get_byte(void __iomem *port, u8 *val)
{
	int loops = 1000;

	while (!(ioread8(port + DSP_PORT_DATA_AVAIL) & 0x80)) {
		if (!loops--)
			return -EIO;
		cpu_relax();
	}
	*val = ioread8(port + DSP_PORT_READ);
	return 0;
}

static int dsp_reset(void __iomem *port)
{
	u8 val;

	iowrite8(1, port + DSP_PORT_RESET);
	udelay(10);
	iowrite8(0, port + DSP_PORT_RESET);

	if (dsp_get_byte(port, &val) < 0 || val != DSP_SIGNATURE)
		return -ENODEV;

	return 0;
}

static int dsp_command(void __iomem *port, u8 cmd)
{
	int loops = 1000;

	while (ioread8(port + DSP_PORT_STATUS) & 0x80) {
		if (!loops--)
			return -EIO;
		cpu_relax();
	}
	iowrite8(cmd, port + DSP_PORT_COMMAND);
	return 0;
}

static int dsp_get_version(void __iomem *port, u8 *major, u8 *minor)
{
	int err;

	err = dsp_command(port, DSP_COMMAND_GET_VERSION);
	if (err < 0)
		return err;

	err = dsp_get_byte(port, major);
	if (err < 0)
		return err;

	err = dsp_get_byte(port, minor);
	if (err < 0)
		return err;

	return 0;
}

/*
 * Generic WSS support routines
 */

#define WSS_CONFIG_DMA_0	(1 << 0)
#define WSS_CONFIG_DMA_1	(2 << 0)
#define WSS_CONFIG_DMA_3	(3 << 0)
#define WSS_CONFIG_DUPLEX	(1 << 2)
#define WSS_CONFIG_IRQ_7	(1 << 3)
#define WSS_CONFIG_IRQ_9	(2 << 3)
#define WSS_CONFIG_IRQ_10	(3 << 3)
#define WSS_CONFIG_IRQ_11	(4 << 3)

#define WSS_PORT_CONFIG		0
#define WSS_PORT_SIGNATURE	3

#define WSS_SIGNATURE		4

static int wss_detect(void __iomem *wss_port)
{
	if ((ioread8(wss_port + WSS_PORT_SIGNATURE) & 0x3f) != WSS_SIGNATURE)
		return -ENODEV;

	return 0;
}

static void wss_set_config(void __iomem *wss_port, u8 wss_config)
{
	iowrite8(wss_config, wss_port + WSS_PORT_CONFIG);
}

/*
 * Aztech Sound Galaxy specifics
 */

#define GALAXY_PORT_CONFIG	1024
#define CONFIG_PORT_SET		4

#define DSP_COMMAND_GALAXY_8	8
#define GALAXY_COMMAND_GET_TYPE	5

#define DSP_COMMAND_GALAXY_9	9
#define GALAXY_COMMAND_WSSMODE	0
#define GALAXY_COMMAND_SB8MODE	1

#define GALAXY_MODE_WSS		GALAXY_COMMAND_WSSMODE
#define GALAXY_MODE_SB8		GALAXY_COMMAND_SB8MODE

struct snd_galaxy {
	void __iomem *port;
	void __iomem *config_port;
	void __iomem *wss_port;
	u32 config;
	struct resource *res_port;
	struct resource *res_config_port;
	struct resource *res_wss_port;
};

static u32 config[SNDRV_CARDS];
static u8 wss_config[SNDRV_CARDS];

static int snd_galaxy_match(struct device *dev, unsigned int n)
{
	if (!enable[n])
		return 0;

	switch (port[n]) {
	case SNDRV_AUTO_PORT:
		dev_err(dev, "please specify port\n");
		return 0;
	case 0x220:
		config[n] |= GALAXY_CONFIG_SBA_220;
		break;
	case 0x240:
		config[n] |= GALAXY_CONFIG_SBA_240;
		break;
	case 0x260:
		config[n] |= GALAXY_CONFIG_SBA_260;
		break;
	case 0x280:
		config[n] |= GALAXY_CONFIG_SBA_280;
		break;
	default:
		dev_err(dev, "invalid port %#lx\n", port[n]);
		return 0;
	}

	switch (wss_port[n]) {
	case SNDRV_AUTO_PORT:
		dev_err(dev,  "please specify wss_port\n");
		return 0;
	case 0x530:
		config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_530;
		break;
	case 0x604:
		config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_604;
		break;
	case 0xe80:
		config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_E80;
		break;
	case 0xf40:
		config[n] |= GALAXY_CONFIG_WSS_ENABLE | GALAXY_CONFIG_WSSA_F40;
		break;
	default:
		dev_err(dev, "invalid WSS port %#lx\n", wss_port[n]);
		return 0;
	}

	switch (irq[n]) {
	case SNDRV_AUTO_IRQ:
		dev_err(dev,  "please specify irq\n");
		return 0;
	case 7:
		wss_config[n] |= WSS_CONFIG_IRQ_7;
		break;
	case 2:
		irq[n] = 9;
	case 9:
		wss_config[n] |= WSS_CONFIG_IRQ_9;
		break;
	case 10:
		wss_config[n] |= WSS_CONFIG_IRQ_10;
		break;
	case 11:
		wss_config[n] |= WSS_CONFIG_IRQ_11;
		break;
	default:
		dev_err(dev, "invalid IRQ %d\n", irq[n]);
		return 0;
	}

	switch (dma1[n]) {
	case SNDRV_AUTO_DMA:
		dev_err(dev,  "please specify dma1\n");
		return 0;
	case 0:
		wss_config[n] |= WSS_CONFIG_DMA_0;
		break;
	case 1:
		wss_config[n] |= WSS_CONFIG_DMA_1;
		break;
	case 3:
		wss_config[n] |= WSS_CONFIG_DMA_3;
		break;
	default:
		dev_err(dev, "invalid playback DMA %d\n", dma1[n]);
		return 0;
	}

	if (dma2[n] == SNDRV_AUTO_DMA || dma2[n] == dma1[n]) {
		dma2[n] = -1;
		goto mpu;
	}

	wss_config[n] |= WSS_CONFIG_DUPLEX;
	switch (dma2[n]) {
	case 0:
		break;
	case 1:
		if (dma1[n] == 0)
			break;
	default:
		dev_err(dev, "invalid capture DMA %d\n", dma2[n]);
		return 0;
	}

mpu:
	switch (mpu_port[n]) {
	case SNDRV_AUTO_PORT:
		dev_warn(dev, "mpu_port not specified; not using MPU-401\n");
		mpu_port[n] = -1;
		goto fm;
	case 0x300:
		config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_300;
		break;
	case 0x330:
		config[n] |= GALAXY_CONFIG_MPU_ENABLE | GALAXY_CONFIG_MPUA_330;
		break;
	default:
		dev_err(dev, "invalid MPU port %#lx\n", mpu_port[n]);
		return 0;
	}

	switch (mpu_irq[n]) {
	case SNDRV_AUTO_IRQ:
		dev_warn(dev, "mpu_irq not specified: using polling mode\n");
		mpu_irq[n] = -1;
		break;
	case 2:
		mpu_irq[n] = 9;
	case 9:
		config[n] |= GALAXY_CONFIG_MPUIRQ_2;
		break;
#ifdef AZT1605
	case 3:
		config[n] |= GALAXY_CONFIG_MPUIRQ_3;
		break;
#endif
	case 5:
		config[n] |= GALAXY_CONFIG_MPUIRQ_5;
		break;
	case 7:
		config[n] |= GALAXY_CONFIG_MPUIRQ_7;
		break;
#ifdef AZT2316
	case 10:
		config[n] |= GALAXY_CONFIG_MPUIRQ_10;
		break;
#endif
	default:
		dev_err(dev, "invalid MPU IRQ %d\n", mpu_irq[n]);
		return 0;
	}

	if (mpu_irq[n] == irq[n]) {
		dev_err(dev, "cannot share IRQ between WSS and MPU-401\n");
		return 0;
	}

fm:
	switch (fm_port[n]) {
	case SNDRV_AUTO_PORT:
		dev_warn(dev, "fm_port not specified: not using OPL3\n");
		fm_port[n] = -1;
		break;
	case 0x388:
		break;
	default:
		dev_err(dev, "illegal FM port %#lx\n", fm_port[n]);
		return 0;
	}

	config[n] |= GALAXY_CONFIG_GAME_ENABLE;
	return 1;
}

static int galaxy_init(struct snd_galaxy *galaxy, u8 *type)
{
	u8 major;
	u8 minor;
	int err;

	err = dsp_reset(galaxy->port);
	if (err < 0)
		return err;

	err = dsp_get_version(galaxy->port, &major, &minor);
	if (err < 0)
		return err;

	if (major != GALAXY_DSP_MAJOR || minor != GALAXY_DSP_MINOR)
		return -ENODEV;

	err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_8);
	if (err < 0)
		return err;

	err = dsp_command(galaxy->port, GALAXY_COMMAND_GET_TYPE);
	if (err < 0)
		return err;

	err = dsp_get_byte(galaxy->port, type);
	if (err < 0)
		return err;

	return 0;
}

static int galaxy_set_mode(struct snd_galaxy *galaxy, u8 mode)
{
	int err;

	err = dsp_command(galaxy->port, DSP_COMMAND_GALAXY_9);
	if (err < 0)
		return err;

	err = dsp_command(galaxy->port, mode);
	if (err < 0)
		return err;

#ifdef AZT1605
	/*
	 * Needed for MPU IRQ on AZT1605, but AZT2316 loses WSS again
	 */
	err = dsp_reset(galaxy->port);
	if (err < 0)
		return err;
#endif

	return 0;
}

static void galaxy_set_config(struct snd_galaxy *galaxy, u32 config)
{
	u8 tmp = ioread8(galaxy->config_port + CONFIG_PORT_SET);
	int i;

	iowrite8(tmp | 0x80, galaxy->config_port + CONFIG_PORT_SET);
	for (i = 0; i < GALAXY_CONFIG_SIZE; i++) {
		iowrite8(config, galaxy->config_port + i);
		config >>= 8;
	}
	iowrite8(tmp & 0x7f, galaxy->config_port + CONFIG_PORT_SET);
	msleep(10);
}

static void galaxy_config(struct snd_galaxy *galaxy, u32 config)
{
	int i;

	for (i = GALAXY_CONFIG_SIZE; i; i--) {
		u8 tmp = ioread8(galaxy->config_port + i - 1);
		galaxy->config = (galaxy->config << 8) | tmp;
	}
	config |= galaxy->config & GALAXY_CONFIG_MASK;
	galaxy_set_config(galaxy, config);
}

static int galaxy_wss_config(struct snd_galaxy *galaxy, u8 wss_config)
{
	int err;

	err = wss_detect(galaxy->wss_port);
	if (err < 0)
		return err;

	wss_set_config(galaxy->wss_port, wss_config);

	err = galaxy_set_mode(galaxy, GALAXY_MODE_WSS);
	if (err < 0)
		return err;

	return 0;
}

static void snd_galaxy_free(struct snd_card *card)
{
	struct snd_galaxy *galaxy = card->private_data;

	if (galaxy->wss_port) {
		wss_set_config(galaxy->wss_port, 0);
		ioport_unmap(galaxy->wss_port);
		release_and_free_resource(galaxy->res_wss_port);
	}
	if (galaxy->config_port) {
		galaxy_set_config(galaxy, galaxy->config);
		ioport_unmap(galaxy->config_port);
		release_and_free_resource(galaxy->res_config_port);
	}
	if (galaxy->port) {
		ioport_unmap(galaxy->port);
		release_and_free_resource(galaxy->res_port);
	}
}

static int snd_galaxy_probe(struct device *dev, unsigned int n)
{
	struct snd_galaxy *galaxy;
	struct snd_wss *chip;
	struct snd_card *card;
	u8 type;
	int err;

	err = snd_card_create(index[n], id[n], THIS_MODULE, sizeof *galaxy,
			      &card);
	if (err < 0)
		return err;

	snd_card_set_dev(card, dev);

	card->private_free = snd_galaxy_free;
	galaxy = card->private_data;

	galaxy->res_port = request_region(port[n], 16, DRV_NAME);
	if (!galaxy->res_port) {
		dev_err(dev, "could not grab ports %#lx-%#lx\n", port[n],
			port[n] + 15);
		err = -EBUSY;
		goto error;
	}
	galaxy->port = ioport_map(port[n], 16);

	err = galaxy_init(galaxy, &type);
	if (err < 0) {
		dev_err(dev, "did not find a Sound Galaxy at %#lx\n", port[n]);
		goto error;
	}
	dev_info(dev, "Sound Galaxy (type %d) found at %#lx\n", type, port[n]);

	galaxy->res_config_port = request_region(port[n] + GALAXY_PORT_CONFIG,
						 16, DRV_NAME);
	if (!galaxy->res_config_port) {
		dev_err(dev, "could not grab ports %#lx-%#lx\n",
			port[n] + GALAXY_PORT_CONFIG,
			port[n] + GALAXY_PORT_CONFIG + 15);
		err = -EBUSY;
		goto error;
	}
	galaxy->config_port = ioport_map(port[n] + GALAXY_PORT_CONFIG, 16);

	galaxy_config(galaxy, config[n]);

	galaxy->res_wss_port = request_region(wss_port[n], 4, DRV_NAME);
	if (!galaxy->res_wss_port)  {
		dev_err(dev, "could not grab ports %#lx-%#lx\n", wss_port[n],
			wss_port[n] + 3);
		err = -EBUSY;
		goto error;
	}
	galaxy->wss_port = ioport_map(wss_port[n], 4);

	err = galaxy_wss_config(galaxy, wss_config[n]);
	if (err < 0) {
		dev_err(dev, "could not configure WSS\n");
		goto error;
	}

	strcpy(card->driver, DRV_NAME);
	strcpy(card->shortname, DRV_NAME);
	sprintf(card->longname, "%s at %#lx/%#lx, irq %d, dma %d/%d",
		card->shortname, port[n], wss_port[n], irq[n], dma1[n],
		dma2[n]);

	err = snd_wss_create(card, wss_port[n] + 4, -1, irq[n], dma1[n],
			     dma2[n], WSS_HW_DETECT, 0, &chip);
	if (err < 0)
		goto error;

	err = snd_wss_pcm(chip, 0, NULL);
	if (err < 0)
		goto error;

	err = snd_wss_mixer(chip);
	if (err < 0)
		goto error;

	err = snd_wss_timer(chip, 0, NULL);
	if (err < 0)
		goto error;

	if (mpu_port[n] >= 0) {
		err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
					  mpu_port[n], 0, mpu_irq[n], NULL);
		if (err < 0)
			goto error;
	}

	if (fm_port[n] >= 0) {
		struct snd_opl3 *opl3;

		err = snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
				      OPL3_HW_AUTO, 0, &opl3);
		if (err < 0) {
			dev_err(dev, "no OPL device at %#lx\n", fm_port[n]);
			goto error;
		}
		err = snd_opl3_timer_new(opl3, 1, 2);
		if (err < 0)
			goto error;

		err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
		if (err < 0)
			goto error;
	}

	err = snd_card_register(card);
	if (err < 0)
		goto error;

	dev_set_drvdata(dev, card);
	return 0;

error:
	snd_card_free(card);
	return err;
}

static int snd_galaxy_remove(struct device *dev, unsigned int n)
{
	snd_card_free(dev_get_drvdata(dev));
	return 0;
}

static struct isa_driver snd_galaxy_driver = {
	.match		= snd_galaxy_match,
	.probe		= snd_galaxy_probe,
	.remove		= snd_galaxy_remove,

	.driver		= {
		.name	= DEV_NAME
	}
};

static int __init alsa_card_galaxy_init(void)
{
	return isa_register_driver(&snd_galaxy_driver, SNDRV_CARDS);
}

static void __exit alsa_card_galaxy_exit(void)
{
	isa_unregister_driver(&snd_galaxy_driver);
}

module_init(alsa_card_galaxy_init);
module_exit(alsa_card_galaxy_exit);
