/*
 * Copyright (C) by Hannu Savolainen 1993-1997
 *
 *	cs4232.c
 *
 * The low level driver for Crystal CS4232 based cards. The CS4232 is
 * a PnP compatible chip which contains a CS4231A codec, SB emulation,
 * a MPU401 compatible MIDI port, joystick and synthesizer and IDE CD-ROM 
 * interfaces. This is just a temporary driver until full PnP support
 * gets implemented. Just the WSS codec, FM synth and the MIDI ports are
 * supported. Other interfaces are left uninitialized.
 *
 * ifdef ...WAVEFRONT...
 * 
 *   Support is provided for initializing the WaveFront synth
 *   interface as well, which is logical device #4. Note that if
 *   you have a Tropez+ card, you probably don't need to setup
 *   the CS4232-supported MIDI interface, since it corresponds to
 *   the internal 26-pin header that's hard to access. Using this
 *   requires an additional IRQ, a resource none too plentiful in
 *   this environment. Just don't set module parameters mpuio and
 *   mpuirq, and the MIDI port will be left uninitialized. You can
 *   still use the ICS2115 hosted MIDI interface which corresponds
 *   to the 9-pin D connector on the back of the card.
 *
 * endif  ...WAVEFRONT...
 *
 * Supported chips are:
 *      CS4232
 *      CS4236
 *      CS4236B
 *
 * Note: You will need a PnP config setup to initialise some CS4232 boards
 * anyway.
 *
 * Changes
 *      John Rood               Added Bose Sound System Support.
 *      Toshio Spoor
 *	Alan Cox		Modularisation, Basic cleanups.
 *      Paul Barton-Davis	Separated MPU configuration, added
 *                                       Tropez+ (WaveFront) support
 *	Christoph Hellwig	Adapted to module_init/module_exit,
 * 					simple cleanups
 * 	Arnaldo C. de Melo	got rid of attach_uart401
 *	Bartlomiej Zolnierkiewicz
 *				Added some __init/__initdata/__exit
 *	Marcus Meissner		Added ISA PnP support.
 */

#include <linux/config.h>
#include <linux/pnp.h>
#include <linux/module.h>
#include <linux/init.h>

#include "sound_config.h"

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

#define KEY_PORT	0x279	/* Same as LPT1 status port */
#define CSN_NUM		0x99	/* Just a random number */
#define INDEX_ADDRESS   0x00    /* (R0) Index Address Register */
#define INDEX_DATA      0x01    /* (R1) Indexed Data Register */
#define PIN_CONTROL     0x0a    /* (I10) Pin Control */
#define ENABLE_PINS     0xc0    /* XCTRL0/XCTRL1 enable */

static void CS_OUT(unsigned char a)
{
	outb(a, KEY_PORT);
}

#define CS_OUT2(a, b)		{CS_OUT(a);CS_OUT(b);}
#define CS_OUT3(a, b, c)	{CS_OUT(a);CS_OUT(b);CS_OUT(c);}

static int __initdata bss       = 0;
static int mpu_base, mpu_irq;
static int synth_base, synth_irq;
static int mpu_detected;

static int probe_cs4232_mpu(struct address_info *hw_config)
{
	/*
	 *	Just write down the config values.
	 */

	mpu_base = hw_config->io_base;
	mpu_irq = hw_config->irq;

	return 1;
}

static unsigned char crystal_key[] =	/* A 32 byte magic key sequence */
{
	0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc,
	0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2,
	0xf1, 0xf8, 0x7c, 0x3e, 0x9f, 0x4f, 0x27, 0x13,
	0x09, 0x84, 0x42, 0xa1, 0xd0, 0x68, 0x34, 0x1a
};

static void sleep(unsigned howlong)
{
	current->state = TASK_INTERRUPTIBLE;
	schedule_timeout(howlong);
}

static void enable_xctrl(int baseio)
{
        unsigned char regd;
                
        /*
         * Some IBM Aptiva's have the Bose Sound System. By default
         * the Bose Amplifier is disabled. The amplifier will be 
         * activated, by setting the XCTRL0 and XCTRL1 bits.
         * Volume of the monitor bose speakers/woofer, can then
         * be set by changing the PCM volume.
         *
         */
                
        printk("cs4232: enabling Bose Sound System Amplifier.\n");
        
        /* Switch to Pin Control Address */                   
        regd = inb(baseio + INDEX_ADDRESS) & 0xe0;
        outb(((unsigned char) (PIN_CONTROL | regd)), baseio + INDEX_ADDRESS );
        
        /* Activate the XCTRL0 and XCTRL1 Pins */
        regd = inb(baseio + INDEX_DATA);
        outb(((unsigned char) (ENABLE_PINS | regd)), baseio + INDEX_DATA );
}

static int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured)
{
	int i, n;
	int base = hw_config->io_base, irq = hw_config->irq;
	int dma1 = hw_config->dma, dma2 = hw_config->dma2;
	struct resource *ports;

	if (base == -1 || irq == -1 || dma1 == -1) {
		printk(KERN_ERR "cs4232: dma, irq and io must be set.\n");
		return 0;
	}

	/*
	 * Verify that the I/O port range is free.
	 */

	ports = request_region(base, 4, "ad1848");
	if (!ports) {
		printk(KERN_ERR "cs4232.c: I/O port 0x%03x not free\n", base);
		return 0;
	}
	if (ad1848_detect(ports, NULL, hw_config->osp)) {
		goto got_it;	/* The card is already active */
	}
	if (isapnp_configured) {
		printk(KERN_ERR "cs4232.c: ISA PnP configured, but not detected?\n");
		goto fail;
	}

	/*
	 * This version of the driver doesn't use the PnP method when configuring
	 * the card but a simplified method defined by Crystal. This means that
	 * just one CS4232 compatible device can exist on the system. Also this
	 * method conflicts with possible PnP support in the OS. For this reason 
	 * driver is just a temporary kludge.
	 *
	 * Also the Cirrus/Crystal method doesn't always work. Try ISA PnP first ;)
	 */

	/*
	 * Repeat initialization few times since it doesn't always succeed in
	 * first time.
	 */

	for (n = 0; n < 4; n++)
	{	
		/*
		 *	Wake up the card by sending a 32 byte Crystal key to the key port.
		 */
		
		for (i = 0; i < 32; i++)
			CS_OUT(crystal_key[i]);

		sleep(HZ / 10);

		/*
		 *	Now set the CSN (Card Select Number).
		 */

		CS_OUT2(0x06, CSN_NUM);

		/*
		 *	Then set some config bytes. First logical device 0 
		 */

		CS_OUT2(0x15, 0x00);	/* Select logical device 0 (WSS/SB/FM) */
		CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff);	/* WSS base */

		if (!request_region(0x388, 4, "FM"))	/* Not free */
			CS_OUT3(0x48, 0x00, 0x00)	/* FM base off */
		else {
			release_region(0x388, 4);
			CS_OUT3(0x48, 0x03, 0x88);	/* FM base 0x388 */
		}

		CS_OUT3(0x42, 0x00, 0x00);	/* SB base off */
		CS_OUT2(0x22, irq);		/* SB+WSS IRQ */
		CS_OUT2(0x2a, dma1);		/* SB+WSS DMA */

		if (dma2 != -1)
			CS_OUT2(0x25, dma2)	/* WSS DMA2 */
		else
			CS_OUT2(0x25, 4);	/* No WSS DMA2 */

		CS_OUT2(0x33, 0x01);	/* Activate logical dev 0 */

		sleep(HZ / 10);

		/*
		 * Initialize logical device 3 (MPU)
		 */

		if (mpu_base != 0 && mpu_irq != 0)
		{
			CS_OUT2(0x15, 0x03);	/* Select logical device 3 (MPU) */
			CS_OUT3(0x47, (mpu_base >> 8) & 0xff, mpu_base & 0xff);	/* MPU base */
			CS_OUT2(0x22, mpu_irq);	/* MPU IRQ */
			CS_OUT2(0x33, 0x01);	/* Activate logical dev 3 */
		}

		if(synth_base != 0)
		{
		    CS_OUT2 (0x15, 0x04);	        /* logical device 4 (WaveFront) */
		    CS_OUT3 (0x47, (synth_base >> 8) & 0xff,
			     synth_base & 0xff);	/* base */
		    CS_OUT2 (0x22, synth_irq);     	/* IRQ */
		    CS_OUT2 (0x33, 0x01);	        /* Activate logical dev 4 */
		}

		/*
		 * Finally activate the chip
		 */
		
		CS_OUT(0x79);

		sleep(HZ / 5);

		/*
		 * Then try to detect the codec part of the chip
		 */

		if (ad1848_detect(ports, NULL, hw_config->osp))
			goto got_it;
		
		sleep(HZ);
	}
fail:
	release_region(base, 4);
	return 0;

got_it:
	if (dma2 == -1)
		dma2 = dma1;

	hw_config->slots[0] = ad1848_init("Crystal audio controller", ports,
					  irq,
					  dma1,		/* Playback DMA */
					  dma2,		/* Capture DMA */
					  0,
					  hw_config->osp,
					  THIS_MODULE);

	if (hw_config->slots[0] != -1 &&
		audio_devs[hw_config->slots[0]]->mixer_dev!=-1)
	{	
		/* Assume the mixer map is as suggested in the CS4232 databook */
		AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);
		AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
		AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH);		/* FM synth */
	}
	if (mpu_base != 0 && mpu_irq != 0)
	{
		static struct address_info hw_config2 = {
			0
		};		/* Ensure it's initialized */

		hw_config2.io_base = mpu_base;
		hw_config2.irq = mpu_irq;
		hw_config2.dma = -1;
		hw_config2.dma2 = -1;
		hw_config2.always_detect = 0;
		hw_config2.name = NULL;
		hw_config2.driver_use_1 = 0;
		hw_config2.driver_use_2 = 0;
		hw_config2.card_subtype = 0;

		if (probe_uart401(&hw_config2, THIS_MODULE))
		{
			mpu_detected = 1;
		}
		else
		{
			mpu_base = mpu_irq = 0;
		}
		hw_config->slots[1] = hw_config2.slots[1];
	}
	
	if (bss)
        	enable_xctrl(base);

	return 1;
}

static void __devexit unload_cs4232(struct address_info *hw_config)
{
	int base = hw_config->io_base, irq = hw_config->irq;
	int dma1 = hw_config->dma, dma2 = hw_config->dma2;

	if (dma2 == -1)
		dma2 = dma1;

	ad1848_unload(base,
		      irq,
		      dma1,	/* Playback DMA */
		      dma2,	/* Capture DMA */
		      0);

	sound_unload_audiodev(hw_config->slots[0]);
	if (mpu_base != 0 && mpu_irq != 0 && mpu_detected)
	{
		static struct address_info hw_config2 =
		{
			0
		};		/* Ensure it's initialized */

		hw_config2.io_base = mpu_base;
		hw_config2.irq = mpu_irq;
		hw_config2.dma = -1;
		hw_config2.dma2 = -1;
		hw_config2.always_detect = 0;
		hw_config2.name = NULL;
		hw_config2.driver_use_1 = 0;
		hw_config2.driver_use_2 = 0;
		hw_config2.card_subtype = 0;
		hw_config2.slots[1] = hw_config->slots[1];

		unload_uart401(&hw_config2);
	}
}

static struct address_info cfg;
static struct address_info cfg_mpu;

static int __initdata io	= -1;
static int __initdata irq	= -1;
static int __initdata dma	= -1;
static int __initdata dma2	= -1;
static int __initdata mpuio	= -1;
static int __initdata mpuirq	= -1;
static int __initdata synthio	= -1;
static int __initdata synthirq	= -1;
static int __initdata isapnp	= 1;

MODULE_DESCRIPTION("CS4232 based soundcard driver"); 
MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); 
MODULE_LICENSE("GPL");

module_param(io, int, 0);
MODULE_PARM_DESC(io,"base I/O port for AD1848");
module_param(irq, int, 0);
MODULE_PARM_DESC(irq,"IRQ for AD1848 chip");
module_param(dma, int, 0);
MODULE_PARM_DESC(dma,"8 bit DMA for AD1848 chip");
module_param(dma2, int, 0);
MODULE_PARM_DESC(dma2,"16 bit DMA for AD1848 chip");
module_param(mpuio, int, 0);
MODULE_PARM_DESC(mpuio,"MPU 401 base address");
module_param(mpuirq, int, 0);
MODULE_PARM_DESC(mpuirq,"MPU 401 IRQ");
module_param(synthio, int, 0);
MODULE_PARM_DESC(synthio,"Maui WaveTable base I/O port");
module_param(synthirq, int, 0);
MODULE_PARM_DESC(synthirq,"Maui WaveTable IRQ");
module_param(isapnp, bool, 0);
MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)");
module_param(bss, bool, 0);
MODULE_PARM_DESC(bss,"Enable Bose Sound System Support (default 0)");

/*
 *	Install a CS4232 based card. Need to have ad1848 and mpu401
 *	loaded ready.
 */

/* All cs4232 based cards have the main ad1848 card either as CSC0000 or
 * CSC0100. */
static const struct pnp_device_id cs4232_pnp_table[] = {
	{ .id = "CSC0100", .driver_data = 0 },
	{ .id = "CSC0000", .driver_data = 0 },
	/* Guillemot Turtlebeach something appears to be cs4232 compatible
	 * (untested) */
	{ .id = "GIM0100", .driver_data = 0 },
	{ .id = ""}
};

MODULE_DEVICE_TABLE(pnp, cs4232_pnp_table);

static int cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
	struct address_info *isapnpcfg;

	isapnpcfg=(struct address_info*)kmalloc(sizeof(*isapnpcfg),GFP_KERNEL);
	if (!isapnpcfg)
		return -ENOMEM;

	isapnpcfg->irq		= pnp_irq(dev, 0);
	isapnpcfg->dma		= pnp_dma(dev, 0);
	isapnpcfg->dma2		= pnp_dma(dev, 1);
	isapnpcfg->io_base	= pnp_port_start(dev, 0);
	if (probe_cs4232(isapnpcfg,TRUE) == 0) {
		printk(KERN_ERR "cs4232: ISA PnP card found, but not detected?\n");
		kfree(isapnpcfg);
		return -ENODEV;
	}
	pnp_set_drvdata(dev,isapnpcfg);
	return 0;
}

static void __devexit cs4232_pnp_remove(struct pnp_dev *dev)
{
	struct address_info *cfg = pnp_get_drvdata(dev);
	if (cfg) {
		unload_cs4232(cfg);
		kfree(cfg);
	}
}

static struct pnp_driver cs4232_driver = {
	.name		= "cs4232",
	.id_table	= cs4232_pnp_table,
	.probe		= cs4232_pnp_probe,
	.remove		= __devexit_p(cs4232_pnp_remove),
};

static int __init init_cs4232(void)
{
#ifdef CONFIG_SOUND_WAVEFRONT_MODULE
	if(synthio == -1)
		printk(KERN_INFO "cs4232: set synthio and synthirq to use the wavefront facilities.\n");
	else {
		synth_base = synthio;
		synth_irq =  synthirq;
	}
#else
	if(synthio != -1)
		printk(KERN_WARNING "cs4232: wavefront support not enabled in this driver.\n");
#endif
	cfg.irq = -1;

	if (isapnp &&
	    (pnp_register_driver(&cs4232_driver) > 0)
	)
		return 0;

	if(io==-1||irq==-1||dma==-1)
	{
		printk(KERN_ERR "cs4232: Must set io, irq and dma.\n");
		return -ENODEV;
	}

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

	cfg_mpu.io_base = -1;
	cfg_mpu.irq = -1;

	if (mpuio != -1 && mpuirq != -1) {
		cfg_mpu.io_base = mpuio;
		cfg_mpu.irq = mpuirq;
		probe_cs4232_mpu(&cfg_mpu); /* Bug always returns 0 not OK -- AC */
	}

	if (probe_cs4232(&cfg,FALSE) == 0)
		return -ENODEV;

	return 0;
}

static void __exit cleanup_cs4232(void)
{
	pnp_unregister_driver(&cs4232_driver);
        if (cfg.irq != -1)
		unload_cs4232(&cfg); /* Unloads global MPU as well, if needed */
}

module_init(init_cs4232);
module_exit(cleanup_cs4232);

#ifndef MODULE
static int __init setup_cs4232(char *str)
{
	/* io, irq, dma, dma2 mpuio, mpuirq*/
	int ints[7];

	/* If we have isapnp cards, no need for options */
	if (pnp_register_driver(&cs4232_driver) > 0)
		return 1;
	
	str = get_options(str, ARRAY_SIZE(ints), ints);
	
	io	= ints[1];
	irq	= ints[2];
	dma	= ints[3];
	dma2	= ints[4];
	mpuio	= ints[5];
	mpuirq	= ints[6];

	return 1;
}

__setup("cs4232=", setup_cs4232);
#endif
