/*
 * sound/oss/trix.c
 *
 * Low level driver for the MediaTrix AudioTrix Pro
 * (MT-0002-PC Control Chip)
 *
 *
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 * for more info.
 *
 * Changes
 *	Alan Cox		Modularisation, cleanup.
 *	Christoph Hellwig	Adapted to module_init/module_exit
 *	Arnaldo C. de Melo	Got rid of attach_uart401
 */
 
#include <linux/init.h>
#include <linux/module.h>

#include "sound_config.h"
#include "sb.h"
#include "sound_firmware.h"

#include "ad1848.h"
#include "mpu401.h"

#include "trix_boot.h"

static int mpu;

static int joystick;

static unsigned char trix_read(int addr)
{
	outb(((unsigned char) addr), 0x390);	/* MT-0002-PC ASIC address */
	return inb(0x391);	/* MT-0002-PC ASIC data */
}

static void trix_write(int addr, int data)
{
	outb(((unsigned char) addr), 0x390);	/* MT-0002-PC ASIC address */
	outb(((unsigned char) data), 0x391);	/* MT-0002-PC ASIC data */
}

static void download_boot(int base)
{
	int i = 0, n = trix_boot_len;

	if (trix_boot_len == 0)
		return;

	trix_write(0xf8, 0x00);	/* ??????? */
	outb((0x01), base + 6);	/* Clear the internal data pointer */
	outb((0x00), base + 6);	/* Restart */

	/*
	   *  Write the boot code to the RAM upload/download register.
	   *  Each write increments the internal data pointer.
	 */
	outb((0x01), base + 6);	/* Clear the internal data pointer */
	outb((0x1A), 0x390);	/* Select RAM download/upload port */

	for (i = 0; i < n; i++)
		outb((trix_boot[i]), 0x391);
	for (i = n; i < 10016; i++)	/* Clear up to first 16 bytes of data RAM */
		outb((0x00), 0x391);
	outb((0x00), base + 6);	/* Reset */
	outb((0x50), 0x390);	/* ?????? */

}

static int trix_set_wss_port(struct address_info *hw_config)
{
	unsigned char   addr_bits;

	if (trix_read(0x15) != 0x71)	/* No ASIC signature */
	{
		MDB(printk(KERN_ERR "No AudioTrix ASIC signature found\n"));
		return 0;
	}

	/*
	 * Reset some registers.
	 */

	trix_write(0x13, 0);
	trix_write(0x14, 0);

	/*
	 * Configure the ASIC to place the codec to the proper I/O location
	 */

	switch (hw_config->io_base)
	{
		case 0x530:
			addr_bits = 0;
			break;
		case 0x604:
			addr_bits = 1;
			break;
		case 0xE80:
			addr_bits = 2;
			break;
		case 0xF40:
			addr_bits = 3;
			break;
		default:
			return 0;
	}

	trix_write(0x19, (trix_read(0x19) & 0x03) | addr_bits);
	return 1;
}

/*
 *    Probe and attach routines for the Windows Sound System mode of
 *      AudioTrix Pro
 */

static int __init init_trix_wss(struct address_info *hw_config)
{
	static unsigned char dma_bits[4] = {
		1, 2, 0, 3
	};
	struct resource *ports;
	int config_port = hw_config->io_base + 0;
	int dma1 = hw_config->dma, dma2 = hw_config->dma2;
	int old_num_mixers = num_mixers;
	u8 config, bits;
	int ret;
 
	switch(hw_config->irq) {
	case 7:
		bits = 8;
		break;
	case 9:
		bits = 0x10;
		break;
	case 10:
		bits = 0x18;
		break;
	case 11:
		bits = 0x20;
		break;
	default:
		printk(KERN_ERR "AudioTrix: Bad WSS IRQ %d\n", hw_config->irq);
		return 0;
	}

	switch (dma1) {
	case 0:
	case 1:
	case 3:
		break;
	default:
		printk(KERN_ERR "AudioTrix: Bad WSS DMA %d\n", dma1);
		return 0;
	}

	switch (dma2) {
	case -1:
	case 0:
	case 1:
	case 3:
		break;
	default:
		printk(KERN_ERR "AudioTrix: Bad capture DMA %d\n", dma2);
		return 0;
	}

	/*
	 * Check if the IO port returns valid signature. The original MS Sound
	 * system returns 0x04 while some cards (AudioTrix Pro for example)
	 * return 0x00.
	 */
	ports = request_region(hw_config->io_base + 4, 4, "ad1848");
	if (!ports) {
		printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
		return 0;
	}

	if (!request_region(hw_config->io_base, 4, "MSS config")) {
		printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
		release_region(hw_config->io_base + 4, 4);
		return 0;
	}

	if (!trix_set_wss_port(hw_config))
		goto fail;

	config = inb(hw_config->io_base + 3);

	if ((config & 0x3f) != 0x00)
	{
		MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x\n", hw_config->io_base));
		goto fail;
	}

	/*
	 * Check that DMA0 is not in use with a 8 bit board.
	 */

	if (dma1 == 0 && config & 0x80)
	{
		printk(KERN_ERR "AudioTrix: Can't use DMA0 with a 8 bit card slot\n");
		goto fail;
	}
	if (hw_config->irq > 9 && config & 0x80)
	{
		printk(KERN_ERR "AudioTrix: Can't use IRQ%d with a 8 bit card slot\n", hw_config->irq);
		goto fail;
	}

	ret = ad1848_detect(ports, NULL, hw_config->osp);
	if (!ret)
		goto fail;

	if (joystick==1)
		trix_write(0x15, 0x80);

	/*
	 * Set the IRQ and DMA addresses.
	 */

	outb((bits | 0x40), config_port);

	if (dma2 == -1 || dma2 == dma1)
	{
		  bits |= dma_bits[dma1];
		  dma2 = dma1;
	}
	else
	{
		unsigned char tmp;

		tmp = trix_read(0x13) & ~30;
		trix_write(0x13, tmp | 0x80 | (dma1 << 4));

		tmp = trix_read(0x14) & ~30;
		trix_write(0x14, tmp | 0x80 | (dma2 << 4));
	}

	outb((bits), config_port);	/* Write IRQ+DMA setup */

	hw_config->slots[0] = ad1848_init("AudioTrix Pro", ports,
					  hw_config->irq,
					  dma1,
					  dma2,
					  0,
					  hw_config->osp,
					  THIS_MODULE);

	if (num_mixers > old_num_mixers)	/* Mixer got installed */
	{
		AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);	/* Line in */
		AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
		AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH);		/* OPL4 */
		AD1848_REROUTE(SOUND_MIXER_SPEAKER, SOUND_MIXER_ALTPCM);	/* SB */
	}
	return 1;

fail:
	release_region(hw_config->io_base, 4);
	release_region(hw_config->io_base + 4, 4);
	return 0;
}

static int __init probe_trix_sb(struct address_info *hw_config)
{

	int tmp;
	unsigned char conf;
	extern int sb_be_quiet;
	int old_quiet;
	static signed char irq_translate[] = {
		-1, -1, -1, 0, 1, 2, -1, 3
	};

	if (trix_boot_len == 0)
		return 0;	/* No boot code -> no fun */

	if ((hw_config->io_base & 0xffffff8f) != 0x200)
		return 0;

	tmp = hw_config->irq;
	if (tmp > 7)
		return 0;
	if (irq_translate[tmp] == -1)
		return 0;

	tmp = hw_config->dma;
	if (tmp != 1 && tmp != 3)
		return 0;

	if (!request_region(hw_config->io_base, 16, "soundblaster")) {
		printk(KERN_ERR "AudioTrix: SB I/O port conflict (%x)\n", hw_config->io_base);
		return 0;
	}

	conf = 0x84;		/* DMA and IRQ enable */
	conf |= hw_config->io_base & 0x70;	/* I/O address bits */
	conf |= irq_translate[hw_config->irq];
	if (hw_config->dma == 3)
		conf |= 0x08;
	trix_write(0x1b, conf);

	download_boot(hw_config->io_base);

	hw_config->name = "AudioTrix SB";
	if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
		release_region(hw_config->io_base, 16);
		return 0;
	}

	hw_config->driver_use_1 = SB_NO_MIDI | SB_NO_MIXER | SB_NO_RECORDING;

	/* Prevent false alarms */
	old_quiet = sb_be_quiet;
	sb_be_quiet = 1;

	sb_dsp_init(hw_config, THIS_MODULE);

	sb_be_quiet = old_quiet;
	return 1;
}

static int __init probe_trix_mpu(struct address_info *hw_config)
{
	unsigned char conf;
	static int irq_bits[] = {
		-1, -1, -1, 1, 2, 3, -1, 4, -1, 5
	};

	if (hw_config->irq > 9)
	{
		printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
		return 0;
	}
	if (irq_bits[hw_config->irq] == -1)
	{
		printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
		return 0;
	}
	switch (hw_config->io_base)
	{
		case 0x330:
			conf = 0x00;
			break;
		case 0x370:
			conf = 0x04;
			break;
		case 0x3b0:
			conf = 0x08;
			break;
		case 0x3f0:
			conf = 0x0c;
			break;
		default:
			return 0;	/* Invalid port */
	}

	conf |= irq_bits[hw_config->irq] << 4;
	trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
	hw_config->name = "AudioTrix Pro";
	return probe_uart401(hw_config, THIS_MODULE);
}

static void __exit unload_trix_wss(struct address_info *hw_config)
{
	int dma2 = hw_config->dma2;

	if (dma2 == -1)
		dma2 = hw_config->dma;

	release_region(0x390, 2);
	release_region(hw_config->io_base, 4);

	ad1848_unload(hw_config->io_base + 4,
		      hw_config->irq,
		      hw_config->dma,
		      dma2,
		      0);
	sound_unload_audiodev(hw_config->slots[0]);
}

static inline void __exit unload_trix_mpu(struct address_info *hw_config)
{
	unload_uart401(hw_config);
}

static inline void __exit unload_trix_sb(struct address_info *hw_config)
{
	sb_dsp_unload(hw_config, mpu);
}

static struct address_info cfg;
static struct address_info cfg2;
static struct address_info cfg_mpu;

static int sb;
static int fw_load;

static int __initdata io	= -1;
static int __initdata irq	= -1;
static int __initdata dma	= -1;
static int __initdata dma2	= -1;	/* Set this for modules that need it */
static int __initdata sb_io	= -1;
static int __initdata sb_dma	= -1;
static int __initdata sb_irq	= -1;
static int __initdata mpu_io	= -1;
static int __initdata mpu_irq	= -1;

module_param(io, int, 0);
module_param(irq, int, 0);
module_param(dma, int, 0);
module_param(dma2, int, 0);
module_param(sb_io, int, 0);
module_param(sb_dma, int, 0);
module_param(sb_irq, int, 0);
module_param(mpu_io, int, 0);
module_param(mpu_irq, int, 0);
module_param(joystick, bool, 0);

static int __init init_trix(void)
{
	printk(KERN_INFO "MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");

	cfg.io_base = io;
	cfg.irq = irq;
	cfg.dma = dma;
	cfg.dma2 = dma2;

	cfg2.io_base = sb_io;
	cfg2.irq = sb_irq;
	cfg2.dma = sb_dma;

	cfg_mpu.io_base = mpu_io;
	cfg_mpu.irq = mpu_irq;

	if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {
		printk(KERN_INFO "I/O, IRQ, DMA and type are mandatory\n");
		return -EINVAL;
	}

	if (cfg2.io_base != -1 && (cfg2.irq == -1 || cfg2.dma == -1)) {
		printk(KERN_INFO "CONFIG_SB_IRQ and CONFIG_SB_DMA must be specified if SB_IO is set.\n");
		return -EINVAL;
	}
	if (cfg_mpu.io_base != -1 && cfg_mpu.irq == -1) {
		printk(KERN_INFO "CONFIG_MPU_IRQ must be specified if MPU_IO is set.\n");
		return -EINVAL;
	}
	if (!trix_boot)
	{
		fw_load = 1;
		trix_boot_len = mod_firmware_load("/etc/sound/trxpro.bin",
						    (char **) &trix_boot);
	}

	if (!request_region(0x390, 2, "AudioTrix")) {
		printk(KERN_ERR "AudioTrix: Config port I/O conflict\n");
		return -ENODEV;
	}

	if (!init_trix_wss(&cfg)) {
		release_region(0x390, 2);
		return -ENODEV;
	}

	/*
	 *    We must attach in the right order to get the firmware
	 *      loaded up in time.
	 */

	if (cfg2.io_base != -1) {
		sb = probe_trix_sb(&cfg2);
	}
	
	if (cfg_mpu.io_base != -1)
		mpu = probe_trix_mpu(&cfg_mpu);

	return 0;
}

static void __exit cleanup_trix(void)
{
	if (fw_load && trix_boot)
		vfree(trix_boot);
	if (sb)
		unload_trix_sb(&cfg2);
	if (mpu)
		unload_trix_mpu(&cfg_mpu);
	unload_trix_wss(&cfg);
}

module_init(init_trix);
module_exit(cleanup_trix);

#ifndef MODULE
static int __init setup_trix (char *str)
{
	/* io, irq, dma, dma2, sb_io, sb_irq, sb_dma, mpu_io, mpu_irq */
	int ints[9];
	
	str = get_options(str, ARRAY_SIZE(ints), ints);

	io	= ints[1];
	irq	= ints[2];
	dma	= ints[3];
	dma2	= ints[4];
	sb_io	= ints[5];
	sb_irq	= ints[6];
	sb_dma	= ints[6];
	mpu_io	= ints[7];
	mpu_irq	= ints[8];

	return 1;
}

__setup("trix=", setup_trix);
#endif
MODULE_LICENSE("GPL");
