#include <sys/io.h>
#include <stdio.h>
#include <pci/pci.h>
#include <stdlib.h>

static int enable_flash_sis630 (struct pci_dev *dev, char *name)
{
	char b;

	/* get io privilege access PCI configuration space */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}

	/* Enable 0xFFF8000~0xFFFF0000 decoding on SiS 540/630 */
	outl(0x80000840, 0x0cf8);
	b = inb(0x0cfc) | 0x0b;
	outb(b, 0xcfc);
	/* Flash write enable on SiS 540/630 */
	outl(0x80000845, 0x0cf8);
	b = inb(0x0cfd) | 0x40;
	outb(b, 0xcfd);

	/* The same thing on SiS 950 SuperIO side */
	outb(0x87, 0x2e);
	outb(0x01, 0x2e);
	outb(0x55, 0x2e);
	outb(0x55, 0x2e);

	if (inb(0x2f) != 0x87) {
		outb(0x87, 0x4e);
		outb(0x01, 0x4e);
		outb(0x55, 0x4e);
		outb(0xaa, 0x4e);
		if (inb(0x4f) != 0x87) {
			printf("Can not access SiS 950\n");
			return -1;
		}
		outb(0x24, 0x4e);
		b = inb(0x4f) | 0xfc;
		outb(0x24, 0x4e);
		outb(b, 0x4f);
		outb(0x02, 0x4e);
		outb(0x02, 0x4f);	
	}

	outb(0x24, 0x2e);
	printf("2f is %#x\n", inb(0x2f));
	b = inb(0x2f) | 0xfc;
	outb(0x24, 0x2e);
	outb(b, 0x2f);

	outb(0x02, 0x2e);
	outb(0x02, 0x2f);

	return 0;
}

static int enable_flash_e7500(struct pci_dev *dev, char *name)
{
	/* register 4e.b gets or'ed with one */
	unsigned char old, new;
	/* if it fails, it fails. There are so many variations of broken mobos
	 * that it is hard to argue that we should quit at this point. 
	 */
  
	old = pci_read_byte(dev, 0x4e);

	new = old | 1;

	if (new == old)
		return 0;

	pci_write_byte(dev, 0x4e, new);

	if (pci_read_byte(dev, 0x4e) != new) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 
		       0x4e, new, name);
		return -1;
	}
	return 0;
}

static int enable_flash_vt8235(struct pci_dev *dev, char *name)
{
	unsigned char old, new, val;
	unsigned int base;
	int ok;
  
	/* get io privilege access PCI configuration space */
	if (iopl(3) != 0) {
		perror("Can not set io priviliage");
		exit(1);
	}

	old = pci_read_byte(dev, 0x40);

	new = old | 0x10;

	if (new == old)
		return 0;

	ok = pci_write_byte(dev, 0x40, new);
	if (ok != 0) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 
		       old, new, name);
	}

	/* enable GPIO15 which is connected to write protect. */
	base = ((pci_read_byte(dev, 0x88) & 0x80) | pci_read_byte(dev, 0x89) << 8);
	val = inb(base + 0x4d);
	val |= 0x80;
	outb(val, base + 0x4d);

	if (ok != 0) {
		return -1;
	} else {
		return 0;
	}
}

static int enable_flash_vt8231(struct pci_dev *dev, char *name)
{
	unsigned char val;
  
	val = pci_read_byte(dev, 0x40);
	val |= 0x10;
	pci_write_byte(dev, 0x40, val);

	if (pci_read_byte(dev, 0x40) != val) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 
		       0x40, val, name);
		return -1;
	}
	return 0;
}

static int enable_flash_cs5530(struct pci_dev *dev, char *name)
{
	unsigned char new;
  
	pci_write_byte(dev, 0x52, 0xee);

	new = pci_read_byte(dev, 0x52);

	if (new != 0xee) {
		printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 
		       0x52, new, name);
		return -1;
	}
	return 0;
}

static int enable_flash_sc1100(struct pci_dev *dev, char *name)
{
	unsigned char new;
  
	pci_write_byte(dev, 0x52, 0xee);

	new = pci_read_byte(dev, 0x52);

	if (new != 0xee) {
		printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 
		       0x52, new, name);
		return -1;
	}
	return 0;
}

static int enable_flash_sis5595(struct pci_dev *dev, char *name)
{
	unsigned char new, newer;
  
	new = pci_read_byte(dev, 0x45);

	/* clear bit 5 */
	new &= (~ 0x20);
	/* set bit 2 */
	new |= 0x4;

	pci_write_byte(dev, 0x45, new);

	newer = pci_read_byte(dev, 0x45);
	if (newer != new) {
		printf("tried to set register 0x%x to 0x%x on %s failed (WARNING ONLY)\n", 
		       0x45, new, name);
		printf("Stuck at 0x%x\n", newer);
		return -1;
	}
	return 0;
}

static int enable_flash_amd8111(struct pci_dev *dev, char *name) {
	/* register 4e.b gets or'ed with one */
	unsigned char old, new;
	/* if it fails, it fails. There are so many variations of broken mobos
	 * that it is hard to argue that we should quit at this point. 
	 */

	//dump_pci_device(dev); 

	old = pci_read_byte(dev, 0x43);
	new = old | 0x80;
	if (new != old) {
		pci_write_byte(dev, 0x43, new);
		if (pci_read_byte(dev, 0x43) != new) {
			printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
			       0x43, new, name);
		}
	}

	old = pci_read_byte(dev, 0x40);  
	new = old | 0x01;
	if (new == old)
		return 0;
	pci_write_byte(dev, 0x40, new);

	if (pci_read_byte(dev, 0x40) != new) {
		printf("tried to set 0x%x to 0x%x on %s failed (WARNING ONLY)\n",
		       0x40, new, name);
		return -1;
	}
	return 0;
}

typedef struct penable {
	unsigned short vendor, device; 
	char *name;
	int (*doit)(struct pci_dev *dev, char *name);
} FLASH_ENABLE;

static FLASH_ENABLE enables[] = {
	{0x1039, 0x0630, "sis630",  enable_flash_sis630},
	{0x8086, 0x2480, "E7500",   enable_flash_e7500},
	{0x1106, 0x8231, "VT8231",  enable_flash_vt8231},
	{0x1106, 0x3177, "VT8235",  enable_flash_vt8235},
	{0x1078, 0x0100, "CS5530",  enable_flash_cs5530},
	{0x100b, 0x0510, "SC1100",  enable_flash_sc1100},
	{0x1039, 0x0008, "SIS5595", enable_flash_sis5595},
	{0x1022, 0x7468, "AMD8111", enable_flash_amd8111},
};
  
int enable_flash_write()
{
	int i;
	struct pci_access *pacc;
	struct pci_dev *dev = 0;
	FLASH_ENABLE *enable = 0;

	pacc = pci_alloc();           /* Get the pci_access structure */
	/* Set all options you want -- here we stick with the defaults */
	pci_init(pacc);               /* Initialize the PCI library */
	pci_scan_bus(pacc);           /* We want to get the list of devices */

	/* now let's try to find the chipset we have ... */
	for (i = 0; i < sizeof(enables)/sizeof(enables[0]) && (! dev); i++) {
		struct pci_filter f;
		struct pci_dev *z;
		/* the first param is unused. */
		pci_filter_init((struct pci_access *) 0, &f);
		f.vendor = enables[i].vendor;
		f.device = enables[i].device;
		for (z=pacc->devices; z; z=z->next)
			if (pci_filter_match(&f, z)) {
				enable = &enables[i];
				dev = z;
			}
	}

	/* now do the deed. */
	if (enable) {
		printf("Enabling flash write on %s...", enable->name);
		if (enable->doit(dev, enable->name) == 0)
			printf("OK\n");
	}
	return 0;
}
