/*
    i2c-i810.c - Part of lm_sensors, Linux kernel modules for hardware
              monitoring
    Copyright (c) 1998, 1999, 2000  Frodo Looijaard <frodol@dds.nl>,
    Philip Edelbrock <phil@netroedge.com>,
    Ralph Metzler <rjkm@thp.uni-koeln.de>, and
    Mark D. Studebaker <mdsxyz123@yahoo.com>
    
    Based on code written by Ralph Metzler <rjkm@thp.uni-koeln.de> and
    Simon Vogl

    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.
*/
/*
   This interfaces to the I810/I815 to provide access to
   the DDC Bus and the I2C Bus.

   SUPPORTED DEVICES	PCI ID
   i810AA		7121           
   i810AB		7123           
   i810E		7125           
   i815			1132           
   i845G		2562
*/

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

/* GPIO register locations */
#define I810_IOCONTROL_OFFSET	0x5000
#define I810_HVSYNC		0x00	/* not used */
#define I810_GPIOA		0x10
#define I810_GPIOB		0x14

/* bit locations in the registers */
#define SCL_DIR_MASK		0x0001
#define SCL_DIR			0x0002
#define SCL_VAL_MASK		0x0004
#define SCL_VAL_OUT		0x0008
#define SCL_VAL_IN		0x0010
#define SDA_DIR_MASK		0x0100
#define SDA_DIR			0x0200
#define SDA_VAL_MASK		0x0400
#define SDA_VAL_OUT		0x0800
#define SDA_VAL_IN		0x1000

/* initialization states */
#define INIT1			0x1
#define INIT2			0x2
#define INIT3			0x4

/* delays */
#define CYCLE_DELAY		10
#define TIMEOUT			(HZ / 2)

static void __iomem *ioaddr;

/* The i810 GPIO registers have individual masks for each bit
   so we never have to read before writing. Nice. */

static void bit_i810i2c_setscl(void *data, int val)
{
	writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
	     ioaddr + I810_GPIOB);
	readl(ioaddr + I810_GPIOB);	/* flush posted write */
}

static void bit_i810i2c_setsda(void *data, int val)
{
 	writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
	     ioaddr + I810_GPIOB);
	readl(ioaddr + I810_GPIOB);	/* flush posted write */
}

/* The GPIO pins are open drain, so the pins could always remain outputs.
   However, some chip versions don't latch the inputs unless they
   are set as inputs.
   We rely on the i2c-algo-bit routines to set the pins high before
   reading the input from other chips. Following guidance in the 815
   prog. ref. guide, we do a "dummy write" of 0 to the register before
   reading which forces the input value to be latched. We presume this
   applies to the 810 as well; shouldn't hurt anyway. This is necessary to get
   i2c_algo_bit bit_test=1 to pass. */

static int bit_i810i2c_getscl(void *data)
{
	writel(SCL_DIR_MASK, ioaddr + I810_GPIOB);
	writel(0, ioaddr + I810_GPIOB);
	return (0 != (readl(ioaddr + I810_GPIOB) & SCL_VAL_IN));
}

static int bit_i810i2c_getsda(void *data)
{
	writel(SDA_DIR_MASK, ioaddr + I810_GPIOB);
	writel(0, ioaddr + I810_GPIOB);
	return (0 != (readl(ioaddr + I810_GPIOB) & SDA_VAL_IN));
}

static void bit_i810ddc_setscl(void *data, int val)
{
	writel((val ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK,
	     ioaddr + I810_GPIOA);
	readl(ioaddr + I810_GPIOA);	/* flush posted write */
}

static void bit_i810ddc_setsda(void *data, int val)
{
 	writel((val ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK,
	     ioaddr + I810_GPIOA);
	readl(ioaddr + I810_GPIOA);	/* flush posted write */
}

static int bit_i810ddc_getscl(void *data)
{
	writel(SCL_DIR_MASK, ioaddr + I810_GPIOA);
	writel(0, ioaddr + I810_GPIOA);
	return (0 != (readl(ioaddr + I810_GPIOA) & SCL_VAL_IN));
}

static int bit_i810ddc_getsda(void *data)
{
	writel(SDA_DIR_MASK, ioaddr + I810_GPIOA);
	writel(0, ioaddr + I810_GPIOA);
	return (0 != (readl(ioaddr + I810_GPIOA) & SDA_VAL_IN));
}

static int config_i810(struct pci_dev *dev)
{
	unsigned long cadr;

	/* map I810 memory */
	cadr = dev->resource[1].start;
	cadr += I810_IOCONTROL_OFFSET;
	cadr &= PCI_BASE_ADDRESS_MEM_MASK;
	ioaddr = ioremap_nocache(cadr, 0x1000);
	if (ioaddr) {
		bit_i810i2c_setscl(NULL, 1);
		bit_i810i2c_setsda(NULL, 1);
		bit_i810ddc_setscl(NULL, 1);
		bit_i810ddc_setsda(NULL, 1);
		return 0;
	}
	return -ENODEV;
}

static struct i2c_algo_bit_data i810_i2c_bit_data = {
	.setsda		= bit_i810i2c_setsda,
	.setscl		= bit_i810i2c_setscl,
	.getsda		= bit_i810i2c_getsda,
	.getscl		= bit_i810i2c_getscl,
	.udelay		= CYCLE_DELAY,
	.mdelay		= CYCLE_DELAY,
	.timeout	= TIMEOUT,
};

static struct i2c_adapter i810_i2c_adapter = {
	.owner		= THIS_MODULE,
	.name		= "I810/I815 I2C Adapter",
	.algo_data	= &i810_i2c_bit_data,
};

static struct i2c_algo_bit_data i810_ddc_bit_data = {
	.setsda		= bit_i810ddc_setsda,
	.setscl		= bit_i810ddc_setscl,
	.getsda		= bit_i810ddc_getsda,
	.getscl		= bit_i810ddc_getscl,
	.udelay		= CYCLE_DELAY,
	.mdelay		= CYCLE_DELAY,
	.timeout	= TIMEOUT,
};

static struct i2c_adapter i810_ddc_adapter = {
	.owner		= THIS_MODULE,
	.name		= "I810/I815 DDC Adapter",
	.algo_data	= &i810_ddc_bit_data,
};

static struct pci_device_id i810_ids[] __devinitdata = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
	{ 0, },
};

MODULE_DEVICE_TABLE (pci, i810_ids);

static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
	int retval;

	retval = config_i810(dev);
	if (retval)
		return retval;
	dev_info(&dev->dev, "i810/i815 i2c device found.\n");

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

	retval = i2c_bit_add_bus(&i810_i2c_adapter);
	if (retval)
		return retval;
	retval = i2c_bit_add_bus(&i810_ddc_adapter);
	if (retval)
		i2c_bit_del_bus(&i810_i2c_adapter);
	return retval;
}

static void __devexit i810_remove(struct pci_dev *dev)
{
	i2c_bit_del_bus(&i810_ddc_adapter);
	i2c_bit_del_bus(&i810_i2c_adapter);
	iounmap(ioaddr);
}

static struct pci_driver i810_driver = {
	.owner		= THIS_MODULE,
	.name		= "i810_smbus",
	.id_table	= i810_ids,
	.probe		= i810_probe,
	.remove		= __devexit_p(i810_remove),
};

static int __init i2c_i810_init(void)
{
	return pci_register_driver(&i810_driver);
}

static void __exit i2c_i810_exit(void)
{
	pci_unregister_driver(&i810_driver);
}

MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
		"Philip Edelbrock <phil@netroedge.com>, "
		"Ralph Metzler <rjkm@thp.uni-koeln.de>, "
		"and Mark D. Studebaker <mdsxyz123@yahoo.com>");
MODULE_DESCRIPTION("I810/I815 I2C/DDC driver");
MODULE_LICENSE("GPL");

module_init(i2c_i810_init);
module_exit(i2c_i810_exit);
