/*
 *	Initialisation code for Cyrix/NatSemi VSA1 softaudio
 *
 *	(C) Copyright 2003 Red Hat Inc <alan@redhat.com>
 *
 * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems.
 * The older version (VSA1) provides fairly good soundblaster emulation
 * although there are a couple of bugs: large DMA buffers break record,
 * and the MPU event handling seems suspect. VSA2 allows the native driver
 * to control the AC97 audio engine directly and requires a different driver.
 *
 * Thanks to National Semiconductor for providing the needed information
 * on the XpressAudio(tm) internals.
 *
 * 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, 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.
 *
 * TO DO:
 *	Investigate whether we can portably support Cognac (5520) in the
 *	same manner.
 */

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>

#include "sound_config.h"

#include "sb.h"

/*
 *	Read a soundblaster compatible mixer register.
 *	In this case we are actually reading an SMI trap
 *	not real hardware.
 */

static u8 __devinit mixer_read(unsigned long io, u8 reg)
{
	outb(reg, io + 4);
	udelay(20);
	reg = inb(io + 5);
	udelay(20);
	return reg;
}

static int __devinit probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct address_info *hw_config;
	unsigned long base;
	void __iomem *mem;
	unsigned long io;
	u16 map;
	u8 irq, dma8, dma16;
	int oldquiet;
	extern int sb_be_quiet;
		
	base = pci_resource_start(pdev, 0);
	if(base == 0UL)
		return 1;
	
	mem = ioremap(base, 128);
	if(mem == 0UL)
		return 1;
	map = readw(mem + 0x18);	/* Read the SMI enables */
	iounmap(mem);
	
	/* Map bits
		0:1	* 0x20 + 0x200 = sb base
		2	sb enable
		3	adlib enable
		5	MPU enable 0x330
		6	MPU enable 0x300
		
	   The other bits may be used internally so must be masked */

	io = 0x220 + 0x20 * (map & 3);	   
	
	if(map & (1<<2))
		printk(KERN_INFO "kahlua: XpressAudio at 0x%lx\n", io);
	else
		return 1;
		
	if(map & (1<<5))
		printk(KERN_INFO "kahlua: MPU at 0x300\n");
	else if(map & (1<<6))
		printk(KERN_INFO "kahlua: MPU at 0x330\n");
	
	irq = mixer_read(io, 0x80) & 0x0F;
	dma8 = mixer_read(io, 0x81);

	// printk("IRQ=%x MAP=%x DMA=%x\n", irq, map, dma8);
	
	if(dma8 & 0x20)
		dma16 = 5;
	else if(dma8 & 0x40)
		dma16 = 6;
	else if(dma8 & 0x80)
		dma16 = 7;
	else
	{
		printk(KERN_ERR "kahlua: No 16bit DMA enabled.\n");
		return 1;
	}
		
	if(dma8 & 0x01)
		dma8 = 0;
	else if(dma8 & 0x02)
		dma8 = 1;
	else if(dma8 & 0x08)
		dma8 = 3;
	else
	{
		printk(KERN_ERR "kahlua: No 8bit DMA enabled.\n");
		return 1;
	}
	
	if(irq & 1)
		irq = 9;
	else if(irq & 2)
		irq = 5;
	else if(irq & 4)
		irq = 7;
	else if(irq & 8)
		irq = 10;
	else
	{
		printk(KERN_ERR "kahlua: SB IRQ not set.\n");
		return 1;
	}
	
	printk(KERN_INFO "kahlua: XpressAudio on IRQ %d, DMA %d, %d\n",
		irq, dma8, dma16);
	
	hw_config = kmalloc(sizeof(struct address_info), GFP_KERNEL);
	if(hw_config == NULL)
	{
		printk(KERN_ERR "kahlua: out of memory.\n");
		return 1;
	}
	memset(hw_config, 0, sizeof(*hw_config));
	
	pci_set_drvdata(pdev, hw_config);
	
	hw_config->io_base = io;
	hw_config->irq = irq;
	hw_config->dma = dma8;
	hw_config->dma2 = dma16;
	hw_config->name = "Cyrix XpressAudio";
	hw_config->driver_use_1 = SB_NO_MIDI | SB_PCI_IRQ;

	if (!request_region(io, 16, "soundblaster"))
		goto err_out_free;
	
	if(sb_dsp_detect(hw_config, 0, 0, NULL)==0)
	{
		printk(KERN_ERR "kahlua: audio not responding.\n");
		release_region(io, 16);
		goto err_out_free;
	}

	oldquiet = sb_be_quiet;	
	sb_be_quiet = 1;
	if(sb_dsp_init(hw_config, THIS_MODULE))
	{
		sb_be_quiet = oldquiet;
		goto err_out_free;
	}
	sb_be_quiet = oldquiet;
	
	return 0;

err_out_free:
	pci_set_drvdata(pdev, NULL);
	kfree(hw_config);
	return 1;
}

static void __devexit remove_one(struct pci_dev *pdev)
{
	struct address_info *hw_config = pci_get_drvdata(pdev);
	sb_dsp_unload(hw_config, 0);
	pci_set_drvdata(pdev, NULL);
	kfree(hw_config);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("Kahlua VSA1 PCI Audio");
MODULE_LICENSE("GPL");

/*
 *	5530 only. The 5510/5520 decode is different.
 */

static struct pci_device_id id_tbl[] = {
	{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
	{ }
};

MODULE_DEVICE_TABLE(pci, id_tbl);

static struct pci_driver kahlua_driver = {
	.name		= "kahlua",
	.id_table	= id_tbl,
	.probe		= probe_one,
	.remove		= __devexit_p(remove_one),
};


static int __init kahlua_init_module(void)
{
	printk(KERN_INFO "Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc\n");
	return pci_register_driver(&kahlua_driver);
}

static void __devexit kahlua_cleanup_module(void)
{
	pci_unregister_driver(&kahlua_driver);
}


module_init(kahlua_init_module);
module_exit(kahlua_cleanup_module);

