/*
 *  This file contains quirk handling code for PnP devices
 *  Some devices do not report all their resources, and need to have extra
 *  resources added. This is most easily accomplished at initialisation time
 *  when building up the resource structure for the first time.
 *
 *  Copyright (c) 2000 Peter Denison <peterd@pnd-pc.demon.co.uk>
 *
 *  Heavily based on PCI quirks handling which is
 *
 *  Copyright (c) 1999 Martin Mares <mj@ucw.cz>
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pnp.h>
#include <linux/io.h>
#include "base.h"


static void quirk_awe32_resources(struct pnp_dev *dev)
{
	struct pnp_port *port, *port2, *port3;
	struct pnp_option *res = dev->dependent;

	/*
	 * Unfortunately the isapnp_add_port_resource is too tightly bound
	 * into the PnP discovery sequence, and cannot be used. Link in the
	 * two extra ports (at offset 0x400 and 0x800 from the one given) by
	 * hand.
	 */
	for ( ; res ; res = res->next ) {
		port2 = pnp_alloc(sizeof(struct pnp_port));
		if (!port2)
			return;
		port3 = pnp_alloc(sizeof(struct pnp_port));
		if (!port3) {
			kfree(port2);
			return;
		}
		port = res->port;
		memcpy(port2, port, sizeof(struct pnp_port));
		memcpy(port3, port, sizeof(struct pnp_port));
		port->next = port2;
		port2->next = port3;
		port2->min += 0x400;
		port2->max += 0x400;
		port3->min += 0x800;
		port3->max += 0x800;
	}
	printk(KERN_INFO "pnp: AWE32 quirk - adding two ports\n");
}

static void quirk_cmi8330_resources(struct pnp_dev *dev)
{
	struct pnp_option *res = dev->dependent;
	unsigned long tmp;

	for ( ; res ; res = res->next ) {

		struct pnp_irq *irq;
		struct pnp_dma *dma;

		for( irq = res->irq; irq; irq = irq->next ) {	// Valid irqs are 5, 7, 10
			tmp = 0x04A0;
			bitmap_copy(irq->map, &tmp, 16);	// 0000 0100 1010 0000
		}

		for( dma = res->dma; dma; dma = dma->next ) // Valid 8bit dma channels are 1,3
			if( ( dma->flags & IORESOURCE_DMA_TYPE_MASK ) == IORESOURCE_DMA_8BIT )
				dma->map = 0x000A;
	}
	printk(KERN_INFO "pnp: CMI8330 quirk - fixing interrupts and dma\n");
}

static void quirk_sb16audio_resources(struct pnp_dev *dev)
{
	struct pnp_port *port;
	struct pnp_option *res = dev->dependent;
	int    changed = 0;

	/*
	 * The default range on the mpu port for these devices is 0x388-0x388.
	 * Here we increase that range so that two such cards can be
	 * auto-configured.
	 */

	for( ; res ; res = res->next ) {
		port = res->port;
		if(!port)
			continue;
		port = port->next;
		if(!port)
			continue;
		port = port->next;
		if(!port)
			continue;
		if(port->min != port->max)
			continue;
		port->max += 0x70;
		changed = 1;
	}
	if(changed)
		printk(KERN_INFO "pnp: SB audio device quirk - increasing port range\n");
	return;
}

static int quirk_smc_fir_enabled(struct pnp_dev *dev)
{
	unsigned long firbase;
	u8 bank, high, low, chip;

	if (!pnp_port_valid(dev, 1))
		return 0;

	firbase = pnp_port_start(dev, 1);

	/* Select register bank 3 */
	bank = inb(firbase + 7);
	bank &= 0xf0;
	bank |= 3;
	outb(bank, firbase + 7);

	high = inb(firbase + 0);
	low  = inb(firbase + 1);
	chip = inb(firbase + 2);

	/* This corresponds to the check in smsc_ircc_present() */
	if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2))
		return 1;

	return 0;
}

static void quirk_smc_enable(struct pnp_dev *dev)
{
	/*
	 * If the BIOS left the device disabled, or it is enabled and
	 * responding correctly, we're in good shape.
	 */
	if (!dev->active || quirk_smc_fir_enabled(dev))
		return;

	/*
	 * Sometimes the BIOS claims the device is enabled, but it reports
	 * the wrong FIR resources or doesn't properly configure ISA or LPC
	 * bridges on the way to the device.
	 *
	 * HP nc6000 and nc8000/nw8000 laptops have known problems like
	 * this.  Fortunately, they do fix things up if we auto-configure
	 * the device using its _PRS and _SRS methods.
	 */
	dev_err(&dev->dev, "%s device not responding, auto-configuring "
		"resources\n", dev->id->id);

	pnp_disable_dev(dev);
	pnp_init_resource_table(&dev->res);
	pnp_auto_config_dev(dev);
	pnp_activate_dev(dev);

	if (!quirk_smc_fir_enabled(dev))
		dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\"\n");
}


/*
 *  PnP Quirks
 *  Cards or devices that need some tweaking due to incomplete resource info
 */

static struct pnp_fixup pnp_fixups[] = {
	/* Soundblaster awe io port quirk */
	{ "CTL0021", quirk_awe32_resources },
	{ "CTL0022", quirk_awe32_resources },
	{ "CTL0023", quirk_awe32_resources },
	/* CMI 8330 interrupt and dma fix */
	{ "@X@0001", quirk_cmi8330_resources },
	/* Soundblaster audio device io port range quirk */
	{ "CTL0001", quirk_sb16audio_resources },
	{ "CTL0031", quirk_sb16audio_resources },
	{ "CTL0041", quirk_sb16audio_resources },
	{ "CTL0042", quirk_sb16audio_resources },
	{ "CTL0043", quirk_sb16audio_resources },
	{ "CTL0044", quirk_sb16audio_resources },
	{ "CTL0045", quirk_sb16audio_resources },
	{ "SMCf010", quirk_smc_enable },
	{ "" }
};

void pnp_fixup_device(struct pnp_dev *dev)
{
	int i = 0;

	while (*pnp_fixups[i].id) {
		if (compare_pnp_id(dev->id,pnp_fixups[i].id)) {
			pnp_dbg("Calling quirk for %s",
		                  dev->dev.bus_id);
			pnp_fixups[i].quirk_function(dev);
		}
		i++;
	}
}
