/*
    i2c Support for Via Technologies 82C586B South Bridge

    Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>

    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 of the License, 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.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/io.h>

/* Power management registers */
#define PM_CFG_REVID	0x08	/* silicon revision code */
#define PM_CFG_IOBASE0	0x20
#define PM_CFG_IOBASE1	0x48

#define I2C_DIR		(pm_io_base+0x40)
#define I2C_OUT		(pm_io_base+0x42)
#define I2C_IN		(pm_io_base+0x44)
#define I2C_SCL		0x02	/* clock bit in DIR/OUT/IN register */
#define I2C_SDA		0x04

/* io-region reservation */
#define IOSPACE		0x06

static struct pci_driver vt586b_driver;
static u16 pm_io_base;

/*
   It does not appear from the datasheet that the GPIO pins are
   open drain. So a we set a low value by setting the direction to
   output and a high value by setting the direction to input and
   relying on the required I2C pullup. The data value is initialized
   to 0 in via_init() and never changed.
*/
static void bit_via_setscl(void *data, int state)
{
	outb(state ? inb(I2C_DIR) & ~I2C_SCL : inb(I2C_DIR) | I2C_SCL, I2C_DIR);
}

static void bit_via_setsda(void *data, int state)
{
	outb(state ? inb(I2C_DIR) & ~I2C_SDA : inb(I2C_DIR) | I2C_SDA, I2C_DIR);
}

static int bit_via_getscl(void *data)
{
	return (0 != (inb(I2C_IN) & I2C_SCL));
}

static int bit_via_getsda(void *data)
{
	return (0 != (inb(I2C_IN) & I2C_SDA));
}


static struct i2c_algo_bit_data bit_data = {
	.setsda		= bit_via_setsda,
	.setscl		= bit_via_setscl,
	.getsda		= bit_via_getsda,
	.getscl		= bit_via_getscl,
	.udelay		= 5,
	.timeout	= HZ
};

static struct i2c_adapter vt586b_adapter = {
	.owner		= THIS_MODULE,
	.id		= I2C_HW_B_VIA,
	.class          = I2C_CLASS_HWMON | I2C_CLASS_SPD,
	.name		= "VIA i2c",
	.algo_data	= &bit_data,
};


static struct pci_device_id vt586b_ids[] __devinitdata = {
	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) },
	{ 0, }
};

MODULE_DEVICE_TABLE (pci, vt586b_ids);

static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	u16 base;
	u8 rev;
	int res;

	if (pm_io_base) {
		dev_err(&dev->dev, "i2c-via: Will only support one host\n");
		return -ENODEV;
	}

	pci_read_config_byte(dev, PM_CFG_REVID, &rev);

	switch (rev) {
	case 0x00:
		base = PM_CFG_IOBASE0;
		break;
	case 0x01:
	case 0x10:
		base = PM_CFG_IOBASE1;
		break;

	default:
		base = PM_CFG_IOBASE1;
		/* later revision */
	}

	pci_read_config_word(dev, base, &pm_io_base);
	pm_io_base &= (0xff << 8);

	if (!request_region(I2C_DIR, IOSPACE, vt586b_driver.name)) {
		dev_err(&dev->dev, "IO 0x%x-0x%x already in use\n", I2C_DIR, I2C_DIR + IOSPACE);
		return -ENODEV;
	}

	outb(inb(I2C_DIR) & ~(I2C_SDA | I2C_SCL), I2C_DIR);
	outb(inb(I2C_OUT) & ~(I2C_SDA | I2C_SCL), I2C_OUT);

	/* set up the sysfs linkage to our parent device */
	vt586b_adapter.dev.parent = &dev->dev;

	res = i2c_bit_add_bus(&vt586b_adapter);
	if ( res < 0 ) {
		release_region(I2C_DIR, IOSPACE);
		pm_io_base = 0;
		return res;
	}
	return 0;
}

static void __devexit vt586b_remove(struct pci_dev *dev)
{
	i2c_del_adapter(&vt586b_adapter);
	release_region(I2C_DIR, IOSPACE);
	pm_io_base = 0;
}


static struct pci_driver vt586b_driver = {
	.name		= "vt586b_smbus",
	.id_table	= vt586b_ids,
	.probe		= vt586b_probe,
	.remove		= __devexit_p(vt586b_remove),
};

static int __init i2c_vt586b_init(void)
{
	return pci_register_driver(&vt586b_driver);
}

static void __exit i2c_vt586b_exit(void)
{
	pci_unregister_driver(&vt586b_driver);
}


MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge");
MODULE_LICENSE("GPL");

module_init(i2c_vt586b_init);
module_exit(i2c_vt586b_exit);
