All of lore.kernel.org
 help / color / mirror / Atom feed
* [BK PATCH] i2c driver fixes for 2.6.0-test2
@ 2005-05-19  6:24 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-02  5:29 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes for 2.6.0-test2.  They include a number
of minor i2c fixes and add a new i2c bus controller driver.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.5

thanks,

greg k-h

 drivers/i2c/Kconfig              |    8 
 drivers/i2c/busses/Kconfig       |   17 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-ali1535.c |   20 -
 drivers/i2c/busses/i2c-ali15x3.c |   15 -
 drivers/i2c/busses/i2c-amd756.c  |   28 --
 drivers/i2c/busses/i2c-amd8111.c |    6 
 drivers/i2c/busses/i2c-i801.c    |   28 --
 drivers/i2c/busses/i2c-nforce2.c |  470 +++++++++++++++++++++++++++++++++++++--
 drivers/i2c/busses/i2c-piix4.c   |   20 -
 drivers/i2c/busses/i2c-sis96x.c  |   18 -
 drivers/i2c/busses/i2c-viapro.c  |   18 -
 drivers/i2c/chips/via686a.c      |   20 -
 drivers/i2c/i2c-keywest.c        |   90 +------
 include/linux/i2c.h              |    7 
 15 files changed, 529 insertions(+), 237 deletions(-)
-----

<nikkne:hotpop.com>:
  o I2C: fix Kconfig info

<patrick:dreker.de>:
  o I2C: add ncforce2 i2c bus driver

Benjamin Herrenschmidt:
  o I2C: timer clean up for i2c-keywest.c

Daniele Bellucci:
  o I2C: fixed a little memory leak in i2c-ali15x3.c

Greg Kroah-Hartman:
  o I2C: remove devinitdata marking from i2c-nforce2.c as it's wrong
  o I2C: consolidate the i2c delay functions
  o I2C: minor cleanups to the i2c-nforce2 driver

Jan Dittmer:
  o I2C: convert via686a temp_* to milli degree celsius


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24 ` Mark M. Hoffman
@ 2005-05-19  6:24     ` Mark M. Hoffman
  0 siblings, 0 replies; 125+ messages in thread
From: Mark M. Hoffman @ 2003-08-14  5:13 UTC (permalink / raw)
  To: Sensors, LKML; +Cc: Greg KH

This is a resend of a patch to the i2c-nforce2.c I2C bus driver.
The start of the relevant thread was here:
http://archives.andrew.net.au/lm-sensors/msg03820.html

[comment]
This patch restores a line that was wrongly removed.  There are also some
trivial cleanups.  It applies & compiles vs. 2.6.0-test3.  It's untested
(no hardware here).
[/comment]

--- linux-2.6.0-test3/drivers/i2c/busses/i2c-nforce2.c.orig	2003-08-14 00:53:00.000000000 -0400
+++ linux-2.6.0-test3/drivers/i2c/busses/i2c-nforce2.c	2003-08-14 01:05:31.000000000 -0400
@@ -51,10 +51,6 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS   0x0064
 #endif
-/* TODO: sync with lm-sensors */
-#ifndef I2C_HW_SMBUS_NFORCE2
-#define I2C_HW_SMBUS_NFORCE2	0x0c
-#endif
 
 
 struct nforce2_smbus {
@@ -128,20 +124,10 @@
 	.name   	= "unset",
 };
 
-
-#if 0
-/* Internally used pause function */
-static void nforce2_do_pause(unsigned int amount)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(amount);
-}
-#endif
-
 /* Return -1 on error. See smbus.h for more information */
-static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-		char read_write, u8 command, int size,
-		union i2c_smbus_data * data)
+static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
+		unsigned short flags, char read_write,
+		u8 command, int size, union i2c_smbus_data * data)
 {
 	struct nforce2_smbus *smbus = adap->algo_data;
 	unsigned char protocol, pec, temp;
@@ -249,7 +235,7 @@
 
 #if 0
 	do {
-		nforce2_do_pause(1);
+		i2c_do_pause(1);
 		temp = inb_p(NVIDIA_SMB_STS);
 	} while (((temp & NVIDIA_SMB_STS_DONE) == 0) && (timeout++ < MAX_TIMEOUT));
 #endif
@@ -332,13 +318,8 @@
 			smbus->base, smbus->base+smbus->size-1, name);
 		return -1;
 	}
-/*
-	smbus->adapter.owner = THIS_MODULE;
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
-	smbus->adapter.algo = &smbus_algorithm;
-	smbus->adapter.algo_data = smbus;
-*/
 	smbus->adapter = nforce2_adapter;
+	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
 	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);

-- 
Mark M. Hoffman
mhoffman@lightlink.com


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24     ` Mark M. Hoffman
@ 2005-05-19  6:24       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-14 21:14 UTC (permalink / raw)
  To: Sensors, LKML

On Thu, Aug 14, 2003 at 01:13:47AM -0400, Mark M. Hoffman wrote:
> This is a resend of a patch to the i2c-nforce2.c I2C bus driver.
> The start of the relevant thread was here:
> http://archives.andrew.net.au/lm-sensors/msg03820.html
> 
> [comment]
> This patch restores a line that was wrongly removed.  There are also some
> trivial cleanups.  It applies & compiles vs. 2.6.0-test3.  It's untested
> (no hardware here).
> [/comment]

Oops, sorry I forgot this one.  I've now applied it and will send it on
later to Linus.

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test3
  2005-05-19  6:24 ` Greg KH
@ 2005-05-19  6:24 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:32 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes for 2.6.0-test3.  They include a fix for
the i2c-dev driver that has gone into 2.4 and a pii4x bugfix from Tom
Rini.  I've also added adapter and client "name" files in sysfs as the
driver core no longer supplies them.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.5

thanks,

greg k-h

 drivers/i2c/busses/i2c-nforce2.c |   29 ++++-----------------------
 drivers/i2c/busses/i2c-piix4.c   |   13 ++++++++++--
 drivers/i2c/chips/Makefile       |    4 ++-
 drivers/i2c/chips/adm1021.c      |    8 +++----
 drivers/i2c/i2c-core.c           |   28 ++++++++++++++++++++++++++
 drivers/i2c/i2c-dev.c            |   41 ++++++++++++++++++++++++---------------
 6 files changed, 77 insertions(+), 46 deletions(-)
-----

<khali:linux-fr.org>:
  o i2c: user/kernel bug and memory leak in i2c-dev

Greg Kroah-Hartman:
  o I2C: add adapter and client name files as the driver core no longer provides them
  o I2C: fix up the wording for the pii4x bugfix
  o i2c: move w83481d to top of link order due to chip address takeover ability
  o i2c: fix up "raw" printk() call

Mark M. Hoffman:
  o I2C: i2c nforce2.c fixes

Rusty Lynch:
  o I2C: bugfix for initialization bug in adm1021 driver

Tom Rini:
  o I2C: Fix for i2c-piix4 with on some boards


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24   ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.1, 2003/08/11 14:36:10-07:00, trini@kernel.crashing.org

[PATCH] I2C: Fix for i2c-piix4 with on some boards

Hello all.  On some boards with an Intel PIIX4 the BIOS (such as the one
found on a Force CPCI-735) will incorrectly configure the chipset, and
leaves a register in an undefined state causing i2c to behave strangley.
The following patches (first vs lm_sensors-2.8.0 and then vs
2.6.0-test3)  fixes the issue.


 drivers/i2c/busses/i2c-piix4.c |    9 +++++++++
 1 files changed, 9 insertions(+)


diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:13 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:13 2003
@@ -160,6 +160,15 @@
 	}
 
 	pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
+
+	/* Some BIOS will set up the chipset incorrectly and leave a register
+	   in an undefined state (causing I2C to act very strangely). */
+	if (temp & 0x02) {
+		printk("Fixed I2C problem on Force CPCI735\n");
+		temp = temp & 0xfd;
+		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
+	}
+ 
 	/* If force_addr is set, we program the new address here. Just to make
 	   sure, we disable the PIIX4 first. */
 	if (force_addr) {


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24   ` Greg KH
@ 2005-05-19  6:24     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.2, 2003/08/11 14:36:29-07:00, khali@linux-fr.org

[PATCH] i2c: user/kernel bug and memory leak in i2c-dev


 drivers/i2c/i2c-dev.c |   41 ++++++++++++++++++++++++++---------------
 1 files changed, 26 insertions(+), 15 deletions(-)


diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Fri Aug 15 11:27:09 2003
+++ b/drivers/i2c/i2c-dev.c	Fri Aug 15 11:27:09 2003
@@ -181,6 +181,7 @@
 	struct i2c_smbus_ioctl_data data_arg;
 	union i2c_smbus_data temp;
 	struct i2c_msg *rdwr_pa;
+	u8 **data_ptrs;
 	int i,datasize,res;
 	unsigned long funcs;
 
@@ -214,7 +215,7 @@
 		return (copy_to_user((unsigned long __user *)arg, &funcs,
 		                     sizeof(unsigned long)))?-EFAULT:0;
 
-        case I2C_RDWR:
+	case I2C_RDWR:
 		if (copy_from_user(&rdwr_arg, 
 				   (struct i2c_rdwr_ioctl_data __user *)arg, 
 				   sizeof(rdwr_arg)))
@@ -231,28 +232,37 @@
 
 		if (rdwr_pa == NULL) return -ENOMEM;
 
+		if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
+				   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
+			kfree(rdwr_pa);
+			return -EFAULT;
+		}
+
+		data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *),
+					    GFP_KERNEL);
+		if (data_ptrs == NULL) {
+			kfree(rdwr_pa);
+			return -ENOMEM;
+		}
+
 		res = 0;
 		for( i=0; i<rdwr_arg.nmsgs; i++ ) {
-		    	if(copy_from_user(&(rdwr_pa[i]),
-					&(rdwr_arg.msgs[i]),
-					sizeof(rdwr_pa[i]))) {
-			        res = -EFAULT;
-				break;
-			}
 			/* Limit the size of the message to a sane amount */
 			if (rdwr_pa[i].len > 8192) {
 				res = -EINVAL;
 				break;
 			}
+			data_ptrs[i] = rdwr_pa[i].buf;
 			rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
 			if(rdwr_pa[i].buf == NULL) {
 				res = -ENOMEM;
 				break;
 			}
 			if(copy_from_user(rdwr_pa[i].buf,
-				rdwr_arg.msgs[i].buf,
+				data_ptrs[i],
 				rdwr_pa[i].len)) {
-			    	res = -EFAULT;
+					++i; /* Needs to be kfreed too */
+					res = -EFAULT;
 				break;
 			}
 		}
@@ -260,18 +270,18 @@
 			int j;
 			for (j = 0; j < i; ++j)
 				kfree(rdwr_pa[j].buf);
+			kfree(data_ptrs);
 			kfree(rdwr_pa);
 			return res;
 		}
-		if (!res) {
-			res = i2c_transfer(client->adapter,
-				rdwr_pa,
-				rdwr_arg.nmsgs);
-		}
+
+		res = i2c_transfer(client->adapter,
+			rdwr_pa,
+			rdwr_arg.nmsgs);
 		while(i-- > 0) {
 			if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
 				if(copy_to_user(
-					rdwr_arg.msgs[i].buf,
+					data_ptrs[i],
 					rdwr_pa[i].buf,
 					rdwr_pa[i].len)) {
 					res = -EFAULT;
@@ -279,6 +289,7 @@
 			}
 			kfree(rdwr_pa[i].buf);
 		}
+		kfree(data_ptrs);
 		kfree(rdwr_pa);
 		return res;
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.4, 2003/08/11 15:22:22-07:00, greg@kroah.com

i2c: move w83481d to top of link order due to chip address takeover ability.

Fixes http://bugme.osdl.org/show_bug.cgi?id=1066


 drivers/i2c/chips/Makefile |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)


diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
--- a/drivers/i2c/chips/Makefile	Fri Aug 15 11:27:01 2003
+++ b/drivers/i2c/chips/Makefile	Fri Aug 15 11:27:01 2003
@@ -2,10 +2,12 @@
 # Makefile for the kernel hardware sensors chip drivers.
 #
 
+# w83781d goes first, as it can override other driver's addresses.
+obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o
+
 obj-$(CONFIG_SENSORS_ADM1021)	+= adm1021.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
 obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
 obj-$(CONFIG_SENSORS_LM85)	+= lm85.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
-obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.3, 2003/08/11 14:36:57-07:00, greg@kroah.com

[PATCH] i2c: fix up "raw" printk() call.


 drivers/i2c/busses/i2c-piix4.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:05 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:05 2003
@@ -164,7 +164,7 @@
 	/* Some BIOS will set up the chipset incorrectly and leave a register
 	   in an undefined state (causing I2C to act very strangely). */
 	if (temp & 0x02) {
-		printk("Fixed I2C problem on Force CPCI735\n");
+		dev_info(&PIIX4_dev->dev, "Fixed I2C problem on Force CPCI735\n");
 		temp = temp & 0xfd;
 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
 	}


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24             ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.6, 2003/08/14 14:31:21-07:00, rusty@linux.co.intel.com

[PATCH] I2C: bugfix for initialization bug in adm1021 driver

While initializing the adm1021 device, the driver is performing a conversion
from fixed point to Celcius on values that were declaired as Celcius.  On
my Dell Precision 220 this results in a shutdown after a couple of minutes
running.

This is a very simple patch against the 2.6.0-test3 tree that just removes the
conversion.


 drivers/i2c/chips/adm1021.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Fri Aug 15 11:26:53 2003
+++ b/drivers/i2c/chips/adm1021.c	Fri Aug 15 11:26:53 2003
@@ -356,13 +356,13 @@
 {
 	/* Initialize the adm1021 chip */
 	adm1021_write_value(client, ADM1021_REG_TOS_W,
-			    TEMP_TO_REG(adm1021_INIT_TOS));
+			    adm1021_INIT_TOS);
 	adm1021_write_value(client, ADM1021_REG_THYST_W,
-			    TEMP_TO_REG(adm1021_INIT_THYST));
+			    adm1021_INIT_THYST);
 	adm1021_write_value(client, ADM1021_REG_REMOTE_TOS_W,
-			    TEMP_TO_REG(adm1021_INIT_REMOTE_TOS));
+			    adm1021_INIT_REMOTE_TOS);
 	adm1021_write_value(client, ADM1021_REG_REMOTE_THYST_W,
-			    TEMP_TO_REG(adm1021_INIT_REMOTE_THYST));
+			    adm1021_INIT_REMOTE_THYST);
 	/* Enable ADC and disable suspend mode */
 	adm1021_write_value(client, ADM1021_REG_CONFIG_W, 0);
 	/* Set Conversion rate to 1/sec (this can be tinkered with) */


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24           ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.5, 2003/08/14 14:13:01-07:00, mhoffman@lightlink.com

[PATCH] I2C: i2c nforce2.c fixes

This patch restores a line that was wrongly removed.  There are also some
trivial cleanups.  It applies & compiles vs. 2.6.0-test3.  It's untested
(no hardware here).


 drivers/i2c/busses/i2c-nforce2.c |   29 +++++------------------------
 1 files changed, 5 insertions(+), 24 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Fri Aug 15 11:26:57 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Fri Aug 15 11:26:57 2003
@@ -51,10 +51,6 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS   0x0064
 #endif
-/* TODO: sync with lm-sensors */
-#ifndef I2C_HW_SMBUS_NFORCE2
-#define I2C_HW_SMBUS_NFORCE2	0x0c
-#endif
 
 
 struct nforce2_smbus {
@@ -128,20 +124,10 @@
 	.name   	= "unset",
 };
 
-
-#if 0
-/* Internally used pause function */
-static void nforce2_do_pause(unsigned int amount)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(amount);
-}
-#endif
-
 /* Return -1 on error. See smbus.h for more information */
-static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-		char read_write, u8 command, int size,
-		union i2c_smbus_data * data)
+static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
+		unsigned short flags, char read_write,
+		u8 command, int size, union i2c_smbus_data * data)
 {
 	struct nforce2_smbus *smbus = adap->algo_data;
 	unsigned char protocol, pec, temp;
@@ -249,7 +235,7 @@
 
 #if 0
 	do {
-		nforce2_do_pause(1);
+		i2c_do_pause(1);
 		temp = inb_p(NVIDIA_SMB_STS);
 	} while (((temp & NVIDIA_SMB_STS_DONE) == 0) && (timeout++ < MAX_TIMEOUT));
 #endif
@@ -332,13 +318,8 @@
 			smbus->base, smbus->base+smbus->size-1, name);
 		return -1;
 	}
-/*
-	smbus->adapter.owner = THIS_MODULE;
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
-	smbus->adapter.algo = &smbus_algorithm;
-	smbus->adapter.algo_data = smbus;
-*/
 	smbus->adapter = nforce2_adapter;
+	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
 	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24               ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.7, 2003/08/14 14:46:08-07:00, greg@kroah.com

[PATCH] I2C: fix up the wording for the pii4x bugfix.


 drivers/i2c/busses/i2c-piix4.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:26:49 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:26:49 2003
@@ -164,7 +164,7 @@
 	/* Some BIOS will set up the chipset incorrectly and leave a register
 	   in an undefined state (causing I2C to act very strangely). */
 	if (temp & 0x02) {
-		dev_info(&PIIX4_dev->dev, "Fixed I2C problem on Force CPCI735\n");
+		dev_info(&PIIX4_dev->dev, "Worked around buggy BIOS (I2C)\n");
 		temp = temp & 0xfd;
 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
 	}


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-08-15 18:33 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.8, 2003/08/15 11:06:52-07:00, greg@kroah.com

I2C: add adapter and client name files as the driver core no longer provides them.


 drivers/i2c/i2c-core.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+)


diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Fri Aug 15 11:26:44 2003
+++ b/drivers/i2c/i2c-core.c	Fri Aug 15 11:26:44 2003
@@ -79,12 +79,36 @@
 	.release =	&i2c_adapter_class_dev_release,
 };
 
+static ssize_t show_adapter_name(struct device *dev, char *buf)
+{
+	struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
+	return sprintf(buf, "%s\n", adap->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
+
+
 static void i2c_client_release(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	complete(&client->released);
 }
 
+static ssize_t show_client_name(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%s\n", client->name);
+}
+
+/* 
+ * We can't use the DEVICE_ATTR() macro here as we want the same filename for a
+ * different type of a device.  So beware if the DEVICE_ATTR() macro ever
+ * changes, this definition will also have to change.
+ */
+static struct device_attribute dev_attr_client_name = {
+	.attr	= {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE },
+	.show	= &show_client_name,
+};
+
 
 /* ---------------------------------------------------
  * registering functions 
@@ -120,6 +144,7 @@
 	adap->dev.driver = &i2c_adapter_driver;
 	adap->dev.release = &i2c_adapter_dev_release;
 	device_register(&adap->dev);
+	device_create_file(&adap->dev, &dev_attr_name);
 
 	/* Add this adapter to the i2c_adapter class */
 	memset(&adap->class_dev, 0x00, sizeof(struct class_device));
@@ -184,6 +209,7 @@
 	init_completion(&adap->dev_released);
 	init_completion(&adap->class_dev_released);
 	class_device_unregister(&adap->class_dev);
+	device_remove_file(&adap->dev, &dev_attr_name);
 	device_unregister(&adap->dev);
 	list_del(&adap->list);
 
@@ -361,6 +387,7 @@
 		"%d-%04x", i2c_adapter_id(adapter), client->addr);
 	printk("registering %s\n", client->dev.bus_id);
 	device_register(&client->dev);
+	device_create_file(&client->dev, &dev_attr_client_name);
 	
 	return 0;
 }
@@ -387,6 +414,7 @@
 	down(&adapter->clist_lock);
 	list_del(&client->list);
 	init_completion(&client->released);
+	device_remove_file(&client->dev, &dev_attr_client_name);
 	device_unregister(&client->dev);
 	up(&adapter->clist_lock);
 	wait_for_completion(&client->released);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24 ` Greg KH
@ 2005-05-19  6:24 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:28 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes and additions for 2.6.0-test5.  I've
ported almost all of the i2c bus drivers from the 2.4 cvs tree to the
2.6 kernel (the one exception is a crazy one that acts like a pci
hotplug driver in its init function, I'll leave that to someone else...)
I've also cleaned up the existing i2c bus drivers by moving them into
the proper directory, and polishing up the Kconfig entries.

There are a also a few other minor i2c cleanups and fixes in here.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.5

thanks,

greg k-h

 drivers/i2c/i2c-adap-ite.c           |  278 ----------
 drivers/i2c/i2c-algo-ibm_ocp.c       |  900 -----------------------------------
 drivers/i2c/i2c-algo-ibm_ocp.h       |   55 --
 drivers/i2c/i2c-elektor.c            |  286 -----------
 drivers/i2c/i2c-elv.c                |  176 ------
 drivers/i2c/i2c-frodo.c              |   85 ---
 drivers/i2c/i2c-ibm_iic.c            |  729 ----------------------------
 drivers/i2c/i2c-ibm_iic.h            |  124 ----
 drivers/i2c/i2c-iop3xx.c             |  536 --------------------
 drivers/i2c/i2c-iop3xx.h             |  118 ----
 drivers/i2c/i2c-keywest.c            |  653 -------------------------
 drivers/i2c/i2c-keywest.h            |  110 ----
 drivers/i2c/i2c-philips-par.c        |  256 ---------
 drivers/i2c/i2c-prosavage.c          |  356 -------------
 drivers/i2c/i2c-rpx.c                |  103 ----
 drivers/i2c/i2c-velleman.c           |  161 ------
 drivers/i2c/scx200_acb.c             |  553 ---------------------
 drivers/i2c/scx200_i2c.c             |  133 -----
 drivers/i2c/Kconfig                  |  237 +--------
 drivers/i2c/Makefile                 |   18 
 drivers/i2c/busses/Kconfig           |  385 +++++++++-----
 drivers/i2c/busses/Makefile          |   22 
 drivers/i2c/busses/i2c-ali1535.c     |    4 
 drivers/i2c/busses/i2c-ali15x3.c     |    4 
 drivers/i2c/busses/i2c-amd756.c      |    4 
 drivers/i2c/busses/i2c-amd8111.c     |    3 
 drivers/i2c/busses/i2c-elektor.c     |  304 +++++++++++
 drivers/i2c/busses/i2c-elv.c         |  197 +++++++
 drivers/i2c/busses/i2c-frodo.c       |   85 +++
 drivers/i2c/busses/i2c-i801.c        |    4 
 drivers/i2c/busses/i2c-i810.c        |  256 +++++++++
 drivers/i2c/busses/i2c-ibm_iic.c     |  729 ++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-ibm_iic.h     |  124 ++++
 drivers/i2c/busses/i2c-iop3xx.c      |  536 ++++++++++++++++++++
 drivers/i2c/busses/i2c-iop3xx.h      |  118 ++++
 drivers/i2c/busses/i2c-isa.c         |   10 
 drivers/i2c/busses/i2c-ite.c         |  278 ++++++++++
 drivers/i2c/busses/i2c-keywest.c     |  653 +++++++++++++++++++++++++
 drivers/i2c/busses/i2c-keywest.h     |  110 ++++
 drivers/i2c/busses/i2c-nforce2.c     |    3 
 drivers/i2c/busses/i2c-philips-par.c |  289 ++++++++++-
 drivers/i2c/busses/i2c-piix4.c       |    4 
 drivers/i2c/busses/i2c-prosavage.c   |  410 ++++++++++++++-
 drivers/i2c/busses/i2c-rpx.c         |  105 ++++
 drivers/i2c/busses/i2c-savage4.c     |  205 +++++++
 drivers/i2c/busses/i2c-sis5595.c     |  420 ++++++++++++++++
 drivers/i2c/busses/i2c-sis630.c      |  497 +++++++++++++++++++
 drivers/i2c/busses/i2c-sis96x.c      |    3 
 drivers/i2c/busses/i2c-velleman.c    |  164 ++++++
 drivers/i2c/busses/i2c-via.c         |  184 +++++++
 drivers/i2c/busses/i2c-viapro.c      |    3 
 drivers/i2c/busses/i2c-voodoo3.c     |  248 +++++++++
 drivers/i2c/busses/scx200_acb.c      |  553 +++++++++++++++++++++
 drivers/i2c/busses/scx200_i2c.c      |  132 +++++
 drivers/i2c/chips/Kconfig            |  111 +---
 drivers/i2c/chips/adm1021.c          |   13 
 drivers/i2c/chips/it87.c             |    5 
 drivers/i2c/chips/lm75.c             |    2 
 drivers/i2c/chips/lm78.c             |    8 
 drivers/i2c/chips/lm85.c             |   16 
 drivers/i2c/chips/via686a.c          |    4 
 drivers/i2c/chips/w83781d.c          |   32 -
 drivers/i2c/i2c-adap-ite.c           |    1 
 drivers/i2c/i2c-algo-ite.c           |    1 
 drivers/i2c/i2c-core.c               |    6 
 drivers/i2c/i2c-dev.c                |    3 
 drivers/i2c/i2c-elektor.c            |    1 
 drivers/i2c/i2c-ibm_iic.c            |  729 ++++++++++++++++++++++++++++
 drivers/i2c/i2c-ibm_iic.h            |  124 ++++
 drivers/i2c/i2c-keywest.c            |    1 
 drivers/i2c/i2c-prosavage.c          |    1 
 drivers/i2c/i2c-sensor.c             |    5 
 drivers/i2c/scx200_acb.c             |    2 
 drivers/media/video/msp3400.c        |    2 
 drivers/media/video/saa5249.c        |    2 
 drivers/media/video/tuner.c          |    4 
 drivers/video/matrox/i2c-matroxfb.c  |    2 
 include/linux/i2c-id.h               |    2 
 include/linux/i2c.h                  |    9 
 79 files changed, 7794 insertions(+), 6205 deletions(-)
-----

<arvidjaar:mail.ru>:
  o I2C: sysfs sensor nameing inconsistency

<mds:paradyne.com>:
  o I2C: i2c-isa functionality

Greg Kroah-Hartman:
  o I2C: remove I2C_VERSION and I2C_DATE as they make no sense in the kernel tree
  o I2C: remove check_region usage and warning from i2c-sensor
  o I2C: move the remaining i2c bus drivers to drivers/i2c/busses
  o I2C: move the scx200* drivers to drivers/i2c/busses
  o I2C: move i2c-velleman driver to drivers/i2c/busses
  o I2C: move i2c-elektor.c driver to drivers/i2c/busses/
  o I2C: clean up the i2c-elv.c driver a bit
  o I2C: move i2c-elv.c driver to drivers/i2c/busses
  o I2C: clean up i2c-philips-par.c driver a bit
  o I2C: move the i2c-philips-par driver to drivers/i2c/busses
  o I2C: fix up dependancies in the i2c/busses/Kconfig file
  o I2C: clean up i2c-prosavage.c driver
  o I2C: move i2c-prosavage.c driver to drivers/i2c/busses where it belongs
  o I2C: clean up the drivers/i2c/Kconfig file
  o I2C: clean up the i2c chips Kconfig logic and help information
  o I2C: add the i2c-voodoo3 i2c bus driver
  o I2C: add the i2c-savage4 i2c bus driver
  o I2C: add the i2c-i810 i2c bus driver
  o I2C: turn off debugging on the new sis i2c bus drivers
  o I2C: clean up the i2c bus Kconfig menu and help texts
  o I2C: add the i2c-via i2c bus driver
  o I2C: add the i2c-sis630 i2c bus driver
  o I2C: add the i2c-sis5595 i2c bus driver
  o I2C: remove some usages of i2c_adapter.id as they are not used
  o I2C: added new id for Radeon driver

Hirofumi Ogawa:
  o DEVICE_NAME_SIZE/_HALF removal (I2C related, but fb stuff)
  o DEVICE_NAME_SIZE/_HALF removal (I2C related, but v4l stuff)
  o DEVICE_NAME_SIZE/_HALF removal (I2C stuff)

Martin Schlemmer:
  o I2C: Fix conversion from milli volts in store_in_reg() for w83781d.c

Matt Porter:
  o I2C: New PPC4xx I2C driver

Randy Hron:
  o I2C: drivers/i2c version.h cleanup


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24   ` Greg KH
@ 2005-05-19  6:24     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.2, 2003/08/27 15:29:33-07:00, mds@paradyne.com

[PATCH] I2C: i2c-isa functionality

The "functionality" return was incorrectly removed for i2c-isa.c when porting to 2.5.
A driver that does nothing must return a 0 or else i2c-core assumes
0xffffffff (all functionality).


 drivers/i2c/busses/i2c-isa.c |    9 +++++++++
 1 files changed, 9 insertions(+)


diff -Nru a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
--- a/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:17:05 2003
+++ b/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:17:05 2003
@@ -30,10 +30,13 @@
 #include <linux/errno.h>
 #include <linux/i2c.h>
 
+static u32 isa_func(struct i2c_adapter *adapter);
+
 /* This is the actual algorithm we define */
 static struct i2c_algorithm isa_algorithm = {
 	.name		= "ISA bus algorithm",
 	.id		= I2C_ALGO_ISA,
+	.functionality	= isa_func,
 };
 
 /* There can only be one... */
@@ -44,6 +47,12 @@
 	.algo		= &isa_algorithm,
 	.name		= "ISA main adapter",
 };
+
+/* We can't do a thing... */
+static u32 isa_func(struct i2c_adapter *adapter)
+{
+	return 0;
+}
 
 static int __init i2c_isa_init(void)
 {


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24   ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.1, 2003/08/27 15:24:53-07:00, greg@kroah.com

[PATCH] I2C: added new id for Radeon driver.

As requested by kronos@kronoz.cjb.net


 include/linux/i2c-id.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/include/linux/i2c-id.h b/include/linux/i2c-id.h
--- a/include/linux/i2c-id.h	Mon Sep 22 16:17:15 2003
+++ b/include/linux/i2c-id.h	Mon Sep 22 16:17:15 2003
@@ -100,7 +100,7 @@
 #define I2C_DRIVERID_STM41T00	52	/* real time clock		*/
 #define I2C_DRIVERID_UDA1342	53	/* UDA1342 audio codec		*/
 #define I2C_DRIVERID_ADV7170	54	/* video encoder		*/
-
+#define I2C_DRIVERID_RADEON	55	/* I2C bus on Radeon boards	*/
 
 
 #define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.3, 2003/08/27 15:32:28-07:00, hirofumi@mail.parknet.co.jp

[PATCH] DEVICE_NAME_SIZE/_HALF removal (I2C stuff)


 drivers/i2c/busses/i2c-ali1535.c |    2 +-
 drivers/i2c/busses/i2c-ali15x3.c |    2 +-
 drivers/i2c/busses/i2c-amd756.c  |    2 +-
 drivers/i2c/busses/i2c-amd8111.c |    2 +-
 drivers/i2c/busses/i2c-i801.c    |    2 +-
 drivers/i2c/busses/i2c-nforce2.c |    2 +-
 drivers/i2c/busses/i2c-piix4.c   |    2 +-
 drivers/i2c/busses/i2c-sis96x.c  |    2 +-
 drivers/i2c/busses/i2c-viapro.c  |    2 +-
 drivers/i2c/chips/adm1021.c      |    2 +-
 drivers/i2c/chips/it87.c         |    2 +-
 drivers/i2c/chips/lm75.c         |    2 +-
 drivers/i2c/chips/lm78.c         |    2 +-
 drivers/i2c/chips/lm85.c         |   10 +++++-----
 drivers/i2c/chips/via686a.c      |    2 +-
 drivers/i2c/chips/w83781d.c      |    4 ++--
 drivers/i2c/scx200_acb.c         |    2 +-
 include/linux/i2c.h              |    6 ++++--
 18 files changed, 26 insertions(+), 24 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:54 2003
@@ -507,7 +507,7 @@
 	/* set up the driverfs linkage to our parent device */
 	ali1535_adapter.dev.parent = &dev->dev;
 
-	snprintf(ali1535_adapter.name, DEVICE_NAME_SIZE, 
+	snprintf(ali1535_adapter.name, I2C_NAME_SIZE, 
 		"SMBus ALI1535 adapter at %04x", ali1535_smba);
 	return i2c_add_adapter(&ali1535_adapter);
 }
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:54 2003
@@ -498,7 +498,7 @@
 	/* set up the driverfs linkage to our parent device */
 	ali15x3_adapter.dev.parent = &dev->dev;
 
-	snprintf(ali15x3_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(ali15x3_adapter.name, I2C_NAME_SIZE,
 		"SMBus ALI15X3 adapter at %04x", ali15x3_smba);
 	return i2c_add_adapter(&ali15x3_adapter);
 }
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:54 2003
@@ -369,7 +369,7 @@
 	/* set up the driverfs linkage to our parent device */
 	amd756_adapter.dev.parent = &pdev->dev;
 
-	snprintf(amd756_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(amd756_adapter.name, I2C_NAME_SIZE,
 		"SMBus AMD75x adapter at %04x", amd756_ioport);
 
 	error = i2c_add_adapter(&amd756_adapter);
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:54 2003
@@ -356,7 +356,7 @@
 		goto out_kfree;
 
 	smbus->adapter.owner = THIS_MODULE;
-	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
+	snprintf(smbus->adapter.name, I2C_NAME_SIZE,
 		"SMBus2 AMD8111 adapter at %04x", smbus->base);
 	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
 	smbus->adapter.class = I2C_ADAP_CLASS_SMBUS;
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:54 2003
@@ -598,7 +598,7 @@
 	/* set up the driverfs linkage to our parent device */
 	i801_adapter.dev.parent = &dev->dev;
 
-	snprintf(i801_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(i801_adapter.name, I2C_NAME_SIZE,
 		"SMBus I801 adapter at %04x", i801_smba);
 	return i2c_add_adapter(&i801_adapter);
 }
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:54 2003
@@ -321,7 +321,7 @@
 	smbus->adapter = nforce2_adapter;
 	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
-	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
+	snprintf(smbus->adapter.name, I2C_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);
 
 	error = i2c_add_adapter(&smbus->adapter);
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:54 2003
@@ -451,7 +451,7 @@
 	/* set up the driverfs linkage to our parent device */
 	piix4_adapter.dev.parent = &dev->dev;
 
-	snprintf(piix4_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(piix4_adapter.name, I2C_NAME_SIZE,
 		"SMBus PIIX4 adapter at %04x", piix4_smba);
 
 	retval = i2c_add_adapter(&piix4_adapter);
diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:54 2003
@@ -318,7 +318,7 @@
 	/* set up the driverfs linkage to our parent device */
 	sis96x_adapter.dev.parent = &dev->dev;
 
-	snprintf(sis96x_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(sis96x_adapter.name, I2C_NAME_SIZE,
 		"SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
 
 	if ((retval = i2c_add_adapter(&sis96x_adapter))) {
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:54 2003
@@ -376,7 +376,7 @@
 	dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
 
 	vt596_adapter.dev.parent = &pdev->dev;
-	snprintf(vt596_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(vt596_adapter.name, I2C_NAME_SIZE,
 			"SMBus Via Pro adapter at %04x", vt596_smba);
 	
 	return i2c_add_adapter(&vt596_adapter);
diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:16:54 2003
@@ -320,7 +320,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	new_client->id = adm1021_id++;
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/it87.c	Mon Sep 22 16:16:54 2003
@@ -692,7 +692,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
 
 	data->type = kind;
 
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/lm75.c	Mon Sep 22 16:16:54 2003
@@ -194,7 +194,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
 
 	new_client->id = lm75_id++;
 	data->valid = 0;
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/lm78.c	Mon Sep 22 16:16:54 2003
@@ -638,7 +638,7 @@
 	}
 
 	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	data->valid = 0;
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/lm85.c	Mon Sep 22 16:16:54 2003
@@ -853,19 +853,19 @@
 	/* Fill in the chip specific driver values */
 	if ( kind == any_chip ) {
 		type_name = "lm85";
-		strlcpy(new_client->name, "Generic LM85", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "Generic LM85", I2C_NAME_SIZE);
 	} else if ( kind == lm85b ) {
 		type_name = "lm85b";
-		strlcpy(new_client->name, "National LM85-B", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "National LM85-B", I2C_NAME_SIZE);
 	} else if ( kind == lm85c ) {
 		type_name = "lm85c";
-		strlcpy(new_client->name, "National LM85-C", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "National LM85-C", I2C_NAME_SIZE);
 	} else if ( kind == adm1027 ) {
 		type_name = "adm1027";
-		strlcpy(new_client->name, "Analog Devices ADM1027", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "Analog Devices ADM1027", I2C_NAME_SIZE);
 	} else if ( kind == adt7463 ) {
 		type_name = "adt7463";
-		strlcpy(new_client->name, "Analog Devices ADT7463", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "Analog Devices ADT7463", I2C_NAME_SIZE);
 	} else {
 		dev_dbg(&adapter->dev, "Internal error, invalid kind (%d)!", kind);
 		err = -EFAULT ;
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/via686a.c	Mon Sep 22 16:16:54 2003
@@ -727,7 +727,7 @@
 	new_client->dev.parent = &adapter->dev;
 
 	/* Fill in the remaining client fields and put into the global list */
-	snprintf(new_client->name, DEVICE_NAME_SIZE, client_name);
+	snprintf(new_client->name, I2C_NAME_SIZE, client_name);
 
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:54 2003
@@ -1117,7 +1117,7 @@
 		data->lm75[i]->driver = &w83781d_driver;
 		data->lm75[i]->flags = 0;
 		strlcpy(data->lm75[i]->name, client_name,
-			DEVICE_NAME_SIZE);
+			I2C_NAME_SIZE);
 		if ((err = i2c_attach_client(data->lm75[i]))) {
 			dev_err(&new_client->dev, "Subclient %d "
 				"registration at address 0x%x "
@@ -1326,7 +1326,7 @@
 	}
 
 	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	data->valid = 0;
diff -Nru a/drivers/i2c/scx200_acb.c b/drivers/i2c/scx200_acb.c
--- a/drivers/i2c/scx200_acb.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/scx200_acb.c	Mon Sep 22 16:16:54 2003
@@ -456,7 +456,7 @@
 	memset(iface, 0, sizeof(*iface));
 	adapter = &iface->adapter;
 	i2c_set_adapdata(adapter, iface);
-	snprintf(adapter->name, DEVICE_NAME_SIZE, "SCx200 ACB%d", index);
+	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
 	adapter->owner = THIS_MODULE;
 	adapter->id = I2C_ALGO_SMBUS;
 	adapter->algo = &scx200_acb_algorithm;
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Mon Sep 22 16:16:54 2003
+++ b/include/linux/i2c.h	Mon Sep 22 16:16:54 2003
@@ -146,6 +146,8 @@
 
 extern struct bus_type i2c_bus_type;
 
+#define I2C_NAME_SIZE	50
+
 /*
  * i2c_client identifies a single device (i.e. chip) that is connected to an 
  * i2c bus. The behaviour is defined by the routines of the driver. This
@@ -166,7 +168,7 @@
 					/* to the client		*/
 	struct device dev;		/* the device structure		*/
 	struct list_head list;
-	char name[DEVICE_NAME_SIZE];
+	char name[I2C_NAME_SIZE];
 	struct completion released;
 };
 #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
@@ -253,7 +255,7 @@
 	int nr;
 	struct list_head clients;
 	struct list_head list;
-	char name[DEVICE_NAME_SIZE];
+	char name[I2C_NAME_SIZE];
 	struct completion dev_released;
 	struct completion class_dev_released;
 };


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24           ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.5, 2003/08/27 15:32:59-07:00, hirofumi@mail.parknet.co.jp

[PATCH] DEVICE_NAME_SIZE/_HALF removal (I2C related, but fb stuff)


 drivers/video/matrox/i2c-matroxfb.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
--- a/drivers/video/matrox/i2c-matroxfb.c	Mon Sep 22 16:16:30 2003
+++ b/drivers/video/matrox/i2c-matroxfb.c	Mon Sep 22 16:16:30 2003
@@ -111,7 +111,7 @@
 	b->mask.data = data;
 	b->mask.clock = clock;
 	b->adapter = matrox_i2c_adapter_template;
-	snprintf(b->adapter.name, DEVICE_NAME_SIZE, name,
+	snprintf(b->adapter.name, I2C_NAME_SIZE, name,
 		minfo->fbcon.node);
 	i2c_set_adapdata(&b->adapter, b);
 	b->adapter.algo_data = &b->bac;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.4, 2003/08/27 15:32:44-07:00, hirofumi@mail.parknet.co.jp

[PATCH] DEVICE_NAME_SIZE/_HALF removal (I2C related, but v4l stuff)


 drivers/media/video/msp3400.c |    2 +-
 drivers/media/video/saa5249.c |    2 +-
 drivers/media/video/tuner.c   |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
--- a/drivers/media/video/msp3400.c	Mon Sep 22 16:16:43 2003
+++ b/drivers/media/video/msp3400.c	Mon Sep 22 16:16:43 2003
@@ -1316,7 +1316,7 @@
 #endif
 	msp3400c_setvolume(c,msp->muted,msp->left,msp->right);
 
-	snprintf(c->name, DEVICE_NAME_SIZE, "MSP34%02d%c-%c%d",
+	snprintf(c->name, I2C_NAME_SIZE, "MSP34%02d%c-%c%d",
 		 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@',
 		 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
 
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	Mon Sep 22 16:16:43 2003
+++ b/drivers/media/video/saa5249.c	Mon Sep 22 16:16:43 2003
@@ -171,7 +171,7 @@
 		return -ENOMEM;
 	}
 	memset(t, 0, sizeof(*t));
-	strlcpy(client->name, IF_NAME, DEVICE_NAME_SIZE);
+	strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
 	init_MUTEX(&t->lock);
 	
 	/*
diff -Nru a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c
--- a/drivers/media/video/tuner.c	Mon Sep 22 16:16:43 2003
+++ b/drivers/media/video/tuner.c	Mon Sep 22 16:16:43 2003
@@ -824,7 +824,7 @@
 	if (type < TUNERS) {
 		t->type = type;
 		printk("tuner(bttv): type forced to %d (%s) [insmod]\n",t->type,tuners[t->type].name);
-		strlcpy(client->name, tuners[t->type].name, DEVICE_NAME_SIZE);
+		strlcpy(client->name, tuners[t->type].name, I2C_NAME_SIZE);
 	}
         i2c_attach_client(client);
         if (t->type == TUNER_MT2032)
@@ -875,7 +875,7 @@
 		t->type = *iarg;
 		printk("tuner: type set to %d (%s)\n",
                         t->type,tuners[t->type].name);
-		strlcpy(client->name, tuners[t->type].name, DEVICE_NAME_SIZE);
+		strlcpy(client->name, tuners[t->type].name, I2C_NAME_SIZE);
 		if (t->type == TUNER_MT2032)
                         mt2032_init(client);
 		break;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24             ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.123.2, 2003/09/04 11:28:46-07:00, azarah@gentoo.org

[PATCH] I2C: Fix conversion from milli volts in store_in_reg() for w83781d.c

I am not sure if it was a later patch from me that fixed in_* to display
milli volts in sysfs, or if it was a patch from Jan Dittmer, but the
conversion in the store_in_*() functions is wrong, and cause something
like:


 drivers/i2c/chips/w83781d.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:19 2003
+++ b/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:19 2003
@@ -378,8 +378,8 @@
 	struct w83781d_data *data = i2c_get_clientdata(client); \
 	u32 val; \
 	 \
-	val = simple_strtoul(buf, NULL, 10); \
-	data->in_##reg[nr] = (IN_TO_REG(val) / 10); \
+	val = simple_strtoul(buf, NULL, 10) / 10; \
+	data->in_##reg[nr] = IN_TO_REG(val); \
 	w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
 	 \
 	return count; \


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.2, 2003/09/15 13:46:00-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-sis5595 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig       |   17 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-sis5595.c |  417 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 435 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:57 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:57 2003
@@ -149,6 +149,23 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_SIS5595
+	tristate "  Sis5595"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the 
+	  SiS5595 SMBus (a subset of I2C) interface.
+
+	  This can also be built as a module which can be inserted and removed 
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-sis5595.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at 
+	  http://www.lm-sensors.nu
+
 
 config I2C_SIS96X
 	tristate "  SiS 96x"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:57 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:57 2003
@@ -10,5 +10,6 @@
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:15:57 2003
@@ -0,0 +1,417 @@
+/*
+    sis5595.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
+    Philip Edelbrock <phil@netroedge.com>
+
+    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.
+*/
+
+/* Note: we assume there can only be one SIS5595 with one SMBus interface */
+
+/*
+   Note: all have mfr. ID 0x1039.
+   SUPPORTED		PCI ID		
+	5595		0008
+
+   Note: these chips contain a 0008 device which is incompatible with the
+         5595. We recognize these by the presence of the listed
+         "blacklist" PCI ID and refuse to load.
+
+   NOT SUPPORTED	PCI ID		BLACKLIST PCI ID	
+	 540		0008		0540
+	 550		0008		0550
+	5513		0008		5511
+	5581		0008		5597
+	5582		0008		5597
+	5597		0008		5597
+	5598		0008		5597/5598
+	 630		0008		0630
+	 645		0008		0645
+	 646		0008		0646
+	 648		0008		0648
+	 650		0008		0650
+	 651		0008		0651
+	 730		0008		0730
+	 735		0008		0735
+	 745		0008		0745
+	 746		0008		0746
+*/
+
+/* TO DO: 
+ * Add Block Transfers (ugly, but supported by the adapter)
+ * Add adapter resets
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+static int blacklist[] = {
+	PCI_DEVICE_ID_SI_540,
+	PCI_DEVICE_ID_SI_550,
+	PCI_DEVICE_ID_SI_630,
+	PCI_DEVICE_ID_SI_645,
+	PCI_DEVICE_ID_SI_646,
+	PCI_DEVICE_ID_SI_648,
+	PCI_DEVICE_ID_SI_650,
+	PCI_DEVICE_ID_SI_651,
+	PCI_DEVICE_ID_SI_730,
+	PCI_DEVICE_ID_SI_735,
+	PCI_DEVICE_ID_SI_745,
+	PCI_DEVICE_ID_SI_746,
+	PCI_DEVICE_ID_SI_5511,	/* 5513 chip has the 0008 device but that ID
+				   shows up in other chips so we use the 5511
+				   ID for recognition */
+	PCI_DEVICE_ID_SI_5597,
+	PCI_DEVICE_ID_SI_5598,
+	0,			/* terminates the list */
+};
+
+/* Length of ISA address segment */
+#define SIS5595_EXTENT		8
+/* SIS5595 SMBus registers */
+#define SMB_STS_LO		0x00
+#define SMB_STS_HI		0x01
+#define SMB_CTL_LO		0x02
+#define SMB_CTL_HI		0x03
+#define SMB_ADDR		0x04
+#define SMB_CMD			0x05
+#define SMB_PCNT		0x06
+#define SMB_CNT			0x07
+#define SMB_BYTE		0x08
+#define SMB_DEV			0x10
+#define SMB_DB0			0x11
+#define SMB_DB1			0x12
+#define SMB_HAA			0x13
+
+/* PCI Address Constants */
+#define SMB_INDEX		0x38
+#define SMB_DAT			0x39
+#define SIS5595_ENABLE_REG	0x40
+#define ACPI_BASE		0x90
+
+/* Other settings */
+#define MAX_TIMEOUT		500
+
+/* SIS5595 constants */
+#define SIS5595_QUICK		0x00
+#define SIS5595_BYTE		0x02
+#define SIS5595_BYTE_DATA	0x04
+#define SIS5595_WORD_DATA	0x06
+#define SIS5595_PROC_CALL	0x08
+#define SIS5595_BLOCK_DATA	0x0A
+
+/* insmod parameters */
+
+/* If force_addr is set to anything different from 0, we forcibly enable
+   the device at the given address. */
+static int force_addr = 0;
+MODULE_PARM(force_addr, "i");
+MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
+
+static unsigned short sis5595_base = 0;
+
+static u8 sis5595_read(u8 reg)
+{
+	outb(reg, sis5595_base + SMB_INDEX);
+	return inb(sis5595_base + SMB_DAT);
+}
+
+static void sis5595_write(u8 reg, u8 data)
+{
+	outb(reg, sis5595_base + SMB_INDEX);
+	outb(data, sis5595_base + SMB_DAT);
+}
+
+static int sis5595_setup(struct pci_dev *SIS5595_dev)
+{
+	u16 a;
+	u8 val;
+	int *i;
+	int retval = -ENODEV;
+
+	/* Look for imposters */
+	for (i = blacklist; *i != 0; i++) {
+		struct pci_dev *dev;
+		dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
+		if (dev) {
+			dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
+			pci_dev_put(dev);
+			return -ENODEV;
+		}
+	}
+
+	/* Determine the address of the SMBus areas */
+	pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
+	if (sis5595_base == 0 && force_addr == 0) {
+		dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
+		return -ENODEV;
+	}
+
+	if (force_addr)
+		sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
+	dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
+
+	/* NB: We grab just the two SMBus registers here, but this may still
+	 * interfere with ACPI :-(  */
+	if (!request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus")) {
+		dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
+			sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
+		return -ENODEV;
+	}
+
+	if (force_addr) {
+		dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
+		if (!pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base))
+			goto error;
+		if (!pci_read_config_word(SIS5595_dev, ACPI_BASE, &a))
+			goto error;
+		if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
+			/* doesn't work for some chips! */
+			dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
+			goto error;
+		}
+	}
+
+	if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val))
+		goto error;
+	if ((val & 0x80) == 0) {
+		dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
+		if (!pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80))
+			goto error;
+		if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val))
+			goto error;
+		if ((val & 0x80) == 0) {
+			/* doesn't work for some chips? */
+			dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
+			goto error;
+		}
+	}
+
+	/* Everything is happy */
+	return 0;
+
+error:
+	release_region(sis5595_base + SMB_INDEX, 2);
+	return retval;
+}
+
+static int sis5595_transaction(struct i2c_adapter *adap)
+{
+	int temp;
+	int result = 0;
+	int timeout = 0;
+
+	/* Make sure the SMBus host is ready to start transmitting */
+	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
+	if (temp != 0x00) {
+		dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting... \n", temp);
+		sis5595_write(SMB_STS_LO, temp & 0xff);
+		sis5595_write(SMB_STS_HI, temp >> 8);
+		if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
+			dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
+			return -1;
+		} else {
+			dev_dbg(&adap->dev, "Successfull!\n");
+		}
+	}
+
+	/* start the transaction by setting bit 4 */
+	sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
+
+	/* We will always wait for a fraction of a second! */
+	do {
+		i2c_delay(1);
+		temp = sis5595_read(SMB_STS_LO);
+	} while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
+
+	/* If the SMBus is still busy, we give up */
+	if (timeout >= MAX_TIMEOUT) {
+		dev_dbg(&adap->dev, "SMBus Timeout!\n");
+		result = -1;
+	}
+
+	if (temp & 0x10) {
+		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
+		result = -1;
+	}
+
+	if (temp & 0x20) {
+		dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
+			"next hard reset (or not...)\n");
+		/* Clock stops and slave is stuck in mid-transmission */
+		result = -1;
+	}
+
+	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
+	if (temp != 0x00) {
+		sis5595_write(SMB_STS_LO, temp & 0xff);
+		sis5595_write(SMB_STS_HI, temp >> 8);
+	}
+
+	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
+	if (temp != 0x00)
+		dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
+
+	return result;
+}
+
+/* Return -1 on error. */
+static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
+			  unsigned short flags, char read_write,
+			  u8 command, int size, union i2c_smbus_data *data)
+{
+	switch (size) {
+	case I2C_SMBUS_QUICK:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		size = SIS5595_QUICK;
+		break;
+	case I2C_SMBUS_BYTE:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		if (read_write == I2C_SMBUS_WRITE)
+			sis5595_write(SMB_CMD, command);
+		size = SIS5595_BYTE;
+		break;
+	case I2C_SMBUS_BYTE_DATA:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		sis5595_write(SMB_CMD, command);
+		if (read_write == I2C_SMBUS_WRITE)
+			sis5595_write(SMB_BYTE, data->byte);
+		size = SIS5595_BYTE_DATA;
+		break;
+	case I2C_SMBUS_PROC_CALL:
+	case I2C_SMBUS_WORD_DATA:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		sis5595_write(SMB_CMD, command);
+		if (read_write == I2C_SMBUS_WRITE) {
+			sis5595_write(SMB_BYTE, data->word & 0xff);
+			sis5595_write(SMB_BYTE + 1,
+				      (data->word & 0xff00) >> 8);
+		}
+		size = (size == I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
+		break;
+/*
+	case I2C_SMBUS_BLOCK_DATA:
+		printk("sis5595.o: Block data not yet implemented!\n");
+		return -1;
+		break;
+*/
+	default:
+		printk
+		    (KERN_WARNING "sis5595.o: Unsupported transaction %d\n", size);
+		return -1;
+	}
+
+	sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
+
+	if (sis5595_transaction(adap))
+		return -1;
+
+	if ((size != SIS5595_PROC_CALL) &&
+	    ((read_write == I2C_SMBUS_WRITE) || (size == SIS5595_QUICK)))
+		return 0;
+
+
+	switch (size) {
+	case SIS5595_BYTE:	/* Where is the result put? I assume here it is in
+				   SMB_DATA but it might just as well be in the
+				   SMB_CMD. No clue in the docs */
+	case SIS5595_BYTE_DATA:
+		data->byte = sis5595_read(SMB_BYTE);
+		break;
+	case SIS5595_WORD_DATA:
+	case SIS5595_PROC_CALL:
+		data->word = sis5595_read(SMB_BYTE) + (sis5595_read(SMB_BYTE + 1) << 8);
+		break;
+	}
+	return 0;
+}
+
+static u32 sis5595_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	    I2C_FUNC_SMBUS_PROC_CALL;
+}
+
+static struct i2c_algorithm smbus_algorithm = {
+	.name		= "Non-I2C SMBus adapter",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= sis5595_access,
+	.functionality	= sis5595_func,
+};
+
+static struct i2c_adapter sis5595_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "unset",
+	.algo		= &smbus_algorithm,
+};
+
+static struct pci_device_id sis5595_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, 
+	{ 0, }
+};
+
+static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	if (sis5595_setup(dev)) {
+		dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
+		return -ENODEV;
+	}
+
+	/* set up the driverfs linkage to our parent device */
+	sis5595_adapter.dev.parent = &dev->dev;
+
+	sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
+		sis5595_base + SMB_INDEX);
+	return i2c_add_adapter(&sis5595_adapter);
+}
+
+static void __devexit sis5595_remove(struct pci_dev *dev)
+{
+	i2c_del_adapter(&sis5595_adapter);
+}
+
+static struct pci_driver sis5595_driver = {
+	.name		= "sis5595 smbus",
+	.id_table	= sis5595_ids,
+	.probe		= sis5595_probe,
+	.remove		= __devexit_p(sis5595_remove),
+};
+
+static int __init i2c_sis5595_init(void)
+{
+	printk(KERN_INFO "i2c-sis5595 version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	return pci_module_init(&sis5595_driver);
+}
+
+static void __exit i2c_sis5595_exit(void)
+{
+	pci_unregister_driver(&sis5595_driver);
+	release_region(sis5595_base + SMB_INDEX, 2);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("SIS5595 SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_sis5595_init);
+module_exit(i2c_sis5595_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24               ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1217.7.2, 2003/09/12 16:58:01-07:00, greg@kroah.com

[PATCH] I2C: remove some usages of i2c_adapter.id as they are not used.

Seems i2c_adapter.id is only used in some video drivers, will work on
cleaning up that mess later...


 drivers/i2c/busses/i2c-ali1535.c |    1 -
 drivers/i2c/busses/i2c-ali15x3.c |    1 -
 drivers/i2c/busses/i2c-amd756.c  |    1 -
 drivers/i2c/busses/i2c-amd8111.c |    1 -
 drivers/i2c/busses/i2c-i801.c    |    1 -
 drivers/i2c/busses/i2c-isa.c     |    1 -
 drivers/i2c/busses/i2c-nforce2.c |    1 -
 drivers/i2c/busses/i2c-piix4.c   |    1 -
 drivers/i2c/busses/i2c-sis96x.c  |    1 -
 drivers/i2c/busses/i2c-viapro.c  |    1 -
 drivers/i2c/i2c-core.c           |    6 ++----
 11 files changed, 2 insertions(+), 14 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:09 2003
@@ -481,7 +481,6 @@
 
 static struct i2c_adapter ali1535_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI1535,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
 };
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:09 2003
@@ -471,7 +471,6 @@
 
 static struct i2c_adapter ali15x3_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI15X3,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:09 2003
@@ -304,7 +304,6 @@
 
 static struct i2c_adapter amd756_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD756,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:09 2003
@@ -358,7 +358,6 @@
 	smbus->adapter.owner = THIS_MODULE;
 	snprintf(smbus->adapter.name, I2C_NAME_SIZE,
 		"SMBus2 AMD8111 adapter at %04x", smbus->base);
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
 	smbus->adapter.class = I2C_ADAP_CLASS_SMBUS;
 	smbus->adapter.algo = &smbus_algorithm;
 	smbus->adapter.algo_data = smbus;
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:09 2003
@@ -540,7 +540,6 @@
 
 static struct i2c_adapter i801_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_I801,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
--- a/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:16:09 2003
@@ -42,7 +42,6 @@
 /* There can only be one... */
 static struct i2c_adapter isa_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_ISA | I2C_HW_ISA,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo		= &isa_algorithm,
 	.name		= "ISA main adapter",
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:09 2003
@@ -118,7 +118,6 @@
 
 static struct i2c_adapter nforce2_adapter = {
 	.owner          = THIS_MODULE,
-	.id             = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo           = &smbus_algorithm,
 	.name   	= "unset",
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:09 2003
@@ -395,7 +395,6 @@
 
 static struct i2c_adapter piix4_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_PIIX4,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:09 2003
@@ -261,7 +261,6 @@
 
 static struct i2c_adapter sis96x_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_SIS96X,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:09 2003
@@ -287,7 +287,6 @@
 
 static struct i2c_adapter vt596_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_VIA2,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/i2c-core.c	Mon Sep 22 16:16:09 2003
@@ -581,8 +581,7 @@
 		 */
 		return (ret == 1 )? count : ret;
 	} else {
-		printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
-		       client->adapter->id);
+		dev_err(&client->adapter->dev, "I2C level transfers not supported\n");
 		return -ENOSYS;
 	}
 }
@@ -614,8 +613,7 @@
 	 	*/
 		return (ret == 1 )? count : ret;
 	} else {
-		printk(KERN_DEBUG "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
-		       client->adapter->id);
+		dev_err(&client->adapter->dev, "I2C level transfers not supported\n");
 		return -ENOSYS;
 	}
 }


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.4, 2003/09/15 16:37:19-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-via i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig   |   17 +++
 drivers/i2c/busses/Makefile  |    1 
 drivers/i2c/busses/i2c-via.c |  183 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 201 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:36 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:36 2003
@@ -207,6 +207,23 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_VIA
+	tristate "  VIA 82C58B"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+
+	  If you say yes to this option, support will be included for the VIA
+          82C586B I2C interface
+
+	  This can also be built as a module which can be inserted and removed
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-via.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at
+	  http://www.lm-sensors.nu
 
 config I2C_VIAPRO
 	tristate "  VIA 82C596/82C686/823x"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:36 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:36 2003
@@ -13,4 +13,5 @@
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
+obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
diff -Nru a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-via.c	Mon Sep 22 16:15:36 2003
@@ -0,0 +1,183 @@
+/*
+    i2c-via.c - Part of lm_sensors,  Linux kernel modules
+                for hardware monitoring
+
+    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.
+*/
+
+#define DEBUG
+
+#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>
+
+/* 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
+#define IOTEXT		"via-i2c"
+
+static u16 pm_io_base = 0;
+
+/*
+   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,
+	.mdelay		= 5,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter vt586b_adapter = {
+	.owner		= THIS_MODULE,
+	.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, }
+};
+
+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, IOTEXT)) {
+		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 driverfs 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_bit_del_bus(&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)
+{
+	printk(KERN_INFO "i2c-via version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	return pci_module_init(&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);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.5, 2003/09/15 16:38:32-07:00, greg@kroah.com

[PATCH] I2C: clean up the i2c bus Kconfig menu and help texts.


 drivers/i2c/busses/Kconfig |  165 ++++++++++-----------------------------------
 1 files changed, 39 insertions(+), 126 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:25 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:25 2003
@@ -5,7 +5,7 @@
 menu "I2C Hardware Sensors Mainboard support"
 
 config I2C_ALI1535
-	tristate "  ALI 1535"
+	tristate "ALI 1535"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SMB
@@ -13,63 +13,41 @@
 	  controller is part of the 7101 device, which is an ACPI-compliant
 	  Power Management Unit (PMU).
 
-	  This can also be built as a module.  If so, the module will be
-	  called i2c-ali1535.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-ali1535.
 
 config I2C_ALI15X3
-	tristate "  ALI 15x3"
+	tristate "ALI 15x3"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the
 	  Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
 
-	  This can also be built as a module.  If so, the module will be
-	  called i2c-ali15x3.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-ali15x3.
 
 config I2C_AMD756
-	tristate "  AMD 756/766"
+	tristate "AMD 756/766"
 	depends on I2C && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the AMD
 	  756/766/768 mainboard I2C interfaces.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-amd756.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-amd756.
 
 config I2C_AMD8111
-	tristate "  AMD 8111"
+	tristate "AMD 8111"
 	depends on I2C && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the AMD
 	  8111 mainboard I2C interfaces.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-amd8111.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-amd8111.
 
 config I2C_I801
-	tristate "  Intel 801"
+	tristate "Intel 801"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -81,53 +59,31 @@
 	    82801CA/CAM
 	    82801DB
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-i801.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-i801.
 
 config I2C_ISA
-	tristate "  ISA Bus support"
+	tristate "ISA Bus support"
 	depends on I2C && ISA && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for i2c
 	  interfaces that are on the ISA bus.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-isa.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-isa.
 
 config I2C_NFORCE2
-	tristate "  Nvidia Nforce2"
+	tristate "Nvidia Nforce2"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Nvidia
 	  Nforce2 family of mainboard I2C interfaces.
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-nforce2.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
-
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-nforce2.
 
 config I2C_PIIX4
-	tristate "  Intel PIIX4"
+	tristate "Intel PIIX4"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -139,52 +95,31 @@
 	    Serverworks CSB5
 	    SMSC Victory66
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-piix4.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-piix4.
 
 config I2C_SIS5595
-	tristate "  Sis5595"
+	tristate "SiS 5595"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS5595 SMBus (a subset of I2C) interface.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-sis5595.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sis5595.
 
 config I2C_SIS630
-	tristate "  Sis630"
+	tristate "SiS 630"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS630 SMBus (a subset of I2C) interface.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-sis630.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sis630.
 
 config I2C_SIS96X
-	tristate "  SiS 96x"
+	tristate "SiS 96x"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SiS
@@ -197,36 +132,22 @@
 	    650/961
 	    735
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-sis96x.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sis96x.
 
 config I2C_VIA
-	tristate "  VIA 82C58B"
+	tristate "VIA 82C58B"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 
 	  If you say yes to this option, support will be included for the VIA
           82C586B I2C interface
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-via.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-via.
 
 config I2C_VIAPRO
-	tristate "  VIA 82C596/82C686/823x"
+	tristate "VIA 82C596/82C686/823x"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 
@@ -240,15 +161,7 @@
 	  8233A
 	  8235
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-viapro.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-viapro.
 
 endmenu
-


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                   ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.3, 2003/09/15 16:15:33-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-sis630 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig      |   16 +
 drivers/i2c/busses/Makefile     |    1 
 drivers/i2c/busses/i2c-sis630.c |  494 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 511 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:46 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:46 2003
@@ -166,6 +166,22 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_SIS630
+	tristate "  Sis630"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the 
+	  SiS630 SMBus (a subset of I2C) interface.
+
+	  This can also be built as a module which can be inserted and removed 
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-sis630.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at 
+	  http://www.lm-sensors.nu
 
 config I2C_SIS96X
 	tristate "  SiS 96x"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:46 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:46 2003
@@ -11,5 +11,6 @@
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
+obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:15:46 2003
@@ -0,0 +1,494 @@
+/*
+    i2c-sis630.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+
+    Copyright (c) 2002,2003 Alexander Malysh <amalysh@web.de>
+
+    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.
+*/
+
+/*
+   Changes:
+   24.08.2002
+   	Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
+	Changed sis630_transaction.(Thanks to Mark M. Hoffman)
+   18.09.2002
+	Added SIS730 as supported
+   21.09.2002
+	Added high_clock module option.If this option is set
+	used Host Master Clock 56KHz (default 14KHz).For now we are save old Host
+	Master Clock and after transaction completed restore (otherwise
+	it's confuse BIOS and hung Machine).
+   24.09.2002
+	Fixed typo in sis630_access
+	Fixed logical error by restoring of Host Master Clock
+   31.07.2003
+   	Added block data read/write support.
+*/
+
+/*
+   Status: beta
+
+   Supports:
+	SIS 630
+	SIS 730
+
+   Note: we assume there can only be one device, with one SMBus interface.
+*/
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+
+/* SIS630 SMBus registers */
+#define SMB_STS			0x80	/* status */
+#define SMB_EN			0x81	/* status enable */
+#define SMB_CNT			0x82
+#define SMBHOST_CNT		0x83
+#define SMB_ADDR		0x84
+#define SMB_CMD			0x85
+#define SMB_PCOUNT		0x86	/* processed count */
+#define SMB_COUNT		0x87
+#define SMB_BYTE		0x88	/* ~0x8F data byte field */
+#define SMBDEV_ADDR		0x90
+#define SMB_DB0			0x91
+#define SMB_DB1			0x92
+#define SMB_SAA			0x93
+
+/* register count for request_region */
+#define SIS630_SMB_IOREGION	20
+
+/* PCI address constants */
+/* acpi base address register  */
+#define SIS630_ACPI_BASE_REG	0x74
+/* bios control register */
+#define SIS630_BIOS_CTL_REG	0x40
+
+/* Other settings */
+#define MAX_TIMEOUT		500
+
+/* SIS630 constants */
+#define SIS630_QUICK		0x00
+#define SIS630_BYTE		0x01
+#define SIS630_BYTE_DATA	0x02
+#define SIS630_WORD_DATA	0x03
+#define SIS630_PCALL		0x04
+#define SIS630_BLOCK_DATA	0x05
+
+/* insmod parameters */
+static int high_clock = 0;
+MODULE_PARM(high_clock, "i");
+MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
+
+
+static unsigned short acpi_base = 0;
+
+static inline u8 sis630_read(u8 reg)
+{
+	return inb(acpi_base + reg);
+}
+
+static inline void sis630_write(u8 reg, u8 data)
+{
+	outb(data, acpi_base + reg);
+}
+
+static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldclock)
+{
+        int temp;
+
+	/* Make sure the SMBus host is ready to start transmitting. */
+	if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
+		dev_dbg(&adap->dev, "SMBus busy (%02x).Resetting...\n",temp);
+		/* kill smbus transaction */
+		sis630_write(SMBHOST_CNT, 0x20);
+
+		if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
+			dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
+			return -1;
+                } else {
+			dev_dbg(&adap->dev, "Successfull!\n");
+		}
+        }
+
+	/* save old clock, so we can prevent machine for hung */
+	*oldclock = sis630_read(SMB_CNT);
+
+	dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock);
+
+	/* disable timeout interrupt , set Host Master Clock to 56KHz if requested */
+	if (high_clock > 0)
+		sis630_write(SMB_CNT, 0x20);
+	else
+		sis630_write(SMB_CNT, (*oldclock & ~0x40));
+
+	/* clear all sticky bits */
+	temp = sis630_read(SMB_STS);
+	sis630_write(SMB_STS, temp & 0x1e);
+
+	/* start the transaction by setting bit 4 and size */
+	sis630_write(SMBHOST_CNT,0x10 | (size & 0x07));
+
+	return 0;
+}
+
+static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
+{
+	int temp, result = 0, timeout = 0;
+
+	/* We will always wait for a fraction of a second! */
+	do {
+		i2c_delay(1);
+		temp = sis630_read(SMB_STS);
+		/* check if block transmitted */
+		if (size == SIS630_BLOCK_DATA && (temp & 0x10))
+			break;
+	} while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
+
+	/* If the SMBus is still busy, we give up */
+	if (timeout >= MAX_TIMEOUT) {
+		dev_dbg(&adap->dev, "SMBus Timeout!\n");
+		result = -1;
+	}
+
+	if (temp & 0x02) {
+		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
+		result = -1;
+	}
+
+	if (temp & 0x04) {
+		dev_err(&adap->dev, "Bus collision!\n");
+		result = -1;
+		/*
+		  TBD: Datasheet say:
+		  the software should clear this bit and restart SMBUS operation.
+		  Should we do it or user start request again?
+		*/
+	}
+
+	return result;
+}
+
+static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock)
+{
+	int temp = 0;
+
+	/* clear all status "sticky" bits */
+	sis630_write(SMB_STS, temp);
+
+	dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT));
+
+	/*
+	 * restore old Host Master Clock if high_clock is set
+	 * and oldclock was not 56KHz
+	 */
+	if (high_clock > 0 && !(oldclock & 0x20))
+		sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20));
+
+	dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT));
+}
+
+static int sis630_transaction(struct i2c_adapter *adap, int size)
+{
+	int result = 0;
+	u8 oldclock = 0;
+
+	result = sis630_transaction_start(adap, size, &oldclock);
+	if (!result) {
+		result = sis630_transaction_wait(adap, size);
+		sis630_transaction_end(adap, oldclock);
+	}
+
+	return result;
+}
+
+static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write)
+{
+	int i, len = 0, rc = 0;
+	u8 oldclock = 0;
+
+	if (read_write == I2C_SMBUS_WRITE) {
+		len = data->block[0];
+		if (len < 0)
+			len = 0;
+		else if (len > 32)
+			len = 32;
+		sis630_write(SMB_COUNT, len);
+		for (i=1; i <= len; i++) {
+			dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]);
+			/* set data */
+			sis630_write(SMB_BYTE+(i-1)%8, data->block[i]);
+			if (i==8 || (len<8 && i==len)) {
+				dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i);
+				/* first transaction */
+				if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock))
+					return -1;
+			}
+			else if ((i-1)%8 == 7 || i==len) {
+				dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i);
+				if (i>8) {
+					dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
+					/*
+					   If this is not first transaction,
+					   we must clear sticky bit.
+					   clear SMBARY_STS
+					*/
+					sis630_write(SMB_STS,0x10);
+				}
+				if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) {
+					dev_dbg(&adap->dev, "trans_wait failed\n");
+					rc = -1;
+					break;
+				}
+			}
+		}
+	}
+	else {
+		/* read request */
+		data->block[0] = len = 0;
+		if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) {
+			return -1;
+		}
+		do {
+			if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) {
+				dev_dbg(&adap->dev, "trans_wait failed\n");
+				rc = -1;
+				break;
+			}
+			/* if this first transaction then read byte count */
+			if (len == 0)
+				data->block[0] = sis630_read(SMB_COUNT);
+
+			dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
+
+			for (i=0; i < 8 && len < data->block[0]; i++,len++) {
+				dev_dbg(&adap->dev, "read i=%d len=%d\n", i, len);
+				data->block[len+1] = sis630_read(SMB_BYTE+i);
+			}
+
+			dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
+
+			/* clear SMBARY_STS */
+			sis630_write(SMB_STS,0x10);
+		} while(len < data->block[0]);
+	}
+
+	sis630_transaction_end(adap, oldclock);
+
+	return rc;
+}
+
+/* Return -1 on error. */
+static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
+			 unsigned short flags, char read_write,
+			 u8 command, int size, union i2c_smbus_data *data)
+{
+	switch (size) {
+		case I2C_SMBUS_QUICK:
+			sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+			size = SIS630_QUICK;
+			break;
+		case I2C_SMBUS_BYTE:
+			sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+			if (read_write == I2C_SMBUS_WRITE)
+				sis630_write(SMB_CMD, command);
+			size = SIS630_BYTE;
+			break;
+		case I2C_SMBUS_BYTE_DATA:
+			sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+			sis630_write(SMB_CMD, command);
+			if (read_write == I2C_SMBUS_WRITE)
+				sis630_write(SMB_BYTE, data->byte);
+			size = SIS630_BYTE_DATA;
+			break;
+		case I2C_SMBUS_PROC_CALL:
+		case I2C_SMBUS_WORD_DATA:
+			sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
+			sis630_write(SMB_CMD, command);
+			if (read_write == I2C_SMBUS_WRITE) {
+				sis630_write(SMB_BYTE, data->word & 0xff);
+				sis630_write(SMB_BYTE + 1,(data->word & 0xff00) >> 8);
+			}
+			size = (size == I2C_SMBUS_PROC_CALL ? SIS630_PCALL : SIS630_WORD_DATA);
+			break;
+		case I2C_SMBUS_BLOCK_DATA:
+			sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
+			sis630_write(SMB_CMD, command);
+			size = SIS630_BLOCK_DATA;
+			return sis630_block_data(adap, data, read_write);
+		default:
+			printk("Unsupported I2C size\n");
+			return -1;
+			break;
+	}
+
+	if (sis630_transaction(adap, size))
+		return -1;
+
+	if ((size != SIS630_PCALL) &&
+		((read_write == I2C_SMBUS_WRITE) || (size == SIS630_QUICK))) {
+		return 0;
+	}
+
+	switch(size) {
+		case SIS630_BYTE:
+		case SIS630_BYTE_DATA:
+			data->byte = sis630_read(SMB_BYTE);
+			break;
+		case SIS630_PCALL:
+		case SIS630_WORD_DATA:
+			data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8);
+			break;
+		default:
+			return -1;
+			break;
+	}
+
+	return 0;
+}
+
+static u32 sis630_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+		I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL |
+		I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static int sis630_setup(struct pci_dev *dummy)
+{
+	unsigned char b;
+	struct pci_dev *sis630_dev = NULL;
+	int retval = -ENODEV;
+
+	/* We need ISA bridge and not pci device passed in.  */
+	sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev);
+	if (!sis630_dev) {
+		dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n");
+		return -ENODEV;
+	}
+
+	/*
+	   Enable ACPI first , so we can accsess reg 74-75
+	   in acpi io space and read acpi base addr
+	*/
+	if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
+		dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
+		goto exit;
+	}
+
+	/* if ACPI already enabled , do nothing */
+	if (!(b & 0x80) &&
+	    !pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
+		dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
+		goto exit;
+	}
+	/* Determine the ACPI base address */
+	if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
+		dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
+		goto exit;
+	}
+
+	dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
+
+	/* Everything is happy, let's grab the memory and set things up. */
+	if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")) {
+		dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
+			"in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
+		goto exit;
+	}
+
+	retval = 0;
+
+exit:
+	pci_dev_put(sis630_dev);
+	return retval;
+}
+
+
+static struct i2c_algorithm smbus_algorithm = {
+	.name		= "Non-I2C SMBus adapter",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= sis630_access,
+	.functionality	= sis630_func,
+};
+
+static struct i2c_adapter sis630_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "unset",
+	.algo		= &smbus_algorithm,
+};
+
+static struct pci_device_id sis630_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) },
+	{ 0, }
+};
+
+static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+
+	if (sis630_setup(dev)) {
+		dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
+		return -ENODEV;
+	}
+
+	/* set up the driverfs linkage to our parent device */
+	sis630_adapter.dev.parent = &dev->dev;
+
+	sprintf(sis630_adapter.name, "SMBus SIS630 adapter at %04x",
+		acpi_base + SMB_STS);
+
+	return i2c_add_adapter(&sis630_adapter);
+}
+
+static void __devexit sis630_remove(struct pci_dev *dev)
+{
+	i2c_del_adapter(&sis630_adapter);
+}
+
+
+static struct pci_driver sis630_driver = {
+	.name		= "sis630 smbus",
+	.id_table	= sis630_ids,
+	.probe		= sis630_probe,
+	.remove		= __devexit_p(sis630_remove),
+};
+
+static int __init i2c_sis630_init(void)
+{
+	printk("i2c-sis630.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	return pci_module_init(&sis630_driver);
+}
+
+
+static void __exit i2c_sis630_exit(void)
+{
+	pci_unregister_driver(&sis630_driver);
+	release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
+}
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>");
+MODULE_DESCRIPTION("SIS630 SMBus driver");
+
+module_init(i2c_sis630_init);
+module_exit(i2c_sis630_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                           ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.7, 2003/09/15 16:53:41-07:00, mporter@kernel.crashing.org

[PATCH] I2C: New PPC4xx I2C driver

This updates the current 2.6 PPC 4xx driver to the rewritten version
we have in the PPC development tree.  It is cleaner, has less bugs,
and has more features.


 drivers/i2c/i2c-algo-ibm_ocp.c |  900 -----------------------------------------
 drivers/i2c/i2c-algo-ibm_ocp.h |   55 --
 drivers/i2c/Kconfig            |    8 
 drivers/i2c/Makefile           |    1 
 drivers/i2c/i2c-ibm_iic.c      |  729 +++++++++++++++++++++++++++++++++
 drivers/i2c/i2c-ibm_iic.h      |  124 +++++
 6 files changed, 856 insertions(+), 961 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:15:04 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:15:04 2003
@@ -203,13 +203,9 @@
 	tristate "Embedded Planet RPX Lite/Classic suppoort"
 	depends on (RPXLITE || RPXCLASSIC) && I2C_ALGO8XX
 
-config I2C_IBM_OCP_ALGO
-	tristate "IBM on-chip I2C Algorithm"
+config I2C_IBM_IIC
+	tristate "IBM IIC I2C"
 	depends on IBM_OCP && I2C
-
-config I2C_IBM_OCP_ADAP
-	tristate "IBM on-chip I2C Adapter"
-	depends on I2C_IBM_OCP_ALGO
 
 config I2C_IOP3XX
 	tristate "Intel XScale IOP3xx on-chip I2C interface"
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:15:04 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:15:04 2003
@@ -16,6 +16,7 @@
 obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
 obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
+obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
 obj-$(CONFIG_I2C_SENSOR)	+= i2c-sensor.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-y				+= busses/ chips/
diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.c b/drivers/i2c/i2c-algo-ibm_ocp.c
--- a/drivers/i2c/i2c-algo-ibm_ocp.c	Mon Sep 22 16:15:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,900 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-algo-ibm_ocp.c i2c driver algorithms for IBM PPC 405 adapters	    
-   -------------------------------------------------------------------------
-      
-   Ian DaSilva, MontaVista Software, Inc.
-   idasilva@mvista.com or source@mvista.com
-
-   Copyright 2000 MontaVista Software Inc.
-
-   Changes made to support the IIC peripheral on the IBM PPC 405
-
-
-   ---------------------------------------------------------------------------
-   This file was highly leveraged from i2c-algo-pcf.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
-
-     Copyright (C) 1995-1997 Simon G. Vogl
-                   1998-2000 Hans Berglund
-
-   With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and 
-   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
-   <mbailey@littlefeet-inc.com>
-
-
-    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.
-   ---------------------------------------------------------------------------
-
-   History: 01/20/12 - Armin
-   	akuster@mvista.com
-   	ported up to 2.4.16+	
-
-   Version 02/03/25 - Armin
-       converted to ocp format
-       removed commented out or #if 0 code
-       added Gérard Basler's fix to iic_combined_transaction() such that it 
-       returns the number of successfully completed transfers .
-*/
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ibm_ocp.h>
-#include <asm/ocp.h>
-
-
-/* ----- global defines ----------------------------------------------- */
-#define DEB(x) if (i2c_debug>=1) x
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEBPROTO(x) if (i2c_debug>=9) x;
- 	/* debug the protocol by showing transferred bits */
-#define DEF_TIMEOUT 5
-
-
-/* ----- global variables ---------------------------------------------	*/
-
-
-/* module parameters:
- */
-static int i2c_debug=0;
-
-/* --- setting states on the bus with the right timing: ---------------	*/
-
-#define iic_outb(adap, reg, val) adap->setiic(adap->data, (int) &(reg), val)
-#define iic_inb(adap, reg) adap->getiic(adap->data, (int) &(reg))
-
-#define IICO_I2C_SDAHIGH	0x0780
-#define IICO_I2C_SDALOW		0x0781
-#define IICO_I2C_SCLHIGH	0x0782
-#define IICO_I2C_SCLLOW		0x0783
-#define IICO_I2C_LINEREAD	0x0784
-
-#define IIC_SINGLE_XFER		0
-#define IIC_COMBINED_XFER	1
-
-#define IIC_ERR_LOST_ARB        -2
-#define IIC_ERR_INCOMPLETE_XFR  -3
-#define IIC_ERR_NACK            -1
-
-/* --- other auxiliary functions --------------------------------------	*/
-
-
-//
-// Description: Puts this process to sleep for a period equal to timeout 
-//
-static inline void iic_sleep(unsigned long timeout)
-{
-	schedule_timeout( timeout * HZ);
-}
-
-
-//
-// Description: This performs the IBM PPC 405 IIC initialization sequence
-// as described in the PPC405GP data book.
-//
-static int iic_init (struct i2c_algo_iic_data *adap)
-{
-	struct iic_regs *iic;	
-	struct iic_ibm *adap_priv_data = adap->data;
-	unsigned short	retval;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-        /* Clear master low master address */
-        iic_outb(adap,iic->lmadr, 0);
-
-        /* Clear high master address */
-        iic_outb(adap,iic->hmadr, 0);
-
-        /* Clear low slave address */
-        iic_outb(adap,iic->lsadr, 0);
-
-        /* Clear high slave address */
-        iic_outb(adap,iic->hsadr, 0);
-
-        /* Clear status */
-        iic_outb(adap,iic->sts, 0x0a);
-
-        /* Clear extended status */
-        iic_outb(adap,iic->extsts, 0x8f);
-
-        /* Set clock division */
-        iic_outb(adap,iic->clkdiv, 0x04);
-
-	retval = iic_inb(adap, iic->clkdiv);
-	DEB(printk("iic_init: CLKDIV register = %x\n", retval));
-
-        /* Enable interrupts on Requested Master Transfer Complete */
-        iic_outb(adap,iic->intmsk, 0x01);
-
-        /* Clear transfer count */
-        iic_outb(adap,iic->xfrcnt, 0x0);
-
-        /* Clear extended control and status */
-        iic_outb(adap,iic->xtcntlss, 0xf0);
-
-        /* Set mode control (flush master data buf, enable hold SCL, exit */
-        /* unknown state.                                                 */
-        iic_outb(adap,iic->mdcntl, 0x47);
-
-        /* Clear control register */
-        iic_outb(adap,iic->cntl, 0x0);
-
-        DEB2(printk(KERN_DEBUG "iic_init: Initialized IIC on PPC 405\n"));
-        return 0;
-}
-
-
-//
-// Description: After we issue a transaction on the IIC bus, this function
-// is called.  It puts this process to sleep until we get an interrupt from
-// from the controller telling us that the transaction we requested in complete.
-//
-static int wait_for_pin(struct i2c_algo_iic_data *adap, int *status) 
-{
-
-	int timeout = DEF_TIMEOUT;
-	int retval;
-	struct iic_regs *iic;
-	struct iic_ibm *adap_priv_data = adap->data;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-
-	*status = iic_inb(adap, iic->sts);
-#ifndef STUB_I2C
-
-	while (timeout-- && (*status & 0x01)) {
-	   adap->waitforpin(adap->data);
-	   *status = iic_inb(adap, iic->sts);
-	}
-#endif
-	if (timeout <= 0) {
-	   /* Issue stop signal on the bus, and force an interrupt */
-           retval = iic_inb(adap, iic->cntl);
-           iic_outb(adap, iic->cntl, retval | 0x80);
-           /* Clear status register */
-	   iic_outb(adap, iic->sts, 0x0a);
-	   /* Exit unknown bus state */
-	   retval = iic_inb(adap, iic->mdcntl);
-	   iic_outb(adap, iic->mdcntl, (retval | 0x02));
-
-	   // Check the status of the controller.  Does it still see a
-	   // pending transfer, even though we've tried to stop any
-	   // ongoing transaction?
-           retval = iic_inb(adap, iic->sts);
-           retval = retval & 0x01;
-           if(retval) {
-	      // The iic controller is hosed.  It is not responding to any
-	      // of our commands.  We have already tried to force it into
-	      // a known state, but it has not worked.  Our only choice now
-	      // is a soft reset, which will clear all registers, and force
-	      // us to re-initialize the controller.
-	      /* Soft reset */
-              iic_outb(adap, iic->xtcntlss, 0x01);
-              udelay(500);
-              iic_init(adap);
-	      /* Is the pending transfer bit in the sts reg finally cleared? */
-              retval = iic_inb(adap, iic->sts);
-              retval = retval & 0x01;
-              if(retval) {
-                 printk(KERN_CRIT "The IIC Controller is hosed.  A processor reset is required\n");
-              }
-	      // For some reason, even though the interrupt bit in this
-	      // register was set during iic_init, it didn't take.  We
-	      // need to set it again.  Don't ask me why....this is just what
-	      // I saw when testing timeouts.
-              iic_outb(adap, iic->intmsk, 0x01);
-           }
-	   return(-1);
-	}
-	else
-	   return(0);
-}
-
-
-//------------------------------------
-// Utility functions
-//
-
-
-//
-// Description: Look at the status register to see if there was an error
-// in the requested transaction.  If there is, look at the extended status
-// register and determine the exact cause.
-//
-int analyze_status(struct i2c_algo_iic_data *adap, int *error_code)
-{
-   int ret;
-   struct iic_regs *iic;
-   struct iic_ibm *adap_priv_data = adap->data;
-   iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	
-   ret = iic_inb(adap, iic->sts);
-   if(ret & 0x04) {
-      // Error occurred
-      ret = iic_inb(adap, iic->extsts);
-      if(ret & 0x04) {
-         // Lost arbitration
-         *error_code =  IIC_ERR_LOST_ARB;
-      }
-      if(ret & 0x02) {
-         // Incomplete transfer
-         *error_code = IIC_ERR_INCOMPLETE_XFR;
-      }
-      if(ret & 0x01) {
-         // Master transfer aborted by a NACK during the transfer of the 
-	 // address byte
-         *error_code = IIC_ERR_NACK;
-      }
-      return -1;
-   }
-   return 0;
-}
-
-
-//
-// Description: This function is called by the upper layers to do the
-// grunt work for a master send transaction
-//
-static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-                         int count, int xfer_flag)
-{
-	struct iic_regs *iic;
-	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	int wrcount, status, timeout;
-	int loops, remainder, i, j;
-	int ret, error_code;
-  	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
- 
-	if( count == 0 ) return 0;
-	wrcount = 0;
-	loops =  count / 4;
-	remainder = count % 4;
-
-	if((loops > 1) && (remainder == 0)) {
-	   for(i=0; i<(loops-1); i++) {
-       	      //
-   	      // Write four bytes to master data buffer
-	      //
-	      for(j=0; j<4; j++) {
-   	         iic_outb(adap, iic->mdbuf, 
-	         buf[wrcount++]);
-  	      }
-	      //
-	      // Issue command to IICO device to begin transmission
-	      //
-	      iic_outb(adap, iic->cntl, 0x35);
-	      //
-	      // Wait for transmission to complete.  When it does, 
-	      //loop to the top of the for statement and write the 
-	      // next four bytes.
-	      //
-	      timeout = wait_for_pin(adap, &status);
-	      if(timeout < 0) {
-	         //
-	         // Error handling
-	         //
-                 //printk(KERN_ERR "Error: write timeout\n");
-                 return wrcount;
-	      }
-	      ret = analyze_status(adap, &error_code);
-	      if(ret < 0) {
-                 if(error_code == IIC_ERR_INCOMPLETE_XFR) {
-                    // Return the number of bytes transferred
-                    ret = iic_inb(adap, iic->xfrcnt);
-                    ret = ret & 0x07;
-                    return (wrcount-4+ret);
-                 }
-                 else return error_code;
-              }
-           }
-	}
-	else if((loops >= 1) && (remainder > 0)){
-	   //printk(KERN_DEBUG "iic_sendbytes: (loops >= 1)\n");
-	   for(i=0; i<loops; i++) {
-              //
-              // Write four bytes to master data buffer
-              //
-              for(j=0; j<4; j++) {
-                 iic_outb(adap, iic->mdbuf,
-                 buf[wrcount++]);
-              }
-              //
-              // Issue command to IICO device to begin transmission
-              //
-              iic_outb(adap, iic->cntl, 0x35);
-              //
-              // Wait for transmission to complete.  When it does,
-              //loop to the top of the for statement and write the
-              // next four bytes.
-              //
-              timeout = wait_for_pin(adap, &status);
-              if(timeout < 0) {
-                 //
-                 // Error handling
-                 //
-                 //printk(KERN_ERR "Error: write timeout\n");
-                 return wrcount;
-              }
-              ret = analyze_status(adap, &error_code);
-              if(ret < 0) {
-                 if(error_code == IIC_ERR_INCOMPLETE_XFR) {
-                    // Return the number of bytes transferred
-                    ret = iic_inb(adap, iic->xfrcnt);
-                    ret = ret & 0x07;
-                    return (wrcount-4+ret);
-                 }
-                 else return error_code;
-              }
-           }
-        }
-
-	//printk(KERN_DEBUG "iic_sendbytes: expedite write\n");
-	if(remainder == 0) remainder = 4;
-	// remainder = remainder - 1;
-	//
-	// Write the remaining bytes (less than or equal to 4)
-	//
-	for(i=0; i<remainder; i++) {
-	   iic_outb(adap, iic->mdbuf, buf[wrcount++]);
-	   //printk(KERN_DEBUG "iic_sendbytes:  data transferred = %x, wrcount = %d\n", buf[wrcount-1], (wrcount-1));
-	}
-        //printk(KERN_DEBUG "iic_sendbytes: Issuing write\n");
-
-        if(xfer_flag == IIC_COMBINED_XFER) {
-           iic_outb(adap, iic->cntl, (0x09 | ((remainder-1) << 4)));
-        }
-	else {
-           iic_outb(adap, iic->cntl, (0x01 | ((remainder-1) << 4)));
-        }
-	DEB2(printk(KERN_DEBUG "iic_sendbytes: Waiting for interrupt\n"));
-	timeout = wait_for_pin(adap, &status);
-        if(timeout < 0) {
-       	   //
-           // Error handling
-           //
-           //printk(KERN_ERR "Error: write timeout\n");
-           return wrcount;
-        }
-        ret = analyze_status(adap, &error_code);
-        if(ret < 0) {
-           if(error_code == IIC_ERR_INCOMPLETE_XFR) {
-              // Return the number of bytes transferred
-              ret = iic_inb(adap, iic->xfrcnt);
-              ret = ret & 0x07;
-              return (wrcount-4+ret);
-           }
-           else return error_code;
-        }
-	DEB2(printk(KERN_DEBUG "iic_sendbytes: Got interrupt\n"));
-	return wrcount;
-}
-
-
-//
-// Description: Called by the upper layers to do the grunt work for
-// a master read transaction.
-//
-static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count, int xfer_type)
-{
-	struct iic_regs *iic;
-	int rdcount=0, i, status, timeout;
-	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	int loops, remainder, j;
-        int ret, error_code;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	if(count == 0) return 0;
-	loops = count / 4;
-	remainder = count % 4;
-
-	//printk(KERN_DEBUG "iic_readbytes: loops = %d, remainder = %d\n", loops, remainder);
-
-	if((loops > 1) && (remainder == 0)) {
-	//printk(KERN_DEBUG "iic_readbytes: (loops > 1) && (remainder == 0)\n");
-	   for(i=0; i<(loops-1); i++) {
-	      //
-              // Issue command to begin master read (4 bytes maximum)
-              //
-	      //printk(KERN_DEBUG "--->Issued read command\n");
-	      iic_outb(adap, iic->cntl, 0x37);
-	      //
-              // Wait for transmission to complete.  When it does,
-              // loop to the top of the for statement and write the
-              // next four bytes.
-              //
-	      //printk(KERN_DEBUG "--->Waiting for interrupt\n");
-              timeout = wait_for_pin(adap, &status);
-              if(timeout < 0) {
-	         // Error Handler
-		 //printk(KERN_ERR "Error: read timed out\n");
-                 return rdcount;
-	      }
-              //printk(KERN_DEBUG "--->Got interrupt\n");
-
-              ret = analyze_status(adap, &error_code);
-	      if(ret < 0) {
-                 if(error_code == IIC_ERR_INCOMPLETE_XFR)
-                    return rdcount;
-                 else
-                    return error_code;
-              }
-
-	      for(j=0; j<4; j++) {
-                 // Wait for data to shuffle to top of data buffer
-                 // This value needs to optimized.
-		 udelay(1);
-	         buf[rdcount] = iic_inb(adap, iic->mdbuf);
-	         rdcount++;
-		 //printk(KERN_DEBUG "--->Read one byte\n");
-              }
-           }
-	}
-
-	else if((loops >= 1) && (remainder > 0)){
-	//printk(KERN_DEBUG "iic_readbytes: (loops >=1) && (remainder > 0)\n");
-	   for(i=0; i<loops; i++) {
-              //
-              // Issue command to begin master read (4 bytes maximum)
-              //
-              //printk(KERN_DEBUG "--->Issued read command\n");
-              iic_outb(adap, iic->cntl, 0x37);
-              //
-              // Wait for transmission to complete.  When it does,
-              // loop to the top of the for statement and write the
-              // next four bytes.
-              //
-              //printk(KERN_DEBUG "--->Waiting for interrupt\n");
-              timeout = wait_for_pin(adap, &status);
-              if(timeout < 0) {
-                 // Error Handler
-                 //printk(KERN_ERR "Error: read timed out\n");
-                 return rdcount;
-              }
-              //printk(KERN_DEBUG "--->Got interrupt\n");
-
-              ret = analyze_status(adap, &error_code);
-              if(ret < 0) {
-                 if(error_code == IIC_ERR_INCOMPLETE_XFR)
-                    return rdcount;
-                 else
-                    return error_code;
-              }
-
-              for(j=0; j<4; j++) {
-                 // Wait for data to shuffle to top of data buffer
-                 // This value needs to optimized.
-                 udelay(1);
-                 buf[rdcount] = iic_inb(adap, iic->mdbuf);
-                 rdcount++;
-                 //printk(KERN_DEBUG "--->Read one byte\n");
-              }
-           }
-        }
-
-	//printk(KERN_DEBUG "iic_readbytes: expedite read\n");
-	if(remainder == 0) remainder = 4;
-	DEB2(printk(KERN_DEBUG "iic_readbytes: writing %x to IICO_CNTL\n", (0x03 | ((remainder-1) << 4))));
-
-	if(xfer_type == IIC_COMBINED_XFER) {
-	   iic_outb(adap, iic->cntl, (0x0b | ((remainder-1) << 4)));
-        }
-        else {
-	   iic_outb(adap, iic->cntl, (0x03 | ((remainder-1) << 4)));
-        }
-	DEB2(printk(KERN_DEBUG "iic_readbytes: Wait for pin\n"));
-        timeout = wait_for_pin(adap, &status);
-	DEB2(printk(KERN_DEBUG "iic_readbytes: Got the interrupt\n"));
-        if(timeout < 0) {
-           // Error Handler
-	   //printk(KERN_ERR "Error: read timed out\n");
-           return rdcount;
-        }
-
-        ret = analyze_status(adap, &error_code);
-        if(ret < 0) {
-           if(error_code == IIC_ERR_INCOMPLETE_XFR)
-              return rdcount;
-           else
-              return error_code;
-        }
-
-	//printk(KERN_DEBUG "iic_readbyte: Begin reading data buffer\n");
-	for(i=0; i<remainder; i++) {
-	   buf[rdcount] = iic_inb(adap, iic->mdbuf);
-	   // printk(KERN_DEBUG "iic_readbytes:  Character read = %x\n", buf[rdcount]);
-           rdcount++;
-	}
-
-	return rdcount;
-}
-
-
-//
-// Description:  This function implements combined transactions.  Combined
-// transactions consist of combinations of reading and writing blocks of data.
-// Each transfer (i.e. a read or a write) is separated by a repeated start
-// condition.
-//
-static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) 
-{
-   int i;
-   struct i2c_msg *pmsg;
-   int ret;
-
-   DEB2(printk(KERN_DEBUG "Beginning combined transaction\n"));
-	for(i=0; i < num; i++) {
-		pmsg = &msgs[i];
-		if(pmsg->flags & I2C_M_RD) {
-
-			// Last read or write segment needs to be terminated with a stop
-			if(i < num-1) {
-				DEB2(printk(KERN_DEBUG "This one is a read\n"));
-			}
-			else {
-				DEB2(printk(KERN_DEBUG "Doing the last read\n"));
-			}
-			ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER);
-
-			if (ret != pmsg->len) {
-				DEB2(printk("i2c-algo-ppc405.o: fail: "
-							"only read %d bytes.\n",ret));
-				return i;
-			}
-			else {
-				DEB2(printk("i2c-algo-ppc405.o: read %d bytes.\n",ret));
-			}
-		}
-		else if(!(pmsg->flags & I2C_M_RD)) {
-
-			// Last read or write segment needs to be terminated with a stop
-			if(i < num-1) {
-				DEB2(printk(KERN_DEBUG "This one is a write\n"));
-			}
-			else {
-				DEB2(printk(KERN_DEBUG "Doing the last write\n"));
-			}
-			ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER);
-
-			if (ret != pmsg->len) {
-				DEB2(printk("i2c-algo-ppc405.o: fail: "
-							"only wrote %d bytes.\n",ret));
-				return i;
-			}
-			else {
-				DEB2(printk("i2c-algo-ppc405.o: wrote %d bytes.\n",ret));
-			}
-		}
-	}
- 
-	return num;
-}
-
-
-//
-// Description: Whenever we initiate a transaction, the first byte clocked
-// onto the bus after the start condition is the address (7 bit) of the
-// device we want to talk to.  This function manipulates the address specified
-// so that it makes sense to the hardware when written to the IIC peripheral.
-//
-// Note: 10 bit addresses are not supported in this driver, although they are
-// supported by the hardware.  This functionality needs to be implemented.
-//
-static inline int iic_doAddress(struct i2c_algo_iic_data *adap,
-                                struct i2c_msg *msg, int retries) 
-{
-	struct iic_regs *iic;
-	unsigned short flags = msg->flags;
-	unsigned char addr;
-	struct iic_ibm *adap_priv_data = adap->data;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-//
-// The following segment for 10 bit addresses needs to be ported
-//
-/* Ten bit addresses not supported right now
-	if ( (flags & I2C_M_TEN)  ) { 
-		// a ten bit address
-		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-		DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
-		// try extended address code...
-		ret = try_address(adap, addr, retries);
-		if (ret!=1) {
-			printk(KERN_ERR "iic_doAddress: died at extended address code.\n");
-			return -EREMOTEIO;
-		}
-		// the remaining 8 bit address
-		iic_outb(adap,msg->addr & 0x7f);
-		// Status check comes here
-		if (ret != 1) {
-			printk(KERN_ERR "iic_doAddress: died at 2nd address code.\n");
-			return -EREMOTEIO;
-		}
-		if ( flags & I2C_M_RD ) {
-			i2c_repstart(adap);
-			// okay, now switch into reading mode
-			addr |= 0x01;
-			ret = try_address(adap, addr, retries);
-			if (ret!=1) {
-				printk(KERN_ERR "iic_doAddress: died at extended address code.\n");
-				return -EREMOTEIO;
-			}
-		}
-	} else ----------> // normal 7 bit address
-
-Ten bit addresses not supported yet */
-
-	addr = ( msg->addr << 1 );
-	if (flags & I2C_M_RD )
-		addr |= 1;
-	if (flags & I2C_M_REV_DIR_ADDR )
-		addr ^= 1;
-	//
-	// Write to the low slave address
-	//
-	iic_outb(adap, iic->lmadr, addr);
-	//
-	// Write zero to the high slave register since we are
-	// only using 7 bit addresses
-	//
-	iic_outb(adap, iic->hmadr, 0);
-
-	return 0;
-}
-
-
-//
-// Description: Prepares the controller for a transaction (clearing status
-// registers, data buffers, etc), and then calls either iic_readbytes or
-// iic_sendbytes to do the actual transaction.
-//
-static int iic_xfer(struct i2c_adapter *i2c_adap,
-		    struct i2c_msg msgs[], 
-		    int num)
-{
-	struct iic_regs *iic;
-	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	struct i2c_msg *pmsg;
-	int i = 0;
-	int ret;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	pmsg = &msgs[i];
-
-	//
-	// Clear status register
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: iic_xfer: Clearing status register\n"));
-	iic_outb(adap, iic->sts, 0x0a);
-
-	//
-	// Wait for any pending transfers to complete
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: Waiting for any pending transfers to complete\n"));
-	while((ret = iic_inb(adap, iic->sts)) == 0x01) {
-		;
-	}
-
-	//
-	// Flush master data buf
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: Clearing master data buffer\n"));		
-	ret = iic_inb(adap, iic->mdcntl);
-	iic_outb(adap, iic->mdcntl, ret | 0x40);
-
-	//
-	// Load slave address
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: Loading slave address\n"));
-	ret = iic_doAddress(adap, pmsg, i2c_adap->retries);
-
-        //
-        // Check to see if the bus is busy
-        //
-        ret = iic_inb(adap, iic->extsts);
-        // Mask off the irrelevent bits
-        ret = ret & 0x70;
-        // When the bus is free, the BCS bits in the EXTSTS register are 0b100
-        if(ret != 0x40) return IIC_ERR_LOST_ARB;
-
-	//
-	// Combined transaction (read and write)
-	//
-	if(num > 1) {
-           DEB2(printk(KERN_DEBUG "iic_xfer: Call combined transaction\n"));
-           ret = iic_combined_transaction(i2c_adap, msgs, num);
-        }
-	//
-	// Read only
-	//
-	else if((num == 1) && (pmsg->flags & I2C_M_RD)) {
-	   //
-	   // Tell device to begin reading data from the  master data 
-	   //
-	   DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's read\n"));
-	   ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-	} 
-        //
-	// Write only
-	//
-	else if((num == 1 ) && (!(pmsg->flags & I2C_M_RD))) {
-	   //
-	   // Write data to master data buffers and tell our device
-	   // to begin transmitting
-	   //
-	   DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's write\n"));
-	   ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-	}	
-
-	return ret;   
-}
-
-
-//
-// Description: Implements device specific ioctls.  Higher level ioctls can
-// be found in i2c-core.c and are typical of any i2c controller (specifying
-// slave address, timeouts, etc).  These ioctls take advantage of any hardware
-// features built into the controller for which this algorithm-adapter set
-// was written.  These ioctls allow you to take control of the data and clock
-// lines on the IBM PPC 405 IIC controller and set the either high or low,
-// similar to a GPIO pin.
-//
-static int algo_control(struct i2c_adapter *adapter, 
-	unsigned int cmd, unsigned long arg)
-{
-	struct iic_regs *iic;
-	struct i2c_algo_iic_data *adap = adapter->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	int ret=0;
-	int lines;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	lines = iic_inb(adap, iic->directcntl);
-
-	if (cmd == IICO_I2C_SDAHIGH) {
-	      lines = lines & 0x01;
-	      if( lines ) lines = 0x04;
-	      else lines = 0;
-	      iic_outb(adap, iic->directcntl,(0x08|lines));
-	}
-	else if (cmd == IICO_I2C_SDALOW) {
-	      lines = lines & 0x01;
-	      if( lines ) lines = 0x04;
-              else lines = 0;
-              iic_outb(adap, iic->directcntl,(0x00|lines));
-	}
-	else if (cmd == IICO_I2C_SCLHIGH) {
-              lines = lines & 0x02;
-              if( lines ) lines = 0x08;
-              else lines = 0;
-              iic_outb(adap, iic->directcntl,(0x04|lines));
-	}
-	else if (cmd == IICO_I2C_SCLLOW) {
-              lines = lines & 0x02;
-	      if( lines ) lines = 0x08;
-              else lines = 0;
-              iic_outb(adap, iic->directcntl,(0x00|lines));
-	}
-	else if (cmd == IICO_I2C_LINEREAD) {
-	      ret = lines;
-	}
-	return ret;
-}
-
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
-	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-	       I2C_FUNC_PROTOCOL_MANGLING; 
-}
-
-
-/* -----exported algorithm data: -------------------------------------	*/
-
-static struct i2c_algorithm iic_algo = {
-	.name		= "IBM on-chip IIC algorithm",
-	.id		= I2C_ALGO_OCP,
-	.master_xfer	= iic_xfer,
-	.algo_control	= algo_control,
-	.functionality	= iic_func,
-};
-
-/* 
- * registering functions to load algorithms at runtime 
- */
-
-
-//
-// Description: Register bus structure
-//
-int i2c_ocp_add_bus(struct i2c_adapter *adap)
-{
-	struct i2c_algo_iic_data *iic_adap = adap->algo_data;
-
-	DEB2(printk(KERN_DEBUG "i2c-algo-iic.o: hw routines for %s registered.\n",
-	            adap->name));
-
-	/* register new adapter to i2c module... */
-
-	adap->id |= iic_algo.id;
-	adap->algo = &iic_algo;
-
-	adap->timeout = 100;	/* default values, should	*/
-	adap->retries = 3;		/* be replaced by defines	*/
-
-	iic_init(iic_adap);
-	i2c_add_adapter(adap);
-	return 0;
-}
-
-
-//
-// Done
-//
-int i2c_ocp_del_bus(struct i2c_adapter *adap)
-{
-	return i2c_del_adapter(adap);
-}
-
-
-EXPORT_SYMBOL(i2c_ocp_add_bus);
-EXPORT_SYMBOL(i2c_ocp_del_bus);
-
-//
-// The MODULE_* macros resolve to nothing if MODULES is not defined
-// when this file is compiled.
-//
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("PPC 405 iic algorithm");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(i2c_debug,"i");
-
-MODULE_PARM_DESC(i2c_debug,
-        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
-
diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.h b/drivers/i2c/i2c-algo-ibm_ocp.h
--- a/drivers/i2c/i2c-algo-ibm_ocp.h	Mon Sep 22 16:15:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,55 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-ibm_ocp.h i2c driver algorithms for IBM PPC 405 IIC adapters         */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    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.                */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* Modifications by MontaVista Software, August 2000
-   Changes made to support the IIC peripheral on the IBM PPC 405 */
-
-#ifndef I2C_ALGO_IIC_H
-#define I2C_ALGO_IIC_H 1
-
-/* --- Defines for pcf-adapters ---------------------------------------	*/
-#include <linux/i2c.h>
-
-struct i2c_algo_iic_data {
-	struct iic_regs *data;		/* private data for lolevel routines	*/
-	void (*setiic) (void *data, int ctl, int val);
-	int  (*getiic) (void *data, int ctl);
-	int  (*getown) (void *data);
-	int  (*getclock) (void *data);
-	void (*waitforpin) (void *data);     
-
-	/* local settings */
-	int udelay;
-	int mdelay;
-	int timeout;
-};
-
-
-#define I2C_IIC_ADAP_MAX	16
-
-
-int i2c_ocp_add_bus(struct i2c_adapter *);
-int i2c_ocp_del_bus(struct i2c_adapter *);
-
-#endif /* I2C_ALGO_IIC_H */
diff -Nru a/drivers/i2c/i2c-ibm_iic.c b/drivers/i2c/i2c-ibm_iic.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/i2c-ibm_iic.c	Mon Sep 22 16:15:04 2003
@@ -0,0 +1,729 @@
+/*
+ * drivers/i2c/i2c-ibm_iic.c
+ *
+ * Support for the IIC peripheral on IBM PPC 4xx
+ *
+ * Copyright (c) 2003 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by 
+ * 	Ian DaSilva  <idasilva@mvista.com>
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Matt Porter  <mporter@mvista.com>
+ *
+ *      Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * Original driver version was highly leveraged from i2c-elektor.c
+ *
+ *   	Copyright 1995-97 Simon G. Vogl
+ *                1998-99 Hans Berglund
+ *
+ *   	With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> 
+ *	and even Frodo Looijaard <frodol@dds.nl>
+ *
+ * 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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <asm/ocp.h>
+#include <asm/ibm4xx.h>
+
+#include "i2c-ibm_iic.h"
+
+#define DRIVER_VERSION "2.0"
+
+MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+static int iic_scan = 0;
+MODULE_PARM(iic_scan, "i");
+MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus");
+
+static int iic_force_poll = 0;
+MODULE_PARM(iic_force_poll, "i");
+MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
+
+static int iic_force_fast = 0;
+MODULE_PARM(iic_force_fast, "i");
+MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)");
+
+#define DBG_LEVEL 0
+
+#ifdef DBG
+#undef DBG
+#endif
+
+#ifdef DBG2
+#undef DBG2
+#endif
+
+#if DBG_LEVEL > 0
+#  define DBG(x...)	printk(KERN_DEBUG "ibm-iic" ##x)
+#else
+#  define DBG(x...)	((void)0)
+#endif
+#if DBG_LEVEL > 1
+#  define DBG2(x...) 	DBG( ##x )
+#else
+#  define DBG2(x...) 	((void)0)
+#endif
+#if DBG_LEVEL > 2
+static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header);
+	printk(KERN_DEBUG "  cntl     = 0x%02x, mdcntl = 0x%02x\n"
+	       KERN_DEBUG "  sts      = 0x%02x, extsts = 0x%02x\n"
+	       KERN_DEBUG "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n"
+	       KERN_DEBUG "  xtcntlss = 0x%02x, directcntl = 0x%02x\n",
+		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), 
+		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), 
+		in_8(&iic->xtcntlss), in_8(&iic->directcntl));
+}
+#  define DUMP_REGS(h,dev)	dump_iic_regs((h),(dev))
+#else
+#  define DUMP_REGS(h,dev)	((void)0)
+#endif
+
+/* Enable/disable interrupt generation */
+static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable)
+{
+	out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);
+}
+ 
+/*
+ * Initialize IIC interface.
+ */
+static void iic_dev_init(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+
+	DBG("%d: init\n", dev->idx);
+	
+	/* Clear master address */
+	out_8(&iic->lmadr, 0);
+	out_8(&iic->hmadr, 0);
+
+	/* Clear slave address */
+	out_8(&iic->lsadr, 0);
+	out_8(&iic->hsadr, 0);
+
+	/* Clear status & extended status */
+	out_8(&iic->sts, STS_SCMP | STS_IRQA);
+	out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA
+			    | EXTSTS_ICT | EXTSTS_XFRA);
+
+	/* Set clock divider */
+	out_8(&iic->clkdiv, dev->clckdiv);
+
+	/* Clear transfer count */
+	out_8(&iic->xfrcnt, 0);
+
+	/* Clear extended control and status */
+	out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC
+			    | XTCNTLSS_SWS);
+
+	/* Clear control register */
+	out_8(&iic->cntl, 0);
+	
+	/* Enable interrupts if possible */
+	iic_interrupt_mode(dev, dev->irq >= 0);
+
+	/* Set mode control */
+	out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS
+			    | (dev->fast_mode ? MDCNTL_FSM : 0));
+
+	DUMP_REGS("iic_init", dev);
+}
+
+/* 
+ * Reset IIC interface
+ */
+static void iic_dev_reset(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	int i;
+	u8 dc;
+	
+	DBG("%d: soft reset\n", dev->idx);
+	DUMP_REGS("reset", dev);
+	
+    	/* Place chip in the reset state */
+	out_8(&iic->xtcntlss, XTCNTLSS_SRST);
+	
+	/* Check if bus is free */
+	dc = in_8(&iic->directcntl);	
+	if (!DIRCTNL_FREE(dc)){
+		DBG("%d: trying to regain bus control\n", dev->idx);
+	
+		/* Try to set bus free state */
+		out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);	
+	
+		/* Wait until we regain bus control */
+		for (i = 0; i < 100; ++i){
+			dc = in_8(&iic->directcntl);
+			if (DIRCTNL_FREE(dc))
+				break;
+			
+			/* Toggle SCL line */
+			dc ^= DIRCNTL_SCC;
+			out_8(&iic->directcntl, dc);
+			udelay(10);
+			dc ^= DIRCNTL_SCC;
+			out_8(&iic->directcntl, dc);
+			
+			/* be nice */
+			cond_resched();
+		}
+	}
+	
+	/* Remove reset */
+	out_8(&iic->xtcntlss, 0);
+	
+	/* Reinitialize interface */
+	iic_dev_init(dev);
+}
+
+/*
+ * IIC interrupt handler
+ */
+static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
+	volatile struct iic_regs* iic = dev->vaddr;
+	
+	DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", 
+	     dev->idx, in_8(&iic->sts), in_8(&iic->extsts));
+	
+	/* Acknowledge IRQ and wakeup iic_wait_for_tc */
+	out_8(&iic->sts, STS_IRQA | STS_SCMP);
+	wake_up_interruptible(&dev->wq);
+	
+	return IRQ_HANDLED;
+}
+
+/*
+ * Get master transfer result and clear errors if any.
+ * Returns the number of actually transferred bytes or error (<0)
+ */
+static int iic_xfer_result(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;	
+	
+	if (unlikely(in_8(&iic->sts) & STS_ERR)){
+		DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, 
+			in_8(&iic->extsts));
+				
+		/* Clear errors and possible pending IRQs */
+		out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | 
+			EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
+			
+		/* Flush master data buffer */
+		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+		
+		/* Is bus free?
+		 * If error happened during combined xfer
+		 * IIC interface is usually stuck in some strange
+		 * state, the only way out - soft reset.
+		 */
+		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+			DBG("%d: bus is stuck, resetting\n", dev->idx);
+			iic_dev_reset(dev);
+		}
+		return -EREMOTEIO;
+	}
+	else
+		return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK;
+}
+
+/*
+ * Try to abort active transfer.
+ */
+static void iic_abort_xfer(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	unsigned long x;
+	
+	DBG("%d: iic_abort_xfer\n", dev->idx);
+	
+	out_8(&iic->cntl, CNTL_HMT);
+	
+	/*
+	 * Wait for the abort command to complete.
+	 * It's not worth to be optimized, just poll (timeout >= 1 tick)
+	 */
+	x = jiffies + 2;
+	while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+		if (time_after(jiffies, x)){
+			DBG("%d: abort timeout, resetting...\n", dev->idx);
+			iic_dev_reset(dev);
+			return;
+		}
+		schedule();
+	}
+
+	/* Just to clear errors */
+	iic_xfer_result(dev);
+}
+
+/*
+ * Wait for master transfer to complete.
+ * It puts current process to sleep until we get interrupt or timeout expires.
+ * Returns the number of transferred bytes or error (<0)
+ */
+static int iic_wait_for_tc(struct ibm_iic_private* dev){
+	
+	volatile struct iic_regs *iic = dev->vaddr;
+	int ret = 0;
+	
+	if (dev->irq >= 0){
+		/* Interrupt mode */
+		wait_queue_t wait;
+    		init_waitqueue_entry(&wait, current);
+		
+		add_wait_queue(&dev->wq, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (in_8(&iic->sts) & STS_PT)
+			schedule_timeout(dev->adap.timeout * HZ);
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&dev->wq, &wait);
+		
+		if (unlikely(signal_pending(current))){
+			DBG("%d: wait interrupted\n", dev->idx);
+			ret = -ERESTARTSYS;
+		} else if (unlikely(in_8(&iic->sts) & STS_PT)){
+			DBG("%d: wait timeout\n", dev->idx);
+			ret = -ETIMEDOUT;
+		}
+	}
+	else {
+		/* Polling mode */
+		unsigned long x = jiffies + dev->adap.timeout * HZ;
+		
+		while (in_8(&iic->sts) & STS_PT){
+			if (unlikely(time_after(jiffies, x))){
+				DBG("%d: poll timeout\n", dev->idx);
+				ret = -ETIMEDOUT;
+				break;
+			}
+		
+			if (unlikely(signal_pending(current))){
+				DBG("%d: poll interrupted\n", dev->idx);
+				ret = -ERESTARTSYS;
+				break;
+			}
+			schedule();
+		}	
+	}
+	
+	if (unlikely(ret < 0))
+		iic_abort_xfer(dev);
+	else
+		ret = iic_xfer_result(dev);
+	
+	DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);
+	
+	return ret;
+}
+
+/*
+ * Low level master transfer routine
+ */
+static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, 
+			  int combined_xfer)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	char* buf = pm->buf;
+	int i, j, loops, ret = 0;
+	int len = pm->len;
+
+	u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;
+	if (pm->flags & I2C_M_RD)
+		cntl |= CNTL_RW;
+	
+	loops = (len + 3) / 4;
+	for (i = 0; i < loops; ++i, len -= 4){
+		int count = len > 4 ? 4 : len;
+		u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);
+		
+		if (!(cntl & CNTL_RW))
+			for (j = 0; j < count; ++j)
+				out_8((volatile u8*)&iic->mdbuf, *buf++);
+		
+		if (i < loops - 1)
+			cmd |= CNTL_CHT;
+		else if (combined_xfer)
+			cmd |= CNTL_RPST;
+		
+		DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);
+		
+		/* Start transfer */
+		out_8(&iic->cntl, cmd);
+		
+		/* Wait for completion */
+		ret = iic_wait_for_tc(dev);
+
+		if (unlikely(ret < 0))
+			break;
+		else if (unlikely(ret != count)){
+			DBG("%d: xfer_bytes, requested %d, transfered %d\n", 
+				dev->idx, count, ret);
+			
+			/* If it's not a last part of xfer, abort it */
+			if (combined_xfer || (i < loops - 1))
+    				iic_abort_xfer(dev);
+				
+			ret = -EREMOTEIO;
+			break;				
+		}
+		
+		if (cntl & CNTL_RW)
+			for (j = 0; j < count; ++j)
+				*buf++ = in_8((volatile u8*)&iic->mdbuf);
+	}
+	
+	return ret > 0 ? 0 : ret;
+}
+
+/*
+ * Set target slave address for master transfer
+ */
+static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	u16 addr = msg->addr;
+	
+	DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, 
+		addr, msg->flags & I2C_M_TEN ? 10 : 7);
+	
+	if (msg->flags & I2C_M_TEN){
+	    out_8(&iic->cntl, CNTL_AMD);
+	    out_8(&iic->lmadr, addr);
+	    out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06));
+	}
+	else {
+	    out_8(&iic->cntl, 0);
+	    out_8(&iic->lmadr, addr << 1);
+	}
+}
+
+static inline int iic_invalid_address(const struct i2c_msg* p)
+{
+	return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));
+}
+
+static inline int iic_address_neq(const struct i2c_msg* p1, 
+				  const struct i2c_msg* p2)
+{
+	return (p1->addr != p2->addr) 
+		|| ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));
+} 
+
+/*
+ * Generic master transfer entrypoint. 
+ * Returns the number of processed messages or error (<0)
+ */
+static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+    	struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));
+	volatile struct iic_regs *iic = dev->vaddr;
+	int i, ret = 0;
+	
+	DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
+	
+	if (!num)
+		return 0;
+	
+	/* Check the sanity of the passed messages.
+	 * Uhh, generic i2c layer is more suitable place for such code...
+	 */
+	if (unlikely(iic_invalid_address(&msgs[0]))){
+		DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, 
+			msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);
+		return -EINVAL;
+	}		
+	for (i = 0; i < num; ++i){
+		if (unlikely(msgs[i].len <= 0)){
+			DBG("%d: invalid len %d in msg[%d]\n", dev->idx, 
+				msgs[i].len, i);
+			return -EINVAL;
+		}
+		if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){
+			DBG("%d: invalid addr in msg[%d]\n", dev->idx, i);
+			return -EINVAL;
+		}
+	}
+	
+	/* Check bus state */
+	if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){
+		DBG("%d: iic_xfer, bus is not free\n", dev->idx);
+		
+		/* Usually it means something serious has happend.
+		 * We *cannot* have unfinished previous transfer
+		 * so it doesn't make any sense to try to stop it.
+		 * Probably we were not able to recover from the 
+		 * previous error.
+		 * The only *reasonable* thing I can think of here
+		 * is soft reset.  --ebs
+		 */
+		iic_dev_reset(dev);
+		
+		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+			DBG("%d: iic_xfer, bus is still not free\n", dev->idx);
+			return -EREMOTEIO;
+		}
+	} 
+	else {
+		/* Flush master data buffer (just in case) */
+		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+	}
+	
+	/* Load slave address */
+	iic_address(dev, &msgs[0]);
+	
+	/* Do real transfer */
+    	for (i = 0; i < num && !ret; ++i)
+		ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);
+
+	return ret < 0 ? ret : num;
+}
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+}
+
+static struct i2c_algorithm iic_algo = {
+	.name 		= "IBM IIC algorithm",
+	.id   		= I2C_ALGO_OCP,
+	.master_xfer 	= iic_xfer,
+	.smbus_xfer	= NULL,
+	.slave_send	= NULL,
+	.slave_recv	= NULL,
+	.algo_control	= NULL,
+	.functionality	= iic_func
+};
+
+/*
+ * Scan bus for valid 7-bit addresses (ie things that ACK on 1 byte read)
+ * We only scan range [0x08 - 0x77], all other addresses are reserved anyway
+ */
+static void __devinit iic_scan_bus(struct ibm_iic_private* dev)
+{
+	int found = 0;
+	char dummy;
+	struct i2c_msg msg = {
+		.buf   = &dummy,
+		.len   = sizeof(dummy),
+		.flags = I2C_M_RD
+	};
+	
+	printk(KERN_INFO "ibm-iic%d: scanning bus...\n" KERN_INFO, dev->idx);
+	
+	for (msg.addr = 8; msg.addr < 0x78; ++msg.addr)
+		if (iic_xfer(&dev->adap, &msg, 1) == 1){
+			++found;
+			printk(" 0x%02x", msg.addr);
+		}
+
+	printk("%sibm-iic%d: %d device(s) detected\n", 
+		found ? "\n" KERN_INFO : "", dev->idx, found);
+}
+
+/*
+ * Calculates IICx_CLCKDIV value for a specific OPB clock frequency
+ */
+static inline u8 iic_clckdiv(unsigned int opb)
+{
+	/* Compatibility kludge, should go away after all cards
+	 * are fixed to fill correct value for opbfreq.
+	 * Previous driver version used hardcoded divider value 4,
+	 * it corresponds to OPB frequency from the range (40, 50] MHz
+	 */
+	if (!opb){
+		printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq,"
+			" fix your board specific setup\n");
+		opb = 50000000;
+	}
+
+	/* Convert to MHz */
+	opb /= 1000000;
+	
+	if (opb < 20 || opb > 150){
+		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
+			opb);
+		opb = opb < 20 ? 20 : 150;
+	}
+	return (u8)((opb + 9) / 10 - 1);
+}
+
+/*
+ * Register single IIC interface
+ */
+static int __devinit iic_probe(struct ocp_device *ocp){
+
+	struct ibm_iic_private* dev;
+	struct i2c_adapter* adap;
+	int ret;
+	bd_t* bd = (bd_t*)&__res;
+	
+	if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){
+		printk(KERN_CRIT "ibm-iic: failed to allocate device data\n");
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->idx = ocp->num;
+	ocp_set_drvdata(ocp, dev);
+	
+	if (!(dev->vaddr = ioremap(ocp->paddr, sizeof(struct iic_regs)))){
+		printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
+			dev->idx);
+		ret = -ENXIO;
+		goto fail2;
+	}
+	
+	init_waitqueue_head(&dev->wq);
+
+	dev->irq = iic_force_poll ? -1 : ocp->irq;
+	if (dev->irq >= 0){
+		/* Disable interrupts until we finish intialization,
+		   assumes level-sensitive IRQ setup...
+		 */
+		iic_interrupt_mode(dev, 0);
+		if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){
+			printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", 
+				dev->idx, dev->irq);
+			/* Fallback to the polling mode */	
+			dev->irq = -1;
+		}
+	}
+	
+	if (dev->irq < 0)
+		printk(KERN_WARNING "ibm-iic%d: using polling mode\n", 
+			dev->idx);
+		
+	/* Board specific settings */
+	BUG_ON(dev->idx >= sizeof(bd->bi_iic_fast) / sizeof(bd->bi_iic_fast[0]));
+	dev->fast_mode = iic_force_fast ? 1 : bd->bi_iic_fast[dev->idx];
+	
+	/* clckdiv is the same for *all* IIC interfaces, 
+	 * but I'd rather make a copy than introduce another global. --ebs
+	 */
+	dev->clckdiv = iic_clckdiv(bd->bi_opb_busfreq);
+	DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);
+	
+	/* Initialize IIC interface */
+	iic_dev_init(dev);
+	
+	/* Register it with i2c layer */
+	adap = &dev->adap;
+	strcpy(adap->dev.name, "IBM IIC");
+	i2c_set_adapdata(adap, dev);
+	adap->id = I2C_HW_OCP | iic_algo.id;
+	adap->algo = &iic_algo;
+	adap->client_register = NULL;
+	adap->client_unregister = NULL;
+	adap->timeout = 1;
+	adap->retries = 1;
+
+	if ((ret = i2c_add_adapter(adap)) != 0){
+		printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n",
+			dev->idx);
+		goto fail;
+	}
+	
+	printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,
+		dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
+
+	/* Scan bus if requested by user */
+	if (iic_scan)
+		iic_scan_bus(dev);
+
+	return 0;
+
+fail:	
+	if (dev->irq >= 0){
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}	
+
+	iounmap((void*)dev->vaddr);
+fail2:	
+	ocp_set_drvdata(ocp, 0);
+	kfree(dev);	
+	return ret;
+}
+
+/*
+ * Cleanup initialized IIC interface
+ */
+static void __devexit iic_remove(struct ocp_device *ocp)
+{
+	struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
+	BUG_ON(dev == NULL);
+	if (i2c_del_adapter(&dev->adap)){
+		printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n",
+			dev->idx);
+		/* That's *very* bad, just shutdown IRQ ... */
+		if (dev->irq >= 0){
+		    iic_interrupt_mode(dev, 0);	
+		    free_irq(dev->irq, dev);
+		    dev->irq = -1;
+		}
+	} else {
+		if (dev->irq >= 0){
+		    iic_interrupt_mode(dev, 0);	
+		    free_irq(dev->irq, dev);
+		}
+		iounmap((void*)dev->vaddr);
+		kfree(dev);
+	}
+}
+
+static struct ocp_device_id ibm_iic_ids[] __devinitdata = 
+{
+	{ .vendor = OCP_VENDOR_IBM, .device = OCP_FUNC_IIC },
+	{ .vendor = OCP_VENDOR_INVALID }
+};
+
+MODULE_DEVICE_TABLE(ocp, ibm_iic_ids);
+
+static struct ocp_driver ibm_iic_driver =
+{
+	.name 		= "ocp_iic",
+	.id_table	= ibm_iic_ids,
+	.probe		= iic_probe,
+	.remove		= __devexit_p(iic_remove),
+#if defined(CONFIG_PM)
+	.suspend	= NULL,
+	.resume		= NULL,
+#endif
+};
+
+static int __init iic_init(void)
+{
+	printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n");
+	return ocp_module_init(&ibm_iic_driver);
+}
+
+static void __exit iic_exit(void)
+{
+	ocp_unregister_driver(&ibm_iic_driver);
+}
+
+module_init(iic_init);
+module_exit(iic_exit);
diff -Nru a/drivers/i2c/i2c-ibm_iic.h b/drivers/i2c/i2c-ibm_iic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/i2c-ibm_iic.h	Mon Sep 22 16:15:04 2003
@@ -0,0 +1,124 @@
+/*
+ * drivers/i2c/i2c-ibm_iic.h
+ *
+ * Support for the IIC peripheral on IBM PPC 4xx
+ * 
+ * Copyright (c) 2003 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by 
+ * 	Ian DaSilva  <idasilva@mvista.com>
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Matt Porter  <mporter@mvista.com>
+ *
+ *      Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * 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.
+ *
+ */
+#ifndef __I2C_IBM_IIC_H_
+#define __I2C_IBM_IIC_H_
+
+#include <linux/config.h>
+#include <linux/i2c.h> 
+
+struct iic_regs {
+	u16 mdbuf;
+	u16 sbbuf;
+	u8 lmadr;
+	u8 hmadr;
+	u8 cntl;
+	u8 mdcntl;
+	u8 sts;
+	u8 extsts;
+	u8 lsadr;
+	u8 hsadr;
+	u8 clkdiv;
+	u8 intmsk;
+	u8 xfrcnt;
+	u8 xtcntlss;
+	u8 directcntl;
+};
+
+struct ibm_iic_private {
+	struct i2c_adapter adap;
+	volatile struct iic_regs *vaddr;
+	wait_queue_head_t wq;
+	int idx;
+	int irq;
+	int fast_mode;
+	u8  clckdiv;
+};
+
+/* IICx_CNTL register */
+#define CNTL_HMT	0x80
+#define CNTL_AMD	0x40
+#define CNTL_TCT_MASK	0x30
+#define CNTL_TCT_SHIFT	4
+#define CNTL_RPST	0x08
+#define CNTL_CHT	0x04 
+#define CNTL_RW		0x02
+#define CNTL_PT		0x01
+
+/* IICx_MDCNTL register */
+#define MDCNTL_FSDB	0x80
+#define MDCNTL_FMDB	0x40
+#define MDCNTL_EGC	0x20
+#define MDCNTL_FSM	0x10
+#define MDCNTL_ESM	0x08
+#define MDCNTL_EINT	0x04
+#define MDCNTL_EUBS	0x02
+#define MDCNTL_HSCL	0x01
+
+/* IICx_STS register */
+#define STS_SSS		0x80
+#define STS_SLPR	0x40
+#define STS_MDBS	0x20
+#define STS_MDBF	0x10
+#define STS_SCMP	0x08
+#define STS_ERR		0x04
+#define STS_IRQA	0x02
+#define STS_PT		0x01
+
+/* IICx_EXTSTS register */
+#define EXTSTS_IRQP	0x80
+#define EXTSTS_BCS_MASK	0x70
+#define   EXTSTS_BCS_FREE  0x40
+#define EXTSTS_IRQD	0x08
+#define EXTSTS_LA	0x04
+#define EXTSTS_ICT	0x02
+#define EXTSTS_XFRA	0x01
+
+/* IICx_INTRMSK register */
+#define INTRMSK_EIRC	0x80
+#define INTRMSK_EIRS	0x40
+#define INTRMSK_EIWC	0x20
+#define INTRMSK_EIWS	0x10
+#define INTRMSK_EIHE	0x08
+#define INTRMSK_EIIC	0x04
+#define INTRMSK_EITA	0x02
+#define INTRMSK_EIMTC	0x01
+
+/* IICx_XFRCNT register */
+#define XFRCNT_MTC_MASK	0x07
+
+/* IICx_XTCNTLSS register */
+#define XTCNTLSS_SRC	0x80
+#define XTCNTLSS_SRS	0x40
+#define XTCNTLSS_SWC	0x20
+#define XTCNTLSS_SWS	0x10
+#define XTCNTLSS_SRST	0x01
+
+/* IICx_DIRECTCNTL register */
+#define DIRCNTL_SDAC	0x08
+#define DIRCNTL_SCC	0x04
+#define DIRCNTL_MSDA	0x02
+#define DIRCNTL_MSC	0x01
+
+/* Check if we really control the I2C bus and bus is free */
+#define DIRCTNL_FREE(v)	(((v) & 0x0f) == 0x0f)
+
+#endif /* __I2C_IBM_IIC_H_ */


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                               ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.9, 2003/09/22 11:03:30-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-i810 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig    |   15 ++
 drivers/i2c/busses/Makefile   |    1 
 drivers/i2c/busses/i2c-i810.c |  256 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 272 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:38 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:38 2003
@@ -62,6 +62,21 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
 
+config I2C_I810
+	tristate "Intel 810/815"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the Intel
+	  810/815 family of mainboard I2C interfaces.  Specifically, the 
+	  following versions of the chipset is supported:
+	    i810AA
+	    i810AB
+	    i810E
+	    i815
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-i810.
+
 config I2C_ISA
 	tristate "ISA Bus support"
 	depends on I2C && ISA && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:38 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:38 2003
@@ -7,6 +7,7 @@
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
+obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
diff -Nru a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-i810.c	Mon Sep 22 16:14:38 2003
@@ -0,0 +1,256 @@
+/*
+    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           
+*/
+
+#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>
+
+/* 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 *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, },
+};
+
+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 = {
+	.name		= "i810 smbus",
+	.id_table	= i810_ids,
+	.probe		= i810_probe,
+	.remove		= __devexit_p(i810_remove),
+};
+
+static int __init i2c_i810_init(void)
+{
+	return pci_module_init(&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);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                             ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.8, 2003/09/15 16:54:37-07:00, rwhron@earthlink.net

[PATCH] I2C: drivers/i2c version.h cleanup

remove unnecessary version.h from drivers/i2c.
test compiled with 2.6.0-test5-bk2 on x86.


 drivers/i2c/busses/i2c-amd756.c |    1 -
 drivers/i2c/i2c-adap-ite.c      |    1 -
 drivers/i2c/i2c-algo-ite.c      |    1 -
 drivers/i2c/i2c-elektor.c       |    1 -
 drivers/i2c/i2c-keywest.c       |    1 -
 drivers/i2c/i2c-prosavage.c     |    1 -
 6 files changed, 6 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:14:51 2003
@@ -37,7 +37,6 @@
 
 /* #define DEBUG 1 */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff -Nru a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c
--- a/drivers/i2c/i2c-adap-ite.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-adap-ite.c	Mon Sep 22 16:14:51 2003
@@ -38,7 +38,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff -Nru a/drivers/i2c/i2c-algo-ite.c b/drivers/i2c/i2c-algo-ite.c
--- a/drivers/i2c/i2c-algo-ite.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-algo-ite.c	Mon Sep 22 16:14:51 2003
@@ -38,7 +38,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <linux/ioport.h>
diff -Nru a/drivers/i2c/i2c-elektor.c b/drivers/i2c/i2c-elektor.c
--- a/drivers/i2c/i2c-elektor.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-elektor.c	Mon Sep 22 16:14:51 2003
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
diff -Nru a/drivers/i2c/i2c-keywest.c b/drivers/i2c/i2c-keywest.c
--- a/drivers/i2c/i2c-keywest.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-keywest.c	Mon Sep 22 16:14:51 2003
@@ -45,7 +45,6 @@
 
 #include <linux/module.h>
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
diff -Nru a/drivers/i2c/i2c-prosavage.c b/drivers/i2c/i2c-prosavage.c
--- a/drivers/i2c/i2c-prosavage.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-prosavage.c	Mon Sep 22 16:14:51 2003
@@ -54,7 +54,6 @@
  *    (Additional documentation needed :(
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.6, 2003/09/15 16:44:07-07:00, greg@kroah.com

[PATCH] I2C: turn off debugging on the new sis i2c bus drivers.

Forgot to do this before...


 drivers/i2c/busses/i2c-sis5595.c |    2 +-
 drivers/i2c/busses/i2c-sis630.c  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:15:15 2003
+++ b/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:15:15 2003
@@ -55,7 +55,7 @@
  * Add adapter resets
  */
 
-#define DEBUG
+/* #define DEBUG 1 */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:15:15 2003
+++ b/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:15:15 2003
@@ -48,7 +48,7 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
-#define DEBUG
+/* #define DEBUG 1 */
 
 #include <linux/kernel.h>
 #include <linux/module.h>


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                   ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.11, 2003/09/22 11:15:16-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-voodoo3 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig       |   11 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-voodoo3.c |  248 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 260 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:18 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:18 2003
@@ -189,4 +189,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-viapro.
 
+config I2C_VOODOO3
+	tristate "Voodoo 3"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+
+	  If you say yes to this option, support will be included for the
+	  Voodoo 3 I2C interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-voodoo3.
+
 endmenu
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:18 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:18 2003
@@ -17,3 +17,4 @@
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
+obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
diff -Nru a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-voodoo3.c	Mon Sep 22 16:14:18 2003
@@ -0,0 +1,248 @@
+/*
+    voodoo3.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+    Copyright (c) 1998, 1999  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 I2C bus of the Voodoo3 to gain access to
+    the BT869 and possibly other I2C devices. */
+
+#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>
+
+/* the only registers we use */
+#define REG		0x78
+#define REG2 		0x70
+
+/* bit locations in the register */
+#define DDC_ENAB	0x00040000
+#define DDC_SCL_OUT	0x00080000
+#define DDC_SDA_OUT	0x00100000
+#define DDC_SCL_IN	0x00200000
+#define DDC_SDA_IN	0x00400000
+#define I2C_ENAB	0x00800000
+#define I2C_SCL_OUT	0x01000000
+#define I2C_SDA_OUT	0x02000000
+#define I2C_SCL_IN	0x04000000
+#define I2C_SDA_IN	0x08000000
+
+/* initialization states */
+#define INIT2		0x2
+#define INIT3		0x4
+
+/* delays */
+#define CYCLE_DELAY	10
+#define TIMEOUT		(HZ / 2)
+
+
+static void *ioaddr;
+
+/* The voo GPIO registers don't have individual masks for each bit
+   so we always have to read before writing. */
+
+static void bit_vooi2c_setscl(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= I2C_SCL_OUT;
+	else
+		r &= ~I2C_SCL_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static void bit_vooi2c_setsda(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= I2C_SDA_OUT;
+	else
+		r &= ~I2C_SDA_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+/* The GPIO pins are open drain, so the pins always remain outputs.
+   We rely on the i2c-algo-bit routines to set the pins high before
+   reading the input from other chips. */
+
+static int bit_vooi2c_getscl(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
+}
+
+static int bit_vooi2c_getsda(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
+}
+
+static void bit_vooddc_setscl(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= DDC_SCL_OUT;
+	else
+		r &= ~DDC_SCL_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static void bit_vooddc_setsda(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= DDC_SDA_OUT;
+	else
+		r &= ~DDC_SDA_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static int bit_vooddc_getscl(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & DDC_SCL_IN));
+}
+
+static int bit_vooddc_getsda(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & DDC_SDA_IN));
+}
+
+static int config_v3(struct pci_dev *dev)
+{
+	unsigned int cadr;
+
+	/* map Voodoo3 memory */
+	cadr = dev->resource[0].start;
+	cadr &= PCI_BASE_ADDRESS_MEM_MASK;
+	ioaddr = ioremap_nocache(cadr, 0x1000);
+	if (ioaddr) {
+		writel(0x8160, ioaddr + REG2);
+		writel(0xcffc0020, ioaddr + REG);
+		dev_info(&dev->dev, "Using Banshee/Voodoo3 I2C device at %p\n", ioaddr);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+static struct i2c_algo_bit_data voo_i2c_bit_data = {
+	.setsda		= bit_vooi2c_setsda,
+	.setscl		= bit_vooi2c_setscl,
+	.getsda		= bit_vooi2c_getsda,
+	.getscl		= bit_vooi2c_getscl,
+	.udelay		= CYCLE_DELAY,
+	.mdelay		= CYCLE_DELAY,
+	.timeout	= TIMEOUT
+};
+
+static struct i2c_adapter voodoo3_i2c_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "I2C Voodoo3/Banshee adapter",
+	.algo_data	= &voo_i2c_bit_data,
+};
+
+static struct i2c_algo_bit_data voo_ddc_bit_data = {
+	.setsda		= bit_vooddc_setsda,
+	.setscl		= bit_vooddc_setscl,
+	.getsda		= bit_vooddc_getsda,
+	.getscl		= bit_vooddc_getscl,
+	.udelay		= CYCLE_DELAY,
+	.mdelay		= CYCLE_DELAY,
+	.timeout	= TIMEOUT
+};
+
+static struct i2c_adapter voodoo3_ddc_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "DDC Voodoo3/Banshee adapter",
+	.algo_data	= &voo_ddc_bit_data,
+};
+
+static struct pci_device_id voodoo3_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE) },
+	{ 0, }
+};
+
+static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int retval;
+
+	retval = config_v3(dev);
+	if (retval)
+		return retval;
+
+	/* set up the sysfs linkage to our parent device */
+	voodoo3_i2c_adapter.dev.parent = &dev->dev;
+	voodoo3_ddc_adapter.dev.parent = &dev->dev;
+
+	retval = i2c_bit_add_bus(&voodoo3_i2c_adapter);
+	if (retval)
+		return retval;
+	retval = i2c_bit_add_bus(&voodoo3_ddc_adapter);
+	if (retval)
+		i2c_bit_del_bus(&voodoo3_i2c_adapter);
+	return retval;
+}
+
+static void __devexit voodoo3_remove(struct pci_dev *dev)
+{
+	i2c_bit_del_bus(&voodoo3_i2c_adapter);
+ 	i2c_bit_del_bus(&voodoo3_ddc_adapter);
+	iounmap(ioaddr);
+}
+
+static struct pci_driver voodoo3_driver = {
+	.name		= "voodoo3 smbus",
+	.id_table	= voodoo3_ids,
+	.probe		= voodoo3_probe,
+	.remove		= __devexit_p(voodoo3_remove),
+};
+
+static int __init i2c_voodoo3_init(void)
+{
+	return pci_module_init(&voodoo3_driver);
+}
+
+static void __exit i2c_voodoo3_exit(void)
+{
+	pci_unregister_driver(&voodoo3_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("Voodoo3 I2C/SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_voodoo3_init);
+module_exit(i2c_voodoo3_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.12, 2003/09/22 11:42:40-07:00, greg@kroah.com

I2C: clean up the i2c chips Kconfig logic and help information


 drivers/i2c/chips/Kconfig |  111 +++++++++++++++++++---------------------------
 1 files changed, 46 insertions(+), 65 deletions(-)


diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	Mon Sep 22 16:14:08 2003
+++ b/drivers/i2c/chips/Kconfig	Mon Sep 22 16:14:08 2003
@@ -1,112 +1,93 @@
 #
-# Sensor device configuration
-# All depend on EXPERIMENTAL and I2C
+# I2C Sensor device configuration
 #
 
 menu "I2C Hardware Sensors Chip support"
 
+config I2C_SENSOR
+	tristate
+	default n
+
 config SENSORS_ADM1021
-	tristate "  Analog Devices ADM1021 and compatibles"
+	tristate "Analog Devices ADM1021 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for Analog Devices ADM1021 
 	  and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
 	  Genesys Logic GL523SM, National Semi LM84, TI THMC10,
-	  and the XEON processor built-in sensor. This can also 
-	  be built as a module which can be inserted and removed while the 
-	  kernel is running.
+	  and the XEON processor built-in sensor.
 
-	  The module will be called adm1021.
-	  
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1021.
 
 config SENSORS_IT87
-	tristate "  National Semiconductors IT87 and compatibles"
+	tristate "National Semiconductors IT87 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
-	  The module will be called it87.
+	  If you say yes here you get support for National Semiconductor IT87
+	  sensor chips and clones: IT8705F, IT8712F and SiS960.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called it87.
 
 config SENSORS_LM75
-	tristate "  National Semiconductors LM75 and compatibles"
+	tristate "National Semiconductors LM75 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for National Semiconductor LM75
 	  sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon
-	  TCN75, and National Semi LM77. This can also be built as a module
-	  which can be inserted and removed while the kernel is running.
-
-	  The module will be called lm75.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
-	  
-config SENSORS_LM85
-	tristate "  National Semiconductors LM85 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	help
-	  If you say yes here you get support for National Semiconductor LM85
-	  sensor chips and clones: ADT7463 and ADM1027.
-	  This can also be built as a module which can be inserted and
-	  removed while the kernel is running.
+	  TCN75, and National Semi LM77.
 
-	  The module will be called lm85.
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm75.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
-	  
 config SENSORS_LM78
-	tristate "  National Semiconductors LM78 and compatibles"
+	tristate "National Semiconductors LM78 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for National Semiconductor LM78,
 	  LM78-J and LM79.  This can also be built as a module which can be
 	  inserted and removed while the kernel is running.
 
-	  The module will be called lm78.
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm78.
+
+config SENSORS_LM85
+	tristate "National Semiconductors LM85 and compatibles"
+	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM85
+	  sensor chips and clones: ADT7463 and ADM1027.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm85.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
-	  
 config SENSORS_VIA686A
-	tristate "  VIA686A"
+	tristate "VIA686A"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
-	  support for via686a
 	  If you say yes here you get support for the integrated sensors in
-	  Via 686A/B South Bridges. This can also be built as a module
-	  which can be inserted and removed while the kernel is running.
+	  Via 686A/B South Bridges.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called via686a.
 
 config SENSORS_W83781D
-	tristate "  Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
+	tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for the Winbond W8378x series
 	  of sensor chips: the W83781D, W83782D, W83783S and W83682HF,
-	  and the similar Asus AS99127F. This
-	  can also be built as a module which can be inserted and removed
-	  while the kernel is running.
+	  and the similar Asus AS99127F.
 	  
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
-
-config I2C_SENSOR
-	tristate
-	default y if SENSORS_ADM1021=y || SENSORS_IT87=y || SENSORS_LM75=y || SENSORS_VIA686A=y || SENSORS_W83781D=y || SENSORS_LM85=y
-	default m if SENSORS_ADM1021=m || SENSORS_IT87=m || SENSORS_LM75=m || SENSORS_VIA686A=m || SENSORS_W83781D=m || SENSORS_LM85=m
-	default n
+	  This driver can also be built as a module.  If so, the module
+	  will be called w83781d.
 
 endmenu


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.10, 2003/09/22 11:05:20-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-savage4 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig       |   10 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-savage4.c |  205 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 216 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:28 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:28 2003
@@ -113,6 +113,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-piix4.
 
+config I2C_SAVAGE4
+	tristate "S3 Savage 4"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the 
+	  S3 Savage 4 I2C interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-savage4.
+
 config I2C_SIS5595
 	tristate "SiS 5595"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:28 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:28 2003
@@ -11,6 +11,7 @@
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
diff -Nru a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-savage4.c	Mon Sep 22 16:14:28 2003
@@ -0,0 +1,205 @@
+/*
+    i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+    Copyright (c) 1998, 1999  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 I2C bus of the Savage4 to gain access to
+   the BT869 and possibly other I2C devices. The DDC bus is not
+   yet supported because its register is not memory-mapped.
+   However we leave the DDC code here, commented out, to make
+   it easier to add later.
+*/
+
+#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>
+
+/* 3DFX defines */
+#define PCI_CHIP_SAVAGE3D	0x8A20
+#define PCI_CHIP_SAVAGE3D_MV	0x8A21
+#define PCI_CHIP_SAVAGE4	0x8A22
+#define PCI_CHIP_SAVAGE2000	0x9102
+#define PCI_CHIP_PROSAVAGE_PM	0x8A25
+#define PCI_CHIP_PROSAVAGE_KM	0x8A26
+#define PCI_CHIP_SAVAGE_MX_MV	0x8c10
+#define PCI_CHIP_SAVAGE_MX	0x8c11
+#define PCI_CHIP_SAVAGE_IX_MV	0x8c12
+#define PCI_CHIP_SAVAGE_IX	0x8c13
+
+#define REG			0xff20	/* Serial Port 1 Register */
+
+/* bit locations in the register */
+#define DDC_ENAB		0x00040000
+#define DDC_SCL_OUT		0x00080000
+#define DDC_SDA_OUT		0x00100000
+#define DDC_SCL_IN		0x00200000
+#define DDC_SDA_IN		0x00400000
+#define I2C_ENAB		0x00000020
+#define I2C_SCL_OUT		0x00000001
+#define I2C_SDA_OUT		0x00000002
+#define I2C_SCL_IN		0x00000008
+#define I2C_SDA_IN		0x00000010
+
+/* initialization states */
+#define INIT2			0x20
+#define INIT3			0x04
+
+/* delays */
+#define CYCLE_DELAY		10
+#define TIMEOUT			(HZ / 2)
+
+
+static void *ioaddr;
+
+/* The sav GPIO registers don't have individual masks for each bit
+   so we always have to read before writing. */
+
+static void bit_savi2c_setscl(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if(val)
+		r |= I2C_SCL_OUT;
+	else
+		r &= ~I2C_SCL_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static void bit_savi2c_setsda(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if(val)
+		r |= I2C_SDA_OUT;
+	else
+		r &= ~I2C_SDA_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+/* The GPIO pins are open drain, so the pins always remain outputs.
+   We rely on the i2c-algo-bit routines to set the pins high before
+   reading the input from other chips. */
+
+static int bit_savi2c_getscl(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
+}
+
+static int bit_savi2c_getsda(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
+}
+
+/* Configures the chip */
+
+static int config_s4(struct pci_dev *dev)
+{
+	unsigned int cadr;
+
+	/* map memory */
+	cadr = dev->resource[0].start;
+	cadr &= PCI_BASE_ADDRESS_MEM_MASK;
+	ioaddr = ioremap_nocache(cadr, 0x0080000);
+	if (ioaddr) {
+		/* writel(0x8160, ioaddr + REG2); */
+		writel(0x00000020, ioaddr + REG);
+		dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+static struct i2c_algo_bit_data sav_i2c_bit_data = {
+	.setsda		= bit_savi2c_setsda,
+	.setscl		= bit_savi2c_setscl,
+	.getsda		= bit_savi2c_getsda,
+	.getscl		= bit_savi2c_getscl,
+	.udelay		= CYCLE_DELAY,
+	.mdelay		= CYCLE_DELAY,
+	.timeout	= TIMEOUT
+};
+
+static struct i2c_adapter savage4_i2c_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "I2C Savage4 adapter",
+	.algo_data	= &sav_i2c_bit_data,
+};
+
+static struct pci_device_id savage4_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) },
+	{ 0, }
+};
+
+static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int retval;
+
+	retval = config_s4(dev);
+	if (retval)
+		return retval;
+
+	/* set up the sysfs linkage to our parent device */
+	savage4_i2c_adapter.dev.parent = &dev->dev;
+
+	return i2c_bit_add_bus(&savage4_i2c_adapter);
+}
+
+static void __devexit savage4_remove(struct pci_dev *dev)
+{
+	i2c_bit_del_bus(&savage4_i2c_adapter);
+	iounmap(ioaddr);
+}
+
+static struct pci_driver savage4_driver = {
+	.name		= "savage4 smbus",
+	.id_table	= savage4_ids,
+	.probe		= savage4_probe,
+	.remove		= __devexit_p(savage4_remove),
+};
+
+static int __init i2c_savage4_init(void)
+{
+	return pci_module_init(&savage4_driver);
+}
+
+static void __exit i2c_savage4_exit(void)
+{
+	pci_unregister_driver(&savage4_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("Savage4 I2C/SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_savage4_init);
+module_exit(i2c_savage4_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.14, 2003/09/22 12:46:46-07:00, greg@kroah.com

[PATCH] I2C: move i2c-prosavage.c driver to drivers/i2c/busses where it belongs.


 drivers/i2c/i2c-prosavage.c        |  356 -------------------------------------
 drivers/i2c/Kconfig                |   14 -
 drivers/i2c/Makefile               |    1 
 drivers/i2c/busses/Kconfig         |   14 +
 drivers/i2c/busses/Makefile        |    1 
 drivers/i2c/busses/i2c-prosavage.c |  356 +++++++++++++++++++++++++++++++++++++
 6 files changed, 371 insertions(+), 371 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:13:48 2003
@@ -48,20 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_PROSAVAGE
-	tristate "S3/VIA (Pro)Savage"
-	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
-	help
-	  If you say yes to this option, support will be included for the
-	  I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8
-	  graphics processors.
-	  chipsets supported:
-	    S3/VIA KM266/VT8375 aka ProSavage8
-	    S3/VIA KM133/VT8365 aka Savage4
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-prosavage.
-
 config I2C_PHILIPSPAR
 	tristate "Philips style parallel port adapter"
 	depends on I2C_ALGOBIT && PARPORT
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:13:48 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:48 2003
@@ -113,6 +113,20 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-piix4.
 
+config I2C_PROSAVAGE
+	tristate "S3/VIA (Pro)Savage"
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the
+	  I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8
+	  graphics processors.
+	  chipsets supported:
+	    S3/VIA KM266/VT8375 aka ProSavage8
+	    S3/VIA KM133/VT8365 aka Savage4
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-prosavage.
+
 config I2C_SAVAGE4
 	tristate "S3 Savage 4"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:48 2003
@@ -11,6 +11,7 @@
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-prosavage.c	Mon Sep 22 16:13:48 2003
@@ -0,0 +1,356 @@
+/*
+ *    kernel/busses/i2c-prosavage.c
+ *
+ *    i2c bus driver for S3/VIA 8365/8375 graphics processor.
+ *    Copyright (c) 2003 Henk Vergonet <henk@god.dyndns.org>
+ *    Based on code written by:
+ *	Frodo Looijaard <frodol@dds.nl>,
+ *	Philip Edelbrock <phil@netroedge.com>,
+ *	Ralph Metzler <rjkm@thp.uni-koeln.de>, and
+ *	Mark D. Studebaker <mdsxyz123@yahoo.com>
+ *	Simon Vogl
+ *	and others
+ *
+ *    Please read the lm_sensors documentation for details on use.
+ *
+ *    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.
+ *
+ */
+/*  18-05-2003 HVE - created
+ *  14-06-2003 HVE - adapted for lm_sensors2
+ *  17-06-2003 HVE - linux 2.5.xx compatible
+ *  18-06-2003 HVE - codingstyle
+ *  21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx
+ *		     codingstyle, mmio enabled
+ *
+ *  This driver interfaces to the I2C bus of the VIA north bridge embedded
+ *  ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips.
+ *
+ *  Graphics cores:
+ *   S3/VIA KM266/VT8375 aka ProSavage8
+ *   S3/VIA KM133/VT8365 aka Savage4
+ *
+ *  Two serial busses are implemented:
+ *   SERIAL1 - I2C serial communications interface
+ *   SERIAL2 - DDC2 monitor communications interface
+ *
+ *  Tested on a FX41 mainboard, see http://www.shuttle.com
+ * 
+ *
+ *  TODO:
+ *  - integration with prosavage framebuffer device
+ *    (Additional documentation needed :(
+ */
+
+#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>
+
+
+/*
+ * driver configuration
+ */
+#define	DRIVER_ID	"i2c-prosavage"
+#define	DRIVER_VERSION	"20030621"
+
+#define ADAPTER_NAME(x) (x).name
+
+#define MAX_BUSSES	2
+
+struct s_i2c_bus {
+	u8	*mmvga;
+	int	i2c_reg;
+	int	adap_ok;
+	struct i2c_adapter		adap;
+	struct i2c_algo_bit_data	algo;
+};
+
+struct s_i2c_chip {
+	u8	*mmio;
+	struct s_i2c_bus	i2c_bus[MAX_BUSSES];
+};
+
+
+/*
+ * i2c configuration
+ */
+#ifndef I2C_HW_B_S3VIA
+#define I2C_HW_B_S3VIA	0x18	/* S3VIA ProSavage adapter		*/
+#endif
+
+/* delays */
+#define CYCLE_DELAY	10
+#define TIMEOUT		(HZ / 2)
+
+
+/* 
+ * S3/VIA 8365/8375 registers
+ */
+#ifndef PCI_VENDOR_ID_S3
+#define PCI_VENDOR_ID_S3		0x5333
+#endif
+#ifndef PCI_DEVICE_ID_S3_SAVAGE4
+#define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
+#endif
+#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8
+#define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
+#endif
+
+#define VGA_CR_IX	0x3d4
+#define VGA_CR_DATA	0x3d5
+
+#define CR_SERIAL1	0xa0	/* I2C serial communications interface */
+#define MM_SERIAL1	0xff20
+#define CR_SERIAL2	0xb1	/* DDC2 monitor communications interface */
+
+/* based on vt8365 documentation */
+#define I2C_ENAB	0x10
+#define I2C_SCL_OUT	0x01
+#define I2C_SDA_OUT	0x02
+#define I2C_SCL_IN	0x04
+#define I2C_SDA_IN	0x08
+
+#define SET_CR_IX(p, val)	*((p)->mmvga + VGA_CR_IX) = (u8)(val)
+#define SET_CR_DATA(p, val)	*((p)->mmvga + VGA_CR_DATA) = (u8)(val)
+#define GET_CR_DATA(p)		*((p)->mmvga + VGA_CR_DATA)
+
+
+/*
+ * Serial bus line handling
+ *
+ * serial communications register as parameter in private data
+ *
+ * TODO: locks with other code sections accessing video registers?
+ */
+static void bit_s3via_setscl(void *bus, int val)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+	unsigned int r;
+
+	SET_CR_IX(p, p->i2c_reg);
+	r = GET_CR_DATA(p);
+	r |= I2C_ENAB;
+	if (val) {
+		r |= I2C_SCL_OUT;
+	} else {
+		r &= ~I2C_SCL_OUT;
+	}
+	SET_CR_DATA(p, r);
+}
+
+static void bit_s3via_setsda(void *bus, int val)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+	unsigned int r;
+	
+	SET_CR_IX(p, p->i2c_reg);
+	r = GET_CR_DATA(p);
+	r |= I2C_ENAB;
+	if (val) {
+		r |= I2C_SDA_OUT;
+	} else {
+		r &= ~I2C_SDA_OUT;
+	}
+	SET_CR_DATA(p, r);
+}
+
+static int bit_s3via_getscl(void *bus)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+
+	SET_CR_IX(p, p->i2c_reg);
+	return (0 != (GET_CR_DATA(p) & I2C_SCL_IN));
+}
+
+static int bit_s3via_getsda(void *bus)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+
+	SET_CR_IX(p, p->i2c_reg);
+	return (0 != (GET_CR_DATA(p) & I2C_SDA_IN));
+}
+
+
+/*
+ * adapter initialisation
+ */
+static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+{
+	int ret;
+	p->adap.owner	  = THIS_MODULE;
+	p->adap.id	  = I2C_HW_B_S3VIA;
+	p->adap.algo_data = &p->algo;
+	p->algo.setsda	  = bit_s3via_setsda;
+	p->algo.setscl	  = bit_s3via_setscl;
+	p->algo.getsda	  = bit_s3via_getsda;
+	p->algo.getscl	  = bit_s3via_getscl;
+	p->algo.udelay	  = CYCLE_DELAY;
+	p->algo.mdelay	  = CYCLE_DELAY;
+	p->algo.timeout	  = TIMEOUT;
+	p->algo.data	  = p;
+	p->mmvga	  = mmvga;
+	p->i2c_reg	  = i2c_reg;
+    
+	ret = i2c_bit_add_bus(&p->adap);
+	if (ret) {
+		return ret;
+	}
+
+	p->adap_ok = 1;
+	return 0;
+}
+
+
+/*
+ * Cleanup stuff
+ */
+static void __devexit prosavage_remove(struct pci_dev *dev)
+{
+	struct s_i2c_chip *chip;
+	int i, ret;
+
+	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
+
+	if (!chip) {
+		return;
+	}
+	for (i = MAX_BUSSES - 1; i >= 0; i--) {
+		if (chip->i2c_bus[i].adap_ok == 0)
+			continue;
+
+		ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
+	        if (ret) {
+			printk(DRIVER_ID ": %s not removed\n",
+				ADAPTER_NAME(chip->i2c_bus[i].adap));
+		}
+	}
+	if (chip->mmio) {
+		iounmap(chip->mmio);
+	}
+	kfree(chip);
+}
+
+
+/*
+ * Detect chip and initialize it
+ */
+static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int ret;
+	unsigned long base, len;
+	struct s_i2c_chip *chip;
+	struct s_i2c_bus  *bus;
+
+        pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); 
+	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
+	if (chip == NULL) {
+		return -ENOMEM;
+	}
+
+	memset(chip, 0, sizeof(struct s_i2c_chip));
+
+	base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
+	len  = dev->resource[0].end - base + 1;
+	chip->mmio = ioremap_nocache(base, len);
+
+	if (chip->mmio == NULL) {
+		printk (DRIVER_ID ": ioremap failed\n");
+		prosavage_remove(dev);
+		return -ENODEV;
+	}
+
+
+	/*
+	 * Chip initialisation
+	 */
+	/* Unlock Extended IO Space ??? */
+
+
+	/*
+	 * i2c bus registration
+	 */
+	bus = &chip->i2c_bus[0];
+	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+		"ProSavage I2C bus at %02x:%02x.%x",
+		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1);
+	if (ret) {
+		goto err_adap;
+	}
+	/*
+	 * ddc bus registration
+	 */
+	bus = &chip->i2c_bus[1];
+	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+		"ProSavage DDC bus at %02x:%02x.%x",
+		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2);
+	if (ret) {
+		goto err_adap;
+	}
+	return 0;
+err_adap:
+	printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap));
+	prosavage_remove(dev);
+	return ret;
+}
+
+
+/*
+ * Data for PCI driver interface
+ */
+static struct pci_device_id prosavage_pci_tbl[] = {
+   {
+	.vendor		=	PCI_VENDOR_ID_S3,
+	.device		=	PCI_DEVICE_ID_S3_SAVAGE4,
+	.subvendor	=	PCI_ANY_ID,
+	.subdevice	=	PCI_ANY_ID,
+   },{
+	.vendor		=	PCI_VENDOR_ID_S3,
+	.device		=	PCI_DEVICE_ID_S3_PROSAVAGE8,
+	.subvendor	=	PCI_ANY_ID,
+	.subdevice	=	PCI_ANY_ID,
+   },{ 0, }
+};
+
+static struct pci_driver prosavage_driver = {
+	.name		=	"prosavage-smbus",
+	.id_table	=	prosavage_pci_tbl,
+	.probe		=	prosavage_probe,
+	.remove		=	__devexit_p(prosavage_remove),
+};
+
+static int __init i2c_prosavage_init(void)
+{
+	printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION);
+	return pci_module_init(&prosavage_driver);
+}
+
+static void __exit i2c_prosavage_exit(void)
+{
+	pci_unregister_driver(&prosavage_driver);
+}
+
+MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl);
+MODULE_AUTHOR("Henk Vergonet");
+MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver");
+MODULE_LICENSE("GPL");
+
+module_init (i2c_prosavage_init);
+module_exit (i2c_prosavage_exit);
diff -Nru a/drivers/i2c/i2c-prosavage.c b/drivers/i2c/i2c-prosavage.c
--- a/drivers/i2c/i2c-prosavage.c	Mon Sep 22 16:13:48 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,356 +0,0 @@
-/*
- *    kernel/busses/i2c-prosavage.c
- *
- *    i2c bus driver for S3/VIA 8365/8375 graphics processor.
- *    Copyright (c) 2003 Henk Vergonet <henk@god.dyndns.org>
- *    Based on code written by:
- *	Frodo Looijaard <frodol@dds.nl>,
- *	Philip Edelbrock <phil@netroedge.com>,
- *	Ralph Metzler <rjkm@thp.uni-koeln.de>, and
- *	Mark D. Studebaker <mdsxyz123@yahoo.com>
- *	Simon Vogl
- *	and others
- *
- *    Please read the lm_sensors documentation for details on use.
- *
- *    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.
- *
- */
-/*  18-05-2003 HVE - created
- *  14-06-2003 HVE - adapted for lm_sensors2
- *  17-06-2003 HVE - linux 2.5.xx compatible
- *  18-06-2003 HVE - codingstyle
- *  21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx
- *		     codingstyle, mmio enabled
- *
- *  This driver interfaces to the I2C bus of the VIA north bridge embedded
- *  ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips.
- *
- *  Graphics cores:
- *   S3/VIA KM266/VT8375 aka ProSavage8
- *   S3/VIA KM133/VT8365 aka Savage4
- *
- *  Two serial busses are implemented:
- *   SERIAL1 - I2C serial communications interface
- *   SERIAL2 - DDC2 monitor communications interface
- *
- *  Tested on a FX41 mainboard, see http://www.shuttle.com
- * 
- *
- *  TODO:
- *  - integration with prosavage framebuffer device
- *    (Additional documentation needed :(
- */
-
-#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>
-
-
-/*
- * driver configuration
- */
-#define	DRIVER_ID	"i2c-prosavage"
-#define	DRIVER_VERSION	"20030621"
-
-#define ADAPTER_NAME(x) (x).name
-
-#define MAX_BUSSES	2
-
-struct s_i2c_bus {
-	u8	*mmvga;
-	int	i2c_reg;
-	int	adap_ok;
-	struct i2c_adapter		adap;
-	struct i2c_algo_bit_data	algo;
-};
-
-struct s_i2c_chip {
-	u8	*mmio;
-	struct s_i2c_bus	i2c_bus[MAX_BUSSES];
-};
-
-
-/*
- * i2c configuration
- */
-#ifndef I2C_HW_B_S3VIA
-#define I2C_HW_B_S3VIA	0x18	/* S3VIA ProSavage adapter		*/
-#endif
-
-/* delays */
-#define CYCLE_DELAY	10
-#define TIMEOUT		(HZ / 2)
-
-
-/* 
- * S3/VIA 8365/8375 registers
- */
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3		0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SAVAGE4
-#define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
-#endif
-#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8
-#define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
-#endif
-
-#define VGA_CR_IX	0x3d4
-#define VGA_CR_DATA	0x3d5
-
-#define CR_SERIAL1	0xa0	/* I2C serial communications interface */
-#define MM_SERIAL1	0xff20
-#define CR_SERIAL2	0xb1	/* DDC2 monitor communications interface */
-
-/* based on vt8365 documentation */
-#define I2C_ENAB	0x10
-#define I2C_SCL_OUT	0x01
-#define I2C_SDA_OUT	0x02
-#define I2C_SCL_IN	0x04
-#define I2C_SDA_IN	0x08
-
-#define SET_CR_IX(p, val)	*((p)->mmvga + VGA_CR_IX) = (u8)(val)
-#define SET_CR_DATA(p, val)	*((p)->mmvga + VGA_CR_DATA) = (u8)(val)
-#define GET_CR_DATA(p)		*((p)->mmvga + VGA_CR_DATA)
-
-
-/*
- * Serial bus line handling
- *
- * serial communications register as parameter in private data
- *
- * TODO: locks with other code sections accessing video registers?
- */
-static void bit_s3via_setscl(void *bus, int val)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-	unsigned int r;
-
-	SET_CR_IX(p, p->i2c_reg);
-	r = GET_CR_DATA(p);
-	r |= I2C_ENAB;
-	if (val) {
-		r |= I2C_SCL_OUT;
-	} else {
-		r &= ~I2C_SCL_OUT;
-	}
-	SET_CR_DATA(p, r);
-}
-
-static void bit_s3via_setsda(void *bus, int val)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-	unsigned int r;
-	
-	SET_CR_IX(p, p->i2c_reg);
-	r = GET_CR_DATA(p);
-	r |= I2C_ENAB;
-	if (val) {
-		r |= I2C_SDA_OUT;
-	} else {
-		r &= ~I2C_SDA_OUT;
-	}
-	SET_CR_DATA(p, r);
-}
-
-static int bit_s3via_getscl(void *bus)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-
-	SET_CR_IX(p, p->i2c_reg);
-	return (0 != (GET_CR_DATA(p) & I2C_SCL_IN));
-}
-
-static int bit_s3via_getsda(void *bus)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-
-	SET_CR_IX(p, p->i2c_reg);
-	return (0 != (GET_CR_DATA(p) & I2C_SDA_IN));
-}
-
-
-/*
- * adapter initialisation
- */
-static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
-{
-	int ret;
-	p->adap.owner	  = THIS_MODULE;
-	p->adap.id	  = I2C_HW_B_S3VIA;
-	p->adap.algo_data = &p->algo;
-	p->algo.setsda	  = bit_s3via_setsda;
-	p->algo.setscl	  = bit_s3via_setscl;
-	p->algo.getsda	  = bit_s3via_getsda;
-	p->algo.getscl	  = bit_s3via_getscl;
-	p->algo.udelay	  = CYCLE_DELAY;
-	p->algo.mdelay	  = CYCLE_DELAY;
-	p->algo.timeout	  = TIMEOUT;
-	p->algo.data	  = p;
-	p->mmvga	  = mmvga;
-	p->i2c_reg	  = i2c_reg;
-    
-	ret = i2c_bit_add_bus(&p->adap);
-	if (ret) {
-		return ret;
-	}
-
-	p->adap_ok = 1;
-	return 0;
-}
-
-
-/*
- * Cleanup stuff
- */
-static void __devexit prosavage_remove(struct pci_dev *dev)
-{
-	struct s_i2c_chip *chip;
-	int i, ret;
-
-	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
-
-	if (!chip) {
-		return;
-	}
-	for (i = MAX_BUSSES - 1; i >= 0; i--) {
-		if (chip->i2c_bus[i].adap_ok == 0)
-			continue;
-
-		ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
-	        if (ret) {
-			printk(DRIVER_ID ": %s not removed\n",
-				ADAPTER_NAME(chip->i2c_bus[i].adap));
-		}
-	}
-	if (chip->mmio) {
-		iounmap(chip->mmio);
-	}
-	kfree(chip);
-}
-
-
-/*
- * Detect chip and initialize it
- */
-static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int ret;
-	unsigned long base, len;
-	struct s_i2c_chip *chip;
-	struct s_i2c_bus  *bus;
-
-        pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); 
-	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
-	if (chip == NULL) {
-		return -ENOMEM;
-	}
-
-	memset(chip, 0, sizeof(struct s_i2c_chip));
-
-	base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
-	len  = dev->resource[0].end - base + 1;
-	chip->mmio = ioremap_nocache(base, len);
-
-	if (chip->mmio == NULL) {
-		printk (DRIVER_ID ": ioremap failed\n");
-		prosavage_remove(dev);
-		return -ENODEV;
-	}
-
-
-	/*
-	 * Chip initialisation
-	 */
-	/* Unlock Extended IO Space ??? */
-
-
-	/*
-	 * i2c bus registration
-	 */
-	bus = &chip->i2c_bus[0];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
-		"ProSavage I2C bus at %02x:%02x.%x",
-		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1);
-	if (ret) {
-		goto err_adap;
-	}
-	/*
-	 * ddc bus registration
-	 */
-	bus = &chip->i2c_bus[1];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
-		"ProSavage DDC bus at %02x:%02x.%x",
-		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2);
-	if (ret) {
-		goto err_adap;
-	}
-	return 0;
-err_adap:
-	printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap));
-	prosavage_remove(dev);
-	return ret;
-}
-
-
-/*
- * Data for PCI driver interface
- */
-static struct pci_device_id prosavage_pci_tbl[] = {
-   {
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_SAVAGE4,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_PROSAVAGE8,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{ 0, }
-};
-
-static struct pci_driver prosavage_driver = {
-	.name		=	"prosavage-smbus",
-	.id_table	=	prosavage_pci_tbl,
-	.probe		=	prosavage_probe,
-	.remove		=	__devexit_p(prosavage_remove),
-};
-
-static int __init i2c_prosavage_init(void)
-{
-	printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION);
-	return pci_module_init(&prosavage_driver);
-}
-
-static void __exit i2c_prosavage_exit(void)
-{
-	pci_unregister_driver(&prosavage_driver);
-}
-
-MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl);
-MODULE_AUTHOR("Henk Vergonet");
-MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver");
-MODULE_LICENSE("GPL");
-
-module_init (i2c_prosavage_init);
-module_exit (i2c_prosavage_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.13, 2003/09/22 12:26:49-07:00, greg@kroah.com

I2C: clean up the drivers/i2c/Kconfig file


 drivers/i2c/Kconfig |  102 +++++++++++++++++++---------------------------------
 1 files changed, 38 insertions(+), 64 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:13:58 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:13:58 2003
@@ -22,10 +22,20 @@
 	  If you want I2C support, you should say Y here and also to the
 	  specific driver for your bus adapter(s) below.
 
-	  This I2C support is also available as a module.  If you want to
-	  compile it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-core.
+	  This I2C support can also be built as a module.  If so, the module
+	  will be called i2c-core.
+
+config I2C_CHARDEV
+	tristate "I2C device interface"
+	depends on I2C
+	help
+	  Say Y here to use i2c-* device files, usually found in the /dev
+	  directory on your system.  They make it possible to have user-space
+	  programs use the I2C bus.  Information on how to do this is
+	  contained in the file <file:Documentation/i2c/dev-interface>.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-dev.
 
 config I2C_ALGOBIT
 	tristate "I2C bit-banging interfaces"
@@ -35,10 +45,8 @@
 	  adapters.  Say Y if you own an I2C adapter belonging to this class
 	  and then say Y to the specific driver for you adapter below.
 
-	  This support is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-algo-bit.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-algo-bit.
 
 config I2C_PROSAVAGE
 	tristate "S3/VIA (Pro)Savage"
@@ -51,14 +59,8 @@
 	    S3/VIA KM266/VT8375 aka ProSavage8
 	    S3/VIA KM133/VT8365 aka Savage4
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-	  The module will be called i2c-prosavage.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-prosavage.
 
 config I2C_PHILIPSPAR
 	tristate "Philips style parallel port adapter"
@@ -67,13 +69,8 @@
 	  This supports parallel-port I2C adapters made by Philips.  Say Y if
 	  you own such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-philips-par.
-
-	  Note that if you want support for different parallel port devices,
-	  life will be much easier if you compile them all as modules.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-philips-par.
 
 config I2C_ELV
 	tristate "ELV adapter"
@@ -82,10 +79,8 @@
 	  This supports parallel-port I2C adapters called ELV.  Say Y if you
 	  own such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-elv.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elv.
 
 config I2C_VELLEMAN
 	tristate "Velleman K9000 adapter"
@@ -94,10 +89,8 @@
 	  This supports the Velleman K9000 parallel-port I2C adapter.  Say Y
 	  if you own such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-velleman.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-velleman.
 
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins"
@@ -107,7 +100,8 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_i2c.
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_i2c.
 
 config SCx200_I2C_SCL
 	int "GPIO pin used for SCL"
@@ -133,7 +127,8 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_acb.
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_acb.
 
 config I2C_ALGOPCF
 	tristate "I2C PCF 8584 interfaces"
@@ -143,10 +138,8 @@
 	  Say Y if you own an I2C adapter belonging to this class and then say
 	  Y to the specific driver for you adapter below.
 
-	  This support is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-algo-pcf.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-algo-pcf.
 
 config I2C_ELEKTOR
 	tristate "Elektor ISA card"
@@ -155,10 +148,8 @@
 	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
 	  such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-elektor.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elektor.
 
 config I2C_KEYWEST
 	tristate "Powermac Keywest I2C interface"
@@ -167,9 +158,8 @@
 	  This supports the use of the I2C interface in the combo-I/O
 	  chip on recent Apple machines.  Say Y if you have such a machine.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read Documentation/modules.txt.
-	  The module will be called i2c-keywest.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-keywest.
 
 config ITE_I2C_ALGO
 	tristate "ITE I2C Algorithm"
@@ -179,9 +169,8 @@
 	  systems. Say Y if you have one of these. You should also say Y for
 	  the ITE I2C peripheral driver support below.
 
-	  This support is also available as a module. If you want to compile
-	  it as a module, say M here and read Documentation/modules.txt.
-	  The module will be called i2c-algo-ite.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-algo-ite.
 
 config ITE_I2C_ADAP
 	tristate "ITE I2C Adapter"
@@ -191,9 +180,8 @@
 	  systems. Say Y if you have one of these. You should also say Y for
 	  the ITE I2C driver algorithm support above.
 
-	  This support is also available as a module. If you want to compile
-	  it as a module, say M here and read Documentation/modules.txt.
-	  The module will be called i2c-adap-ite.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-adap-ite.
 
 config I2C_ALGO8XX
 	tristate "MPC8xx CPM I2C interface"
@@ -210,20 +198,6 @@
 config I2C_IOP3XX
 	tristate "Intel XScale IOP3xx on-chip I2C interface"
 	depends on ARCH_IOP3XX && I2C
-
-config I2C_CHARDEV
-	tristate "I2C device interface"
-	depends on I2C
-	help
-	  Say Y here to use i2c-* device files, usually found in the /dev
-	  directory on your system.  They make it possible to have user-space
-	  programs use the I2C bus.  Information on how to do this is
-	  contained in the file <file:Documentation/i2c/dev-interface>.
-
-	  This code is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-dev.
 
 	source drivers/i2c/busses/Kconfig
 	source drivers/i2c/chips/Kconfig


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                             ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.16, 2003/09/22 13:10:15-07:00, greg@kroah.com

[PATCH] I2C: fix up dependancies in the i2c/busses/Kconfig file


 drivers/i2c/busses/Kconfig |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:27 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:27 2003
@@ -64,7 +64,7 @@
 
 config I2C_I810
 	tristate "Intel 810/815"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  810/815 family of mainboard I2C interfaces.  Specifically, the 
@@ -129,7 +129,7 @@
 
 config I2C_SAVAGE4
 	tristate "S3 Savage 4"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  S3 Savage 4 I2C interface.
@@ -176,7 +176,7 @@
 
 config I2C_VIA
 	tristate "VIA 82C58B"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 
 	  If you say yes to this option, support will be included for the VIA
@@ -205,7 +205,7 @@
 
 config I2C_VOODOO3
 	tristate "Voodoo 3"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 
 	  If you say yes to this option, support will be included for the


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                           ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.15, 2003/09/22 13:06:04-07:00, greg@kroah.com

[PATCH] I2C: clean up i2c-prosavage.c driver

Remove direct memory accesses and link up device in the proper place in the
sysfs tree.


 drivers/i2c/busses/i2c-prosavage.c |   54 ++++++++++++-------------------------
 1 files changed, 18 insertions(+), 36 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c	Mon Sep 22 16:13:38 2003
+++ b/drivers/i2c/busses/i2c-prosavage.c	Mon Sep 22 16:13:38 2003
@@ -60,21 +60,14 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 
-#include <asm/io.h>
-
 
 /*
  * driver configuration
  */
-#define	DRIVER_ID	"i2c-prosavage"
-#define	DRIVER_VERSION	"20030621"
-
-#define ADAPTER_NAME(x) (x).name
-
 #define MAX_BUSSES	2
 
 struct s_i2c_bus {
-	u8	*mmvga;
+	void	*mmvga;
 	int	i2c_reg;
 	int	adap_ok;
 	struct i2c_adapter		adap;
@@ -82,7 +75,7 @@
 };
 
 struct s_i2c_chip {
-	u8	*mmio;
+	void	*mmio;
 	struct s_i2c_bus	i2c_bus[MAX_BUSSES];
 };
 
@@ -102,9 +95,6 @@
 /* 
  * S3/VIA 8365/8375 registers
  */
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3		0x5333
-#endif
 #ifndef PCI_DEVICE_ID_S3_SAVAGE4
 #define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
 #endif
@@ -126,9 +116,9 @@
 #define I2C_SCL_IN	0x04
 #define I2C_SDA_IN	0x08
 
-#define SET_CR_IX(p, val)	*((p)->mmvga + VGA_CR_IX) = (u8)(val)
-#define SET_CR_DATA(p, val)	*((p)->mmvga + VGA_CR_DATA) = (u8)(val)
-#define GET_CR_DATA(p)		*((p)->mmvga + VGA_CR_DATA)
+#define SET_CR_IX(p, val)	writeb((val), (p)->mmvga + VGA_CR_IX)
+#define SET_CR_DATA(p, val)	writeb((val), (p)->mmvga + VGA_CR_DATA)
+#define GET_CR_DATA(p)		readb((p)->mmvga + VGA_CR_DATA)
 
 
 /*
@@ -190,12 +180,13 @@
 /*
  * adapter initialisation
  */
-static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
 {
 	int ret;
 	p->adap.owner	  = THIS_MODULE;
 	p->adap.id	  = I2C_HW_B_S3VIA;
 	p->adap.algo_data = &p->algo;
+	p->adap.dev.parent = &dev->dev;
 	p->algo.setsda	  = bit_s3via_setsda;
 	p->algo.setscl	  = bit_s3via_setscl;
 	p->algo.getsda	  = bit_s3via_getsda;
@@ -236,8 +227,8 @@
 
 		ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
 	        if (ret) {
-			printk(DRIVER_ID ": %s not removed\n",
-				ADAPTER_NAME(chip->i2c_bus[i].adap));
+			dev_err(&dev->dev, ": %s not removed\n",
+				chip->i2c_bus[i].adap.name);
 		}
 	}
 	if (chip->mmio) {
@@ -270,7 +261,7 @@
 	chip->mmio = ioremap_nocache(base, len);
 
 	if (chip->mmio == NULL) {
-		printk (DRIVER_ID ": ioremap failed\n");
+		dev_err(&dev->dev, "ioremap failed\n");
 		prosavage_remove(dev);
 		return -ENODEV;
 	}
@@ -286,10 +277,10 @@
 	 * i2c bus registration
 	 */
 	bus = &chip->i2c_bus[0];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage I2C bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1);
 	if (ret) {
 		goto err_adap;
 	}
@@ -297,16 +288,16 @@
 	 * ddc bus registration
 	 */
 	bus = &chip->i2c_bus[1];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage DDC bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2);
 	if (ret) {
 		goto err_adap;
 	}
 	return 0;
 err_adap:
-	printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap));
+	dev_err(&dev->dev, ": %s failed\n", bus->adap.name);
 	prosavage_remove(dev);
 	return ret;
 }
@@ -316,17 +307,9 @@
  * Data for PCI driver interface
  */
 static struct pci_device_id prosavage_pci_tbl[] = {
-   {
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_SAVAGE4,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_PROSAVAGE8,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{ 0, }
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SAVAGE4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_PROSAVAGE8) },
+	{ 0, },
 };
 
 static struct pci_driver prosavage_driver = {
@@ -338,7 +321,6 @@
 
 static int __init i2c_prosavage_init(void)
 {
-	printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION);
 	return pci_module_init(&prosavage_driver);
 }
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                               ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.17, 2003/09/22 13:20:35-07:00, greg@kroah.com

[PATCH] I2C: move the i2c-philips-par driver to drivers/i2c/busses


 drivers/i2c/i2c-philips-par.c        |  256 -----------------------------------
 drivers/i2c/Kconfig                  |   10 -
 drivers/i2c/Makefile                 |    1 
 drivers/i2c/busses/Kconfig           |    9 +
 drivers/i2c/busses/Makefile          |    1 
 drivers/i2c/busses/i2c-philips-par.c |  256 +++++++++++++++++++++++++++++++++++
 6 files changed, 266 insertions(+), 267 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:13:17 2003
@@ -48,16 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_PHILIPSPAR
-	tristate "Philips style parallel port adapter"
-	depends on I2C_ALGOBIT && PARPORT
-	---help---
-	  This supports parallel-port I2C adapters made by Philips.  Say Y if
-	  you own such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-philips-par.
-
 config I2C_ELV
 	tristate "ELV adapter"
 	depends on I2C_ALGOBIT && ISA
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:13:17 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:17 2003
@@ -97,6 +97,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-nforce2.
 
+config I2C_PHILIPSPAR
+	tristate "Philips style parallel port adapter"
+	depends on I2C_ALGOBIT && PARPORT
+	help
+	  This supports parallel-port I2C adapters made by Philips.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-philips-par.
+
 config I2C_PIIX4
 	tristate "Intel PIIX4"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:17 2003
@@ -10,6 +10,7 @@
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
+obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
diff -Nru a/drivers/i2c/busses/i2c-philips-par.c b/drivers/i2c/busses/i2c-philips-par.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-philips-par.c	Mon Sep 22 16:13:17 2003
@@ -0,0 +1,256 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-philips-par.c i2c-hw access for philips style parallel port adapters  */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-2000 Simon G. 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.		     */
+/* ------------------------------------------------------------------------- */ 
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+/* $Id: i2c-philips-par.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/parport.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+static int type;
+
+struct i2c_par
+{
+	struct pardevice *pdev;
+	struct i2c_adapter adapter;
+	struct i2c_algo_bit_data bit_lp_data;
+	struct i2c_par *next;
+};
+
+static struct i2c_par *adapter_list;
+
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+
+/* ----- printer port defines ------------------------------------------*/
+					/* Pin Port  Inverted	name	*/
+#define I2C_ON		0x20		/* 12 status N	paper		*/
+					/* ... only for phil. not used  */
+#define I2C_SDA		0x80		/*  9 data   N	data7		*/
+#define I2C_SCL		0x08		/* 17 ctrl   N	dsel		*/
+
+#define I2C_SDAIN	0x80		/* 11 stat   Y	busy		*/
+#define I2C_SCLIN	0x08		/* 15 stat   Y	enable		*/
+
+#define I2C_DMASK	0x7f
+#define I2C_CMASK	0xf7
+
+/* ----- local functions ----------------------------------------------	*/
+
+static void bit_lp_setscl(void *data, int state)
+{
+	/*be cautious about state of the control register - 
+		touch only the one bit needed*/
+	if (state) {
+		parport_write_control((struct parport *) data,
+		      parport_read_control((struct parport *) data)|I2C_SCL);
+	} else {
+		parport_write_control((struct parport *) data,
+		      parport_read_control((struct parport *) data)&I2C_CMASK);
+	}
+}
+
+static void bit_lp_setsda(void *data, int state)
+{
+	if (state) {
+		parport_write_data((struct parport *) data, I2C_DMASK);
+	} else {
+		parport_write_data((struct parport *) data, I2C_SDA);
+	}
+}
+
+static int bit_lp_getscl(void *data)
+{
+	return parport_read_status((struct parport *) data) & I2C_SCLIN;
+}
+
+static int bit_lp_getsda(void *data)
+{
+	return parport_read_status((struct parport *) data) & I2C_SDAIN;
+}
+
+static void bit_lp_setscl2(void *data, int state)
+{
+	if (state) {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)|0x1);
+	} else {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)&0xfe);
+	}
+}
+
+static void bit_lp_setsda2(void *data, int state)
+{
+	if (state) {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)|0x2);
+	} else {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)&0xfd);
+	}
+}
+
+static int bit_lp_getsda2(void *data)
+{
+	return (parport_read_status((struct parport *) data) & 
+			             PARPORT_STATUS_BUSY) ? 0 : 1;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+ 
+static struct i2c_algo_bit_data bit_lp_data = {
+	.setsda		= bit_lp_setsda,
+	.setscl		= bit_lp_setscl,
+	.getsda		= bit_lp_getsda,
+	.getscl		= bit_lp_getscl,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+}; 
+
+static struct i2c_algo_bit_data bit_lp_data2 = {
+	.setsda		= bit_lp_setsda2,
+	.setscl		= bit_lp_setscl2,
+	.getsda		= bit_lp_getsda2,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+}; 
+
+static struct i2c_adapter bit_lp_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_B_LP,
+	.name		= "Philips Parallel port adapter",
+};
+
+static void i2c_parport_attach (struct parport *port)
+{
+	struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par),
+					  GFP_KERNEL);
+	if (!adapter) {
+		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
+		return;
+	}
+
+	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
+
+	adapter->pdev = parport_register_device(port, "i2c-philips-par",
+						NULL, NULL, NULL, 
+						PARPORT_FLAG_EXCL,
+						NULL);
+	if (!adapter->pdev) {
+		printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
+		kfree(adapter);
+		return;
+	}
+
+	adapter->adapter = bit_lp_ops;
+	adapter->adapter.algo_data = &adapter->bit_lp_data;
+	adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data;
+	adapter->bit_lp_data.data = port;
+
+	if (parport_claim_or_block(adapter->pdev) < 0 ) {
+		printk(KERN_ERR "i2c-philips-par: Could not claim parallel port.\n");
+		kfree(adapter);
+		return;
+	}
+	/* reset hardware to sane state */
+	bit_lp_setsda(port, 1);
+	bit_lp_setscl(port, 1);
+	parport_release(adapter->pdev);
+
+	if (i2c_bit_add_bus(&adapter->adapter) < 0)
+	{
+		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
+		parport_unregister_device(adapter->pdev);
+		kfree(adapter);
+		return;		/* No good */
+	}
+
+	adapter->next = adapter_list;
+	adapter_list = adapter;
+}
+
+static void i2c_parport_detach (struct parport *port)
+{
+	struct i2c_par *adapter, *prev = NULL;
+
+	for (adapter = adapter_list; adapter; adapter = adapter->next)
+	{
+		if (adapter->pdev->port == port)
+		{
+			parport_unregister_device(adapter->pdev);
+			i2c_bit_del_bus(&adapter->adapter);
+			if (prev)
+				prev->next = adapter->next;
+			else
+				adapter_list = adapter->next;
+			kfree(adapter);
+			return;
+		}
+		prev = adapter;
+	}
+}
+
+
+static struct parport_driver i2c_driver = {
+	"i2c-philips-par",
+	i2c_parport_attach,
+	i2c_parport_detach,
+	NULL
+};
+
+int __init i2c_bitlp_init(void)
+{
+	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+
+	parport_register_driver(&i2c_driver);
+	
+	return 0;
+}
+
+void __exit i2c_bitlp_exit(void)
+{
+	parport_unregister_driver(&i2c_driver);
+}
+
+MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(type, "i");
+
+module_init(i2c_bitlp_init);
+module_exit(i2c_bitlp_exit);
diff -Nru a/drivers/i2c/i2c-philips-par.c b/drivers/i2c/i2c-philips-par.c
--- a/drivers/i2c/i2c-philips-par.c	Mon Sep 22 16:13:17 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,256 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-philips-par.c i2c-hw access for philips style parallel port adapters  */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-2000 Simon G. 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.		     */
-/* ------------------------------------------------------------------------- */ 
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* $Id: i2c-philips-par.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/stddef.h>
-#include <linux/parport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-static int type;
-
-struct i2c_par
-{
-	struct pardevice *pdev;
-	struct i2c_adapter adapter;
-	struct i2c_algo_bit_data bit_lp_data;
-	struct i2c_par *next;
-};
-
-static struct i2c_par *adapter_list;
-
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-
-/* ----- printer port defines ------------------------------------------*/
-					/* Pin Port  Inverted	name	*/
-#define I2C_ON		0x20		/* 12 status N	paper		*/
-					/* ... only for phil. not used  */
-#define I2C_SDA		0x80		/*  9 data   N	data7		*/
-#define I2C_SCL		0x08		/* 17 ctrl   N	dsel		*/
-
-#define I2C_SDAIN	0x80		/* 11 stat   Y	busy		*/
-#define I2C_SCLIN	0x08		/* 15 stat   Y	enable		*/
-
-#define I2C_DMASK	0x7f
-#define I2C_CMASK	0xf7
-
-/* ----- local functions ----------------------------------------------	*/
-
-static void bit_lp_setscl(void *data, int state)
-{
-	/*be cautious about state of the control register - 
-		touch only the one bit needed*/
-	if (state) {
-		parport_write_control((struct parport *) data,
-		      parport_read_control((struct parport *) data)|I2C_SCL);
-	} else {
-		parport_write_control((struct parport *) data,
-		      parport_read_control((struct parport *) data)&I2C_CMASK);
-	}
-}
-
-static void bit_lp_setsda(void *data, int state)
-{
-	if (state) {
-		parport_write_data((struct parport *) data, I2C_DMASK);
-	} else {
-		parport_write_data((struct parport *) data, I2C_SDA);
-	}
-}
-
-static int bit_lp_getscl(void *data)
-{
-	return parport_read_status((struct parport *) data) & I2C_SCLIN;
-}
-
-static int bit_lp_getsda(void *data)
-{
-	return parport_read_status((struct parport *) data) & I2C_SDAIN;
-}
-
-static void bit_lp_setscl2(void *data, int state)
-{
-	if (state) {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)|0x1);
-	} else {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)&0xfe);
-	}
-}
-
-static void bit_lp_setsda2(void *data, int state)
-{
-	if (state) {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)|0x2);
-	} else {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)&0xfd);
-	}
-}
-
-static int bit_lp_getsda2(void *data)
-{
-	return (parport_read_status((struct parport *) data) & 
-			             PARPORT_STATUS_BUSY) ? 0 : 1;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
- 
-static struct i2c_algo_bit_data bit_lp_data = {
-	.setsda		= bit_lp_setsda,
-	.setscl		= bit_lp_setscl,
-	.getsda		= bit_lp_getsda,
-	.getscl		= bit_lp_getscl,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-}; 
-
-static struct i2c_algo_bit_data bit_lp_data2 = {
-	.setsda		= bit_lp_setsda2,
-	.setscl		= bit_lp_setscl2,
-	.getsda		= bit_lp_getsda2,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-}; 
-
-static struct i2c_adapter bit_lp_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_LP,
-	.name		= "Philips Parallel port adapter",
-};
-
-static void i2c_parport_attach (struct parport *port)
-{
-	struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par),
-					  GFP_KERNEL);
-	if (!adapter) {
-		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
-		return;
-	}
-
-	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
-
-	adapter->pdev = parport_register_device(port, "i2c-philips-par",
-						NULL, NULL, NULL, 
-						PARPORT_FLAG_EXCL,
-						NULL);
-	if (!adapter->pdev) {
-		printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
-		kfree(adapter);
-		return;
-	}
-
-	adapter->adapter = bit_lp_ops;
-	adapter->adapter.algo_data = &adapter->bit_lp_data;
-	adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data;
-	adapter->bit_lp_data.data = port;
-
-	if (parport_claim_or_block(adapter->pdev) < 0 ) {
-		printk(KERN_ERR "i2c-philips-par: Could not claim parallel port.\n");
-		kfree(adapter);
-		return;
-	}
-	/* reset hardware to sane state */
-	bit_lp_setsda(port, 1);
-	bit_lp_setscl(port, 1);
-	parport_release(adapter->pdev);
-
-	if (i2c_bit_add_bus(&adapter->adapter) < 0)
-	{
-		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
-		parport_unregister_device(adapter->pdev);
-		kfree(adapter);
-		return;		/* No good */
-	}
-
-	adapter->next = adapter_list;
-	adapter_list = adapter;
-}
-
-static void i2c_parport_detach (struct parport *port)
-{
-	struct i2c_par *adapter, *prev = NULL;
-
-	for (adapter = adapter_list; adapter; adapter = adapter->next)
-	{
-		if (adapter->pdev->port == port)
-		{
-			parport_unregister_device(adapter->pdev);
-			i2c_bit_del_bus(&adapter->adapter);
-			if (prev)
-				prev->next = adapter->next;
-			else
-				adapter_list = adapter->next;
-			kfree(adapter);
-			return;
-		}
-		prev = adapter;
-	}
-}
-
-
-static struct parport_driver i2c_driver = {
-	"i2c-philips-par",
-	i2c_parport_attach,
-	i2c_parport_detach,
-	NULL
-};
-
-int __init i2c_bitlp_init(void)
-{
-	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-	parport_register_driver(&i2c_driver);
-	
-	return 0;
-}
-
-void __exit i2c_bitlp_exit(void)
-{
-	parport_unregister_driver(&i2c_driver);
-}
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(type, "i");
-
-module_init(i2c_bitlp_init);
-module_exit(i2c_bitlp_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                                 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.18, 2003/09/22 13:30:23-07:00, greg@kroah.com

[PATCH] I2C: clean up i2c-philips-par.c driver a bit

Fix bug when registering the i2c_adap as the structure was not set to 0.


 drivers/i2c/busses/i2c-philips-par.c |   33 ++++++++++-----------------------
 1 files changed, 10 insertions(+), 23 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-philips-par.c b/drivers/i2c/busses/i2c-philips-par.c
--- a/drivers/i2c/busses/i2c-philips-par.c	Mon Sep 22 16:13:06 2003
+++ b/drivers/i2c/busses/i2c-philips-par.c	Mon Sep 22 16:13:06 2003
@@ -24,10 +24,8 @@
 /* $Id: i2c-philips-par.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
 
 #include <linux/kernel.h>
-#include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/stddef.h>
 #include <linux/parport.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -45,11 +43,6 @@
 static struct i2c_par *adapter_list;
 
 
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-
 /* ----- printer port defines ------------------------------------------*/
 					/* Pin Port  Inverted	name	*/
 #define I2C_ON		0x20		/* 12 status N	paper		*/
@@ -163,8 +156,9 @@
 		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
 		return;
 	}
+	memset (adapter, 0x00, sizeof(struct i2c_par));
 
-	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
+	/* printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name); */
 
 	adapter->pdev = parport_register_device(port, "i2c-philips-par",
 						NULL, NULL, NULL, 
@@ -191,8 +185,7 @@
 	bit_lp_setscl(port, 1);
 	parport_release(adapter->pdev);
 
-	if (i2c_bit_add_bus(&adapter->adapter) < 0)
-	{
+	if (i2c_bit_add_bus(&adapter->adapter) < 0) {
 		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
 		parport_unregister_device(adapter->pdev);
 		kfree(adapter);
@@ -207,10 +200,8 @@
 {
 	struct i2c_par *adapter, *prev = NULL;
 
-	for (adapter = adapter_list; adapter; adapter = adapter->next)
-	{
-		if (adapter->pdev->port == port)
-		{
+	for (adapter = adapter_list; adapter; adapter = adapter->next) {
+		if (adapter->pdev->port == port) {
 			parport_unregister_device(adapter->pdev);
 			i2c_bit_del_bus(&adapter->adapter);
 			if (prev)
@@ -224,21 +215,17 @@
 	}
 }
 
-
 static struct parport_driver i2c_driver = {
-	"i2c-philips-par",
-	i2c_parport_attach,
-	i2c_parport_detach,
-	NULL
+	.name =		"i2c-philips-par",
+	.attach =	i2c_parport_attach,
+	.detach =	i2c_parport_detach,
 };
 
 int __init i2c_bitlp_init(void)
 {
-	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c Philips parallel port adapter driver\n");
 
-	parport_register_driver(&i2c_driver);
-	
-	return 0;
+	return parport_register_driver(&i2c_driver);
 }
 
 void __exit i2c_bitlp_exit(void)


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                                     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.20, 2003/09/22 13:44:13-07:00, greg@kroah.com

[PATCH] I2C: clean up the i2c-elv.c driver a bit


 drivers/i2c/busses/i2c-elv.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-elv.c b/drivers/i2c/busses/i2c-elv.c
--- a/drivers/i2c/busses/i2c-elv.c	Mon Sep 22 16:12:46 2003
+++ b/drivers/i2c/busses/i2c-elv.c	Mon Sep 22 16:12:46 2003
@@ -21,8 +21,6 @@
 /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elv.c,v 1.27 2003/01/21 08:08:16 kmalkki Exp $ */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -36,7 +34,7 @@
 
 #define DEFAULT_BASE 0x378
 static int base=0;
-static unsigned char PortData = 0;
+static unsigned char port_data = 0;
 
 /* ----- global defines -----------------------------------------------	*/
 #define DEB(x)		/* should be reasonable open, close &c. 	*/
@@ -57,21 +55,21 @@
 static void bit_elv_setscl(void *data, int state)
 {
 	if (state) {
-		PortData &= 0xfe;
+		port_data &= 0xfe;
 	} else {
-		PortData |=1;
+		port_data |=1;
 	}
-	outb(PortData, DATA);
+	outb(port_data, DATA);
 }
 
 static void bit_elv_setsda(void *data, int state)
 {
 	if (state) {
-		PortData &=0xfd;
+		port_data &=0xfd;
 	} else {
-		PortData |=2;
+		port_data |=2;
 	}
-	outb(PortData, DATA);
+	outb(port_data, DATA);
 } 
 
 static int bit_elv_getscl(void *data)
@@ -103,7 +101,7 @@
 		goto fail;
 	}
 
-	PortData = 0;
+	port_data = 0;
 	bit_elv_setsda((void*)base,1);
 	bit_elv_setscl((void*)base,1);
 	return 0;
@@ -129,14 +127,13 @@
 
 static struct i2c_adapter bit_elv_ops = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_ELV,
 	.algo_data	= &bit_elv_data,
 	.name		= "ELV Parallel port adaptor",
 };
 
 static int __init i2c_bitelv_init(void)
 {
-	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c ELV parallel port adapter driver\n");
 	if (base==0) {
 		/* probe some values */
 		base=DEFAULT_BASE;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                                   ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.19, 2003/09/22 13:36:52-07:00, greg@kroah.com

[PATCH] I2C: move i2c-elv.c driver to drivers/i2c/busses


 drivers/i2c/i2c-elv.c        |  176 -------------------------------------------
 drivers/i2c/Kconfig          |   10 --
 drivers/i2c/Makefile         |    1 
 drivers/i2c/busses/Kconfig   |   10 ++
 drivers/i2c/busses/Makefile  |    1 
 drivers/i2c/busses/i2c-elv.c |  176 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 187 insertions(+), 187 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:56 2003
@@ -48,16 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_ELV
-	tristate "ELV adapter"
-	depends on I2C_ALGOBIT && ISA
-	help
-	  This supports parallel-port I2C adapters called ELV.  Say Y if you
-	  own such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-elv.
-
 config I2C_VELLEMAN
 	tristate "Velleman K9000 adapter"
 	depends on I2C_ALGOBIT && ISA
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:56 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:56 2003
@@ -46,6 +46,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-amd8111.
 
+config I2C_ELV
+	tristate "ELV adapter"
+	depends on I2C_ALGOBIT && ISA
+	help
+	  This supports parallel-port I2C adapters called ELV.  Say Y if you
+	  own such an adapter.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elv.
+
 config I2C_I801
 	tristate "Intel 801"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:56 2003
@@ -6,6 +6,7 @@
 obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
+obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
diff -Nru a/drivers/i2c/busses/i2c-elv.c b/drivers/i2c/busses/i2c-elv.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-elv.c	Mon Sep 22 16:12:56 2003
@@ -0,0 +1,176 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-elv.c i2c-hw access for philips style parallel port adapters	     */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-2000 Simon G. 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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+/* $Id: i2c-elv.c,v 1.27 2003/01/21 08:08:16 kmalkki Exp $ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/io.h>
+
+#define DEFAULT_BASE 0x378
+static int base=0;
+static unsigned char PortData = 0;
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+#define DEBINIT(x) x	/* detection status messages			*/
+
+/* --- Convenience defines for the parallel port:			*/
+#define BASE	(unsigned int)(data)
+#define DATA	BASE			/* Centronics data port		*/
+#define STAT	(BASE+1)		/* Centronics status port	*/
+#define CTRL	(BASE+2)		/* Centronics control port	*/
+
+
+/* ----- local functions ----------------------------------------------	*/
+
+
+static void bit_elv_setscl(void *data, int state)
+{
+	if (state) {
+		PortData &= 0xfe;
+	} else {
+		PortData |=1;
+	}
+	outb(PortData, DATA);
+}
+
+static void bit_elv_setsda(void *data, int state)
+{
+	if (state) {
+		PortData &=0xfd;
+	} else {
+		PortData |=2;
+	}
+	outb(PortData, DATA);
+} 
+
+static int bit_elv_getscl(void *data)
+{
+	return ( 0 == ( (inb_p(STAT)) & 0x08 ) );
+}
+
+static int bit_elv_getsda(void *data)
+{
+	return ( 0 == ( (inb_p(STAT)) & 0x40 ) );
+}
+
+static int bit_elv_init(void)
+{
+	if (!request_region(base, (base == 0x3bc) ? 3 : 8,
+				"i2c (ELV adapter)"))
+		return -ENODEV;
+
+	if (inb(base+1) & 0x80) {	/* BUSY should be high	*/
+		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
+		goto fail;
+	} 
+
+	outb(0x0c,base+2);	/* SLCT auf low		*/
+	udelay(400);
+	if (!(inb(base+1) && 0x10)) {
+		outb(0x04,base+2);
+		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
+		goto fail;
+	}
+
+	PortData = 0;
+	bit_elv_setsda((void*)base,1);
+	bit_elv_setscl((void*)base,1);
+	return 0;
+
+fail:
+	release_region(base , (base == 0x3bc) ? 3 : 8);
+	return -ENODEV;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_bit_data bit_elv_data = {
+	.setsda		= bit_elv_setsda,
+	.setscl		= bit_elv_setscl,
+	.getsda		= bit_elv_getsda,
+	.getscl		= bit_elv_getscl,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter bit_elv_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_B_ELV,
+	.algo_data	= &bit_elv_data,
+	.name		= "ELV Parallel port adaptor",
+};
+
+static int __init i2c_bitelv_init(void)
+{
+	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	if (base==0) {
+		/* probe some values */
+		base=DEFAULT_BASE;
+		bit_elv_data.data=(void*)DEFAULT_BASE;
+		if (bit_elv_init()==0) {
+			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	} else {
+		i2c_set_adapdata(&bit_elv_ops, (void *)base);
+		if (bit_elv_init()==0) {
+			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	}
+	printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base);
+	return 0;
+}
+
+static void __exit i2c_bitelv_exit(void)
+{
+	i2c_bit_del_bus(&bit_elv_ops);
+	release_region(base , (base == 0x3bc) ? 3 : 8);
+}
+
+MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+
+module_init(i2c_bitelv_init);
+module_exit(i2c_bitelv_exit);
diff -Nru a/drivers/i2c/i2c-elv.c b/drivers/i2c/i2c-elv.c
--- a/drivers/i2c/i2c-elv.c	Mon Sep 22 16:12:56 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,176 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-elv.c i2c-hw access for philips style parallel port adapters	     */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-2000 Simon G. 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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* $Id: i2c-elv.c,v 1.27 2003/01/21 08:08:16 kmalkki Exp $ */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-#define DEFAULT_BASE 0x378
-static int base=0;
-static unsigned char PortData = 0;
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-#define DEBINIT(x) x	/* detection status messages			*/
-
-/* --- Convenience defines for the parallel port:			*/
-#define BASE	(unsigned int)(data)
-#define DATA	BASE			/* Centronics data port		*/
-#define STAT	(BASE+1)		/* Centronics status port	*/
-#define CTRL	(BASE+2)		/* Centronics control port	*/
-
-
-/* ----- local functions ----------------------------------------------	*/
-
-
-static void bit_elv_setscl(void *data, int state)
-{
-	if (state) {
-		PortData &= 0xfe;
-	} else {
-		PortData |=1;
-	}
-	outb(PortData, DATA);
-}
-
-static void bit_elv_setsda(void *data, int state)
-{
-	if (state) {
-		PortData &=0xfd;
-	} else {
-		PortData |=2;
-	}
-	outb(PortData, DATA);
-} 
-
-static int bit_elv_getscl(void *data)
-{
-	return ( 0 == ( (inb_p(STAT)) & 0x08 ) );
-}
-
-static int bit_elv_getsda(void *data)
-{
-	return ( 0 == ( (inb_p(STAT)) & 0x40 ) );
-}
-
-static int bit_elv_init(void)
-{
-	if (!request_region(base, (base == 0x3bc) ? 3 : 8,
-				"i2c (ELV adapter)"))
-		return -ENODEV;
-
-	if (inb(base+1) & 0x80) {	/* BUSY should be high	*/
-		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
-		goto fail;
-	} 
-
-	outb(0x0c,base+2);	/* SLCT auf low		*/
-	udelay(400);
-	if (!(inb(base+1) && 0x10)) {
-		outb(0x04,base+2);
-		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
-		goto fail;
-	}
-
-	PortData = 0;
-	bit_elv_setsda((void*)base,1);
-	bit_elv_setscl((void*)base,1);
-	return 0;
-
-fail:
-	release_region(base , (base == 0x3bc) ? 3 : 8);
-	return -ENODEV;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_bit_data bit_elv_data = {
-	.setsda		= bit_elv_setsda,
-	.setscl		= bit_elv_setscl,
-	.getsda		= bit_elv_getsda,
-	.getscl		= bit_elv_getscl,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-};
-
-static struct i2c_adapter bit_elv_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_ELV,
-	.algo_data	= &bit_elv_data,
-	.name		= "ELV Parallel port adaptor",
-};
-
-static int __init i2c_bitelv_init(void)
-{
-	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-	if (base==0) {
-		/* probe some values */
-		base=DEFAULT_BASE;
-		bit_elv_data.data=(void*)DEFAULT_BASE;
-		if (bit_elv_init()==0) {
-			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	} else {
-		i2c_set_adapdata(&bit_elv_ops, (void *)base);
-		if (bit_elv_init()==0) {
-			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	}
-	printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base);
-	return 0;
-}
-
-static void __exit i2c_bitelv_exit(void)
-{
-	i2c_bit_del_bus(&bit_elv_ops);
-	release_region(base , (base == 0x3bc) ? 3 : 8);
-}
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-
-module_init(i2c_bitelv_init);
-module_exit(i2c_bitelv_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                                       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.21, 2003/09/22 13:57:44-07:00, greg@kroah.com

I2C: move i2c-elektor.c driver to drivers/i2c/busses/


 drivers/i2c/i2c-elektor.c        |  286 ---------------------------------------
 drivers/i2c/Kconfig              |   10 -
 drivers/i2c/Makefile             |    1 
 drivers/i2c/busses/Kconfig       |   10 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-elektor.c |  286 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 297 insertions(+), 297 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:35 2003
@@ -107,16 +107,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-pcf.
 
-config I2C_ELEKTOR
-	tristate "Elektor ISA card"
-	depends on I2C_ALGOPCF && BROKEN_ON_SMP
-	help
-	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
-	  such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-elektor.
-
 config I2C_KEYWEST
 	tristate "Powermac Keywest I2C interface"
 	depends on I2C && PPC_PMAC
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:35 2003
@@ -7,7 +7,6 @@
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
-obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
 obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:35 2003
@@ -46,6 +46,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-amd8111.
 
+config I2C_ELEKTOR
+	tristate "Elektor ISA card"
+	depends on I2C_ALGOPCF && BROKEN_ON_SMP
+	help
+	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
+	  such an adapter.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elektor.
+
 config I2C_ELV
 	tristate "ELV adapter"
 	depends on I2C_ALGOBIT && ISA
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:35 2003
@@ -6,6 +6,7 @@
 obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
+obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
diff -Nru a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-elektor.c	Mon Sep 22 16:12:35 2003
@@ -0,0 +1,286 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes             */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-97 Simon G. Vogl
+                   1998-99 Hans Berglund
+
+    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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
+   for Alpha Processor Inc. UP-2000(+) boards */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-pcf.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "../i2c-pcf8584.h"
+
+#define DEFAULT_BASE 0x330
+
+static int base;
+static int irq;
+static int clock  = 0x1c;
+static int own    = 0x55;
+static int mmapped;
+static int i2c_debug;
+
+/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
+  this module in real supports only one device, due to missing arguments
+  in some functions, called from the algo-pcf module. Sometimes it's
+  need to be rewriten - but for now just remove this for simpler reading */
+
+static wait_queue_head_t pcf_wait;
+static int pcf_pending;
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)	if (i2c_debug>=1) x
+#define DEB2(x) if (i2c_debug>=2) x
+#define DEB3(x) if (i2c_debug>=3) x
+#define DEBE(x)	x	/* error messages 				*/
+
+/* ----- local functions ----------------------------------------------	*/
+
+static void pcf_isa_setbyte(void *data, int ctl, int val)
+{
+	int address = ctl ? (base + 1) : base;
+
+	/* enable irq if any specified for serial operation */
+	if (ctl && irq && (val & I2C_PCF_ESO)) {
+		val |= I2C_PCF_ENI;
+	}
+
+	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+
+	switch (mmapped) {
+	case 0: /* regular I/O */
+		outb(val, address);
+		break;
+	case 2: /* double mapped I/O needed for UP2000 board,
+                   I don't know why this... */
+		writeb(val, address);
+		/* fall */
+	case 1: /* memory mapped I/O */
+		writeb(val, address);
+		break;
+	}
+}
+
+static int pcf_isa_getbyte(void *data, int ctl)
+{
+	int address = ctl ? (base + 1) : base;
+	int val = mmapped ? readb(address) : inb(address);
+
+	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
+
+	return (val);
+}
+
+static int pcf_isa_getown(void *data)
+{
+	return (own);
+}
+
+
+static int pcf_isa_getclock(void *data)
+{
+	return (clock);
+}
+
+static void pcf_isa_waitforpin(void) {
+
+	int timeout = 2;
+
+	if (irq > 0) {
+		cli();
+		if (pcf_pending == 0) {
+			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
+		} else
+			pcf_pending = 0;
+		sti();
+	} else {
+		udelay(100);
+	}
+}
+
+
+static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
+	pcf_pending = 1;
+	wake_up_interruptible(&pcf_wait);
+	return IRQ_HANDLED;
+}
+
+
+static int pcf_isa_init(void)
+{
+	if (!mmapped) {
+		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
+			printk(KERN_ERR
+			       "i2c-elektor.o: requested I/O region (0x%X:2) "
+			       "is in use.\n", base);
+			return -ENODEV;
+		}
+	}
+	if (irq > 0) {
+		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
+			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
+			irq = 0;
+		} else
+			enable_irq(irq);
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_pcf_data pcf_isa_data = {
+	.setpcf	    = pcf_isa_setbyte,
+	.getpcf	    = pcf_isa_getbyte,
+	.getown	    = pcf_isa_getown,
+	.getclock   = pcf_isa_getclock,
+	.waitforpin = pcf_isa_waitforpin,
+	.udelay	    = 10,
+	.mdelay	    = 10,
+	.timeout    = 100,
+};
+
+static struct i2c_adapter pcf_isa_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_P_ELEK,
+	.algo_data	= &pcf_isa_data,
+	.name		= "PCF8584 ISA adapter",
+};
+
+static int __init i2c_pcfisa_init(void) 
+{
+#ifdef __alpha__
+	/* check to see we have memory mapped PCF8584 connected to the 
+	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
+	if (base == 0) {
+		
+		struct pci_dev *cy693_dev =
+                    pci_find_device(PCI_VENDOR_ID_CONTAQ, 
+		                    PCI_DEVICE_ID_CONTAQ_82C693, NULL);
+
+		if (cy693_dev) {
+			char config;
+			/* yeap, we've found cypress, let's check config */
+			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
+				
+				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+
+				/* UP2000 board has this register set to 0xe1,
+                                   but the most significant bit as seems can be 
+				   reset during the proper initialisation
+                                   sequence if guys from API decides to do that
+                                   (so, we can even enable Tsunami Pchip
+                                   window for the upper 1 Gb) */
+
+				/* so just check for ROMCS at 0xe0000,
+                                   ROMCS enabled for writes
+				   and external XD Bus buffer in use. */
+				if ((config & 0x7f) == 0x61) {
+					/* seems to be UP2000 like board */
+					base = 0xe0000;
+                                        /* I don't know why we need to
+                                           write twice */
+					mmapped = 2;
+                                        /* UP2000 drives ISA with
+					   8.25 MHz (PCI/4) clock
+					   (this can be read from cypress) */
+					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
+					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+				}
+			}
+		}
+	}
+#endif
+
+	/* sanity checks for mmapped I/O */
+	if (mmapped && base < 0xc8000) {
+		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+
+	if (base == 0) {
+		base = DEFAULT_BASE;
+	}
+
+	init_waitqueue_head(&pcf_wait);
+	if (pcf_isa_init())
+		return -ENODEV;
+	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
+		goto fail;
+	
+	printk(KERN_ERR "i2c-elektor.o: found device at %#x.\n", base);
+
+	return 0;
+
+ fail:
+	if (irq > 0) {
+		disable_irq(irq);
+		free_irq(irq, 0);
+	}
+
+	if (!mmapped)
+		release_region(base , 2);
+	return -ENODEV;
+}
+
+static void i2c_pcfisa_exit(void)
+{
+	i2c_pcf_del_bus(&pcf_isa_ops);
+
+	if (irq > 0) {
+		disable_irq(irq);
+		free_irq(irq, 0);
+	}
+
+	if (!mmapped)
+		release_region(base , 2);
+}
+
+MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clock, "i");
+MODULE_PARM(own, "i");
+MODULE_PARM(mmapped, "i");
+MODULE_PARM(i2c_debug, "i");
+
+module_init(i2c_pcfisa_init);
+module_exit(i2c_pcfisa_exit);
diff -Nru a/drivers/i2c/i2c-elektor.c b/drivers/i2c/i2c-elektor.c
--- a/drivers/i2c/i2c-elektor.c	Mon Sep 22 16:12:35 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,286 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes             */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
-   for Alpha Processor Inc. UP-2000(+) boards */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/wait.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-pcf.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "i2c-pcf8584.h"
-
-#define DEFAULT_BASE 0x330
-
-static int base;
-static int irq;
-static int clock  = 0x1c;
-static int own    = 0x55;
-static int mmapped;
-static int i2c_debug;
-
-/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
-  this module in real supports only one device, due to missing arguments
-  in some functions, called from the algo-pcf module. Sometimes it's
-  need to be rewriten - but for now just remove this for simpler reading */
-
-static wait_queue_head_t pcf_wait;
-static int pcf_pending;
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)	if (i2c_debug>=1) x
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x
-#define DEBE(x)	x	/* error messages 				*/
-
-/* ----- local functions ----------------------------------------------	*/
-
-static void pcf_isa_setbyte(void *data, int ctl, int val)
-{
-	int address = ctl ? (base + 1) : base;
-
-	/* enable irq if any specified for serial operation */
-	if (ctl && irq && (val & I2C_PCF_ESO)) {
-		val |= I2C_PCF_ENI;
-	}
-
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
-
-	switch (mmapped) {
-	case 0: /* regular I/O */
-		outb(val, address);
-		break;
-	case 2: /* double mapped I/O needed for UP2000 board,
-                   I don't know why this... */
-		writeb(val, address);
-		/* fall */
-	case 1: /* memory mapped I/O */
-		writeb(val, address);
-		break;
-	}
-}
-
-static int pcf_isa_getbyte(void *data, int ctl)
-{
-	int address = ctl ? (base + 1) : base;
-	int val = mmapped ? readb(address) : inb(address);
-
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
-
-	return (val);
-}
-
-static int pcf_isa_getown(void *data)
-{
-	return (own);
-}
-
-
-static int pcf_isa_getclock(void *data)
-{
-	return (clock);
-}
-
-static void pcf_isa_waitforpin(void) {
-
-	int timeout = 2;
-
-	if (irq > 0) {
-		cli();
-		if (pcf_pending == 0) {
-			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
-		} else
-			pcf_pending = 0;
-		sti();
-	} else {
-		udelay(100);
-	}
-}
-
-
-static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
-	pcf_pending = 1;
-	wake_up_interruptible(&pcf_wait);
-	return IRQ_HANDLED;
-}
-
-
-static int pcf_isa_init(void)
-{
-	if (!mmapped) {
-		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
-			printk(KERN_ERR
-			       "i2c-elektor.o: requested I/O region (0x%X:2) "
-			       "is in use.\n", base);
-			return -ENODEV;
-		}
-	}
-	if (irq > 0) {
-		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
-			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
-			irq = 0;
-		} else
-			enable_irq(irq);
-	}
-	return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_pcf_data pcf_isa_data = {
-	.setpcf	    = pcf_isa_setbyte,
-	.getpcf	    = pcf_isa_getbyte,
-	.getown	    = pcf_isa_getown,
-	.getclock   = pcf_isa_getclock,
-	.waitforpin = pcf_isa_waitforpin,
-	.udelay	    = 10,
-	.mdelay	    = 10,
-	.timeout    = 100,
-};
-
-static struct i2c_adapter pcf_isa_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_P_ELEK,
-	.algo_data	= &pcf_isa_data,
-	.name		= "PCF8584 ISA adapter",
-};
-
-static int __init i2c_pcfisa_init(void) 
-{
-#ifdef __alpha__
-	/* check to see we have memory mapped PCF8584 connected to the 
-	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
-	if (base == 0) {
-		
-		struct pci_dev *cy693_dev =
-                    pci_find_device(PCI_VENDOR_ID_CONTAQ, 
-		                    PCI_DEVICE_ID_CONTAQ_82C693, NULL);
-
-		if (cy693_dev) {
-			char config;
-			/* yeap, we've found cypress, let's check config */
-			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
-				
-				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
-
-				/* UP2000 board has this register set to 0xe1,
-                                   but the most significant bit as seems can be 
-				   reset during the proper initialisation
-                                   sequence if guys from API decides to do that
-                                   (so, we can even enable Tsunami Pchip
-                                   window for the upper 1 Gb) */
-
-				/* so just check for ROMCS at 0xe0000,
-                                   ROMCS enabled for writes
-				   and external XD Bus buffer in use. */
-				if ((config & 0x7f) == 0x61) {
-					/* seems to be UP2000 like board */
-					base = 0xe0000;
-                                        /* I don't know why we need to
-                                           write twice */
-					mmapped = 2;
-                                        /* UP2000 drives ISA with
-					   8.25 MHz (PCI/4) clock
-					   (this can be read from cypress) */
-					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
-					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
-				}
-			}
-		}
-	}
-#endif
-
-	/* sanity checks for mmapped I/O */
-	if (mmapped && base < 0xc8000) {
-		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
-		return -ENODEV;
-	}
-
-	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-	if (base == 0) {
-		base = DEFAULT_BASE;
-	}
-
-	init_waitqueue_head(&pcf_wait);
-	if (pcf_isa_init())
-		return -ENODEV;
-	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
-		goto fail;
-	
-	printk(KERN_ERR "i2c-elektor.o: found device at %#x.\n", base);
-
-	return 0;
-
- fail:
-	if (irq > 0) {
-		disable_irq(irq);
-		free_irq(irq, 0);
-	}
-
-	if (!mmapped)
-		release_region(base , 2);
-	return -ENODEV;
-}
-
-static void i2c_pcfisa_exit(void)
-{
-	i2c_pcf_del_bus(&pcf_isa_ops);
-
-	if (irq > 0) {
-		disable_irq(irq);
-		free_irq(irq, 0);
-	}
-
-	if (!mmapped)
-		release_region(base , 2);
-}
-
-MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(clock, "i");
-MODULE_PARM(own, "i");
-MODULE_PARM(mmapped, "i");
-MODULE_PARM(i2c_debug, "i");
-
-module_init(i2c_pcfisa_init);
-module_exit(i2c_pcfisa_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                                           ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.23, 2003/09/22 14:21:09-07:00, greg@kroah.com

[PATCH] I2C: move the scx200* drivers to drivers/i2c/busses


 drivers/i2c/scx200_acb.c        |  553 ----------------------------------------
 drivers/i2c/scx200_i2c.c        |  133 ---------
 drivers/i2c/Kconfig             |   38 --
 drivers/i2c/Makefile            |    2 
 drivers/i2c/busses/Kconfig      |   38 ++
 drivers/i2c/busses/Makefile     |    2 
 drivers/i2c/busses/scx200_acb.c |  553 ++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/busses/scx200_i2c.c |  132 +++++++++
 8 files changed, 725 insertions(+), 726 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:15 2003
@@ -48,44 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config SCx200_I2C
-	tristate "NatSemi SCx200 I2C using GPIO pins"
-	depends on SCx200 && I2C_ALGOBIT
-	help
-	  Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
-
-	  If you don't know what to do here, say N.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called scx200_i2c.
-
-config SCx200_I2C_SCL
-	int "GPIO pin used for SCL"
-	depends on SCx200_I2C
-	default "12"
-	help
-	  Enter the GPIO pin number used for the SCL signal.  This value can
-	  also be specified with a module parameter.
-
-config SCx200_I2C_SDA
-	int "GPIO pin used for SDA"
-	depends on SCx200_I2C
-	default "13"
-	help
-	  Enter the GPIO pin number used for the SSA signal.  This value can
-	  also be specified with a module parameter.
-
-config SCx200_ACB
-	tristate "NatSemi SCx200 ACCESS.bus"
-	depends on I2C_ALGOBIT!=n && I2C
-	help
-	  Enable the use of the ACCESS.bus controllers of a SCx200 processor.
-
-	  If you don't know what to do here, say N.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called scx200_acb.
-
 config I2C_ALGOPCF
 	tristate "I2C PCF 8584 interfaces"
 	depends on I2C
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:15 2003
@@ -9,8 +9,6 @@
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
 obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
-obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
-obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
 obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
 obj-$(CONFIG_I2C_SENSOR)	+= i2c-sensor.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:15 2003
@@ -166,6 +166,44 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-savage4.
 
+config SCx200_I2C
+	tristate "NatSemi SCx200 I2C using GPIO pins"
+	depends on SCx200 && I2C_ALGOBIT
+	help
+	  Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
+
+	  If you don't know what to do here, say N.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_i2c.
+
+config SCx200_I2C_SCL
+	int "GPIO pin used for SCL"
+	depends on SCx200_I2C
+	default "12"
+	help
+	  Enter the GPIO pin number used for the SCL signal.  This value can
+	  also be specified with a module parameter.
+
+config SCx200_I2C_SDA
+	int "GPIO pin used for SDA"
+	depends on SCx200_I2C
+	default "13"
+	help
+	  Enter the GPIO pin number used for the SSA signal.  This value can
+	  also be specified with a module parameter.
+
+config SCx200_ACB
+	tristate "NatSemi SCx200 ACCESS.bus"
+	depends on I2C_ALGOBIT!=n && I2C
+	help
+	  Enable the use of the ACCESS.bus controllers of a SCx200 processor.
+
+	  If you don't know what to do here, say N.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_acb.
+
 config I2C_SIS5595
 	tristate "SiS 5595"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:15 2003
@@ -23,3 +23,5 @@
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
+obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
+obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
diff -Nru a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/scx200_acb.c	Mon Sep 22 16:12:15 2003
@@ -0,0 +1,553 @@
+/*  linux/drivers/i2c/scx200_acb.c 
+
+    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
+
+    National Semiconductor SCx200 ACCESS.bus support
+    
+    Based on i2c-keywest.c which is:
+        Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+        Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+    
+    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/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/smp_lock.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#include <linux/scx200.h>
+
+#define NAME "scx200_acb"
+
+MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
+MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
+MODULE_LICENSE("GPL");
+
+#define MAX_DEVICES 4
+static int base[MAX_DEVICES] = { 0x840 };
+MODULE_PARM(base, "1-4i");
+MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
+
+#define DEBUG 0
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG NAME ": " x)
+#else
+#define DBG(x...)
+#endif
+
+/* The hardware supports interrupt driven mode too, but I haven't
+   implemented that. */
+#define POLLED_MODE 1
+#define POLL_TIMEOUT (HZ)
+
+enum scx200_acb_state {
+	state_idle,
+	state_address,
+	state_command,
+	state_repeat_start,
+	state_quick,
+	state_read,
+	state_write,
+};
+
+static const char *scx200_acb_state_name[] = {
+	"idle",
+	"address",
+	"command",
+	"repeat_start",
+	"quick",
+	"read",
+	"write",
+};
+
+/* Physical interface */
+struct scx200_acb_iface
+{
+	struct scx200_acb_iface *next;
+	struct i2c_adapter adapter;
+	unsigned base;
+	struct semaphore sem;
+
+	/* State machine data */
+	enum scx200_acb_state state;
+	int result;
+	u8 address_byte;
+	u8 command;
+	u8 *ptr;
+	char needs_reset;
+	unsigned len;
+};
+
+/* Register Definitions */
+#define ACBSDA		(iface->base + 0)
+#define ACBST		(iface->base + 1)
+#define    ACBST_SDAST		0x40 /* SDA Status */
+#define    ACBST_BER		0x20 
+#define    ACBST_NEGACK		0x10 /* Negative Acknowledge */
+#define    ACBST_STASTR		0x08 /* Stall After Start */
+#define    ACBST_MASTER		0x02
+#define ACBCST		(iface->base + 2)
+#define    ACBCST_BB		0x02
+#define ACBCTL1		(iface->base + 3)
+#define    ACBCTL1_STASTRE	0x80
+#define    ACBCTL1_NMINTE	0x40
+#define	   ACBCTL1_ACK		0x10
+#define	   ACBCTL1_STOP		0x02
+#define	   ACBCTL1_START	0x01
+#define ACBADDR		(iface->base + 4)
+#define ACBCTL2		(iface->base + 5)
+#define    ACBCTL2_ENABLE	0x01
+
+/************************************************************************/
+
+static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
+{
+	const char *errmsg;
+
+	DBG("state %s, status = 0x%02x\n", 
+	    scx200_acb_state_name[iface->state], status);
+
+	if (status & ACBST_BER) {
+		errmsg = "bus error";
+		goto error;
+	}
+	if (!(status & ACBST_MASTER)) {
+		errmsg = "not master";
+		goto error;
+	}
+	if (status & ACBST_NEGACK)
+		goto negack;
+
+	switch (iface->state) {
+	case state_idle:
+		dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
+		break;
+
+	case state_address:
+		/* Do a pointer write first */
+		outb(iface->address_byte & ~1, ACBSDA);
+
+		iface->state = state_command;
+		break;
+
+	case state_command:
+		outb(iface->command, ACBSDA);
+
+		if (iface->address_byte & 1)
+			iface->state = state_repeat_start;
+		else
+			iface->state = state_write;
+		break;
+
+	case state_repeat_start:
+		outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
+		/* fallthrough */
+		
+	case state_quick:
+		if (iface->address_byte & 1) {
+			if (iface->len == 1) 
+				outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
+			else
+				outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
+			outb(iface->address_byte, ACBSDA);
+
+			iface->state = state_read;
+		} else {
+			outb(iface->address_byte, ACBSDA);
+
+			iface->state = state_write;
+		}
+		break;
+
+	case state_read:
+		/* Set ACK if receiving the last byte */
+		if (iface->len == 1)
+			outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
+		else
+			outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
+
+		*iface->ptr++ = inb(ACBSDA);
+		--iface->len;
+
+		if (iface->len == 0) {
+			iface->result = 0;
+			iface->state = state_idle;
+			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+		}
+
+		break;
+
+	case state_write:
+		if (iface->len == 0) {
+			iface->result = 0;
+			iface->state = state_idle;
+			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+			break;
+		}
+		
+		outb(*iface->ptr++, ACBSDA);
+		--iface->len;
+		
+		break;
+	}
+
+	return;
+
+ negack:
+	DBG("negative acknowledge in state %s\n", 
+	    scx200_acb_state_name[iface->state]);
+
+	iface->state = state_idle;
+	iface->result = -ENXIO;
+
+	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+	outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
+	return;
+
+ error:
+	dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
+		scx200_acb_state_name[iface->state]);
+
+	iface->state = state_idle;
+	iface->result = -EIO;
+	iface->needs_reset = 1;
+}
+
+static void scx200_acb_timeout(struct scx200_acb_iface *iface) 
+{
+	dev_err(&iface->adapter.dev, "timeout in state %s\n",
+		scx200_acb_state_name[iface->state]);
+
+	iface->state = state_idle;
+	iface->result = -EIO;
+	iface->needs_reset = 1;
+}
+
+#ifdef POLLED_MODE
+static void scx200_acb_poll(struct scx200_acb_iface *iface)
+{
+	u8 status = 0;
+	unsigned long timeout;
+
+	timeout = jiffies + POLL_TIMEOUT;
+	while (time_before(jiffies, timeout)) {
+		status = inb(ACBST);
+		if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
+			scx200_acb_machine(iface, status);
+			return;
+		}
+		schedule_timeout(HZ/100+1);
+	}
+
+	scx200_acb_timeout(iface);
+}
+#endif /* POLLED_MODE */
+
+static void scx200_acb_reset(struct scx200_acb_iface *iface)
+{
+	/* Disable the ACCESS.bus device and Configure the SCL
+           frequency: 16 clock cycles */
+	outb(0x70, ACBCTL2);
+	/* Polling mode */
+	outb(0, ACBCTL1);
+	/* Disable slave address */
+	outb(0, ACBADDR);
+	/* Enable the ACCESS.bus device */
+	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
+	/* Free STALL after START */
+	outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
+	/* Send a STOP */
+	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+	/* Clear BER, NEGACK and STASTR bits */
+	outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
+	/* Clear BB bit */
+	outb(inb(ACBCST) | ACBCST_BB, ACBCST);
+}
+
+static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
+				u16 address, unsigned short flags,	
+				char rw, u8 command, int size, 
+				union i2c_smbus_data *data)
+{
+	struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
+	int len;
+	u8 *buffer;
+	u16 cur_word;
+	int rc;
+
+	switch (size) {
+	case I2C_SMBUS_QUICK:
+	    	len = 0;
+	    	buffer = NULL;
+	    	break;
+	case I2C_SMBUS_BYTE:
+		if (rw == I2C_SMBUS_READ) {
+			len = 1;
+			buffer = &data->byte;
+		} else {
+			len = 1;
+			buffer = &command;
+		}
+	    	break;
+	case I2C_SMBUS_BYTE_DATA:
+	    	len = 1;
+	    	buffer = &data->byte;
+	    	break;
+	case I2C_SMBUS_WORD_DATA:
+		len = 2;
+	    	cur_word = cpu_to_le16(data->word);
+	    	buffer = (u8 *)&cur_word;
+		break;
+	case I2C_SMBUS_BLOCK_DATA:
+	    	len = data->block[0];
+	    	buffer = &data->block[1];
+		break;
+	default:
+	    	return -EINVAL;
+	}
+
+	DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
+	    size, address, command, len, rw == I2C_SMBUS_READ);
+
+	if (!len && rw == I2C_SMBUS_READ) {
+		dev_warn(&adapter->dev, "zero length read\n");
+		return -EINVAL;
+	}
+
+	if (len && !buffer) {
+		dev_warn(&adapter->dev, "nonzero length but no buffer\n");
+		return -EFAULT;
+	}
+
+	down(&iface->sem);
+
+	iface->address_byte = address<<1;
+	if (rw == I2C_SMBUS_READ)
+		iface->address_byte |= 1;
+	iface->command = command;
+	iface->ptr = buffer;
+	iface->len = len;
+	iface->result = -EINVAL;
+	iface->needs_reset = 0;
+
+	outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
+
+	if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
+		iface->state = state_quick;
+	else
+		iface->state = state_address;
+
+#ifdef POLLED_MODE
+	while (iface->state != state_idle)
+		scx200_acb_poll(iface);
+#else /* POLLED_MODE */
+#error Interrupt driven mode not implemented
+#endif /* POLLED_MODE */	
+
+	if (iface->needs_reset)
+		scx200_acb_reset(iface);
+
+	rc = iface->result;
+
+	up(&iface->sem);
+
+	if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
+	    	data->word = le16_to_cpu(cur_word);
+
+#if DEBUG
+	printk(KERN_DEBUG NAME ": transfer done, result: %d", rc);
+	if (buffer) {
+		int i;
+		printk(" data:");
+		for (i = 0; i < len; ++i)
+			printk(" %02x", buffer[i]);
+	}
+	printk("\n");
+#endif
+
+	return rc;
+}
+
+static u32 scx200_acb_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	       I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+/* For now, we only handle combined mode (smbus) */
+static struct i2c_algorithm scx200_acb_algorithm = {
+	.name		= "NatSemi SCx200 ACCESS.bus",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= scx200_acb_smbus_xfer,
+	.functionality	= scx200_acb_func,
+};
+
+struct scx200_acb_iface *scx200_acb_list;
+
+int scx200_acb_probe(struct scx200_acb_iface *iface)
+{
+	u8 val;
+
+	/* Disable the ACCESS.bus device and Configure the SCL
+           frequency: 16 clock cycles */
+	outb(0x70, ACBCTL2);
+
+	if (inb(ACBCTL2) != 0x70) {
+		DBG("ACBCTL2 readback failed\n");
+		return -ENXIO;
+	}
+
+	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
+
+	val = inb(ACBCTL1);
+	if (val) {
+		DBG("disabled, but ACBCTL1=0x%02x\n", val);
+		return -ENXIO;
+	}
+
+	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
+
+	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
+
+	val = inb(ACBCTL1);
+	if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
+		DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int  __init scx200_acb_create(int base, int index)
+{
+	struct scx200_acb_iface *iface;
+	struct i2c_adapter *adapter;
+	int rc = 0;
+	char description[64];
+
+	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
+	if (!iface) {
+		printk(KERN_ERR NAME ": can't allocate memory\n");
+		rc = -ENOMEM;
+		goto errout;
+	}
+
+	memset(iface, 0, sizeof(*iface));
+	adapter = &iface->adapter;
+	i2c_set_adapdata(adapter, iface);
+	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
+	adapter->owner = THIS_MODULE;
+	adapter->id = I2C_ALGO_SMBUS;
+	adapter->algo = &scx200_acb_algorithm;
+
+	init_MUTEX(&iface->sem);
+
+	snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
+	if (request_region(base, 8, description) == 0) {
+		dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
+			base, base + 8-1);
+		rc = -EBUSY;
+		goto errout;
+	}
+	iface->base = base;
+
+	rc = scx200_acb_probe(iface);
+	if (rc) {
+		dev_warn(&adapter->dev, "probe failed\n");
+		goto errout;
+	}
+
+	scx200_acb_reset(iface);
+
+	if (i2c_add_adapter(adapter) < 0) {
+		dev_err(&adapter->dev, "failed to register\n");
+		rc = -ENODEV;
+		goto errout;
+	}
+
+	lock_kernel();
+	iface->next = scx200_acb_list;
+	scx200_acb_list = iface;
+	unlock_kernel();
+
+	return 0;
+
+ errout:
+	if (iface) {
+		if (iface->base)
+			release_region(iface->base, 8);
+		kfree(iface);
+	}
+	return rc;
+}
+
+static int __init scx200_acb_init(void)
+{
+	int i;
+	int rc;
+
+	printk(KERN_DEBUG NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
+
+	/* Verify that this really is a SCx200 processor */
+	if (pci_find_device(PCI_VENDOR_ID_NS,
+			    PCI_DEVICE_ID_NS_SCx200_BRIDGE,
+			    NULL) == NULL)
+		return -ENODEV;
+
+	rc = -ENXIO;
+	for (i = 0; i < MAX_DEVICES; ++i) {
+		if (base[i] > 0)
+			rc = scx200_acb_create(base[i], i);
+	}
+	if (scx200_acb_list)
+		return 0;
+	return rc;
+}
+
+static void __exit scx200_acb_cleanup(void)
+{
+	struct scx200_acb_iface *iface;
+	lock_kernel();
+	while ((iface = scx200_acb_list) != NULL) {
+		scx200_acb_list = iface->next;
+		unlock_kernel();
+
+		i2c_del_adapter(&iface->adapter);
+		release_region(iface->base, 8);
+		kfree(iface);
+		lock_kernel();
+	}
+	unlock_kernel();
+}
+
+module_init(scx200_acb_init);
+module_exit(scx200_acb_cleanup);
+
+/*
+    Local variables:
+        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
+        c-basic-offset: 8
+    End:
+*/
+
diff -Nru a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/scx200_i2c.c	Mon Sep 22 16:12:15 2003
@@ -0,0 +1,132 @@
+/* linux/drivers/i2c/scx200_i2c.c 
+
+   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
+
+   National Semiconductor SCx200 I2C bus on GPIO pins
+
+   Based on i2c-velleman.c Copyright (C) 1995-96, 2000 Simon G. 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.		     
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/io.h>
+
+#include <linux/scx200_gpio.h>
+
+#define NAME "scx200_i2c"
+
+MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
+MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(scl, "i");
+MODULE_PARM_DESC(scl, "GPIO line for SCL");
+MODULE_PARM(sda, "i");
+MODULE_PARM_DESC(sda, "GPIO line for SDA");
+
+static int scl = CONFIG_SCx200_I2C_SCL;
+static int sda = CONFIG_SCx200_I2C_SDA;
+
+static void scx200_i2c_setscl(void *data, int state)
+{
+	scx200_gpio_set(scl, state);
+}
+
+static void scx200_i2c_setsda(void *data, int state)
+{
+	scx200_gpio_set(sda, state);
+} 
+
+static int scx200_i2c_getscl(void *data)
+{
+	return scx200_gpio_get(scl);
+}
+
+static int scx200_i2c_getsda(void *data)
+{
+	return scx200_gpio_get(sda);
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+
+static struct i2c_algo_bit_data scx200_i2c_data = {
+	NULL,
+	scx200_i2c_setsda,
+	scx200_i2c_setscl,
+	scx200_i2c_getsda,
+	scx200_i2c_getscl,
+	10, 10, 100,		/* waits, timeout */
+};
+
+static struct i2c_adapter scx200_i2c_ops = {
+	.owner		   = THIS_MODULE,
+	.algo_data	   = &scx200_i2c_data,
+	.name	= "NatSemi SCx200 I2C",
+};
+
+int scx200_i2c_init(void)
+{
+	printk(KERN_DEBUG NAME ": NatSemi SCx200 I2C Driver\n");
+
+	if (!scx200_gpio_present()) {
+		printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
+		return -ENODEV;
+	}
+
+	printk(KERN_DEBUG NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", 
+	       scl, sda);
+
+	if (scl == -1 || sda == -1 || scl == sda) {
+		printk(KERN_ERR NAME ": scl and sda must be specified\n");
+		return -EINVAL;
+	}
+
+	/* Configure GPIOs as open collector outputs */
+	scx200_gpio_configure(scl, ~2, 5);
+	scx200_gpio_configure(sda, ~2, 5);
+
+	if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
+		printk(KERN_ERR NAME ": adapter %s registration failed\n", 
+		       scx200_i2c_ops.name);
+		return -ENODEV;
+	}
+	
+	return 0;
+}
+
+void scx200_i2c_cleanup(void)
+{
+	i2c_bit_del_bus(&scx200_i2c_ops);
+}
+
+module_init(scx200_i2c_init);
+module_exit(scx200_i2c_cleanup);
+
+/*
+    Local variables:
+        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
+        c-basic-offset: 8
+    End:
+*/
diff -Nru a/drivers/i2c/scx200_acb.c b/drivers/i2c/scx200_acb.c
--- a/drivers/i2c/scx200_acb.c	Mon Sep 22 16:12:15 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,553 +0,0 @@
-/*  linux/drivers/i2c/scx200_acb.c 
-
-    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
-    National Semiconductor SCx200 ACCESS.bus support
-    
-    Based on i2c-keywest.c which is:
-        Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
-        Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-    
-    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/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/smp_lock.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-
-#include <linux/scx200.h>
-
-#define NAME "scx200_acb"
-
-MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
-MODULE_LICENSE("GPL");
-
-#define MAX_DEVICES 4
-static int base[MAX_DEVICES] = { 0x840 };
-MODULE_PARM(base, "1-4i");
-MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
-
-#define DEBUG 0
-
-#if DEBUG
-#define DBG(x...) printk(KERN_DEBUG NAME ": " x)
-#else
-#define DBG(x...)
-#endif
-
-/* The hardware supports interrupt driven mode too, but I haven't
-   implemented that. */
-#define POLLED_MODE 1
-#define POLL_TIMEOUT (HZ)
-
-enum scx200_acb_state {
-	state_idle,
-	state_address,
-	state_command,
-	state_repeat_start,
-	state_quick,
-	state_read,
-	state_write,
-};
-
-static const char *scx200_acb_state_name[] = {
-	"idle",
-	"address",
-	"command",
-	"repeat_start",
-	"quick",
-	"read",
-	"write",
-};
-
-/* Physical interface */
-struct scx200_acb_iface
-{
-	struct scx200_acb_iface *next;
-	struct i2c_adapter adapter;
-	unsigned base;
-	struct semaphore sem;
-
-	/* State machine data */
-	enum scx200_acb_state state;
-	int result;
-	u8 address_byte;
-	u8 command;
-	u8 *ptr;
-	char needs_reset;
-	unsigned len;
-};
-
-/* Register Definitions */
-#define ACBSDA		(iface->base + 0)
-#define ACBST		(iface->base + 1)
-#define    ACBST_SDAST		0x40 /* SDA Status */
-#define    ACBST_BER		0x20 
-#define    ACBST_NEGACK		0x10 /* Negative Acknowledge */
-#define    ACBST_STASTR		0x08 /* Stall After Start */
-#define    ACBST_MASTER		0x02
-#define ACBCST		(iface->base + 2)
-#define    ACBCST_BB		0x02
-#define ACBCTL1		(iface->base + 3)
-#define    ACBCTL1_STASTRE	0x80
-#define    ACBCTL1_NMINTE	0x40
-#define	   ACBCTL1_ACK		0x10
-#define	   ACBCTL1_STOP		0x02
-#define	   ACBCTL1_START	0x01
-#define ACBADDR		(iface->base + 4)
-#define ACBCTL2		(iface->base + 5)
-#define    ACBCTL2_ENABLE	0x01
-
-/************************************************************************/
-
-static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
-{
-	const char *errmsg;
-
-	DBG("state %s, status = 0x%02x\n", 
-	    scx200_acb_state_name[iface->state], status);
-
-	if (status & ACBST_BER) {
-		errmsg = "bus error";
-		goto error;
-	}
-	if (!(status & ACBST_MASTER)) {
-		errmsg = "not master";
-		goto error;
-	}
-	if (status & ACBST_NEGACK)
-		goto negack;
-
-	switch (iface->state) {
-	case state_idle:
-		dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
-		break;
-
-	case state_address:
-		/* Do a pointer write first */
-		outb(iface->address_byte & ~1, ACBSDA);
-
-		iface->state = state_command;
-		break;
-
-	case state_command:
-		outb(iface->command, ACBSDA);
-
-		if (iface->address_byte & 1)
-			iface->state = state_repeat_start;
-		else
-			iface->state = state_write;
-		break;
-
-	case state_repeat_start:
-		outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
-		/* fallthrough */
-		
-	case state_quick:
-		if (iface->address_byte & 1) {
-			if (iface->len == 1) 
-				outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
-			else
-				outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
-			outb(iface->address_byte, ACBSDA);
-
-			iface->state = state_read;
-		} else {
-			outb(iface->address_byte, ACBSDA);
-
-			iface->state = state_write;
-		}
-		break;
-
-	case state_read:
-		/* Set ACK if receiving the last byte */
-		if (iface->len == 1)
-			outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
-		else
-			outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
-
-		*iface->ptr++ = inb(ACBSDA);
-		--iface->len;
-
-		if (iface->len == 0) {
-			iface->result = 0;
-			iface->state = state_idle;
-			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-		}
-
-		break;
-
-	case state_write:
-		if (iface->len == 0) {
-			iface->result = 0;
-			iface->state = state_idle;
-			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-			break;
-		}
-		
-		outb(*iface->ptr++, ACBSDA);
-		--iface->len;
-		
-		break;
-	}
-
-	return;
-
- negack:
-	DBG("negative acknowledge in state %s\n", 
-	    scx200_acb_state_name[iface->state]);
-
-	iface->state = state_idle;
-	iface->result = -ENXIO;
-
-	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-	outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
-	return;
-
- error:
-	dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
-		scx200_acb_state_name[iface->state]);
-
-	iface->state = state_idle;
-	iface->result = -EIO;
-	iface->needs_reset = 1;
-}
-
-static void scx200_acb_timeout(struct scx200_acb_iface *iface) 
-{
-	dev_err(&iface->adapter.dev, "timeout in state %s\n",
-		scx200_acb_state_name[iface->state]);
-
-	iface->state = state_idle;
-	iface->result = -EIO;
-	iface->needs_reset = 1;
-}
-
-#ifdef POLLED_MODE
-static void scx200_acb_poll(struct scx200_acb_iface *iface)
-{
-	u8 status = 0;
-	unsigned long timeout;
-
-	timeout = jiffies + POLL_TIMEOUT;
-	while (time_before(jiffies, timeout)) {
-		status = inb(ACBST);
-		if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
-			scx200_acb_machine(iface, status);
-			return;
-		}
-		schedule_timeout(HZ/100+1);
-	}
-
-	scx200_acb_timeout(iface);
-}
-#endif /* POLLED_MODE */
-
-static void scx200_acb_reset(struct scx200_acb_iface *iface)
-{
-	/* Disable the ACCESS.bus device and Configure the SCL
-           frequency: 16 clock cycles */
-	outb(0x70, ACBCTL2);
-	/* Polling mode */
-	outb(0, ACBCTL1);
-	/* Disable slave address */
-	outb(0, ACBADDR);
-	/* Enable the ACCESS.bus device */
-	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
-	/* Free STALL after START */
-	outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
-	/* Send a STOP */
-	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-	/* Clear BER, NEGACK and STASTR bits */
-	outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
-	/* Clear BB bit */
-	outb(inb(ACBCST) | ACBCST_BB, ACBCST);
-}
-
-static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
-				u16 address, unsigned short flags,	
-				char rw, u8 command, int size, 
-				union i2c_smbus_data *data)
-{
-	struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
-	int len;
-	u8 *buffer;
-	u16 cur_word;
-	int rc;
-
-	switch (size) {
-	case I2C_SMBUS_QUICK:
-	    	len = 0;
-	    	buffer = NULL;
-	    	break;
-	case I2C_SMBUS_BYTE:
-		if (rw == I2C_SMBUS_READ) {
-			len = 1;
-			buffer = &data->byte;
-		} else {
-			len = 1;
-			buffer = &command;
-		}
-	    	break;
-	case I2C_SMBUS_BYTE_DATA:
-	    	len = 1;
-	    	buffer = &data->byte;
-	    	break;
-	case I2C_SMBUS_WORD_DATA:
-		len = 2;
-	    	cur_word = cpu_to_le16(data->word);
-	    	buffer = (u8 *)&cur_word;
-		break;
-	case I2C_SMBUS_BLOCK_DATA:
-	    	len = data->block[0];
-	    	buffer = &data->block[1];
-		break;
-	default:
-	    	return -EINVAL;
-	}
-
-	DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
-	    size, address, command, len, rw == I2C_SMBUS_READ);
-
-	if (!len && rw == I2C_SMBUS_READ) {
-		dev_warn(&adapter->dev, "zero length read\n");
-		return -EINVAL;
-	}
-
-	if (len && !buffer) {
-		dev_warn(&adapter->dev, "nonzero length but no buffer\n");
-		return -EFAULT;
-	}
-
-	down(&iface->sem);
-
-	iface->address_byte = address<<1;
-	if (rw == I2C_SMBUS_READ)
-		iface->address_byte |= 1;
-	iface->command = command;
-	iface->ptr = buffer;
-	iface->len = len;
-	iface->result = -EINVAL;
-	iface->needs_reset = 0;
-
-	outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
-
-	if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)
-		iface->state = state_quick;
-	else
-		iface->state = state_address;
-
-#ifdef POLLED_MODE
-	while (iface->state != state_idle)
-		scx200_acb_poll(iface);
-#else /* POLLED_MODE */
-#error Interrupt driven mode not implemented
-#endif /* POLLED_MODE */	
-
-	if (iface->needs_reset)
-		scx200_acb_reset(iface);
-
-	rc = iface->result;
-
-	up(&iface->sem);
-
-	if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
-	    	data->word = le16_to_cpu(cur_word);
-
-#if DEBUG
-	printk(KERN_DEBUG NAME ": transfer done, result: %d", rc);
-	if (buffer) {
-		int i;
-		printk(" data:");
-		for (i = 0; i < len; ++i)
-			printk(" %02x", buffer[i]);
-	}
-	printk("\n");
-#endif
-
-	return rc;
-}
-
-static u32 scx200_acb_func(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-	       I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-/* For now, we only handle combined mode (smbus) */
-static struct i2c_algorithm scx200_acb_algorithm = {
-	.name		= "NatSemi SCx200 ACCESS.bus",
-	.id		= I2C_ALGO_SMBUS,
-	.smbus_xfer	= scx200_acb_smbus_xfer,
-	.functionality	= scx200_acb_func,
-};
-
-struct scx200_acb_iface *scx200_acb_list;
-
-int scx200_acb_probe(struct scx200_acb_iface *iface)
-{
-	u8 val;
-
-	/* Disable the ACCESS.bus device and Configure the SCL
-           frequency: 16 clock cycles */
-	outb(0x70, ACBCTL2);
-
-	if (inb(ACBCTL2) != 0x70) {
-		DBG("ACBCTL2 readback failed\n");
-		return -ENXIO;
-	}
-
-	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
-
-	val = inb(ACBCTL1);
-	if (val) {
-		DBG("disabled, but ACBCTL1=0x%02x\n", val);
-		return -ENXIO;
-	}
-
-	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
-
-	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
-
-	val = inb(ACBCTL1);
-	if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
-		DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-static int  __init scx200_acb_create(int base, int index)
-{
-	struct scx200_acb_iface *iface;
-	struct i2c_adapter *adapter;
-	int rc = 0;
-	char description[64];
-
-	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
-	if (!iface) {
-		printk(KERN_ERR NAME ": can't allocate memory\n");
-		rc = -ENOMEM;
-		goto errout;
-	}
-
-	memset(iface, 0, sizeof(*iface));
-	adapter = &iface->adapter;
-	i2c_set_adapdata(adapter, iface);
-	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
-	adapter->owner = THIS_MODULE;
-	adapter->id = I2C_ALGO_SMBUS;
-	adapter->algo = &scx200_acb_algorithm;
-
-	init_MUTEX(&iface->sem);
-
-	snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
-	if (request_region(base, 8, description) == 0) {
-		dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
-			base, base + 8-1);
-		rc = -EBUSY;
-		goto errout;
-	}
-	iface->base = base;
-
-	rc = scx200_acb_probe(iface);
-	if (rc) {
-		dev_warn(&adapter->dev, "probe failed\n");
-		goto errout;
-	}
-
-	scx200_acb_reset(iface);
-
-	if (i2c_add_adapter(adapter) < 0) {
-		dev_err(&adapter->dev, "failed to register\n");
-		rc = -ENODEV;
-		goto errout;
-	}
-
-	lock_kernel();
-	iface->next = scx200_acb_list;
-	scx200_acb_list = iface;
-	unlock_kernel();
-
-	return 0;
-
- errout:
-	if (iface) {
-		if (iface->base)
-			release_region(iface->base, 8);
-		kfree(iface);
-	}
-	return rc;
-}
-
-static int __init scx200_acb_init(void)
-{
-	int i;
-	int rc;
-
-	printk(KERN_DEBUG NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
-
-	/* Verify that this really is a SCx200 processor */
-	if (pci_find_device(PCI_VENDOR_ID_NS,
-			    PCI_DEVICE_ID_NS_SCx200_BRIDGE,
-			    NULL) == NULL)
-		return -ENODEV;
-
-	rc = -ENXIO;
-	for (i = 0; i < MAX_DEVICES; ++i) {
-		if (base[i] > 0)
-			rc = scx200_acb_create(base[i], i);
-	}
-	if (scx200_acb_list)
-		return 0;
-	return rc;
-}
-
-static void __exit scx200_acb_cleanup(void)
-{
-	struct scx200_acb_iface *iface;
-	lock_kernel();
-	while ((iface = scx200_acb_list) != NULL) {
-		scx200_acb_list = iface->next;
-		unlock_kernel();
-
-		i2c_del_adapter(&iface->adapter);
-		release_region(iface->base, 8);
-		kfree(iface);
-		lock_kernel();
-	}
-	unlock_kernel();
-}
-
-module_init(scx200_acb_init);
-module_exit(scx200_acb_cleanup);
-
-/*
-    Local variables:
-        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
-        c-basic-offset: 8
-    End:
-*/
-
diff -Nru a/drivers/i2c/scx200_i2c.c b/drivers/i2c/scx200_i2c.c
--- a/drivers/i2c/scx200_i2c.c	Mon Sep 22 16:12:15 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,133 +0,0 @@
-/* linux/drivers/i2c/scx200_i2c.c 
-
-   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
-   National Semiconductor SCx200 I2C bus on GPIO pins
-
-   Based on i2c-velleman.c Copyright (C) 1995-96, 2000 Simon G. 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.		     
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-#include <linux/scx200_gpio.h>
-
-#define NAME "scx200_i2c"
-
-MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(scl, "i");
-MODULE_PARM_DESC(scl, "GPIO line for SCL");
-MODULE_PARM(sda, "i");
-MODULE_PARM_DESC(sda, "GPIO line for SDA");
-
-static int scl = CONFIG_SCx200_I2C_SCL;
-static int sda = CONFIG_SCx200_I2C_SDA;
-
-static void scx200_i2c_setscl(void *data, int state)
-{
-	scx200_gpio_set(scl, state);
-}
-
-static void scx200_i2c_setsda(void *data, int state)
-{
-	scx200_gpio_set(sda, state);
-} 
-
-static int scx200_i2c_getscl(void *data)
-{
-	return scx200_gpio_get(scl);
-}
-
-static int scx200_i2c_getsda(void *data)
-{
-	return scx200_gpio_get(sda);
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-
-static struct i2c_algo_bit_data scx200_i2c_data = {
-	NULL,
-	scx200_i2c_setsda,
-	scx200_i2c_setscl,
-	scx200_i2c_getsda,
-	scx200_i2c_getscl,
-	10, 10, 100,		/* waits, timeout */
-};
-
-static struct i2c_adapter scx200_i2c_ops = {
-	.owner		   = THIS_MODULE,
-	.id		   = I2C_HW_B_VELLE,
-	.algo_data	   = &scx200_i2c_data,
-	.name	= "NatSemi SCx200 I2C",
-};
-
-int scx200_i2c_init(void)
-{
-	printk(KERN_DEBUG NAME ": NatSemi SCx200 I2C Driver\n");
-
-	if (!scx200_gpio_present()) {
-		printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
-		return -ENODEV;
-	}
-
-	printk(KERN_DEBUG NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", 
-	       scl, sda);
-
-	if (scl == -1 || sda == -1 || scl == sda) {
-		printk(KERN_ERR NAME ": scl and sda must be specified\n");
-		return -EINVAL;
-	}
-
-	/* Configure GPIOs as open collector outputs */
-	scx200_gpio_configure(scl, ~2, 5);
-	scx200_gpio_configure(sda, ~2, 5);
-
-	if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
-		printk(KERN_ERR NAME ": adapter %s registration failed\n", 
-		       scx200_i2c_ops.name);
-		return -ENODEV;
-	}
-	
-	return 0;
-}
-
-void scx200_i2c_cleanup(void)
-{
-	i2c_bit_del_bus(&scx200_i2c_ops);
-}
-
-module_init(scx200_i2c_init);
-module_exit(scx200_i2c_cleanup);
-
-/*
-    Local variables:
-        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
-        c-basic-offset: 8
-    End:
-*/


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24                                                         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.22, 2003/09/22 14:09:17-07:00, greg@kroah.com

[PATCH] I2C: move i2c-velleman driver to drivers/i2c/busses


 drivers/i2c/i2c-velleman.c        |  161 --------------------------------------
 drivers/i2c/Kconfig               |   10 --
 drivers/i2c/Makefile              |    1 
 drivers/i2c/busses/Kconfig        |   10 ++
 drivers/i2c/busses/Makefile       |    1 
 drivers/i2c/busses/i2c-velleman.c |  160 +++++++++++++++++++++++++++++++++++++
 6 files changed, 171 insertions(+), 172 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:26 2003
@@ -48,16 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_VELLEMAN
-	tristate "Velleman K9000 adapter"
-	depends on I2C_ALGOBIT && ISA
-	help
-	  This supports the Velleman K9000 parallel-port I2C adapter.  Say Y
-	  if you own such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-velleman.
-
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins"
 	depends on SCx200 && I2C_ALGOBIT
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:26 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:26 2003
@@ -203,6 +203,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-sis96x.
 
+config I2C_VELLEMAN
+	tristate "Velleman K9000 adapter"
+	depends on I2C_ALGOBIT && ISA
+	help
+	  This supports the Velleman K9000 parallel-port I2C adapter.  Say Y
+	  if you own such an adapter.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-velleman.
+
 config I2C_VIA
 	tristate "VIA 82C58B"
 	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:26 2003
@@ -19,6 +19,7 @@
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
+obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
diff -Nru a/drivers/i2c/busses/i2c-velleman.c b/drivers/i2c/busses/i2c-velleman.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-velleman.c	Mon Sep 22 16:12:26 2003
@@ -0,0 +1,160 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters		     */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-96, 2000 Simon G. 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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* $Id: i2c-velleman.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/io.h>
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+
+					/* Pin Port  Inverted	name	*/
+#define I2C_SDA		0x02		/*  ctrl bit 1 	(inv)	*/
+#define I2C_SCL		0x08		/*  ctrl bit 3 	(inv)	*/
+
+#define I2C_SDAIN	0x10		/* stat bit 4		*/
+#define I2C_SCLIN	0x08		/* ctrl bit 3 (inv)(reads own output)*/
+
+#define I2C_DMASK	0xfd
+#define I2C_CMASK	0xf7
+
+
+/* --- Convenience defines for the parallel port:			*/
+#define BASE	(unsigned int)(data)
+#define DATA	BASE			/* Centronics data port		*/
+#define STAT	(BASE+1)		/* Centronics status port	*/
+#define CTRL	(BASE+2)		/* Centronics control port	*/
+
+#define DEFAULT_BASE 0x378
+static int base=0;
+
+/* ----- local functions --------------------------------------------------- */
+
+static void bit_velle_setscl(void *data, int state)
+{
+	if (state) {
+		outb(inb(CTRL) & I2C_CMASK,   CTRL);
+	} else {
+		outb(inb(CTRL) | I2C_SCL, CTRL);
+	}
+	
+}
+
+static void bit_velle_setsda(void *data, int state)
+{
+	if (state) {
+		outb(inb(CTRL) & I2C_DMASK , CTRL);
+	} else {
+		outb(inb(CTRL) | I2C_SDA, CTRL);
+	}
+	
+} 
+
+static int bit_velle_getscl(void *data)
+{
+	return ( 0 == ( (inb(CTRL)) & I2C_SCLIN ) );
+}
+
+static int bit_velle_getsda(void *data)
+{
+	return ( 0 != ( (inb(STAT)) & I2C_SDAIN ) );
+}
+
+static int bit_velle_init(void)
+{
+	if (!request_region(base, (base == 0x3bc) ? 3 : 8, 
+			"i2c (Vellemann adapter)"))
+		return -ENODEV;
+
+	bit_velle_setsda((void*)base,1);
+	bit_velle_setscl((void*)base,1);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+
+static struct i2c_algo_bit_data bit_velle_data = {
+	.setsda		= bit_velle_setsda,
+	.setscl		= bit_velle_setscl,
+	.getsda		= bit_velle_getsda,
+	.getscl		= bit_velle_getscl,
+	.udelay		= 10,
+	.mdelay		= 10,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter bit_velle_ops = {
+	.owner		= THIS_MODULE,
+	.algo_data	= &bit_velle_data,
+	.name		= "Velleman K8000",
+};
+
+static int __init i2c_bitvelle_init(void)
+{
+	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	if (base==0) {
+		/* probe some values */
+		base=DEFAULT_BASE;
+		bit_velle_data.data=(void*)DEFAULT_BASE;
+		if (bit_velle_init()==0) {
+			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	} else {
+		bit_velle_data.data=(void*)base;
+		if (bit_velle_init()==0) {
+			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	}
+	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
+	return 0;
+}
+
+static void __exit i2c_bitvelle_exit(void)
+{	
+	i2c_bit_del_bus(&bit_velle_ops);
+	release_region(base, (base == 0x3bc) ? 3 : 8);
+}
+
+MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+
+module_init(i2c_bitvelle_init);
+module_exit(i2c_bitvelle_exit);
diff -Nru a/drivers/i2c/i2c-velleman.c b/drivers/i2c/i2c-velleman.c
--- a/drivers/i2c/i2c-velleman.c	Mon Sep 22 16:12:26 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,161 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters		     */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-96, 2000 Simon G. 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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* $Id: i2c-velleman.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-
-					/* Pin Port  Inverted	name	*/
-#define I2C_SDA		0x02		/*  ctrl bit 1 	(inv)	*/
-#define I2C_SCL		0x08		/*  ctrl bit 3 	(inv)	*/
-
-#define I2C_SDAIN	0x10		/* stat bit 4		*/
-#define I2C_SCLIN	0x08		/* ctrl bit 3 (inv)(reads own output)*/
-
-#define I2C_DMASK	0xfd
-#define I2C_CMASK	0xf7
-
-
-/* --- Convenience defines for the parallel port:			*/
-#define BASE	(unsigned int)(data)
-#define DATA	BASE			/* Centronics data port		*/
-#define STAT	(BASE+1)		/* Centronics status port	*/
-#define CTRL	(BASE+2)		/* Centronics control port	*/
-
-#define DEFAULT_BASE 0x378
-static int base=0;
-
-/* ----- local functions --------------------------------------------------- */
-
-static void bit_velle_setscl(void *data, int state)
-{
-	if (state) {
-		outb(inb(CTRL) & I2C_CMASK,   CTRL);
-	} else {
-		outb(inb(CTRL) | I2C_SCL, CTRL);
-	}
-	
-}
-
-static void bit_velle_setsda(void *data, int state)
-{
-	if (state) {
-		outb(inb(CTRL) & I2C_DMASK , CTRL);
-	} else {
-		outb(inb(CTRL) | I2C_SDA, CTRL);
-	}
-	
-} 
-
-static int bit_velle_getscl(void *data)
-{
-	return ( 0 == ( (inb(CTRL)) & I2C_SCLIN ) );
-}
-
-static int bit_velle_getsda(void *data)
-{
-	return ( 0 != ( (inb(STAT)) & I2C_SDAIN ) );
-}
-
-static int bit_velle_init(void)
-{
-	if (!request_region(base, (base == 0x3bc) ? 3 : 8, 
-			"i2c (Vellemann adapter)"))
-		return -ENODEV;
-
-	bit_velle_setsda((void*)base,1);
-	bit_velle_setscl((void*)base,1);
-	return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-
-static struct i2c_algo_bit_data bit_velle_data = {
-	.setsda		= bit_velle_setsda,
-	.setscl		= bit_velle_setscl,
-	.getsda		= bit_velle_getsda,
-	.getscl		= bit_velle_getscl,
-	.udelay		= 10,
-	.mdelay		= 10,
-	.timeout	= HZ
-};
-
-static struct i2c_adapter bit_velle_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_VELLE,
-	.algo_data	= &bit_velle_data,
-	.name		= "Velleman K8000",
-};
-
-static int __init i2c_bitvelle_init(void)
-{
-	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-	if (base==0) {
-		/* probe some values */
-		base=DEFAULT_BASE;
-		bit_velle_data.data=(void*)DEFAULT_BASE;
-		if (bit_velle_init()==0) {
-			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	} else {
-		bit_velle_data.data=(void*)base;
-		if (bit_velle_init()==0) {
-			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	}
-	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
-	return 0;
-}
-
-static void __exit i2c_bitvelle_exit(void)
-{	
-	i2c_bit_del_bus(&bit_velle_ops);
-	release_region(base, (base == 0x3bc) ? 3 : 8);
-}
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-
-module_init(i2c_bitvelle_init);
-module_exit(i2c_bitvelle_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24           ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.26, 2003/09/22 15:24:36-07:00, arvidjaar@mail.ru

[PATCH] I2C: sysfs sensor nameing inconsistency

> That's what you are going to have to set the name file to in the
> i2c_client structure, much like your patch did.  Then look at the
> different name files in each device directory to see what kind of device
> it is (chip, subclient, etc.)

OK attached patch sets all names to just chip name for chips themselves and
"chipname subclient" when subclient ios registered.


 drivers/i2c/chips/adm1021.c |   11 +----------
 drivers/i2c/chips/it87.c    |    3 ---
 drivers/i2c/chips/lm78.c    |    6 +++---
 drivers/i2c/chips/lm85.c    |    6 +-----
 drivers/i2c/chips/via686a.c |    2 +-
 drivers/i2c/chips/w83781d.c |   24 ++++++++++++------------
 6 files changed, 18 insertions(+), 34 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:11:39 2003
+++ b/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:11:39 2003
@@ -225,7 +225,6 @@
 	struct adm1021_data *data;
 	int err = 0;
 	const char *type_name = "";
-	const char *client_name = "";
 
 	/* Make sure we aren't probing the ISA bus!! This is just a safety check
 	   at this moment; i2c_detect really won't call us. */
@@ -291,28 +290,20 @@
 
 	if (kind == max1617) {
 		type_name = "max1617";
-		client_name = "MAX1617 chip";
 	} else if (kind == max1617a) {
 		type_name = "max1617a";
-		client_name = "MAX1617A chip";
 	} else if (kind == adm1021) {
 		type_name = "adm1021";
-		client_name = "ADM1021 chip";
 	} else if (kind == adm1023) {
 		type_name = "adm1023";
-		client_name = "ADM1023 chip";
 	} else if (kind == thmc10) {
 		type_name = "thmc10";
-		client_name = "THMC10 chip";
 	} else if (kind == lm84) {
 		type_name = "lm84";
-		client_name = "LM84 chip";
 	} else if (kind == gl523sm) {
 		type_name = "gl523sm";
-		client_name = "GL523SM chip";
 	} else if (kind == mc1066) {
 		type_name = "mc1066";
-		client_name = "MC1066 chip";
 	} else {
 		dev_err(&adapter->dev, "Internal error: unknown kind (%d)?!?",
 			kind);
@@ -320,7 +311,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	new_client->id = adm1021_id++;
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/it87.c	Mon Sep 22 16:11:40 2003
@@ -592,7 +592,6 @@
 	struct it87_data *data;
 	int err = 0;
 	const char *name = "";
-	const char *client_name = "";
 	int is_isa = i2c_is_isa_adapter(adapter);
 
 	if (!is_isa && 
@@ -681,10 +680,8 @@
 
 	if (kind == it87) {
 		name = "it87";
-		client_name = "IT87 chip";
 	} /* else if (kind == it8712) {
 		name = "it8712";
-		client_name = "IT87-J chip";
 	} */ else {
 		dev_dbg(&adapter->dev, "Internal error: unknown kind (%d)?!?",
 			kind);
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/lm78.c	Mon Sep 22 16:11:40 2003
@@ -625,11 +625,11 @@
 	}
 
 	if (kind == lm78) {
-		client_name = "LM78 chip";
+		client_name = "lm78";
 	} else if (kind == lm78j) {
-		client_name = "LM78-J chip";
+		client_name = "lm78-j";
 	} else if (kind == lm79) {
-		client_name = "LM79 chip";
+		client_name = "lm79";
 	} else {
 		dev_dbg(&adapter->dev, "Internal error: unknown kind (%d)?!?",
 			kind);
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/lm85.c	Mon Sep 22 16:11:40 2003
@@ -853,24 +853,20 @@
 	/* Fill in the chip specific driver values */
 	if ( kind == any_chip ) {
 		type_name = "lm85";
-		strlcpy(new_client->name, "Generic LM85", I2C_NAME_SIZE);
 	} else if ( kind == lm85b ) {
 		type_name = "lm85b";
-		strlcpy(new_client->name, "National LM85-B", I2C_NAME_SIZE);
 	} else if ( kind == lm85c ) {
 		type_name = "lm85c";
-		strlcpy(new_client->name, "National LM85-C", I2C_NAME_SIZE);
 	} else if ( kind == adm1027 ) {
 		type_name = "adm1027";
-		strlcpy(new_client->name, "Analog Devices ADM1027", I2C_NAME_SIZE);
 	} else if ( kind == adt7463 ) {
 		type_name = "adt7463";
-		strlcpy(new_client->name, "Analog Devices ADT7463", I2C_NAME_SIZE);
 	} else {
 		dev_dbg(&adapter->dev, "Internal error, invalid kind (%d)!", kind);
 		err = -EFAULT ;
 		goto ERROR1;
 	}
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
 
 	/* Fill in the remaining client fields */
 	new_client->id = lm85_id++;
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/via686a.c	Mon Sep 22 16:11:40 2003
@@ -671,7 +671,7 @@
 	struct i2c_client *new_client;
 	struct via686a_data *data;
 	int err = 0;
-	const char client_name[] = "via686a chip";
+	const char client_name[] = "via686a";
 	u16 val;
 
 	/* Make sure we are probing the ISA bus!!  */
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:11:39 2003
+++ b/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:11:39 2003
@@ -1098,15 +1098,15 @@
 	}
 
 	if (kind == w83781d)
-		client_name = "W83781D subclient";
+		client_name = "w83781d subclient";
 	else if (kind == w83782d)
-		client_name = "W83782D subclient";
+		client_name = "w83782d subclient";
 	else if (kind == w83783s)
-		client_name = "W83783S subclient";
+		client_name = "w83783s subclient";
 	else if (kind == w83627hf)
-		client_name = "W83627HF subclient";
+		client_name = "w83627hf subclient";
 	else if (kind == as99127f)
-		client_name = "AS99127F subclient";
+		client_name = "as99127f subclient";
 	else
 		client_name = "unknown subclient?";
 
@@ -1304,20 +1304,20 @@
 	}
 
 	if (kind == w83781d) {
-		client_name = "W83781D chip";
+		client_name = "w83781d";
 	} else if (kind == w83782d) {
-		client_name = "W83782D chip";
+		client_name = "w83782d";
 	} else if (kind == w83783s) {
-		client_name = "W83783S chip";
+		client_name = "w83783s";
 	} else if (kind == w83627hf) {
 		if (val1 == 0x90)
-			client_name = "W83627THF chip";
+			client_name = "w83627thf";
 		else
-			client_name = "W83627HF chip";
+			client_name = "w83627hf";
 	} else if (kind == as99127f) {
-		client_name = "AS99127F chip";
+		client_name = "as99127f";
 	} else if (kind == w83697hf) {
-		client_name = "W83697HF chip";
+		client_name = "w83697hf";
 	} else {
 		dev_err(&new_client->dev, "Internal error: unknown "
 						"kind (%d)?!?", kind);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24             ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1381, 2003/09/22 16:03:26-07:00, greg@kroah.com

[PATCH] I2C: remove I2C_VERSION and I2C_DATE as they make no sense in the kernel tree.


 drivers/i2c/busses/i2c-ali1535.c  |    1 -
 drivers/i2c/busses/i2c-ali15x3.c  |    1 -
 drivers/i2c/busses/i2c-elektor.c  |   18 +++++++++---------
 drivers/i2c/busses/i2c-i801.c     |    1 -
 drivers/i2c/busses/i2c-piix4.c    |    1 -
 drivers/i2c/busses/i2c-rpx.c      |    2 +-
 drivers/i2c/busses/i2c-sis5595.c  |    1 -
 drivers/i2c/busses/i2c-sis630.c   |    1 -
 drivers/i2c/busses/i2c-velleman.c |    4 ++--
 drivers/i2c/busses/i2c-via.c      |    1 -
 drivers/i2c/i2c-dev.c             |    3 +--
 include/linux/i2c.h               |    3 ---
 12 files changed, 13 insertions(+), 24 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:11:27 2003
@@ -525,7 +525,6 @@
 
 static int __init i2c_ali1535_init(void)
 {
-	printk(KERN_INFO "i2c-ali1535 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&ali1535_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:11:27 2003
@@ -517,7 +517,6 @@
 
 static int __init i2c_ali15x3_init(void)
 {
-	printk("i2c-ali15x3.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&ali15x3_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
--- a/drivers/i2c/busses/i2c-elektor.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-elektor.c	Mon Sep 22 16:11:27 2003
@@ -77,7 +77,7 @@
 		val |= I2C_PCF_ENI;
 	}
 
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+	DEB3(printk(KERN_DEBUG "i2c-elektor: Write 0x%X 0x%02X\n", address, val & 255));
 
 	switch (mmapped) {
 	case 0: /* regular I/O */
@@ -98,7 +98,7 @@
 	int address = ctl ? (base + 1) : base;
 	int val = mmapped ? readb(address) : inb(address);
 
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
+	DEB3(printk(KERN_DEBUG "i2c-elektor: Read 0x%X 0x%02X\n", address, val));
 
 	return (val);
 }
@@ -143,14 +143,14 @@
 	if (!mmapped) {
 		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
 			printk(KERN_ERR
-			       "i2c-elektor.o: requested I/O region (0x%X:2) "
+			       "i2c-elektor: requested I/O region (0x%X:2) "
 			       "is in use.\n", base);
 			return -ENODEV;
 		}
 	}
 	if (irq > 0) {
 		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
-			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
+			printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq);
 			irq = 0;
 		} else
 			enable_irq(irq);
@@ -196,7 +196,7 @@
 			/* yeap, we've found cypress, let's check config */
 			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
 				
-				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+				DEB3(printk(KERN_DEBUG "i2c-elektor: found cy82c693, config register 0x47 = 0x%02x.\n", config));
 
 				/* UP2000 board has this register set to 0xe1,
                                    but the most significant bit as seems can be 
@@ -218,7 +218,7 @@
 					   8.25 MHz (PCI/4) clock
 					   (this can be read from cypress) */
 					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
-					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+					printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n");
 				}
 			}
 		}
@@ -227,11 +227,11 @@
 
 	/* sanity checks for mmapped I/O */
 	if (mmapped && base < 0xc8000) {
-		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+		printk(KERN_ERR "i2c-elektor: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-elektor: i2c pcf8584-isa adapter driver\n");
 
 	if (base == 0) {
 		base = DEFAULT_BASE;
@@ -243,7 +243,7 @@
 	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
 		goto fail;
 	
-	printk(KERN_ERR "i2c-elektor.o: found device at %#x.\n", base);
+	printk(KERN_ERR "i2c-elektor: found device at %#x.\n", base);
 
 	return 0;
 
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:11:27 2003
@@ -616,7 +616,6 @@
 
 static int __init i2c_i801_init(void)
 {
-	printk(KERN_INFO "i2c-i801 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&i801_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:11:27 2003
@@ -473,7 +473,6 @@
 
 static int __init i2c_piix4_init(void)
 {
-	printk(KERN_INFO "i2c-piix4 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&piix4_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
--- a/drivers/i2c/busses/i2c-rpx.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-rpx.c	Mon Sep 22 16:11:27 2003
@@ -78,7 +78,7 @@
 
 int __init i2c_rpx_init(void)
 {
-	printk("i2c-rpx.o: i2c MPC8xx module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-rpx: i2c MPC8xx driver\n");
 
 	/* reset hardware to sane state */
 	rpx_iic_init(&rpx_data);
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:11:27 2003
@@ -399,7 +399,6 @@
 
 static int __init i2c_sis5595_init(void)
 {
-	printk(KERN_INFO "i2c-sis5595 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&sis5595_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:11:27 2003
@@ -474,7 +474,6 @@
 
 static int __init i2c_sis630_init(void)
 {
-	printk("i2c-sis630.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&sis630_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-velleman.c b/drivers/i2c/busses/i2c-velleman.c
--- a/drivers/i2c/busses/i2c-velleman.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-velleman.c	Mon Sep 22 16:11:27 2003
@@ -120,7 +120,7 @@
 
 static int __init i2c_bitvelle_init(void)
 {
-	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-velleman: i2c Velleman K8000 driver\n");
 	if (base==0) {
 		/* probe some values */
 		base=DEFAULT_BASE;
@@ -140,7 +140,7 @@
 			return -ENODEV;
 		}
 	}
-	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
+	printk(KERN_DEBUG "i2c-velleman: found device at %#x.\n",base);
 	return 0;
 }
 
diff -Nru a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- a/drivers/i2c/busses/i2c-via.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-via.c	Mon Sep 22 16:11:27 2003
@@ -165,7 +165,6 @@
 
 static int __init i2c_vt586b_init(void)
 {
-	printk(KERN_INFO "i2c-via version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&vt586b_driver);
 }
 
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/i2c-dev.c	Mon Sep 22 16:11:27 2003
@@ -505,8 +505,7 @@
 {
 	int res;
 
-	printk(KERN_INFO "i2c /dev entries driver module version %s (%s)\n",
-		I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c /dev entries driver\n");
 
 	if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
 		printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Mon Sep 22 16:11:27 2003
+++ b/include/linux/i2c.h	Mon Sep 22 16:11:27 2003
@@ -28,9 +28,6 @@
 #ifndef _LINUX_I2C_H
 #define _LINUX_I2C_H
 
-#define I2C_DATE "20021208"
-#define I2C_VERSION "2.7.0"
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/i2c-id.h>


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
@ 2005-05-19  6:24         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-22 23:30 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.25, 2003/09/22 15:11:24-07:00, greg@kroah.com

[PATCH] I2C: remove check_region usage and warning from i2c-sensor


 drivers/i2c/i2c-sensor.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/i2c-sensor.c b/drivers/i2c/i2c-sensor.c
--- a/drivers/i2c/i2c-sensor.c	Mon Sep 22 16:11:52 2003
+++ b/drivers/i2c/i2c-sensor.c	Mon Sep 22 16:11:52 2003
@@ -50,8 +50,9 @@
 		return -1;
 
 	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
-		/* XXX: WTF is going on here??? */
-		if ((is_isa && check_region(addr, 1)) ||
+		void *region_used = request_region(addr, 1, "foo");
+		release_region(addr, 1);
+		if ((is_isa && (region_used == NULL)) ||
 		    (!is_isa && i2c_check_addr(adapter, addr)))
 			continue;
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24         ` Greg KH
@ 2005-05-19  6:24           ` Christoph Hellwig
  -1 siblings, 0 replies; 125+ messages in thread
From: Christoph Hellwig @ 2003-09-23  8:16 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, sensors

On Mon, Sep 22, 2003 at 04:30:28PM -0700, Greg KH wrote:
>  	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
> -		/* XXX: WTF is going on here??? */
> -		if ((is_isa && check_region(addr, 1)) ||
> +		void *region_used = request_region(addr, 1, "foo");
> +		release_region(addr, 1);
> +		if ((is_isa && (region_used == NULL)) ||

WTF??  Your papering over bugs again, this doesn't help at all.


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24           ` Christoph Hellwig
@ 2005-05-19  6:24             ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-23 16:19 UTC (permalink / raw)
  To: Christoph Hellwig, linux-kernel, sensors

On Tue, Sep 23, 2003 at 09:16:17AM +0100, Christoph Hellwig wrote:
> On Mon, Sep 22, 2003 at 04:30:28PM -0700, Greg KH wrote:
> >  	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
> > -		/* XXX: WTF is going on here??? */
> > -		if ((is_isa && check_region(addr, 1)) ||
> > +		void *region_used = request_region(addr, 1, "foo");
> > +		release_region(addr, 1);
> > +		if ((is_isa && (region_used == NULL)) ||
> 
> WTF??  Your papering over bugs again, this doesn't help at all.

Why?

Ok, from my reading of this horrible chunk of code it does the
following:
	- if this is a isa based controller, then we check the region
	  that is to be used.
	- If it is already in use by someone else, then we skip it, and
	  move on to the next address.
	- If it is not in use, then we pass the address down to the chip
	  driver and let it try to find the chip at this address (it
	  will do the reserving of the address space on its own.)

So basically, check_region is pretty valid here, as we are trying to see
if something else is already at this address, to try to prevent i2c
drivers from stomping on each other.  I replaced this with a
request_region()/release_region() pair to get rid of the compiler
warning.

Is this your understanding too?  Or do you think we should just get rid
of the request_region() check here all together?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24             ` Greg KH
@ 2005-05-19  6:24               ` Christoph Hellwig
  -1 siblings, 0 replies; 125+ messages in thread
From: Christoph Hellwig @ 2003-09-23 16:22 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, sensors

On Tue, Sep 23, 2003 at 09:19:29AM -0700, Greg KH wrote:
> Ok, from my reading of this horrible chunk of code it does the
> following:
> 	- if this is a isa based controller, then we check the region
> 	  that is to be used.
> 	- If it is already in use by someone else, then we skip it, and
> 	  move on to the next address.
> 	- If it is not in use, then we pass the address down to the chip
> 	  driver and let it try to find the chip at this address (it
> 	  will do the reserving of the address space on its own.)
> 
> So basically, check_region is pretty valid here, as we are trying to see
> if something else is already at this address, to try to prevent i2c
> drivers from stomping on each other.  I replaced this with a
> request_region()/release_region() pair to get rid of the compiler
> warning.
> 
> Is this your understanding too?  Or do you think we should just get rid
> of the request_region() check here all together?

Yes, either we should get rid of it or move claiming the address to
the i2c midlayer (not sure whether that's a good idea).  But an
opencoded check_region doesn't make any more sense than an explicit
one.  And you're also looking at the pointer it returned after it's
already invalid again..


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24               ` Christoph Hellwig
@ 2005-05-19  6:24                 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-09-23 19:04 UTC (permalink / raw)
  To: Christoph Hellwig, linux-kernel, sensors

On Tue, Sep 23, 2003 at 05:22:58PM +0100, Christoph Hellwig wrote:
> On Tue, Sep 23, 2003 at 09:19:29AM -0700, Greg KH wrote:
> > Ok, from my reading of this horrible chunk of code it does the
> > following:
> > 	- if this is a isa based controller, then we check the region
> > 	  that is to be used.
> > 	- If it is already in use by someone else, then we skip it, and
> > 	  move on to the next address.
> > 	- If it is not in use, then we pass the address down to the chip
> > 	  driver and let it try to find the chip at this address (it
> > 	  will do the reserving of the address space on its own.)
> > 
> > So basically, check_region is pretty valid here, as we are trying to see
> > if something else is already at this address, to try to prevent i2c
> > drivers from stomping on each other.  I replaced this with a
> > request_region()/release_region() pair to get rid of the compiler
> > warning.
> > 
> > Is this your understanding too?  Or do you think we should just get rid
> > of the request_region() check here all together?
> 
> Yes, either we should get rid of it or move claiming the address to
> the i2c midlayer (not sure whether that's a good idea).  But an
> opencoded check_region doesn't make any more sense than an explicit
> one.  And you're also looking at the pointer it returned after it's
> already invalid again..

Heh, good point.  Ok, I dug out a box that uses a isa i2c adapter and
tested the patch below.  As the chip drivers are using request_region
properly, taking this check out of i2c-sensor.c makes sense.

thanks,

greg k-h


diff -Nru a/drivers/i2c/i2c-sensor.c b/drivers/i2c/i2c-sensor.c
--- a/drivers/i2c/i2c-sensor.c	Tue Sep 23 12:03:13 2003
+++ b/drivers/i2c/i2c-sensor.c	Tue Sep 23 12:03:13 2003
@@ -50,10 +50,7 @@
 		return -1;
 
 	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
-		void *region_used = request_region(addr, 1, "foo");
-		release_region(addr, 1);
-		if ((is_isa && (region_used == NULL)) ||
-		    (!is_isa && i2c_check_addr(adapter, addr)))
+		if (!is_isa && i2c_check_addr(adapter, addr))
 			continue;
 
 		/* If it is in one of the force entries, we don't do any

^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24                 ` Greg KH
@ 2005-05-19  6:24                   ` Christoph Hellwig
  -1 siblings, 0 replies; 125+ messages in thread
From: Christoph Hellwig @ 2003-09-23 19:08 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, sensors

On Tue, Sep 23, 2003 at 12:04:40PM -0700, Greg KH wrote:
> Heh, good point.  Ok, I dug out a box that uses a isa i2c adapter and
> tested the patch below.  As the chip drivers are using request_region
> properly, taking this check out of i2c-sensor.c makes sense.

Looks better already, but I really wonder WTF this i2c_check_addr
thing is.  It looks at least as racy as check_region..

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test7
  2005-05-19  6:24 ` Greg KH
@ 2005-05-19  6:24 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-10-10 23:10 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes for 2.6.0-test7.  They fix a bug in the
i2c-dev class code, fix oopses in the i2c-sis630 driver, and fix a
potential use-before-initialized error in the i2c chip drivers.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.6

thanks,

greg k-h

 drivers/i2c/busses/Kconfig      |    4 +-
 drivers/i2c/busses/i2c-sis630.c |   67 ++++++++++++++++++++++++++++------------
 drivers/i2c/chips/Kconfig       |   16 ++++-----
 drivers/i2c/chips/adm1021.c     |    6 ++-
 drivers/i2c/chips/it87.c        |    7 ++--
 drivers/i2c/chips/lm75.c        |    5 ++
 drivers/i2c/chips/lm78.c        |    7 ++--
 drivers/i2c/chips/lm85.c        |    6 ++-
 drivers/i2c/chips/via686a.c     |    7 ++--
 drivers/i2c/chips/w83781d.c     |    6 ++-
 drivers/i2c/i2c-dev.c           |   17 ++++++++--
 11 files changed, 99 insertions(+), 49 deletions(-)
-----

<amalysh:web.de>:
  o I2C: i2c-sis630 driver fixes

Greg Kroah-Hartman:
  o I2C: fix i2c-dev class release function bug

Jean Delvare:
  o I2C: correct some errors in i2c/chips/Kconfig
  o I2C: Chip driver initialization fixes


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test7
  2005-05-19  6:24 ` Greg KH
@ 2005-05-19  6:24   ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-10-10 23:11 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.1, 2003/10/09 13:33:03-07:00, khali@linux-fr.org

[PATCH] I2C: Chip driver initialization fixes

fixes all chip drivers by moving the initialization before any sysfs
entry is created.


 drivers/i2c/chips/adm1021.c |    6 ++++--
 drivers/i2c/chips/it87.c    |    7 ++++---
 drivers/i2c/chips/lm75.c    |    5 ++++-
 drivers/i2c/chips/lm78.c    |    7 ++++---
 drivers/i2c/chips/lm85.c    |    6 ++++--
 drivers/i2c/chips/via686a.c |    7 ++++---
 drivers/i2c/chips/w83781d.c |    6 ++++--
 7 files changed, 28 insertions(+), 16 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/adm1021.c	Fri Oct 10 16:00:52 2003
@@ -322,6 +322,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto error3;
 
+	/* Initialize the ADM1021 chip */
+	adm1021_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_temp_max1);
 	device_create_file(&new_client->dev, &dev_attr_temp_min1);
 	device_create_file(&new_client->dev, &dev_attr_temp_input1);
@@ -332,8 +336,6 @@
 	if (data->type == adm1021)
 		device_create_file(&new_client->dev, &dev_attr_die_code);
 
-	/* Initialize the ADM1021 chip */
-	adm1021_init_client(new_client);
 	return 0;
 
 error3:
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/it87.c	Fri Oct 10 16:00:52 2003
@@ -701,7 +701,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR1;
 
-	/* register sysfs hooks */
+	/* Initialize the IT87 chip */
+	it87_init_client(new_client, data);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in_input0);
 	device_create_file(&new_client->dev, &dev_attr_in_input1);
 	device_create_file(&new_client->dev, &dev_attr_in_input2);
@@ -750,8 +753,6 @@
 	device_create_file(&new_client->dev, &dev_attr_fan_div3);
 	device_create_file(&new_client->dev, &dev_attr_alarm);
 
-	/* Initialize the IT87 chip */
-	it87_init_client(new_client, data);
 	return 0;
 
 ERROR1:
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/lm75.c	Fri Oct 10 16:00:52 2003
@@ -204,11 +204,14 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto exit_free;
 
+	/* Initialize the LM75 chip */
+	lm75_init_client(new_client);
+	
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_temp_max);
 	device_create_file(&new_client->dev, &dev_attr_temp_min);
 	device_create_file(&new_client->dev, &dev_attr_temp_input);
 
-	lm75_init_client(new_client);
 	return 0;
 
 exit_free:
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/lm78.c	Fri Oct 10 16:00:52 2003
@@ -648,7 +648,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR2;
 
-	/* register sysfs hooks */
+	/* Initialize the LM78 chip */
+	lm78_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in_input0);
 	device_create_file(&new_client->dev, &dev_attr_in_min0);
 	device_create_file(&new_client->dev, &dev_attr_in_max0);
@@ -685,8 +688,6 @@
 	device_create_file(&new_client->dev, &dev_attr_alarms);
 	device_create_file(&new_client->dev, &dev_attr_vid);
 
-	/* Initialize the LM78 chip */
-	lm78_init_client(new_client);
 	return 0;
 
 ERROR2:
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/lm85.c	Fri Oct 10 16:00:52 2003
@@ -888,6 +888,10 @@
 	/* Set the VRM version */
 	data->vrm = LM85_INIT_VRM ;
 
+	/* Initialize the LM85 chip */
+	lm85_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_fan_input1);
 	device_create_file(&new_client->dev, &dev_attr_fan_input2);
 	device_create_file(&new_client->dev, &dev_attr_fan_input3);
@@ -930,8 +934,6 @@
 	device_create_file(&new_client->dev, &dev_attr_vid);
 	device_create_file(&new_client->dev, &dev_attr_alarms);
 
-	/* Initialize the LM85 chip */
-	lm85_init_client(new_client);
 	return 0;
 
 	/* Error out and cleanup code */
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/via686a.c	Fri Oct 10 16:00:52 2003
@@ -735,7 +735,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR3;
 	
-	/* register sysfs hooks */
+	/* Initialize the VIA686A chip */
+	via686a_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in_input0);
 	device_create_file(&new_client->dev, &dev_attr_in_input1);
 	device_create_file(&new_client->dev, &dev_attr_in_input2);
@@ -768,8 +771,6 @@
 	device_create_file(&new_client->dev, &dev_attr_fan_div2);
 	device_create_file(&new_client->dev, &dev_attr_alarm);
 
-	/* Initialize the VIA686A chip */
-	via686a_init_client(new_client);
 	return 0;
 
       ERROR3:
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/w83781d.c	Fri Oct 10 16:00:52 2003
@@ -1346,6 +1346,10 @@
 		data->lm75[1] = NULL;
 	}
 
+	/* Initialize the chip */
+	w83781d_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file_in(new_client, 0);
 	if (kind != w83783s && kind != w83697hf)
 		device_create_file_in(new_client, 1);
@@ -1408,8 +1412,6 @@
 	}
 #endif
 
-	/* Initialize the chip */
-	w83781d_init_client(new_client);
 	return 0;
 
 ERROR3:


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test7
  2005-05-19  6:24   ` Greg KH
@ 2005-05-19  6:24       ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-10-10 23:11 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.3, 2003/10/10 14:11:04-07:00, amalysh@web.de

[PATCH] I2C: i2c-sis630 driver fixes

attached you can find a patch that should fix i2c-sis630 driver for
2.6.0-X kernel. With i2c-sis630 from stock 2.6.0-X we have oops and
driver was not correct registered against i2c-core.

Changes:
	1) fixed a oops while modprobing
	2) added check for buffer overflow for i2c block data read transaction
	3) added 'force' modprobe parameter. It's allow more easily
	   testing for not yet supported SiS chips.


 drivers/i2c/busses/Kconfig      |    4 +-
 drivers/i2c/busses/i2c-sis630.c |   67 ++++++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 22 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Fri Oct 10 16:00:43 2003
+++ b/drivers/i2c/busses/Kconfig	Fri Oct 10 16:00:43 2003
@@ -248,11 +248,11 @@
 	  will be called i2c-sis5595.
 
 config I2C_SIS630
-	tristate "SiS 630"
+	tristate "SiS 630/730"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
-	  SiS630 SMBus (a subset of I2C) interface.
+	  SiS630 and SiS730 SMBus (a subset of I2C) interface.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-sis630.
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c	Fri Oct 10 16:00:43 2003
+++ b/drivers/i2c/busses/i2c-sis630.c	Fri Oct 10 16:00:43 2003
@@ -25,10 +25,10 @@
    	Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
 	Changed sis630_transaction.(Thanks to Mark M. Hoffman)
    18.09.2002
-	Added SIS730 as supported
+	Added SIS730 as supported.
    21.09.2002
 	Added high_clock module option.If this option is set
-	used Host Master Clock 56KHz (default 14KHz).For now we are save old Host
+	used Host Master Clock 56KHz (default 14KHz).For now we save old Host
 	Master Clock and after transaction completed restore (otherwise
 	it's confuse BIOS and hung Machine).
    24.09.2002
@@ -95,12 +95,22 @@
 
 /* insmod parameters */
 static int high_clock = 0;
+static int force = 0;
 MODULE_PARM(high_clock, "i");
 MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
+MODULE_PARM(force, "i");
+MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
 
-
+/* acpi base address */
 static unsigned short acpi_base = 0;
 
+/* supported chips */
+static int supported[] = {
+	PCI_DEVICE_ID_SI_630,
+	PCI_DEVICE_ID_SI_730,
+	0 /* terminates the list */
+};
+
 static inline u8 sis630_read(u8 reg)
 {
 	return inb(acpi_base + reg);
@@ -277,6 +287,10 @@
 			if (len == 0)
 				data->block[0] = sis630_read(SMB_COUNT);
 
+			/* just to be sure */
+			if (data->block[0] > 32)
+				data->block[0] = 32;
+
 			dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
 
 			for (i=0; i < 8 && len < data->block[0]; i++,len++) {
@@ -372,16 +386,26 @@
 		I2C_FUNC_SMBUS_BLOCK_DATA;
 }
 
-static int sis630_setup(struct pci_dev *dummy)
+static int sis630_setup(struct pci_dev *sis630_dev)
 {
 	unsigned char b;
-	struct pci_dev *sis630_dev = NULL;
-	int retval = -ENODEV;
+	struct pci_dev *dummy = NULL;
+	int retval = -ENODEV, i;
 
-	/* We need ISA bridge and not pci device passed in.  */
-	sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev);
-	if (!sis630_dev) {
-		dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n");
+	/* check for supported SiS devices */
+	for (i=0; supported[i] > 0 ; i++) {
+		if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy)))
+			break; /* found */
+	}
+
+	if (dummy) {
+		pci_dev_put(dummy);
+	}
+        else if (force > 0) {
+		dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but "
+			"loading because of force option enabled\n");
+ 	}
+	else {
 		return -ENODEV;
 	}
 
@@ -389,19 +413,19 @@
 	   Enable ACPI first , so we can accsess reg 74-75
 	   in acpi io space and read acpi base addr
 	*/
-	if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
+	if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
 		dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
 		goto exit;
 	}
-
 	/* if ACPI already enabled , do nothing */
 	if (!(b & 0x80) &&
-	    !pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
+	    pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
 		dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
 		goto exit;
 	}
+
 	/* Determine the ACPI base address */
-	if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
+	if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
 		dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
 		goto exit;
 	}
@@ -418,7 +442,8 @@
 	retval = 0;
 
 exit:
-	pci_dev_put(sis630_dev);
+	if (retval)
+		acpi_base = 0;
 	return retval;
 }
 
@@ -432,19 +457,18 @@
 
 static struct i2c_adapter sis630_adapter = {
 	.owner		= THIS_MODULE,
+	.class		= I2C_ADAP_CLASS_SMBUS,
 	.name		= "unset",
 	.algo		= &smbus_algorithm,
 };
 
 static struct pci_device_id sis630_ids[] __devinitdata = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
 	{ 0, }
 };
 
 static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-
 	if (sis630_setup(dev)) {
 		dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
 		return -ENODEV;
@@ -461,7 +485,11 @@
 
 static void __devexit sis630_remove(struct pci_dev *dev)
 {
-	i2c_del_adapter(&sis630_adapter);
+	if (acpi_base) {
+		i2c_del_adapter(&sis630_adapter);
+		release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
+		acpi_base = 0;
+	}
 }
 
 
@@ -481,7 +509,6 @@
 static void __exit i2c_sis630_exit(void)
 {
 	pci_unregister_driver(&sis630_driver);
-	release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
 }
 
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test7
  2005-05-19  6:24   ` Greg KH
@ 2005-05-19  6:24     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-10-10 23:11 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.2, 2003/10/09 13:35:09-07:00, khali@linux-fr.org

[PATCH] I2C: correct some errors in i2c/chips/Kconfig


 drivers/i2c/chips/Kconfig |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)


diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	Fri Oct 10 16:00:47 2003
+++ b/drivers/i2c/chips/Kconfig	Fri Oct 10 16:00:47 2003
@@ -15,7 +15,7 @@
 	help
 	  If you say yes here you get support for Analog Devices ADM1021 
 	  and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
-	  Genesys Logic GL523SM, National Semi LM84, TI THMC10,
+	  Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
 	  and the XEON processor built-in sensor.
 
 	  This driver can also be built as a module.  If so, the module
@@ -34,30 +34,30 @@
 	  will be called eeprom.
 
 config SENSORS_IT87
-	tristate "National Semiconductors IT87 and compatibles"
+	tristate "ITE IT87xx and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
-	  If you say yes here you get support for National Semiconductor IT87
-	  sensor chips and clones: IT8705F, IT8712F and SiS960.
+	  If you say yes here you get support for ITE IT87xx sensor chips
+	  and clones: SiS960.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called it87.
 
 config SENSORS_LM75
-	tristate "National Semiconductors LM75 and compatibles"
+	tristate "National Semiconductor LM75 and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
 	  If you say yes here you get support for National Semiconductor LM75
 	  sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon
-	  TCN75, and National Semi LM77.
+	  TCN75, and National Semiconductor LM77.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm75.
 
 config SENSORS_LM78
-	tristate "National Semiconductors LM78 and compatibles"
+	tristate "National Semiconductor LM78 and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
@@ -69,7 +69,7 @@
 	  will be called lm78.
 
 config SENSORS_LM85
-	tristate "National Semiconductors LM85 and compatibles"
+	tristate "National Semiconductor LM85 and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help


^ permalink raw reply	[flat|nested] 125+ messages in thread

* Re: [PATCH] i2c driver fixes for 2.6.0-test7
  2005-05-19  6:24   ` Greg KH
@ 2005-05-19  6:24         ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2003-10-10 23:11 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.4, 2003/10/10 14:59:18-07:00, greg@kroah.com

[PATCH] I2C: fix i2c-dev class release function bug.

There was no release function, that was the bug :)
It caused bad messages to show up in the syslog whenever a i2c driver was removed, and could
easily oops.


 drivers/i2c/i2c-dev.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)


diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Fri Oct 10 16:00:34 2003
+++ b/drivers/i2c/i2c-dev.c	Fri Oct 10 16:00:34 2003
@@ -49,6 +49,7 @@
 	int minor;
 	struct i2c_adapter *adap;
 	struct class_device class_dev;
+	struct completion released;	/* FIXME, we need a class_device_unregister() */
 };
 #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
 
@@ -112,7 +113,6 @@
 	spin_lock(&i2c_dev_array_lock);
 	i2c_dev_array[i2c_dev->minor] = NULL;
 	spin_unlock(&i2c_dev_array_lock);
-	kfree(i2c_dev);
 }
 
 static ssize_t show_dev(struct class_device *class_dev, char *buf)
@@ -421,8 +421,15 @@
 	.release	= i2cdev_release,
 };
 
+static void release_i2c_dev(struct class_device *dev)
+{
+	struct i2c_dev *i2c_dev = to_i2c_dev(dev);
+	complete(&i2c_dev->released);
+}
+
 static struct class i2c_dev_class = {
-	.name	= "i2c-dev",
+	.name		= "i2c-dev",
+	.release	= &release_i2c_dev,
 };
 
 static int i2cdev_attach_adapter(struct i2c_adapter *adap)
@@ -453,6 +460,7 @@
 	return 0;
 error:
 	return_i2c_dev(i2c_dev);
+	kfree(i2c_dev);
 	return retval;
 }
 
@@ -464,9 +472,12 @@
 	if (!i2c_dev)
 		return -ENODEV;
 
-	class_device_unregister(&i2c_dev->class_dev);
+	init_completion(&i2c_dev->released);
 	devfs_remove("i2c/%d", i2c_dev->minor);
 	return_i2c_dev(i2c_dev);
+	class_device_unregister(&i2c_dev->class_dev);
+	wait_for_completion(&i2c_dev->released);
+	kfree(i2c_dev);
 
 	dev_dbg(&adap->dev, "Adapter unregistered\n");
 	return 0;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
@ 2005-05-19  6:24 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes for 2.6.0-test2.  They include a number
of minor i2c fixes and add a new i2c bus controller driver.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.5

thanks,

greg k-h

 drivers/i2c/Kconfig              |    8 
 drivers/i2c/busses/Kconfig       |   17 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-ali1535.c |   20 -
 drivers/i2c/busses/i2c-ali15x3.c |   15 -
 drivers/i2c/busses/i2c-amd756.c  |   28 --
 drivers/i2c/busses/i2c-amd8111.c |    6 
 drivers/i2c/busses/i2c-i801.c    |   28 --
 drivers/i2c/busses/i2c-nforce2.c |  470 +++++++++++++++++++++++++++++++++++++--
 drivers/i2c/busses/i2c-piix4.c   |   20 -
 drivers/i2c/busses/i2c-sis96x.c  |   18 -
 drivers/i2c/busses/i2c-viapro.c  |   18 -
 drivers/i2c/chips/via686a.c      |   20 -
 drivers/i2c/i2c-keywest.c        |   90 +------
 include/linux/i2c.h              |    7 
 15 files changed, 529 insertions(+), 237 deletions(-)
-----

<nikkne:hotpop.com>:
  o I2C: fix Kconfig info

<patrick:dreker.de>:
  o I2C: add ncforce2 i2c bus driver

Benjamin Herrenschmidt:
  o I2C: timer clean up for i2c-keywest.c

Daniele Bellucci:
  o I2C: fixed a little memory leak in i2c-ali15x3.c

Greg Kroah-Hartman:
  o I2C: remove devinitdata marking from i2c-nforce2.c as it's wrong
  o I2C: consolidate the i2c delay functions
  o I2C: minor cleanups to the i2c-nforce2 driver

Jan Dittmer:
  o I2C: convert via686a temp_* to milli degree celsius

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24 ` Greg KH
  (?)
@ 2005-05-19  6:24 ` Jean Delvare
  -1 siblings, 0 replies; 125+ messages in thread
From: Jean Delvare @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors


Greg,

> <nikkne:hotpop.com>:
>   o I2C: fix Kconfig info
> 
> <patrick:dreker.de>:
>   o I2C: add ncforce2 i2c bus driver
> 
> Benjamin Herrenschmidt:
>   o I2C: timer clean up for i2c-keywest.c
> 
> Daniele Bellucci:
>   o I2C: fixed a little memory leak in i2c-ali15x3.c
> 
> Greg Kroah-Hartman:
>   o I2C: remove devinitdata marking from i2c-nforce2.c as it's wrong
>   o I2C: consolidate the i2c delay functions
>   o I2C: minor cleanups to the i2c-nforce2 driver
> 
> Jan Dittmer:
>   o I2C: convert via686a temp_* to milli degree celsius

Does any of these apply to our CVS repository?

-- 
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24 ` Greg KH
                   ` (2 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

On Sat, Aug 02, 2003 at 09:55:18AM +0200, Jean Delvare wrote:
> 
> Greg,
> 
> > <nikkne:hotpop.com>:
> >   o I2C: fix Kconfig info
> > 
> > <patrick:dreker.de>:
> >   o I2C: add ncforce2 i2c bus driver
> > 
> > Benjamin Herrenschmidt:
> >   o I2C: timer clean up for i2c-keywest.c
> > 
> > Daniele Bellucci:
> >   o I2C: fixed a little memory leak in i2c-ali15x3.c
> > 
> > Greg Kroah-Hartman:
> >   o I2C: remove devinitdata marking from i2c-nforce2.c as it's wrong
> >   o I2C: consolidate the i2c delay functions
> >   o I2C: minor cleanups to the i2c-nforce2 driver
> > 
> > Jan Dittmer:
> >   o I2C: convert via686a temp_* to milli degree celsius
> 
> Does any of these apply to our CVS repository?

Probably :)

The memory leak from Daniele is probably needed, and the i2c delay
cleanup can also be moved there.  I don't think the others really apply
though.  I've put the individual patches in my kernel.org account if
people want to see them (sorry for not posting them to the list, but I
already have, this was just a re-send of these patches to Linus.)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24 ` Greg KH
  (?)
  (?)
@ 2005-05-19  6:24 ` Mark M. Hoffman
  -1 siblings, 0 replies; 125+ messages in thread
From: Mark M. Hoffman @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

* Greg KH <greg@kroah.com> [2003-08-02 09:56:38 -0700]:
> On Sat, Aug 02, 2003 at 09:55:18AM +0200, Jean Delvare wrote:
> > 
> > Greg,
> > 
> > > <nikkne:hotpop.com>:
> > >   o I2C: fix Kconfig info
> > > 
> > > <patrick:dreker.de>:
> > >   o I2C: add ncforce2 i2c bus driver
> > > 
> > > Benjamin Herrenschmidt:
> > >   o I2C: timer clean up for i2c-keywest.c
> > > 
> > > Daniele Bellucci:
> > >   o I2C: fixed a little memory leak in i2c-ali15x3.c
> > > 
> > > Greg Kroah-Hartman:
> > >   o I2C: remove devinitdata marking from i2c-nforce2.c as it's wrong
> > >   o I2C: consolidate the i2c delay functions
> > >   o I2C: minor cleanups to the i2c-nforce2 driver
> > > 
> > > Jan Dittmer:
> > >   o I2C: convert via686a temp_* to milli degree celsius
> > 
> > Does any of these apply to our CVS repository?
> 
> Probably :)
> 
> The memory leak from Daniele is probably needed, and the i2c delay
> cleanup can also be moved there.  I don't think the others really apply

Done, plus most of the nforce2 patch.  This bit though... any particular
reason you didn't just whack all of it?

@@ -345,18 +334,12 @@
 			smbus->base, smbus->base+smbus->size-1, name);
 		return -1;
 	}
-
-	/* TODO: find a better way to find out whether this file is compiled
-	 * with i2c 2.7.0 of earlier
-	 */
-/*#ifdef I2C_HW_SMBUS_AMD8111
+/*
 	smbus->adapter.owner = THIS_MODULE;
-#endif
-
 	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
 	smbus->adapter.algo = &smbus_algorithm;
-	smbus->adapter.algo_data = smbus;*/
-
+	smbus->adapter.algo_data = smbus;
+*/

Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24 ` Greg KH
                   ` (3 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

On Sun, Aug 03, 2003 at 01:27:28AM -0400, Mark M. Hoffman wrote:
> 
> Done, plus most of the nforce2 patch.  This bit though... any particular
> reason you didn't just whack all of it?
> 
> @@ -345,18 +334,12 @@
>  			smbus->base, smbus->base+smbus->size-1, name);
>  		return -1;
>  	}
> -
> -	/* TODO: find a better way to find out whether this file is compiled
> -	 * with i2c 2.7.0 of earlier
> -	 */
> -/*#ifdef I2C_HW_SMBUS_AMD8111
> +/*
>  	smbus->adapter.owner = THIS_MODULE;
> -#endif
> -
>  	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
>  	smbus->adapter.algo = &smbus_algorithm;
> -	smbus->adapter.algo_data = smbus;*/
> -
> +	smbus->adapter.algo_data = smbus;
> +*/

I didn't have the time to verify if this really should be set or not, so
I left the main portion alone.  Does this mean I can delete all of the
commented out area for 2.6?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
  2005-05-19  6:24 ` Greg KH
                   ` (4 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Mark M. Hoffman
  2005-05-19  6:24     ` Mark M. Hoffman
  -1 siblings, 1 reply; 125+ messages in thread
From: Mark M. Hoffman @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

* Greg KH <greg@kroah.com> [2003-08-04 09:06:30 -0700]:
> On Sun, Aug 03, 2003 at 01:27:28AM -0400, Mark M. Hoffman wrote:
> > 
> > Done, plus most of the nforce2 patch.  This bit though... any particular
> > reason you didn't just whack all of it?
> > 
> > @@ -345,18 +334,12 @@
> >  			smbus->base, smbus->base+smbus->size-1, name);
> >  		return -1;
> >  	}
> > -
> > -	/* TODO: find a better way to find out whether this file is compiled
> > -	 * with i2c 2.7.0 of earlier
> > -	 */
> > -/*#ifdef I2C_HW_SMBUS_AMD8111
> > +/*
> >  	smbus->adapter.owner = THIS_MODULE;
> > -#endif
> > -
> >  	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
> >  	smbus->adapter.algo = &smbus_algorithm;
> > -	smbus->adapter.algo_data = smbus;*/
> > -
> > +	smbus->adapter.algo_data = smbus;
> > +*/
> 
> I didn't have the time to verify if this really should be set or not, so
> I left the main portion alone.  Does this mean I can delete all of the
> commented out area for 2.6?

With a closer look, I think this driver was broken before and after
your patch.  The algo_data field has to be set (to smbus), because it's
used in nforce2_access().  Notice the macros...

#define NVIDIA_SMB_PRTCL        (smbus->base + 0x00)    /* protocol, PEC */
#define NVIDIA_SMB_STS          (smbus->base + 0x01)    /* status */
#define NVIDIA_SMB_ADDR         (smbus->base + 0x02)    /* address */

I'm not a fan of that (I would give the macros a parameter) but whatever.

A new patch is attached; please consider...

[comment]
This patch restores a line that was wrongly removed.  There are also some
trivial cleanups.  It applies & compiles vs. 2.6.0-test2-bk4.  It's untested
(no hardware here).
[/comment]

Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com

-------------- next part --------------
--- linux-2.6.0-test2/drivers/i2c/busses/i2c-nforce2.c.old	2003-08-04 23:01:39.000000000 -0400
+++ linux-2.6.0-test2/drivers/i2c/busses/i2c-nforce2.c	2003-08-04 23:07:33.000000000 -0400
@@ -51,10 +51,6 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS   0x0064
 #endif
-/* TODO: sync with lm-sensors */
-#ifndef I2C_HW_SMBUS_NFORCE2
-#define I2C_HW_SMBUS_NFORCE2	0x0c
-#endif
 
 
 struct nforce2_smbus {
@@ -130,20 +126,10 @@
 	},
 };
 
-
-#if 0
-/* Internally used pause function */
-static void nforce2_do_pause(unsigned int amount)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(amount);
-}
-#endif
-
 /* Return -1 on error. See smbus.h for more information */
-static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-		char read_write, u8 command, int size,
-		union i2c_smbus_data * data)
+static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
+		unsigned short flags, char read_write,
+		u8 command, int size, union i2c_smbus_data * data)
 {
 	struct nforce2_smbus *smbus = adap->algo_data;
 	unsigned char protocol, pec, temp;
@@ -251,7 +237,7 @@
 
 #if 0
 	do {
-		nforce2_do_pause(1);
+		i2c_do_pause(1);
 		temp = inb_p(NVIDIA_SMB_STS);
 	} while (((temp & NVIDIA_SMB_STS_DONE) = 0) && (timeout++ < MAX_TIMEOUT));
 #endif
@@ -334,13 +320,8 @@
 			smbus->base, smbus->base+smbus->size-1, name);
 		return -1;
 	}
-/*
-	smbus->adapter.owner = THIS_MODULE;
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
-	smbus->adapter.algo = &smbus_algorithm;
-	smbus->adapter.algo_data = smbus;
-*/
 	smbus->adapter = nforce2_adapter;
+	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
 	snprintf(smbus->adapter.dev.name, DEVICE_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
@ 2005-05-19  6:24     ` Mark M. Hoffman
  0 siblings, 0 replies; 125+ messages in thread
From: Mark M. Hoffman @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Sensors, LKML; +Cc: Greg KH

This is a resend of a patch to the i2c-nforce2.c I2C bus driver.
The start of the relevant thread was here:
http://archives.andrew.net.au/lm-sensors/msg03820.html

[comment]
This patch restores a line that was wrongly removed.  There are also some
trivial cleanups.  It applies & compiles vs. 2.6.0-test3.  It's untested
(no hardware here).
[/comment]

--- linux-2.6.0-test3/drivers/i2c/busses/i2c-nforce2.c.orig	2003-08-14 00:53:00.000000000 -0400
+++ linux-2.6.0-test3/drivers/i2c/busses/i2c-nforce2.c	2003-08-14 01:05:31.000000000 -0400
@@ -51,10 +51,6 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS   0x0064
 #endif
-/* TODO: sync with lm-sensors */
-#ifndef I2C_HW_SMBUS_NFORCE2
-#define I2C_HW_SMBUS_NFORCE2	0x0c
-#endif
 
 
 struct nforce2_smbus {
@@ -128,20 +124,10 @@
 	.name   	= "unset",
 };
 
-
-#if 0
-/* Internally used pause function */
-static void nforce2_do_pause(unsigned int amount)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(amount);
-}
-#endif
-
 /* Return -1 on error. See smbus.h for more information */
-static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-		char read_write, u8 command, int size,
-		union i2c_smbus_data * data)
+static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
+		unsigned short flags, char read_write,
+		u8 command, int size, union i2c_smbus_data * data)
 {
 	struct nforce2_smbus *smbus = adap->algo_data;
 	unsigned char protocol, pec, temp;
@@ -249,7 +235,7 @@
 
 #if 0
 	do {
-		nforce2_do_pause(1);
+		i2c_do_pause(1);
 		temp = inb_p(NVIDIA_SMB_STS);
 	} while (((temp & NVIDIA_SMB_STS_DONE) = 0) && (timeout++ < MAX_TIMEOUT));
 #endif
@@ -332,13 +318,8 @@
 			smbus->base, smbus->base+smbus->size-1, name);
 		return -1;
 	}
-/*
-	smbus->adapter.owner = THIS_MODULE;
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
-	smbus->adapter.algo = &smbus_algorithm;
-	smbus->adapter.algo_data = smbus;
-*/
 	smbus->adapter = nforce2_adapter;
+	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
 	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);

-- 
Mark M. Hoffman
mhoffman@lightlink.com

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test2
@ 2005-05-19  6:24       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Sensors, LKML

On Thu, Aug 14, 2003 at 01:13:47AM -0400, Mark M. Hoffman wrote:
> This is a resend of a patch to the i2c-nforce2.c I2C bus driver.
> The start of the relevant thread was here:
> http://archives.andrew.net.au/lm-sensors/msg03820.html
> 
> [comment]
> This patch restores a line that was wrongly removed.  There are also some
> trivial cleanups.  It applies & compiles vs. 2.6.0-test3.  It's untested
> (no hardware here).
> [/comment]

Oops, sorry I forgot this one.  I've now applied it and will send it on
later to Linus.

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test3
@ 2005-05-19  6:24 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes for 2.6.0-test3.  They include a fix for
the i2c-dev driver that has gone into 2.4 and a pii4x bugfix from Tom
Rini.  I've also added adapter and client "name" files in sysfs as the
driver core no longer supplies them.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.5

thanks,

greg k-h

 drivers/i2c/busses/i2c-nforce2.c |   29 ++++-----------------------
 drivers/i2c/busses/i2c-piix4.c   |   13 ++++++++++--
 drivers/i2c/chips/Makefile       |    4 ++-
 drivers/i2c/chips/adm1021.c      |    8 +++----
 drivers/i2c/i2c-core.c           |   28 ++++++++++++++++++++++++++
 drivers/i2c/i2c-dev.c            |   41 ++++++++++++++++++++++++---------------
 6 files changed, 77 insertions(+), 46 deletions(-)
-----

<khali:linux-fr.org>:
  o i2c: user/kernel bug and memory leak in i2c-dev

Greg Kroah-Hartman:
  o I2C: add adapter and client name files as the driver core no longer provides them
  o I2C: fix up the wording for the pii4x bugfix
  o i2c: move w83481d to top of link order due to chip address takeover ability
  o i2c: fix up "raw" printk() call

Mark M. Hoffman:
  o I2C: i2c nforce2.c fixes

Rusty Lynch:
  o I2C: bugfix for initialization bug in adm1021 driver

Tom Rini:
  o I2C: Fix for i2c-piix4 with on some boards

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24     ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.2, 2003/08/11 14:36:29-07:00, khali@linux-fr.org

[PATCH] i2c: user/kernel bug and memory leak in i2c-dev


 drivers/i2c/i2c-dev.c |   41 ++++++++++++++++++++++++++---------------
 1 files changed, 26 insertions(+), 15 deletions(-)


diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Fri Aug 15 11:27:09 2003
+++ b/drivers/i2c/i2c-dev.c	Fri Aug 15 11:27:09 2003
@@ -181,6 +181,7 @@
 	struct i2c_smbus_ioctl_data data_arg;
 	union i2c_smbus_data temp;
 	struct i2c_msg *rdwr_pa;
+	u8 **data_ptrs;
 	int i,datasize,res;
 	unsigned long funcs;
 
@@ -214,7 +215,7 @@
 		return (copy_to_user((unsigned long __user *)arg, &funcs,
 		                     sizeof(unsigned long)))?-EFAULT:0;
 
-        case I2C_RDWR:
+	case I2C_RDWR:
 		if (copy_from_user(&rdwr_arg, 
 				   (struct i2c_rdwr_ioctl_data __user *)arg, 
 				   sizeof(rdwr_arg)))
@@ -231,28 +232,37 @@
 
 		if (rdwr_pa = NULL) return -ENOMEM;
 
+		if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
+				   rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
+			kfree(rdwr_pa);
+			return -EFAULT;
+		}
+
+		data_ptrs = (u8 **) kmalloc(rdwr_arg.nmsgs * sizeof(u8 *),
+					    GFP_KERNEL);
+		if (data_ptrs = NULL) {
+			kfree(rdwr_pa);
+			return -ENOMEM;
+		}
+
 		res = 0;
 		for( i=0; i<rdwr_arg.nmsgs; i++ ) {
-		    	if(copy_from_user(&(rdwr_pa[i]),
-					&(rdwr_arg.msgs[i]),
-					sizeof(rdwr_pa[i]))) {
-			        res = -EFAULT;
-				break;
-			}
 			/* Limit the size of the message to a sane amount */
 			if (rdwr_pa[i].len > 8192) {
 				res = -EINVAL;
 				break;
 			}
+			data_ptrs[i] = rdwr_pa[i].buf;
 			rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
 			if(rdwr_pa[i].buf = NULL) {
 				res = -ENOMEM;
 				break;
 			}
 			if(copy_from_user(rdwr_pa[i].buf,
-				rdwr_arg.msgs[i].buf,
+				data_ptrs[i],
 				rdwr_pa[i].len)) {
-			    	res = -EFAULT;
+					++i; /* Needs to be kfreed too */
+					res = -EFAULT;
 				break;
 			}
 		}
@@ -260,18 +270,18 @@
 			int j;
 			for (j = 0; j < i; ++j)
 				kfree(rdwr_pa[j].buf);
+			kfree(data_ptrs);
 			kfree(rdwr_pa);
 			return res;
 		}
-		if (!res) {
-			res = i2c_transfer(client->adapter,
-				rdwr_pa,
-				rdwr_arg.nmsgs);
-		}
+
+		res = i2c_transfer(client->adapter,
+			rdwr_pa,
+			rdwr_arg.nmsgs);
 		while(i-- > 0) {
 			if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD)) {
 				if(copy_to_user(
-					rdwr_arg.msgs[i].buf,
+					data_ptrs[i],
 					rdwr_pa[i].buf,
 					rdwr_pa[i].len)) {
 					res = -EFAULT;
@@ -279,6 +289,7 @@
 			}
 			kfree(rdwr_pa[i].buf);
 		}
+		kfree(data_ptrs);
 		kfree(rdwr_pa);
 		return res;
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24   ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.1, 2003/08/11 14:36:10-07:00, trini@kernel.crashing.org

[PATCH] I2C: Fix for i2c-piix4 with on some boards

Hello all.  On some boards with an Intel PIIX4 the BIOS (such as the one
found on a Force CPCI-735) will incorrectly configure the chipset, and
leaves a register in an undefined state causing i2c to behave strangley.
The following patches (first vs lm_sensors-2.8.0 and then vs
2.6.0-test3)  fixes the issue.


 drivers/i2c/busses/i2c-piix4.c |    9 +++++++++
 1 files changed, 9 insertions(+)


diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:13 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:13 2003
@@ -160,6 +160,15 @@
 	}
 
 	pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
+
+	/* Some BIOS will set up the chipset incorrectly and leave a register
+	   in an undefined state (causing I2C to act very strangely). */
+	if (temp & 0x02) {
+		printk("Fixed I2C problem on Force CPCI735\n");
+		temp = temp & 0xfd;
+		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
+	}
+ 
 	/* If force_addr is set, we program the new address here. Just to make
 	   sure, we disable the PIIX4 first. */
 	if (force_addr) {


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.4, 2003/08/11 15:22:22-07:00, greg@kroah.com

i2c: move w83481d to top of link order due to chip address takeover ability.

Fixes http://bugme.osdl.org/show_bug.cgi?id\x1066


 drivers/i2c/chips/Makefile |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)


diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
--- a/drivers/i2c/chips/Makefile	Fri Aug 15 11:27:01 2003
+++ b/drivers/i2c/chips/Makefile	Fri Aug 15 11:27:01 2003
@@ -2,10 +2,12 @@
 # Makefile for the kernel hardware sensors chip drivers.
 #
 
+# w83781d goes first, as it can override other driver's addresses.
+obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o
+
 obj-$(CONFIG_SENSORS_ADM1021)	+= adm1021.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
 obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
 obj-$(CONFIG_SENSORS_LM85)	+= lm85.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
-obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.3, 2003/08/11 14:36:57-07:00, greg@kroah.com

[PATCH] i2c: fix up "raw" printk() call.


 drivers/i2c/busses/i2c-piix4.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:05 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:27:05 2003
@@ -164,7 +164,7 @@
 	/* Some BIOS will set up the chipset incorrectly and leave a register
 	   in an undefined state (causing I2C to act very strangely). */
 	if (temp & 0x02) {
-		printk("Fixed I2C problem on Force CPCI735\n");
+		dev_info(&PIIX4_dev->dev, "Fixed I2C problem on Force CPCI735\n");
 		temp = temp & 0xfd;
 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
 	}


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24             ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.6, 2003/08/14 14:31:21-07:00, rusty@linux.co.intel.com

[PATCH] I2C: bugfix for initialization bug in adm1021 driver

While initializing the adm1021 device, the driver is performing a conversion
from fixed point to Celcius on values that were declaired as Celcius.  On
my Dell Precision 220 this results in a shutdown after a couple of minutes
running.

This is a very simple patch against the 2.6.0-test3 tree that just removes the
conversion.


 drivers/i2c/chips/adm1021.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Fri Aug 15 11:26:53 2003
+++ b/drivers/i2c/chips/adm1021.c	Fri Aug 15 11:26:53 2003
@@ -356,13 +356,13 @@
 {
 	/* Initialize the adm1021 chip */
 	adm1021_write_value(client, ADM1021_REG_TOS_W,
-			    TEMP_TO_REG(adm1021_INIT_TOS));
+			    adm1021_INIT_TOS);
 	adm1021_write_value(client, ADM1021_REG_THYST_W,
-			    TEMP_TO_REG(adm1021_INIT_THYST));
+			    adm1021_INIT_THYST);
 	adm1021_write_value(client, ADM1021_REG_REMOTE_TOS_W,
-			    TEMP_TO_REG(adm1021_INIT_REMOTE_TOS));
+			    adm1021_INIT_REMOTE_TOS);
 	adm1021_write_value(client, ADM1021_REG_REMOTE_THYST_W,
-			    TEMP_TO_REG(adm1021_INIT_REMOTE_THYST));
+			    adm1021_INIT_REMOTE_THYST);
 	/* Enable ADC and disable suspend mode */
 	adm1021_write_value(client, ADM1021_REG_CONFIG_W, 0);
 	/* Set Conversion rate to 1/sec (this can be tinkered with) */


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24           ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.5, 2003/08/14 14:13:01-07:00, mhoffman@lightlink.com

[PATCH] I2C: i2c nforce2.c fixes

This patch restores a line that was wrongly removed.  There are also some
trivial cleanups.  It applies & compiles vs. 2.6.0-test3.  It's untested
(no hardware here).


 drivers/i2c/busses/i2c-nforce2.c |   29 +++++------------------------
 1 files changed, 5 insertions(+), 24 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Fri Aug 15 11:26:57 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Fri Aug 15 11:26:57 2003
@@ -51,10 +51,6 @@
 #ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS   0x0064
 #endif
-/* TODO: sync with lm-sensors */
-#ifndef I2C_HW_SMBUS_NFORCE2
-#define I2C_HW_SMBUS_NFORCE2	0x0c
-#endif
 
 
 struct nforce2_smbus {
@@ -128,20 +124,10 @@
 	.name   	= "unset",
 };
 
-
-#if 0
-/* Internally used pause function */
-static void nforce2_do_pause(unsigned int amount)
-{
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(amount);
-}
-#endif
-
 /* Return -1 on error. See smbus.h for more information */
-static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
-		char read_write, u8 command, int size,
-		union i2c_smbus_data * data)
+static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
+		unsigned short flags, char read_write,
+		u8 command, int size, union i2c_smbus_data * data)
 {
 	struct nforce2_smbus *smbus = adap->algo_data;
 	unsigned char protocol, pec, temp;
@@ -249,7 +235,7 @@
 
 #if 0
 	do {
-		nforce2_do_pause(1);
+		i2c_do_pause(1);
 		temp = inb_p(NVIDIA_SMB_STS);
 	} while (((temp & NVIDIA_SMB_STS_DONE) = 0) && (timeout++ < MAX_TIMEOUT));
 #endif
@@ -332,13 +318,8 @@
 			smbus->base, smbus->base+smbus->size-1, name);
 		return -1;
 	}
-/*
-	smbus->adapter.owner = THIS_MODULE;
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2;
-	smbus->adapter.algo = &smbus_algorithm;
-	smbus->adapter.algo_data = smbus;
-*/
 	smbus->adapter = nforce2_adapter;
+	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
 	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24               ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.7, 2003/08/14 14:46:08-07:00, greg@kroah.com

[PATCH] I2C: fix up the wording for the pii4x bugfix.


 drivers/i2c/busses/i2c-piix4.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:26:49 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Fri Aug 15 11:26:49 2003
@@ -164,7 +164,7 @@
 	/* Some BIOS will set up the chipset incorrectly and leave a register
 	   in an undefined state (causing I2C to act very strangely). */
 	if (temp & 0x02) {
-		dev_info(&PIIX4_dev->dev, "Fixed I2C problem on Force CPCI735\n");
+		dev_info(&PIIX4_dev->dev, "Worked around buggy BIOS (I2C)\n");
 		temp = temp & 0xfd;
 		pci_write_config_byte(PIIX4_dev, SMBHSTCFG, temp);
 	}


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
@ 2005-05-19  6:24                 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1123.18.8, 2003/08/15 11:06:52-07:00, greg@kroah.com

I2C: add adapter and client name files as the driver core no longer provides them.


 drivers/i2c/i2c-core.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+)


diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Fri Aug 15 11:26:44 2003
+++ b/drivers/i2c/i2c-core.c	Fri Aug 15 11:26:44 2003
@@ -79,12 +79,36 @@
 	.release =	&i2c_adapter_class_dev_release,
 };
 
+static ssize_t show_adapter_name(struct device *dev, char *buf)
+{
+	struct i2c_adapter *adap = dev_to_i2c_adapter(dev);
+	return sprintf(buf, "%s\n", adap->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
+
+
 static void i2c_client_release(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	complete(&client->released);
 }
 
+static ssize_t show_client_name(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	return sprintf(buf, "%s\n", client->name);
+}
+
+/* 
+ * We can't use the DEVICE_ATTR() macro here as we want the same filename for a
+ * different type of a device.  So beware if the DEVICE_ATTR() macro ever
+ * changes, this definition will also have to change.
+ */
+static struct device_attribute dev_attr_client_name = {
+	.attr	= {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE },
+	.show	= &show_client_name,
+};
+
 
 /* ---------------------------------------------------
  * registering functions 
@@ -120,6 +144,7 @@
 	adap->dev.driver = &i2c_adapter_driver;
 	adap->dev.release = &i2c_adapter_dev_release;
 	device_register(&adap->dev);
+	device_create_file(&adap->dev, &dev_attr_name);
 
 	/* Add this adapter to the i2c_adapter class */
 	memset(&adap->class_dev, 0x00, sizeof(struct class_device));
@@ -184,6 +209,7 @@
 	init_completion(&adap->dev_released);
 	init_completion(&adap->class_dev_released);
 	class_device_unregister(&adap->class_dev);
+	device_remove_file(&adap->dev, &dev_attr_name);
 	device_unregister(&adap->dev);
 	list_del(&adap->list);
 
@@ -361,6 +387,7 @@
 		"%d-%04x", i2c_adapter_id(adapter), client->addr);
 	printk("registering %s\n", client->dev.bus_id);
 	device_register(&client->dev);
+	device_create_file(&client->dev, &dev_attr_client_name);
 	
 	return 0;
 }
@@ -387,6 +414,7 @@
 	down(&adapter->clist_lock);
 	list_del(&client->list);
 	init_completion(&client->released);
+	device_remove_file(&client->dev, &dev_attr_client_name);
 	device_unregister(&client->dev);
 	up(&adapter->clist_lock);
 	wait_for_completion(&client->released);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
  (?)
  (?)
@ 2005-05-19  6:24     ` Philip Pokorny
  -1 siblings, 0 replies; 125+ messages in thread
From: Philip Pokorny @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

Why don't we just make it policy that now and in the future we don't 
initialize the limits on the sensors?

We don't know in what crazy way a motherboard manufacturer may have wired or 
scaled the inputs and with the newer sensors, it's leading to shutdowns and 
fan spinup behavior that is "less than optimal".

If the BIOS knows what reasonable limits are, it will set them and we are 
better off reading and displaying those values than resetting them.  If the 
BIOS hasn't set any limits, the hardware almost always (does anyone have a 
counter example?) initializes with the limits at the extreme values.  No harm 
there.  We've got (or had...) a user space library that could initialize 
limits with much more configurability than the drivers ever will have.

I'd really like to see this whole initialization mess go away...

And it would make the drivers blah-blah lines smaller ... :)

:v)

Greg KH wrote:

> ChangeSet 1.1123.18.6, 2003/08/14 14:31:21-07:00, rusty@linux.co.intel.com
> 
> [PATCH] I2C: bugfix for initialization bug in adm1021 driver
> 
> While initializing the adm1021 device, the driver is performing a conversion
> from fixed point to Celcius on values that were declaired as Celcius.  On
> my Dell Precision 220 this results in a shutdown after a couple of minutes
> running.
> 
> This is a very simple patch against the 2.6.0-test3 tree that just removes the
> conversion.
> 
> 
>  drivers/i2c/chips/adm1021.c |    8 ++++----
>  1 files changed, 4 insertions(+), 4 deletions(-)
> 
> 
> diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
> --- a/drivers/i2c/chips/adm1021.c	Fri Aug 15 11:26:53 2003
> +++ b/drivers/i2c/chips/adm1021.c	Fri Aug 15 11:26:53 2003
> @@ -356,13 +356,13 @@
>  {
>  	/* Initialize the adm1021 chip */
>  	adm1021_write_value(client, ADM1021_REG_TOS_W,
> -			    TEMP_TO_REG(adm1021_INIT_TOS));
> +			    adm1021_INIT_TOS);
>  	adm1021_write_value(client, ADM1021_REG_THYST_W,
> -			    TEMP_TO_REG(adm1021_INIT_THYST));
> +			    adm1021_INIT_THYST);
>  	adm1021_write_value(client, ADM1021_REG_REMOTE_TOS_W,
> -			    TEMP_TO_REG(adm1021_INIT_REMOTE_TOS));
> +			    adm1021_INIT_REMOTE_TOS);
>  	adm1021_write_value(client, ADM1021_REG_REMOTE_THYST_W,
> -			    TEMP_TO_REG(adm1021_INIT_REMOTE_THYST));
> +			    adm1021_INIT_REMOTE_THYST);
>  	/* Enable ADC and disable suspend mode */
>  	adm1021_write_value(client, ADM1021_REG_CONFIG_W, 0);
>  	/* Set Conversion rate to 1/sec (this can be tinkered with) */
> 
> 
> 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
                       ` (2 preceding siblings ...)
  (?)
@ 2005-05-19  6:24     ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

On Sun, Aug 17, 2003 at 05:32:19PM -0700, Philip Pokorny wrote:
> Why don't we just make it policy that now and in the future we don't 
> initialize the limits on the sensors?

Sounds good to me.  Anyone want to test the existing 2.6 drivers with
the init code ripped out from them and send me a patch?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
                       ` (3 preceding siblings ...)
  (?)
@ 2005-05-19  6:24     ` Jean Delvare
  -1 siblings, 0 replies; 125+ messages in thread
From: Jean Delvare @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors


> Why don't we just make it policy that now and in the future we don't 
> initialize the limits on the sensors?
> (...)

I think I agree. As long as it doesn't cause extra problems, I believe
the drivers should be kept as simple and "neutral" as possible. If
certain drivers really have to intialize limits for any reason, it's OK,
but I don't object against the default policy being to not initialize.

(Which doesn't mean I'll rush to remove initializations in "my"
drivers".)

> We don't know in what crazy way a motherboard manufacturer may have
> wired or scaled the inputs and with the newer sensors, it's leading to
> shutdowns and fan spinup behavior that is "less than optimal".

In this precise case, the reason is not initializing, but initializing
with awful values. That's different.

-- 
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
                       ` (4 preceding siblings ...)
  (?)
@ 2005-05-19  6:24     ` Mark D. Studebaker 
  -1 siblings, 0 replies; 125+ messages in thread
From: Mark D. Studebaker  @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

agreed. it causes lots of problems, e.g. "I loaded your driver and my PC beeped like crazy and then shut down".

should we do this for 2.8.1?

Jean Delvare wrote:
>>Why don't we just make it policy that now and in the future we don't 
>>initialize the limits on the sensors?
>>(...)
> 
> 
> I think I agree. As long as it doesn't cause extra problems, I believe
> the drivers should be kept as simple and "neutral" as possible. If
> certain drivers really have to intialize limits for any reason, it's OK,
> but I don't object against the default policy being to not initialize.
> 
> (Which doesn't mean I'll rush to remove initializations in "my"
> drivers".)
> 
> 
>>We don't know in what crazy way a motherboard manufacturer may have
>>wired or scaled the inputs and with the newer sensors, it's leading to
>>shutdowns and fan spinup behavior that is "less than optimal".
> 
> 
> In this precise case, the reason is not initializing, but initializing
> with awful values. That's different.
> 

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver changes 2.6.0-test3
  2005-05-19  6:24     ` Greg KH
                       ` (5 preceding siblings ...)
  (?)
@ 2005-05-19  6:24     ` Jean Delvare
  -1 siblings, 0 replies; 125+ messages in thread
From: Jean Delvare @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors


> agreed. it causes lots of problems, e.g. "I loaded your driver and my
> PC beeped like crazy and then shut down".

Yes, I remember these ones.

> should we do this for 2.8.1?

It's not required. To me, 2.8.1 has to be released right after Linux
2.4.22 so that we can have our i2c subsystem go into Linux 2.4. The rest
if far less important. 




> Jean Delvare wrote:
> >>Why don't we just make it policy that now and in the future we don't
> >
> >>initialize the limits on the sensors?
> >>(...)
> > 
> > 
> > I think I agree. As long as it doesn't cause extra problems, I
> > believe the drivers should be kept as simple and "neutral" as
> > possible. If certain drivers really have to intialize limits for any
> > reason, it's OK, but I don't object against the default policy being
> > to not initialize.
> > 
> > (Which doesn't mean I'll rush to remove initializations in "my"
> > drivers".)
> > 
> > 
> >>We don't know in what crazy way a motherboard manufacturer may have
> >>wired or scaled the inputs and with the newer sensors, it's leading
> >to>shutdowns and fan spinup behavior that is "less than optimal".
> > 
> > 
> > In this precise case, the reason is not initializing, but
> > initializing with awful values. That's different.
> > 
> 


-- 
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24     ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.2, 2003/08/27 15:29:33-07:00, mds@paradyne.com

[PATCH] I2C: i2c-isa functionality

The "functionality" return was incorrectly removed for i2c-isa.c when porting to 2.5.
A driver that does nothing must return a 0 or else i2c-core assumes
0xffffffff (all functionality).


 drivers/i2c/busses/i2c-isa.c |    9 +++++++++
 1 files changed, 9 insertions(+)


diff -Nru a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
--- a/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:17:05 2003
+++ b/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:17:05 2003
@@ -30,10 +30,13 @@
 #include <linux/errno.h>
 #include <linux/i2c.h>
 
+static u32 isa_func(struct i2c_adapter *adapter);
+
 /* This is the actual algorithm we define */
 static struct i2c_algorithm isa_algorithm = {
 	.name		= "ISA bus algorithm",
 	.id		= I2C_ALGO_ISA,
+	.functionality	= isa_func,
 };
 
 /* There can only be one... */
@@ -44,6 +47,12 @@
 	.algo		= &isa_algorithm,
 	.name		= "ISA main adapter",
 };
+
+/* We can't do a thing... */
+static u32 isa_func(struct i2c_adapter *adapter)
+{
+	return 0;
+}
 
 static int __init i2c_isa_init(void)
 {


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24   ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.1, 2003/08/27 15:24:53-07:00, greg@kroah.com

[PATCH] I2C: added new id for Radeon driver.

As requested by kronos@kronoz.cjb.net


 include/linux/i2c-id.h |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/include/linux/i2c-id.h b/include/linux/i2c-id.h
--- a/include/linux/i2c-id.h	Mon Sep 22 16:17:15 2003
+++ b/include/linux/i2c-id.h	Mon Sep 22 16:17:15 2003
@@ -100,7 +100,7 @@
 #define I2C_DRIVERID_STM41T00	52	/* real time clock		*/
 #define I2C_DRIVERID_UDA1342	53	/* UDA1342 audio codec		*/
 #define I2C_DRIVERID_ADV7170	54	/* video encoder		*/
-
+#define I2C_DRIVERID_RADEON	55	/* I2C bus on Radeon boards	*/
 
 
 #define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.3, 2003/08/27 15:32:28-07:00, hirofumi@mail.parknet.co.jp

[PATCH] DEVICE_NAME_SIZE/_HALF removal (I2C stuff)


 drivers/i2c/busses/i2c-ali1535.c |    2 +-
 drivers/i2c/busses/i2c-ali15x3.c |    2 +-
 drivers/i2c/busses/i2c-amd756.c  |    2 +-
 drivers/i2c/busses/i2c-amd8111.c |    2 +-
 drivers/i2c/busses/i2c-i801.c    |    2 +-
 drivers/i2c/busses/i2c-nforce2.c |    2 +-
 drivers/i2c/busses/i2c-piix4.c   |    2 +-
 drivers/i2c/busses/i2c-sis96x.c  |    2 +-
 drivers/i2c/busses/i2c-viapro.c  |    2 +-
 drivers/i2c/chips/adm1021.c      |    2 +-
 drivers/i2c/chips/it87.c         |    2 +-
 drivers/i2c/chips/lm75.c         |    2 +-
 drivers/i2c/chips/lm78.c         |    2 +-
 drivers/i2c/chips/lm85.c         |   10 +++++-----
 drivers/i2c/chips/via686a.c      |    2 +-
 drivers/i2c/chips/w83781d.c      |    4 ++--
 drivers/i2c/scx200_acb.c         |    2 +-
 include/linux/i2c.h              |    6 ++++--
 18 files changed, 26 insertions(+), 24 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:54 2003
@@ -507,7 +507,7 @@
 	/* set up the driverfs linkage to our parent device */
 	ali1535_adapter.dev.parent = &dev->dev;
 
-	snprintf(ali1535_adapter.name, DEVICE_NAME_SIZE, 
+	snprintf(ali1535_adapter.name, I2C_NAME_SIZE, 
 		"SMBus ALI1535 adapter at %04x", ali1535_smba);
 	return i2c_add_adapter(&ali1535_adapter);
 }
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:54 2003
@@ -498,7 +498,7 @@
 	/* set up the driverfs linkage to our parent device */
 	ali15x3_adapter.dev.parent = &dev->dev;
 
-	snprintf(ali15x3_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(ali15x3_adapter.name, I2C_NAME_SIZE,
 		"SMBus ALI15X3 adapter at %04x", ali15x3_smba);
 	return i2c_add_adapter(&ali15x3_adapter);
 }
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:54 2003
@@ -369,7 +369,7 @@
 	/* set up the driverfs linkage to our parent device */
 	amd756_adapter.dev.parent = &pdev->dev;
 
-	snprintf(amd756_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(amd756_adapter.name, I2C_NAME_SIZE,
 		"SMBus AMD75x adapter at %04x", amd756_ioport);
 
 	error = i2c_add_adapter(&amd756_adapter);
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:54 2003
@@ -356,7 +356,7 @@
 		goto out_kfree;
 
 	smbus->adapter.owner = THIS_MODULE;
-	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
+	snprintf(smbus->adapter.name, I2C_NAME_SIZE,
 		"SMBus2 AMD8111 adapter at %04x", smbus->base);
 	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
 	smbus->adapter.class = I2C_ADAP_CLASS_SMBUS;
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:54 2003
@@ -598,7 +598,7 @@
 	/* set up the driverfs linkage to our parent device */
 	i801_adapter.dev.parent = &dev->dev;
 
-	snprintf(i801_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(i801_adapter.name, I2C_NAME_SIZE,
 		"SMBus I801 adapter at %04x", i801_smba);
 	return i2c_add_adapter(&i801_adapter);
 }
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:54 2003
@@ -321,7 +321,7 @@
 	smbus->adapter = nforce2_adapter;
 	smbus->adapter.algo_data = smbus;
 	smbus->adapter.dev.parent = &dev->dev;
-	snprintf(smbus->adapter.name, DEVICE_NAME_SIZE,
+	snprintf(smbus->adapter.name, I2C_NAME_SIZE,
 		"SMBus nForce2 adapter at %04x", smbus->base);
 
 	error = i2c_add_adapter(&smbus->adapter);
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:54 2003
@@ -451,7 +451,7 @@
 	/* set up the driverfs linkage to our parent device */
 	piix4_adapter.dev.parent = &dev->dev;
 
-	snprintf(piix4_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(piix4_adapter.name, I2C_NAME_SIZE,
 		"SMBus PIIX4 adapter at %04x", piix4_smba);
 
 	retval = i2c_add_adapter(&piix4_adapter);
diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:54 2003
@@ -318,7 +318,7 @@
 	/* set up the driverfs linkage to our parent device */
 	sis96x_adapter.dev.parent = &dev->dev;
 
-	snprintf(sis96x_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(sis96x_adapter.name, I2C_NAME_SIZE,
 		"SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base);
 
 	if ((retval = i2c_add_adapter(&sis96x_adapter))) {
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:54 2003
@@ -376,7 +376,7 @@
 	dev_dbg(&pdev->dev, "VT596_smba = 0x%X\n", vt596_smba);
 
 	vt596_adapter.dev.parent = &pdev->dev;
-	snprintf(vt596_adapter.name, DEVICE_NAME_SIZE,
+	snprintf(vt596_adapter.name, I2C_NAME_SIZE,
 			"SMBus Via Pro adapter at %04x", vt596_smba);
 	
 	return i2c_add_adapter(&vt596_adapter);
diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:16:54 2003
@@ -320,7 +320,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	new_client->id = adm1021_id++;
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/it87.c	Mon Sep 22 16:16:54 2003
@@ -692,7 +692,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
 
 	data->type = kind;
 
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/lm75.c	Mon Sep 22 16:16:54 2003
@@ -194,7 +194,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, name, I2C_NAME_SIZE);
 
 	new_client->id = lm75_id++;
 	data->valid = 0;
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/lm78.c	Mon Sep 22 16:16:54 2003
@@ -638,7 +638,7 @@
 	}
 
 	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	data->valid = 0;
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/lm85.c	Mon Sep 22 16:16:54 2003
@@ -853,19 +853,19 @@
 	/* Fill in the chip specific driver values */
 	if ( kind = any_chip ) {
 		type_name = "lm85";
-		strlcpy(new_client->name, "Generic LM85", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "Generic LM85", I2C_NAME_SIZE);
 	} else if ( kind = lm85b ) {
 		type_name = "lm85b";
-		strlcpy(new_client->name, "National LM85-B", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "National LM85-B", I2C_NAME_SIZE);
 	} else if ( kind = lm85c ) {
 		type_name = "lm85c";
-		strlcpy(new_client->name, "National LM85-C", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "National LM85-C", I2C_NAME_SIZE);
 	} else if ( kind = adm1027 ) {
 		type_name = "adm1027";
-		strlcpy(new_client->name, "Analog Devices ADM1027", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "Analog Devices ADM1027", I2C_NAME_SIZE);
 	} else if ( kind = adt7463 ) {
 		type_name = "adt7463";
-		strlcpy(new_client->name, "Analog Devices ADT7463", DEVICE_NAME_SIZE);
+		strlcpy(new_client->name, "Analog Devices ADT7463", I2C_NAME_SIZE);
 	} else {
 		dev_dbg(&adapter->dev, "Internal error, invalid kind (%d)!", kind);
 		err = -EFAULT ;
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/via686a.c	Mon Sep 22 16:16:54 2003
@@ -727,7 +727,7 @@
 	new_client->dev.parent = &adapter->dev;
 
 	/* Fill in the remaining client fields and put into the global list */
-	snprintf(new_client->name, DEVICE_NAME_SIZE, client_name);
+	snprintf(new_client->name, I2C_NAME_SIZE, client_name);
 
 	data->valid = 0;
 	init_MUTEX(&data->update_lock);
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:54 2003
@@ -1117,7 +1117,7 @@
 		data->lm75[i]->driver = &w83781d_driver;
 		data->lm75[i]->flags = 0;
 		strlcpy(data->lm75[i]->name, client_name,
-			DEVICE_NAME_SIZE);
+			I2C_NAME_SIZE);
 		if ((err = i2c_attach_client(data->lm75[i]))) {
 			dev_err(&new_client->dev, "Subclient %d "
 				"registration at address 0x%x "
@@ -1326,7 +1326,7 @@
 	}
 
 	/* Fill in the remaining client fields and put into the global list */
-	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	data->valid = 0;
diff -Nru a/drivers/i2c/scx200_acb.c b/drivers/i2c/scx200_acb.c
--- a/drivers/i2c/scx200_acb.c	Mon Sep 22 16:16:54 2003
+++ b/drivers/i2c/scx200_acb.c	Mon Sep 22 16:16:54 2003
@@ -456,7 +456,7 @@
 	memset(iface, 0, sizeof(*iface));
 	adapter = &iface->adapter;
 	i2c_set_adapdata(adapter, iface);
-	snprintf(adapter->name, DEVICE_NAME_SIZE, "SCx200 ACB%d", index);
+	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
 	adapter->owner = THIS_MODULE;
 	adapter->id = I2C_ALGO_SMBUS;
 	adapter->algo = &scx200_acb_algorithm;
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Mon Sep 22 16:16:54 2003
+++ b/include/linux/i2c.h	Mon Sep 22 16:16:54 2003
@@ -146,6 +146,8 @@
 
 extern struct bus_type i2c_bus_type;
 
+#define I2C_NAME_SIZE	50
+
 /*
  * i2c_client identifies a single device (i.e. chip) that is connected to an 
  * i2c bus. The behaviour is defined by the routines of the driver. This
@@ -166,7 +168,7 @@
 					/* to the client		*/
 	struct device dev;		/* the device structure		*/
 	struct list_head list;
-	char name[DEVICE_NAME_SIZE];
+	char name[I2C_NAME_SIZE];
 	struct completion released;
 };
 #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
@@ -253,7 +255,7 @@
 	int nr;
 	struct list_head clients;
 	struct list_head list;
-	char name[DEVICE_NAME_SIZE];
+	char name[I2C_NAME_SIZE];
 	struct completion dev_released;
 	struct completion class_dev_released;
 };


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24           ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.5, 2003/08/27 15:32:59-07:00, hirofumi@mail.parknet.co.jp

[PATCH] DEVICE_NAME_SIZE/_HALF removal (I2C related, but fb stuff)


 drivers/video/matrox/i2c-matroxfb.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
--- a/drivers/video/matrox/i2c-matroxfb.c	Mon Sep 22 16:16:30 2003
+++ b/drivers/video/matrox/i2c-matroxfb.c	Mon Sep 22 16:16:30 2003
@@ -111,7 +111,7 @@
 	b->mask.data = data;
 	b->mask.clock = clock;
 	b->adapter = matrox_i2c_adapter_template;
-	snprintf(b->adapter.name, DEVICE_NAME_SIZE, name,
+	snprintf(b->adapter.name, I2C_NAME_SIZE, name,
 		minfo->fbcon.node);
 	i2c_set_adapdata(&b->adapter, b);
 	b->adapter.algo_data = &b->bac;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24             ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.123.2, 2003/09/04 11:28:46-07:00, azarah@gentoo.org

[PATCH] I2C: Fix conversion from milli volts in store_in_reg() for w83781d.c

I am not sure if it was a later patch from me that fixed in_* to display
milli volts in sysfs, or if it was a patch from Jan Dittmer, but the
conversion in the store_in_*() functions is wrong, and cause something
like:


 drivers/i2c/chips/w83781d.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:19 2003
+++ b/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:16:19 2003
@@ -378,8 +378,8 @@
 	struct w83781d_data *data = i2c_get_clientdata(client); \
 	u32 val; \
 	 \
-	val = simple_strtoul(buf, NULL, 10); \
-	data->in_##reg[nr] = (IN_TO_REG(val) / 10); \
+	val = simple_strtoul(buf, NULL, 10) / 10; \
+	data->in_##reg[nr] = IN_TO_REG(val); \
 	w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
 	 \
 	return count; \


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1153.85.4, 2003/08/27 15:32:44-07:00, hirofumi@mail.parknet.co.jp

[PATCH] DEVICE_NAME_SIZE/_HALF removal (I2C related, but v4l stuff)


 drivers/media/video/msp3400.c |    2 +-
 drivers/media/video/saa5249.c |    2 +-
 drivers/media/video/tuner.c   |    4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
--- a/drivers/media/video/msp3400.c	Mon Sep 22 16:16:43 2003
+++ b/drivers/media/video/msp3400.c	Mon Sep 22 16:16:43 2003
@@ -1316,7 +1316,7 @@
 #endif
 	msp3400c_setvolume(c,msp->muted,msp->left,msp->right);
 
-	snprintf(c->name, DEVICE_NAME_SIZE, "MSP34%02d%c-%c%d",
+	snprintf(c->name, I2C_NAME_SIZE, "MSP34%02d%c-%c%d",
 		 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@',
 		 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
 
diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
--- a/drivers/media/video/saa5249.c	Mon Sep 22 16:16:43 2003
+++ b/drivers/media/video/saa5249.c	Mon Sep 22 16:16:43 2003
@@ -171,7 +171,7 @@
 		return -ENOMEM;
 	}
 	memset(t, 0, sizeof(*t));
-	strlcpy(client->name, IF_NAME, DEVICE_NAME_SIZE);
+	strlcpy(client->name, IF_NAME, I2C_NAME_SIZE);
 	init_MUTEX(&t->lock);
 	
 	/*
diff -Nru a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c
--- a/drivers/media/video/tuner.c	Mon Sep 22 16:16:43 2003
+++ b/drivers/media/video/tuner.c	Mon Sep 22 16:16:43 2003
@@ -824,7 +824,7 @@
 	if (type < TUNERS) {
 		t->type = type;
 		printk("tuner(bttv): type forced to %d (%s) [insmod]\n",t->type,tuners[t->type].name);
-		strlcpy(client->name, tuners[t->type].name, DEVICE_NAME_SIZE);
+		strlcpy(client->name, tuners[t->type].name, I2C_NAME_SIZE);
 	}
         i2c_attach_client(client);
         if (t->type = TUNER_MT2032)
@@ -875,7 +875,7 @@
 		t->type = *iarg;
 		printk("tuner: type set to %d (%s)\n",
                         t->type,tuners[t->type].name);
-		strlcpy(client->name, tuners[t->type].name, DEVICE_NAME_SIZE);
+		strlcpy(client->name, tuners[t->type].name, I2C_NAME_SIZE);
 		if (t->type = TUNER_MT2032)
                         mt2032_init(client);
 		break;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.2, 2003/09/15 13:46:00-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-sis5595 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig       |   17 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-sis5595.c |  417 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 435 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:57 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:57 2003
@@ -149,6 +149,23 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_SIS5595
+	tristate "  Sis5595"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the 
+	  SiS5595 SMBus (a subset of I2C) interface.
+
+	  This can also be built as a module which can be inserted and removed 
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-sis5595.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at 
+	  http://www.lm-sensors.nu
+
 
 config I2C_SIS96X
 	tristate "  SiS 96x"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:57 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:57 2003
@@ -10,5 +10,6 @@
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:15:57 2003
@@ -0,0 +1,417 @@
+/*
+    sis5595.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
+    Philip Edelbrock <phil@netroedge.com>
+
+    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.
+*/
+
+/* Note: we assume there can only be one SIS5595 with one SMBus interface */
+
+/*
+   Note: all have mfr. ID 0x1039.
+   SUPPORTED		PCI ID		
+	5595		0008
+
+   Note: these chips contain a 0008 device which is incompatible with the
+         5595. We recognize these by the presence of the listed
+         "blacklist" PCI ID and refuse to load.
+
+   NOT SUPPORTED	PCI ID		BLACKLIST PCI ID	
+	 540		0008		0540
+	 550		0008		0550
+	5513		0008		5511
+	5581		0008		5597
+	5582		0008		5597
+	5597		0008		5597
+	5598		0008		5597/5598
+	 630		0008		0630
+	 645		0008		0645
+	 646		0008		0646
+	 648		0008		0648
+	 650		0008		0650
+	 651		0008		0651
+	 730		0008		0730
+	 735		0008		0735
+	 745		0008		0745
+	 746		0008		0746
+*/
+
+/* TO DO: 
+ * Add Block Transfers (ugly, but supported by the adapter)
+ * Add adapter resets
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+static int blacklist[] = {
+	PCI_DEVICE_ID_SI_540,
+	PCI_DEVICE_ID_SI_550,
+	PCI_DEVICE_ID_SI_630,
+	PCI_DEVICE_ID_SI_645,
+	PCI_DEVICE_ID_SI_646,
+	PCI_DEVICE_ID_SI_648,
+	PCI_DEVICE_ID_SI_650,
+	PCI_DEVICE_ID_SI_651,
+	PCI_DEVICE_ID_SI_730,
+	PCI_DEVICE_ID_SI_735,
+	PCI_DEVICE_ID_SI_745,
+	PCI_DEVICE_ID_SI_746,
+	PCI_DEVICE_ID_SI_5511,	/* 5513 chip has the 0008 device but that ID
+				   shows up in other chips so we use the 5511
+				   ID for recognition */
+	PCI_DEVICE_ID_SI_5597,
+	PCI_DEVICE_ID_SI_5598,
+	0,			/* terminates the list */
+};
+
+/* Length of ISA address segment */
+#define SIS5595_EXTENT		8
+/* SIS5595 SMBus registers */
+#define SMB_STS_LO		0x00
+#define SMB_STS_HI		0x01
+#define SMB_CTL_LO		0x02
+#define SMB_CTL_HI		0x03
+#define SMB_ADDR		0x04
+#define SMB_CMD			0x05
+#define SMB_PCNT		0x06
+#define SMB_CNT			0x07
+#define SMB_BYTE		0x08
+#define SMB_DEV			0x10
+#define SMB_DB0			0x11
+#define SMB_DB1			0x12
+#define SMB_HAA			0x13
+
+/* PCI Address Constants */
+#define SMB_INDEX		0x38
+#define SMB_DAT			0x39
+#define SIS5595_ENABLE_REG	0x40
+#define ACPI_BASE		0x90
+
+/* Other settings */
+#define MAX_TIMEOUT		500
+
+/* SIS5595 constants */
+#define SIS5595_QUICK		0x00
+#define SIS5595_BYTE		0x02
+#define SIS5595_BYTE_DATA	0x04
+#define SIS5595_WORD_DATA	0x06
+#define SIS5595_PROC_CALL	0x08
+#define SIS5595_BLOCK_DATA	0x0A
+
+/* insmod parameters */
+
+/* If force_addr is set to anything different from 0, we forcibly enable
+   the device at the given address. */
+static int force_addr = 0;
+MODULE_PARM(force_addr, "i");
+MODULE_PARM_DESC(force_addr, "Initialize the base address of the i2c controller");
+
+static unsigned short sis5595_base = 0;
+
+static u8 sis5595_read(u8 reg)
+{
+	outb(reg, sis5595_base + SMB_INDEX);
+	return inb(sis5595_base + SMB_DAT);
+}
+
+static void sis5595_write(u8 reg, u8 data)
+{
+	outb(reg, sis5595_base + SMB_INDEX);
+	outb(data, sis5595_base + SMB_DAT);
+}
+
+static int sis5595_setup(struct pci_dev *SIS5595_dev)
+{
+	u16 a;
+	u8 val;
+	int *i;
+	int retval = -ENODEV;
+
+	/* Look for imposters */
+	for (i = blacklist; *i != 0; i++) {
+		struct pci_dev *dev;
+		dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL);
+		if (dev) {
+			dev_err(&SIS5595_dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i);
+			pci_dev_put(dev);
+			return -ENODEV;
+		}
+	}
+
+	/* Determine the address of the SMBus areas */
+	pci_read_config_word(SIS5595_dev, ACPI_BASE, &sis5595_base);
+	if (sis5595_base = 0 && force_addr = 0) {
+		dev_err(&SIS5595_dev->dev, "ACPI base address uninitialized - upgrade BIOS or use force_addr=0xaddr\n");
+		return -ENODEV;
+	}
+
+	if (force_addr)
+		sis5595_base = force_addr & ~(SIS5595_EXTENT - 1);
+	dev_dbg(&SIS5595_dev->dev, "ACPI Base address: %04x\n", sis5595_base);
+
+	/* NB: We grab just the two SMBus registers here, but this may still
+	 * interfere with ACPI :-(  */
+	if (!request_region(sis5595_base + SMB_INDEX, 2, "sis5595-smbus")) {
+		dev_err(&SIS5595_dev->dev, "SMBus registers 0x%04x-0x%04x already in use!\n",
+			sis5595_base + SMB_INDEX, sis5595_base + SMB_INDEX + 1);
+		return -ENODEV;
+	}
+
+	if (force_addr) {
+		dev_info(&SIS5595_dev->dev, "forcing ISA address 0x%04X\n", sis5595_base);
+		if (!pci_write_config_word(SIS5595_dev, ACPI_BASE, sis5595_base))
+			goto error;
+		if (!pci_read_config_word(SIS5595_dev, ACPI_BASE, &a))
+			goto error;
+		if ((a & ~(SIS5595_EXTENT - 1)) != sis5595_base) {
+			/* doesn't work for some chips! */
+			dev_err(&SIS5595_dev->dev, "force address failed - not supported?\n");
+			goto error;
+		}
+	}
+
+	if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val))
+		goto error;
+	if ((val & 0x80) = 0) {
+		dev_info(&SIS5595_dev->dev, "enabling ACPI\n");
+		if (!pci_write_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, val | 0x80))
+			goto error;
+		if (!pci_read_config_byte(SIS5595_dev, SIS5595_ENABLE_REG, &val))
+			goto error;
+		if ((val & 0x80) = 0) {
+			/* doesn't work for some chips? */
+			dev_err(&SIS5595_dev->dev, "ACPI enable failed - not supported?\n");
+			goto error;
+		}
+	}
+
+	/* Everything is happy */
+	return 0;
+
+error:
+	release_region(sis5595_base + SMB_INDEX, 2);
+	return retval;
+}
+
+static int sis5595_transaction(struct i2c_adapter *adap)
+{
+	int temp;
+	int result = 0;
+	int timeout = 0;
+
+	/* Make sure the SMBus host is ready to start transmitting */
+	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
+	if (temp != 0x00) {
+		dev_dbg(&adap->dev, "SMBus busy (%04x). Resetting... \n", temp);
+		sis5595_write(SMB_STS_LO, temp & 0xff);
+		sis5595_write(SMB_STS_HI, temp >> 8);
+		if ((temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8)) != 0x00) {
+			dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
+			return -1;
+		} else {
+			dev_dbg(&adap->dev, "Successfull!\n");
+		}
+	}
+
+	/* start the transaction by setting bit 4 */
+	sis5595_write(SMB_CTL_LO, sis5595_read(SMB_CTL_LO) | 0x10);
+
+	/* We will always wait for a fraction of a second! */
+	do {
+		i2c_delay(1);
+		temp = sis5595_read(SMB_STS_LO);
+	} while (!(temp & 0x40) && (timeout++ < MAX_TIMEOUT));
+
+	/* If the SMBus is still busy, we give up */
+	if (timeout >= MAX_TIMEOUT) {
+		dev_dbg(&adap->dev, "SMBus Timeout!\n");
+		result = -1;
+	}
+
+	if (temp & 0x10) {
+		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
+		result = -1;
+	}
+
+	if (temp & 0x20) {
+		dev_err(&adap->dev, "Bus collision! SMBus may be locked until "
+			"next hard reset (or not...)\n");
+		/* Clock stops and slave is stuck in mid-transmission */
+		result = -1;
+	}
+
+	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
+	if (temp != 0x00) {
+		sis5595_write(SMB_STS_LO, temp & 0xff);
+		sis5595_write(SMB_STS_HI, temp >> 8);
+	}
+
+	temp = sis5595_read(SMB_STS_LO) + (sis5595_read(SMB_STS_HI) << 8);
+	if (temp != 0x00)
+		dev_dbg(&adap->dev, "Failed reset at end of transaction (%02x)\n", temp);
+
+	return result;
+}
+
+/* Return -1 on error. */
+static s32 sis5595_access(struct i2c_adapter *adap, u16 addr,
+			  unsigned short flags, char read_write,
+			  u8 command, int size, union i2c_smbus_data *data)
+{
+	switch (size) {
+	case I2C_SMBUS_QUICK:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		size = SIS5595_QUICK;
+		break;
+	case I2C_SMBUS_BYTE:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		if (read_write = I2C_SMBUS_WRITE)
+			sis5595_write(SMB_CMD, command);
+		size = SIS5595_BYTE;
+		break;
+	case I2C_SMBUS_BYTE_DATA:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		sis5595_write(SMB_CMD, command);
+		if (read_write = I2C_SMBUS_WRITE)
+			sis5595_write(SMB_BYTE, data->byte);
+		size = SIS5595_BYTE_DATA;
+		break;
+	case I2C_SMBUS_PROC_CALL:
+	case I2C_SMBUS_WORD_DATA:
+		sis5595_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+		sis5595_write(SMB_CMD, command);
+		if (read_write = I2C_SMBUS_WRITE) {
+			sis5595_write(SMB_BYTE, data->word & 0xff);
+			sis5595_write(SMB_BYTE + 1,
+				      (data->word & 0xff00) >> 8);
+		}
+		size = (size = I2C_SMBUS_PROC_CALL) ? SIS5595_PROC_CALL : SIS5595_WORD_DATA;
+		break;
+/*
+	case I2C_SMBUS_BLOCK_DATA:
+		printk("sis5595.o: Block data not yet implemented!\n");
+		return -1;
+		break;
+*/
+	default:
+		printk
+		    (KERN_WARNING "sis5595.o: Unsupported transaction %d\n", size);
+		return -1;
+	}
+
+	sis5595_write(SMB_CTL_LO, ((size & 0x0E)));
+
+	if (sis5595_transaction(adap))
+		return -1;
+
+	if ((size != SIS5595_PROC_CALL) &&
+	    ((read_write = I2C_SMBUS_WRITE) || (size = SIS5595_QUICK)))
+		return 0;
+
+
+	switch (size) {
+	case SIS5595_BYTE:	/* Where is the result put? I assume here it is in
+				   SMB_DATA but it might just as well be in the
+				   SMB_CMD. No clue in the docs */
+	case SIS5595_BYTE_DATA:
+		data->byte = sis5595_read(SMB_BYTE);
+		break;
+	case SIS5595_WORD_DATA:
+	case SIS5595_PROC_CALL:
+		data->word = sis5595_read(SMB_BYTE) + (sis5595_read(SMB_BYTE + 1) << 8);
+		break;
+	}
+	return 0;
+}
+
+static u32 sis5595_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+	    I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	    I2C_FUNC_SMBUS_PROC_CALL;
+}
+
+static struct i2c_algorithm smbus_algorithm = {
+	.name		= "Non-I2C SMBus adapter",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= sis5595_access,
+	.functionality	= sis5595_func,
+};
+
+static struct i2c_adapter sis5595_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "unset",
+	.algo		= &smbus_algorithm,
+};
+
+static struct pci_device_id sis5595_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, 
+	{ 0, }
+};
+
+static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	if (sis5595_setup(dev)) {
+		dev_err(&dev->dev, "SIS5595 not detected, module not inserted.\n");
+		return -ENODEV;
+	}
+
+	/* set up the driverfs linkage to our parent device */
+	sis5595_adapter.dev.parent = &dev->dev;
+
+	sprintf(sis5595_adapter.name, "SMBus SIS5595 adapter at %04x",
+		sis5595_base + SMB_INDEX);
+	return i2c_add_adapter(&sis5595_adapter);
+}
+
+static void __devexit sis5595_remove(struct pci_dev *dev)
+{
+	i2c_del_adapter(&sis5595_adapter);
+}
+
+static struct pci_driver sis5595_driver = {
+	.name		= "sis5595 smbus",
+	.id_table	= sis5595_ids,
+	.probe		= sis5595_probe,
+	.remove		= __devexit_p(sis5595_remove),
+};
+
+static int __init i2c_sis5595_init(void)
+{
+	printk(KERN_INFO "i2c-sis5595 version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	return pci_module_init(&sis5595_driver);
+}
+
+static void __exit i2c_sis5595_exit(void)
+{
+	pci_unregister_driver(&sis5595_driver);
+	release_region(sis5595_base + SMB_INDEX, 2);
+}
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("SIS5595 SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_sis5595_init);
+module_exit(i2c_sis5595_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes and additions for 2.6.0-test5.  I've
ported almost all of the i2c bus drivers from the 2.4 cvs tree to the
2.6 kernel (the one exception is a crazy one that acts like a pci
hotplug driver in its init function, I'll leave that to someone else...)
I've also cleaned up the existing i2c bus drivers by moving them into
the proper directory, and polishing up the Kconfig entries.

There are a also a few other minor i2c cleanups and fixes in here.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.5

thanks,

greg k-h

 drivers/i2c/i2c-adap-ite.c           |  278 ----------
 drivers/i2c/i2c-algo-ibm_ocp.c       |  900 -----------------------------------
 drivers/i2c/i2c-algo-ibm_ocp.h       |   55 --
 drivers/i2c/i2c-elektor.c            |  286 -----------
 drivers/i2c/i2c-elv.c                |  176 ------
 drivers/i2c/i2c-frodo.c              |   85 ---
 drivers/i2c/i2c-ibm_iic.c            |  729 ----------------------------
 drivers/i2c/i2c-ibm_iic.h            |  124 ----
 drivers/i2c/i2c-iop3xx.c             |  536 --------------------
 drivers/i2c/i2c-iop3xx.h             |  118 ----
 drivers/i2c/i2c-keywest.c            |  653 -------------------------
 drivers/i2c/i2c-keywest.h            |  110 ----
 drivers/i2c/i2c-philips-par.c        |  256 ---------
 drivers/i2c/i2c-prosavage.c          |  356 -------------
 drivers/i2c/i2c-rpx.c                |  103 ----
 drivers/i2c/i2c-velleman.c           |  161 ------
 drivers/i2c/scx200_acb.c             |  553 ---------------------
 drivers/i2c/scx200_i2c.c             |  133 -----
 drivers/i2c/Kconfig                  |  237 +--------
 drivers/i2c/Makefile                 |   18 
 drivers/i2c/busses/Kconfig           |  385 +++++++++-----
 drivers/i2c/busses/Makefile          |   22 
 drivers/i2c/busses/i2c-ali1535.c     |    4 
 drivers/i2c/busses/i2c-ali15x3.c     |    4 
 drivers/i2c/busses/i2c-amd756.c      |    4 
 drivers/i2c/busses/i2c-amd8111.c     |    3 
 drivers/i2c/busses/i2c-elektor.c     |  304 +++++++++++
 drivers/i2c/busses/i2c-elv.c         |  197 +++++++
 drivers/i2c/busses/i2c-frodo.c       |   85 +++
 drivers/i2c/busses/i2c-i801.c        |    4 
 drivers/i2c/busses/i2c-i810.c        |  256 +++++++++
 drivers/i2c/busses/i2c-ibm_iic.c     |  729 ++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-ibm_iic.h     |  124 ++++
 drivers/i2c/busses/i2c-iop3xx.c      |  536 ++++++++++++++++++++
 drivers/i2c/busses/i2c-iop3xx.h      |  118 ++++
 drivers/i2c/busses/i2c-isa.c         |   10 
 drivers/i2c/busses/i2c-ite.c         |  278 ++++++++++
 drivers/i2c/busses/i2c-keywest.c     |  653 +++++++++++++++++++++++++
 drivers/i2c/busses/i2c-keywest.h     |  110 ++++
 drivers/i2c/busses/i2c-nforce2.c     |    3 
 drivers/i2c/busses/i2c-philips-par.c |  289 ++++++++++-
 drivers/i2c/busses/i2c-piix4.c       |    4 
 drivers/i2c/busses/i2c-prosavage.c   |  410 ++++++++++++++-
 drivers/i2c/busses/i2c-rpx.c         |  105 ++++
 drivers/i2c/busses/i2c-savage4.c     |  205 +++++++
 drivers/i2c/busses/i2c-sis5595.c     |  420 ++++++++++++++++
 drivers/i2c/busses/i2c-sis630.c      |  497 +++++++++++++++++++
 drivers/i2c/busses/i2c-sis96x.c      |    3 
 drivers/i2c/busses/i2c-velleman.c    |  164 ++++++
 drivers/i2c/busses/i2c-via.c         |  184 +++++++
 drivers/i2c/busses/i2c-viapro.c      |    3 
 drivers/i2c/busses/i2c-voodoo3.c     |  248 +++++++++
 drivers/i2c/busses/scx200_acb.c      |  553 +++++++++++++++++++++
 drivers/i2c/busses/scx200_i2c.c      |  132 +++++
 drivers/i2c/chips/Kconfig            |  111 +---
 drivers/i2c/chips/adm1021.c          |   13 
 drivers/i2c/chips/it87.c             |    5 
 drivers/i2c/chips/lm75.c             |    2 
 drivers/i2c/chips/lm78.c             |    8 
 drivers/i2c/chips/lm85.c             |   16 
 drivers/i2c/chips/via686a.c          |    4 
 drivers/i2c/chips/w83781d.c          |   32 -
 drivers/i2c/i2c-adap-ite.c           |    1 
 drivers/i2c/i2c-algo-ite.c           |    1 
 drivers/i2c/i2c-core.c               |    6 
 drivers/i2c/i2c-dev.c                |    3 
 drivers/i2c/i2c-elektor.c            |    1 
 drivers/i2c/i2c-ibm_iic.c            |  729 ++++++++++++++++++++++++++++
 drivers/i2c/i2c-ibm_iic.h            |  124 ++++
 drivers/i2c/i2c-keywest.c            |    1 
 drivers/i2c/i2c-prosavage.c          |    1 
 drivers/i2c/i2c-sensor.c             |    5 
 drivers/i2c/scx200_acb.c             |    2 
 drivers/media/video/msp3400.c        |    2 
 drivers/media/video/saa5249.c        |    2 
 drivers/media/video/tuner.c          |    4 
 drivers/video/matrox/i2c-matroxfb.c  |    2 
 include/linux/i2c-id.h               |    2 
 include/linux/i2c.h                  |    9 
 79 files changed, 7794 insertions(+), 6205 deletions(-)
-----

<arvidjaar:mail.ru>:
  o I2C: sysfs sensor nameing inconsistency

<mds:paradyne.com>:
  o I2C: i2c-isa functionality

Greg Kroah-Hartman:
  o I2C: remove I2C_VERSION and I2C_DATE as they make no sense in the kernel tree
  o I2C: remove check_region usage and warning from i2c-sensor
  o I2C: move the remaining i2c bus drivers to drivers/i2c/busses
  o I2C: move the scx200* drivers to drivers/i2c/busses
  o I2C: move i2c-velleman driver to drivers/i2c/busses
  o I2C: move i2c-elektor.c driver to drivers/i2c/busses/
  o I2C: clean up the i2c-elv.c driver a bit
  o I2C: move i2c-elv.c driver to drivers/i2c/busses
  o I2C: clean up i2c-philips-par.c driver a bit
  o I2C: move the i2c-philips-par driver to drivers/i2c/busses
  o I2C: fix up dependancies in the i2c/busses/Kconfig file
  o I2C: clean up i2c-prosavage.c driver
  o I2C: move i2c-prosavage.c driver to drivers/i2c/busses where it belongs
  o I2C: clean up the drivers/i2c/Kconfig file
  o I2C: clean up the i2c chips Kconfig logic and help information
  o I2C: add the i2c-voodoo3 i2c bus driver
  o I2C: add the i2c-savage4 i2c bus driver
  o I2C: add the i2c-i810 i2c bus driver
  o I2C: turn off debugging on the new sis i2c bus drivers
  o I2C: clean up the i2c bus Kconfig menu and help texts
  o I2C: add the i2c-via i2c bus driver
  o I2C: add the i2c-sis630 i2c bus driver
  o I2C: add the i2c-sis5595 i2c bus driver
  o I2C: remove some usages of i2c_adapter.id as they are not used
  o I2C: added new id for Radeon driver

Hirofumi Ogawa:
  o DEVICE_NAME_SIZE/_HALF removal (I2C related, but fb stuff)
  o DEVICE_NAME_SIZE/_HALF removal (I2C related, but v4l stuff)
  o DEVICE_NAME_SIZE/_HALF removal (I2C stuff)

Martin Schlemmer:
  o I2C: Fix conversion from milli volts in store_in_reg() for w83781d.c

Matt Porter:
  o I2C: New PPC4xx I2C driver

Randy Hron:
  o I2C: drivers/i2c version.h cleanup

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24               ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1217.7.2, 2003/09/12 16:58:01-07:00, greg@kroah.com

[PATCH] I2C: remove some usages of i2c_adapter.id as they are not used.

Seems i2c_adapter.id is only used in some video drivers, will work on
cleaning up that mess later...


 drivers/i2c/busses/i2c-ali1535.c |    1 -
 drivers/i2c/busses/i2c-ali15x3.c |    1 -
 drivers/i2c/busses/i2c-amd756.c  |    1 -
 drivers/i2c/busses/i2c-amd8111.c |    1 -
 drivers/i2c/busses/i2c-i801.c    |    1 -
 drivers/i2c/busses/i2c-isa.c     |    1 -
 drivers/i2c/busses/i2c-nforce2.c |    1 -
 drivers/i2c/busses/i2c-piix4.c   |    1 -
 drivers/i2c/busses/i2c-sis96x.c  |    1 -
 drivers/i2c/busses/i2c-viapro.c  |    1 -
 drivers/i2c/i2c-core.c           |    6 ++----
 11 files changed, 2 insertions(+), 14 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:16:09 2003
@@ -481,7 +481,6 @@
 
 static struct i2c_adapter ali1535_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI1535,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
 };
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:16:09 2003
@@ -471,7 +471,6 @@
 
 static struct i2c_adapter ali15x3_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_ALI15X3,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:16:09 2003
@@ -304,7 +304,6 @@
 
 static struct i2c_adapter amd756_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD756,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-amd8111.c	Mon Sep 22 16:16:09 2003
@@ -358,7 +358,6 @@
 	smbus->adapter.owner = THIS_MODULE;
 	snprintf(smbus->adapter.name, I2C_NAME_SIZE,
 		"SMBus2 AMD8111 adapter at %04x", smbus->base);
-	smbus->adapter.id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_AMD8111;
 	smbus->adapter.class = I2C_ADAP_CLASS_SMBUS;
 	smbus->adapter.algo = &smbus_algorithm;
 	smbus->adapter.algo_data = smbus;
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:16:09 2003
@@ -540,7 +540,6 @@
 
 static struct i2c_adapter i801_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_I801,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
--- a/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-isa.c	Mon Sep 22 16:16:09 2003
@@ -42,7 +42,6 @@
 /* There can only be one... */
 static struct i2c_adapter isa_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_ISA | I2C_HW_ISA,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo		= &isa_algorithm,
 	.name		= "ISA main adapter",
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-nforce2.c	Mon Sep 22 16:16:09 2003
@@ -118,7 +118,6 @@
 
 static struct i2c_adapter nforce2_adapter = {
 	.owner          = THIS_MODULE,
-	.id             = I2C_ALGO_SMBUS | I2C_HW_SMBUS_NFORCE2,
 	.class          = I2C_ADAP_CLASS_SMBUS,
 	.algo           = &smbus_algorithm,
 	.name   	= "unset",
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:16:09 2003
@@ -395,7 +395,6 @@
 
 static struct i2c_adapter piix4_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_PIIX4,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-sis96x.c	Mon Sep 22 16:16:09 2003
@@ -261,7 +261,6 @@
 
 static struct i2c_adapter sis96x_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_SIS96X,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/busses/i2c-viapro.c	Mon Sep 22 16:16:09 2003
@@ -287,7 +287,6 @@
 
 static struct i2c_adapter vt596_adapter = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_ALGO_SMBUS | I2C_HW_SMBUS_VIA2,
 	.class		= I2C_ADAP_CLASS_SMBUS,
 	.algo		= &smbus_algorithm,
 	.name		= "unset",
diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c	Mon Sep 22 16:16:09 2003
+++ b/drivers/i2c/i2c-core.c	Mon Sep 22 16:16:09 2003
@@ -581,8 +581,7 @@
 		 */
 		return (ret = 1 )? count : ret;
 	} else {
-		printk(KERN_ERR "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
-		       client->adapter->id);
+		dev_err(&client->adapter->dev, "I2C level transfers not supported\n");
 		return -ENOSYS;
 	}
 }
@@ -614,8 +613,7 @@
 	 	*/
 		return (ret = 1 )? count : ret;
 	} else {
-		printk(KERN_DEBUG "i2c-core.o: I2C adapter %04x: I2C level transfers not supported\n",
-		       client->adapter->id);
+		dev_err(&client->adapter->dev, "I2C level transfers not supported\n");
 		return -ENOSYS;
 	}
 }


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                     ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.4, 2003/09/15 16:37:19-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-via i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig   |   17 +++
 drivers/i2c/busses/Makefile  |    1 
 drivers/i2c/busses/i2c-via.c |  183 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 201 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:36 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:36 2003
@@ -207,6 +207,23 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_VIA
+	tristate "  VIA 82C58B"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+
+	  If you say yes to this option, support will be included for the VIA
+          82C586B I2C interface
+
+	  This can also be built as a module which can be inserted and removed
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-via.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at
+	  http://www.lm-sensors.nu
 
 config I2C_VIAPRO
 	tristate "  VIA 82C596/82C686/823x"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:36 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:36 2003
@@ -13,4 +13,5 @@
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
+obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
diff -Nru a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-via.c	Mon Sep 22 16:15:36 2003
@@ -0,0 +1,183 @@
+/*
+    i2c-via.c - Part of lm_sensors,  Linux kernel modules
+                for hardware monitoring
+
+    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.
+*/
+
+#define DEBUG
+
+#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>
+
+/* 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
+#define IOTEXT		"via-i2c"
+
+static u16 pm_io_base = 0;
+
+/*
+   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,
+	.mdelay		= 5,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter vt586b_adapter = {
+	.owner		= THIS_MODULE,
+	.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, }
+};
+
+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, IOTEXT)) {
+		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 driverfs 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_bit_del_bus(&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)
+{
+	printk(KERN_INFO "i2c-via version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	return pci_module_init(&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);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                   ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.3, 2003/09/15 16:15:33-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-sis630 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig      |   16 +
 drivers/i2c/busses/Makefile     |    1 
 drivers/i2c/busses/i2c-sis630.c |  494 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 511 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:46 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:46 2003
@@ -166,6 +166,22 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 
+config I2C_SIS630
+	tristate "  Sis630"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the 
+	  SiS630 SMBus (a subset of I2C) interface.
+
+	  This can also be built as a module which can be inserted and removed 
+	  while the kernel is running.  If you want to compile it as a module,
+	  say M here and read <file:Documentation/modules.txt>.
+
+	  The module will be called i2c-sis630.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at 
+	  http://www.lm-sensors.nu
 
 config I2C_SIS96X
 	tristate "  SiS 96x"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:46 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:15:46 2003
@@ -11,5 +11,6 @@
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
+obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:15:46 2003
@@ -0,0 +1,494 @@
+/*
+    i2c-sis630.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+
+    Copyright (c) 2002,2003 Alexander Malysh <amalysh@web.de>
+
+    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.
+*/
+
+/*
+   Changes:
+   24.08.2002
+   	Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
+	Changed sis630_transaction.(Thanks to Mark M. Hoffman)
+   18.09.2002
+	Added SIS730 as supported
+   21.09.2002
+	Added high_clock module option.If this option is set
+	used Host Master Clock 56KHz (default 14KHz).For now we are save old Host
+	Master Clock and after transaction completed restore (otherwise
+	it's confuse BIOS and hung Machine).
+   24.09.2002
+	Fixed typo in sis630_access
+	Fixed logical error by restoring of Host Master Clock
+   31.07.2003
+   	Added block data read/write support.
+*/
+
+/*
+   Status: beta
+
+   Supports:
+	SIS 630
+	SIS 730
+
+   Note: we assume there can only be one device, with one SMBus interface.
+*/
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+
+/* SIS630 SMBus registers */
+#define SMB_STS			0x80	/* status */
+#define SMB_EN			0x81	/* status enable */
+#define SMB_CNT			0x82
+#define SMBHOST_CNT		0x83
+#define SMB_ADDR		0x84
+#define SMB_CMD			0x85
+#define SMB_PCOUNT		0x86	/* processed count */
+#define SMB_COUNT		0x87
+#define SMB_BYTE		0x88	/* ~0x8F data byte field */
+#define SMBDEV_ADDR		0x90
+#define SMB_DB0			0x91
+#define SMB_DB1			0x92
+#define SMB_SAA			0x93
+
+/* register count for request_region */
+#define SIS630_SMB_IOREGION	20
+
+/* PCI address constants */
+/* acpi base address register  */
+#define SIS630_ACPI_BASE_REG	0x74
+/* bios control register */
+#define SIS630_BIOS_CTL_REG	0x40
+
+/* Other settings */
+#define MAX_TIMEOUT		500
+
+/* SIS630 constants */
+#define SIS630_QUICK		0x00
+#define SIS630_BYTE		0x01
+#define SIS630_BYTE_DATA	0x02
+#define SIS630_WORD_DATA	0x03
+#define SIS630_PCALL		0x04
+#define SIS630_BLOCK_DATA	0x05
+
+/* insmod parameters */
+static int high_clock = 0;
+MODULE_PARM(high_clock, "i");
+MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
+
+
+static unsigned short acpi_base = 0;
+
+static inline u8 sis630_read(u8 reg)
+{
+	return inb(acpi_base + reg);
+}
+
+static inline void sis630_write(u8 reg, u8 data)
+{
+	outb(data, acpi_base + reg);
+}
+
+static int sis630_transaction_start(struct i2c_adapter *adap, int size, u8 *oldclock)
+{
+        int temp;
+
+	/* Make sure the SMBus host is ready to start transmitting. */
+	if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
+		dev_dbg(&adap->dev, "SMBus busy (%02x).Resetting...\n",temp);
+		/* kill smbus transaction */
+		sis630_write(SMBHOST_CNT, 0x20);
+
+		if ((temp = sis630_read(SMB_CNT) & 0x03) != 0x00) {
+			dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
+			return -1;
+                } else {
+			dev_dbg(&adap->dev, "Successfull!\n");
+		}
+        }
+
+	/* save old clock, so we can prevent machine for hung */
+	*oldclock = sis630_read(SMB_CNT);
+
+	dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock);
+
+	/* disable timeout interrupt , set Host Master Clock to 56KHz if requested */
+	if (high_clock > 0)
+		sis630_write(SMB_CNT, 0x20);
+	else
+		sis630_write(SMB_CNT, (*oldclock & ~0x40));
+
+	/* clear all sticky bits */
+	temp = sis630_read(SMB_STS);
+	sis630_write(SMB_STS, temp & 0x1e);
+
+	/* start the transaction by setting bit 4 and size */
+	sis630_write(SMBHOST_CNT,0x10 | (size & 0x07));
+
+	return 0;
+}
+
+static int sis630_transaction_wait(struct i2c_adapter *adap, int size)
+{
+	int temp, result = 0, timeout = 0;
+
+	/* We will always wait for a fraction of a second! */
+	do {
+		i2c_delay(1);
+		temp = sis630_read(SMB_STS);
+		/* check if block transmitted */
+		if (size = SIS630_BLOCK_DATA && (temp & 0x10))
+			break;
+	} while (!(temp & 0x0e) && (timeout++ < MAX_TIMEOUT));
+
+	/* If the SMBus is still busy, we give up */
+	if (timeout >= MAX_TIMEOUT) {
+		dev_dbg(&adap->dev, "SMBus Timeout!\n");
+		result = -1;
+	}
+
+	if (temp & 0x02) {
+		dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
+		result = -1;
+	}
+
+	if (temp & 0x04) {
+		dev_err(&adap->dev, "Bus collision!\n");
+		result = -1;
+		/*
+		  TBD: Datasheet say:
+		  the software should clear this bit and restart SMBUS operation.
+		  Should we do it or user start request again?
+		*/
+	}
+
+	return result;
+}
+
+static void sis630_transaction_end(struct i2c_adapter *adap, u8 oldclock)
+{
+	int temp = 0;
+
+	/* clear all status "sticky" bits */
+	sis630_write(SMB_STS, temp);
+
+	dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n", sis630_read(SMB_CNT));
+
+	/*
+	 * restore old Host Master Clock if high_clock is set
+	 * and oldclock was not 56KHz
+	 */
+	if (high_clock > 0 && !(oldclock & 0x20))
+		sis630_write(SMB_CNT,(sis630_read(SMB_CNT) & ~0x20));
+
+	dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n", sis630_read(SMB_CNT));
+}
+
+static int sis630_transaction(struct i2c_adapter *adap, int size)
+{
+	int result = 0;
+	u8 oldclock = 0;
+
+	result = sis630_transaction_start(adap, size, &oldclock);
+	if (!result) {
+		result = sis630_transaction_wait(adap, size);
+		sis630_transaction_end(adap, oldclock);
+	}
+
+	return result;
+}
+
+static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write)
+{
+	int i, len = 0, rc = 0;
+	u8 oldclock = 0;
+
+	if (read_write = I2C_SMBUS_WRITE) {
+		len = data->block[0];
+		if (len < 0)
+			len = 0;
+		else if (len > 32)
+			len = 32;
+		sis630_write(SMB_COUNT, len);
+		for (i=1; i <= len; i++) {
+			dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]);
+			/* set data */
+			sis630_write(SMB_BYTE+(i-1)%8, data->block[i]);
+			if (i=8 || (len<8 && i=len)) {
+				dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i);
+				/* first transaction */
+				if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock))
+					return -1;
+			}
+			else if ((i-1)%8 = 7 || i=len) {
+				dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i);
+				if (i>8) {
+					dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
+					/*
+					   If this is not first transaction,
+					   we must clear sticky bit.
+					   clear SMBARY_STS
+					*/
+					sis630_write(SMB_STS,0x10);
+				}
+				if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) {
+					dev_dbg(&adap->dev, "trans_wait failed\n");
+					rc = -1;
+					break;
+				}
+			}
+		}
+	}
+	else {
+		/* read request */
+		data->block[0] = len = 0;
+		if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) {
+			return -1;
+		}
+		do {
+			if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) {
+				dev_dbg(&adap->dev, "trans_wait failed\n");
+				rc = -1;
+				break;
+			}
+			/* if this first transaction then read byte count */
+			if (len = 0)
+				data->block[0] = sis630_read(SMB_COUNT);
+
+			dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
+
+			for (i=0; i < 8 && len < data->block[0]; i++,len++) {
+				dev_dbg(&adap->dev, "read i=%d len=%d\n", i, len);
+				data->block[len+1] = sis630_read(SMB_BYTE+i);
+			}
+
+			dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i);
+
+			/* clear SMBARY_STS */
+			sis630_write(SMB_STS,0x10);
+		} while(len < data->block[0]);
+	}
+
+	sis630_transaction_end(adap, oldclock);
+
+	return rc;
+}
+
+/* Return -1 on error. */
+static s32 sis630_access(struct i2c_adapter *adap, u16 addr,
+			 unsigned short flags, char read_write,
+			 u8 command, int size, union i2c_smbus_data *data)
+{
+	switch (size) {
+		case I2C_SMBUS_QUICK:
+			sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+			size = SIS630_QUICK;
+			break;
+		case I2C_SMBUS_BYTE:
+			sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+			if (read_write = I2C_SMBUS_WRITE)
+				sis630_write(SMB_CMD, command);
+			size = SIS630_BYTE;
+			break;
+		case I2C_SMBUS_BYTE_DATA:
+			sis630_write(SMB_ADDR, ((addr & 0x7f) << 1) | (read_write & 0x01));
+			sis630_write(SMB_CMD, command);
+			if (read_write = I2C_SMBUS_WRITE)
+				sis630_write(SMB_BYTE, data->byte);
+			size = SIS630_BYTE_DATA;
+			break;
+		case I2C_SMBUS_PROC_CALL:
+		case I2C_SMBUS_WORD_DATA:
+			sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
+			sis630_write(SMB_CMD, command);
+			if (read_write = I2C_SMBUS_WRITE) {
+				sis630_write(SMB_BYTE, data->word & 0xff);
+				sis630_write(SMB_BYTE + 1,(data->word & 0xff00) >> 8);
+			}
+			size = (size = I2C_SMBUS_PROC_CALL ? SIS630_PCALL : SIS630_WORD_DATA);
+			break;
+		case I2C_SMBUS_BLOCK_DATA:
+			sis630_write(SMB_ADDR,((addr & 0x7f) << 1) | (read_write & 0x01));
+			sis630_write(SMB_CMD, command);
+			size = SIS630_BLOCK_DATA;
+			return sis630_block_data(adap, data, read_write);
+		default:
+			printk("Unsupported I2C size\n");
+			return -1;
+			break;
+	}
+
+	if (sis630_transaction(adap, size))
+		return -1;
+
+	if ((size != SIS630_PCALL) &&
+		((read_write = I2C_SMBUS_WRITE) || (size = SIS630_QUICK))) {
+		return 0;
+	}
+
+	switch(size) {
+		case SIS630_BYTE:
+		case SIS630_BYTE_DATA:
+			data->byte = sis630_read(SMB_BYTE);
+			break;
+		case SIS630_PCALL:
+		case SIS630_WORD_DATA:
+			data->word = sis630_read(SMB_BYTE) + (sis630_read(SMB_BYTE + 1) << 8);
+			break;
+		default:
+			return -1;
+			break;
+	}
+
+	return 0;
+}
+
+static u32 sis630_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
+		I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL |
+		I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+static int sis630_setup(struct pci_dev *dummy)
+{
+	unsigned char b;
+	struct pci_dev *sis630_dev = NULL;
+	int retval = -ENODEV;
+
+	/* We need ISA bridge and not pci device passed in.  */
+	sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev);
+	if (!sis630_dev) {
+		dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n");
+		return -ENODEV;
+	}
+
+	/*
+	   Enable ACPI first , so we can accsess reg 74-75
+	   in acpi io space and read acpi base addr
+	*/
+	if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
+		dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
+		goto exit;
+	}
+
+	/* if ACPI already enabled , do nothing */
+	if (!(b & 0x80) &&
+	    !pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
+		dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
+		goto exit;
+	}
+	/* Determine the ACPI base address */
+	if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
+		dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
+		goto exit;
+	}
+
+	dev_dbg(&sis630_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
+
+	/* Everything is happy, let's grab the memory and set things up. */
+	if (!request_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION, "sis630-smbus")) {
+		dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
+			"in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
+		goto exit;
+	}
+
+	retval = 0;
+
+exit:
+	pci_dev_put(sis630_dev);
+	return retval;
+}
+
+
+static struct i2c_algorithm smbus_algorithm = {
+	.name		= "Non-I2C SMBus adapter",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= sis630_access,
+	.functionality	= sis630_func,
+};
+
+static struct i2c_adapter sis630_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "unset",
+	.algo		= &smbus_algorithm,
+};
+
+static struct pci_device_id sis630_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) },
+	{ 0, }
+};
+
+static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+
+	if (sis630_setup(dev)) {
+		dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
+		return -ENODEV;
+	}
+
+	/* set up the driverfs linkage to our parent device */
+	sis630_adapter.dev.parent = &dev->dev;
+
+	sprintf(sis630_adapter.name, "SMBus SIS630 adapter at %04x",
+		acpi_base + SMB_STS);
+
+	return i2c_add_adapter(&sis630_adapter);
+}
+
+static void __devexit sis630_remove(struct pci_dev *dev)
+{
+	i2c_del_adapter(&sis630_adapter);
+}
+
+
+static struct pci_driver sis630_driver = {
+	.name		= "sis630 smbus",
+	.id_table	= sis630_ids,
+	.probe		= sis630_probe,
+	.remove		= __devexit_p(sis630_remove),
+};
+
+static int __init i2c_sis630_init(void)
+{
+	printk("i2c-sis630.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	return pci_module_init(&sis630_driver);
+}
+
+
+static void __exit i2c_sis630_exit(void)
+{
+	pci_unregister_driver(&sis630_driver);
+	release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
+}
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Malysh <amalysh@web.de>");
+MODULE_DESCRIPTION("SIS630 SMBus driver");
+
+module_init(i2c_sis630_init);
+module_exit(i2c_sis630_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.5, 2003/09/15 16:38:32-07:00, greg@kroah.com

[PATCH] I2C: clean up the i2c bus Kconfig menu and help texts.


 drivers/i2c/busses/Kconfig |  165 ++++++++++-----------------------------------
 1 files changed, 39 insertions(+), 126 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:25 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:15:25 2003
@@ -5,7 +5,7 @@
 menu "I2C Hardware Sensors Mainboard support"
 
 config I2C_ALI1535
-	tristate "  ALI 1535"
+	tristate "ALI 1535"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SMB
@@ -13,63 +13,41 @@
 	  controller is part of the 7101 device, which is an ACPI-compliant
 	  Power Management Unit (PMU).
 
-	  This can also be built as a module.  If so, the module will be
-	  called i2c-ali1535.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-ali1535.
 
 config I2C_ALI15X3
-	tristate "  ALI 15x3"
+	tristate "ALI 15x3"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the
 	  Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces.
 
-	  This can also be built as a module.  If so, the module will be
-	  called i2c-ali15x3.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-ali15x3.
 
 config I2C_AMD756
-	tristate "  AMD 756/766"
+	tristate "AMD 756/766"
 	depends on I2C && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the AMD
 	  756/766/768 mainboard I2C interfaces.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-amd756.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-amd756.
 
 config I2C_AMD8111
-	tristate "  AMD 8111"
+	tristate "AMD 8111"
 	depends on I2C && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the AMD
 	  8111 mainboard I2C interfaces.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-amd8111.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-amd8111.
 
 config I2C_I801
-	tristate "  Intel 801"
+	tristate "Intel 801"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -81,53 +59,31 @@
 	    82801CA/CAM
 	    82801DB
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-i801.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-i801.
 
 config I2C_ISA
-	tristate "  ISA Bus support"
+	tristate "ISA Bus support"
 	depends on I2C && ISA && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for i2c
 	  interfaces that are on the ISA bus.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-isa.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-isa.
 
 config I2C_NFORCE2
-	tristate "  Nvidia Nforce2"
+	tristate "Nvidia Nforce2"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Nvidia
 	  Nforce2 family of mainboard I2C interfaces.
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-nforce2.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
-
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-nforce2.
 
 config I2C_PIIX4
-	tristate "  Intel PIIX4"
+	tristate "Intel PIIX4"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
@@ -139,52 +95,31 @@
 	    Serverworks CSB5
 	    SMSC Victory66
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-piix4.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-piix4.
 
 config I2C_SIS5595
-	tristate "  Sis5595"
+	tristate "SiS 5595"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS5595 SMBus (a subset of I2C) interface.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-sis5595.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sis5595.
 
 config I2C_SIS630
-	tristate "  Sis630"
+	tristate "SiS 630"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  SiS630 SMBus (a subset of I2C) interface.
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-sis630.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sis630.
 
 config I2C_SIS96X
-	tristate "  SiS 96x"
+	tristate "SiS 96x"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the SiS
@@ -197,36 +132,22 @@
 	    650/961
 	    735
 
-	  This can also be built as a module which can be inserted and removed 
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-sis96x.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-sis96x.
 
 config I2C_VIA
-	tristate "  VIA 82C58B"
+	tristate "VIA 82C58B"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 
 	  If you say yes to this option, support will be included for the VIA
           82C586B I2C interface
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-via.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-via.
 
 config I2C_VIAPRO
-	tristate "  VIA 82C596/82C686/823x"
+	tristate "VIA 82C596/82C686/823x"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 
@@ -240,15 +161,7 @@
 	  8233A
 	  8235
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-
-	  The module will be called i2c-viapro.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-viapro.
 
 endmenu
-


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.6, 2003/09/15 16:44:07-07:00, greg@kroah.com

[PATCH] I2C: turn off debugging on the new sis i2c bus drivers.

Forgot to do this before...


 drivers/i2c/busses/i2c-sis5595.c |    2 +-
 drivers/i2c/busses/i2c-sis630.c  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:15:15 2003
+++ b/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:15:15 2003
@@ -55,7 +55,7 @@
  * Add adapter resets
  */
 
-#define DEBUG
+/* #define DEBUG 1 */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:15:15 2003
+++ b/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:15:15 2003
@@ -48,7 +48,7 @@
    Note: we assume there can only be one device, with one SMBus interface.
 */
 
-#define DEBUG
+/* #define DEBUG 1 */
 
 #include <linux/kernel.h>
 #include <linux/module.h>


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                               ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.9, 2003/09/22 11:03:30-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-i810 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig    |   15 ++
 drivers/i2c/busses/Makefile   |    1 
 drivers/i2c/busses/i2c-i810.c |  256 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 272 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:38 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:38 2003
@@ -62,6 +62,21 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
 
+config I2C_I810
+	tristate "Intel 810/815"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the Intel
+	  810/815 family of mainboard I2C interfaces.  Specifically, the 
+	  following versions of the chipset is supported:
+	    i810AA
+	    i810AB
+	    i810E
+	    i815
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-i810.
+
 config I2C_ISA
 	tristate "ISA Bus support"
 	depends on I2C && ISA && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:38 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:38 2003
@@ -7,6 +7,7 @@
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
+obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
diff -Nru a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-i810.c	Mon Sep 22 16:14:38 2003
@@ -0,0 +1,256 @@
+/*
+    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           
+*/
+
+#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>
+
+/* 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 *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, },
+};
+
+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 = {
+	.name		= "i810 smbus",
+	.id_table	= i810_ids,
+	.probe		= i810_probe,
+	.remove		= __devexit_p(i810_remove),
+};
+
+static int __init i2c_i810_init(void)
+{
+	return pci_module_init(&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);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                             ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.8, 2003/09/15 16:54:37-07:00, rwhron@earthlink.net

[PATCH] I2C: drivers/i2c version.h cleanup

remove unnecessary version.h from drivers/i2c.
test compiled with 2.6.0-test5-bk2 on x86.


 drivers/i2c/busses/i2c-amd756.c |    1 -
 drivers/i2c/i2c-adap-ite.c      |    1 -
 drivers/i2c/i2c-algo-ite.c      |    1 -
 drivers/i2c/i2c-elektor.c       |    1 -
 drivers/i2c/i2c-keywest.c       |    1 -
 drivers/i2c/i2c-prosavage.c     |    1 -
 6 files changed, 6 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/busses/i2c-amd756.c	Mon Sep 22 16:14:51 2003
@@ -37,7 +37,6 @@
 
 /* #define DEBUG 1 */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
diff -Nru a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c
--- a/drivers/i2c/i2c-adap-ite.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-adap-ite.c	Mon Sep 22 16:14:51 2003
@@ -38,7 +38,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff -Nru a/drivers/i2c/i2c-algo-ite.c b/drivers/i2c/i2c-algo-ite.c
--- a/drivers/i2c/i2c-algo-ite.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-algo-ite.c	Mon Sep 22 16:14:51 2003
@@ -38,7 +38,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <linux/ioport.h>
diff -Nru a/drivers/i2c/i2c-elektor.c b/drivers/i2c/i2c-elektor.c
--- a/drivers/i2c/i2c-elektor.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-elektor.c	Mon Sep 22 16:14:51 2003
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
diff -Nru a/drivers/i2c/i2c-keywest.c b/drivers/i2c/i2c-keywest.c
--- a/drivers/i2c/i2c-keywest.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-keywest.c	Mon Sep 22 16:14:51 2003
@@ -45,7 +45,6 @@
 
 #include <linux/module.h>
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
diff -Nru a/drivers/i2c/i2c-prosavage.c b/drivers/i2c/i2c-prosavage.c
--- a/drivers/i2c/i2c-prosavage.c	Mon Sep 22 16:14:51 2003
+++ b/drivers/i2c/i2c-prosavage.c	Mon Sep 22 16:14:51 2003
@@ -54,7 +54,6 @@
  *    (Additional documentation needed :(
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                           ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.7, 2003/09/15 16:53:41-07:00, mporter@kernel.crashing.org

[PATCH] I2C: New PPC4xx I2C driver

This updates the current 2.6 PPC 4xx driver to the rewritten version
we have in the PPC development tree.  It is cleaner, has less bugs,
and has more features.


 drivers/i2c/i2c-algo-ibm_ocp.c |  900 -----------------------------------------
 drivers/i2c/i2c-algo-ibm_ocp.h |   55 --
 drivers/i2c/Kconfig            |    8 
 drivers/i2c/Makefile           |    1 
 drivers/i2c/i2c-ibm_iic.c      |  729 +++++++++++++++++++++++++++++++++
 drivers/i2c/i2c-ibm_iic.h      |  124 +++++
 6 files changed, 856 insertions(+), 961 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:15:04 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:15:04 2003
@@ -203,13 +203,9 @@
 	tristate "Embedded Planet RPX Lite/Classic suppoort"
 	depends on (RPXLITE || RPXCLASSIC) && I2C_ALGO8XX
 
-config I2C_IBM_OCP_ALGO
-	tristate "IBM on-chip I2C Algorithm"
+config I2C_IBM_IIC
+	tristate "IBM IIC I2C"
 	depends on IBM_OCP && I2C
-
-config I2C_IBM_OCP_ADAP
-	tristate "IBM on-chip I2C Adapter"
-	depends on I2C_IBM_OCP_ALGO
 
 config I2C_IOP3XX
 	tristate "Intel XScale IOP3xx on-chip I2C interface"
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:15:04 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:15:04 2003
@@ -16,6 +16,7 @@
 obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
 obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
+obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
 obj-$(CONFIG_I2C_SENSOR)	+= i2c-sensor.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-y				+= busses/ chips/
diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.c b/drivers/i2c/i2c-algo-ibm_ocp.c
--- a/drivers/i2c/i2c-algo-ibm_ocp.c	Mon Sep 22 16:15:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,900 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-algo-ibm_ocp.c i2c driver algorithms for IBM PPC 405 adapters	    
-   -------------------------------------------------------------------------
-      
-   Ian DaSilva, MontaVista Software, Inc.
-   idasilva@mvista.com or source@mvista.com
-
-   Copyright 2000 MontaVista Software Inc.
-
-   Changes made to support the IIC peripheral on the IBM PPC 405
-
-
-   ---------------------------------------------------------------------------
-   This file was highly leveraged from i2c-algo-pcf.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
-
-     Copyright (C) 1995-1997 Simon G. Vogl
-                   1998-2000 Hans Berglund
-
-   With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and 
-   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
-   <mbailey@littlefeet-inc.com>
-
-
-    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.
-   ---------------------------------------------------------------------------
-
-   History: 01/20/12 - Armin
-   	akuster@mvista.com
-   	ported up to 2.4.16+	
-
-   Version 02/03/25 - Armin
-       converted to ocp format
-       removed commented out or #if 0 code
-       added G?rard Basler's fix to iic_combined_transaction() such that it 
-       returns the number of successfully completed transfers .
-*/
-
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ibm_ocp.h>
-#include <asm/ocp.h>
-
-
-/* ----- global defines ----------------------------------------------- */
-#define DEB(x) if (i2c_debug>=1) x
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
-#define DEBPROTO(x) if (i2c_debug>=9) x;
- 	/* debug the protocol by showing transferred bits */
-#define DEF_TIMEOUT 5
-
-
-/* ----- global variables ---------------------------------------------	*/
-
-
-/* module parameters:
- */
-static int i2c_debug=0;
-
-/* --- setting states on the bus with the right timing: ---------------	*/
-
-#define iic_outb(adap, reg, val) adap->setiic(adap->data, (int) &(reg), val)
-#define iic_inb(adap, reg) adap->getiic(adap->data, (int) &(reg))
-
-#define IICO_I2C_SDAHIGH	0x0780
-#define IICO_I2C_SDALOW		0x0781
-#define IICO_I2C_SCLHIGH	0x0782
-#define IICO_I2C_SCLLOW		0x0783
-#define IICO_I2C_LINEREAD	0x0784
-
-#define IIC_SINGLE_XFER		0
-#define IIC_COMBINED_XFER	1
-
-#define IIC_ERR_LOST_ARB        -2
-#define IIC_ERR_INCOMPLETE_XFR  -3
-#define IIC_ERR_NACK            -1
-
-/* --- other auxiliary functions --------------------------------------	*/
-
-
-//
-// Description: Puts this process to sleep for a period equal to timeout 
-//
-static inline void iic_sleep(unsigned long timeout)
-{
-	schedule_timeout( timeout * HZ);
-}
-
-
-//
-// Description: This performs the IBM PPC 405 IIC initialization sequence
-// as described in the PPC405GP data book.
-//
-static int iic_init (struct i2c_algo_iic_data *adap)
-{
-	struct iic_regs *iic;	
-	struct iic_ibm *adap_priv_data = adap->data;
-	unsigned short	retval;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-        /* Clear master low master address */
-        iic_outb(adap,iic->lmadr, 0);
-
-        /* Clear high master address */
-        iic_outb(adap,iic->hmadr, 0);
-
-        /* Clear low slave address */
-        iic_outb(adap,iic->lsadr, 0);
-
-        /* Clear high slave address */
-        iic_outb(adap,iic->hsadr, 0);
-
-        /* Clear status */
-        iic_outb(adap,iic->sts, 0x0a);
-
-        /* Clear extended status */
-        iic_outb(adap,iic->extsts, 0x8f);
-
-        /* Set clock division */
-        iic_outb(adap,iic->clkdiv, 0x04);
-
-	retval = iic_inb(adap, iic->clkdiv);
-	DEB(printk("iic_init: CLKDIV register = %x\n", retval));
-
-        /* Enable interrupts on Requested Master Transfer Complete */
-        iic_outb(adap,iic->intmsk, 0x01);
-
-        /* Clear transfer count */
-        iic_outb(adap,iic->xfrcnt, 0x0);
-
-        /* Clear extended control and status */
-        iic_outb(adap,iic->xtcntlss, 0xf0);
-
-        /* Set mode control (flush master data buf, enable hold SCL, exit */
-        /* unknown state.                                                 */
-        iic_outb(adap,iic->mdcntl, 0x47);
-
-        /* Clear control register */
-        iic_outb(adap,iic->cntl, 0x0);
-
-        DEB2(printk(KERN_DEBUG "iic_init: Initialized IIC on PPC 405\n"));
-        return 0;
-}
-
-
-//
-// Description: After we issue a transaction on the IIC bus, this function
-// is called.  It puts this process to sleep until we get an interrupt from
-// from the controller telling us that the transaction we requested in complete.
-//
-static int wait_for_pin(struct i2c_algo_iic_data *adap, int *status) 
-{
-
-	int timeout = DEF_TIMEOUT;
-	int retval;
-	struct iic_regs *iic;
-	struct iic_ibm *adap_priv_data = adap->data;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-
-	*status = iic_inb(adap, iic->sts);
-#ifndef STUB_I2C
-
-	while (timeout-- && (*status & 0x01)) {
-	   adap->waitforpin(adap->data);
-	   *status = iic_inb(adap, iic->sts);
-	}
-#endif
-	if (timeout <= 0) {
-	   /* Issue stop signal on the bus, and force an interrupt */
-           retval = iic_inb(adap, iic->cntl);
-           iic_outb(adap, iic->cntl, retval | 0x80);
-           /* Clear status register */
-	   iic_outb(adap, iic->sts, 0x0a);
-	   /* Exit unknown bus state */
-	   retval = iic_inb(adap, iic->mdcntl);
-	   iic_outb(adap, iic->mdcntl, (retval | 0x02));
-
-	   // Check the status of the controller.  Does it still see a
-	   // pending transfer, even though we've tried to stop any
-	   // ongoing transaction?
-           retval = iic_inb(adap, iic->sts);
-           retval = retval & 0x01;
-           if(retval) {
-	      // The iic controller is hosed.  It is not responding to any
-	      // of our commands.  We have already tried to force it into
-	      // a known state, but it has not worked.  Our only choice now
-	      // is a soft reset, which will clear all registers, and force
-	      // us to re-initialize the controller.
-	      /* Soft reset */
-              iic_outb(adap, iic->xtcntlss, 0x01);
-              udelay(500);
-              iic_init(adap);
-	      /* Is the pending transfer bit in the sts reg finally cleared? */
-              retval = iic_inb(adap, iic->sts);
-              retval = retval & 0x01;
-              if(retval) {
-                 printk(KERN_CRIT "The IIC Controller is hosed.  A processor reset is required\n");
-              }
-	      // For some reason, even though the interrupt bit in this
-	      // register was set during iic_init, it didn't take.  We
-	      // need to set it again.  Don't ask me why....this is just what
-	      // I saw when testing timeouts.
-              iic_outb(adap, iic->intmsk, 0x01);
-           }
-	   return(-1);
-	}
-	else
-	   return(0);
-}
-
-
-//------------------------------------
-// Utility functions
-//
-
-
-//
-// Description: Look at the status register to see if there was an error
-// in the requested transaction.  If there is, look at the extended status
-// register and determine the exact cause.
-//
-int analyze_status(struct i2c_algo_iic_data *adap, int *error_code)
-{
-   int ret;
-   struct iic_regs *iic;
-   struct iic_ibm *adap_priv_data = adap->data;
-   iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	
-   ret = iic_inb(adap, iic->sts);
-   if(ret & 0x04) {
-      // Error occurred
-      ret = iic_inb(adap, iic->extsts);
-      if(ret & 0x04) {
-         // Lost arbitration
-         *error_code =  IIC_ERR_LOST_ARB;
-      }
-      if(ret & 0x02) {
-         // Incomplete transfer
-         *error_code = IIC_ERR_INCOMPLETE_XFR;
-      }
-      if(ret & 0x01) {
-         // Master transfer aborted by a NACK during the transfer of the 
-	 // address byte
-         *error_code = IIC_ERR_NACK;
-      }
-      return -1;
-   }
-   return 0;
-}
-
-
-//
-// Description: This function is called by the upper layers to do the
-// grunt work for a master send transaction
-//
-static int iic_sendbytes(struct i2c_adapter *i2c_adap,const char *buf,
-                         int count, int xfer_flag)
-{
-	struct iic_regs *iic;
-	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	int wrcount, status, timeout;
-	int loops, remainder, i, j;
-	int ret, error_code;
-  	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
- 
-	if( count = 0 ) return 0;
-	wrcount = 0;
-	loops =  count / 4;
-	remainder = count % 4;
-
-	if((loops > 1) && (remainder = 0)) {
-	   for(i=0; i<(loops-1); i++) {
-       	      //
-   	      // Write four bytes to master data buffer
-	      //
-	      for(j=0; j<4; j++) {
-   	         iic_outb(adap, iic->mdbuf, 
-	         buf[wrcount++]);
-  	      }
-	      //
-	      // Issue command to IICO device to begin transmission
-	      //
-	      iic_outb(adap, iic->cntl, 0x35);
-	      //
-	      // Wait for transmission to complete.  When it does, 
-	      //loop to the top of the for statement and write the 
-	      // next four bytes.
-	      //
-	      timeout = wait_for_pin(adap, &status);
-	      if(timeout < 0) {
-	         //
-	         // Error handling
-	         //
-                 //printk(KERN_ERR "Error: write timeout\n");
-                 return wrcount;
-	      }
-	      ret = analyze_status(adap, &error_code);
-	      if(ret < 0) {
-                 if(error_code = IIC_ERR_INCOMPLETE_XFR) {
-                    // Return the number of bytes transferred
-                    ret = iic_inb(adap, iic->xfrcnt);
-                    ret = ret & 0x07;
-                    return (wrcount-4+ret);
-                 }
-                 else return error_code;
-              }
-           }
-	}
-	else if((loops >= 1) && (remainder > 0)){
-	   //printk(KERN_DEBUG "iic_sendbytes: (loops >= 1)\n");
-	   for(i=0; i<loops; i++) {
-              //
-              // Write four bytes to master data buffer
-              //
-              for(j=0; j<4; j++) {
-                 iic_outb(adap, iic->mdbuf,
-                 buf[wrcount++]);
-              }
-              //
-              // Issue command to IICO device to begin transmission
-              //
-              iic_outb(adap, iic->cntl, 0x35);
-              //
-              // Wait for transmission to complete.  When it does,
-              //loop to the top of the for statement and write the
-              // next four bytes.
-              //
-              timeout = wait_for_pin(adap, &status);
-              if(timeout < 0) {
-                 //
-                 // Error handling
-                 //
-                 //printk(KERN_ERR "Error: write timeout\n");
-                 return wrcount;
-              }
-              ret = analyze_status(adap, &error_code);
-              if(ret < 0) {
-                 if(error_code = IIC_ERR_INCOMPLETE_XFR) {
-                    // Return the number of bytes transferred
-                    ret = iic_inb(adap, iic->xfrcnt);
-                    ret = ret & 0x07;
-                    return (wrcount-4+ret);
-                 }
-                 else return error_code;
-              }
-           }
-        }
-
-	//printk(KERN_DEBUG "iic_sendbytes: expedite write\n");
-	if(remainder = 0) remainder = 4;
-	// remainder = remainder - 1;
-	//
-	// Write the remaining bytes (less than or equal to 4)
-	//
-	for(i=0; i<remainder; i++) {
-	   iic_outb(adap, iic->mdbuf, buf[wrcount++]);
-	   //printk(KERN_DEBUG "iic_sendbytes:  data transferred = %x, wrcount = %d\n", buf[wrcount-1], (wrcount-1));
-	}
-        //printk(KERN_DEBUG "iic_sendbytes: Issuing write\n");
-
-        if(xfer_flag = IIC_COMBINED_XFER) {
-           iic_outb(adap, iic->cntl, (0x09 | ((remainder-1) << 4)));
-        }
-	else {
-           iic_outb(adap, iic->cntl, (0x01 | ((remainder-1) << 4)));
-        }
-	DEB2(printk(KERN_DEBUG "iic_sendbytes: Waiting for interrupt\n"));
-	timeout = wait_for_pin(adap, &status);
-        if(timeout < 0) {
-       	   //
-           // Error handling
-           //
-           //printk(KERN_ERR "Error: write timeout\n");
-           return wrcount;
-        }
-        ret = analyze_status(adap, &error_code);
-        if(ret < 0) {
-           if(error_code = IIC_ERR_INCOMPLETE_XFR) {
-              // Return the number of bytes transferred
-              ret = iic_inb(adap, iic->xfrcnt);
-              ret = ret & 0x07;
-              return (wrcount-4+ret);
-           }
-           else return error_code;
-        }
-	DEB2(printk(KERN_DEBUG "iic_sendbytes: Got interrupt\n"));
-	return wrcount;
-}
-
-
-//
-// Description: Called by the upper layers to do the grunt work for
-// a master read transaction.
-//
-static int iic_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count, int xfer_type)
-{
-	struct iic_regs *iic;
-	int rdcount=0, i, status, timeout;
-	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	int loops, remainder, j;
-        int ret, error_code;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	if(count = 0) return 0;
-	loops = count / 4;
-	remainder = count % 4;
-
-	//printk(KERN_DEBUG "iic_readbytes: loops = %d, remainder = %d\n", loops, remainder);
-
-	if((loops > 1) && (remainder = 0)) {
-	//printk(KERN_DEBUG "iic_readbytes: (loops > 1) && (remainder = 0)\n");
-	   for(i=0; i<(loops-1); i++) {
-	      //
-              // Issue command to begin master read (4 bytes maximum)
-              //
-	      //printk(KERN_DEBUG "--->Issued read command\n");
-	      iic_outb(adap, iic->cntl, 0x37);
-	      //
-              // Wait for transmission to complete.  When it does,
-              // loop to the top of the for statement and write the
-              // next four bytes.
-              //
-	      //printk(KERN_DEBUG "--->Waiting for interrupt\n");
-              timeout = wait_for_pin(adap, &status);
-              if(timeout < 0) {
-	         // Error Handler
-		 //printk(KERN_ERR "Error: read timed out\n");
-                 return rdcount;
-	      }
-              //printk(KERN_DEBUG "--->Got interrupt\n");
-
-              ret = analyze_status(adap, &error_code);
-	      if(ret < 0) {
-                 if(error_code = IIC_ERR_INCOMPLETE_XFR)
-                    return rdcount;
-                 else
-                    return error_code;
-              }
-
-	      for(j=0; j<4; j++) {
-                 // Wait for data to shuffle to top of data buffer
-                 // This value needs to optimized.
-		 udelay(1);
-	         buf[rdcount] = iic_inb(adap, iic->mdbuf);
-	         rdcount++;
-		 //printk(KERN_DEBUG "--->Read one byte\n");
-              }
-           }
-	}
-
-	else if((loops >= 1) && (remainder > 0)){
-	//printk(KERN_DEBUG "iic_readbytes: (loops >=1) && (remainder > 0)\n");
-	   for(i=0; i<loops; i++) {
-              //
-              // Issue command to begin master read (4 bytes maximum)
-              //
-              //printk(KERN_DEBUG "--->Issued read command\n");
-              iic_outb(adap, iic->cntl, 0x37);
-              //
-              // Wait for transmission to complete.  When it does,
-              // loop to the top of the for statement and write the
-              // next four bytes.
-              //
-              //printk(KERN_DEBUG "--->Waiting for interrupt\n");
-              timeout = wait_for_pin(adap, &status);
-              if(timeout < 0) {
-                 // Error Handler
-                 //printk(KERN_ERR "Error: read timed out\n");
-                 return rdcount;
-              }
-              //printk(KERN_DEBUG "--->Got interrupt\n");
-
-              ret = analyze_status(adap, &error_code);
-              if(ret < 0) {
-                 if(error_code = IIC_ERR_INCOMPLETE_XFR)
-                    return rdcount;
-                 else
-                    return error_code;
-              }
-
-              for(j=0; j<4; j++) {
-                 // Wait for data to shuffle to top of data buffer
-                 // This value needs to optimized.
-                 udelay(1);
-                 buf[rdcount] = iic_inb(adap, iic->mdbuf);
-                 rdcount++;
-                 //printk(KERN_DEBUG "--->Read one byte\n");
-              }
-           }
-        }
-
-	//printk(KERN_DEBUG "iic_readbytes: expedite read\n");
-	if(remainder = 0) remainder = 4;
-	DEB2(printk(KERN_DEBUG "iic_readbytes: writing %x to IICO_CNTL\n", (0x03 | ((remainder-1) << 4))));
-
-	if(xfer_type = IIC_COMBINED_XFER) {
-	   iic_outb(adap, iic->cntl, (0x0b | ((remainder-1) << 4)));
-        }
-        else {
-	   iic_outb(adap, iic->cntl, (0x03 | ((remainder-1) << 4)));
-        }
-	DEB2(printk(KERN_DEBUG "iic_readbytes: Wait for pin\n"));
-        timeout = wait_for_pin(adap, &status);
-	DEB2(printk(KERN_DEBUG "iic_readbytes: Got the interrupt\n"));
-        if(timeout < 0) {
-           // Error Handler
-	   //printk(KERN_ERR "Error: read timed out\n");
-           return rdcount;
-        }
-
-        ret = analyze_status(adap, &error_code);
-        if(ret < 0) {
-           if(error_code = IIC_ERR_INCOMPLETE_XFR)
-              return rdcount;
-           else
-              return error_code;
-        }
-
-	//printk(KERN_DEBUG "iic_readbyte: Begin reading data buffer\n");
-	for(i=0; i<remainder; i++) {
-	   buf[rdcount] = iic_inb(adap, iic->mdbuf);
-	   // printk(KERN_DEBUG "iic_readbytes:  Character read = %x\n", buf[rdcount]);
-           rdcount++;
-	}
-
-	return rdcount;
-}
-
-
-//
-// Description:  This function implements combined transactions.  Combined
-// transactions consist of combinations of reading and writing blocks of data.
-// Each transfer (i.e. a read or a write) is separated by a repeated start
-// condition.
-//
-static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) 
-{
-   int i;
-   struct i2c_msg *pmsg;
-   int ret;
-
-   DEB2(printk(KERN_DEBUG "Beginning combined transaction\n"));
-	for(i=0; i < num; i++) {
-		pmsg = &msgs[i];
-		if(pmsg->flags & I2C_M_RD) {
-
-			// Last read or write segment needs to be terminated with a stop
-			if(i < num-1) {
-				DEB2(printk(KERN_DEBUG "This one is a read\n"));
-			}
-			else {
-				DEB2(printk(KERN_DEBUG "Doing the last read\n"));
-			}
-			ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER);
-
-			if (ret != pmsg->len) {
-				DEB2(printk("i2c-algo-ppc405.o: fail: "
-							"only read %d bytes.\n",ret));
-				return i;
-			}
-			else {
-				DEB2(printk("i2c-algo-ppc405.o: read %d bytes.\n",ret));
-			}
-		}
-		else if(!(pmsg->flags & I2C_M_RD)) {
-
-			// Last read or write segment needs to be terminated with a stop
-			if(i < num-1) {
-				DEB2(printk(KERN_DEBUG "This one is a write\n"));
-			}
-			else {
-				DEB2(printk(KERN_DEBUG "Doing the last write\n"));
-			}
-			ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num-1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER);
-
-			if (ret != pmsg->len) {
-				DEB2(printk("i2c-algo-ppc405.o: fail: "
-							"only wrote %d bytes.\n",ret));
-				return i;
-			}
-			else {
-				DEB2(printk("i2c-algo-ppc405.o: wrote %d bytes.\n",ret));
-			}
-		}
-	}
- 
-	return num;
-}
-
-
-//
-// Description: Whenever we initiate a transaction, the first byte clocked
-// onto the bus after the start condition is the address (7 bit) of the
-// device we want to talk to.  This function manipulates the address specified
-// so that it makes sense to the hardware when written to the IIC peripheral.
-//
-// Note: 10 bit addresses are not supported in this driver, although they are
-// supported by the hardware.  This functionality needs to be implemented.
-//
-static inline int iic_doAddress(struct i2c_algo_iic_data *adap,
-                                struct i2c_msg *msg, int retries) 
-{
-	struct iic_regs *iic;
-	unsigned short flags = msg->flags;
-	unsigned char addr;
-	struct iic_ibm *adap_priv_data = adap->data;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-//
-// The following segment for 10 bit addresses needs to be ported
-//
-/* Ten bit addresses not supported right now
-	if ( (flags & I2C_M_TEN)  ) { 
-		// a ten bit address
-		addr = 0xf0 | (( msg->addr >> 7) & 0x03);
-		DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
-		// try extended address code...
-		ret = try_address(adap, addr, retries);
-		if (ret!=1) {
-			printk(KERN_ERR "iic_doAddress: died at extended address code.\n");
-			return -EREMOTEIO;
-		}
-		// the remaining 8 bit address
-		iic_outb(adap,msg->addr & 0x7f);
-		// Status check comes here
-		if (ret != 1) {
-			printk(KERN_ERR "iic_doAddress: died at 2nd address code.\n");
-			return -EREMOTEIO;
-		}
-		if ( flags & I2C_M_RD ) {
-			i2c_repstart(adap);
-			// okay, now switch into reading mode
-			addr |= 0x01;
-			ret = try_address(adap, addr, retries);
-			if (ret!=1) {
-				printk(KERN_ERR "iic_doAddress: died at extended address code.\n");
-				return -EREMOTEIO;
-			}
-		}
-	} else ----------> // normal 7 bit address
-
-Ten bit addresses not supported yet */
-
-	addr = ( msg->addr << 1 );
-	if (flags & I2C_M_RD )
-		addr |= 1;
-	if (flags & I2C_M_REV_DIR_ADDR )
-		addr ^= 1;
-	//
-	// Write to the low slave address
-	//
-	iic_outb(adap, iic->lmadr, addr);
-	//
-	// Write zero to the high slave register since we are
-	// only using 7 bit addresses
-	//
-	iic_outb(adap, iic->hmadr, 0);
-
-	return 0;
-}
-
-
-//
-// Description: Prepares the controller for a transaction (clearing status
-// registers, data buffers, etc), and then calls either iic_readbytes or
-// iic_sendbytes to do the actual transaction.
-//
-static int iic_xfer(struct i2c_adapter *i2c_adap,
-		    struct i2c_msg msgs[], 
-		    int num)
-{
-	struct iic_regs *iic;
-	struct i2c_algo_iic_data *adap = i2c_adap->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	struct i2c_msg *pmsg;
-	int i = 0;
-	int ret;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	pmsg = &msgs[i];
-
-	//
-	// Clear status register
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: iic_xfer: Clearing status register\n"));
-	iic_outb(adap, iic->sts, 0x0a);
-
-	//
-	// Wait for any pending transfers to complete
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: Waiting for any pending transfers to complete\n"));
-	while((ret = iic_inb(adap, iic->sts)) = 0x01) {
-		;
-	}
-
-	//
-	// Flush master data buf
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: Clearing master data buffer\n"));		
-	ret = iic_inb(adap, iic->mdcntl);
-	iic_outb(adap, iic->mdcntl, ret | 0x40);
-
-	//
-	// Load slave address
-	//
-	DEB2(printk(KERN_DEBUG "iic_xfer: Loading slave address\n"));
-	ret = iic_doAddress(adap, pmsg, i2c_adap->retries);
-
-        //
-        // Check to see if the bus is busy
-        //
-        ret = iic_inb(adap, iic->extsts);
-        // Mask off the irrelevent bits
-        ret = ret & 0x70;
-        // When the bus is free, the BCS bits in the EXTSTS register are 0b100
-        if(ret != 0x40) return IIC_ERR_LOST_ARB;
-
-	//
-	// Combined transaction (read and write)
-	//
-	if(num > 1) {
-           DEB2(printk(KERN_DEBUG "iic_xfer: Call combined transaction\n"));
-           ret = iic_combined_transaction(i2c_adap, msgs, num);
-        }
-	//
-	// Read only
-	//
-	else if((num = 1) && (pmsg->flags & I2C_M_RD)) {
-	   //
-	   // Tell device to begin reading data from the  master data 
-	   //
-	   DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's read\n"));
-	   ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-	} 
-        //
-	// Write only
-	//
-	else if((num = 1 ) && (!(pmsg->flags & I2C_M_RD))) {
-	   //
-	   // Write data to master data buffers and tell our device
-	   // to begin transmitting
-	   //
-	   DEB2(printk(KERN_DEBUG "iic_xfer: Call adapter's write\n"));
-	   ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, IIC_SINGLE_XFER);
-	}	
-
-	return ret;   
-}
-
-
-//
-// Description: Implements device specific ioctls.  Higher level ioctls can
-// be found in i2c-core.c and are typical of any i2c controller (specifying
-// slave address, timeouts, etc).  These ioctls take advantage of any hardware
-// features built into the controller for which this algorithm-adapter set
-// was written.  These ioctls allow you to take control of the data and clock
-// lines on the IBM PPC 405 IIC controller and set the either high or low,
-// similar to a GPIO pin.
-//
-static int algo_control(struct i2c_adapter *adapter, 
-	unsigned int cmd, unsigned long arg)
-{
-	struct iic_regs *iic;
-	struct i2c_algo_iic_data *adap = adapter->algo_data;
-	struct iic_ibm *adap_priv_data = adap->data;
-	int ret=0;
-	int lines;
-	iic = (struct iic_regs *) adap_priv_data->iic_base;
-
-	lines = iic_inb(adap, iic->directcntl);
-
-	if (cmd = IICO_I2C_SDAHIGH) {
-	      lines = lines & 0x01;
-	      if( lines ) lines = 0x04;
-	      else lines = 0;
-	      iic_outb(adap, iic->directcntl,(0x08|lines));
-	}
-	else if (cmd = IICO_I2C_SDALOW) {
-	      lines = lines & 0x01;
-	      if( lines ) lines = 0x04;
-              else lines = 0;
-              iic_outb(adap, iic->directcntl,(0x00|lines));
-	}
-	else if (cmd = IICO_I2C_SCLHIGH) {
-              lines = lines & 0x02;
-              if( lines ) lines = 0x08;
-              else lines = 0;
-              iic_outb(adap, iic->directcntl,(0x04|lines));
-	}
-	else if (cmd = IICO_I2C_SCLLOW) {
-              lines = lines & 0x02;
-	      if( lines ) lines = 0x08;
-              else lines = 0;
-              iic_outb(adap, iic->directcntl,(0x00|lines));
-	}
-	else if (cmd = IICO_I2C_LINEREAD) {
-	      ret = lines;
-	}
-	return ret;
-}
-
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
-	return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
-	       I2C_FUNC_PROTOCOL_MANGLING; 
-}
-
-
-/* -----exported algorithm data: -------------------------------------	*/
-
-static struct i2c_algorithm iic_algo = {
-	.name		= "IBM on-chip IIC algorithm",
-	.id		= I2C_ALGO_OCP,
-	.master_xfer	= iic_xfer,
-	.algo_control	= algo_control,
-	.functionality	= iic_func,
-};
-
-/* 
- * registering functions to load algorithms at runtime 
- */
-
-
-//
-// Description: Register bus structure
-//
-int i2c_ocp_add_bus(struct i2c_adapter *adap)
-{
-	struct i2c_algo_iic_data *iic_adap = adap->algo_data;
-
-	DEB2(printk(KERN_DEBUG "i2c-algo-iic.o: hw routines for %s registered.\n",
-	            adap->name));
-
-	/* register new adapter to i2c module... */
-
-	adap->id |= iic_algo.id;
-	adap->algo = &iic_algo;
-
-	adap->timeout = 100;	/* default values, should	*/
-	adap->retries = 3;		/* be replaced by defines	*/
-
-	iic_init(iic_adap);
-	i2c_add_adapter(adap);
-	return 0;
-}
-
-
-//
-// Done
-//
-int i2c_ocp_del_bus(struct i2c_adapter *adap)
-{
-	return i2c_del_adapter(adap);
-}
-
-
-EXPORT_SYMBOL(i2c_ocp_add_bus);
-EXPORT_SYMBOL(i2c_ocp_del_bus);
-
-//
-// The MODULE_* macros resolve to nothing if MODULES is not defined
-// when this file is compiled.
-//
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("PPC 405 iic algorithm");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(i2c_debug,"i");
-
-MODULE_PARM_DESC(i2c_debug,
-        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
-
diff -Nru a/drivers/i2c/i2c-algo-ibm_ocp.h b/drivers/i2c/i2c-algo-ibm_ocp.h
--- a/drivers/i2c/i2c-algo-ibm_ocp.h	Mon Sep 22 16:15:04 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,55 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-algo-ibm_ocp.h i2c driver algorithms for IBM PPC 405 IIC adapters         */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    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.                */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* Modifications by MontaVista Software, August 2000
-   Changes made to support the IIC peripheral on the IBM PPC 405 */
-
-#ifndef I2C_ALGO_IIC_H
-#define I2C_ALGO_IIC_H 1
-
-/* --- Defines for pcf-adapters ---------------------------------------	*/
-#include <linux/i2c.h>
-
-struct i2c_algo_iic_data {
-	struct iic_regs *data;		/* private data for lolevel routines	*/
-	void (*setiic) (void *data, int ctl, int val);
-	int  (*getiic) (void *data, int ctl);
-	int  (*getown) (void *data);
-	int  (*getclock) (void *data);
-	void (*waitforpin) (void *data);     
-
-	/* local settings */
-	int udelay;
-	int mdelay;
-	int timeout;
-};
-
-
-#define I2C_IIC_ADAP_MAX	16
-
-
-int i2c_ocp_add_bus(struct i2c_adapter *);
-int i2c_ocp_del_bus(struct i2c_adapter *);
-
-#endif /* I2C_ALGO_IIC_H */
diff -Nru a/drivers/i2c/i2c-ibm_iic.c b/drivers/i2c/i2c-ibm_iic.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/i2c-ibm_iic.c	Mon Sep 22 16:15:04 2003
@@ -0,0 +1,729 @@
+/*
+ * drivers/i2c/i2c-ibm_iic.c
+ *
+ * Support for the IIC peripheral on IBM PPC 4xx
+ *
+ * Copyright (c) 2003 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by 
+ * 	Ian DaSilva  <idasilva@mvista.com>
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Matt Porter  <mporter@mvista.com>
+ *
+ *      Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * Original driver version was highly leveraged from i2c-elektor.c
+ *
+ *   	Copyright 1995-97 Simon G. Vogl
+ *                1998-99 Hans Berglund
+ *
+ *   	With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> 
+ *	and even Frodo Looijaard <frodol@dds.nl>
+ *
+ * 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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <asm/ocp.h>
+#include <asm/ibm4xx.h>
+
+#include "i2c-ibm_iic.h"
+
+#define DRIVER_VERSION "2.0"
+
+MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+static int iic_scan = 0;
+MODULE_PARM(iic_scan, "i");
+MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus");
+
+static int iic_force_poll = 0;
+MODULE_PARM(iic_force_poll, "i");
+MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
+
+static int iic_force_fast = 0;
+MODULE_PARM(iic_force_fast, "i");
+MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)");
+
+#define DBG_LEVEL 0
+
+#ifdef DBG
+#undef DBG
+#endif
+
+#ifdef DBG2
+#undef DBG2
+#endif
+
+#if DBG_LEVEL > 0
+#  define DBG(x...)	printk(KERN_DEBUG "ibm-iic" ##x)
+#else
+#  define DBG(x...)	((void)0)
+#endif
+#if DBG_LEVEL > 1
+#  define DBG2(x...) 	DBG( ##x )
+#else
+#  define DBG2(x...) 	((void)0)
+#endif
+#if DBG_LEVEL > 2
+static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header);
+	printk(KERN_DEBUG "  cntl     = 0x%02x, mdcntl = 0x%02x\n"
+	       KERN_DEBUG "  sts      = 0x%02x, extsts = 0x%02x\n"
+	       KERN_DEBUG "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n"
+	       KERN_DEBUG "  xtcntlss = 0x%02x, directcntl = 0x%02x\n",
+		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), 
+		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), 
+		in_8(&iic->xtcntlss), in_8(&iic->directcntl));
+}
+#  define DUMP_REGS(h,dev)	dump_iic_regs((h),(dev))
+#else
+#  define DUMP_REGS(h,dev)	((void)0)
+#endif
+
+/* Enable/disable interrupt generation */
+static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable)
+{
+	out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);
+}
+ 
+/*
+ * Initialize IIC interface.
+ */
+static void iic_dev_init(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+
+	DBG("%d: init\n", dev->idx);
+	
+	/* Clear master address */
+	out_8(&iic->lmadr, 0);
+	out_8(&iic->hmadr, 0);
+
+	/* Clear slave address */
+	out_8(&iic->lsadr, 0);
+	out_8(&iic->hsadr, 0);
+
+	/* Clear status & extended status */
+	out_8(&iic->sts, STS_SCMP | STS_IRQA);
+	out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA
+			    | EXTSTS_ICT | EXTSTS_XFRA);
+
+	/* Set clock divider */
+	out_8(&iic->clkdiv, dev->clckdiv);
+
+	/* Clear transfer count */
+	out_8(&iic->xfrcnt, 0);
+
+	/* Clear extended control and status */
+	out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC
+			    | XTCNTLSS_SWS);
+
+	/* Clear control register */
+	out_8(&iic->cntl, 0);
+	
+	/* Enable interrupts if possible */
+	iic_interrupt_mode(dev, dev->irq >= 0);
+
+	/* Set mode control */
+	out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS
+			    | (dev->fast_mode ? MDCNTL_FSM : 0));
+
+	DUMP_REGS("iic_init", dev);
+}
+
+/* 
+ * Reset IIC interface
+ */
+static void iic_dev_reset(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	int i;
+	u8 dc;
+	
+	DBG("%d: soft reset\n", dev->idx);
+	DUMP_REGS("reset", dev);
+	
+    	/* Place chip in the reset state */
+	out_8(&iic->xtcntlss, XTCNTLSS_SRST);
+	
+	/* Check if bus is free */
+	dc = in_8(&iic->directcntl);	
+	if (!DIRCTNL_FREE(dc)){
+		DBG("%d: trying to regain bus control\n", dev->idx);
+	
+		/* Try to set bus free state */
+		out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);	
+	
+		/* Wait until we regain bus control */
+		for (i = 0; i < 100; ++i){
+			dc = in_8(&iic->directcntl);
+			if (DIRCTNL_FREE(dc))
+				break;
+			
+			/* Toggle SCL line */
+			dc ^= DIRCNTL_SCC;
+			out_8(&iic->directcntl, dc);
+			udelay(10);
+			dc ^= DIRCNTL_SCC;
+			out_8(&iic->directcntl, dc);
+			
+			/* be nice */
+			cond_resched();
+		}
+	}
+	
+	/* Remove reset */
+	out_8(&iic->xtcntlss, 0);
+	
+	/* Reinitialize interface */
+	iic_dev_init(dev);
+}
+
+/*
+ * IIC interrupt handler
+ */
+static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
+	volatile struct iic_regs* iic = dev->vaddr;
+	
+	DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", 
+	     dev->idx, in_8(&iic->sts), in_8(&iic->extsts));
+	
+	/* Acknowledge IRQ and wakeup iic_wait_for_tc */
+	out_8(&iic->sts, STS_IRQA | STS_SCMP);
+	wake_up_interruptible(&dev->wq);
+	
+	return IRQ_HANDLED;
+}
+
+/*
+ * Get master transfer result and clear errors if any.
+ * Returns the number of actually transferred bytes or error (<0)
+ */
+static int iic_xfer_result(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;	
+	
+	if (unlikely(in_8(&iic->sts) & STS_ERR)){
+		DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, 
+			in_8(&iic->extsts));
+				
+		/* Clear errors and possible pending IRQs */
+		out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | 
+			EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
+			
+		/* Flush master data buffer */
+		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+		
+		/* Is bus free?
+		 * If error happened during combined xfer
+		 * IIC interface is usually stuck in some strange
+		 * state, the only way out - soft reset.
+		 */
+		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+			DBG("%d: bus is stuck, resetting\n", dev->idx);
+			iic_dev_reset(dev);
+		}
+		return -EREMOTEIO;
+	}
+	else
+		return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK;
+}
+
+/*
+ * Try to abort active transfer.
+ */
+static void iic_abort_xfer(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	unsigned long x;
+	
+	DBG("%d: iic_abort_xfer\n", dev->idx);
+	
+	out_8(&iic->cntl, CNTL_HMT);
+	
+	/*
+	 * Wait for the abort command to complete.
+	 * It's not worth to be optimized, just poll (timeout >= 1 tick)
+	 */
+	x = jiffies + 2;
+	while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+		if (time_after(jiffies, x)){
+			DBG("%d: abort timeout, resetting...\n", dev->idx);
+			iic_dev_reset(dev);
+			return;
+		}
+		schedule();
+	}
+
+	/* Just to clear errors */
+	iic_xfer_result(dev);
+}
+
+/*
+ * Wait for master transfer to complete.
+ * It puts current process to sleep until we get interrupt or timeout expires.
+ * Returns the number of transferred bytes or error (<0)
+ */
+static int iic_wait_for_tc(struct ibm_iic_private* dev){
+	
+	volatile struct iic_regs *iic = dev->vaddr;
+	int ret = 0;
+	
+	if (dev->irq >= 0){
+		/* Interrupt mode */
+		wait_queue_t wait;
+    		init_waitqueue_entry(&wait, current);
+		
+		add_wait_queue(&dev->wq, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (in_8(&iic->sts) & STS_PT)
+			schedule_timeout(dev->adap.timeout * HZ);
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&dev->wq, &wait);
+		
+		if (unlikely(signal_pending(current))){
+			DBG("%d: wait interrupted\n", dev->idx);
+			ret = -ERESTARTSYS;
+		} else if (unlikely(in_8(&iic->sts) & STS_PT)){
+			DBG("%d: wait timeout\n", dev->idx);
+			ret = -ETIMEDOUT;
+		}
+	}
+	else {
+		/* Polling mode */
+		unsigned long x = jiffies + dev->adap.timeout * HZ;
+		
+		while (in_8(&iic->sts) & STS_PT){
+			if (unlikely(time_after(jiffies, x))){
+				DBG("%d: poll timeout\n", dev->idx);
+				ret = -ETIMEDOUT;
+				break;
+			}
+		
+			if (unlikely(signal_pending(current))){
+				DBG("%d: poll interrupted\n", dev->idx);
+				ret = -ERESTARTSYS;
+				break;
+			}
+			schedule();
+		}	
+	}
+	
+	if (unlikely(ret < 0))
+		iic_abort_xfer(dev);
+	else
+		ret = iic_xfer_result(dev);
+	
+	DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);
+	
+	return ret;
+}
+
+/*
+ * Low level master transfer routine
+ */
+static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, 
+			  int combined_xfer)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	char* buf = pm->buf;
+	int i, j, loops, ret = 0;
+	int len = pm->len;
+
+	u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;
+	if (pm->flags & I2C_M_RD)
+		cntl |= CNTL_RW;
+	
+	loops = (len + 3) / 4;
+	for (i = 0; i < loops; ++i, len -= 4){
+		int count = len > 4 ? 4 : len;
+		u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);
+		
+		if (!(cntl & CNTL_RW))
+			for (j = 0; j < count; ++j)
+				out_8((volatile u8*)&iic->mdbuf, *buf++);
+		
+		if (i < loops - 1)
+			cmd |= CNTL_CHT;
+		else if (combined_xfer)
+			cmd |= CNTL_RPST;
+		
+		DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);
+		
+		/* Start transfer */
+		out_8(&iic->cntl, cmd);
+		
+		/* Wait for completion */
+		ret = iic_wait_for_tc(dev);
+
+		if (unlikely(ret < 0))
+			break;
+		else if (unlikely(ret != count)){
+			DBG("%d: xfer_bytes, requested %d, transfered %d\n", 
+				dev->idx, count, ret);
+			
+			/* If it's not a last part of xfer, abort it */
+			if (combined_xfer || (i < loops - 1))
+    				iic_abort_xfer(dev);
+				
+			ret = -EREMOTEIO;
+			break;				
+		}
+		
+		if (cntl & CNTL_RW)
+			for (j = 0; j < count; ++j)
+				*buf++ = in_8((volatile u8*)&iic->mdbuf);
+	}
+	
+	return ret > 0 ? 0 : ret;
+}
+
+/*
+ * Set target slave address for master transfer
+ */
+static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	u16 addr = msg->addr;
+	
+	DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, 
+		addr, msg->flags & I2C_M_TEN ? 10 : 7);
+	
+	if (msg->flags & I2C_M_TEN){
+	    out_8(&iic->cntl, CNTL_AMD);
+	    out_8(&iic->lmadr, addr);
+	    out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06));
+	}
+	else {
+	    out_8(&iic->cntl, 0);
+	    out_8(&iic->lmadr, addr << 1);
+	}
+}
+
+static inline int iic_invalid_address(const struct i2c_msg* p)
+{
+	return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));
+}
+
+static inline int iic_address_neq(const struct i2c_msg* p1, 
+				  const struct i2c_msg* p2)
+{
+	return (p1->addr != p2->addr) 
+		|| ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));
+} 
+
+/*
+ * Generic master transfer entrypoint. 
+ * Returns the number of processed messages or error (<0)
+ */
+static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+    	struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));
+	volatile struct iic_regs *iic = dev->vaddr;
+	int i, ret = 0;
+	
+	DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
+	
+	if (!num)
+		return 0;
+	
+	/* Check the sanity of the passed messages.
+	 * Uhh, generic i2c layer is more suitable place for such code...
+	 */
+	if (unlikely(iic_invalid_address(&msgs[0]))){
+		DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, 
+			msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);
+		return -EINVAL;
+	}		
+	for (i = 0; i < num; ++i){
+		if (unlikely(msgs[i].len <= 0)){
+			DBG("%d: invalid len %d in msg[%d]\n", dev->idx, 
+				msgs[i].len, i);
+			return -EINVAL;
+		}
+		if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){
+			DBG("%d: invalid addr in msg[%d]\n", dev->idx, i);
+			return -EINVAL;
+		}
+	}
+	
+	/* Check bus state */
+	if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){
+		DBG("%d: iic_xfer, bus is not free\n", dev->idx);
+		
+		/* Usually it means something serious has happend.
+		 * We *cannot* have unfinished previous transfer
+		 * so it doesn't make any sense to try to stop it.
+		 * Probably we were not able to recover from the 
+		 * previous error.
+		 * The only *reasonable* thing I can think of here
+		 * is soft reset.  --ebs
+		 */
+		iic_dev_reset(dev);
+		
+		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+			DBG("%d: iic_xfer, bus is still not free\n", dev->idx);
+			return -EREMOTEIO;
+		}
+	} 
+	else {
+		/* Flush master data buffer (just in case) */
+		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+	}
+	
+	/* Load slave address */
+	iic_address(dev, &msgs[0]);
+	
+	/* Do real transfer */
+    	for (i = 0; i < num && !ret; ++i)
+		ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);
+
+	return ret < 0 ? ret : num;
+}
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+}
+
+static struct i2c_algorithm iic_algo = {
+	.name 		= "IBM IIC algorithm",
+	.id   		= I2C_ALGO_OCP,
+	.master_xfer 	= iic_xfer,
+	.smbus_xfer	= NULL,
+	.slave_send	= NULL,
+	.slave_recv	= NULL,
+	.algo_control	= NULL,
+	.functionality	= iic_func
+};
+
+/*
+ * Scan bus for valid 7-bit addresses (ie things that ACK on 1 byte read)
+ * We only scan range [0x08 - 0x77], all other addresses are reserved anyway
+ */
+static void __devinit iic_scan_bus(struct ibm_iic_private* dev)
+{
+	int found = 0;
+	char dummy;
+	struct i2c_msg msg = {
+		.buf   = &dummy,
+		.len   = sizeof(dummy),
+		.flags = I2C_M_RD
+	};
+	
+	printk(KERN_INFO "ibm-iic%d: scanning bus...\n" KERN_INFO, dev->idx);
+	
+	for (msg.addr = 8; msg.addr < 0x78; ++msg.addr)
+		if (iic_xfer(&dev->adap, &msg, 1) = 1){
+			++found;
+			printk(" 0x%02x", msg.addr);
+		}
+
+	printk("%sibm-iic%d: %d device(s) detected\n", 
+		found ? "\n" KERN_INFO : "", dev->idx, found);
+}
+
+/*
+ * Calculates IICx_CLCKDIV value for a specific OPB clock frequency
+ */
+static inline u8 iic_clckdiv(unsigned int opb)
+{
+	/* Compatibility kludge, should go away after all cards
+	 * are fixed to fill correct value for opbfreq.
+	 * Previous driver version used hardcoded divider value 4,
+	 * it corresponds to OPB frequency from the range (40, 50] MHz
+	 */
+	if (!opb){
+		printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq,"
+			" fix your board specific setup\n");
+		opb = 50000000;
+	}
+
+	/* Convert to MHz */
+	opb /= 1000000;
+	
+	if (opb < 20 || opb > 150){
+		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
+			opb);
+		opb = opb < 20 ? 20 : 150;
+	}
+	return (u8)((opb + 9) / 10 - 1);
+}
+
+/*
+ * Register single IIC interface
+ */
+static int __devinit iic_probe(struct ocp_device *ocp){
+
+	struct ibm_iic_private* dev;
+	struct i2c_adapter* adap;
+	int ret;
+	bd_t* bd = (bd_t*)&__res;
+	
+	if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){
+		printk(KERN_CRIT "ibm-iic: failed to allocate device data\n");
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->idx = ocp->num;
+	ocp_set_drvdata(ocp, dev);
+	
+	if (!(dev->vaddr = ioremap(ocp->paddr, sizeof(struct iic_regs)))){
+		printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
+			dev->idx);
+		ret = -ENXIO;
+		goto fail2;
+	}
+	
+	init_waitqueue_head(&dev->wq);
+
+	dev->irq = iic_force_poll ? -1 : ocp->irq;
+	if (dev->irq >= 0){
+		/* Disable interrupts until we finish intialization,
+		   assumes level-sensitive IRQ setup...
+		 */
+		iic_interrupt_mode(dev, 0);
+		if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){
+			printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", 
+				dev->idx, dev->irq);
+			/* Fallback to the polling mode */	
+			dev->irq = -1;
+		}
+	}
+	
+	if (dev->irq < 0)
+		printk(KERN_WARNING "ibm-iic%d: using polling mode\n", 
+			dev->idx);
+		
+	/* Board specific settings */
+	BUG_ON(dev->idx >= sizeof(bd->bi_iic_fast) / sizeof(bd->bi_iic_fast[0]));
+	dev->fast_mode = iic_force_fast ? 1 : bd->bi_iic_fast[dev->idx];
+	
+	/* clckdiv is the same for *all* IIC interfaces, 
+	 * but I'd rather make a copy than introduce another global. --ebs
+	 */
+	dev->clckdiv = iic_clckdiv(bd->bi_opb_busfreq);
+	DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);
+	
+	/* Initialize IIC interface */
+	iic_dev_init(dev);
+	
+	/* Register it with i2c layer */
+	adap = &dev->adap;
+	strcpy(adap->dev.name, "IBM IIC");
+	i2c_set_adapdata(adap, dev);
+	adap->id = I2C_HW_OCP | iic_algo.id;
+	adap->algo = &iic_algo;
+	adap->client_register = NULL;
+	adap->client_unregister = NULL;
+	adap->timeout = 1;
+	adap->retries = 1;
+
+	if ((ret = i2c_add_adapter(adap)) != 0){
+		printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n",
+			dev->idx);
+		goto fail;
+	}
+	
+	printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,
+		dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
+
+	/* Scan bus if requested by user */
+	if (iic_scan)
+		iic_scan_bus(dev);
+
+	return 0;
+
+fail:	
+	if (dev->irq >= 0){
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}	
+
+	iounmap((void*)dev->vaddr);
+fail2:	
+	ocp_set_drvdata(ocp, 0);
+	kfree(dev);	
+	return ret;
+}
+
+/*
+ * Cleanup initialized IIC interface
+ */
+static void __devexit iic_remove(struct ocp_device *ocp)
+{
+	struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
+	BUG_ON(dev = NULL);
+	if (i2c_del_adapter(&dev->adap)){
+		printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n",
+			dev->idx);
+		/* That's *very* bad, just shutdown IRQ ... */
+		if (dev->irq >= 0){
+		    iic_interrupt_mode(dev, 0);	
+		    free_irq(dev->irq, dev);
+		    dev->irq = -1;
+		}
+	} else {
+		if (dev->irq >= 0){
+		    iic_interrupt_mode(dev, 0);	
+		    free_irq(dev->irq, dev);
+		}
+		iounmap((void*)dev->vaddr);
+		kfree(dev);
+	}
+}
+
+static struct ocp_device_id ibm_iic_ids[] __devinitdata = 
+{
+	{ .vendor = OCP_VENDOR_IBM, .device = OCP_FUNC_IIC },
+	{ .vendor = OCP_VENDOR_INVALID }
+};
+
+MODULE_DEVICE_TABLE(ocp, ibm_iic_ids);
+
+static struct ocp_driver ibm_iic_driver +{
+	.name 		= "ocp_iic",
+	.id_table	= ibm_iic_ids,
+	.probe		= iic_probe,
+	.remove		= __devexit_p(iic_remove),
+#if defined(CONFIG_PM)
+	.suspend	= NULL,
+	.resume		= NULL,
+#endif
+};
+
+static int __init iic_init(void)
+{
+	printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n");
+	return ocp_module_init(&ibm_iic_driver);
+}
+
+static void __exit iic_exit(void)
+{
+	ocp_unregister_driver(&ibm_iic_driver);
+}
+
+module_init(iic_init);
+module_exit(iic_exit);
diff -Nru a/drivers/i2c/i2c-ibm_iic.h b/drivers/i2c/i2c-ibm_iic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/i2c-ibm_iic.h	Mon Sep 22 16:15:04 2003
@@ -0,0 +1,124 @@
+/*
+ * drivers/i2c/i2c-ibm_iic.h
+ *
+ * Support for the IIC peripheral on IBM PPC 4xx
+ * 
+ * Copyright (c) 2003 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by 
+ * 	Ian DaSilva  <idasilva@mvista.com>
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Matt Porter  <mporter@mvista.com>
+ *
+ *      Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * 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.
+ *
+ */
+#ifndef __I2C_IBM_IIC_H_
+#define __I2C_IBM_IIC_H_
+
+#include <linux/config.h>
+#include <linux/i2c.h> 
+
+struct iic_regs {
+	u16 mdbuf;
+	u16 sbbuf;
+	u8 lmadr;
+	u8 hmadr;
+	u8 cntl;
+	u8 mdcntl;
+	u8 sts;
+	u8 extsts;
+	u8 lsadr;
+	u8 hsadr;
+	u8 clkdiv;
+	u8 intmsk;
+	u8 xfrcnt;
+	u8 xtcntlss;
+	u8 directcntl;
+};
+
+struct ibm_iic_private {
+	struct i2c_adapter adap;
+	volatile struct iic_regs *vaddr;
+	wait_queue_head_t wq;
+	int idx;
+	int irq;
+	int fast_mode;
+	u8  clckdiv;
+};
+
+/* IICx_CNTL register */
+#define CNTL_HMT	0x80
+#define CNTL_AMD	0x40
+#define CNTL_TCT_MASK	0x30
+#define CNTL_TCT_SHIFT	4
+#define CNTL_RPST	0x08
+#define CNTL_CHT	0x04 
+#define CNTL_RW		0x02
+#define CNTL_PT		0x01
+
+/* IICx_MDCNTL register */
+#define MDCNTL_FSDB	0x80
+#define MDCNTL_FMDB	0x40
+#define MDCNTL_EGC	0x20
+#define MDCNTL_FSM	0x10
+#define MDCNTL_ESM	0x08
+#define MDCNTL_EINT	0x04
+#define MDCNTL_EUBS	0x02
+#define MDCNTL_HSCL	0x01
+
+/* IICx_STS register */
+#define STS_SSS		0x80
+#define STS_SLPR	0x40
+#define STS_MDBS	0x20
+#define STS_MDBF	0x10
+#define STS_SCMP	0x08
+#define STS_ERR		0x04
+#define STS_IRQA	0x02
+#define STS_PT		0x01
+
+/* IICx_EXTSTS register */
+#define EXTSTS_IRQP	0x80
+#define EXTSTS_BCS_MASK	0x70
+#define   EXTSTS_BCS_FREE  0x40
+#define EXTSTS_IRQD	0x08
+#define EXTSTS_LA	0x04
+#define EXTSTS_ICT	0x02
+#define EXTSTS_XFRA	0x01
+
+/* IICx_INTRMSK register */
+#define INTRMSK_EIRC	0x80
+#define INTRMSK_EIRS	0x40
+#define INTRMSK_EIWC	0x20
+#define INTRMSK_EIWS	0x10
+#define INTRMSK_EIHE	0x08
+#define INTRMSK_EIIC	0x04
+#define INTRMSK_EITA	0x02
+#define INTRMSK_EIMTC	0x01
+
+/* IICx_XFRCNT register */
+#define XFRCNT_MTC_MASK	0x07
+
+/* IICx_XTCNTLSS register */
+#define XTCNTLSS_SRC	0x80
+#define XTCNTLSS_SRS	0x40
+#define XTCNTLSS_SWC	0x20
+#define XTCNTLSS_SWS	0x10
+#define XTCNTLSS_SRST	0x01
+
+/* IICx_DIRECTCNTL register */
+#define DIRCNTL_SDAC	0x08
+#define DIRCNTL_SCC	0x04
+#define DIRCNTL_MSDA	0x02
+#define DIRCNTL_MSC	0x01
+
+/* Check if we really control the I2C bus and bus is free */
+#define DIRCTNL_FREE(v)	(((v) & 0x0f) = 0x0f)
+
+#endif /* __I2C_IBM_IIC_H_ */


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                   ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.11, 2003/09/22 11:15:16-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-voodoo3 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig       |   11 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-voodoo3.c |  248 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 260 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:18 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:18 2003
@@ -189,4 +189,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-viapro.
 
+config I2C_VOODOO3
+	tristate "Voodoo 3"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+
+	  If you say yes to this option, support will be included for the
+	  Voodoo 3 I2C interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-voodoo3.
+
 endmenu
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:18 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:18 2003
@@ -17,3 +17,4 @@
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
+obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
diff -Nru a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-voodoo3.c	Mon Sep 22 16:14:18 2003
@@ -0,0 +1,248 @@
+/*
+    voodoo3.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+    Copyright (c) 1998, 1999  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 I2C bus of the Voodoo3 to gain access to
+    the BT869 and possibly other I2C devices. */
+
+#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>
+
+/* the only registers we use */
+#define REG		0x78
+#define REG2 		0x70
+
+/* bit locations in the register */
+#define DDC_ENAB	0x00040000
+#define DDC_SCL_OUT	0x00080000
+#define DDC_SDA_OUT	0x00100000
+#define DDC_SCL_IN	0x00200000
+#define DDC_SDA_IN	0x00400000
+#define I2C_ENAB	0x00800000
+#define I2C_SCL_OUT	0x01000000
+#define I2C_SDA_OUT	0x02000000
+#define I2C_SCL_IN	0x04000000
+#define I2C_SDA_IN	0x08000000
+
+/* initialization states */
+#define INIT2		0x2
+#define INIT3		0x4
+
+/* delays */
+#define CYCLE_DELAY	10
+#define TIMEOUT		(HZ / 2)
+
+
+static void *ioaddr;
+
+/* The voo GPIO registers don't have individual masks for each bit
+   so we always have to read before writing. */
+
+static void bit_vooi2c_setscl(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= I2C_SCL_OUT;
+	else
+		r &= ~I2C_SCL_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static void bit_vooi2c_setsda(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= I2C_SDA_OUT;
+	else
+		r &= ~I2C_SDA_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+/* The GPIO pins are open drain, so the pins always remain outputs.
+   We rely on the i2c-algo-bit routines to set the pins high before
+   reading the input from other chips. */
+
+static int bit_vooi2c_getscl(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
+}
+
+static int bit_vooi2c_getsda(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
+}
+
+static void bit_vooddc_setscl(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= DDC_SCL_OUT;
+	else
+		r &= ~DDC_SCL_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static void bit_vooddc_setsda(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if (val)
+		r |= DDC_SDA_OUT;
+	else
+		r &= ~DDC_SDA_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static int bit_vooddc_getscl(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & DDC_SCL_IN));
+}
+
+static int bit_vooddc_getsda(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & DDC_SDA_IN));
+}
+
+static int config_v3(struct pci_dev *dev)
+{
+	unsigned int cadr;
+
+	/* map Voodoo3 memory */
+	cadr = dev->resource[0].start;
+	cadr &= PCI_BASE_ADDRESS_MEM_MASK;
+	ioaddr = ioremap_nocache(cadr, 0x1000);
+	if (ioaddr) {
+		writel(0x8160, ioaddr + REG2);
+		writel(0xcffc0020, ioaddr + REG);
+		dev_info(&dev->dev, "Using Banshee/Voodoo3 I2C device at %p\n", ioaddr);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+static struct i2c_algo_bit_data voo_i2c_bit_data = {
+	.setsda		= bit_vooi2c_setsda,
+	.setscl		= bit_vooi2c_setscl,
+	.getsda		= bit_vooi2c_getsda,
+	.getscl		= bit_vooi2c_getscl,
+	.udelay		= CYCLE_DELAY,
+	.mdelay		= CYCLE_DELAY,
+	.timeout	= TIMEOUT
+};
+
+static struct i2c_adapter voodoo3_i2c_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "I2C Voodoo3/Banshee adapter",
+	.algo_data	= &voo_i2c_bit_data,
+};
+
+static struct i2c_algo_bit_data voo_ddc_bit_data = {
+	.setsda		= bit_vooddc_setsda,
+	.setscl		= bit_vooddc_setscl,
+	.getsda		= bit_vooddc_getsda,
+	.getscl		= bit_vooddc_getscl,
+	.udelay		= CYCLE_DELAY,
+	.mdelay		= CYCLE_DELAY,
+	.timeout	= TIMEOUT
+};
+
+static struct i2c_adapter voodoo3_ddc_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "DDC Voodoo3/Banshee adapter",
+	.algo_data	= &voo_ddc_bit_data,
+};
+
+static struct pci_device_id voodoo3_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE) },
+	{ 0, }
+};
+
+static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int retval;
+
+	retval = config_v3(dev);
+	if (retval)
+		return retval;
+
+	/* set up the sysfs linkage to our parent device */
+	voodoo3_i2c_adapter.dev.parent = &dev->dev;
+	voodoo3_ddc_adapter.dev.parent = &dev->dev;
+
+	retval = i2c_bit_add_bus(&voodoo3_i2c_adapter);
+	if (retval)
+		return retval;
+	retval = i2c_bit_add_bus(&voodoo3_ddc_adapter);
+	if (retval)
+		i2c_bit_del_bus(&voodoo3_i2c_adapter);
+	return retval;
+}
+
+static void __devexit voodoo3_remove(struct pci_dev *dev)
+{
+	i2c_bit_del_bus(&voodoo3_i2c_adapter);
+ 	i2c_bit_del_bus(&voodoo3_ddc_adapter);
+	iounmap(ioaddr);
+}
+
+static struct pci_driver voodoo3_driver = {
+	.name		= "voodoo3 smbus",
+	.id_table	= voodoo3_ids,
+	.probe		= voodoo3_probe,
+	.remove		= __devexit_p(voodoo3_remove),
+};
+
+static int __init i2c_voodoo3_init(void)
+{
+	return pci_module_init(&voodoo3_driver);
+}
+
+static void __exit i2c_voodoo3_exit(void)
+{
+	pci_unregister_driver(&voodoo3_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("Voodoo3 I2C/SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_voodoo3_init);
+module_exit(i2c_voodoo3_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.10, 2003/09/22 11:05:20-07:00, greg@kroah.com

[PATCH] I2C: add the i2c-savage4 i2c bus driver

This is based on the lmsensor cvs version of the driver, but is cleaned
it up and ported it to 2.6.


 drivers/i2c/busses/Kconfig       |   10 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-savage4.c |  205 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 216 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:28 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:14:28 2003
@@ -113,6 +113,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-piix4.
 
+config I2C_SAVAGE4
+	tristate "S3 Savage 4"
+	depends on I2C && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the 
+	  S3 Savage 4 I2C interface.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-savage4.
+
 config I2C_SIS5595
 	tristate "SiS 5595"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:28 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:14:28 2003
@@ -11,6 +11,7 @@
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
diff -Nru a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-savage4.c	Mon Sep 22 16:14:28 2003
@@ -0,0 +1,205 @@
+/*
+    i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware
+              monitoring
+    Copyright (c) 1998, 1999  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 I2C bus of the Savage4 to gain access to
+   the BT869 and possibly other I2C devices. The DDC bus is not
+   yet supported because its register is not memory-mapped.
+   However we leave the DDC code here, commented out, to make
+   it easier to add later.
+*/
+
+#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>
+
+/* 3DFX defines */
+#define PCI_CHIP_SAVAGE3D	0x8A20
+#define PCI_CHIP_SAVAGE3D_MV	0x8A21
+#define PCI_CHIP_SAVAGE4	0x8A22
+#define PCI_CHIP_SAVAGE2000	0x9102
+#define PCI_CHIP_PROSAVAGE_PM	0x8A25
+#define PCI_CHIP_PROSAVAGE_KM	0x8A26
+#define PCI_CHIP_SAVAGE_MX_MV	0x8c10
+#define PCI_CHIP_SAVAGE_MX	0x8c11
+#define PCI_CHIP_SAVAGE_IX_MV	0x8c12
+#define PCI_CHIP_SAVAGE_IX	0x8c13
+
+#define REG			0xff20	/* Serial Port 1 Register */
+
+/* bit locations in the register */
+#define DDC_ENAB		0x00040000
+#define DDC_SCL_OUT		0x00080000
+#define DDC_SDA_OUT		0x00100000
+#define DDC_SCL_IN		0x00200000
+#define DDC_SDA_IN		0x00400000
+#define I2C_ENAB		0x00000020
+#define I2C_SCL_OUT		0x00000001
+#define I2C_SDA_OUT		0x00000002
+#define I2C_SCL_IN		0x00000008
+#define I2C_SDA_IN		0x00000010
+
+/* initialization states */
+#define INIT2			0x20
+#define INIT3			0x04
+
+/* delays */
+#define CYCLE_DELAY		10
+#define TIMEOUT			(HZ / 2)
+
+
+static void *ioaddr;
+
+/* The sav GPIO registers don't have individual masks for each bit
+   so we always have to read before writing. */
+
+static void bit_savi2c_setscl(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if(val)
+		r |= I2C_SCL_OUT;
+	else
+		r &= ~I2C_SCL_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+static void bit_savi2c_setsda(void *data, int val)
+{
+	unsigned int r;
+	r = readl(ioaddr + REG);
+	if(val)
+		r |= I2C_SDA_OUT;
+	else
+		r &= ~I2C_SDA_OUT;
+	writel(r, ioaddr + REG);
+	readl(ioaddr + REG);	/* flush posted write */
+}
+
+/* The GPIO pins are open drain, so the pins always remain outputs.
+   We rely on the i2c-algo-bit routines to set the pins high before
+   reading the input from other chips. */
+
+static int bit_savi2c_getscl(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SCL_IN));
+}
+
+static int bit_savi2c_getsda(void *data)
+{
+	return (0 != (readl(ioaddr + REG) & I2C_SDA_IN));
+}
+
+/* Configures the chip */
+
+static int config_s4(struct pci_dev *dev)
+{
+	unsigned int cadr;
+
+	/* map memory */
+	cadr = dev->resource[0].start;
+	cadr &= PCI_BASE_ADDRESS_MEM_MASK;
+	ioaddr = ioremap_nocache(cadr, 0x0080000);
+	if (ioaddr) {
+		/* writel(0x8160, ioaddr + REG2); */
+		writel(0x00000020, ioaddr + REG);
+		dev_info(&dev->dev, "Using Savage4 at %p\n", ioaddr);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+static struct i2c_algo_bit_data sav_i2c_bit_data = {
+	.setsda		= bit_savi2c_setsda,
+	.setscl		= bit_savi2c_setscl,
+	.getsda		= bit_savi2c_getsda,
+	.getscl		= bit_savi2c_getscl,
+	.udelay		= CYCLE_DELAY,
+	.mdelay		= CYCLE_DELAY,
+	.timeout	= TIMEOUT
+};
+
+static struct i2c_adapter savage4_i2c_adapter = {
+	.owner		= THIS_MODULE,
+	.name		= "I2C Savage4 adapter",
+	.algo_data	= &sav_i2c_bit_data,
+};
+
+static struct pci_device_id savage4_ids[] __devinitdata = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_CHIP_SAVAGE2000) },
+	{ 0, }
+};
+
+static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int retval;
+
+	retval = config_s4(dev);
+	if (retval)
+		return retval;
+
+	/* set up the sysfs linkage to our parent device */
+	savage4_i2c_adapter.dev.parent = &dev->dev;
+
+	return i2c_bit_add_bus(&savage4_i2c_adapter);
+}
+
+static void __devexit savage4_remove(struct pci_dev *dev)
+{
+	i2c_bit_del_bus(&savage4_i2c_adapter);
+	iounmap(ioaddr);
+}
+
+static struct pci_driver savage4_driver = {
+	.name		= "savage4 smbus",
+	.id_table	= savage4_ids,
+	.probe		= savage4_probe,
+	.remove		= __devexit_p(savage4_remove),
+};
+
+static int __init i2c_savage4_init(void)
+{
+	return pci_module_init(&savage4_driver);
+}
+
+static void __exit i2c_savage4_exit(void)
+{
+	pci_unregister_driver(&savage4_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("Savage4 I2C/SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_savage4_init);
+module_exit(i2c_savage4_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                     ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.12, 2003/09/22 11:42:40-07:00, greg@kroah.com

I2C: clean up the i2c chips Kconfig logic and help information


 drivers/i2c/chips/Kconfig |  111 +++++++++++++++++++---------------------------
 1 files changed, 46 insertions(+), 65 deletions(-)


diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	Mon Sep 22 16:14:08 2003
+++ b/drivers/i2c/chips/Kconfig	Mon Sep 22 16:14:08 2003
@@ -1,112 +1,93 @@
 #
-# Sensor device configuration
-# All depend on EXPERIMENTAL and I2C
+# I2C Sensor device configuration
 #
 
 menu "I2C Hardware Sensors Chip support"
 
+config I2C_SENSOR
+	tristate
+	default n
+
 config SENSORS_ADM1021
-	tristate "  Analog Devices ADM1021 and compatibles"
+	tristate "Analog Devices ADM1021 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for Analog Devices ADM1021 
 	  and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
 	  Genesys Logic GL523SM, National Semi LM84, TI THMC10,
-	  and the XEON processor built-in sensor. This can also 
-	  be built as a module which can be inserted and removed while the 
-	  kernel is running.
+	  and the XEON processor built-in sensor.
 
-	  The module will be called adm1021.
-	  
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called adm1021.
 
 config SENSORS_IT87
-	tristate "  National Semiconductors IT87 and compatibles"
+	tristate "National Semiconductors IT87 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
-	  The module will be called it87.
+	  If you say yes here you get support for National Semiconductor IT87
+	  sensor chips and clones: IT8705F, IT8712F and SiS960.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called it87.
 
 config SENSORS_LM75
-	tristate "  National Semiconductors LM75 and compatibles"
+	tristate "National Semiconductors LM75 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for National Semiconductor LM75
 	  sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon
-	  TCN75, and National Semi LM77. This can also be built as a module
-	  which can be inserted and removed while the kernel is running.
-
-	  The module will be called lm75.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
-	  
-config SENSORS_LM85
-	tristate "  National Semiconductors LM85 and compatibles"
-	depends on I2C && EXPERIMENTAL
-	help
-	  If you say yes here you get support for National Semiconductor LM85
-	  sensor chips and clones: ADT7463 and ADM1027.
-	  This can also be built as a module which can be inserted and
-	  removed while the kernel is running.
+	  TCN75, and National Semi LM77.
 
-	  The module will be called lm85.
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm75.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
-	  
 config SENSORS_LM78
-	tristate "  National Semiconductors LM78 and compatibles"
+	tristate "National Semiconductors LM78 and compatibles"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for National Semiconductor LM78,
 	  LM78-J and LM79.  This can also be built as a module which can be
 	  inserted and removed while the kernel is running.
 
-	  The module will be called lm78.
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm78.
+
+config SENSORS_LM85
+	tristate "National Semiconductors LM85 and compatibles"
+	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
+	help
+	  If you say yes here you get support for National Semiconductor LM85
+	  sensor chips and clones: ADT7463 and ADM1027.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called lm85.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at 
-	  http://www.lm-sensors.nu
-	  
 config SENSORS_VIA686A
-	tristate "  VIA686A"
+	tristate "VIA686A"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
-	  support for via686a
 	  If you say yes here you get support for the integrated sensors in
-	  Via 686A/B South Bridges. This can also be built as a module
-	  which can be inserted and removed while the kernel is running.
+	  Via 686A/B South Bridges.
 
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This driver can also be built as a module.  If so, the module
+	  will be called via686a.
 
 config SENSORS_W83781D
-	tristate "  Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
+	tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
 	depends on I2C && EXPERIMENTAL
+	select I2C_SENSOR
 	help
 	  If you say yes here you get support for the Winbond W8378x series
 	  of sensor chips: the W83781D, W83782D, W83783S and W83682HF,
-	  and the similar Asus AS99127F. This
-	  can also be built as a module which can be inserted and removed
-	  while the kernel is running.
+	  and the similar Asus AS99127F.
 	  
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
-
-config I2C_SENSOR
-	tristate
-	default y if SENSORS_ADM1021=y || SENSORS_IT87=y || SENSORS_LM75=y || SENSORS_VIA686A=y || SENSORS_W83781D=y || SENSORS_LM85=y
-	default m if SENSORS_ADM1021=m || SENSORS_IT87=m || SENSORS_LM75=m || SENSORS_VIA686A=m || SENSORS_W83781D=m || SENSORS_LM85=m
-	default n
+	  This driver can also be built as a module.  If so, the module
+	  will be called w83781d.
 
 endmenu


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.13, 2003/09/22 12:26:49-07:00, greg@kroah.com

I2C: clean up the drivers/i2c/Kconfig file


 drivers/i2c/Kconfig |  102 +++++++++++++++++++---------------------------------
 1 files changed, 38 insertions(+), 64 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:13:58 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:13:58 2003
@@ -22,10 +22,20 @@
 	  If you want I2C support, you should say Y here and also to the
 	  specific driver for your bus adapter(s) below.
 
-	  This I2C support is also available as a module.  If you want to
-	  compile it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-core.
+	  This I2C support can also be built as a module.  If so, the module
+	  will be called i2c-core.
+
+config I2C_CHARDEV
+	tristate "I2C device interface"
+	depends on I2C
+	help
+	  Say Y here to use i2c-* device files, usually found in the /dev
+	  directory on your system.  They make it possible to have user-space
+	  programs use the I2C bus.  Information on how to do this is
+	  contained in the file <file:Documentation/i2c/dev-interface>.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-dev.
 
 config I2C_ALGOBIT
 	tristate "I2C bit-banging interfaces"
@@ -35,10 +45,8 @@
 	  adapters.  Say Y if you own an I2C adapter belonging to this class
 	  and then say Y to the specific driver for you adapter below.
 
-	  This support is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-algo-bit.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-algo-bit.
 
 config I2C_PROSAVAGE
 	tristate "S3/VIA (Pro)Savage"
@@ -51,14 +59,8 @@
 	    S3/VIA KM266/VT8375 aka ProSavage8
 	    S3/VIA KM133/VT8365 aka Savage4
 
-	  This can also be built as a module which can be inserted and removed
-	  while the kernel is running.  If you want to compile it as a module,
-	  say M here and read <file:Documentation/modules.txt>.
-	  The module will be called i2c-prosavage.
-
-	  You will also need the latest user-space utilties: you can find them
-	  in the lm_sensors package, which you can download at
-	  http://www.lm-sensors.nu
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-prosavage.
 
 config I2C_PHILIPSPAR
 	tristate "Philips style parallel port adapter"
@@ -67,13 +69,8 @@
 	  This supports parallel-port I2C adapters made by Philips.  Say Y if
 	  you own such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-philips-par.
-
-	  Note that if you want support for different parallel port devices,
-	  life will be much easier if you compile them all as modules.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-philips-par.
 
 config I2C_ELV
 	tristate "ELV adapter"
@@ -82,10 +79,8 @@
 	  This supports parallel-port I2C adapters called ELV.  Say Y if you
 	  own such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-elv.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elv.
 
 config I2C_VELLEMAN
 	tristate "Velleman K9000 adapter"
@@ -94,10 +89,8 @@
 	  This supports the Velleman K9000 parallel-port I2C adapter.  Say Y
 	  if you own such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-velleman.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-velleman.
 
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins"
@@ -107,7 +100,8 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_i2c.
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_i2c.
 
 config SCx200_I2C_SCL
 	int "GPIO pin used for SCL"
@@ -133,7 +127,8 @@
 
 	  If you don't know what to do here, say N.
 
-	  If compiled as a module, it will be called scx200_acb.
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_acb.
 
 config I2C_ALGOPCF
 	tristate "I2C PCF 8584 interfaces"
@@ -143,10 +138,8 @@
 	  Say Y if you own an I2C adapter belonging to this class and then say
 	  Y to the specific driver for you adapter below.
 
-	  This support is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-algo-pcf.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-algo-pcf.
 
 config I2C_ELEKTOR
 	tristate "Elektor ISA card"
@@ -155,10 +148,8 @@
 	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
 	  such an adapter.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-elektor.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elektor.
 
 config I2C_KEYWEST
 	tristate "Powermac Keywest I2C interface"
@@ -167,9 +158,8 @@
 	  This supports the use of the I2C interface in the combo-I/O
 	  chip on recent Apple machines.  Say Y if you have such a machine.
 
-	  This driver is also available as a module.  If you want to compile
-	  it as a module, say M here and read Documentation/modules.txt.
-	  The module will be called i2c-keywest.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-keywest.
 
 config ITE_I2C_ALGO
 	tristate "ITE I2C Algorithm"
@@ -179,9 +169,8 @@
 	  systems. Say Y if you have one of these. You should also say Y for
 	  the ITE I2C peripheral driver support below.
 
-	  This support is also available as a module. If you want to compile
-	  it as a module, say M here and read Documentation/modules.txt.
-	  The module will be called i2c-algo-ite.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-algo-ite.
 
 config ITE_I2C_ADAP
 	tristate "ITE I2C Adapter"
@@ -191,9 +180,8 @@
 	  systems. Say Y if you have one of these. You should also say Y for
 	  the ITE I2C driver algorithm support above.
 
-	  This support is also available as a module. If you want to compile
-	  it as a module, say M here and read Documentation/modules.txt.
-	  The module will be called i2c-adap-ite.
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-adap-ite.
 
 config I2C_ALGO8XX
 	tristate "MPC8xx CPM I2C interface"
@@ -210,20 +198,6 @@
 config I2C_IOP3XX
 	tristate "Intel XScale IOP3xx on-chip I2C interface"
 	depends on ARCH_IOP3XX && I2C
-
-config I2C_CHARDEV
-	tristate "I2C device interface"
-	depends on I2C
-	help
-	  Say Y here to use i2c-* device files, usually found in the /dev
-	  directory on your system.  They make it possible to have user-space
-	  programs use the I2C bus.  Information on how to do this is
-	  contained in the file <file:Documentation/i2c/dev-interface>.
-
-	  This code is also available as a module.  If you want to compile
-	  it as a module, say M here and read
-	  <file:Documentation/modules.txt>.
-	  The module will be called i2c-dev.
 
 	source drivers/i2c/busses/Kconfig
 	source drivers/i2c/chips/Kconfig


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.14, 2003/09/22 12:46:46-07:00, greg@kroah.com

[PATCH] I2C: move i2c-prosavage.c driver to drivers/i2c/busses where it belongs.


 drivers/i2c/i2c-prosavage.c        |  356 -------------------------------------
 drivers/i2c/Kconfig                |   14 -
 drivers/i2c/Makefile               |    1 
 drivers/i2c/busses/Kconfig         |   14 +
 drivers/i2c/busses/Makefile        |    1 
 drivers/i2c/busses/i2c-prosavage.c |  356 +++++++++++++++++++++++++++++++++++++
 6 files changed, 371 insertions(+), 371 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:13:48 2003
@@ -48,20 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_PROSAVAGE
-	tristate "S3/VIA (Pro)Savage"
-	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
-	help
-	  If you say yes to this option, support will be included for the
-	  I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8
-	  graphics processors.
-	  chipsets supported:
-	    S3/VIA KM266/VT8375 aka ProSavage8
-	    S3/VIA KM133/VT8365 aka Savage4
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-prosavage.
-
 config I2C_PHILIPSPAR
 	tristate "Philips style parallel port adapter"
 	depends on I2C_ALGOBIT && PARPORT
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:13:48 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:48 2003
@@ -113,6 +113,20 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-piix4.
 
+config I2C_PROSAVAGE
+	tristate "S3/VIA (Pro)Savage"
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
+	help
+	  If you say yes to this option, support will be included for the
+	  I2C bus and DDC bus of the S3VIA embedded Savage4 and ProSavage8
+	  graphics processors.
+	  chipsets supported:
+	    S3/VIA KM266/VT8375 aka ProSavage8
+	    S3/VIA KM133/VT8365 aka Savage4
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-prosavage.
+
 config I2C_SAVAGE4
 	tristate "S3 Savage 4"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:48 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:48 2003
@@ -11,6 +11,7 @@
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
+obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-prosavage.c	Mon Sep 22 16:13:48 2003
@@ -0,0 +1,356 @@
+/*
+ *    kernel/busses/i2c-prosavage.c
+ *
+ *    i2c bus driver for S3/VIA 8365/8375 graphics processor.
+ *    Copyright (c) 2003 Henk Vergonet <henk@god.dyndns.org>
+ *    Based on code written by:
+ *	Frodo Looijaard <frodol@dds.nl>,
+ *	Philip Edelbrock <phil@netroedge.com>,
+ *	Ralph Metzler <rjkm@thp.uni-koeln.de>, and
+ *	Mark D. Studebaker <mdsxyz123@yahoo.com>
+ *	Simon Vogl
+ *	and others
+ *
+ *    Please read the lm_sensors documentation for details on use.
+ *
+ *    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.
+ *
+ */
+/*  18-05-2003 HVE - created
+ *  14-06-2003 HVE - adapted for lm_sensors2
+ *  17-06-2003 HVE - linux 2.5.xx compatible
+ *  18-06-2003 HVE - codingstyle
+ *  21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx
+ *		     codingstyle, mmio enabled
+ *
+ *  This driver interfaces to the I2C bus of the VIA north bridge embedded
+ *  ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips.
+ *
+ *  Graphics cores:
+ *   S3/VIA KM266/VT8375 aka ProSavage8
+ *   S3/VIA KM133/VT8365 aka Savage4
+ *
+ *  Two serial busses are implemented:
+ *   SERIAL1 - I2C serial communications interface
+ *   SERIAL2 - DDC2 monitor communications interface
+ *
+ *  Tested on a FX41 mainboard, see http://www.shuttle.com
+ * 
+ *
+ *  TODO:
+ *  - integration with prosavage framebuffer device
+ *    (Additional documentation needed :(
+ */
+
+#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>
+
+
+/*
+ * driver configuration
+ */
+#define	DRIVER_ID	"i2c-prosavage"
+#define	DRIVER_VERSION	"20030621"
+
+#define ADAPTER_NAME(x) (x).name
+
+#define MAX_BUSSES	2
+
+struct s_i2c_bus {
+	u8	*mmvga;
+	int	i2c_reg;
+	int	adap_ok;
+	struct i2c_adapter		adap;
+	struct i2c_algo_bit_data	algo;
+};
+
+struct s_i2c_chip {
+	u8	*mmio;
+	struct s_i2c_bus	i2c_bus[MAX_BUSSES];
+};
+
+
+/*
+ * i2c configuration
+ */
+#ifndef I2C_HW_B_S3VIA
+#define I2C_HW_B_S3VIA	0x18	/* S3VIA ProSavage adapter		*/
+#endif
+
+/* delays */
+#define CYCLE_DELAY	10
+#define TIMEOUT		(HZ / 2)
+
+
+/* 
+ * S3/VIA 8365/8375 registers
+ */
+#ifndef PCI_VENDOR_ID_S3
+#define PCI_VENDOR_ID_S3		0x5333
+#endif
+#ifndef PCI_DEVICE_ID_S3_SAVAGE4
+#define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
+#endif
+#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8
+#define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
+#endif
+
+#define VGA_CR_IX	0x3d4
+#define VGA_CR_DATA	0x3d5
+
+#define CR_SERIAL1	0xa0	/* I2C serial communications interface */
+#define MM_SERIAL1	0xff20
+#define CR_SERIAL2	0xb1	/* DDC2 monitor communications interface */
+
+/* based on vt8365 documentation */
+#define I2C_ENAB	0x10
+#define I2C_SCL_OUT	0x01
+#define I2C_SDA_OUT	0x02
+#define I2C_SCL_IN	0x04
+#define I2C_SDA_IN	0x08
+
+#define SET_CR_IX(p, val)	*((p)->mmvga + VGA_CR_IX) = (u8)(val)
+#define SET_CR_DATA(p, val)	*((p)->mmvga + VGA_CR_DATA) = (u8)(val)
+#define GET_CR_DATA(p)		*((p)->mmvga + VGA_CR_DATA)
+
+
+/*
+ * Serial bus line handling
+ *
+ * serial communications register as parameter in private data
+ *
+ * TODO: locks with other code sections accessing video registers?
+ */
+static void bit_s3via_setscl(void *bus, int val)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+	unsigned int r;
+
+	SET_CR_IX(p, p->i2c_reg);
+	r = GET_CR_DATA(p);
+	r |= I2C_ENAB;
+	if (val) {
+		r |= I2C_SCL_OUT;
+	} else {
+		r &= ~I2C_SCL_OUT;
+	}
+	SET_CR_DATA(p, r);
+}
+
+static void bit_s3via_setsda(void *bus, int val)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+	unsigned int r;
+	
+	SET_CR_IX(p, p->i2c_reg);
+	r = GET_CR_DATA(p);
+	r |= I2C_ENAB;
+	if (val) {
+		r |= I2C_SDA_OUT;
+	} else {
+		r &= ~I2C_SDA_OUT;
+	}
+	SET_CR_DATA(p, r);
+}
+
+static int bit_s3via_getscl(void *bus)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+
+	SET_CR_IX(p, p->i2c_reg);
+	return (0 != (GET_CR_DATA(p) & I2C_SCL_IN));
+}
+
+static int bit_s3via_getsda(void *bus)
+{
+	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
+
+	SET_CR_IX(p, p->i2c_reg);
+	return (0 != (GET_CR_DATA(p) & I2C_SDA_IN));
+}
+
+
+/*
+ * adapter initialisation
+ */
+static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+{
+	int ret;
+	p->adap.owner	  = THIS_MODULE;
+	p->adap.id	  = I2C_HW_B_S3VIA;
+	p->adap.algo_data = &p->algo;
+	p->algo.setsda	  = bit_s3via_setsda;
+	p->algo.setscl	  = bit_s3via_setscl;
+	p->algo.getsda	  = bit_s3via_getsda;
+	p->algo.getscl	  = bit_s3via_getscl;
+	p->algo.udelay	  = CYCLE_DELAY;
+	p->algo.mdelay	  = CYCLE_DELAY;
+	p->algo.timeout	  = TIMEOUT;
+	p->algo.data	  = p;
+	p->mmvga	  = mmvga;
+	p->i2c_reg	  = i2c_reg;
+    
+	ret = i2c_bit_add_bus(&p->adap);
+	if (ret) {
+		return ret;
+	}
+
+	p->adap_ok = 1;
+	return 0;
+}
+
+
+/*
+ * Cleanup stuff
+ */
+static void __devexit prosavage_remove(struct pci_dev *dev)
+{
+	struct s_i2c_chip *chip;
+	int i, ret;
+
+	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
+
+	if (!chip) {
+		return;
+	}
+	for (i = MAX_BUSSES - 1; i >= 0; i--) {
+		if (chip->i2c_bus[i].adap_ok = 0)
+			continue;
+
+		ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
+	        if (ret) {
+			printk(DRIVER_ID ": %s not removed\n",
+				ADAPTER_NAME(chip->i2c_bus[i].adap));
+		}
+	}
+	if (chip->mmio) {
+		iounmap(chip->mmio);
+	}
+	kfree(chip);
+}
+
+
+/*
+ * Detect chip and initialize it
+ */
+static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int ret;
+	unsigned long base, len;
+	struct s_i2c_chip *chip;
+	struct s_i2c_bus  *bus;
+
+        pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); 
+	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
+	if (chip = NULL) {
+		return -ENOMEM;
+	}
+
+	memset(chip, 0, sizeof(struct s_i2c_chip));
+
+	base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
+	len  = dev->resource[0].end - base + 1;
+	chip->mmio = ioremap_nocache(base, len);
+
+	if (chip->mmio = NULL) {
+		printk (DRIVER_ID ": ioremap failed\n");
+		prosavage_remove(dev);
+		return -ENODEV;
+	}
+
+
+	/*
+	 * Chip initialisation
+	 */
+	/* Unlock Extended IO Space ??? */
+
+
+	/*
+	 * i2c bus registration
+	 */
+	bus = &chip->i2c_bus[0];
+	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+		"ProSavage I2C bus at %02x:%02x.%x",
+		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1);
+	if (ret) {
+		goto err_adap;
+	}
+	/*
+	 * ddc bus registration
+	 */
+	bus = &chip->i2c_bus[1];
+	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+		"ProSavage DDC bus at %02x:%02x.%x",
+		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2);
+	if (ret) {
+		goto err_adap;
+	}
+	return 0;
+err_adap:
+	printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap));
+	prosavage_remove(dev);
+	return ret;
+}
+
+
+/*
+ * Data for PCI driver interface
+ */
+static struct pci_device_id prosavage_pci_tbl[] = {
+   {
+	.vendor		=	PCI_VENDOR_ID_S3,
+	.device		=	PCI_DEVICE_ID_S3_SAVAGE4,
+	.subvendor	=	PCI_ANY_ID,
+	.subdevice	=	PCI_ANY_ID,
+   },{
+	.vendor		=	PCI_VENDOR_ID_S3,
+	.device		=	PCI_DEVICE_ID_S3_PROSAVAGE8,
+	.subvendor	=	PCI_ANY_ID,
+	.subdevice	=	PCI_ANY_ID,
+   },{ 0, }
+};
+
+static struct pci_driver prosavage_driver = {
+	.name		=	"prosavage-smbus",
+	.id_table	=	prosavage_pci_tbl,
+	.probe		=	prosavage_probe,
+	.remove		=	__devexit_p(prosavage_remove),
+};
+
+static int __init i2c_prosavage_init(void)
+{
+	printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION);
+	return pci_module_init(&prosavage_driver);
+}
+
+static void __exit i2c_prosavage_exit(void)
+{
+	pci_unregister_driver(&prosavage_driver);
+}
+
+MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl);
+MODULE_AUTHOR("Henk Vergonet");
+MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver");
+MODULE_LICENSE("GPL");
+
+module_init (i2c_prosavage_init);
+module_exit (i2c_prosavage_exit);
diff -Nru a/drivers/i2c/i2c-prosavage.c b/drivers/i2c/i2c-prosavage.c
--- a/drivers/i2c/i2c-prosavage.c	Mon Sep 22 16:13:48 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,356 +0,0 @@
-/*
- *    kernel/busses/i2c-prosavage.c
- *
- *    i2c bus driver for S3/VIA 8365/8375 graphics processor.
- *    Copyright (c) 2003 Henk Vergonet <henk@god.dyndns.org>
- *    Based on code written by:
- *	Frodo Looijaard <frodol@dds.nl>,
- *	Philip Edelbrock <phil@netroedge.com>,
- *	Ralph Metzler <rjkm@thp.uni-koeln.de>, and
- *	Mark D. Studebaker <mdsxyz123@yahoo.com>
- *	Simon Vogl
- *	and others
- *
- *    Please read the lm_sensors documentation for details on use.
- *
- *    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.
- *
- */
-/*  18-05-2003 HVE - created
- *  14-06-2003 HVE - adapted for lm_sensors2
- *  17-06-2003 HVE - linux 2.5.xx compatible
- *  18-06-2003 HVE - codingstyle
- *  21-06-2003 HVE - compatibility lm_sensors2 and linux 2.5.xx
- *		     codingstyle, mmio enabled
- *
- *  This driver interfaces to the I2C bus of the VIA north bridge embedded
- *  ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips.
- *
- *  Graphics cores:
- *   S3/VIA KM266/VT8375 aka ProSavage8
- *   S3/VIA KM133/VT8365 aka Savage4
- *
- *  Two serial busses are implemented:
- *   SERIAL1 - I2C serial communications interface
- *   SERIAL2 - DDC2 monitor communications interface
- *
- *  Tested on a FX41 mainboard, see http://www.shuttle.com
- * 
- *
- *  TODO:
- *  - integration with prosavage framebuffer device
- *    (Additional documentation needed :(
- */
-
-#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>
-
-
-/*
- * driver configuration
- */
-#define	DRIVER_ID	"i2c-prosavage"
-#define	DRIVER_VERSION	"20030621"
-
-#define ADAPTER_NAME(x) (x).name
-
-#define MAX_BUSSES	2
-
-struct s_i2c_bus {
-	u8	*mmvga;
-	int	i2c_reg;
-	int	adap_ok;
-	struct i2c_adapter		adap;
-	struct i2c_algo_bit_data	algo;
-};
-
-struct s_i2c_chip {
-	u8	*mmio;
-	struct s_i2c_bus	i2c_bus[MAX_BUSSES];
-};
-
-
-/*
- * i2c configuration
- */
-#ifndef I2C_HW_B_S3VIA
-#define I2C_HW_B_S3VIA	0x18	/* S3VIA ProSavage adapter		*/
-#endif
-
-/* delays */
-#define CYCLE_DELAY	10
-#define TIMEOUT		(HZ / 2)
-
-
-/* 
- * S3/VIA 8365/8375 registers
- */
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3		0x5333
-#endif
-#ifndef PCI_DEVICE_ID_S3_SAVAGE4
-#define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
-#endif
-#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8
-#define PCI_DEVICE_ID_S3_PROSAVAGE8	0x8d04
-#endif
-
-#define VGA_CR_IX	0x3d4
-#define VGA_CR_DATA	0x3d5
-
-#define CR_SERIAL1	0xa0	/* I2C serial communications interface */
-#define MM_SERIAL1	0xff20
-#define CR_SERIAL2	0xb1	/* DDC2 monitor communications interface */
-
-/* based on vt8365 documentation */
-#define I2C_ENAB	0x10
-#define I2C_SCL_OUT	0x01
-#define I2C_SDA_OUT	0x02
-#define I2C_SCL_IN	0x04
-#define I2C_SDA_IN	0x08
-
-#define SET_CR_IX(p, val)	*((p)->mmvga + VGA_CR_IX) = (u8)(val)
-#define SET_CR_DATA(p, val)	*((p)->mmvga + VGA_CR_DATA) = (u8)(val)
-#define GET_CR_DATA(p)		*((p)->mmvga + VGA_CR_DATA)
-
-
-/*
- * Serial bus line handling
- *
- * serial communications register as parameter in private data
- *
- * TODO: locks with other code sections accessing video registers?
- */
-static void bit_s3via_setscl(void *bus, int val)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-	unsigned int r;
-
-	SET_CR_IX(p, p->i2c_reg);
-	r = GET_CR_DATA(p);
-	r |= I2C_ENAB;
-	if (val) {
-		r |= I2C_SCL_OUT;
-	} else {
-		r &= ~I2C_SCL_OUT;
-	}
-	SET_CR_DATA(p, r);
-}
-
-static void bit_s3via_setsda(void *bus, int val)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-	unsigned int r;
-	
-	SET_CR_IX(p, p->i2c_reg);
-	r = GET_CR_DATA(p);
-	r |= I2C_ENAB;
-	if (val) {
-		r |= I2C_SDA_OUT;
-	} else {
-		r &= ~I2C_SDA_OUT;
-	}
-	SET_CR_DATA(p, r);
-}
-
-static int bit_s3via_getscl(void *bus)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-
-	SET_CR_IX(p, p->i2c_reg);
-	return (0 != (GET_CR_DATA(p) & I2C_SCL_IN));
-}
-
-static int bit_s3via_getsda(void *bus)
-{
-	struct s_i2c_bus *p = (struct s_i2c_bus *)bus;
-
-	SET_CR_IX(p, p->i2c_reg);
-	return (0 != (GET_CR_DATA(p) & I2C_SDA_IN));
-}
-
-
-/*
- * adapter initialisation
- */
-static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
-{
-	int ret;
-	p->adap.owner	  = THIS_MODULE;
-	p->adap.id	  = I2C_HW_B_S3VIA;
-	p->adap.algo_data = &p->algo;
-	p->algo.setsda	  = bit_s3via_setsda;
-	p->algo.setscl	  = bit_s3via_setscl;
-	p->algo.getsda	  = bit_s3via_getsda;
-	p->algo.getscl	  = bit_s3via_getscl;
-	p->algo.udelay	  = CYCLE_DELAY;
-	p->algo.mdelay	  = CYCLE_DELAY;
-	p->algo.timeout	  = TIMEOUT;
-	p->algo.data	  = p;
-	p->mmvga	  = mmvga;
-	p->i2c_reg	  = i2c_reg;
-    
-	ret = i2c_bit_add_bus(&p->adap);
-	if (ret) {
-		return ret;
-	}
-
-	p->adap_ok = 1;
-	return 0;
-}
-
-
-/*
- * Cleanup stuff
- */
-static void __devexit prosavage_remove(struct pci_dev *dev)
-{
-	struct s_i2c_chip *chip;
-	int i, ret;
-
-	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
-
-	if (!chip) {
-		return;
-	}
-	for (i = MAX_BUSSES - 1; i >= 0; i--) {
-		if (chip->i2c_bus[i].adap_ok = 0)
-			continue;
-
-		ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
-	        if (ret) {
-			printk(DRIVER_ID ": %s not removed\n",
-				ADAPTER_NAME(chip->i2c_bus[i].adap));
-		}
-	}
-	if (chip->mmio) {
-		iounmap(chip->mmio);
-	}
-	kfree(chip);
-}
-
-
-/*
- * Detect chip and initialize it
- */
-static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id)
-{
-	int ret;
-	unsigned long base, len;
-	struct s_i2c_chip *chip;
-	struct s_i2c_bus  *bus;
-
-        pci_set_drvdata(dev, kmalloc(sizeof(struct s_i2c_chip), GFP_KERNEL)); 
-	chip = (struct s_i2c_chip *)pci_get_drvdata(dev);
-	if (chip = NULL) {
-		return -ENOMEM;
-	}
-
-	memset(chip, 0, sizeof(struct s_i2c_chip));
-
-	base = dev->resource[0].start & PCI_BASE_ADDRESS_MEM_MASK;
-	len  = dev->resource[0].end - base + 1;
-	chip->mmio = ioremap_nocache(base, len);
-
-	if (chip->mmio = NULL) {
-		printk (DRIVER_ID ": ioremap failed\n");
-		prosavage_remove(dev);
-		return -ENODEV;
-	}
-
-
-	/*
-	 * Chip initialisation
-	 */
-	/* Unlock Extended IO Space ??? */
-
-
-	/*
-	 * i2c bus registration
-	 */
-	bus = &chip->i2c_bus[0];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
-		"ProSavage I2C bus at %02x:%02x.%x",
-		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1);
-	if (ret) {
-		goto err_adap;
-	}
-	/*
-	 * ddc bus registration
-	 */
-	bus = &chip->i2c_bus[1];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
-		"ProSavage DDC bus at %02x:%02x.%x",
-		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2);
-	if (ret) {
-		goto err_adap;
-	}
-	return 0;
-err_adap:
-	printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap));
-	prosavage_remove(dev);
-	return ret;
-}
-
-
-/*
- * Data for PCI driver interface
- */
-static struct pci_device_id prosavage_pci_tbl[] = {
-   {
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_SAVAGE4,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_PROSAVAGE8,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{ 0, }
-};
-
-static struct pci_driver prosavage_driver = {
-	.name		=	"prosavage-smbus",
-	.id_table	=	prosavage_pci_tbl,
-	.probe		=	prosavage_probe,
-	.remove		=	__devexit_p(prosavage_remove),
-};
-
-static int __init i2c_prosavage_init(void)
-{
-	printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION);
-	return pci_module_init(&prosavage_driver);
-}
-
-static void __exit i2c_prosavage_exit(void)
-{
-	pci_unregister_driver(&prosavage_driver);
-}
-
-MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl);
-MODULE_AUTHOR("Henk Vergonet");
-MODULE_DESCRIPTION("ProSavage VIA 8365/8375 smbus driver");
-MODULE_LICENSE("GPL");
-
-module_init (i2c_prosavage_init);
-module_exit (i2c_prosavage_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                           ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.15, 2003/09/22 13:06:04-07:00, greg@kroah.com

[PATCH] I2C: clean up i2c-prosavage.c driver

Remove direct memory accesses and link up device in the proper place in the
sysfs tree.


 drivers/i2c/busses/i2c-prosavage.c |   54 ++++++++++++-------------------------
 1 files changed, 18 insertions(+), 36 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c	Mon Sep 22 16:13:38 2003
+++ b/drivers/i2c/busses/i2c-prosavage.c	Mon Sep 22 16:13:38 2003
@@ -60,21 +60,14 @@
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 
-#include <asm/io.h>
-
 
 /*
  * driver configuration
  */
-#define	DRIVER_ID	"i2c-prosavage"
-#define	DRIVER_VERSION	"20030621"
-
-#define ADAPTER_NAME(x) (x).name
-
 #define MAX_BUSSES	2
 
 struct s_i2c_bus {
-	u8	*mmvga;
+	void	*mmvga;
 	int	i2c_reg;
 	int	adap_ok;
 	struct i2c_adapter		adap;
@@ -82,7 +75,7 @@
 };
 
 struct s_i2c_chip {
-	u8	*mmio;
+	void	*mmio;
 	struct s_i2c_bus	i2c_bus[MAX_BUSSES];
 };
 
@@ -102,9 +95,6 @@
 /* 
  * S3/VIA 8365/8375 registers
  */
-#ifndef PCI_VENDOR_ID_S3
-#define PCI_VENDOR_ID_S3		0x5333
-#endif
 #ifndef PCI_DEVICE_ID_S3_SAVAGE4
 #define PCI_DEVICE_ID_S3_SAVAGE4	0x8a25
 #endif
@@ -126,9 +116,9 @@
 #define I2C_SCL_IN	0x04
 #define I2C_SDA_IN	0x08
 
-#define SET_CR_IX(p, val)	*((p)->mmvga + VGA_CR_IX) = (u8)(val)
-#define SET_CR_DATA(p, val)	*((p)->mmvga + VGA_CR_DATA) = (u8)(val)
-#define GET_CR_DATA(p)		*((p)->mmvga + VGA_CR_DATA)
+#define SET_CR_IX(p, val)	writeb((val), (p)->mmvga + VGA_CR_IX)
+#define SET_CR_DATA(p, val)	writeb((val), (p)->mmvga + VGA_CR_DATA)
+#define GET_CR_DATA(p)		readb((p)->mmvga + VGA_CR_DATA)
 
 
 /*
@@ -190,12 +180,13 @@
 /*
  * adapter initialisation
  */
-static int i2c_register_bus(struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
 {
 	int ret;
 	p->adap.owner	  = THIS_MODULE;
 	p->adap.id	  = I2C_HW_B_S3VIA;
 	p->adap.algo_data = &p->algo;
+	p->adap.dev.parent = &dev->dev;
 	p->algo.setsda	  = bit_s3via_setsda;
 	p->algo.setscl	  = bit_s3via_setscl;
 	p->algo.getsda	  = bit_s3via_getsda;
@@ -236,8 +227,8 @@
 
 		ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
 	        if (ret) {
-			printk(DRIVER_ID ": %s not removed\n",
-				ADAPTER_NAME(chip->i2c_bus[i].adap));
+			dev_err(&dev->dev, ": %s not removed\n",
+				chip->i2c_bus[i].adap.name);
 		}
 	}
 	if (chip->mmio) {
@@ -270,7 +261,7 @@
 	chip->mmio = ioremap_nocache(base, len);
 
 	if (chip->mmio = NULL) {
-		printk (DRIVER_ID ": ioremap failed\n");
+		dev_err(&dev->dev, "ioremap failed\n");
 		prosavage_remove(dev);
 		return -ENODEV;
 	}
@@ -286,10 +277,10 @@
 	 * i2c bus registration
 	 */
 	bus = &chip->i2c_bus[0];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage I2C bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL1);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL1);
 	if (ret) {
 		goto err_adap;
 	}
@@ -297,16 +288,16 @@
 	 * ddc bus registration
 	 */
 	bus = &chip->i2c_bus[1];
-	snprintf(ADAPTER_NAME(bus->adap), sizeof(ADAPTER_NAME(bus->adap)),
+	snprintf(bus->adap.name, sizeof(bus->adap.name),
 		"ProSavage DDC bus at %02x:%02x.%x",
 		dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-	ret = i2c_register_bus(bus, chip->mmio + 0x8000, CR_SERIAL2);
+	ret = i2c_register_bus(dev, bus, chip->mmio + 0x8000, CR_SERIAL2);
 	if (ret) {
 		goto err_adap;
 	}
 	return 0;
 err_adap:
-	printk (DRIVER_ID ": %s failed\n", ADAPTER_NAME(bus->adap));
+	dev_err(&dev->dev, ": %s failed\n", bus->adap.name);
 	prosavage_remove(dev);
 	return ret;
 }
@@ -316,17 +307,9 @@
  * Data for PCI driver interface
  */
 static struct pci_device_id prosavage_pci_tbl[] = {
-   {
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_SAVAGE4,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{
-	.vendor		=	PCI_VENDOR_ID_S3,
-	.device		=	PCI_DEVICE_ID_S3_PROSAVAGE8,
-	.subvendor	=	PCI_ANY_ID,
-	.subdevice	=	PCI_ANY_ID,
-   },{ 0, }
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_SAVAGE4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_S3, PCI_DEVICE_ID_S3_PROSAVAGE8) },
+	{ 0, },
 };
 
 static struct pci_driver prosavage_driver = {
@@ -338,7 +321,6 @@
 
 static int __init i2c_prosavage_init(void)
 {
-	printk(DRIVER_ID " version %s (%s)\n", I2C_VERSION, DRIVER_VERSION);
 	return pci_module_init(&prosavage_driver);
 }
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                             ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.16, 2003/09/22 13:10:15-07:00, greg@kroah.com

[PATCH] I2C: fix up dependancies in the i2c/busses/Kconfig file


 drivers/i2c/busses/Kconfig |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:27 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:27 2003
@@ -64,7 +64,7 @@
 
 config I2C_I810
 	tristate "Intel 810/815"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  810/815 family of mainboard I2C interfaces.  Specifically, the 
@@ -129,7 +129,7 @@
 
 config I2C_SAVAGE4
 	tristate "S3 Savage 4"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
 	  S3 Savage 4 I2C interface.
@@ -176,7 +176,7 @@
 
 config I2C_VIA
 	tristate "VIA 82C58B"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 
 	  If you say yes to this option, support will be included for the VIA
@@ -205,7 +205,7 @@
 
 config I2C_VOODOO3
 	tristate "Voodoo 3"
-	depends on I2C && PCI && EXPERIMENTAL
+	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
 	help
 
 	  If you say yes to this option, support will be included for the


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                               ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.17, 2003/09/22 13:20:35-07:00, greg@kroah.com

[PATCH] I2C: move the i2c-philips-par driver to drivers/i2c/busses


 drivers/i2c/i2c-philips-par.c        |  256 -----------------------------------
 drivers/i2c/Kconfig                  |   10 -
 drivers/i2c/Makefile                 |    1 
 drivers/i2c/busses/Kconfig           |    9 +
 drivers/i2c/busses/Makefile          |    1 
 drivers/i2c/busses/i2c-philips-par.c |  256 +++++++++++++++++++++++++++++++++++
 6 files changed, 266 insertions(+), 267 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:13:17 2003
@@ -48,16 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_PHILIPSPAR
-	tristate "Philips style parallel port adapter"
-	depends on I2C_ALGOBIT && PARPORT
-	---help---
-	  This supports parallel-port I2C adapters made by Philips.  Say Y if
-	  you own such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-philips-par.
-
 config I2C_ELV
 	tristate "ELV adapter"
 	depends on I2C_ALGOBIT && ISA
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:13:17 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:13:17 2003
@@ -97,6 +97,15 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-nforce2.
 
+config I2C_PHILIPSPAR
+	tristate "Philips style parallel port adapter"
+	depends on I2C_ALGOBIT && PARPORT
+	help
+	  This supports parallel-port I2C adapters made by Philips.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-philips-par.
+
 config I2C_PIIX4
 	tristate "Intel PIIX4"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:17 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:13:17 2003
@@ -10,6 +10,7 @@
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
+obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
diff -Nru a/drivers/i2c/busses/i2c-philips-par.c b/drivers/i2c/busses/i2c-philips-par.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-philips-par.c	Mon Sep 22 16:13:17 2003
@@ -0,0 +1,256 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-philips-par.c i2c-hw access for philips style parallel port adapters  */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-2000 Simon G. 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.		     */
+/* ------------------------------------------------------------------------- */ 
+
+/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+/* $Id: i2c-philips-par.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/parport.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+static int type;
+
+struct i2c_par
+{
+	struct pardevice *pdev;
+	struct i2c_adapter adapter;
+	struct i2c_algo_bit_data bit_lp_data;
+	struct i2c_par *next;
+};
+
+static struct i2c_par *adapter_list;
+
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+
+/* ----- printer port defines ------------------------------------------*/
+					/* Pin Port  Inverted	name	*/
+#define I2C_ON		0x20		/* 12 status N	paper		*/
+					/* ... only for phil. not used  */
+#define I2C_SDA		0x80		/*  9 data   N	data7		*/
+#define I2C_SCL		0x08		/* 17 ctrl   N	dsel		*/
+
+#define I2C_SDAIN	0x80		/* 11 stat   Y	busy		*/
+#define I2C_SCLIN	0x08		/* 15 stat   Y	enable		*/
+
+#define I2C_DMASK	0x7f
+#define I2C_CMASK	0xf7
+
+/* ----- local functions ----------------------------------------------	*/
+
+static void bit_lp_setscl(void *data, int state)
+{
+	/*be cautious about state of the control register - 
+		touch only the one bit needed*/
+	if (state) {
+		parport_write_control((struct parport *) data,
+		      parport_read_control((struct parport *) data)|I2C_SCL);
+	} else {
+		parport_write_control((struct parport *) data,
+		      parport_read_control((struct parport *) data)&I2C_CMASK);
+	}
+}
+
+static void bit_lp_setsda(void *data, int state)
+{
+	if (state) {
+		parport_write_data((struct parport *) data, I2C_DMASK);
+	} else {
+		parport_write_data((struct parport *) data, I2C_SDA);
+	}
+}
+
+static int bit_lp_getscl(void *data)
+{
+	return parport_read_status((struct parport *) data) & I2C_SCLIN;
+}
+
+static int bit_lp_getsda(void *data)
+{
+	return parport_read_status((struct parport *) data) & I2C_SDAIN;
+}
+
+static void bit_lp_setscl2(void *data, int state)
+{
+	if (state) {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)|0x1);
+	} else {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)&0xfe);
+	}
+}
+
+static void bit_lp_setsda2(void *data, int state)
+{
+	if (state) {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)|0x2);
+	} else {
+		parport_write_data((struct parport *) data,
+		      parport_read_data((struct parport *) data)&0xfd);
+	}
+}
+
+static int bit_lp_getsda2(void *data)
+{
+	return (parport_read_status((struct parport *) data) & 
+			             PARPORT_STATUS_BUSY) ? 0 : 1;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+ 
+static struct i2c_algo_bit_data bit_lp_data = {
+	.setsda		= bit_lp_setsda,
+	.setscl		= bit_lp_setscl,
+	.getsda		= bit_lp_getsda,
+	.getscl		= bit_lp_getscl,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+}; 
+
+static struct i2c_algo_bit_data bit_lp_data2 = {
+	.setsda		= bit_lp_setsda2,
+	.setscl		= bit_lp_setscl2,
+	.getsda		= bit_lp_getsda2,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+}; 
+
+static struct i2c_adapter bit_lp_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_B_LP,
+	.name		= "Philips Parallel port adapter",
+};
+
+static void i2c_parport_attach (struct parport *port)
+{
+	struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par),
+					  GFP_KERNEL);
+	if (!adapter) {
+		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
+		return;
+	}
+
+	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
+
+	adapter->pdev = parport_register_device(port, "i2c-philips-par",
+						NULL, NULL, NULL, 
+						PARPORT_FLAG_EXCL,
+						NULL);
+	if (!adapter->pdev) {
+		printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
+		kfree(adapter);
+		return;
+	}
+
+	adapter->adapter = bit_lp_ops;
+	adapter->adapter.algo_data = &adapter->bit_lp_data;
+	adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data;
+	adapter->bit_lp_data.data = port;
+
+	if (parport_claim_or_block(adapter->pdev) < 0 ) {
+		printk(KERN_ERR "i2c-philips-par: Could not claim parallel port.\n");
+		kfree(adapter);
+		return;
+	}
+	/* reset hardware to sane state */
+	bit_lp_setsda(port, 1);
+	bit_lp_setscl(port, 1);
+	parport_release(adapter->pdev);
+
+	if (i2c_bit_add_bus(&adapter->adapter) < 0)
+	{
+		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
+		parport_unregister_device(adapter->pdev);
+		kfree(adapter);
+		return;		/* No good */
+	}
+
+	adapter->next = adapter_list;
+	adapter_list = adapter;
+}
+
+static void i2c_parport_detach (struct parport *port)
+{
+	struct i2c_par *adapter, *prev = NULL;
+
+	for (adapter = adapter_list; adapter; adapter = adapter->next)
+	{
+		if (adapter->pdev->port = port)
+		{
+			parport_unregister_device(adapter->pdev);
+			i2c_bit_del_bus(&adapter->adapter);
+			if (prev)
+				prev->next = adapter->next;
+			else
+				adapter_list = adapter->next;
+			kfree(adapter);
+			return;
+		}
+		prev = adapter;
+	}
+}
+
+
+static struct parport_driver i2c_driver = {
+	"i2c-philips-par",
+	i2c_parport_attach,
+	i2c_parport_detach,
+	NULL
+};
+
+int __init i2c_bitlp_init(void)
+{
+	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+
+	parport_register_driver(&i2c_driver);
+	
+	return 0;
+}
+
+void __exit i2c_bitlp_exit(void)
+{
+	parport_unregister_driver(&i2c_driver);
+}
+
+MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(type, "i");
+
+module_init(i2c_bitlp_init);
+module_exit(i2c_bitlp_exit);
diff -Nru a/drivers/i2c/i2c-philips-par.c b/drivers/i2c/i2c-philips-par.c
--- a/drivers/i2c/i2c-philips-par.c	Mon Sep 22 16:13:17 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,256 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-philips-par.c i2c-hw access for philips style parallel port adapters  */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-2000 Simon G. 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.		     */
-/* ------------------------------------------------------------------------- */ 
-
-/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* $Id: i2c-philips-par.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/stddef.h>
-#include <linux/parport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-
-static int type;
-
-struct i2c_par
-{
-	struct pardevice *pdev;
-	struct i2c_adapter adapter;
-	struct i2c_algo_bit_data bit_lp_data;
-	struct i2c_par *next;
-};
-
-static struct i2c_par *adapter_list;
-
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-
-/* ----- printer port defines ------------------------------------------*/
-					/* Pin Port  Inverted	name	*/
-#define I2C_ON		0x20		/* 12 status N	paper		*/
-					/* ... only for phil. not used  */
-#define I2C_SDA		0x80		/*  9 data   N	data7		*/
-#define I2C_SCL		0x08		/* 17 ctrl   N	dsel		*/
-
-#define I2C_SDAIN	0x80		/* 11 stat   Y	busy		*/
-#define I2C_SCLIN	0x08		/* 15 stat   Y	enable		*/
-
-#define I2C_DMASK	0x7f
-#define I2C_CMASK	0xf7
-
-/* ----- local functions ----------------------------------------------	*/
-
-static void bit_lp_setscl(void *data, int state)
-{
-	/*be cautious about state of the control register - 
-		touch only the one bit needed*/
-	if (state) {
-		parport_write_control((struct parport *) data,
-		      parport_read_control((struct parport *) data)|I2C_SCL);
-	} else {
-		parport_write_control((struct parport *) data,
-		      parport_read_control((struct parport *) data)&I2C_CMASK);
-	}
-}
-
-static void bit_lp_setsda(void *data, int state)
-{
-	if (state) {
-		parport_write_data((struct parport *) data, I2C_DMASK);
-	} else {
-		parport_write_data((struct parport *) data, I2C_SDA);
-	}
-}
-
-static int bit_lp_getscl(void *data)
-{
-	return parport_read_status((struct parport *) data) & I2C_SCLIN;
-}
-
-static int bit_lp_getsda(void *data)
-{
-	return parport_read_status((struct parport *) data) & I2C_SDAIN;
-}
-
-static void bit_lp_setscl2(void *data, int state)
-{
-	if (state) {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)|0x1);
-	} else {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)&0xfe);
-	}
-}
-
-static void bit_lp_setsda2(void *data, int state)
-{
-	if (state) {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)|0x2);
-	} else {
-		parport_write_data((struct parport *) data,
-		      parport_read_data((struct parport *) data)&0xfd);
-	}
-}
-
-static int bit_lp_getsda2(void *data)
-{
-	return (parport_read_status((struct parport *) data) & 
-			             PARPORT_STATUS_BUSY) ? 0 : 1;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
- 
-static struct i2c_algo_bit_data bit_lp_data = {
-	.setsda		= bit_lp_setsda,
-	.setscl		= bit_lp_setscl,
-	.getsda		= bit_lp_getsda,
-	.getscl		= bit_lp_getscl,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-}; 
-
-static struct i2c_algo_bit_data bit_lp_data2 = {
-	.setsda		= bit_lp_setsda2,
-	.setscl		= bit_lp_setscl2,
-	.getsda		= bit_lp_getsda2,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-}; 
-
-static struct i2c_adapter bit_lp_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_LP,
-	.name		= "Philips Parallel port adapter",
-};
-
-static void i2c_parport_attach (struct parport *port)
-{
-	struct i2c_par *adapter = kmalloc(sizeof(struct i2c_par),
-					  GFP_KERNEL);
-	if (!adapter) {
-		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
-		return;
-	}
-
-	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
-
-	adapter->pdev = parport_register_device(port, "i2c-philips-par",
-						NULL, NULL, NULL, 
-						PARPORT_FLAG_EXCL,
-						NULL);
-	if (!adapter->pdev) {
-		printk(KERN_ERR "i2c-philips-par: Unable to register with parport.\n");
-		kfree(adapter);
-		return;
-	}
-
-	adapter->adapter = bit_lp_ops;
-	adapter->adapter.algo_data = &adapter->bit_lp_data;
-	adapter->bit_lp_data = type ? bit_lp_data2 : bit_lp_data;
-	adapter->bit_lp_data.data = port;
-
-	if (parport_claim_or_block(adapter->pdev) < 0 ) {
-		printk(KERN_ERR "i2c-philips-par: Could not claim parallel port.\n");
-		kfree(adapter);
-		return;
-	}
-	/* reset hardware to sane state */
-	bit_lp_setsda(port, 1);
-	bit_lp_setscl(port, 1);
-	parport_release(adapter->pdev);
-
-	if (i2c_bit_add_bus(&adapter->adapter) < 0)
-	{
-		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
-		parport_unregister_device(adapter->pdev);
-		kfree(adapter);
-		return;		/* No good */
-	}
-
-	adapter->next = adapter_list;
-	adapter_list = adapter;
-}
-
-static void i2c_parport_detach (struct parport *port)
-{
-	struct i2c_par *adapter, *prev = NULL;
-
-	for (adapter = adapter_list; adapter; adapter = adapter->next)
-	{
-		if (adapter->pdev->port = port)
-		{
-			parport_unregister_device(adapter->pdev);
-			i2c_bit_del_bus(&adapter->adapter);
-			if (prev)
-				prev->next = adapter->next;
-			else
-				adapter_list = adapter->next;
-			kfree(adapter);
-			return;
-		}
-		prev = adapter;
-	}
-}
-
-
-static struct parport_driver i2c_driver = {
-	"i2c-philips-par",
-	i2c_parport_attach,
-	i2c_parport_detach,
-	NULL
-};
-
-int __init i2c_bitlp_init(void)
-{
-	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-	parport_register_driver(&i2c_driver);
-	
-	return 0;
-}
-
-void __exit i2c_bitlp_exit(void)
-{
-	parport_unregister_driver(&i2c_driver);
-}
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for Philips parallel port adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(type, "i");
-
-module_init(i2c_bitlp_init);
-module_exit(i2c_bitlp_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                                 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.18, 2003/09/22 13:30:23-07:00, greg@kroah.com

[PATCH] I2C: clean up i2c-philips-par.c driver a bit

Fix bug when registering the i2c_adap as the structure was not set to 0.


 drivers/i2c/busses/i2c-philips-par.c |   33 ++++++++++-----------------------
 1 files changed, 10 insertions(+), 23 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-philips-par.c b/drivers/i2c/busses/i2c-philips-par.c
--- a/drivers/i2c/busses/i2c-philips-par.c	Mon Sep 22 16:13:06 2003
+++ b/drivers/i2c/busses/i2c-philips-par.c	Mon Sep 22 16:13:06 2003
@@ -24,10 +24,8 @@
 /* $Id: i2c-philips-par.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
 
 #include <linux/kernel.h>
-#include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/stddef.h>
 #include <linux/parport.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
@@ -45,11 +43,6 @@
 static struct i2c_par *adapter_list;
 
 
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-
 /* ----- printer port defines ------------------------------------------*/
 					/* Pin Port  Inverted	name	*/
 #define I2C_ON		0x20		/* 12 status N	paper		*/
@@ -163,8 +156,9 @@
 		printk(KERN_ERR "i2c-philips-par: Unable to malloc.\n");
 		return;
 	}
+	memset (adapter, 0x00, sizeof(struct i2c_par));
 
-	printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
+	/* printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name); */
 
 	adapter->pdev = parport_register_device(port, "i2c-philips-par",
 						NULL, NULL, NULL, 
@@ -191,8 +185,7 @@
 	bit_lp_setscl(port, 1);
 	parport_release(adapter->pdev);
 
-	if (i2c_bit_add_bus(&adapter->adapter) < 0)
-	{
+	if (i2c_bit_add_bus(&adapter->adapter) < 0) {
 		printk(KERN_ERR "i2c-philips-par: Unable to register with I2C.\n");
 		parport_unregister_device(adapter->pdev);
 		kfree(adapter);
@@ -207,10 +200,8 @@
 {
 	struct i2c_par *adapter, *prev = NULL;
 
-	for (adapter = adapter_list; adapter; adapter = adapter->next)
-	{
-		if (adapter->pdev->port = port)
-		{
+	for (adapter = adapter_list; adapter; adapter = adapter->next) {
+		if (adapter->pdev->port = port) {
 			parport_unregister_device(adapter->pdev);
 			i2c_bit_del_bus(&adapter->adapter);
 			if (prev)
@@ -224,21 +215,17 @@
 	}
 }
 
-
 static struct parport_driver i2c_driver = {
-	"i2c-philips-par",
-	i2c_parport_attach,
-	i2c_parport_detach,
-	NULL
+	.name =		"i2c-philips-par",
+	.attach =	i2c_parport_attach,
+	.detach =	i2c_parport_detach,
 };
 
 int __init i2c_bitlp_init(void)
 {
-	printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c Philips parallel port adapter driver\n");
 
-	parport_register_driver(&i2c_driver);
-	
-	return 0;
+	return parport_register_driver(&i2c_driver);
 }
 
 void __exit i2c_bitlp_exit(void)


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                                   ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.19, 2003/09/22 13:36:52-07:00, greg@kroah.com

[PATCH] I2C: move i2c-elv.c driver to drivers/i2c/busses


 drivers/i2c/i2c-elv.c        |  176 -------------------------------------------
 drivers/i2c/Kconfig          |   10 --
 drivers/i2c/Makefile         |    1 
 drivers/i2c/busses/Kconfig   |   10 ++
 drivers/i2c/busses/Makefile  |    1 
 drivers/i2c/busses/i2c-elv.c |  176 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 187 insertions(+), 187 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:56 2003
@@ -48,16 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_ELV
-	tristate "ELV adapter"
-	depends on I2C_ALGOBIT && ISA
-	help
-	  This supports parallel-port I2C adapters called ELV.  Say Y if you
-	  own such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-elv.
-
 config I2C_VELLEMAN
 	tristate "Velleman K9000 adapter"
 	depends on I2C_ALGOBIT && ISA
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:56 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:56 2003
@@ -46,6 +46,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-amd8111.
 
+config I2C_ELV
+	tristate "ELV adapter"
+	depends on I2C_ALGOBIT && ISA
+	help
+	  This supports parallel-port I2C adapters called ELV.  Say Y if you
+	  own such an adapter.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elv.
+
 config I2C_I801
 	tristate "Intel 801"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:56 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:56 2003
@@ -6,6 +6,7 @@
 obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
+obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
diff -Nru a/drivers/i2c/busses/i2c-elv.c b/drivers/i2c/busses/i2c-elv.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-elv.c	Mon Sep 22 16:12:56 2003
@@ -0,0 +1,176 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-elv.c i2c-hw access for philips style parallel port adapters	     */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-2000 Simon G. 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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+/* $Id: i2c-elv.c,v 1.27 2003/01/21 08:08:16 kmalkki Exp $ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/io.h>
+
+#define DEFAULT_BASE 0x378
+static int base=0;
+static unsigned char PortData = 0;
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+#define DEBINIT(x) x	/* detection status messages			*/
+
+/* --- Convenience defines for the parallel port:			*/
+#define BASE	(unsigned int)(data)
+#define DATA	BASE			/* Centronics data port		*/
+#define STAT	(BASE+1)		/* Centronics status port	*/
+#define CTRL	(BASE+2)		/* Centronics control port	*/
+
+
+/* ----- local functions ----------------------------------------------	*/
+
+
+static void bit_elv_setscl(void *data, int state)
+{
+	if (state) {
+		PortData &= 0xfe;
+	} else {
+		PortData |=1;
+	}
+	outb(PortData, DATA);
+}
+
+static void bit_elv_setsda(void *data, int state)
+{
+	if (state) {
+		PortData &=0xfd;
+	} else {
+		PortData |=2;
+	}
+	outb(PortData, DATA);
+} 
+
+static int bit_elv_getscl(void *data)
+{
+	return ( 0 = ( (inb_p(STAT)) & 0x08 ) );
+}
+
+static int bit_elv_getsda(void *data)
+{
+	return ( 0 = ( (inb_p(STAT)) & 0x40 ) );
+}
+
+static int bit_elv_init(void)
+{
+	if (!request_region(base, (base = 0x3bc) ? 3 : 8,
+				"i2c (ELV adapter)"))
+		return -ENODEV;
+
+	if (inb(base+1) & 0x80) {	/* BUSY should be high	*/
+		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
+		goto fail;
+	} 
+
+	outb(0x0c,base+2);	/* SLCT auf low		*/
+	udelay(400);
+	if (!(inb(base+1) && 0x10)) {
+		outb(0x04,base+2);
+		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
+		goto fail;
+	}
+
+	PortData = 0;
+	bit_elv_setsda((void*)base,1);
+	bit_elv_setscl((void*)base,1);
+	return 0;
+
+fail:
+	release_region(base , (base = 0x3bc) ? 3 : 8);
+	return -ENODEV;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_bit_data bit_elv_data = {
+	.setsda		= bit_elv_setsda,
+	.setscl		= bit_elv_setscl,
+	.getsda		= bit_elv_getsda,
+	.getscl		= bit_elv_getscl,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter bit_elv_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_B_ELV,
+	.algo_data	= &bit_elv_data,
+	.name		= "ELV Parallel port adaptor",
+};
+
+static int __init i2c_bitelv_init(void)
+{
+	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	if (base=0) {
+		/* probe some values */
+		basefiFAULT_BASE;
+		bit_elv_data.data=(void*)DEFAULT_BASE;
+		if (bit_elv_init()=0) {
+			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	} else {
+		i2c_set_adapdata(&bit_elv_ops, (void *)base);
+		if (bit_elv_init()=0) {
+			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	}
+	printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base);
+	return 0;
+}
+
+static void __exit i2c_bitelv_exit(void)
+{
+	i2c_bit_del_bus(&bit_elv_ops);
+	release_region(base , (base = 0x3bc) ? 3 : 8);
+}
+
+MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+
+module_init(i2c_bitelv_init);
+module_exit(i2c_bitelv_exit);
diff -Nru a/drivers/i2c/i2c-elv.c b/drivers/i2c/i2c-elv.c
--- a/drivers/i2c/i2c-elv.c	Mon Sep 22 16:12:56 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,176 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-elv.c i2c-hw access for philips style parallel port adapters	     */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-2000 Simon G. 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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* $Id: i2c-elv.c,v 1.27 2003/01/21 08:08:16 kmalkki Exp $ */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-#define DEFAULT_BASE 0x378
-static int base=0;
-static unsigned char PortData = 0;
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-#define DEBINIT(x) x	/* detection status messages			*/
-
-/* --- Convenience defines for the parallel port:			*/
-#define BASE	(unsigned int)(data)
-#define DATA	BASE			/* Centronics data port		*/
-#define STAT	(BASE+1)		/* Centronics status port	*/
-#define CTRL	(BASE+2)		/* Centronics control port	*/
-
-
-/* ----- local functions ----------------------------------------------	*/
-
-
-static void bit_elv_setscl(void *data, int state)
-{
-	if (state) {
-		PortData &= 0xfe;
-	} else {
-		PortData |=1;
-	}
-	outb(PortData, DATA);
-}
-
-static void bit_elv_setsda(void *data, int state)
-{
-	if (state) {
-		PortData &=0xfd;
-	} else {
-		PortData |=2;
-	}
-	outb(PortData, DATA);
-} 
-
-static int bit_elv_getscl(void *data)
-{
-	return ( 0 = ( (inb_p(STAT)) & 0x08 ) );
-}
-
-static int bit_elv_getsda(void *data)
-{
-	return ( 0 = ( (inb_p(STAT)) & 0x40 ) );
-}
-
-static int bit_elv_init(void)
-{
-	if (!request_region(base, (base = 0x3bc) ? 3 : 8,
-				"i2c (ELV adapter)"))
-		return -ENODEV;
-
-	if (inb(base+1) & 0x80) {	/* BUSY should be high	*/
-		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Busy was low.\n"));
-		goto fail;
-	} 
-
-	outb(0x0c,base+2);	/* SLCT auf low		*/
-	udelay(400);
-	if (!(inb(base+1) && 0x10)) {
-		outb(0x04,base+2);
-		DEBINIT(printk(KERN_DEBUG "i2c-elv.o: Select was high.\n"));
-		goto fail;
-	}
-
-	PortData = 0;
-	bit_elv_setsda((void*)base,1);
-	bit_elv_setscl((void*)base,1);
-	return 0;
-
-fail:
-	release_region(base , (base = 0x3bc) ? 3 : 8);
-	return -ENODEV;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_bit_data bit_elv_data = {
-	.setsda		= bit_elv_setsda,
-	.setscl		= bit_elv_setscl,
-	.getsda		= bit_elv_getsda,
-	.getscl		= bit_elv_getscl,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-};
-
-static struct i2c_adapter bit_elv_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_ELV,
-	.algo_data	= &bit_elv_data,
-	.name		= "ELV Parallel port adaptor",
-};
-
-static int __init i2c_bitelv_init(void)
-{
-	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-	if (base=0) {
-		/* probe some values */
-		basefiFAULT_BASE;
-		bit_elv_data.data=(void*)DEFAULT_BASE;
-		if (bit_elv_init()=0) {
-			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	} else {
-		i2c_set_adapdata(&bit_elv_ops, (void *)base);
-		if (bit_elv_init()=0) {
-			if(i2c_bit_add_bus(&bit_elv_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	}
-	printk(KERN_DEBUG "i2c-elv.o: found device at %#x.\n",base);
-	return 0;
-}
-
-static void __exit i2c_bitelv_exit(void)
-{
-	i2c_bit_del_bus(&bit_elv_ops);
-	release_region(base , (base = 0x3bc) ? 3 : 8);
-}
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-
-module_init(i2c_bitelv_init);
-module_exit(i2c_bitelv_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                                     ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.20, 2003/09/22 13:44:13-07:00, greg@kroah.com

[PATCH] I2C: clean up the i2c-elv.c driver a bit


 drivers/i2c/busses/i2c-elv.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-elv.c b/drivers/i2c/busses/i2c-elv.c
--- a/drivers/i2c/busses/i2c-elv.c	Mon Sep 22 16:12:46 2003
+++ b/drivers/i2c/busses/i2c-elv.c	Mon Sep 22 16:12:46 2003
@@ -21,8 +21,6 @@
 /* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
    Frodo Looijaard <frodol@dds.nl> */
 
-/* $Id: i2c-elv.c,v 1.27 2003/01/21 08:08:16 kmalkki Exp $ */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -36,7 +34,7 @@
 
 #define DEFAULT_BASE 0x378
 static int base=0;
-static unsigned char PortData = 0;
+static unsigned char port_data = 0;
 
 /* ----- global defines -----------------------------------------------	*/
 #define DEB(x)		/* should be reasonable open, close &c. 	*/
@@ -57,21 +55,21 @@
 static void bit_elv_setscl(void *data, int state)
 {
 	if (state) {
-		PortData &= 0xfe;
+		port_data &= 0xfe;
 	} else {
-		PortData |=1;
+		port_data |=1;
 	}
-	outb(PortData, DATA);
+	outb(port_data, DATA);
 }
 
 static void bit_elv_setsda(void *data, int state)
 {
 	if (state) {
-		PortData &=0xfd;
+		port_data &=0xfd;
 	} else {
-		PortData |=2;
+		port_data |=2;
 	}
-	outb(PortData, DATA);
+	outb(port_data, DATA);
 } 
 
 static int bit_elv_getscl(void *data)
@@ -103,7 +101,7 @@
 		goto fail;
 	}
 
-	PortData = 0;
+	port_data = 0;
 	bit_elv_setsda((void*)base,1);
 	bit_elv_setscl((void*)base,1);
 	return 0;
@@ -129,14 +127,13 @@
 
 static struct i2c_adapter bit_elv_ops = {
 	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_ELV,
 	.algo_data	= &bit_elv_data,
 	.name		= "ELV Parallel port adaptor",
 };
 
 static int __init i2c_bitelv_init(void)
 {
-	printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c ELV parallel port adapter driver\n");
 	if (base=0) {
 		/* probe some values */
 		basefiFAULT_BASE;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                                       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.21, 2003/09/22 13:57:44-07:00, greg@kroah.com

I2C: move i2c-elektor.c driver to drivers/i2c/busses/


 drivers/i2c/i2c-elektor.c        |  286 ---------------------------------------
 drivers/i2c/Kconfig              |   10 -
 drivers/i2c/Makefile             |    1 
 drivers/i2c/busses/Kconfig       |   10 +
 drivers/i2c/busses/Makefile      |    1 
 drivers/i2c/busses/i2c-elektor.c |  286 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 297 insertions(+), 297 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:35 2003
@@ -107,16 +107,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-pcf.
 
-config I2C_ELEKTOR
-	tristate "Elektor ISA card"
-	depends on I2C_ALGOPCF && BROKEN_ON_SMP
-	help
-	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
-	  such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-elektor.
-
 config I2C_KEYWEST
 	tristate "Powermac Keywest I2C interface"
 	depends on I2C && PPC_PMAC
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:35 2003
@@ -7,7 +7,6 @@
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
 obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
-obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
 obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:35 2003
@@ -46,6 +46,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-amd8111.
 
+config I2C_ELEKTOR
+	tristate "Elektor ISA card"
+	depends on I2C_ALGOPCF && BROKEN_ON_SMP
+	help
+	  This supports the PCF8584 ISA bus I2C adapter.  Say Y if you own
+	  such an adapter.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-elektor.
+
 config I2C_ELV
 	tristate "ELV adapter"
 	depends on I2C_ALGOBIT && ISA
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:35 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:35 2003
@@ -6,6 +6,7 @@
 obj-$(CONFIG_I2C_ALI15X3)	+= i2c-ali15x3.o
 obj-$(CONFIG_I2C_AMD756)	+= i2c-amd756.o
 obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
+obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
diff -Nru a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-elektor.c	Mon Sep 22 16:12:35 2003
@@ -0,0 +1,286 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes             */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-97 Simon G. Vogl
+                   1998-99 Hans Berglund
+
+    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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
+   for Alpha Processor Inc. UP-2000(+) boards */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/wait.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-pcf.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "../i2c-pcf8584.h"
+
+#define DEFAULT_BASE 0x330
+
+static int base;
+static int irq;
+static int clock  = 0x1c;
+static int own    = 0x55;
+static int mmapped;
+static int i2c_debug;
+
+/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
+  this module in real supports only one device, due to missing arguments
+  in some functions, called from the algo-pcf module. Sometimes it's
+  need to be rewriten - but for now just remove this for simpler reading */
+
+static wait_queue_head_t pcf_wait;
+static int pcf_pending;
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)	if (i2c_debug>=1) x
+#define DEB2(x) if (i2c_debug>=2) x
+#define DEB3(x) if (i2c_debug>=3) x
+#define DEBE(x)	x	/* error messages 				*/
+
+/* ----- local functions ----------------------------------------------	*/
+
+static void pcf_isa_setbyte(void *data, int ctl, int val)
+{
+	int address = ctl ? (base + 1) : base;
+
+	/* enable irq if any specified for serial operation */
+	if (ctl && irq && (val & I2C_PCF_ESO)) {
+		val |= I2C_PCF_ENI;
+	}
+
+	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+
+	switch (mmapped) {
+	case 0: /* regular I/O */
+		outb(val, address);
+		break;
+	case 2: /* double mapped I/O needed for UP2000 board,
+                   I don't know why this... */
+		writeb(val, address);
+		/* fall */
+	case 1: /* memory mapped I/O */
+		writeb(val, address);
+		break;
+	}
+}
+
+static int pcf_isa_getbyte(void *data, int ctl)
+{
+	int address = ctl ? (base + 1) : base;
+	int val = mmapped ? readb(address) : inb(address);
+
+	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
+
+	return (val);
+}
+
+static int pcf_isa_getown(void *data)
+{
+	return (own);
+}
+
+
+static int pcf_isa_getclock(void *data)
+{
+	return (clock);
+}
+
+static void pcf_isa_waitforpin(void) {
+
+	int timeout = 2;
+
+	if (irq > 0) {
+		cli();
+		if (pcf_pending = 0) {
+			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
+		} else
+			pcf_pending = 0;
+		sti();
+	} else {
+		udelay(100);
+	}
+}
+
+
+static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
+	pcf_pending = 1;
+	wake_up_interruptible(&pcf_wait);
+	return IRQ_HANDLED;
+}
+
+
+static int pcf_isa_init(void)
+{
+	if (!mmapped) {
+		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
+			printk(KERN_ERR
+			       "i2c-elektor.o: requested I/O region (0x%X:2) "
+			       "is in use.\n", base);
+			return -ENODEV;
+		}
+	}
+	if (irq > 0) {
+		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
+			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
+			irq = 0;
+		} else
+			enable_irq(irq);
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_pcf_data pcf_isa_data = {
+	.setpcf	    = pcf_isa_setbyte,
+	.getpcf	    = pcf_isa_getbyte,
+	.getown	    = pcf_isa_getown,
+	.getclock   = pcf_isa_getclock,
+	.waitforpin = pcf_isa_waitforpin,
+	.udelay	    = 10,
+	.mdelay	    = 10,
+	.timeout    = 100,
+};
+
+static struct i2c_adapter pcf_isa_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_P_ELEK,
+	.algo_data	= &pcf_isa_data,
+	.name		= "PCF8584 ISA adapter",
+};
+
+static int __init i2c_pcfisa_init(void) 
+{
+#ifdef __alpha__
+	/* check to see we have memory mapped PCF8584 connected to the 
+	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
+	if (base = 0) {
+		
+		struct pci_dev *cy693_dev +                    pci_find_device(PCI_VENDOR_ID_CONTAQ, 
+		                    PCI_DEVICE_ID_CONTAQ_82C693, NULL);
+
+		if (cy693_dev) {
+			char config;
+			/* yeap, we've found cypress, let's check config */
+			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
+				
+				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+
+				/* UP2000 board has this register set to 0xe1,
+                                   but the most significant bit as seems can be 
+				   reset during the proper initialisation
+                                   sequence if guys from API decides to do that
+                                   (so, we can even enable Tsunami Pchip
+                                   window for the upper 1 Gb) */
+
+				/* so just check for ROMCS at 0xe0000,
+                                   ROMCS enabled for writes
+				   and external XD Bus buffer in use. */
+				if ((config & 0x7f) = 0x61) {
+					/* seems to be UP2000 like board */
+					base = 0xe0000;
+                                        /* I don't know why we need to
+                                           write twice */
+					mmapped = 2;
+                                        /* UP2000 drives ISA with
+					   8.25 MHz (PCI/4) clock
+					   (this can be read from cypress) */
+					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
+					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+				}
+			}
+		}
+	}
+#endif
+
+	/* sanity checks for mmapped I/O */
+	if (mmapped && base < 0xc8000) {
+		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+		return -ENODEV;
+	}
+
+	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+
+	if (base = 0) {
+		base = DEFAULT_BASE;
+	}
+
+	init_waitqueue_head(&pcf_wait);
+	if (pcf_isa_init())
+		return -ENODEV;
+	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
+		goto fail;
+	
+	printk(KERN_ERR "i2c-elektor.o: found device at %#x.\n", base);
+
+	return 0;
+
+ fail:
+	if (irq > 0) {
+		disable_irq(irq);
+		free_irq(irq, 0);
+	}
+
+	if (!mmapped)
+		release_region(base , 2);
+	return -ENODEV;
+}
+
+static void i2c_pcfisa_exit(void)
+{
+	i2c_pcf_del_bus(&pcf_isa_ops);
+
+	if (irq > 0) {
+		disable_irq(irq);
+		free_irq(irq, 0);
+	}
+
+	if (!mmapped)
+		release_region(base , 2);
+}
+
+MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clock, "i");
+MODULE_PARM(own, "i");
+MODULE_PARM(mmapped, "i");
+MODULE_PARM(i2c_debug, "i");
+
+module_init(i2c_pcfisa_init);
+module_exit(i2c_pcfisa_exit);
diff -Nru a/drivers/i2c/i2c-elektor.c b/drivers/i2c/i2c-elektor.c
--- a/drivers/i2c/i2c-elektor.c	Mon Sep 22 16:12:35 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,286 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-elektor.c i2c-hw access for PCF8584 style isa bus adaptes             */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of 
-   for Alpha Processor Inc. UP-2000(+) boards */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/wait.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-pcf.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "i2c-pcf8584.h"
-
-#define DEFAULT_BASE 0x330
-
-static int base;
-static int irq;
-static int clock  = 0x1c;
-static int own    = 0x55;
-static int mmapped;
-static int i2c_debug;
-
-/* vdovikin: removed static struct i2c_pcf_isa gpi; code - 
-  this module in real supports only one device, due to missing arguments
-  in some functions, called from the algo-pcf module. Sometimes it's
-  need to be rewriten - but for now just remove this for simpler reading */
-
-static wait_queue_head_t pcf_wait;
-static int pcf_pending;
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)	if (i2c_debug>=1) x
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x
-#define DEBE(x)	x	/* error messages 				*/
-
-/* ----- local functions ----------------------------------------------	*/
-
-static void pcf_isa_setbyte(void *data, int ctl, int val)
-{
-	int address = ctl ? (base + 1) : base;
-
-	/* enable irq if any specified for serial operation */
-	if (ctl && irq && (val & I2C_PCF_ESO)) {
-		val |= I2C_PCF_ENI;
-	}
-
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
-
-	switch (mmapped) {
-	case 0: /* regular I/O */
-		outb(val, address);
-		break;
-	case 2: /* double mapped I/O needed for UP2000 board,
-                   I don't know why this... */
-		writeb(val, address);
-		/* fall */
-	case 1: /* memory mapped I/O */
-		writeb(val, address);
-		break;
-	}
-}
-
-static int pcf_isa_getbyte(void *data, int ctl)
-{
-	int address = ctl ? (base + 1) : base;
-	int val = mmapped ? readb(address) : inb(address);
-
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
-
-	return (val);
-}
-
-static int pcf_isa_getown(void *data)
-{
-	return (own);
-}
-
-
-static int pcf_isa_getclock(void *data)
-{
-	return (clock);
-}
-
-static void pcf_isa_waitforpin(void) {
-
-	int timeout = 2;
-
-	if (irq > 0) {
-		cli();
-		if (pcf_pending = 0) {
-			interruptible_sleep_on_timeout(&pcf_wait, timeout*HZ );
-		} else
-			pcf_pending = 0;
-		sti();
-	} else {
-		udelay(100);
-	}
-}
-
-
-static irqreturn_t pcf_isa_handler(int this_irq, void *dev_id, struct pt_regs *regs) {
-	pcf_pending = 1;
-	wake_up_interruptible(&pcf_wait);
-	return IRQ_HANDLED;
-}
-
-
-static int pcf_isa_init(void)
-{
-	if (!mmapped) {
-		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
-			printk(KERN_ERR
-			       "i2c-elektor.o: requested I/O region (0x%X:2) "
-			       "is in use.\n", base);
-			return -ENODEV;
-		}
-	}
-	if (irq > 0) {
-		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
-			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
-			irq = 0;
-		} else
-			enable_irq(irq);
-	}
-	return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_pcf_data pcf_isa_data = {
-	.setpcf	    = pcf_isa_setbyte,
-	.getpcf	    = pcf_isa_getbyte,
-	.getown	    = pcf_isa_getown,
-	.getclock   = pcf_isa_getclock,
-	.waitforpin = pcf_isa_waitforpin,
-	.udelay	    = 10,
-	.mdelay	    = 10,
-	.timeout    = 100,
-};
-
-static struct i2c_adapter pcf_isa_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_P_ELEK,
-	.algo_data	= &pcf_isa_data,
-	.name		= "PCF8584 ISA adapter",
-};
-
-static int __init i2c_pcfisa_init(void) 
-{
-#ifdef __alpha__
-	/* check to see we have memory mapped PCF8584 connected to the 
-	Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
-	if (base = 0) {
-		
-		struct pci_dev *cy693_dev -                    pci_find_device(PCI_VENDOR_ID_CONTAQ, 
-		                    PCI_DEVICE_ID_CONTAQ_82C693, NULL);
-
-		if (cy693_dev) {
-			char config;
-			/* yeap, we've found cypress, let's check config */
-			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
-				
-				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
-
-				/* UP2000 board has this register set to 0xe1,
-                                   but the most significant bit as seems can be 
-				   reset during the proper initialisation
-                                   sequence if guys from API decides to do that
-                                   (so, we can even enable Tsunami Pchip
-                                   window for the upper 1 Gb) */
-
-				/* so just check for ROMCS at 0xe0000,
-                                   ROMCS enabled for writes
-				   and external XD Bus buffer in use. */
-				if ((config & 0x7f) = 0x61) {
-					/* seems to be UP2000 like board */
-					base = 0xe0000;
-                                        /* I don't know why we need to
-                                           write twice */
-					mmapped = 2;
-                                        /* UP2000 drives ISA with
-					   8.25 MHz (PCI/4) clock
-					   (this can be read from cypress) */
-					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
-					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
-				}
-			}
-		}
-	}
-#endif
-
-	/* sanity checks for mmapped I/O */
-	if (mmapped && base < 0xc8000) {
-		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
-		return -ENODEV;
-	}
-
-	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-	if (base = 0) {
-		base = DEFAULT_BASE;
-	}
-
-	init_waitqueue_head(&pcf_wait);
-	if (pcf_isa_init())
-		return -ENODEV;
-	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
-		goto fail;
-	
-	printk(KERN_ERR "i2c-elektor.o: found device at %#x.\n", base);
-
-	return 0;
-
- fail:
-	if (irq > 0) {
-		disable_irq(irq);
-		free_irq(irq, 0);
-	}
-
-	if (!mmapped)
-		release_region(base , 2);
-	return -ENODEV;
-}
-
-static void i2c_pcfisa_exit(void)
-{
-	i2c_pcf_del_bus(&pcf_isa_ops);
-
-	if (irq > 0) {
-		disable_irq(irq);
-		free_irq(irq, 0);
-	}
-
-	if (!mmapped)
-		release_region(base , 2);
-}
-
-MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(clock, "i");
-MODULE_PARM(own, "i");
-MODULE_PARM(mmapped, "i");
-MODULE_PARM(i2c_debug, "i");
-
-module_init(i2c_pcfisa_init);
-module_exit(i2c_pcfisa_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                                           ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.23, 2003/09/22 14:21:09-07:00, greg@kroah.com

[PATCH] I2C: move the scx200* drivers to drivers/i2c/busses


 drivers/i2c/scx200_acb.c        |  553 ----------------------------------------
 drivers/i2c/scx200_i2c.c        |  133 ---------
 drivers/i2c/Kconfig             |   38 --
 drivers/i2c/Makefile            |    2 
 drivers/i2c/busses/Kconfig      |   38 ++
 drivers/i2c/busses/Makefile     |    2 
 drivers/i2c/busses/scx200_acb.c |  553 ++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/busses/scx200_i2c.c |  132 +++++++++
 8 files changed, 725 insertions(+), 726 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:15 2003
@@ -48,44 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config SCx200_I2C
-	tristate "NatSemi SCx200 I2C using GPIO pins"
-	depends on SCx200 && I2C_ALGOBIT
-	help
-	  Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
-
-	  If you don't know what to do here, say N.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called scx200_i2c.
-
-config SCx200_I2C_SCL
-	int "GPIO pin used for SCL"
-	depends on SCx200_I2C
-	default "12"
-	help
-	  Enter the GPIO pin number used for the SCL signal.  This value can
-	  also be specified with a module parameter.
-
-config SCx200_I2C_SDA
-	int "GPIO pin used for SDA"
-	depends on SCx200_I2C
-	default "13"
-	help
-	  Enter the GPIO pin number used for the SSA signal.  This value can
-	  also be specified with a module parameter.
-
-config SCx200_ACB
-	tristate "NatSemi SCx200 ACCESS.bus"
-	depends on I2C_ALGOBIT!=n && I2C
-	help
-	  Enable the use of the ACCESS.bus controllers of a SCx200 processor.
-
-	  If you don't know what to do here, say N.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called scx200_acb.
-
 config I2C_ALGOPCF
 	tristate "I2C PCF 8584 interfaces"
 	depends on I2C
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:15 2003
@@ -9,8 +9,6 @@
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
 obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
-obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
-obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
 obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
 obj-$(CONFIG_I2C_SENSOR)	+= i2c-sensor.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:15 2003
@@ -166,6 +166,44 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-savage4.
 
+config SCx200_I2C
+	tristate "NatSemi SCx200 I2C using GPIO pins"
+	depends on SCx200 && I2C_ALGOBIT
+	help
+	  Enable the use of two GPIO pins of a SCx200 processor as an I2C bus.
+
+	  If you don't know what to do here, say N.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_i2c.
+
+config SCx200_I2C_SCL
+	int "GPIO pin used for SCL"
+	depends on SCx200_I2C
+	default "12"
+	help
+	  Enter the GPIO pin number used for the SCL signal.  This value can
+	  also be specified with a module parameter.
+
+config SCx200_I2C_SDA
+	int "GPIO pin used for SDA"
+	depends on SCx200_I2C
+	default "13"
+	help
+	  Enter the GPIO pin number used for the SSA signal.  This value can
+	  also be specified with a module parameter.
+
+config SCx200_ACB
+	tristate "NatSemi SCx200 ACCESS.bus"
+	depends on I2C_ALGOBIT!=n && I2C
+	help
+	  Enable the use of the ACCESS.bus controllers of a SCx200 processor.
+
+	  If you don't know what to do here, say N.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called scx200_acb.
+
 config I2C_SIS5595
 	tristate "SiS 5595"
 	depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:15 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:15 2003
@@ -23,3 +23,5 @@
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
+obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
+obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
diff -Nru a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/scx200_acb.c	Mon Sep 22 16:12:15 2003
@@ -0,0 +1,553 @@
+/*  linux/drivers/i2c/scx200_acb.c 
+
+    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
+
+    National Semiconductor SCx200 ACCESS.bus support
+    
+    Based on i2c-keywest.c which is:
+        Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+        Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+    
+    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/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/smp_lock.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+#include <linux/scx200.h>
+
+#define NAME "scx200_acb"
+
+MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
+MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
+MODULE_LICENSE("GPL");
+
+#define MAX_DEVICES 4
+static int base[MAX_DEVICES] = { 0x840 };
+MODULE_PARM(base, "1-4i");
+MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
+
+#define DEBUG 0
+
+#if DEBUG
+#define DBG(x...) printk(KERN_DEBUG NAME ": " x)
+#else
+#define DBG(x...)
+#endif
+
+/* The hardware supports interrupt driven mode too, but I haven't
+   implemented that. */
+#define POLLED_MODE 1
+#define POLL_TIMEOUT (HZ)
+
+enum scx200_acb_state {
+	state_idle,
+	state_address,
+	state_command,
+	state_repeat_start,
+	state_quick,
+	state_read,
+	state_write,
+};
+
+static const char *scx200_acb_state_name[] = {
+	"idle",
+	"address",
+	"command",
+	"repeat_start",
+	"quick",
+	"read",
+	"write",
+};
+
+/* Physical interface */
+struct scx200_acb_iface
+{
+	struct scx200_acb_iface *next;
+	struct i2c_adapter adapter;
+	unsigned base;
+	struct semaphore sem;
+
+	/* State machine data */
+	enum scx200_acb_state state;
+	int result;
+	u8 address_byte;
+	u8 command;
+	u8 *ptr;
+	char needs_reset;
+	unsigned len;
+};
+
+/* Register Definitions */
+#define ACBSDA		(iface->base + 0)
+#define ACBST		(iface->base + 1)
+#define    ACBST_SDAST		0x40 /* SDA Status */
+#define    ACBST_BER		0x20 
+#define    ACBST_NEGACK		0x10 /* Negative Acknowledge */
+#define    ACBST_STASTR		0x08 /* Stall After Start */
+#define    ACBST_MASTER		0x02
+#define ACBCST		(iface->base + 2)
+#define    ACBCST_BB		0x02
+#define ACBCTL1		(iface->base + 3)
+#define    ACBCTL1_STASTRE	0x80
+#define    ACBCTL1_NMINTE	0x40
+#define	   ACBCTL1_ACK		0x10
+#define	   ACBCTL1_STOP		0x02
+#define	   ACBCTL1_START	0x01
+#define ACBADDR		(iface->base + 4)
+#define ACBCTL2		(iface->base + 5)
+#define    ACBCTL2_ENABLE	0x01
+
+/************************************************************************/
+
+static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
+{
+	const char *errmsg;
+
+	DBG("state %s, status = 0x%02x\n", 
+	    scx200_acb_state_name[iface->state], status);
+
+	if (status & ACBST_BER) {
+		errmsg = "bus error";
+		goto error;
+	}
+	if (!(status & ACBST_MASTER)) {
+		errmsg = "not master";
+		goto error;
+	}
+	if (status & ACBST_NEGACK)
+		goto negack;
+
+	switch (iface->state) {
+	case state_idle:
+		dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
+		break;
+
+	case state_address:
+		/* Do a pointer write first */
+		outb(iface->address_byte & ~1, ACBSDA);
+
+		iface->state = state_command;
+		break;
+
+	case state_command:
+		outb(iface->command, ACBSDA);
+
+		if (iface->address_byte & 1)
+			iface->state = state_repeat_start;
+		else
+			iface->state = state_write;
+		break;
+
+	case state_repeat_start:
+		outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
+		/* fallthrough */
+		
+	case state_quick:
+		if (iface->address_byte & 1) {
+			if (iface->len = 1) 
+				outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
+			else
+				outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
+			outb(iface->address_byte, ACBSDA);
+
+			iface->state = state_read;
+		} else {
+			outb(iface->address_byte, ACBSDA);
+
+			iface->state = state_write;
+		}
+		break;
+
+	case state_read:
+		/* Set ACK if receiving the last byte */
+		if (iface->len = 1)
+			outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
+		else
+			outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
+
+		*iface->ptr++ = inb(ACBSDA);
+		--iface->len;
+
+		if (iface->len = 0) {
+			iface->result = 0;
+			iface->state = state_idle;
+			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+		}
+
+		break;
+
+	case state_write:
+		if (iface->len = 0) {
+			iface->result = 0;
+			iface->state = state_idle;
+			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+			break;
+		}
+		
+		outb(*iface->ptr++, ACBSDA);
+		--iface->len;
+		
+		break;
+	}
+
+	return;
+
+ negack:
+	DBG("negative acknowledge in state %s\n", 
+	    scx200_acb_state_name[iface->state]);
+
+	iface->state = state_idle;
+	iface->result = -ENXIO;
+
+	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+	outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
+	return;
+
+ error:
+	dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
+		scx200_acb_state_name[iface->state]);
+
+	iface->state = state_idle;
+	iface->result = -EIO;
+	iface->needs_reset = 1;
+}
+
+static void scx200_acb_timeout(struct scx200_acb_iface *iface) 
+{
+	dev_err(&iface->adapter.dev, "timeout in state %s\n",
+		scx200_acb_state_name[iface->state]);
+
+	iface->state = state_idle;
+	iface->result = -EIO;
+	iface->needs_reset = 1;
+}
+
+#ifdef POLLED_MODE
+static void scx200_acb_poll(struct scx200_acb_iface *iface)
+{
+	u8 status = 0;
+	unsigned long timeout;
+
+	timeout = jiffies + POLL_TIMEOUT;
+	while (time_before(jiffies, timeout)) {
+		status = inb(ACBST);
+		if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
+			scx200_acb_machine(iface, status);
+			return;
+		}
+		schedule_timeout(HZ/100+1);
+	}
+
+	scx200_acb_timeout(iface);
+}
+#endif /* POLLED_MODE */
+
+static void scx200_acb_reset(struct scx200_acb_iface *iface)
+{
+	/* Disable the ACCESS.bus device and Configure the SCL
+           frequency: 16 clock cycles */
+	outb(0x70, ACBCTL2);
+	/* Polling mode */
+	outb(0, ACBCTL1);
+	/* Disable slave address */
+	outb(0, ACBADDR);
+	/* Enable the ACCESS.bus device */
+	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
+	/* Free STALL after START */
+	outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
+	/* Send a STOP */
+	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
+	/* Clear BER, NEGACK and STASTR bits */
+	outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
+	/* Clear BB bit */
+	outb(inb(ACBCST) | ACBCST_BB, ACBCST);
+}
+
+static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
+				u16 address, unsigned short flags,	
+				char rw, u8 command, int size, 
+				union i2c_smbus_data *data)
+{
+	struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
+	int len;
+	u8 *buffer;
+	u16 cur_word;
+	int rc;
+
+	switch (size) {
+	case I2C_SMBUS_QUICK:
+	    	len = 0;
+	    	buffer = NULL;
+	    	break;
+	case I2C_SMBUS_BYTE:
+		if (rw = I2C_SMBUS_READ) {
+			len = 1;
+			buffer = &data->byte;
+		} else {
+			len = 1;
+			buffer = &command;
+		}
+	    	break;
+	case I2C_SMBUS_BYTE_DATA:
+	    	len = 1;
+	    	buffer = &data->byte;
+	    	break;
+	case I2C_SMBUS_WORD_DATA:
+		len = 2;
+	    	cur_word = cpu_to_le16(data->word);
+	    	buffer = (u8 *)&cur_word;
+		break;
+	case I2C_SMBUS_BLOCK_DATA:
+	    	len = data->block[0];
+	    	buffer = &data->block[1];
+		break;
+	default:
+	    	return -EINVAL;
+	}
+
+	DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
+	    size, address, command, len, rw = I2C_SMBUS_READ);
+
+	if (!len && rw = I2C_SMBUS_READ) {
+		dev_warn(&adapter->dev, "zero length read\n");
+		return -EINVAL;
+	}
+
+	if (len && !buffer) {
+		dev_warn(&adapter->dev, "nonzero length but no buffer\n");
+		return -EFAULT;
+	}
+
+	down(&iface->sem);
+
+	iface->address_byte = address<<1;
+	if (rw = I2C_SMBUS_READ)
+		iface->address_byte |= 1;
+	iface->command = command;
+	iface->ptr = buffer;
+	iface->len = len;
+	iface->result = -EINVAL;
+	iface->needs_reset = 0;
+
+	outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
+
+	if (size = I2C_SMBUS_QUICK || size = I2C_SMBUS_BYTE)
+		iface->state = state_quick;
+	else
+		iface->state = state_address;
+
+#ifdef POLLED_MODE
+	while (iface->state != state_idle)
+		scx200_acb_poll(iface);
+#else /* POLLED_MODE */
+#error Interrupt driven mode not implemented
+#endif /* POLLED_MODE */	
+
+	if (iface->needs_reset)
+		scx200_acb_reset(iface);
+
+	rc = iface->result;
+
+	up(&iface->sem);
+
+	if (rc = 0 && size = I2C_SMBUS_WORD_DATA && rw = I2C_SMBUS_READ)
+	    	data->word = le16_to_cpu(cur_word);
+
+#if DEBUG
+	printk(KERN_DEBUG NAME ": transfer done, result: %d", rc);
+	if (buffer) {
+		int i;
+		printk(" data:");
+		for (i = 0; i < len; ++i)
+			printk(" %02x", buffer[i]);
+	}
+	printk("\n");
+#endif
+
+	return rc;
+}
+
+static u32 scx200_acb_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	       I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+/* For now, we only handle combined mode (smbus) */
+static struct i2c_algorithm scx200_acb_algorithm = {
+	.name		= "NatSemi SCx200 ACCESS.bus",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= scx200_acb_smbus_xfer,
+	.functionality	= scx200_acb_func,
+};
+
+struct scx200_acb_iface *scx200_acb_list;
+
+int scx200_acb_probe(struct scx200_acb_iface *iface)
+{
+	u8 val;
+
+	/* Disable the ACCESS.bus device and Configure the SCL
+           frequency: 16 clock cycles */
+	outb(0x70, ACBCTL2);
+
+	if (inb(ACBCTL2) != 0x70) {
+		DBG("ACBCTL2 readback failed\n");
+		return -ENXIO;
+	}
+
+	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
+
+	val = inb(ACBCTL1);
+	if (val) {
+		DBG("disabled, but ACBCTL1=0x%02x\n", val);
+		return -ENXIO;
+	}
+
+	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
+
+	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
+
+	val = inb(ACBCTL1);
+	if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
+		DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int  __init scx200_acb_create(int base, int index)
+{
+	struct scx200_acb_iface *iface;
+	struct i2c_adapter *adapter;
+	int rc = 0;
+	char description[64];
+
+	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
+	if (!iface) {
+		printk(KERN_ERR NAME ": can't allocate memory\n");
+		rc = -ENOMEM;
+		goto errout;
+	}
+
+	memset(iface, 0, sizeof(*iface));
+	adapter = &iface->adapter;
+	i2c_set_adapdata(adapter, iface);
+	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
+	adapter->owner = THIS_MODULE;
+	adapter->id = I2C_ALGO_SMBUS;
+	adapter->algo = &scx200_acb_algorithm;
+
+	init_MUTEX(&iface->sem);
+
+	snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
+	if (request_region(base, 8, description) = 0) {
+		dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
+			base, base + 8-1);
+		rc = -EBUSY;
+		goto errout;
+	}
+	iface->base = base;
+
+	rc = scx200_acb_probe(iface);
+	if (rc) {
+		dev_warn(&adapter->dev, "probe failed\n");
+		goto errout;
+	}
+
+	scx200_acb_reset(iface);
+
+	if (i2c_add_adapter(adapter) < 0) {
+		dev_err(&adapter->dev, "failed to register\n");
+		rc = -ENODEV;
+		goto errout;
+	}
+
+	lock_kernel();
+	iface->next = scx200_acb_list;
+	scx200_acb_list = iface;
+	unlock_kernel();
+
+	return 0;
+
+ errout:
+	if (iface) {
+		if (iface->base)
+			release_region(iface->base, 8);
+		kfree(iface);
+	}
+	return rc;
+}
+
+static int __init scx200_acb_init(void)
+{
+	int i;
+	int rc;
+
+	printk(KERN_DEBUG NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
+
+	/* Verify that this really is a SCx200 processor */
+	if (pci_find_device(PCI_VENDOR_ID_NS,
+			    PCI_DEVICE_ID_NS_SCx200_BRIDGE,
+			    NULL) = NULL)
+		return -ENODEV;
+
+	rc = -ENXIO;
+	for (i = 0; i < MAX_DEVICES; ++i) {
+		if (base[i] > 0)
+			rc = scx200_acb_create(base[i], i);
+	}
+	if (scx200_acb_list)
+		return 0;
+	return rc;
+}
+
+static void __exit scx200_acb_cleanup(void)
+{
+	struct scx200_acb_iface *iface;
+	lock_kernel();
+	while ((iface = scx200_acb_list) != NULL) {
+		scx200_acb_list = iface->next;
+		unlock_kernel();
+
+		i2c_del_adapter(&iface->adapter);
+		release_region(iface->base, 8);
+		kfree(iface);
+		lock_kernel();
+	}
+	unlock_kernel();
+}
+
+module_init(scx200_acb_init);
+module_exit(scx200_acb_cleanup);
+
+/*
+    Local variables:
+        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
+        c-basic-offset: 8
+    End:
+*/
+
diff -Nru a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/scx200_i2c.c	Mon Sep 22 16:12:15 2003
@@ -0,0 +1,132 @@
+/* linux/drivers/i2c/scx200_i2c.c 
+
+   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
+
+   National Semiconductor SCx200 I2C bus on GPIO pins
+
+   Based on i2c-velleman.c Copyright (C) 1995-96, 2000 Simon G. 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.		     
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/io.h>
+
+#include <linux/scx200_gpio.h>
+
+#define NAME "scx200_i2c"
+
+MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
+MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(scl, "i");
+MODULE_PARM_DESC(scl, "GPIO line for SCL");
+MODULE_PARM(sda, "i");
+MODULE_PARM_DESC(sda, "GPIO line for SDA");
+
+static int scl = CONFIG_SCx200_I2C_SCL;
+static int sda = CONFIG_SCx200_I2C_SDA;
+
+static void scx200_i2c_setscl(void *data, int state)
+{
+	scx200_gpio_set(scl, state);
+}
+
+static void scx200_i2c_setsda(void *data, int state)
+{
+	scx200_gpio_set(sda, state);
+} 
+
+static int scx200_i2c_getscl(void *data)
+{
+	return scx200_gpio_get(scl);
+}
+
+static int scx200_i2c_getsda(void *data)
+{
+	return scx200_gpio_get(sda);
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+
+static struct i2c_algo_bit_data scx200_i2c_data = {
+	NULL,
+	scx200_i2c_setsda,
+	scx200_i2c_setscl,
+	scx200_i2c_getsda,
+	scx200_i2c_getscl,
+	10, 10, 100,		/* waits, timeout */
+};
+
+static struct i2c_adapter scx200_i2c_ops = {
+	.owner		   = THIS_MODULE,
+	.algo_data	   = &scx200_i2c_data,
+	.name	= "NatSemi SCx200 I2C",
+};
+
+int scx200_i2c_init(void)
+{
+	printk(KERN_DEBUG NAME ": NatSemi SCx200 I2C Driver\n");
+
+	if (!scx200_gpio_present()) {
+		printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
+		return -ENODEV;
+	}
+
+	printk(KERN_DEBUG NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", 
+	       scl, sda);
+
+	if (scl = -1 || sda = -1 || scl = sda) {
+		printk(KERN_ERR NAME ": scl and sda must be specified\n");
+		return -EINVAL;
+	}
+
+	/* Configure GPIOs as open collector outputs */
+	scx200_gpio_configure(scl, ~2, 5);
+	scx200_gpio_configure(sda, ~2, 5);
+
+	if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
+		printk(KERN_ERR NAME ": adapter %s registration failed\n", 
+		       scx200_i2c_ops.name);
+		return -ENODEV;
+	}
+	
+	return 0;
+}
+
+void scx200_i2c_cleanup(void)
+{
+	i2c_bit_del_bus(&scx200_i2c_ops);
+}
+
+module_init(scx200_i2c_init);
+module_exit(scx200_i2c_cleanup);
+
+/*
+    Local variables:
+        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
+        c-basic-offset: 8
+    End:
+*/
diff -Nru a/drivers/i2c/scx200_acb.c b/drivers/i2c/scx200_acb.c
--- a/drivers/i2c/scx200_acb.c	Mon Sep 22 16:12:15 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,553 +0,0 @@
-/*  linux/drivers/i2c/scx200_acb.c 
-
-    Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
-    National Semiconductor SCx200 ACCESS.bus support
-    
-    Based on i2c-keywest.c which is:
-        Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
-        Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-    
-    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/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/smp_lock.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-
-#include <linux/scx200.h>
-
-#define NAME "scx200_acb"
-
-MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
-MODULE_LICENSE("GPL");
-
-#define MAX_DEVICES 4
-static int base[MAX_DEVICES] = { 0x840 };
-MODULE_PARM(base, "1-4i");
-MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
-
-#define DEBUG 0
-
-#if DEBUG
-#define DBG(x...) printk(KERN_DEBUG NAME ": " x)
-#else
-#define DBG(x...)
-#endif
-
-/* The hardware supports interrupt driven mode too, but I haven't
-   implemented that. */
-#define POLLED_MODE 1
-#define POLL_TIMEOUT (HZ)
-
-enum scx200_acb_state {
-	state_idle,
-	state_address,
-	state_command,
-	state_repeat_start,
-	state_quick,
-	state_read,
-	state_write,
-};
-
-static const char *scx200_acb_state_name[] = {
-	"idle",
-	"address",
-	"command",
-	"repeat_start",
-	"quick",
-	"read",
-	"write",
-};
-
-/* Physical interface */
-struct scx200_acb_iface
-{
-	struct scx200_acb_iface *next;
-	struct i2c_adapter adapter;
-	unsigned base;
-	struct semaphore sem;
-
-	/* State machine data */
-	enum scx200_acb_state state;
-	int result;
-	u8 address_byte;
-	u8 command;
-	u8 *ptr;
-	char needs_reset;
-	unsigned len;
-};
-
-/* Register Definitions */
-#define ACBSDA		(iface->base + 0)
-#define ACBST		(iface->base + 1)
-#define    ACBST_SDAST		0x40 /* SDA Status */
-#define    ACBST_BER		0x20 
-#define    ACBST_NEGACK		0x10 /* Negative Acknowledge */
-#define    ACBST_STASTR		0x08 /* Stall After Start */
-#define    ACBST_MASTER		0x02
-#define ACBCST		(iface->base + 2)
-#define    ACBCST_BB		0x02
-#define ACBCTL1		(iface->base + 3)
-#define    ACBCTL1_STASTRE	0x80
-#define    ACBCTL1_NMINTE	0x40
-#define	   ACBCTL1_ACK		0x10
-#define	   ACBCTL1_STOP		0x02
-#define	   ACBCTL1_START	0x01
-#define ACBADDR		(iface->base + 4)
-#define ACBCTL2		(iface->base + 5)
-#define    ACBCTL2_ENABLE	0x01
-
-/************************************************************************/
-
-static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
-{
-	const char *errmsg;
-
-	DBG("state %s, status = 0x%02x\n", 
-	    scx200_acb_state_name[iface->state], status);
-
-	if (status & ACBST_BER) {
-		errmsg = "bus error";
-		goto error;
-	}
-	if (!(status & ACBST_MASTER)) {
-		errmsg = "not master";
-		goto error;
-	}
-	if (status & ACBST_NEGACK)
-		goto negack;
-
-	switch (iface->state) {
-	case state_idle:
-		dev_warn(&iface->adapter.dev, "interrupt in idle state\n");
-		break;
-
-	case state_address:
-		/* Do a pointer write first */
-		outb(iface->address_byte & ~1, ACBSDA);
-
-		iface->state = state_command;
-		break;
-
-	case state_command:
-		outb(iface->command, ACBSDA);
-
-		if (iface->address_byte & 1)
-			iface->state = state_repeat_start;
-		else
-			iface->state = state_write;
-		break;
-
-	case state_repeat_start:
-		outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
-		/* fallthrough */
-		
-	case state_quick:
-		if (iface->address_byte & 1) {
-			if (iface->len = 1) 
-				outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
-			else
-				outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
-			outb(iface->address_byte, ACBSDA);
-
-			iface->state = state_read;
-		} else {
-			outb(iface->address_byte, ACBSDA);
-
-			iface->state = state_write;
-		}
-		break;
-
-	case state_read:
-		/* Set ACK if receiving the last byte */
-		if (iface->len = 1)
-			outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
-		else
-			outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
-
-		*iface->ptr++ = inb(ACBSDA);
-		--iface->len;
-
-		if (iface->len = 0) {
-			iface->result = 0;
-			iface->state = state_idle;
-			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-		}
-
-		break;
-
-	case state_write:
-		if (iface->len = 0) {
-			iface->result = 0;
-			iface->state = state_idle;
-			outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-			break;
-		}
-		
-		outb(*iface->ptr++, ACBSDA);
-		--iface->len;
-		
-		break;
-	}
-
-	return;
-
- negack:
-	DBG("negative acknowledge in state %s\n", 
-	    scx200_acb_state_name[iface->state]);
-
-	iface->state = state_idle;
-	iface->result = -ENXIO;
-
-	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-	outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
-	return;
-
- error:
-	dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
-		scx200_acb_state_name[iface->state]);
-
-	iface->state = state_idle;
-	iface->result = -EIO;
-	iface->needs_reset = 1;
-}
-
-static void scx200_acb_timeout(struct scx200_acb_iface *iface) 
-{
-	dev_err(&iface->adapter.dev, "timeout in state %s\n",
-		scx200_acb_state_name[iface->state]);
-
-	iface->state = state_idle;
-	iface->result = -EIO;
-	iface->needs_reset = 1;
-}
-
-#ifdef POLLED_MODE
-static void scx200_acb_poll(struct scx200_acb_iface *iface)
-{
-	u8 status = 0;
-	unsigned long timeout;
-
-	timeout = jiffies + POLL_TIMEOUT;
-	while (time_before(jiffies, timeout)) {
-		status = inb(ACBST);
-		if ((status & (ACBST_SDAST|ACBST_BER|ACBST_NEGACK)) != 0) {
-			scx200_acb_machine(iface, status);
-			return;
-		}
-		schedule_timeout(HZ/100+1);
-	}
-
-	scx200_acb_timeout(iface);
-}
-#endif /* POLLED_MODE */
-
-static void scx200_acb_reset(struct scx200_acb_iface *iface)
-{
-	/* Disable the ACCESS.bus device and Configure the SCL
-           frequency: 16 clock cycles */
-	outb(0x70, ACBCTL2);
-	/* Polling mode */
-	outb(0, ACBCTL1);
-	/* Disable slave address */
-	outb(0, ACBADDR);
-	/* Enable the ACCESS.bus device */
-	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
-	/* Free STALL after START */
-	outb(inb(ACBCTL1) & ~(ACBCTL1_STASTRE | ACBCTL1_NMINTE), ACBCTL1);
-	/* Send a STOP */
-	outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
-	/* Clear BER, NEGACK and STASTR bits */
-	outb(ACBST_BER | ACBST_NEGACK | ACBST_STASTR, ACBST);
-	/* Clear BB bit */
-	outb(inb(ACBCST) | ACBCST_BB, ACBCST);
-}
-
-static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
-				u16 address, unsigned short flags,	
-				char rw, u8 command, int size, 
-				union i2c_smbus_data *data)
-{
-	struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
-	int len;
-	u8 *buffer;
-	u16 cur_word;
-	int rc;
-
-	switch (size) {
-	case I2C_SMBUS_QUICK:
-	    	len = 0;
-	    	buffer = NULL;
-	    	break;
-	case I2C_SMBUS_BYTE:
-		if (rw = I2C_SMBUS_READ) {
-			len = 1;
-			buffer = &data->byte;
-		} else {
-			len = 1;
-			buffer = &command;
-		}
-	    	break;
-	case I2C_SMBUS_BYTE_DATA:
-	    	len = 1;
-	    	buffer = &data->byte;
-	    	break;
-	case I2C_SMBUS_WORD_DATA:
-		len = 2;
-	    	cur_word = cpu_to_le16(data->word);
-	    	buffer = (u8 *)&cur_word;
-		break;
-	case I2C_SMBUS_BLOCK_DATA:
-	    	len = data->block[0];
-	    	buffer = &data->block[1];
-		break;
-	default:
-	    	return -EINVAL;
-	}
-
-	DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
-	    size, address, command, len, rw = I2C_SMBUS_READ);
-
-	if (!len && rw = I2C_SMBUS_READ) {
-		dev_warn(&adapter->dev, "zero length read\n");
-		return -EINVAL;
-	}
-
-	if (len && !buffer) {
-		dev_warn(&adapter->dev, "nonzero length but no buffer\n");
-		return -EFAULT;
-	}
-
-	down(&iface->sem);
-
-	iface->address_byte = address<<1;
-	if (rw = I2C_SMBUS_READ)
-		iface->address_byte |= 1;
-	iface->command = command;
-	iface->ptr = buffer;
-	iface->len = len;
-	iface->result = -EINVAL;
-	iface->needs_reset = 0;
-
-	outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
-
-	if (size = I2C_SMBUS_QUICK || size = I2C_SMBUS_BYTE)
-		iface->state = state_quick;
-	else
-		iface->state = state_address;
-
-#ifdef POLLED_MODE
-	while (iface->state != state_idle)
-		scx200_acb_poll(iface);
-#else /* POLLED_MODE */
-#error Interrupt driven mode not implemented
-#endif /* POLLED_MODE */	
-
-	if (iface->needs_reset)
-		scx200_acb_reset(iface);
-
-	rc = iface->result;
-
-	up(&iface->sem);
-
-	if (rc = 0 && size = I2C_SMBUS_WORD_DATA && rw = I2C_SMBUS_READ)
-	    	data->word = le16_to_cpu(cur_word);
-
-#if DEBUG
-	printk(KERN_DEBUG NAME ": transfer done, result: %d", rc);
-	if (buffer) {
-		int i;
-		printk(" data:");
-		for (i = 0; i < len; ++i)
-			printk(" %02x", buffer[i]);
-	}
-	printk("\n");
-#endif
-
-	return rc;
-}
-
-static u32 scx200_acb_func(struct i2c_adapter *adapter)
-{
-	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-	       I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-/* For now, we only handle combined mode (smbus) */
-static struct i2c_algorithm scx200_acb_algorithm = {
-	.name		= "NatSemi SCx200 ACCESS.bus",
-	.id		= I2C_ALGO_SMBUS,
-	.smbus_xfer	= scx200_acb_smbus_xfer,
-	.functionality	= scx200_acb_func,
-};
-
-struct scx200_acb_iface *scx200_acb_list;
-
-int scx200_acb_probe(struct scx200_acb_iface *iface)
-{
-	u8 val;
-
-	/* Disable the ACCESS.bus device and Configure the SCL
-           frequency: 16 clock cycles */
-	outb(0x70, ACBCTL2);
-
-	if (inb(ACBCTL2) != 0x70) {
-		DBG("ACBCTL2 readback failed\n");
-		return -ENXIO;
-	}
-
-	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
-
-	val = inb(ACBCTL1);
-	if (val) {
-		DBG("disabled, but ACBCTL1=0x%02x\n", val);
-		return -ENXIO;
-	}
-
-	outb(inb(ACBCTL2) | ACBCTL2_ENABLE, ACBCTL2);
-
-	outb(inb(ACBCTL1) | ACBCTL1_NMINTE, ACBCTL1);
-
-	val = inb(ACBCTL1);
-	if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
-		DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-static int  __init scx200_acb_create(int base, int index)
-{
-	struct scx200_acb_iface *iface;
-	struct i2c_adapter *adapter;
-	int rc = 0;
-	char description[64];
-
-	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
-	if (!iface) {
-		printk(KERN_ERR NAME ": can't allocate memory\n");
-		rc = -ENOMEM;
-		goto errout;
-	}
-
-	memset(iface, 0, sizeof(*iface));
-	adapter = &iface->adapter;
-	i2c_set_adapdata(adapter, iface);
-	snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
-	adapter->owner = THIS_MODULE;
-	adapter->id = I2C_ALGO_SMBUS;
-	adapter->algo = &scx200_acb_algorithm;
-
-	init_MUTEX(&iface->sem);
-
-	snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
-	if (request_region(base, 8, description) = 0) {
-		dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
-			base, base + 8-1);
-		rc = -EBUSY;
-		goto errout;
-	}
-	iface->base = base;
-
-	rc = scx200_acb_probe(iface);
-	if (rc) {
-		dev_warn(&adapter->dev, "probe failed\n");
-		goto errout;
-	}
-
-	scx200_acb_reset(iface);
-
-	if (i2c_add_adapter(adapter) < 0) {
-		dev_err(&adapter->dev, "failed to register\n");
-		rc = -ENODEV;
-		goto errout;
-	}
-
-	lock_kernel();
-	iface->next = scx200_acb_list;
-	scx200_acb_list = iface;
-	unlock_kernel();
-
-	return 0;
-
- errout:
-	if (iface) {
-		if (iface->base)
-			release_region(iface->base, 8);
-		kfree(iface);
-	}
-	return rc;
-}
-
-static int __init scx200_acb_init(void)
-{
-	int i;
-	int rc;
-
-	printk(KERN_DEBUG NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
-
-	/* Verify that this really is a SCx200 processor */
-	if (pci_find_device(PCI_VENDOR_ID_NS,
-			    PCI_DEVICE_ID_NS_SCx200_BRIDGE,
-			    NULL) = NULL)
-		return -ENODEV;
-
-	rc = -ENXIO;
-	for (i = 0; i < MAX_DEVICES; ++i) {
-		if (base[i] > 0)
-			rc = scx200_acb_create(base[i], i);
-	}
-	if (scx200_acb_list)
-		return 0;
-	return rc;
-}
-
-static void __exit scx200_acb_cleanup(void)
-{
-	struct scx200_acb_iface *iface;
-	lock_kernel();
-	while ((iface = scx200_acb_list) != NULL) {
-		scx200_acb_list = iface->next;
-		unlock_kernel();
-
-		i2c_del_adapter(&iface->adapter);
-		release_region(iface->base, 8);
-		kfree(iface);
-		lock_kernel();
-	}
-	unlock_kernel();
-}
-
-module_init(scx200_acb_init);
-module_exit(scx200_acb_cleanup);
-
-/*
-    Local variables:
-        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
-        c-basic-offset: 8
-    End:
-*/
-
diff -Nru a/drivers/i2c/scx200_i2c.c b/drivers/i2c/scx200_i2c.c
--- a/drivers/i2c/scx200_i2c.c	Mon Sep 22 16:12:15 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,133 +0,0 @@
-/* linux/drivers/i2c/scx200_i2c.c 
-
-   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
-   National Semiconductor SCx200 I2C bus on GPIO pins
-
-   Based on i2c-velleman.c Copyright (C) 1995-96, 2000 Simon G. 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.		     
-*/
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-#include <linux/scx200_gpio.h>
-
-#define NAME "scx200_i2c"
-
-MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
-MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(scl, "i");
-MODULE_PARM_DESC(scl, "GPIO line for SCL");
-MODULE_PARM(sda, "i");
-MODULE_PARM_DESC(sda, "GPIO line for SDA");
-
-static int scl = CONFIG_SCx200_I2C_SCL;
-static int sda = CONFIG_SCx200_I2C_SDA;
-
-static void scx200_i2c_setscl(void *data, int state)
-{
-	scx200_gpio_set(scl, state);
-}
-
-static void scx200_i2c_setsda(void *data, int state)
-{
-	scx200_gpio_set(sda, state);
-} 
-
-static int scx200_i2c_getscl(void *data)
-{
-	return scx200_gpio_get(scl);
-}
-
-static int scx200_i2c_getsda(void *data)
-{
-	return scx200_gpio_get(sda);
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-
-static struct i2c_algo_bit_data scx200_i2c_data = {
-	NULL,
-	scx200_i2c_setsda,
-	scx200_i2c_setscl,
-	scx200_i2c_getsda,
-	scx200_i2c_getscl,
-	10, 10, 100,		/* waits, timeout */
-};
-
-static struct i2c_adapter scx200_i2c_ops = {
-	.owner		   = THIS_MODULE,
-	.id		   = I2C_HW_B_VELLE,
-	.algo_data	   = &scx200_i2c_data,
-	.name	= "NatSemi SCx200 I2C",
-};
-
-int scx200_i2c_init(void)
-{
-	printk(KERN_DEBUG NAME ": NatSemi SCx200 I2C Driver\n");
-
-	if (!scx200_gpio_present()) {
-		printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
-		return -ENODEV;
-	}
-
-	printk(KERN_DEBUG NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", 
-	       scl, sda);
-
-	if (scl = -1 || sda = -1 || scl = sda) {
-		printk(KERN_ERR NAME ": scl and sda must be specified\n");
-		return -EINVAL;
-	}
-
-	/* Configure GPIOs as open collector outputs */
-	scx200_gpio_configure(scl, ~2, 5);
-	scx200_gpio_configure(sda, ~2, 5);
-
-	if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
-		printk(KERN_ERR NAME ": adapter %s registration failed\n", 
-		       scx200_i2c_ops.name);
-		return -ENODEV;
-	}
-	
-	return 0;
-}
-
-void scx200_i2c_cleanup(void)
-{
-	i2c_bit_del_bus(&scx200_i2c_ops);
-}
-
-module_init(scx200_i2c_init);
-module_exit(scx200_i2c_cleanup);
-
-/*
-    Local variables:
-        compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
-        c-basic-offset: 8
-    End:
-*/


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                                                         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.22, 2003/09/22 14:09:17-07:00, greg@kroah.com

[PATCH] I2C: move i2c-velleman driver to drivers/i2c/busses


 drivers/i2c/i2c-velleman.c        |  161 --------------------------------------
 drivers/i2c/Kconfig               |   10 --
 drivers/i2c/Makefile              |    1 
 drivers/i2c/busses/Kconfig        |   10 ++
 drivers/i2c/busses/Makefile       |    1 
 drivers/i2c/busses/i2c-velleman.c |  160 +++++++++++++++++++++++++++++++++++++
 6 files changed, 171 insertions(+), 172 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:26 2003
@@ -48,16 +48,6 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-bit.
 
-config I2C_VELLEMAN
-	tristate "Velleman K9000 adapter"
-	depends on I2C_ALGOBIT && ISA
-	help
-	  This supports the Velleman K9000 parallel-port I2C adapter.  Say Y
-	  if you own such an adapter.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-velleman.
-
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins"
 	depends on SCx200 && I2C_ALGOBIT
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:26 2003
@@ -5,7 +5,6 @@
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
-obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
 obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:26 2003
@@ -203,6 +203,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-sis96x.
 
+config I2C_VELLEMAN
+	tristate "Velleman K9000 adapter"
+	depends on I2C_ALGOBIT && ISA
+	help
+	  This supports the Velleman K9000 parallel-port I2C adapter.  Say Y
+	  if you own such an adapter.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-velleman.
+
 config I2C_VIA
 	tristate "VIA 82C58B"
 	depends on I2C_ALGOBIT && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:26 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:26 2003
@@ -19,6 +19,7 @@
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
 obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
+obj-$(CONFIG_I2C_VELLEMAN)	+= i2c-velleman.o
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
diff -Nru a/drivers/i2c/busses/i2c-velleman.c b/drivers/i2c/busses/i2c-velleman.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-velleman.c	Mon Sep 22 16:12:26 2003
@@ -0,0 +1,160 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters		     */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 1995-96, 2000 Simon G. 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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* $Id: i2c-velleman.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/io.h>
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)		/* should be reasonable open, close &c. 	*/
+#define DEB2(x) 	/* low level debugging - very slow 		*/
+#define DEBE(x)	x	/* error messages 				*/
+
+					/* Pin Port  Inverted	name	*/
+#define I2C_SDA		0x02		/*  ctrl bit 1 	(inv)	*/
+#define I2C_SCL		0x08		/*  ctrl bit 3 	(inv)	*/
+
+#define I2C_SDAIN	0x10		/* stat bit 4		*/
+#define I2C_SCLIN	0x08		/* ctrl bit 3 (inv)(reads own output)*/
+
+#define I2C_DMASK	0xfd
+#define I2C_CMASK	0xf7
+
+
+/* --- Convenience defines for the parallel port:			*/
+#define BASE	(unsigned int)(data)
+#define DATA	BASE			/* Centronics data port		*/
+#define STAT	(BASE+1)		/* Centronics status port	*/
+#define CTRL	(BASE+2)		/* Centronics control port	*/
+
+#define DEFAULT_BASE 0x378
+static int base=0;
+
+/* ----- local functions --------------------------------------------------- */
+
+static void bit_velle_setscl(void *data, int state)
+{
+	if (state) {
+		outb(inb(CTRL) & I2C_CMASK,   CTRL);
+	} else {
+		outb(inb(CTRL) | I2C_SCL, CTRL);
+	}
+	
+}
+
+static void bit_velle_setsda(void *data, int state)
+{
+	if (state) {
+		outb(inb(CTRL) & I2C_DMASK , CTRL);
+	} else {
+		outb(inb(CTRL) | I2C_SDA, CTRL);
+	}
+	
+} 
+
+static int bit_velle_getscl(void *data)
+{
+	return ( 0 = ( (inb(CTRL)) & I2C_SCLIN ) );
+}
+
+static int bit_velle_getsda(void *data)
+{
+	return ( 0 != ( (inb(STAT)) & I2C_SDAIN ) );
+}
+
+static int bit_velle_init(void)
+{
+	if (!request_region(base, (base = 0x3bc) ? 3 : 8, 
+			"i2c (Vellemann adapter)"))
+		return -ENODEV;
+
+	bit_velle_setsda((void*)base,1);
+	bit_velle_setscl((void*)base,1);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+
+static struct i2c_algo_bit_data bit_velle_data = {
+	.setsda		= bit_velle_setsda,
+	.setscl		= bit_velle_setscl,
+	.getsda		= bit_velle_getsda,
+	.getscl		= bit_velle_getscl,
+	.udelay		= 10,
+	.mdelay		= 10,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter bit_velle_ops = {
+	.owner		= THIS_MODULE,
+	.algo_data	= &bit_velle_data,
+	.name		= "Velleman K8000",
+};
+
+static int __init i2c_bitvelle_init(void)
+{
+	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	if (base=0) {
+		/* probe some values */
+		basefiFAULT_BASE;
+		bit_velle_data.data=(void*)DEFAULT_BASE;
+		if (bit_velle_init()=0) {
+			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	} else {
+		bit_velle_data.data=(void*)base;
+		if (bit_velle_init()=0) {
+			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
+				return -ENODEV;
+		} else {
+			return -ENODEV;
+		}
+	}
+	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
+	return 0;
+}
+
+static void __exit i2c_bitvelle_exit(void)
+{	
+	i2c_bit_del_bus(&bit_velle_ops);
+	release_region(base, (base = 0x3bc) ? 3 : 8);
+}
+
+MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+
+module_init(i2c_bitvelle_init);
+module_exit(i2c_bitvelle_exit);
diff -Nru a/drivers/i2c/i2c-velleman.c b/drivers/i2c/i2c-velleman.c
--- a/drivers/i2c/i2c-velleman.c	Mon Sep 22 16:12:26 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,161 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-velleman.c i2c-hw access for Velleman K9000 adapters		     */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 1995-96, 2000 Simon G. 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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* $Id: i2c-velleman.c,v 1.29 2003/01/21 08:08:16 kmalkki Exp $ */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/io.h>
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)		/* should be reasonable open, close &c. 	*/
-#define DEB2(x) 	/* low level debugging - very slow 		*/
-#define DEBE(x)	x	/* error messages 				*/
-
-					/* Pin Port  Inverted	name	*/
-#define I2C_SDA		0x02		/*  ctrl bit 1 	(inv)	*/
-#define I2C_SCL		0x08		/*  ctrl bit 3 	(inv)	*/
-
-#define I2C_SDAIN	0x10		/* stat bit 4		*/
-#define I2C_SCLIN	0x08		/* ctrl bit 3 (inv)(reads own output)*/
-
-#define I2C_DMASK	0xfd
-#define I2C_CMASK	0xf7
-
-
-/* --- Convenience defines for the parallel port:			*/
-#define BASE	(unsigned int)(data)
-#define DATA	BASE			/* Centronics data port		*/
-#define STAT	(BASE+1)		/* Centronics status port	*/
-#define CTRL	(BASE+2)		/* Centronics control port	*/
-
-#define DEFAULT_BASE 0x378
-static int base=0;
-
-/* ----- local functions --------------------------------------------------- */
-
-static void bit_velle_setscl(void *data, int state)
-{
-	if (state) {
-		outb(inb(CTRL) & I2C_CMASK,   CTRL);
-	} else {
-		outb(inb(CTRL) | I2C_SCL, CTRL);
-	}
-	
-}
-
-static void bit_velle_setsda(void *data, int state)
-{
-	if (state) {
-		outb(inb(CTRL) & I2C_DMASK , CTRL);
-	} else {
-		outb(inb(CTRL) | I2C_SDA, CTRL);
-	}
-	
-} 
-
-static int bit_velle_getscl(void *data)
-{
-	return ( 0 = ( (inb(CTRL)) & I2C_SCLIN ) );
-}
-
-static int bit_velle_getsda(void *data)
-{
-	return ( 0 != ( (inb(STAT)) & I2C_SDAIN ) );
-}
-
-static int bit_velle_init(void)
-{
-	if (!request_region(base, (base = 0x3bc) ? 3 : 8, 
-			"i2c (Vellemann adapter)"))
-		return -ENODEV;
-
-	bit_velle_setsda((void*)base,1);
-	bit_velle_setscl((void*)base,1);
-	return 0;
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-
-static struct i2c_algo_bit_data bit_velle_data = {
-	.setsda		= bit_velle_setsda,
-	.setscl		= bit_velle_setscl,
-	.getsda		= bit_velle_getsda,
-	.getscl		= bit_velle_getscl,
-	.udelay		= 10,
-	.mdelay		= 10,
-	.timeout	= HZ
-};
-
-static struct i2c_adapter bit_velle_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_B_VELLE,
-	.algo_data	= &bit_velle_data,
-	.name		= "Velleman K8000",
-};
-
-static int __init i2c_bitvelle_init(void)
-{
-	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-	if (base=0) {
-		/* probe some values */
-		basefiFAULT_BASE;
-		bit_velle_data.data=(void*)DEFAULT_BASE;
-		if (bit_velle_init()=0) {
-			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	} else {
-		bit_velle_data.data=(void*)base;
-		if (bit_velle_init()=0) {
-			if(i2c_bit_add_bus(&bit_velle_ops) < 0)
-				return -ENODEV;
-		} else {
-			return -ENODEV;
-		}
-	}
-	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
-	return 0;
-}
-
-static void __exit i2c_bitvelle_exit(void)
-{	
-	i2c_bit_del_bus(&bit_velle_ops);
-	release_region(base, (base = 0x3bc) ? 3 : 8);
-}
-
-MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-
-module_init(i2c_bitvelle_init);
-module_exit(i2c_bitvelle_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24     ` Greg KH
  (?)
  (?)
@ 2005-05-19  6:24     ` Greg KH
  2005-05-19  6:24         ` Greg KH
  -1 siblings, 1 reply; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

ChangeSet 1.1315.1.24, 2003/09/22 15:00:04-07:00, greg@kroah.com

[PATCH] I2C: move the remaining i2c bus drivers to drivers/i2c/busses


 drivers/i2c/i2c-adap-ite.c       |  278 --------------
 drivers/i2c/i2c-frodo.c          |   85 ----
 drivers/i2c/i2c-ibm_iic.c        |  729 ---------------------------------------
 drivers/i2c/i2c-ibm_iic.h        |  124 ------
 drivers/i2c/i2c-iop3xx.c         |  536 ----------------------------
 drivers/i2c/i2c-iop3xx.h         |  118 ------
 drivers/i2c/i2c-keywest.c        |  653 ----------------------------------
 drivers/i2c/i2c-keywest.h        |  110 -----
 drivers/i2c/i2c-rpx.c            |  103 -----
 drivers/i2c/Kconfig              |   35 -
 drivers/i2c/Makefile             |   10 
 drivers/i2c/busses/Kconfig       |   35 +
 drivers/i2c/busses/Makefile      |    9 
 drivers/i2c/busses/i2c-frodo.c   |   85 ++++
 drivers/i2c/busses/i2c-ibm_iic.c |  729 +++++++++++++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-ibm_iic.h |  124 ++++++
 drivers/i2c/busses/i2c-iop3xx.c  |  536 ++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-iop3xx.h  |  118 ++++++
 drivers/i2c/busses/i2c-ite.c     |  278 ++++++++++++++
 drivers/i2c/busses/i2c-keywest.c |  653 ++++++++++++++++++++++++++++++++++
 drivers/i2c/busses/i2c-keywest.h |  110 +++++
 drivers/i2c/busses/i2c-rpx.c     |  103 +++++
 22 files changed, 2781 insertions(+), 2780 deletions(-)


diff -Nru a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
--- a/drivers/i2c/Kconfig	Mon Sep 22 16:12:05 2003
+++ b/drivers/i2c/Kconfig	Mon Sep 22 16:12:05 2003
@@ -59,17 +59,7 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-pcf.
 
-config I2C_KEYWEST
-	tristate "Powermac Keywest I2C interface"
-	depends on I2C && PPC_PMAC
-	help
-	  This supports the use of the I2C interface in the combo-I/O
-	  chip on recent Apple machines.  Say Y if you have such a machine.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-keywest.
-
-config ITE_I2C_ALGO
+config I2C_ALGOITE
 	tristate "ITE I2C Algorithm"
 	depends on MIPS_ITE8172 && I2C
 	help
@@ -80,32 +70,9 @@
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-algo-ite.
 
-config ITE_I2C_ADAP
-	tristate "ITE I2C Adapter"
-	depends on ITE_I2C_ALGO
-	help
-	  This supports the ITE8172 I2C peripheral found on some MIPS
-	  systems. Say Y if you have one of these. You should also say Y for
-	  the ITE I2C driver algorithm support above.
-
-	  This support is also available as a module.  If so, the module 
-	  will be called i2c-adap-ite.
-
 config I2C_ALGO8XX
 	tristate "MPC8xx CPM I2C interface"
 	depends on 8xx && I2C
-
-config I2C_RPXLITE
-	tristate "Embedded Planet RPX Lite/Classic suppoort"
-	depends on (RPXLITE || RPXCLASSIC) && I2C_ALGO8XX
-
-config I2C_IBM_IIC
-	tristate "IBM IIC I2C"
-	depends on IBM_OCP && I2C
-
-config I2C_IOP3XX
-	tristate "Intel XScale IOP3xx on-chip I2C interface"
-	depends on ARCH_IOP3XX && I2C
 
 	source drivers/i2c/busses/Kconfig
 	source drivers/i2c/chips/Kconfig
diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile
--- a/drivers/i2c/Makefile	Mon Sep 22 16:12:05 2003
+++ b/drivers/i2c/Makefile	Mon Sep 22 16:12:05 2003
@@ -1,15 +1,11 @@
 #
-# Makefile for the kernel i2c bus driver.
+# Makefile for the i2c core.
 #
 
 obj-$(CONFIG_I2C)		+= i2c-core.o
 obj-$(CONFIG_I2C_CHARDEV)	+= i2c-dev.o
+obj-$(CONFIG_I2C_SENSOR)	+= i2c-sensor.o
 obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bit.o
 obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
-obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
-obj-$(CONFIG_ITE_I2C_ALGO)	+= i2c-algo-ite.o
-obj-$(CONFIG_ITE_I2C_ADAP)	+= i2c-adap-ite.o
-obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
-obj-$(CONFIG_I2C_SENSOR)	+= i2c-sensor.o
-obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
+obj-$(CONFIG_I2C_ALGOITE)	+= i2c-algo-ite.o
 obj-y				+= busses/ chips/
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:05 2003
+++ b/drivers/i2c/busses/Kconfig	Mon Sep 22 16:12:05 2003
@@ -2,7 +2,7 @@
 # Sensor device configuration
 #
 
-menu "I2C Hardware Sensors Mainboard support"
+menu "I2C Hardware Bus support"
 
 config I2C_ALI1535
 	tristate "ALI 1535"
@@ -97,6 +97,14 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i810.
 
+config I2C_IBM_IIC
+	tristate "IBM IIC I2C"
+	depends on IBM_OCP && I2C
+
+config I2C_IOP3XX
+	tristate "Intel XScale IOP3xx on-chip I2C interface"
+	depends on ARCH_IOP3XX && I2C
+
 config I2C_ISA
 	tristate "ISA Bus support"
 	depends on I2C && ISA && EXPERIMENTAL
@@ -107,6 +115,27 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-isa.
 
+config I2C_ITE
+	tristate "ITE I2C Adapter"
+	depends on I2C_ALGOITE
+	help
+	  This supports the ITE8172 I2C peripheral found on some MIPS
+	  systems. Say Y if you have one of these. You should also say Y for
+	  the ITE I2C driver algorithm support above.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-ite.
+
+config I2C_KEYWEST
+	tristate "Powermac Keywest I2C interface"
+	depends on I2C && PPC_PMAC
+	help
+	  This supports the use of the I2C interface in the combo-I/O
+	  chip on recent Apple machines.  Say Y if you have such a machine.
+
+	  This support is also available as a module.  If so, the module 
+	  will be called i2c-keywest.
+
 config I2C_NFORCE2
 	tristate "Nvidia Nforce2"
 	depends on I2C && PCI && EXPERIMENTAL
@@ -155,6 +184,10 @@
 
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-prosavage.
+
+config I2C_RPXLITE
+	tristate "Embedded Planet RPX Lite/Classic suppoort"
+	depends on (RPXLITE || RPXCLASSIC) && I2C_ALGO8XX
 
 config I2C_SAVAGE4
 	tristate "S3 Savage 4"
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:05 2003
+++ b/drivers/i2c/busses/Makefile	Mon Sep 22 16:12:05 2003
@@ -1,5 +1,5 @@
 #
-# Makefile for the kernel hardware sensors bus drivers.
+# Makefile for the i2c bus drivers.
 #
 
 obj-$(CONFIG_I2C_ALI1535)	+= i2c-ali1535.o
@@ -10,11 +10,16 @@
 obj-$(CONFIG_I2C_ELV)		+= i2c-elv.o
 obj-$(CONFIG_I2C_I801)		+= i2c-i801.o
 obj-$(CONFIG_I2C_I810)		+= i2c-i810.o
+obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
+obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_ISA)		+= i2c-isa.o
+obj-$(CONFIG_I2C_ITE)		+= i2c-ite.o
+obj-$(CONFIG_I2C_KEYWEST)	+= i2c-keywest.o
 obj-$(CONFIG_I2C_NFORCE2)	+= i2c-nforce2.o
 obj-$(CONFIG_I2C_PHILIPSPAR)	+= i2c-philips-par.o
 obj-$(CONFIG_I2C_PIIX4)		+= i2c-piix4.o
 obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosavage.o
+obj-$(CONFIG_I2C_RPXLITE)	+= i2c-rpx.o
 obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
 obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
 obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
@@ -23,5 +28,5 @@
 obj-$(CONFIG_I2C_VIA)		+= i2c-via.o
 obj-$(CONFIG_I2C_VIAPRO)	+= i2c-viapro.o
 obj-$(CONFIG_I2C_VOODOO3)	+= i2c-voodoo3.o
-obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
 obj-$(CONFIG_SCx200_ACB)	+= scx200_acb.o
+obj-$(CONFIG_SCx200_I2C)	+= scx200_i2c.o
diff -Nru a/drivers/i2c/busses/i2c-frodo.c b/drivers/i2c/busses/i2c-frodo.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-frodo.c	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,85 @@
+
+/*
+ * linux/drivers/i2c/i2c-frodo.c
+ *
+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
+ *
+ * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110
+ * Development board (Frodo).
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <asm/hardware.h>
+
+
+static void frodo_setsda (void *data,int state)
+{
+	if (state)
+		FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT;
+	else
+		FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT;
+}
+
+static void frodo_setscl (void *data,int state)
+{
+	if (state)
+		FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT;
+	else
+		FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT;
+}
+
+static int frodo_getsda (void *data)
+{
+	return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0);
+}
+
+static int frodo_getscl (void *data)
+{
+	return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0);
+}
+
+static struct i2c_algo_bit_data bit_frodo_data = {
+	.setsda		= frodo_setsda,
+	.setscl		= frodo_setscl,
+	.getsda		= frodo_getsda,
+	.getscl		= frodo_getscl,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= HZ
+};
+
+static struct i2c_adapter frodo_ops = {
+	.owner			= THIS_MODULE,
+	.id			= I2C_HW_B_FRODO,
+	.algo_data		= &bit_frodo_data,
+	.dev			= {
+		.name		= "Frodo adapter driver",
+	},
+};
+
+static int __init i2c_frodo_init (void)
+{
+	return i2c_bit_add_bus(&frodo_ops);
+}
+
+static void __exit i2c_frodo_exit (void)
+{
+	i2c_bit_del_bus(&frodo_ops);
+}
+
+MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
+MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo");
+MODULE_LICENSE ("GPL");
+
+module_init (i2c_frodo_init);
+module_exit (i2c_frodo_exit);
+
diff -Nru a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-ibm_iic.c	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,729 @@
+/*
+ * drivers/i2c/i2c-ibm_iic.c
+ *
+ * Support for the IIC peripheral on IBM PPC 4xx
+ *
+ * Copyright (c) 2003 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by 
+ * 	Ian DaSilva  <idasilva@mvista.com>
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Matt Porter  <mporter@mvista.com>
+ *
+ *      Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * Original driver version was highly leveraged from i2c-elektor.c
+ *
+ *   	Copyright 1995-97 Simon G. Vogl
+ *                1998-99 Hans Berglund
+ *
+ *   	With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> 
+ *	and even Frodo Looijaard <frodol@dds.nl>
+ *
+ * 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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <asm/ocp.h>
+#include <asm/ibm4xx.h>
+
+#include "i2c-ibm_iic.h"
+
+#define DRIVER_VERSION "2.0"
+
+MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+
+static int iic_scan = 0;
+MODULE_PARM(iic_scan, "i");
+MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus");
+
+static int iic_force_poll = 0;
+MODULE_PARM(iic_force_poll, "i");
+MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
+
+static int iic_force_fast = 0;
+MODULE_PARM(iic_force_fast, "i");
+MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)");
+
+#define DBG_LEVEL 0
+
+#ifdef DBG
+#undef DBG
+#endif
+
+#ifdef DBG2
+#undef DBG2
+#endif
+
+#if DBG_LEVEL > 0
+#  define DBG(x...)	printk(KERN_DEBUG "ibm-iic" ##x)
+#else
+#  define DBG(x...)	((void)0)
+#endif
+#if DBG_LEVEL > 1
+#  define DBG2(x...) 	DBG( ##x )
+#else
+#  define DBG2(x...) 	((void)0)
+#endif
+#if DBG_LEVEL > 2
+static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header);
+	printk(KERN_DEBUG "  cntl     = 0x%02x, mdcntl = 0x%02x\n"
+	       KERN_DEBUG "  sts      = 0x%02x, extsts = 0x%02x\n"
+	       KERN_DEBUG "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n"
+	       KERN_DEBUG "  xtcntlss = 0x%02x, directcntl = 0x%02x\n",
+		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), 
+		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), 
+		in_8(&iic->xtcntlss), in_8(&iic->directcntl));
+}
+#  define DUMP_REGS(h,dev)	dump_iic_regs((h),(dev))
+#else
+#  define DUMP_REGS(h,dev)	((void)0)
+#endif
+
+/* Enable/disable interrupt generation */
+static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable)
+{
+	out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);
+}
+ 
+/*
+ * Initialize IIC interface.
+ */
+static void iic_dev_init(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+
+	DBG("%d: init\n", dev->idx);
+	
+	/* Clear master address */
+	out_8(&iic->lmadr, 0);
+	out_8(&iic->hmadr, 0);
+
+	/* Clear slave address */
+	out_8(&iic->lsadr, 0);
+	out_8(&iic->hsadr, 0);
+
+	/* Clear status & extended status */
+	out_8(&iic->sts, STS_SCMP | STS_IRQA);
+	out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA
+			    | EXTSTS_ICT | EXTSTS_XFRA);
+
+	/* Set clock divider */
+	out_8(&iic->clkdiv, dev->clckdiv);
+
+	/* Clear transfer count */
+	out_8(&iic->xfrcnt, 0);
+
+	/* Clear extended control and status */
+	out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC
+			    | XTCNTLSS_SWS);
+
+	/* Clear control register */
+	out_8(&iic->cntl, 0);
+	
+	/* Enable interrupts if possible */
+	iic_interrupt_mode(dev, dev->irq >= 0);
+
+	/* Set mode control */
+	out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS
+			    | (dev->fast_mode ? MDCNTL_FSM : 0));
+
+	DUMP_REGS("iic_init", dev);
+}
+
+/* 
+ * Reset IIC interface
+ */
+static void iic_dev_reset(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	int i;
+	u8 dc;
+	
+	DBG("%d: soft reset\n", dev->idx);
+	DUMP_REGS("reset", dev);
+	
+    	/* Place chip in the reset state */
+	out_8(&iic->xtcntlss, XTCNTLSS_SRST);
+	
+	/* Check if bus is free */
+	dc = in_8(&iic->directcntl);	
+	if (!DIRCTNL_FREE(dc)){
+		DBG("%d: trying to regain bus control\n", dev->idx);
+	
+		/* Try to set bus free state */
+		out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);	
+	
+		/* Wait until we regain bus control */
+		for (i = 0; i < 100; ++i){
+			dc = in_8(&iic->directcntl);
+			if (DIRCTNL_FREE(dc))
+				break;
+			
+			/* Toggle SCL line */
+			dc ^= DIRCNTL_SCC;
+			out_8(&iic->directcntl, dc);
+			udelay(10);
+			dc ^= DIRCNTL_SCC;
+			out_8(&iic->directcntl, dc);
+			
+			/* be nice */
+			cond_resched();
+		}
+	}
+	
+	/* Remove reset */
+	out_8(&iic->xtcntlss, 0);
+	
+	/* Reinitialize interface */
+	iic_dev_init(dev);
+}
+
+/*
+ * IIC interrupt handler
+ */
+static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
+	volatile struct iic_regs* iic = dev->vaddr;
+	
+	DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", 
+	     dev->idx, in_8(&iic->sts), in_8(&iic->extsts));
+	
+	/* Acknowledge IRQ and wakeup iic_wait_for_tc */
+	out_8(&iic->sts, STS_IRQA | STS_SCMP);
+	wake_up_interruptible(&dev->wq);
+	
+	return IRQ_HANDLED;
+}
+
+/*
+ * Get master transfer result and clear errors if any.
+ * Returns the number of actually transferred bytes or error (<0)
+ */
+static int iic_xfer_result(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;	
+	
+	if (unlikely(in_8(&iic->sts) & STS_ERR)){
+		DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, 
+			in_8(&iic->extsts));
+				
+		/* Clear errors and possible pending IRQs */
+		out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | 
+			EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
+			
+		/* Flush master data buffer */
+		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+		
+		/* Is bus free?
+		 * If error happened during combined xfer
+		 * IIC interface is usually stuck in some strange
+		 * state, the only way out - soft reset.
+		 */
+		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+			DBG("%d: bus is stuck, resetting\n", dev->idx);
+			iic_dev_reset(dev);
+		}
+		return -EREMOTEIO;
+	}
+	else
+		return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK;
+}
+
+/*
+ * Try to abort active transfer.
+ */
+static void iic_abort_xfer(struct ibm_iic_private* dev)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	unsigned long x;
+	
+	DBG("%d: iic_abort_xfer\n", dev->idx);
+	
+	out_8(&iic->cntl, CNTL_HMT);
+	
+	/*
+	 * Wait for the abort command to complete.
+	 * It's not worth to be optimized, just poll (timeout >= 1 tick)
+	 */
+	x = jiffies + 2;
+	while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+		if (time_after(jiffies, x)){
+			DBG("%d: abort timeout, resetting...\n", dev->idx);
+			iic_dev_reset(dev);
+			return;
+		}
+		schedule();
+	}
+
+	/* Just to clear errors */
+	iic_xfer_result(dev);
+}
+
+/*
+ * Wait for master transfer to complete.
+ * It puts current process to sleep until we get interrupt or timeout expires.
+ * Returns the number of transferred bytes or error (<0)
+ */
+static int iic_wait_for_tc(struct ibm_iic_private* dev){
+	
+	volatile struct iic_regs *iic = dev->vaddr;
+	int ret = 0;
+	
+	if (dev->irq >= 0){
+		/* Interrupt mode */
+		wait_queue_t wait;
+    		init_waitqueue_entry(&wait, current);
+		
+		add_wait_queue(&dev->wq, &wait);
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (in_8(&iic->sts) & STS_PT)
+			schedule_timeout(dev->adap.timeout * HZ);
+		set_current_state(TASK_RUNNING);
+		remove_wait_queue(&dev->wq, &wait);
+		
+		if (unlikely(signal_pending(current))){
+			DBG("%d: wait interrupted\n", dev->idx);
+			ret = -ERESTARTSYS;
+		} else if (unlikely(in_8(&iic->sts) & STS_PT)){
+			DBG("%d: wait timeout\n", dev->idx);
+			ret = -ETIMEDOUT;
+		}
+	}
+	else {
+		/* Polling mode */
+		unsigned long x = jiffies + dev->adap.timeout * HZ;
+		
+		while (in_8(&iic->sts) & STS_PT){
+			if (unlikely(time_after(jiffies, x))){
+				DBG("%d: poll timeout\n", dev->idx);
+				ret = -ETIMEDOUT;
+				break;
+			}
+		
+			if (unlikely(signal_pending(current))){
+				DBG("%d: poll interrupted\n", dev->idx);
+				ret = -ERESTARTSYS;
+				break;
+			}
+			schedule();
+		}	
+	}
+	
+	if (unlikely(ret < 0))
+		iic_abort_xfer(dev);
+	else
+		ret = iic_xfer_result(dev);
+	
+	DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);
+	
+	return ret;
+}
+
+/*
+ * Low level master transfer routine
+ */
+static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, 
+			  int combined_xfer)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	char* buf = pm->buf;
+	int i, j, loops, ret = 0;
+	int len = pm->len;
+
+	u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;
+	if (pm->flags & I2C_M_RD)
+		cntl |= CNTL_RW;
+	
+	loops = (len + 3) / 4;
+	for (i = 0; i < loops; ++i, len -= 4){
+		int count = len > 4 ? 4 : len;
+		u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);
+		
+		if (!(cntl & CNTL_RW))
+			for (j = 0; j < count; ++j)
+				out_8((volatile u8*)&iic->mdbuf, *buf++);
+		
+		if (i < loops - 1)
+			cmd |= CNTL_CHT;
+		else if (combined_xfer)
+			cmd |= CNTL_RPST;
+		
+		DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);
+		
+		/* Start transfer */
+		out_8(&iic->cntl, cmd);
+		
+		/* Wait for completion */
+		ret = iic_wait_for_tc(dev);
+
+		if (unlikely(ret < 0))
+			break;
+		else if (unlikely(ret != count)){
+			DBG("%d: xfer_bytes, requested %d, transfered %d\n", 
+				dev->idx, count, ret);
+			
+			/* If it's not a last part of xfer, abort it */
+			if (combined_xfer || (i < loops - 1))
+    				iic_abort_xfer(dev);
+				
+			ret = -EREMOTEIO;
+			break;				
+		}
+		
+		if (cntl & CNTL_RW)
+			for (j = 0; j < count; ++j)
+				*buf++ = in_8((volatile u8*)&iic->mdbuf);
+	}
+	
+	return ret > 0 ? 0 : ret;
+}
+
+/*
+ * Set target slave address for master transfer
+ */
+static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
+{
+	volatile struct iic_regs *iic = dev->vaddr;
+	u16 addr = msg->addr;
+	
+	DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, 
+		addr, msg->flags & I2C_M_TEN ? 10 : 7);
+	
+	if (msg->flags & I2C_M_TEN){
+	    out_8(&iic->cntl, CNTL_AMD);
+	    out_8(&iic->lmadr, addr);
+	    out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06));
+	}
+	else {
+	    out_8(&iic->cntl, 0);
+	    out_8(&iic->lmadr, addr << 1);
+	}
+}
+
+static inline int iic_invalid_address(const struct i2c_msg* p)
+{
+	return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));
+}
+
+static inline int iic_address_neq(const struct i2c_msg* p1, 
+				  const struct i2c_msg* p2)
+{
+	return (p1->addr != p2->addr) 
+		|| ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));
+} 
+
+/*
+ * Generic master transfer entrypoint. 
+ * Returns the number of processed messages or error (<0)
+ */
+static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+{
+    	struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));
+	volatile struct iic_regs *iic = dev->vaddr;
+	int i, ret = 0;
+	
+	DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
+	
+	if (!num)
+		return 0;
+	
+	/* Check the sanity of the passed messages.
+	 * Uhh, generic i2c layer is more suitable place for such code...
+	 */
+	if (unlikely(iic_invalid_address(&msgs[0]))){
+		DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, 
+			msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);
+		return -EINVAL;
+	}		
+	for (i = 0; i < num; ++i){
+		if (unlikely(msgs[i].len <= 0)){
+			DBG("%d: invalid len %d in msg[%d]\n", dev->idx, 
+				msgs[i].len, i);
+			return -EINVAL;
+		}
+		if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){
+			DBG("%d: invalid addr in msg[%d]\n", dev->idx, i);
+			return -EINVAL;
+		}
+	}
+	
+	/* Check bus state */
+	if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){
+		DBG("%d: iic_xfer, bus is not free\n", dev->idx);
+		
+		/* Usually it means something serious has happend.
+		 * We *cannot* have unfinished previous transfer
+		 * so it doesn't make any sense to try to stop it.
+		 * Probably we were not able to recover from the 
+		 * previous error.
+		 * The only *reasonable* thing I can think of here
+		 * is soft reset.  --ebs
+		 */
+		iic_dev_reset(dev);
+		
+		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
+			DBG("%d: iic_xfer, bus is still not free\n", dev->idx);
+			return -EREMOTEIO;
+		}
+	} 
+	else {
+		/* Flush master data buffer (just in case) */
+		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
+	}
+	
+	/* Load slave address */
+	iic_address(dev, &msgs[0]);
+	
+	/* Do real transfer */
+    	for (i = 0; i < num && !ret; ++i)
+		ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);
+
+	return ret < 0 ? ret : num;
+}
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+}
+
+static struct i2c_algorithm iic_algo = {
+	.name 		= "IBM IIC algorithm",
+	.id   		= I2C_ALGO_OCP,
+	.master_xfer 	= iic_xfer,
+	.smbus_xfer	= NULL,
+	.slave_send	= NULL,
+	.slave_recv	= NULL,
+	.algo_control	= NULL,
+	.functionality	= iic_func
+};
+
+/*
+ * Scan bus for valid 7-bit addresses (ie things that ACK on 1 byte read)
+ * We only scan range [0x08 - 0x77], all other addresses are reserved anyway
+ */
+static void __devinit iic_scan_bus(struct ibm_iic_private* dev)
+{
+	int found = 0;
+	char dummy;
+	struct i2c_msg msg = {
+		.buf   = &dummy,
+		.len   = sizeof(dummy),
+		.flags = I2C_M_RD
+	};
+	
+	printk(KERN_INFO "ibm-iic%d: scanning bus...\n" KERN_INFO, dev->idx);
+	
+	for (msg.addr = 8; msg.addr < 0x78; ++msg.addr)
+		if (iic_xfer(&dev->adap, &msg, 1) = 1){
+			++found;
+			printk(" 0x%02x", msg.addr);
+		}
+
+	printk("%sibm-iic%d: %d device(s) detected\n", 
+		found ? "\n" KERN_INFO : "", dev->idx, found);
+}
+
+/*
+ * Calculates IICx_CLCKDIV value for a specific OPB clock frequency
+ */
+static inline u8 iic_clckdiv(unsigned int opb)
+{
+	/* Compatibility kludge, should go away after all cards
+	 * are fixed to fill correct value for opbfreq.
+	 * Previous driver version used hardcoded divider value 4,
+	 * it corresponds to OPB frequency from the range (40, 50] MHz
+	 */
+	if (!opb){
+		printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq,"
+			" fix your board specific setup\n");
+		opb = 50000000;
+	}
+
+	/* Convert to MHz */
+	opb /= 1000000;
+	
+	if (opb < 20 || opb > 150){
+		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
+			opb);
+		opb = opb < 20 ? 20 : 150;
+	}
+	return (u8)((opb + 9) / 10 - 1);
+}
+
+/*
+ * Register single IIC interface
+ */
+static int __devinit iic_probe(struct ocp_device *ocp){
+
+	struct ibm_iic_private* dev;
+	struct i2c_adapter* adap;
+	int ret;
+	bd_t* bd = (bd_t*)&__res;
+	
+	if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){
+		printk(KERN_CRIT "ibm-iic: failed to allocate device data\n");
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	dev->idx = ocp->num;
+	ocp_set_drvdata(ocp, dev);
+	
+	if (!(dev->vaddr = ioremap(ocp->paddr, sizeof(struct iic_regs)))){
+		printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
+			dev->idx);
+		ret = -ENXIO;
+		goto fail2;
+	}
+	
+	init_waitqueue_head(&dev->wq);
+
+	dev->irq = iic_force_poll ? -1 : ocp->irq;
+	if (dev->irq >= 0){
+		/* Disable interrupts until we finish intialization,
+		   assumes level-sensitive IRQ setup...
+		 */
+		iic_interrupt_mode(dev, 0);
+		if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){
+			printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", 
+				dev->idx, dev->irq);
+			/* Fallback to the polling mode */	
+			dev->irq = -1;
+		}
+	}
+	
+	if (dev->irq < 0)
+		printk(KERN_WARNING "ibm-iic%d: using polling mode\n", 
+			dev->idx);
+		
+	/* Board specific settings */
+	BUG_ON(dev->idx >= sizeof(bd->bi_iic_fast) / sizeof(bd->bi_iic_fast[0]));
+	dev->fast_mode = iic_force_fast ? 1 : bd->bi_iic_fast[dev->idx];
+	
+	/* clckdiv is the same for *all* IIC interfaces, 
+	 * but I'd rather make a copy than introduce another global. --ebs
+	 */
+	dev->clckdiv = iic_clckdiv(bd->bi_opb_busfreq);
+	DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);
+	
+	/* Initialize IIC interface */
+	iic_dev_init(dev);
+	
+	/* Register it with i2c layer */
+	adap = &dev->adap;
+	strcpy(adap->dev.name, "IBM IIC");
+	i2c_set_adapdata(adap, dev);
+	adap->id = I2C_HW_OCP | iic_algo.id;
+	adap->algo = &iic_algo;
+	adap->client_register = NULL;
+	adap->client_unregister = NULL;
+	adap->timeout = 1;
+	adap->retries = 1;
+
+	if ((ret = i2c_add_adapter(adap)) != 0){
+		printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n",
+			dev->idx);
+		goto fail;
+	}
+	
+	printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,
+		dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
+
+	/* Scan bus if requested by user */
+	if (iic_scan)
+		iic_scan_bus(dev);
+
+	return 0;
+
+fail:	
+	if (dev->irq >= 0){
+		iic_interrupt_mode(dev, 0);
+		free_irq(dev->irq, dev);
+	}	
+
+	iounmap((void*)dev->vaddr);
+fail2:	
+	ocp_set_drvdata(ocp, 0);
+	kfree(dev);	
+	return ret;
+}
+
+/*
+ * Cleanup initialized IIC interface
+ */
+static void __devexit iic_remove(struct ocp_device *ocp)
+{
+	struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
+	BUG_ON(dev = NULL);
+	if (i2c_del_adapter(&dev->adap)){
+		printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n",
+			dev->idx);
+		/* That's *very* bad, just shutdown IRQ ... */
+		if (dev->irq >= 0){
+		    iic_interrupt_mode(dev, 0);	
+		    free_irq(dev->irq, dev);
+		    dev->irq = -1;
+		}
+	} else {
+		if (dev->irq >= 0){
+		    iic_interrupt_mode(dev, 0);	
+		    free_irq(dev->irq, dev);
+		}
+		iounmap((void*)dev->vaddr);
+		kfree(dev);
+	}
+}
+
+static struct ocp_device_id ibm_iic_ids[] __devinitdata = 
+{
+	{ .vendor = OCP_VENDOR_IBM, .device = OCP_FUNC_IIC },
+	{ .vendor = OCP_VENDOR_INVALID }
+};
+
+MODULE_DEVICE_TABLE(ocp, ibm_iic_ids);
+
+static struct ocp_driver ibm_iic_driver +{
+	.name 		= "ocp_iic",
+	.id_table	= ibm_iic_ids,
+	.probe		= iic_probe,
+	.remove		= __devexit_p(iic_remove),
+#if defined(CONFIG_PM)
+	.suspend	= NULL,
+	.resume		= NULL,
+#endif
+};
+
+static int __init iic_init(void)
+{
+	printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n");
+	return ocp_module_init(&ibm_iic_driver);
+}
+
+static void __exit iic_exit(void)
+{
+	ocp_unregister_driver(&ibm_iic_driver);
+}
+
+module_init(iic_init);
+module_exit(iic_exit);
diff -Nru a/drivers/i2c/busses/i2c-ibm_iic.h b/drivers/i2c/busses/i2c-ibm_iic.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-ibm_iic.h	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,124 @@
+/*
+ * drivers/i2c/i2c-ibm_iic.h
+ *
+ * Support for the IIC peripheral on IBM PPC 4xx
+ * 
+ * Copyright (c) 2003 Zultys Technologies.
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *
+ * Based on original work by 
+ * 	Ian DaSilva  <idasilva@mvista.com>
+ *      Armin Kuster <akuster@mvista.com>
+ * 	Matt Porter  <mporter@mvista.com>
+ *
+ *      Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * 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.
+ *
+ */
+#ifndef __I2C_IBM_IIC_H_
+#define __I2C_IBM_IIC_H_
+
+#include <linux/config.h>
+#include <linux/i2c.h> 
+
+struct iic_regs {
+	u16 mdbuf;
+	u16 sbbuf;
+	u8 lmadr;
+	u8 hmadr;
+	u8 cntl;
+	u8 mdcntl;
+	u8 sts;
+	u8 extsts;
+	u8 lsadr;
+	u8 hsadr;
+	u8 clkdiv;
+	u8 intmsk;
+	u8 xfrcnt;
+	u8 xtcntlss;
+	u8 directcntl;
+};
+
+struct ibm_iic_private {
+	struct i2c_adapter adap;
+	volatile struct iic_regs *vaddr;
+	wait_queue_head_t wq;
+	int idx;
+	int irq;
+	int fast_mode;
+	u8  clckdiv;
+};
+
+/* IICx_CNTL register */
+#define CNTL_HMT	0x80
+#define CNTL_AMD	0x40
+#define CNTL_TCT_MASK	0x30
+#define CNTL_TCT_SHIFT	4
+#define CNTL_RPST	0x08
+#define CNTL_CHT	0x04 
+#define CNTL_RW		0x02
+#define CNTL_PT		0x01
+
+/* IICx_MDCNTL register */
+#define MDCNTL_FSDB	0x80
+#define MDCNTL_FMDB	0x40
+#define MDCNTL_EGC	0x20
+#define MDCNTL_FSM	0x10
+#define MDCNTL_ESM	0x08
+#define MDCNTL_EINT	0x04
+#define MDCNTL_EUBS	0x02
+#define MDCNTL_HSCL	0x01
+
+/* IICx_STS register */
+#define STS_SSS		0x80
+#define STS_SLPR	0x40
+#define STS_MDBS	0x20
+#define STS_MDBF	0x10
+#define STS_SCMP	0x08
+#define STS_ERR		0x04
+#define STS_IRQA	0x02
+#define STS_PT		0x01
+
+/* IICx_EXTSTS register */
+#define EXTSTS_IRQP	0x80
+#define EXTSTS_BCS_MASK	0x70
+#define   EXTSTS_BCS_FREE  0x40
+#define EXTSTS_IRQD	0x08
+#define EXTSTS_LA	0x04
+#define EXTSTS_ICT	0x02
+#define EXTSTS_XFRA	0x01
+
+/* IICx_INTRMSK register */
+#define INTRMSK_EIRC	0x80
+#define INTRMSK_EIRS	0x40
+#define INTRMSK_EIWC	0x20
+#define INTRMSK_EIWS	0x10
+#define INTRMSK_EIHE	0x08
+#define INTRMSK_EIIC	0x04
+#define INTRMSK_EITA	0x02
+#define INTRMSK_EIMTC	0x01
+
+/* IICx_XFRCNT register */
+#define XFRCNT_MTC_MASK	0x07
+
+/* IICx_XTCNTLSS register */
+#define XTCNTLSS_SRC	0x80
+#define XTCNTLSS_SRS	0x40
+#define XTCNTLSS_SWC	0x20
+#define XTCNTLSS_SWS	0x10
+#define XTCNTLSS_SRST	0x01
+
+/* IICx_DIRECTCNTL register */
+#define DIRCNTL_SDAC	0x08
+#define DIRCNTL_SCC	0x04
+#define DIRCNTL_MSDA	0x02
+#define DIRCNTL_MSC	0x01
+
+/* Check if we really control the I2C bus and bus is free */
+#define DIRCTNL_FREE(v)	(((v) & 0x0f) = 0x0f)
+
+#endif /* __I2C_IBM_IIC_H_ */
diff -Nru a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-iop3xx.c	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,536 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx                */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
+ *                      <Peter dot Milne at D hyphen TACQ dot com>
+
+    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, version 2.
+
+
+    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.                */
+/* ------------------------------------------------------------------------- */
+/*
+   With acknowledgements to i2c-algo-ibm_ocp.c by 
+   Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
+
+   And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
+
+     Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
+   
+   And which acknowledged Ky?sti M?lkki <kmalkki@cc.hut.fi>,
+   Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
+
+  ---------------------------------------------------------------------------*/
+
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/i2c.h>
+
+
+#include <asm/arch-iop3xx/iop321.h>
+#include <asm/arch-iop3xx/iop321-irqs.h>
+#include "i2c-iop3xx.h"
+
+
+/* ----- global defines ----------------------------------------------- */
+#define PASSERT(x) do { if (!(x) ) \
+		printk(KERN_CRIT "PASSERT %s in %s:%d\n", #x, __FILE__, __LINE__ );\
+	} while (0)
+
+
+/* ----- global variables ---------------------------------------------	*/
+
+
+static inline unsigned char iic_cook_addr(struct i2c_msg *msg) 
+{
+	unsigned char addr;
+
+	addr = (msg->addr << 1);
+
+	if (msg->flags & I2C_M_RD)
+		addr |= 1;
+
+	/* PGM: what is M_REV_DIR_ADDR - do we need it ?? */
+	if (msg->flags & I2C_M_REV_DIR_ADDR)
+		addr ^= 1;
+
+	return addr;   
+}
+
+
+static inline void iop3xx_adap_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	/* Follows devman 9.3 */
+	*iop3xx_adap->biu->CR = IOP321_ICR_UNIT_RESET;
+	*iop3xx_adap->biu->SR = IOP321_ISR_CLEARBITS;
+	*iop3xx_adap->biu->CR = 0;
+} 
+
+static inline void iop3xx_adap_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	*iop3xx_adap->biu->SAR = MYSAR;
+}
+
+static inline void iop3xx_adap_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	u32 cr = IOP321_ICR_GCD|IOP321_ICR_SCLEN|IOP321_ICR_UE;
+
+	/* NB SR bits not same position as CR IE bits :-( */
+	iop3xx_adap->biu->SR_enabled = 
+		IOP321_ISR_ALD | IOP321_ISR_BERRD |
+		IOP321_ISR_RXFULL | IOP321_ISR_TXEMPTY;
+
+	cr |= IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
+		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE;
+
+	*iop3xx_adap->biu->CR = cr;
+}
+
+static void iop3xx_adap_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	
+	cr &= ~(IOP321_ICR_MSTART | IOP321_ICR_TBYTE | 
+		IOP321_ICR_MSTOP | IOP321_ICR_SCLEN);
+	*iop3xx_adap->biu->CR = cr;
+}
+
+static void iop3xx_adap_final_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	
+	cr &= ~(IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
+		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE);
+	iop3xx_adap->biu->SR_enabled = 0;
+	*iop3xx_adap->biu->CR = cr;
+}
+
+/* 
+ * NB: the handler has to clear the source of the interrupt! 
+ * Then it passes the SR flags of interest to BH via adap data
+ */
+static void iop3xx_i2c_handler(int this_irq, 
+				void *dev_id, 
+				struct pt_regs *regs) 
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
+
+	u32 sr = *iop3xx_adap->biu->SR;
+
+	if ((sr &= iop3xx_adap->biu->SR_enabled)) {
+		*iop3xx_adap->biu->SR = sr;
+		iop3xx_adap->biu->SR_received |= sr;
+		wake_up_interruptible(&iop3xx_adap->waitq);
+	}
+}
+
+/* check all error conditions, clear them , report most important */
+static int iop3xx_adap_error(u32 sr)
+{
+	int rc = 0;
+
+	if ((sr&IOP321_ISR_BERRD)) {
+		if ( !rc ) rc = -I2C_ERR_BERR;
+	}
+	if ((sr&IOP321_ISR_ALD)) {
+		if ( !rc ) rc = -I2C_ERR_ALD;		
+	}
+	return rc;	
+}
+
+static inline u32 get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	unsigned long flags;
+	u32 sr;
+
+	spin_lock_irqsave(&iop3xx_adap->lock, flags);
+	sr = iop3xx_adap->biu->SR_received;
+	iop3xx_adap->biu->SR_received = 0;
+	spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
+
+	return sr;
+}
+
+/*
+ * sleep until interrupted, then recover and analyse the SR
+ * saved by handler
+ */
+typedef int (* compare_func)(unsigned test, unsigned mask);
+/* returns 1 on correct comparison */
+
+static int iop3xx_adap_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 
+				  unsigned flags, unsigned* status,
+				  compare_func compare)
+{
+	unsigned sr = 0;
+	int interrupted;
+	int done;
+	int rc;
+
+	do {
+		interrupted = wait_event_interruptible_timeout (
+			iop3xx_adap->waitq,
+			(done = compare( sr = get_srstat(iop3xx_adap),flags )),
+			iop3xx_adap->timeout
+			);
+		if ((rc = iop3xx_adap_error(sr)) < 0) {
+			*status = sr;
+			return rc;
+		}else if (!interrupted) {
+			*status = sr;
+			return rc = -ETIMEDOUT;
+		}
+	} while(!done);
+
+	*status = sr;
+
+	return rc = 0;
+}
+
+/*
+ * Concrete compare_funcs 
+ */
+static int all_bits_clear(unsigned test, unsigned mask)
+{
+	return (test & mask) = 0;
+}
+static int any_bits_set(unsigned test, unsigned mask)
+{
+	return (test & mask) != 0;
+}
+
+static int iop3xx_adap_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+{
+	return iop3xx_adap_wait_event( 
+		iop3xx_adap, 
+	        IOP321_ISR_TXEMPTY|IOP321_ISR_ALD|IOP321_ISR_BERRD,
+		status, any_bits_set);
+}
+
+static int iop3xx_adap_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+{
+	return iop3xx_adap_wait_event( 
+		iop3xx_adap, 
+		IOP321_ISR_RXFULL|IOP321_ISR_ALD|IOP321_ISR_BERRD,
+		status,	any_bits_set);
+}
+
+static int iop3xx_adap_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
+{
+	return iop3xx_adap_wait_event( 
+		iop3xx_adap, IOP321_ISR_UNITBUSY, status, all_bits_clear);
+}
+
+/*
+ * Description: This performs the IOP3xx initialization sequence
+ * Valid for IOP321. Maybe valid for IOP310?.
+ */
+static int iop3xx_adap_init (struct i2c_algo_iop3xx_data *iop3xx_adap)
+{
+	*IOP321_GPOD &= ~(iop3xx_adap->channel=0 ?
+			  IOP321_GPOD_I2C0:
+			  IOP321_GPOD_I2C1);
+
+	iop3xx_adap_reset(iop3xx_adap);
+	iop3xx_adap_set_slave_addr(iop3xx_adap);
+	iop3xx_adap_enable(iop3xx_adap);
+	
+        return 0;
+}
+
+static int iop3xx_adap_send_target_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
+					      struct i2c_msg* msg)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	int status;
+	int rc;
+
+	*iop3xx_adap->biu->DBR = iic_cook_addr(msg);
+	
+	cr &= ~(IOP321_ICR_MSTOP | IOP321_ICR_NACK);
+	cr |= IOP321_ICR_MSTART | IOP321_ICR_TBYTE;
+
+	*iop3xx_adap->biu->CR = cr;
+	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
+	/* this assert fires every time, contrary to IOP manual	
+	PASSERT((status&IOP321_ISR_UNITBUSY)!=0);
+	*/
+	PASSERT((status&IOP321_ISR_RXREAD)=0);
+	     
+	return rc;
+}
+
+static int iop3xx_adap_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, int stop)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	int status;
+	int rc;
+
+	*iop3xx_adap->biu->DBR = byte;
+	cr &= ~IOP321_ICR_MSTART;
+	if (stop) {
+		cr |= IOP321_ICR_MSTOP;
+	} else {
+		cr &= ~IOP321_ICR_MSTOP;
+	}
+	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
+	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
+
+	return rc;
+} 
+
+static int iop3xx_adap_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap,
+				 char* byte, int stop)
+{
+	unsigned cr = *iop3xx_adap->biu->CR;
+	int status;
+	int rc;
+
+	cr &= ~IOP321_ICR_MSTART;
+
+	if (stop) {
+		cr |= IOP321_ICR_MSTOP|IOP321_ICR_NACK;
+	} else {
+		cr &= ~(IOP321_ICR_MSTOP|IOP321_ICR_NACK);
+	}
+	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
+
+	rc = iop3xx_adap_wait_rx_done(iop3xx_adap, &status);
+
+	*byte = *iop3xx_adap->biu->DBR;
+
+	return rc;
+}
+
+static int iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, 
+				 const char *buf, int count)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int ii;
+	int rc = 0;
+
+	for (ii = 0; rc = 0 && ii != count; ++ii) {
+		rc = iop3xx_adap_write_byte(iop3xx_adap, buf[ii], ii=count-1);
+	}
+	return rc;
+}
+
+static int iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, 
+				char *buf, int count)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int ii;
+	int rc = 0;
+
+	for (ii = 0; rc = 0 && ii != count; ++ii) {
+		rc = iop3xx_adap_read_byte(iop3xx_adap, &buf[ii], ii=count-1);
+	}
+	return rc;
+}
+
+/*
+ * Description:  This function implements combined transactions.  Combined
+ * transactions consist of combinations of reading and writing blocks of data.
+ * FROM THE SAME ADDRESS
+ * Each transfer (i.e. a read or a write) is separated by a repeated start
+ * condition.
+ */
+static int iop3xx_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int rc;
+
+	rc = iop3xx_adap_send_target_slave_addr(iop3xx_adap, pmsg);
+	if (rc < 0) {
+		return rc;
+	}
+
+	if ((pmsg->flags&I2C_M_RD)) {
+		return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
+	} else {
+		return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
+	}
+}
+
+/*
+ * master_xfer() - main read/write entry
+ */
+static int iop3xx_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
+	int im = 0;
+	int ret = 0;
+	int status;
+
+	iop3xx_adap_wait_idle(iop3xx_adap, &status);
+	iop3xx_adap_reset(iop3xx_adap);
+	iop3xx_adap_enable(iop3xx_adap);
+
+	for (im = 0; ret = 0 && im != num; ++im) {
+		ret = iop3xx_handle_msg(i2c_adap, &msgs[im]);
+	}
+
+	iop3xx_adap_transaction_cleanup(iop3xx_adap);
+
+	return ret;   
+}
+
+static int algo_control(struct i2c_adapter *adapter, unsigned int cmd,
+			unsigned long arg)
+{
+	return 0;
+}
+
+static u32 iic_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm iic_algo = {
+	.name		= "IOP3xx I2C algorithm",
+	.id		= I2C_ALGO_OCP_IOP3XX,
+	.master_xfer	= iop3xx_master_xfer,
+	.algo_control	= algo_control,
+	.functionality	= iic_func,
+};
+
+/* 
+ * registering functions to load algorithms at runtime 
+ */
+static int i2c_iop3xx_add_bus(struct i2c_adapter *iic_adap)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
+
+	if (!request_region( REGION_START(iop3xx_adap), 
+			      REGION_LENGTH(iop3xx_adap),
+			      iic_adap->name)) {
+		return -ENODEV;
+	}
+
+	init_waitqueue_head(&iop3xx_adap->waitq);
+	spin_lock_init(&iop3xx_adap->lock);
+
+	if (request_irq( 
+		     iop3xx_adap->biu->irq,
+		     iop3xx_i2c_handler,
+		     /* SA_SAMPLE_RANDOM */ 0,
+		     iic_adap->name,
+		     iop3xx_adap)) {
+		return -ENODEV;
+	}			  
+
+	/* register new iic_adapter to i2c module... */
+	iic_adap->id |= iic_algo.id;
+	iic_adap->algo = &iic_algo;
+
+	iic_adap->timeout = 100;	/* default values, should */
+	iic_adap->retries = 3;		/* be replaced by defines */
+
+	iop3xx_adap_init(iic_adap->algo_data);
+	i2c_add_adapter(iic_adap);
+	return 0;
+}
+
+static int i2c_iop3xx_del_bus(struct i2c_adapter *iic_adap)
+{
+	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
+
+	iop3xx_adap_final_cleanup(iop3xx_adap);
+	free_irq(iop3xx_adap->biu->irq, iop3xx_adap);
+
+	release_region(REGION_START(iop3xx_adap), REGION_LENGTH(iop3xx_adap));
+
+	return i2c_del_adapter(iic_adap);
+}
+
+#ifdef CONFIG_ARCH_IOP321
+
+static struct iop3xx_biu biu0 = {
+	.CR	= IOP321_ICR0,
+	.SR	= IOP321_ISR0,
+	.SAR	= IOP321_ISAR0,
+	.DBR	= IOP321_IDBR0,
+	.BMR	= IOP321_IBMR0,
+	.irq	= IRQ_IOP321_I2C_0,
+};
+
+static struct iop3xx_biu biu1 = {
+	.CR	= IOP321_ICR1,
+	.SR	= IOP321_ISR1,
+	.SAR	= IOP321_ISAR1,
+	.DBR	= IOP321_IDBR1,
+	.BMR	= IOP321_IBMR1,
+	.irq	= IRQ_IOP321_I2C_1,
+};
+
+#define ADAPTER_NAME_ROOT "IOP321 i2c biu adapter "
+#else
+#error Please define the BIU struct iop3xx_biu for your processor arch
+#endif
+
+static struct i2c_algo_iop3xx_data algo_iop3xx_data0 = {
+	.channel		= 0,
+	.biu			= &biu0,
+	.timeout		= 1*HZ,
+};
+static struct i2c_algo_iop3xx_data algo_iop3xx_data1 = {
+	.channel		= 1,
+	.biu			= &biu1,
+	.timeout		= 1*HZ,
+};
+
+static struct i2c_adapter iop3xx_ops0 = {
+	.owner			= THIS_MODULE,
+	.name			= ADAPTER_NAME_ROOT "0",
+	.id			= I2C_HW_IOP321,
+	.algo_data		= &algo_iop3xx_data0,
+};
+static struct i2c_adapter iop3xx_ops1 = {
+	.owner			= THIS_MODULE,
+	.name			= ADAPTER_NAME_ROOT "1",
+	.id			= I2C_HW_IOP321,
+	.algo_data		= &algo_iop3xx_data1,
+};
+
+static int __init i2c_iop3xx_init (void)
+{
+	return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
+		i2c_iop3xx_add_bus(&iop3xx_ops1);
+}
+
+static void __exit i2c_iop3xx_exit (void)
+{
+	i2c_iop3xx_del_bus(&iop3xx_ops0);
+	i2c_iop3xx_del_bus(&iop3xx_ops1);
+}
+
+module_init (i2c_iop3xx_init);
+module_exit (i2c_iop3xx_exit);
+
+MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
+MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(i2c_debug,"i");
+
+MODULE_PARM_DESC(i2c_debug, "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
+
diff -Nru a/drivers/i2c/busses/i2c-iop3xx.h b/drivers/i2c/busses/i2c-iop3xx.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-iop3xx.h	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,118 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-iop3xx.h algorithm driver definitions private to i2c-iop3xx.c         */
+/* ------------------------------------------------------------------------- */
+/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
+ *                      <Peter dot Milne at D hyphen TACQ dot com>
+
+    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, version 2.
+
+    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.                */
+/* ------------------------------------------------------------------------- */
+
+
+#ifndef I2C_IOP3XX_H
+#define I2C_IOP3XX_H 1
+
+/*
+ * iop321 hardware bit definitions
+ */
+#define IOP321_ICR_FAST_MODE	0x8000	/* 1@0kBps, 0\x100kBps */
+#define IOP321_ICR_UNIT_RESET	0x4000	/* 1=RESET */
+#define IOP321_ICR_SADIE	0x2000	/* 1=Slave Detect Interrupt Enable */
+#define IOP321_ICR_ALDIE	0x1000	/* 1=Arb Loss Detect Interrupt Enable */
+#define IOP321_ICR_SSDIE	0x0800	/* 1=Slave STOP Detect Interrupt Enable */
+#define IOP321_ICR_BERRIE	0x0400	/* 1=Bus Error Interrupt Enable */
+#define IOP321_ICR_RXFULLIE	0x0200	/* 1=Receive Full Interrupt Enable */
+#define IOP321_ICR_TXEMPTYIE	0x0100	/* 1=Transmit Empty Interrupt Enable */
+#define IOP321_ICR_GCD		0x0080	/* 1=General Call Disable */
+/*
+ * IOP321_ICR_GCD: 1 disables response as slave. "This bit must be set
+ * when sending a master mode general call message from the I2C unit"
+ */
+#define IOP321_ICR_UE		0x0040	/* 1=Unit Enable */
+/*
+ * "NOTE: To avoid I2C bus integrity problems, 
+ * the user needs to ensure that the GPIO Output Data Register - 
+ * GPOD bits associated with an I2C port are cleared prior to setting 
+ * the enable bit for that I2C serial port. 
+ * The user prepares to enable I2C port 0 and 
+ * I2C port 1 by clearing GPOD bits 7:6 and GPOD bits 5:4, respectively.
+ */
+#define IOP321_ICR_SCLEN	0x0020	/* 1=SCL enable for master mode */
+#define IOP321_ICR_MABORT	0x0010	/* 1=Send a STOP with no data 
+					 * NB TBYTE must be clear */
+#define IOP321_ICR_TBYTE	0x0008	/* 1=Send/Receive a byte. i2c clears */
+#define IOP321_ICR_NACK		0x0004	/* 1=reply with NACK */
+#define IOP321_ICR_MSTOP	0x0002	/* 1=send a STOP after next data byte */
+#define IOP321_ICR_MSTART	0x0001	/* 1=initiate a START */
+
+
+#define IOP321_ISR_BERRD	0x0400	/* 1=BUS ERROR Detected */
+#define IOP321_ISR_SAD		0x0200	/* 1=Slave ADdress Detected */
+#define IOP321_ISR_GCAD		0x0100	/* 1=General Call Address Detected */
+#define IOP321_ISR_RXFULL	0x0080	/* 1=Receive Full */
+#define IOP321_ISR_TXEMPTY	0x0040	/* 1=Transmit Empty */
+#define IOP321_ISR_ALD		0x0020	/* 1=Arbitration Loss Detected */
+#define IOP321_ISR_SSD		0x0010	/* 1=Slave STOP Detected */
+#define IOP321_ISR_BBUSY	0x0008	/* 1=Bus BUSY */
+#define IOP321_ISR_UNITBUSY	0x0004	/* 1=Unit Busy */
+#define IOP321_ISR_NACK		0x0002	/* 1=Unit Rx or Tx a NACK */
+#define IOP321_ISR_RXREAD	0x0001	/* 1=READ 0=WRITE (R/W bit of slave addr */
+
+#define IOP321_ISR_CLEARBITS	0x07f0
+
+#define IOP321_ISAR_SAMASK	0x007f
+
+#define IOP321_IDBR_MASK	0x00ff
+
+#define IOP321_IBMR_SCL		0x0002
+#define IOP321_IBMR_SDA		0x0001
+
+#define IOP321_GPOD_I2C0	0x00c0	/* clear these bits to enable ch0 */
+#define IOP321_GPOD_I2C1	0x0030	/* clear these bits to enable ch1 */
+
+#define MYSAR			0x02	/* SWAG a suitable slave address */
+
+#define I2C_ERR			321
+#define I2C_ERR_BERR		(I2C_ERR+0)
+#define I2C_ERR_ALD		(I2C_ERR+1)
+
+
+struct iop3xx_biu {                /* Bus Interface Unit - the hardware */
+/* physical hardware defs - regs*/
+	u32 *CR;
+	u32 *SR;
+	u32 *SAR;
+	u32 *DBR;
+	u32 *BMR;
+/* irq bit vector */
+	u32 irq;
+/* stored flags */
+	u32 SR_enabled, SR_received;
+};
+
+struct i2c_algo_iop3xx_data {
+	int channel;
+
+	wait_queue_head_t waitq;
+	spinlock_t lock;
+	int timeout;
+	struct iop3xx_biu* biu;
+};
+
+#define REGION_START(adap)	((u32)((adap)->biu->CR))
+#define REGION_END(adap)	((u32)((adap)->biu->BMR+1))
+#define REGION_LENGTH(adap)	(REGION_END(adap)-REGION_START(adap))
+
+#define IRQ_STATUS_MASK(adap)	(1<<adap->biu->irq)
+
+#endif /* I2C_IOP3XX_H */
diff -Nru a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-ite.c	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,278 @@
+/*
+   -------------------------------------------------------------------------
+   i2c-adap-ite.c i2c-hw access for the IIC peripheral on the ITE MIPS system
+   -------------------------------------------------------------------------
+   Hai-Pao Fan, MontaVista Software, Inc.
+   hpfan@mvista.com or source@mvista.com
+
+   Copyright 2001 MontaVista Software Inc.
+
+   ----------------------------------------------------------------------------
+   This file was highly leveraged from i2c-elektor.c, which was created
+   by Simon G. Vogl and Hans Berglund:
+
+ 
+     Copyright (C) 1995-97 Simon G. Vogl
+                   1998-99 Hans Berglund
+
+    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.		     */
+/* ------------------------------------------------------------------------- */
+
+/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
+   Frodo Looijaard <frodol@dds.nl> */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-ite.h>
+#include <linux/i2c-adap-ite.h>
+#include "../i2c-ite.h"
+
+#define DEFAULT_BASE  0x14014030
+#define ITE_IIC_IO_SIZE	0x40
+#define DEFAULT_IRQ   0
+#define DEFAULT_CLOCK 0x1b0e	/* default 16MHz/(27+14) = 400KHz */
+#define DEFAULT_OWN   0x55
+
+static int base  = 0;
+static int irq   = 0;
+static int clock = 0;
+static int own   = 0;
+
+static int i2c_debug=0;
+static struct iic_ite gpi;
+static wait_queue_head_t iic_wait;
+static int iic_pending;
+
+/* ----- global defines -----------------------------------------------	*/
+#define DEB(x)	if (i2c_debug>=1) x
+#define DEB2(x) if (i2c_debug>=2) x
+#define DEB3(x) if (i2c_debug>=3) x
+#define DEBE(x)	x	/* error messages 				*/
+
+
+/* ----- local functions ----------------------------------------------	*/
+
+static void iic_ite_setiic(void *data, int ctl, short val)
+{
+        unsigned long j = jiffies + 10;
+
+	DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff));
+	DEB3({while (time_before(jiffies, j)) schedule();})
+	outw(val,ctl);
+}
+
+static short iic_ite_getiic(void *data, int ctl)
+{
+	short val;
+
+	val = inw(ctl);
+	DEB3(printk("Read 0x%02x from 0x%x\n",(unsigned short)val, ctl&0xff));  
+	return (val);
+}
+
+/* Return our slave address.  This is the address
+ * put on the I2C bus when another master on the bus wants to address us
+ * as a slave
+ */
+static int iic_ite_getown(void *data)
+{
+	return (gpi.iic_own);
+}
+
+
+static int iic_ite_getclock(void *data)
+{
+	return (gpi.iic_clock);
+}
+
+
+#if 0
+static void iic_ite_sleep(unsigned long timeout)
+{
+	schedule_timeout( timeout * HZ);
+}
+#endif
+
+
+/* Put this process to sleep.  We will wake up when the
+ * IIC controller interrupts.
+ */
+static void iic_ite_waitforpin(void) {
+
+   int timeout = 2;
+
+   /* If interrupts are enabled (which they are), then put the process to
+    * sleep.  This process will be awakened by two events -- either the
+    * the IIC peripheral interrupts or the timeout expires. 
+    * If interrupts are not enabled then delay for a reasonable amount 
+    * of time and return.
+    */
+   if (gpi.iic_irq > 0) {
+	cli();
+	if (iic_pending = 0) {
+		interruptible_sleep_on_timeout(&iic_wait, timeout*HZ );
+	} else
+		iic_pending = 0;
+	sti();
+   } else {
+      udelay(100);
+   }
+}
+
+
+static void iic_ite_handler(int this_irq, void *dev_id, struct pt_regs *regs) 
+{
+	
+   iic_pending = 1;
+
+   DEB2(printk("iic_ite_handler: in interrupt handler\n"));
+   wake_up_interruptible(&iic_wait);
+}
+
+
+/* Lock the region of memory where I/O registers exist.  Request our
+ * interrupt line and register its associated handler.
+ */
+static int iic_hw_resrc_init(void)
+{
+	if (!request_region(gpi.iic_base, ITE_IIC_IO_SIZE, "i2c"))
+		return -ENODEV;
+  
+	if (gpi.iic_irq <= 0)
+		return 0;
+
+	if (request_irq(gpi.iic_irq, iic_ite_handler, 0, "ITE IIC", 0) < 0)
+		gpi.iic_irq = 0;
+	else
+		enable_irq(gpi.iic_irq);
+
+	return 0;
+}
+
+
+static void iic_ite_release(void)
+{
+	if (gpi.iic_irq > 0) {
+		disable_irq(gpi.iic_irq);
+		free_irq(gpi.iic_irq, 0);
+	}
+	release_region(gpi.iic_base , 2);
+}
+
+/* ------------------------------------------------------------------------
+ * Encapsulate the above functions in the correct operations structure.
+ * This is only done when more than one hardware adapter is supported.
+ */
+static struct i2c_algo_iic_data iic_ite_data = {
+	NULL,
+	iic_ite_setiic,
+	iic_ite_getiic,
+	iic_ite_getown,
+	iic_ite_getclock,
+	iic_ite_waitforpin,
+	80, 80, 100,		/*	waits, timeout */
+};
+
+static struct i2c_adapter iic_ite_ops = {
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_I_IIC,
+	.algo_data	= &iic_ite_data,
+	.dev		= {
+		.name	= "ITE IIC adapter",
+	},
+};
+
+/* Called when the module is loaded.  This function starts the
+ * cascade of calls up through the hierarchy of i2c modules (i.e. up to the
+ *  algorithm layer and into to the core layer)
+ */
+static int __init iic_ite_init(void) 
+{
+
+	struct iic_ite *piic = &gpi;
+
+	printk(KERN_INFO "Initialize ITE IIC adapter module\n");
+	if (base = 0)
+		piic->iic_base = DEFAULT_BASE;
+	else
+		piic->iic_base = base;
+
+	if (irq = 0)
+		piic->iic_irq = DEFAULT_IRQ;
+	else
+		piic->iic_irq = irq;
+
+	if (clock = 0)
+		piic->iic_clock = DEFAULT_CLOCK;
+	else
+		piic->iic_clock = clock;
+
+	if (own = 0)
+		piic->iic_own = DEFAULT_OWN;
+	else
+		piic->iic_own = own;
+
+	iic_ite_data.data = (void *)piic;
+	init_waitqueue_head(&iic_wait);
+	if (iic_hw_resrc_init() = 0) {
+		if (i2c_iic_add_bus(&iic_ite_ops) < 0)
+			return -ENODEV;
+	} else {
+		return -ENODEV;
+	}
+	printk(KERN_INFO " found device at %#x irq %d.\n", 
+		piic->iic_base, piic->iic_irq);
+	return 0;
+}
+
+
+static void iic_ite_exit(void)
+{
+	i2c_iic_del_bus(&iic_ite_ops);
+        iic_ite_release();
+}
+
+/* If modules is NOT defined when this file is compiled, then the MODULE_*
+ * macros will resolve to nothing
+ */
+MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(base, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(clock, "i");
+MODULE_PARM(own, "i");
+MODULE_PARM(i2c_debug,"i");
+
+
+/* Called when module is loaded or when kernel is initialized.
+ * If MODULES is defined when this file is compiled, then this function will
+ * resolve to init_module (the function called when insmod is invoked for a
+ * module).  Otherwise, this function is called early in the boot, when the
+ * kernel is intialized.  Check out /include/init.h to see how this works.
+ */
+module_init(iic_ite_init);
+
+/* Resolves to module_cleanup when MODULES is defined. */
+module_exit(iic_ite_exit); 
diff -Nru a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-keywest.c	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,653 @@
+/*
+    i2c Support for Apple Keywest I2C Bus Controller
+
+    Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+
+    Original work by
+    
+    Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+
+    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.
+
+    Changes:
+
+    2001/12/13 BenH	New implementation
+    2001/12/15 BenH	Add support for "byte" and "quick"
+                        transfers. Add i2c_xfer routine.
+
+    My understanding of the various modes supported by keywest are:
+
+     - Dumb mode : not implemented, probably direct tweaking of lines
+     - Standard mode : simple i2c transaction of type
+         S Addr R/W A Data A Data ... T
+     - Standard sub mode : combined 8 bit subaddr write with data read
+         S Addr R/W A SubAddr A Data A Data ... T
+     - Combined mode : Subaddress and Data sequences appended with no stop
+         S Addr R/W A SubAddr S Addr R/W A Data A Data ... T
+
+    Currently, this driver uses only Standard mode for i2c xfer, and
+    smbus byte & quick transfers ; and uses StandardSub mode for
+    other smbus transfers instead of combined as we need that for the
+    sound driver to be happy
+*/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+
+#include "i2c-keywest.h"
+
+#define DBG(x...) do {\
+	if (debug > 0) \
+		printk(KERN_DEBUG "KW:" x); \
+	} while(0)
+
+
+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
+MODULE_DESCRIPTION("I2C driver for Apple's Keywest");
+MODULE_LICENSE("GPL");
+MODULE_PARM(probe, "i");
+MODULE_PARM(debug, "i");
+
+int probe = 0;
+int debug = 0;
+
+static void
+do_stop(struct keywest_iface* iface, int result)
+{
+	write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_STOP);
+	iface->state = state_stop;
+	iface->result = result;
+}
+
+/* Main state machine for standard & standard sub mode */
+static int
+handle_interrupt(struct keywest_iface *iface, u8 isr)
+{
+	int ack;
+	int rearm_timer = 1;
+	
+	DBG("handle_interrupt(), got: %x, status: %x, state: %d\n",
+		isr, read_reg(reg_status), iface->state);
+	if (isr = 0 && iface->state != state_stop) {
+		do_stop(iface, -1);
+		return rearm_timer;
+	}
+	if (isr & KW_I2C_IRQ_STOP && iface->state != state_stop) {
+		iface->result = -1;
+		iface->state = state_stop;
+	}
+	switch(iface->state) {
+	case state_addr:
+		if (!(isr & KW_I2C_IRQ_ADDR)) {
+			do_stop(iface, -1);
+			break;
+		}
+		ack = read_reg(reg_status);
+		DBG("ack on set address: %x\n", ack);
+		if ((ack & KW_I2C_STAT_LAST_AAK) = 0) {
+			do_stop(iface, -1);
+			break;
+		}
+		/* Handle rw "quick" mode */
+		if (iface->datalen = 0)
+			do_stop(iface, 0);
+		else if (iface->read_write = I2C_SMBUS_READ) {
+			iface->state = state_read;
+			if (iface->datalen > 1)
+				write_reg(reg_control, read_reg(reg_control)
+					| KW_I2C_CTL_AAK);
+		} else {
+			iface->state = state_write;
+			DBG("write byte: %x\n", *(iface->data));
+			write_reg(reg_data, *(iface->data++));
+			iface->datalen--;
+		}
+		
+		break;
+	case state_read:
+		if (!(isr & KW_I2C_IRQ_DATA)) {
+			do_stop(iface, -1);
+			break;
+		}
+		*(iface->data++) = read_reg(reg_data);
+		DBG("read byte: %x\n", *(iface->data-1));
+		iface->datalen--;
+		if (iface->datalen = 0)
+			iface->state = state_stop;
+		else
+			write_reg(reg_control, 0);
+		break;
+	case state_write:
+		if (!(isr & KW_I2C_IRQ_DATA)) {
+			do_stop(iface, -1);
+			break;
+		}
+		/* Check ack status */
+		ack = read_reg(reg_status);
+		DBG("ack on data write: %x\n", ack);
+		if ((ack & KW_I2C_STAT_LAST_AAK) = 0) {
+			do_stop(iface, -1);
+			break;
+		}
+		if (iface->datalen) {
+			DBG("write byte: %x\n", *(iface->data));
+			write_reg(reg_data, *(iface->data++));
+			iface->datalen--;
+		} else
+			do_stop(iface, 0);
+		break;
+		
+	case state_stop:
+		if (!(isr & KW_I2C_IRQ_STOP) && (++iface->stopretry) < 10)
+			do_stop(iface, -1);
+		else {
+			rearm_timer = 0;
+			iface->state = state_idle;
+			write_reg(reg_control, 0x00);
+			write_reg(reg_ier, 0x00);
+			complete(&iface->complete);
+		}
+		break;
+	}
+	
+	write_reg(reg_isr, isr);
+
+	return rearm_timer;
+}
+
+/* Interrupt handler */
+static irqreturn_t
+keywest_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct keywest_iface *iface = (struct keywest_iface *)dev_id;
+
+	spin_lock(&iface->lock);
+	del_timer(&iface->timeout_timer);
+	if (handle_interrupt(iface, read_reg(reg_isr)))
+		mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
+	spin_unlock(&iface->lock);
+	return IRQ_HANDLED;
+}
+
+static void
+keywest_timeout(unsigned long data)
+{
+	struct keywest_iface *iface = (struct keywest_iface *)data;
+
+	DBG("timeout !\n");
+	spin_lock_irq(&iface->lock);
+	if (handle_interrupt(iface, read_reg(reg_isr)))
+		mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
+	spin_unlock(&iface->lock);
+}
+
+/*
+ * SMBUS-type transfer entrypoint
+ */
+static s32
+keywest_smbus_xfer(	struct i2c_adapter*	adap,
+			u16			addr,
+			unsigned short		flags,
+			char			read_write,
+			u8			command,
+			int			size,
+			union i2c_smbus_data*	data)
+{
+	struct keywest_chan* chan = i2c_get_adapdata(adap);
+	struct keywest_iface* iface = chan->iface;
+	int len;
+	u8* buffer;
+	u16 cur_word;
+	int rc = 0;
+
+	if (iface->state = state_dead)
+		return -1;
+		
+	/* Prepare datas & select mode */
+	iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
+	switch (size) {
+	    case I2C_SMBUS_QUICK:
+	    	len = 0;
+	    	buffer = NULL;
+	    	iface->cur_mode |= KW_I2C_MODE_STANDARD;
+	    	break;
+	    case I2C_SMBUS_BYTE:
+	    	len = 1;
+	    	buffer = &data->byte;
+	    	iface->cur_mode |= KW_I2C_MODE_STANDARD;
+	    	break;
+	    case I2C_SMBUS_BYTE_DATA:
+	    	len = 1;
+	    	buffer = &data->byte;
+	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
+	    	break;
+	    case I2C_SMBUS_WORD_DATA:
+	    	len = 2;
+	    	cur_word = cpu_to_le16(data->word);
+	    	buffer = (u8 *)&cur_word;
+	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
+		break;
+	    case I2C_SMBUS_BLOCK_DATA:
+	    	len = data->block[0];
+	    	buffer = &data->block[1];
+	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
+		break;
+	    default:
+	    	return -1;
+	}
+
+	/* Original driver had this limitation */
+	if (len > 32)
+		len = 32;
+
+	down(&iface->sem);
+
+	DBG("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n",
+		chan->chan_no, addr, len, read_write = I2C_SMBUS_READ);
+
+	iface->data = buffer;
+	iface->datalen = len;
+	iface->state = state_addr;
+	iface->result = 0;
+	iface->stopretry = 0;
+	iface->read_write = read_write;
+	
+	/* Setup channel & clear pending irqs */
+	write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
+	write_reg(reg_isr, read_reg(reg_isr));
+	write_reg(reg_status, 0);
+
+	/* Set up address and r/w bit */
+	write_reg(reg_addr,
+		(addr << 1) | ((read_write = I2C_SMBUS_READ) ? 0x01 : 0x00));
+
+	/* Set up the sub address */
+	if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) = KW_I2C_MODE_STANDARDSUB
+	    || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) = KW_I2C_MODE_COMBINED)
+		write_reg(reg_subaddr, command);
+
+	/* Arm timeout */
+	mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
+
+	/* Start sending address & enable interrupt*/
+	write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR);
+	write_reg(reg_ier, KW_I2C_IRQ_MASK);
+
+	/* Wait interrupt operations completion */
+	wait_for_completion(&iface->complete);	
+
+	rc = iface->result;	
+	DBG("transfer done, result: %d\n", rc);
+
+	if (rc = 0 && size = I2C_SMBUS_WORD_DATA && read_write = I2C_SMBUS_READ)
+	    	data->word = le16_to_cpu(cur_word);
+	
+	/* Release sem */
+	up(&iface->sem);
+	
+	return rc;
+}
+
+/*
+ * Generic i2c master transfer entrypoint
+ */
+static int
+keywest_xfer(	struct i2c_adapter *adap,
+		struct i2c_msg msgs[], 
+		int num)
+{
+	struct keywest_chan* chan = i2c_get_adapdata(adap);
+	struct keywest_iface* iface = chan->iface;
+	struct i2c_msg *pmsg;
+	int i, completed;
+	int rc = 0;
+
+	down(&iface->sem);
+
+	/* Set adapter to standard mode */
+	iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
+	iface->cur_mode |= KW_I2C_MODE_STANDARD;
+
+	completed = 0;
+	for (i = 0; rc >= 0 && i < num;) {
+		u8 addr;
+		
+		pmsg = &msgs[i++];
+		addr = pmsg->addr;
+		if (pmsg->flags & I2C_M_TEN) {
+			printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n");
+			rc = -EINVAL;
+			break;
+		}
+		DBG("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n",
+		     chan->chan_no,
+		     pmsg->flags & I2C_M_RD ? "read" : "write",
+                     pmsg->len, addr, i, num);
+    
+		/* Setup channel & clear pending irqs */
+		write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
+		write_reg(reg_isr, read_reg(reg_isr));
+		write_reg(reg_status, 0);
+		
+		iface->data = pmsg->buf;
+		iface->datalen = pmsg->len;
+		iface->state = state_addr;
+		iface->result = 0;
+		iface->stopretry = 0;
+		if (pmsg->flags & I2C_M_RD)
+			iface->read_write = I2C_SMBUS_READ;
+		else
+			iface->read_write = I2C_SMBUS_WRITE;
+
+		/* Set up address and r/w bit */
+		if (pmsg->flags & I2C_M_REV_DIR_ADDR)
+			addr ^= 1;		
+		write_reg(reg_addr,
+			(addr << 1) |
+			((iface->read_write = I2C_SMBUS_READ) ? 0x01 : 0x00));
+
+		/* Arm timeout */
+		mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
+
+		/* Start sending address & enable interrupt*/
+		write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR);
+		write_reg(reg_ier, KW_I2C_IRQ_MASK);
+
+		/* Wait interrupt operations completion */
+		wait_for_completion(&iface->complete);	
+
+		rc = iface->result;
+		if (rc = 0)
+			completed++;
+		DBG("transfer done, result: %d\n", rc);
+	}
+
+	/* Release sem */
+	up(&iface->sem);
+
+	return completed;
+}
+
+static u32
+keywest_func(struct i2c_adapter * adapter)
+{
+	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
+	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
+	       I2C_FUNC_SMBUS_BLOCK_DATA;
+}
+
+/* For now, we only handle combined mode (smbus) */
+static struct i2c_algorithm keywest_algorithm = {
+	.name		= "Keywest i2c",
+	.id		= I2C_ALGO_SMBUS,
+	.smbus_xfer	= keywest_smbus_xfer,
+	.master_xfer	= keywest_xfer,
+	.functionality	= keywest_func,
+};
+
+
+static int
+create_iface(struct device_node *np, struct device *dev)
+{
+	unsigned long steps, *psteps, *prate;
+	unsigned bsteps, tsize, i, nchan, addroffset;
+	struct keywest_iface* iface;
+	int rc;
+
+	psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL);
+	steps = psteps ? (*psteps) : 0x10;
+
+	/* Hrm... maybe we can be smarter here */
+	for (bsteps = 0; (steps & 0x01) = 0; bsteps++)
+		steps >>= 1;
+
+	if (!strcmp(np->parent->name, "uni-n")) {
+		nchan = 2;
+		addroffset = 3;
+	} else {
+		addroffset = 0;
+		nchan = 1;
+	}
+
+	tsize = sizeof(struct keywest_iface) +
+		(sizeof(struct keywest_chan) + 4) * nchan;
+	iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL);
+	if (iface = NULL) {
+		printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n");
+		return -ENOMEM;
+	}
+	memset(iface, 0, tsize);
+	init_MUTEX(&iface->sem);
+	spin_lock_init(&iface->lock);
+	init_completion(&iface->complete);
+	iface->bsteps = bsteps;
+	iface->chan_count = nchan;
+	iface->state = state_idle;
+	iface->irq = np->intrs[0].line;
+	iface->channels = (struct keywest_chan *)
+		(((unsigned long)(iface + 1) + 3UL) & ~3UL);
+	iface->base = (unsigned long)ioremap(np->addrs[0].address + addroffset,
+						np->addrs[0].size);
+	if (iface->base = 0) {
+		printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
+		kfree(iface);
+		return -ENOMEM;
+	}
+
+	init_timer(&iface->timeout_timer);
+	iface->timeout_timer.function = keywest_timeout;
+	iface->timeout_timer.data = (unsigned long)iface;
+
+	/* Select interface rate */
+	iface->cur_mode = KW_I2C_MODE_100KHZ;
+	prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL);
+	if (prate) switch(*prate) {
+	case 100:
+		iface->cur_mode = KW_I2C_MODE_100KHZ;
+		break;
+	case 50:
+		iface->cur_mode = KW_I2C_MODE_50KHZ;
+		break;
+	case 25:
+		iface->cur_mode = KW_I2C_MODE_25KHZ;
+		break;
+	default:
+		printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n",
+			*prate);
+	}
+	
+	/* Select standard sub mode */
+	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
+	
+	/* Write mode */
+	write_reg(reg_mode, iface->cur_mode);
+	
+	/* Switch interrupts off & clear them*/
+	write_reg(reg_ier, 0x00);
+	write_reg(reg_isr, KW_I2C_IRQ_MASK);
+
+	/* Request chip interrupt */	
+	rc = request_irq(iface->irq, keywest_irq, 0, "keywest i2c", iface);
+	if (rc) {
+		printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq);
+		iounmap((void *)iface->base);
+		kfree(iface);
+		return -ENODEV;
+	}
+
+	dev_set_drvdata(dev, iface);
+	
+	for (i=0; i<nchan; i++) {
+		struct keywest_chan* chan = &iface->channels[i];
+		u8 addr;
+		
+		sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
+		chan->iface = iface;
+		chan->chan_no = i;
+		chan->adapter.id = I2C_ALGO_SMBUS;
+		chan->adapter.algo = &keywest_algorithm;
+		chan->adapter.algo_data = NULL;
+		chan->adapter.client_register = NULL;
+		chan->adapter.client_unregister = NULL;
+		i2c_set_adapdata(&chan->adapter, chan);
+		chan->adapter.dev.parent = dev;
+
+		rc = i2c_add_adapter(&chan->adapter);
+		if (rc) {
+			printk("i2c-keywest.c: Adapter %s registration failed\n",
+				chan->adapter.name);
+			i2c_set_adapdata(&chan->adapter, NULL);
+		}
+		if (probe) {
+			printk("Probe: ");
+			for (addr = 0x00; addr <= 0x7f; addr++) {
+				if (i2c_smbus_xfer(&chan->adapter,addr,
+				    0,0,0,I2C_SMBUS_QUICK,NULL) >= 0)
+					printk("%02x ", addr);
+			}
+			printk("\n");
+		}
+	}
+
+	printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n",
+		np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps);
+		
+	return 0;
+}
+
+static int
+dispose_iface(struct device *dev)
+{
+	struct keywest_iface *iface = dev_get_drvdata(dev);
+	int i, rc;
+	
+	/* Make sure we stop all activity */
+	down(&iface->sem);
+
+	spin_lock_irq(&iface->lock);
+	while (iface->state != state_idle) {
+		spin_unlock_irq(&iface->lock);
+		set_task_state(current,TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ/10);
+		spin_lock_irq(&iface->lock);
+	}
+	iface->state = state_dead;
+	spin_unlock_irq(&iface->lock);
+	free_irq(iface->irq, iface);
+	up(&iface->sem);
+
+	/* Release all channels */
+	for (i=0; i<iface->chan_count; i++) {
+		struct keywest_chan* chan = &iface->channels[i];
+		if (i2c_get_adapdata(&chan->adapter) = NULL)
+			continue;
+		rc = i2c_del_adapter(&chan->adapter);
+		i2c_set_adapdata(&chan->adapter, NULL);
+		/* We aren't that prepared to deal with this... */
+		if (rc)
+			printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n");
+	}
+	iounmap((void *)iface->base);
+	dev_set_drvdata(dev, NULL);
+	kfree(iface);
+
+	return 0;
+}
+
+static int
+create_iface_macio(struct macio_dev* dev, const struct of_match *match)
+{
+	return create_iface(dev->ofdev.node, &dev->ofdev.dev);
+}
+
+static int
+dispose_iface_macio(struct macio_dev* dev)
+{
+	return dispose_iface(&dev->ofdev.dev);
+}
+
+static int
+create_iface_of_platform(struct of_device* dev, const struct of_match *match)
+{
+	return create_iface(dev->node, &dev->dev);
+}
+
+static int
+dispose_iface_of_platform(struct of_device* dev)
+{
+	return dispose_iface(&dev->dev);
+}
+
+static struct of_match i2c_keywest_match[] = 
+{
+	{
+	.name 		= OF_ANY_MATCH,
+	.type		= "i2c",
+	.compatible	= "keywest"
+	},
+	{},
+};
+
+static struct macio_driver i2c_keywest_macio_driver = 
+{
+	.name 		= "i2c-keywest",
+	.match_table	= i2c_keywest_match,
+	.probe		= create_iface_macio,
+	.remove		= dispose_iface_macio
+};
+
+static struct of_platform_driver i2c_keywest_of_platform_driver = 
+{
+	.name 		= "i2c-keywest",
+	.match_table	= i2c_keywest_match,
+	.probe		= create_iface_of_platform,
+	.remove		= dispose_iface_of_platform
+};
+
+static int __init
+i2c_keywest_init(void)
+{
+	macio_register_driver(&i2c_keywest_macio_driver);
+	of_register_driver(&i2c_keywest_of_platform_driver);
+
+	return 0;
+}
+
+static void __exit
+i2c_keywest_cleanup(void)
+{
+	macio_unregister_driver(&i2c_keywest_macio_driver);
+	of_unregister_driver(&i2c_keywest_of_platform_driver);
+}
+
+module_init(i2c_keywest_init);
+module_exit(i2c_keywest_cleanup);
diff -Nru a/drivers/i2c/busses/i2c-keywest.h b/drivers/i2c/busses/i2c-keywest.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-keywest.h	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,110 @@
+#ifndef __I2C_KEYWEST_H__
+#define __I2C_KEYWEST_H__
+
+/* The Tumbler audio equalizer can be really slow sometimes */
+#define POLL_TIMEOUT		(2*HZ)
+
+/* Register indices */
+typedef enum {
+	reg_mode = 0,
+	reg_control,
+	reg_status,
+	reg_isr,
+	reg_ier,
+	reg_addr,
+	reg_subaddr,
+	reg_data
+} reg_t;
+
+
+/* Mode register */
+#define KW_I2C_MODE_100KHZ	0x00
+#define KW_I2C_MODE_50KHZ	0x01
+#define KW_I2C_MODE_25KHZ	0x02
+#define KW_I2C_MODE_DUMB	0x00
+#define KW_I2C_MODE_STANDARD	0x04
+#define KW_I2C_MODE_STANDARDSUB	0x08
+#define KW_I2C_MODE_COMBINED	0x0C
+#define KW_I2C_MODE_MODE_MASK	0x0C
+#define KW_I2C_MODE_CHAN_MASK	0xF0
+
+/* Control register */
+#define KW_I2C_CTL_AAK		0x01
+#define KW_I2C_CTL_XADDR	0x02
+#define KW_I2C_CTL_STOP		0x04
+#define KW_I2C_CTL_START	0x08
+
+/* Status register */
+#define KW_I2C_STAT_BUSY	0x01
+#define KW_I2C_STAT_LAST_AAK	0x02
+#define KW_I2C_STAT_LAST_RW	0x04
+#define KW_I2C_STAT_SDA		0x08
+#define KW_I2C_STAT_SCL		0x10
+
+/* IER & ISR registers */
+#define KW_I2C_IRQ_DATA		0x01
+#define KW_I2C_IRQ_ADDR		0x02
+#define KW_I2C_IRQ_STOP		0x04
+#define KW_I2C_IRQ_START	0x08
+#define KW_I2C_IRQ_MASK		0x0F
+
+/* Physical interface */
+struct keywest_iface
+{
+	unsigned long		base;
+	unsigned		bsteps;
+	int			irq;
+	struct semaphore	sem;
+	spinlock_t		lock;
+	struct keywest_chan*	channels;
+	unsigned		chan_count;
+	u8			cur_mode;
+	char			read_write;
+	u8*			data;
+	unsigned		datalen;
+	int			state;
+	int			result;
+	int			stopretry;
+	struct timer_list	timeout_timer;
+	struct completion	complete;
+};
+
+enum {
+	state_idle,
+	state_addr,
+	state_read,
+	state_write,
+	state_stop,
+	state_dead
+};
+
+/* Channel on an interface */
+struct keywest_chan
+{
+	struct i2c_adapter	adapter;
+	struct keywest_iface*	iface;
+	unsigned		chan_no;
+};
+
+/* Register access */
+
+static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg)
+{
+	return in_8(((volatile u8 *)iface->base)
+		+ (((unsigned)reg) << iface->bsteps));
+}
+
+static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val)
+{
+	out_8(((volatile u8 *)iface->base)
+		+ (((unsigned)reg) << iface->bsteps), val);
+	(void)__read_reg(iface, reg);
+	udelay(10);
+}
+
+#define write_reg(reg, val)	__write_reg(iface, reg, val) 
+#define read_reg(reg)		__read_reg(iface, reg) 
+
+
+
+#endif /* __I2C_KEYWEST_H__ */
diff -Nru a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/busses/i2c-rpx.c	Mon Sep 22 16:12:05 2003
@@ -0,0 +1,103 @@
+/*
+ * Embedded Planet RPX Lite MPC8xx CPM I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update:  There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any 8xx board.  The console messages have been 
+ * changed to eliminate RPXLite references.
+ */
+
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/parport.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-8xx.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+
+static void
+rpx_iic_init(struct i2c_algo_8xx_data *data)
+{
+	volatile cpm8xx_t *cp;
+	volatile immap_t *immap;
+
+	cp = cpmp;	/* Get pointer to Communication Processor */
+	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */
+
+	data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+
+	/* Check for and use a microcode relocation patch.
+	*/
+	if ((data->reloc = data->iip->iic_rpbase))
+		data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase];
+		
+	data->i2c = (i2c8xx_t *)&(immap->im_i2c);
+	data->cp = cp;
+
+	/* Initialize Port B IIC pins.
+	*/
+	cp->cp_pbpar |= 0x00000030;
+	cp->cp_pbdir |= 0x00000030;
+	cp->cp_pbodr |= 0x00000030;
+
+	/* Allocate space for two transmit and two receive buffer
+	 * descriptors in the DP ram.
+	 */
+	data->dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 4);
+
+	/* ptr to i2c area */
+	data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
+}
+
+static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data)
+{
+	/* install interrupt handler */
+	cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data);
+
+	return 0;
+}
+
+static struct i2c_algo_8xx_data rpx_data = {
+	.setisr = rpx_install_isr
+};
+
+static struct i2c_adapter rpx_ops = {
+	.owner		= THIS_MODULE,
+	.name		= "m8xx",
+	.id		= I2C_HW_MPC8XX_EPON,
+	.algo_data	= &rpx_data,
+};
+
+int __init i2c_rpx_init(void)
+{
+	printk("i2c-rpx.o: i2c MPC8xx module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+
+	/* reset hardware to sane state */
+	rpx_iic_init(&rpx_data);
+
+	if (i2c_8xx_add_bus(&rpx_ops) < 0) {
+		printk("i2c-rpx: Unable to register with I2C\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+void __exit i2c_rpx_exit(void)
+{
+	i2c_8xx_del_bus(&rpx_ops);
+}
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
+
+module_init(i2c_rpx_init);
+module_exit(i2c_rpx_exit);
diff -Nru a/drivers/i2c/i2c-adap-ite.c b/drivers/i2c/i2c-adap-ite.c
--- a/drivers/i2c/i2c-adap-ite.c	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,278 +0,0 @@
-/*
-   -------------------------------------------------------------------------
-   i2c-adap-ite.c i2c-hw access for the IIC peripheral on the ITE MIPS system
-   -------------------------------------------------------------------------
-   Hai-Pao Fan, MontaVista Software, Inc.
-   hpfan@mvista.com or source@mvista.com
-
-   Copyright 2001 MontaVista Software Inc.
-
-   ----------------------------------------------------------------------------
-   This file was highly leveraged from i2c-elektor.c, which was created
-   by Simon G. Vogl and Hans Berglund:
-
- 
-     Copyright (C) 1995-97 Simon G. Vogl
-                   1998-99 Hans Berglund
-
-    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.		     */
-/* ------------------------------------------------------------------------- */
-
-/* With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> and even
-   Frodo Looijaard <frodol@dds.nl> */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-ite.h>
-#include <linux/i2c-adap-ite.h>
-#include "i2c-ite.h"
-
-#define DEFAULT_BASE  0x14014030
-#define ITE_IIC_IO_SIZE	0x40
-#define DEFAULT_IRQ   0
-#define DEFAULT_CLOCK 0x1b0e	/* default 16MHz/(27+14) = 400KHz */
-#define DEFAULT_OWN   0x55
-
-static int base  = 0;
-static int irq   = 0;
-static int clock = 0;
-static int own   = 0;
-
-static int i2c_debug=0;
-static struct iic_ite gpi;
-static wait_queue_head_t iic_wait;
-static int iic_pending;
-
-/* ----- global defines -----------------------------------------------	*/
-#define DEB(x)	if (i2c_debug>=1) x
-#define DEB2(x) if (i2c_debug>=2) x
-#define DEB3(x) if (i2c_debug>=3) x
-#define DEBE(x)	x	/* error messages 				*/
-
-
-/* ----- local functions ----------------------------------------------	*/
-
-static void iic_ite_setiic(void *data, int ctl, short val)
-{
-        unsigned long j = jiffies + 10;
-
-	DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff));
-	DEB3({while (time_before(jiffies, j)) schedule();})
-	outw(val,ctl);
-}
-
-static short iic_ite_getiic(void *data, int ctl)
-{
-	short val;
-
-	val = inw(ctl);
-	DEB3(printk("Read 0x%02x from 0x%x\n",(unsigned short)val, ctl&0xff));  
-	return (val);
-}
-
-/* Return our slave address.  This is the address
- * put on the I2C bus when another master on the bus wants to address us
- * as a slave
- */
-static int iic_ite_getown(void *data)
-{
-	return (gpi.iic_own);
-}
-
-
-static int iic_ite_getclock(void *data)
-{
-	return (gpi.iic_clock);
-}
-
-
-#if 0
-static void iic_ite_sleep(unsigned long timeout)
-{
-	schedule_timeout( timeout * HZ);
-}
-#endif
-
-
-/* Put this process to sleep.  We will wake up when the
- * IIC controller interrupts.
- */
-static void iic_ite_waitforpin(void) {
-
-   int timeout = 2;
-
-   /* If interrupts are enabled (which they are), then put the process to
-    * sleep.  This process will be awakened by two events -- either the
-    * the IIC peripheral interrupts or the timeout expires. 
-    * If interrupts are not enabled then delay for a reasonable amount 
-    * of time and return.
-    */
-   if (gpi.iic_irq > 0) {
-	cli();
-	if (iic_pending = 0) {
-		interruptible_sleep_on_timeout(&iic_wait, timeout*HZ );
-	} else
-		iic_pending = 0;
-	sti();
-   } else {
-      udelay(100);
-   }
-}
-
-
-static void iic_ite_handler(int this_irq, void *dev_id, struct pt_regs *regs) 
-{
-	
-   iic_pending = 1;
-
-   DEB2(printk("iic_ite_handler: in interrupt handler\n"));
-   wake_up_interruptible(&iic_wait);
-}
-
-
-/* Lock the region of memory where I/O registers exist.  Request our
- * interrupt line and register its associated handler.
- */
-static int iic_hw_resrc_init(void)
-{
-	if (!request_region(gpi.iic_base, ITE_IIC_IO_SIZE, "i2c"))
-		return -ENODEV;
-  
-	if (gpi.iic_irq <= 0)
-		return 0;
-
-	if (request_irq(gpi.iic_irq, iic_ite_handler, 0, "ITE IIC", 0) < 0)
-		gpi.iic_irq = 0;
-	else
-		enable_irq(gpi.iic_irq);
-
-	return 0;
-}
-
-
-static void iic_ite_release(void)
-{
-	if (gpi.iic_irq > 0) {
-		disable_irq(gpi.iic_irq);
-		free_irq(gpi.iic_irq, 0);
-	}
-	release_region(gpi.iic_base , 2);
-}
-
-/* ------------------------------------------------------------------------
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
-static struct i2c_algo_iic_data iic_ite_data = {
-	NULL,
-	iic_ite_setiic,
-	iic_ite_getiic,
-	iic_ite_getown,
-	iic_ite_getclock,
-	iic_ite_waitforpin,
-	80, 80, 100,		/*	waits, timeout */
-};
-
-static struct i2c_adapter iic_ite_ops = {
-	.owner		= THIS_MODULE,
-	.id		= I2C_HW_I_IIC,
-	.algo_data	= &iic_ite_data,
-	.dev		= {
-		.name	= "ITE IIC adapter",
-	},
-};
-
-/* Called when the module is loaded.  This function starts the
- * cascade of calls up through the hierarchy of i2c modules (i.e. up to the
- *  algorithm layer and into to the core layer)
- */
-static int __init iic_ite_init(void) 
-{
-
-	struct iic_ite *piic = &gpi;
-
-	printk(KERN_INFO "Initialize ITE IIC adapter module\n");
-	if (base = 0)
-		piic->iic_base = DEFAULT_BASE;
-	else
-		piic->iic_base = base;
-
-	if (irq = 0)
-		piic->iic_irq = DEFAULT_IRQ;
-	else
-		piic->iic_irq = irq;
-
-	if (clock = 0)
-		piic->iic_clock = DEFAULT_CLOCK;
-	else
-		piic->iic_clock = clock;
-
-	if (own = 0)
-		piic->iic_own = DEFAULT_OWN;
-	else
-		piic->iic_own = own;
-
-	iic_ite_data.data = (void *)piic;
-	init_waitqueue_head(&iic_wait);
-	if (iic_hw_resrc_init() = 0) {
-		if (i2c_iic_add_bus(&iic_ite_ops) < 0)
-			return -ENODEV;
-	} else {
-		return -ENODEV;
-	}
-	printk(KERN_INFO " found device at %#x irq %d.\n", 
-		piic->iic_base, piic->iic_irq);
-	return 0;
-}
-
-
-static void iic_ite_exit(void)
-{
-	i2c_iic_del_bus(&iic_ite_ops);
-        iic_ite_release();
-}
-
-/* If modules is NOT defined when this file is compiled, then the MODULE_*
- * macros will resolve to nothing
- */
-MODULE_AUTHOR("MontaVista Software <www.mvista.com>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for ITE IIC bus adapter");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(base, "i");
-MODULE_PARM(irq, "i");
-MODULE_PARM(clock, "i");
-MODULE_PARM(own, "i");
-MODULE_PARM(i2c_debug,"i");
-
-
-/* Called when module is loaded or when kernel is initialized.
- * If MODULES is defined when this file is compiled, then this function will
- * resolve to init_module (the function called when insmod is invoked for a
- * module).  Otherwise, this function is called early in the boot, when the
- * kernel is intialized.  Check out /include/init.h to see how this works.
- */
-module_init(iic_ite_init);
-
-/* Resolves to module_cleanup when MODULES is defined. */
-module_exit(iic_ite_exit); 
diff -Nru a/drivers/i2c/i2c-frodo.c b/drivers/i2c/i2c-frodo.c
--- a/drivers/i2c/i2c-frodo.c	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,85 +0,0 @@
-
-/*
- * linux/drivers/i2c/i2c-frodo.c
- *
- * Author: Abraham van der Merwe <abraham@2d3d.co.za>
- *
- * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110
- * Development board (Frodo).
- *
- * This source code is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <asm/hardware.h>
-
-
-static void frodo_setsda (void *data,int state)
-{
-	if (state)
-		FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT;
-	else
-		FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT;
-}
-
-static void frodo_setscl (void *data,int state)
-{
-	if (state)
-		FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT;
-	else
-		FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT;
-}
-
-static int frodo_getsda (void *data)
-{
-	return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0);
-}
-
-static int frodo_getscl (void *data)
-{
-	return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0);
-}
-
-static struct i2c_algo_bit_data bit_frodo_data = {
-	.setsda		= frodo_setsda,
-	.setscl		= frodo_setscl,
-	.getsda		= frodo_getsda,
-	.getscl		= frodo_getscl,
-	.udelay		= 80,
-	.mdelay		= 80,
-	.timeout	= HZ
-};
-
-static struct i2c_adapter frodo_ops = {
-	.owner			= THIS_MODULE,
-	.id			= I2C_HW_B_FRODO,
-	.algo_data		= &bit_frodo_data,
-	.dev			= {
-		.name		= "Frodo adapter driver",
-	},
-};
-
-static int __init i2c_frodo_init (void)
-{
-	return i2c_bit_add_bus(&frodo_ops);
-}
-
-static void __exit i2c_frodo_exit (void)
-{
-	i2c_bit_del_bus(&frodo_ops);
-}
-
-MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
-MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo");
-MODULE_LICENSE ("GPL");
-
-module_init (i2c_frodo_init);
-module_exit (i2c_frodo_exit);
-
diff -Nru a/drivers/i2c/i2c-ibm_iic.c b/drivers/i2c/i2c-ibm_iic.c
--- a/drivers/i2c/i2c-ibm_iic.c	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,729 +0,0 @@
-/*
- * drivers/i2c/i2c-ibm_iic.c
- *
- * Support for the IIC peripheral on IBM PPC 4xx
- *
- * Copyright (c) 2003 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by 
- * 	Ian DaSilva  <idasilva@mvista.com>
- *      Armin Kuster <akuster@mvista.com>
- * 	Matt Porter  <mporter@mvista.com>
- *
- *      Copyright 2000-2003 MontaVista Software Inc.
- *
- * Original driver version was highly leveraged from i2c-elektor.c
- *
- *   	Copyright 1995-97 Simon G. Vogl
- *                1998-99 Hans Berglund
- *
- *   	With some changes from Ky?sti M?lkki <kmalkki@cc.hut.fi> 
- *	and even Frodo Looijaard <frodol@dds.nl>
- *
- * 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.
- *
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <asm/ocp.h>
-#include <asm/ibm4xx.h>
-
-#include "i2c-ibm_iic.h"
-
-#define DRIVER_VERSION "2.0"
-
-MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
-static int iic_scan = 0;
-MODULE_PARM(iic_scan, "i");
-MODULE_PARM_DESC(iic_scan, "Scan for active chips on the bus");
-
-static int iic_force_poll = 0;
-MODULE_PARM(iic_force_poll, "i");
-MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
-
-static int iic_force_fast = 0;
-MODULE_PARM(iic_force_fast, "i");
-MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)");
-
-#define DBG_LEVEL 0
-
-#ifdef DBG
-#undef DBG
-#endif
-
-#ifdef DBG2
-#undef DBG2
-#endif
-
-#if DBG_LEVEL > 0
-#  define DBG(x...)	printk(KERN_DEBUG "ibm-iic" ##x)
-#else
-#  define DBG(x...)	((void)0)
-#endif
-#if DBG_LEVEL > 1
-#  define DBG2(x...) 	DBG( ##x )
-#else
-#  define DBG2(x...) 	((void)0)
-#endif
-#if DBG_LEVEL > 2
-static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)
-{
-	volatile struct iic_regs *iic = dev->vaddr;
-	printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header);
-	printk(KERN_DEBUG "  cntl     = 0x%02x, mdcntl = 0x%02x\n"
-	       KERN_DEBUG "  sts      = 0x%02x, extsts = 0x%02x\n"
-	       KERN_DEBUG "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n"
-	       KERN_DEBUG "  xtcntlss = 0x%02x, directcntl = 0x%02x\n",
-		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), 
-		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), 
-		in_8(&iic->xtcntlss), in_8(&iic->directcntl));
-}
-#  define DUMP_REGS(h,dev)	dump_iic_regs((h),(dev))
-#else
-#  define DUMP_REGS(h,dev)	((void)0)
-#endif
-
-/* Enable/disable interrupt generation */
-static inline void iic_interrupt_mode(struct ibm_iic_private* dev, int enable)
-{
-	out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);
-}
- 
-/*
- * Initialize IIC interface.
- */
-static void iic_dev_init(struct ibm_iic_private* dev)
-{
-	volatile struct iic_regs *iic = dev->vaddr;
-
-	DBG("%d: init\n", dev->idx);
-	
-	/* Clear master address */
-	out_8(&iic->lmadr, 0);
-	out_8(&iic->hmadr, 0);
-
-	/* Clear slave address */
-	out_8(&iic->lsadr, 0);
-	out_8(&iic->hsadr, 0);
-
-	/* Clear status & extended status */
-	out_8(&iic->sts, STS_SCMP | STS_IRQA);
-	out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | EXTSTS_LA
-			    | EXTSTS_ICT | EXTSTS_XFRA);
-
-	/* Set clock divider */
-	out_8(&iic->clkdiv, dev->clckdiv);
-
-	/* Clear transfer count */
-	out_8(&iic->xfrcnt, 0);
-
-	/* Clear extended control and status */
-	out_8(&iic->xtcntlss, XTCNTLSS_SRC | XTCNTLSS_SRS | XTCNTLSS_SWC
-			    | XTCNTLSS_SWS);
-
-	/* Clear control register */
-	out_8(&iic->cntl, 0);
-	
-	/* Enable interrupts if possible */
-	iic_interrupt_mode(dev, dev->irq >= 0);
-
-	/* Set mode control */
-	out_8(&iic->mdcntl, MDCNTL_FMDB | MDCNTL_EINT | MDCNTL_EUBS
-			    | (dev->fast_mode ? MDCNTL_FSM : 0));
-
-	DUMP_REGS("iic_init", dev);
-}
-
-/* 
- * Reset IIC interface
- */
-static void iic_dev_reset(struct ibm_iic_private* dev)
-{
-	volatile struct iic_regs *iic = dev->vaddr;
-	int i;
-	u8 dc;
-	
-	DBG("%d: soft reset\n", dev->idx);
-	DUMP_REGS("reset", dev);
-	
-    	/* Place chip in the reset state */
-	out_8(&iic->xtcntlss, XTCNTLSS_SRST);
-	
-	/* Check if bus is free */
-	dc = in_8(&iic->directcntl);	
-	if (!DIRCTNL_FREE(dc)){
-		DBG("%d: trying to regain bus control\n", dev->idx);
-	
-		/* Try to set bus free state */
-		out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);	
-	
-		/* Wait until we regain bus control */
-		for (i = 0; i < 100; ++i){
-			dc = in_8(&iic->directcntl);
-			if (DIRCTNL_FREE(dc))
-				break;
-			
-			/* Toggle SCL line */
-			dc ^= DIRCNTL_SCC;
-			out_8(&iic->directcntl, dc);
-			udelay(10);
-			dc ^= DIRCNTL_SCC;
-			out_8(&iic->directcntl, dc);
-			
-			/* be nice */
-			cond_resched();
-		}
-	}
-	
-	/* Remove reset */
-	out_8(&iic->xtcntlss, 0);
-	
-	/* Reinitialize interface */
-	iic_dev_init(dev);
-}
-
-/*
- * IIC interrupt handler
- */
-static irqreturn_t iic_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;
-	volatile struct iic_regs* iic = dev->vaddr;
-	
-	DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", 
-	     dev->idx, in_8(&iic->sts), in_8(&iic->extsts));
-	
-	/* Acknowledge IRQ and wakeup iic_wait_for_tc */
-	out_8(&iic->sts, STS_IRQA | STS_SCMP);
-	wake_up_interruptible(&dev->wq);
-	
-	return IRQ_HANDLED;
-}
-
-/*
- * Get master transfer result and clear errors if any.
- * Returns the number of actually transferred bytes or error (<0)
- */
-static int iic_xfer_result(struct ibm_iic_private* dev)
-{
-	volatile struct iic_regs *iic = dev->vaddr;	
-	
-	if (unlikely(in_8(&iic->sts) & STS_ERR)){
-		DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, 
-			in_8(&iic->extsts));
-				
-		/* Clear errors and possible pending IRQs */
-		out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | 
-			EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);
-			
-		/* Flush master data buffer */
-		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
-		
-		/* Is bus free?
-		 * If error happened during combined xfer
-		 * IIC interface is usually stuck in some strange
-		 * state, the only way out - soft reset.
-		 */
-		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
-			DBG("%d: bus is stuck, resetting\n", dev->idx);
-			iic_dev_reset(dev);
-		}
-		return -EREMOTEIO;
-	}
-	else
-		return in_8(&iic->xfrcnt) & XFRCNT_MTC_MASK;
-}
-
-/*
- * Try to abort active transfer.
- */
-static void iic_abort_xfer(struct ibm_iic_private* dev)
-{
-	volatile struct iic_regs *iic = dev->vaddr;
-	unsigned long x;
-	
-	DBG("%d: iic_abort_xfer\n", dev->idx);
-	
-	out_8(&iic->cntl, CNTL_HMT);
-	
-	/*
-	 * Wait for the abort command to complete.
-	 * It's not worth to be optimized, just poll (timeout >= 1 tick)
-	 */
-	x = jiffies + 2;
-	while ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
-		if (time_after(jiffies, x)){
-			DBG("%d: abort timeout, resetting...\n", dev->idx);
-			iic_dev_reset(dev);
-			return;
-		}
-		schedule();
-	}
-
-	/* Just to clear errors */
-	iic_xfer_result(dev);
-}
-
-/*
- * Wait for master transfer to complete.
- * It puts current process to sleep until we get interrupt or timeout expires.
- * Returns the number of transferred bytes or error (<0)
- */
-static int iic_wait_for_tc(struct ibm_iic_private* dev){
-	
-	volatile struct iic_regs *iic = dev->vaddr;
-	int ret = 0;
-	
-	if (dev->irq >= 0){
-		/* Interrupt mode */
-		wait_queue_t wait;
-    		init_waitqueue_entry(&wait, current);
-		
-		add_wait_queue(&dev->wq, &wait);
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (in_8(&iic->sts) & STS_PT)
-			schedule_timeout(dev->adap.timeout * HZ);
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&dev->wq, &wait);
-		
-		if (unlikely(signal_pending(current))){
-			DBG("%d: wait interrupted\n", dev->idx);
-			ret = -ERESTARTSYS;
-		} else if (unlikely(in_8(&iic->sts) & STS_PT)){
-			DBG("%d: wait timeout\n", dev->idx);
-			ret = -ETIMEDOUT;
-		}
-	}
-	else {
-		/* Polling mode */
-		unsigned long x = jiffies + dev->adap.timeout * HZ;
-		
-		while (in_8(&iic->sts) & STS_PT){
-			if (unlikely(time_after(jiffies, x))){
-				DBG("%d: poll timeout\n", dev->idx);
-				ret = -ETIMEDOUT;
-				break;
-			}
-		
-			if (unlikely(signal_pending(current))){
-				DBG("%d: poll interrupted\n", dev->idx);
-				ret = -ERESTARTSYS;
-				break;
-			}
-			schedule();
-		}	
-	}
-	
-	if (unlikely(ret < 0))
-		iic_abort_xfer(dev);
-	else
-		ret = iic_xfer_result(dev);
-	
-	DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);
-	
-	return ret;
-}
-
-/*
- * Low level master transfer routine
- */
-static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, 
-			  int combined_xfer)
-{
-	volatile struct iic_regs *iic = dev->vaddr;
-	char* buf = pm->buf;
-	int i, j, loops, ret = 0;
-	int len = pm->len;
-
-	u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;
-	if (pm->flags & I2C_M_RD)
-		cntl |= CNTL_RW;
-	
-	loops = (len + 3) / 4;
-	for (i = 0; i < loops; ++i, len -= 4){
-		int count = len > 4 ? 4 : len;
-		u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);
-		
-		if (!(cntl & CNTL_RW))
-			for (j = 0; j < count; ++j)
-				out_8((volatile u8*)&iic->mdbuf, *buf++);
-		
-		if (i < loops - 1)
-			cmd |= CNTL_CHT;
-		else if (combined_xfer)
-			cmd |= CNTL_RPST;
-		
-		DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);
-		
-		/* Start transfer */
-		out_8(&iic->cntl, cmd);
-		
-		/* Wait for completion */
-		ret = iic_wait_for_tc(dev);
-
-		if (unlikely(ret < 0))
-			break;
-		else if (unlikely(ret != count)){
-			DBG("%d: xfer_bytes, requested %d, transfered %d\n", 
-				dev->idx, count, ret);
-			
-			/* If it's not a last part of xfer, abort it */
-			if (combined_xfer || (i < loops - 1))
-    				iic_abort_xfer(dev);
-				
-			ret = -EREMOTEIO;
-			break;				
-		}
-		
-		if (cntl & CNTL_RW)
-			for (j = 0; j < count; ++j)
-				*buf++ = in_8((volatile u8*)&iic->mdbuf);
-	}
-	
-	return ret > 0 ? 0 : ret;
-}
-
-/*
- * Set target slave address for master transfer
- */
-static inline void iic_address(struct ibm_iic_private* dev, struct i2c_msg* msg)
-{
-	volatile struct iic_regs *iic = dev->vaddr;
-	u16 addr = msg->addr;
-	
-	DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, 
-		addr, msg->flags & I2C_M_TEN ? 10 : 7);
-	
-	if (msg->flags & I2C_M_TEN){
-	    out_8(&iic->cntl, CNTL_AMD);
-	    out_8(&iic->lmadr, addr);
-	    out_8(&iic->hmadr, 0xf0 | ((addr >> 7) & 0x06));
-	}
-	else {
-	    out_8(&iic->cntl, 0);
-	    out_8(&iic->lmadr, addr << 1);
-	}
-}
-
-static inline int iic_invalid_address(const struct i2c_msg* p)
-{
-	return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));
-}
-
-static inline int iic_address_neq(const struct i2c_msg* p1, 
-				  const struct i2c_msg* p2)
-{
-	return (p1->addr != p2->addr) 
-		|| ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));
-} 
-
-/*
- * Generic master transfer entrypoint. 
- * Returns the number of processed messages or error (<0)
- */
-static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-{
-    	struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));
-	volatile struct iic_regs *iic = dev->vaddr;
-	int i, ret = 0;
-	
-	DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);
-	
-	if (!num)
-		return 0;
-	
-	/* Check the sanity of the passed messages.
-	 * Uhh, generic i2c layer is more suitable place for such code...
-	 */
-	if (unlikely(iic_invalid_address(&msgs[0]))){
-		DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, 
-			msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);
-		return -EINVAL;
-	}		
-	for (i = 0; i < num; ++i){
-		if (unlikely(msgs[i].len <= 0)){
-			DBG("%d: invalid len %d in msg[%d]\n", dev->idx, 
-				msgs[i].len, i);
-			return -EINVAL;
-		}
-		if (unlikely(iic_address_neq(&msgs[0], &msgs[i]))){
-			DBG("%d: invalid addr in msg[%d]\n", dev->idx, i);
-			return -EINVAL;
-		}
-	}
-	
-	/* Check bus state */
-	if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){
-		DBG("%d: iic_xfer, bus is not free\n", dev->idx);
-		
-		/* Usually it means something serious has happend.
-		 * We *cannot* have unfinished previous transfer
-		 * so it doesn't make any sense to try to stop it.
-		 * Probably we were not able to recover from the 
-		 * previous error.
-		 * The only *reasonable* thing I can think of here
-		 * is soft reset.  --ebs
-		 */
-		iic_dev_reset(dev);
-		
-		if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){
-			DBG("%d: iic_xfer, bus is still not free\n", dev->idx);
-			return -EREMOTEIO;
-		}
-	} 
-	else {
-		/* Flush master data buffer (just in case) */
-		out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);
-	}
-	
-	/* Load slave address */
-	iic_address(dev, &msgs[0]);
-	
-	/* Do real transfer */
-    	for (i = 0; i < num && !ret; ++i)
-		ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);
-
-	return ret < 0 ? ret : num;
-}
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
-}
-
-static struct i2c_algorithm iic_algo = {
-	.name 		= "IBM IIC algorithm",
-	.id   		= I2C_ALGO_OCP,
-	.master_xfer 	= iic_xfer,
-	.smbus_xfer	= NULL,
-	.slave_send	= NULL,
-	.slave_recv	= NULL,
-	.algo_control	= NULL,
-	.functionality	= iic_func
-};
-
-/*
- * Scan bus for valid 7-bit addresses (ie things that ACK on 1 byte read)
- * We only scan range [0x08 - 0x77], all other addresses are reserved anyway
- */
-static void __devinit iic_scan_bus(struct ibm_iic_private* dev)
-{
-	int found = 0;
-	char dummy;
-	struct i2c_msg msg = {
-		.buf   = &dummy,
-		.len   = sizeof(dummy),
-		.flags = I2C_M_RD
-	};
-	
-	printk(KERN_INFO "ibm-iic%d: scanning bus...\n" KERN_INFO, dev->idx);
-	
-	for (msg.addr = 8; msg.addr < 0x78; ++msg.addr)
-		if (iic_xfer(&dev->adap, &msg, 1) = 1){
-			++found;
-			printk(" 0x%02x", msg.addr);
-		}
-
-	printk("%sibm-iic%d: %d device(s) detected\n", 
-		found ? "\n" KERN_INFO : "", dev->idx, found);
-}
-
-/*
- * Calculates IICx_CLCKDIV value for a specific OPB clock frequency
- */
-static inline u8 iic_clckdiv(unsigned int opb)
-{
-	/* Compatibility kludge, should go away after all cards
-	 * are fixed to fill correct value for opbfreq.
-	 * Previous driver version used hardcoded divider value 4,
-	 * it corresponds to OPB frequency from the range (40, 50] MHz
-	 */
-	if (!opb){
-		printk(KERN_WARNING "ibm-iic: using compatibility value for OPB freq,"
-			" fix your board specific setup\n");
-		opb = 50000000;
-	}
-
-	/* Convert to MHz */
-	opb /= 1000000;
-	
-	if (opb < 20 || opb > 150){
-		printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",
-			opb);
-		opb = opb < 20 ? 20 : 150;
-	}
-	return (u8)((opb + 9) / 10 - 1);
-}
-
-/*
- * Register single IIC interface
- */
-static int __devinit iic_probe(struct ocp_device *ocp){
-
-	struct ibm_iic_private* dev;
-	struct i2c_adapter* adap;
-	int ret;
-	bd_t* bd = (bd_t*)&__res;
-	
-	if (!(dev = kmalloc(sizeof(*dev), GFP_KERNEL))){
-		printk(KERN_CRIT "ibm-iic: failed to allocate device data\n");
-		return -ENOMEM;
-	}
-
-	memset(dev, 0, sizeof(*dev));
-	dev->idx = ocp->num;
-	ocp_set_drvdata(ocp, dev);
-	
-	if (!(dev->vaddr = ioremap(ocp->paddr, sizeof(struct iic_regs)))){
-		printk(KERN_CRIT "ibm-iic%d: failed to ioremap device registers\n",
-			dev->idx);
-		ret = -ENXIO;
-		goto fail2;
-	}
-	
-	init_waitqueue_head(&dev->wq);
-
-	dev->irq = iic_force_poll ? -1 : ocp->irq;
-	if (dev->irq >= 0){
-		/* Disable interrupts until we finish intialization,
-		   assumes level-sensitive IRQ setup...
-		 */
-		iic_interrupt_mode(dev, 0);
-		if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){
-			printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", 
-				dev->idx, dev->irq);
-			/* Fallback to the polling mode */	
-			dev->irq = -1;
-		}
-	}
-	
-	if (dev->irq < 0)
-		printk(KERN_WARNING "ibm-iic%d: using polling mode\n", 
-			dev->idx);
-		
-	/* Board specific settings */
-	BUG_ON(dev->idx >= sizeof(bd->bi_iic_fast) / sizeof(bd->bi_iic_fast[0]));
-	dev->fast_mode = iic_force_fast ? 1 : bd->bi_iic_fast[dev->idx];
-	
-	/* clckdiv is the same for *all* IIC interfaces, 
-	 * but I'd rather make a copy than introduce another global. --ebs
-	 */
-	dev->clckdiv = iic_clckdiv(bd->bi_opb_busfreq);
-	DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);
-	
-	/* Initialize IIC interface */
-	iic_dev_init(dev);
-	
-	/* Register it with i2c layer */
-	adap = &dev->adap;
-	strcpy(adap->dev.name, "IBM IIC");
-	i2c_set_adapdata(adap, dev);
-	adap->id = I2C_HW_OCP | iic_algo.id;
-	adap->algo = &iic_algo;
-	adap->client_register = NULL;
-	adap->client_unregister = NULL;
-	adap->timeout = 1;
-	adap->retries = 1;
-
-	if ((ret = i2c_add_adapter(adap)) != 0){
-		printk(KERN_CRIT "ibm-iic%d: failed to register i2c adapter\n",
-			dev->idx);
-		goto fail;
-	}
-	
-	printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,
-		dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
-
-	/* Scan bus if requested by user */
-	if (iic_scan)
-		iic_scan_bus(dev);
-
-	return 0;
-
-fail:	
-	if (dev->irq >= 0){
-		iic_interrupt_mode(dev, 0);
-		free_irq(dev->irq, dev);
-	}	
-
-	iounmap((void*)dev->vaddr);
-fail2:	
-	ocp_set_drvdata(ocp, 0);
-	kfree(dev);	
-	return ret;
-}
-
-/*
- * Cleanup initialized IIC interface
- */
-static void __devexit iic_remove(struct ocp_device *ocp)
-{
-	struct ibm_iic_private* dev = (struct ibm_iic_private*)ocp_get_drvdata(ocp);
-	BUG_ON(dev = NULL);
-	if (i2c_del_adapter(&dev->adap)){
-		printk(KERN_CRIT "ibm-iic%d: failed to delete i2c adapter :(\n",
-			dev->idx);
-		/* That's *very* bad, just shutdown IRQ ... */
-		if (dev->irq >= 0){
-		    iic_interrupt_mode(dev, 0);	
-		    free_irq(dev->irq, dev);
-		    dev->irq = -1;
-		}
-	} else {
-		if (dev->irq >= 0){
-		    iic_interrupt_mode(dev, 0);	
-		    free_irq(dev->irq, dev);
-		}
-		iounmap((void*)dev->vaddr);
-		kfree(dev);
-	}
-}
-
-static struct ocp_device_id ibm_iic_ids[] __devinitdata = 
-{
-	{ .vendor = OCP_VENDOR_IBM, .device = OCP_FUNC_IIC },
-	{ .vendor = OCP_VENDOR_INVALID }
-};
-
-MODULE_DEVICE_TABLE(ocp, ibm_iic_ids);
-
-static struct ocp_driver ibm_iic_driver -{
-	.name 		= "ocp_iic",
-	.id_table	= ibm_iic_ids,
-	.probe		= iic_probe,
-	.remove		= __devexit_p(iic_remove),
-#if defined(CONFIG_PM)
-	.suspend	= NULL,
-	.resume		= NULL,
-#endif
-};
-
-static int __init iic_init(void)
-{
-	printk(KERN_INFO "IBM IIC driver v" DRIVER_VERSION "\n");
-	return ocp_module_init(&ibm_iic_driver);
-}
-
-static void __exit iic_exit(void)
-{
-	ocp_unregister_driver(&ibm_iic_driver);
-}
-
-module_init(iic_init);
-module_exit(iic_exit);
diff -Nru a/drivers/i2c/i2c-ibm_iic.h b/drivers/i2c/i2c-ibm_iic.h
--- a/drivers/i2c/i2c-ibm_iic.h	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,124 +0,0 @@
-/*
- * drivers/i2c/i2c-ibm_iic.h
- *
- * Support for the IIC peripheral on IBM PPC 4xx
- * 
- * Copyright (c) 2003 Zultys Technologies.
- * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- *
- * Based on original work by 
- * 	Ian DaSilva  <idasilva@mvista.com>
- *      Armin Kuster <akuster@mvista.com>
- * 	Matt Porter  <mporter@mvista.com>
- *
- *      Copyright 2000-2003 MontaVista Software Inc.
- *
- * 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.
- *
- */
-#ifndef __I2C_IBM_IIC_H_
-#define __I2C_IBM_IIC_H_
-
-#include <linux/config.h>
-#include <linux/i2c.h> 
-
-struct iic_regs {
-	u16 mdbuf;
-	u16 sbbuf;
-	u8 lmadr;
-	u8 hmadr;
-	u8 cntl;
-	u8 mdcntl;
-	u8 sts;
-	u8 extsts;
-	u8 lsadr;
-	u8 hsadr;
-	u8 clkdiv;
-	u8 intmsk;
-	u8 xfrcnt;
-	u8 xtcntlss;
-	u8 directcntl;
-};
-
-struct ibm_iic_private {
-	struct i2c_adapter adap;
-	volatile struct iic_regs *vaddr;
-	wait_queue_head_t wq;
-	int idx;
-	int irq;
-	int fast_mode;
-	u8  clckdiv;
-};
-
-/* IICx_CNTL register */
-#define CNTL_HMT	0x80
-#define CNTL_AMD	0x40
-#define CNTL_TCT_MASK	0x30
-#define CNTL_TCT_SHIFT	4
-#define CNTL_RPST	0x08
-#define CNTL_CHT	0x04 
-#define CNTL_RW		0x02
-#define CNTL_PT		0x01
-
-/* IICx_MDCNTL register */
-#define MDCNTL_FSDB	0x80
-#define MDCNTL_FMDB	0x40
-#define MDCNTL_EGC	0x20
-#define MDCNTL_FSM	0x10
-#define MDCNTL_ESM	0x08
-#define MDCNTL_EINT	0x04
-#define MDCNTL_EUBS	0x02
-#define MDCNTL_HSCL	0x01
-
-/* IICx_STS register */
-#define STS_SSS		0x80
-#define STS_SLPR	0x40
-#define STS_MDBS	0x20
-#define STS_MDBF	0x10
-#define STS_SCMP	0x08
-#define STS_ERR		0x04
-#define STS_IRQA	0x02
-#define STS_PT		0x01
-
-/* IICx_EXTSTS register */
-#define EXTSTS_IRQP	0x80
-#define EXTSTS_BCS_MASK	0x70
-#define   EXTSTS_BCS_FREE  0x40
-#define EXTSTS_IRQD	0x08
-#define EXTSTS_LA	0x04
-#define EXTSTS_ICT	0x02
-#define EXTSTS_XFRA	0x01
-
-/* IICx_INTRMSK register */
-#define INTRMSK_EIRC	0x80
-#define INTRMSK_EIRS	0x40
-#define INTRMSK_EIWC	0x20
-#define INTRMSK_EIWS	0x10
-#define INTRMSK_EIHE	0x08
-#define INTRMSK_EIIC	0x04
-#define INTRMSK_EITA	0x02
-#define INTRMSK_EIMTC	0x01
-
-/* IICx_XFRCNT register */
-#define XFRCNT_MTC_MASK	0x07
-
-/* IICx_XTCNTLSS register */
-#define XTCNTLSS_SRC	0x80
-#define XTCNTLSS_SRS	0x40
-#define XTCNTLSS_SWC	0x20
-#define XTCNTLSS_SWS	0x10
-#define XTCNTLSS_SRST	0x01
-
-/* IICx_DIRECTCNTL register */
-#define DIRCNTL_SDAC	0x08
-#define DIRCNTL_SCC	0x04
-#define DIRCNTL_MSDA	0x02
-#define DIRCNTL_MSC	0x01
-
-/* Check if we really control the I2C bus and bus is free */
-#define DIRCTNL_FREE(v)	(((v) & 0x0f) = 0x0f)
-
-#endif /* __I2C_IBM_IIC_H_ */
diff -Nru a/drivers/i2c/i2c-iop3xx.c b/drivers/i2c/i2c-iop3xx.c
--- a/drivers/i2c/i2c-iop3xx.c	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,536 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-iop3xx.c i2c driver algorithms for Intel XScale IOP3xx                */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
- *                      <Peter dot Milne at D hyphen TACQ dot com>
-
-    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, version 2.
-
-
-    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.                */
-/* ------------------------------------------------------------------------- */
-/*
-   With acknowledgements to i2c-algo-ibm_ocp.c by 
-   Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com
-
-   And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund:
-
-     Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund
-   
-   And which acknowledged Ky?sti M?lkki <kmalkki@cc.hut.fi>,
-   Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com>
-
-  ---------------------------------------------------------------------------*/
-
-
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/i2c.h>
-
-
-#include <asm/arch-iop3xx/iop321.h>
-#include <asm/arch-iop3xx/iop321-irqs.h>
-#include "i2c-iop3xx.h"
-
-
-/* ----- global defines ----------------------------------------------- */
-#define PASSERT(x) do { if (!(x) ) \
-		printk(KERN_CRIT "PASSERT %s in %s:%d\n", #x, __FILE__, __LINE__ );\
-	} while (0)
-
-
-/* ----- global variables ---------------------------------------------	*/
-
-
-static inline unsigned char iic_cook_addr(struct i2c_msg *msg) 
-{
-	unsigned char addr;
-
-	addr = (msg->addr << 1);
-
-	if (msg->flags & I2C_M_RD)
-		addr |= 1;
-
-	/* PGM: what is M_REV_DIR_ADDR - do we need it ?? */
-	if (msg->flags & I2C_M_REV_DIR_ADDR)
-		addr ^= 1;
-
-	return addr;   
-}
-
-
-static inline void iop3xx_adap_reset(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	/* Follows devman 9.3 */
-	*iop3xx_adap->biu->CR = IOP321_ICR_UNIT_RESET;
-	*iop3xx_adap->biu->SR = IOP321_ISR_CLEARBITS;
-	*iop3xx_adap->biu->CR = 0;
-} 
-
-static inline void iop3xx_adap_set_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	*iop3xx_adap->biu->SAR = MYSAR;
-}
-
-static inline void iop3xx_adap_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	u32 cr = IOP321_ICR_GCD|IOP321_ICR_SCLEN|IOP321_ICR_UE;
-
-	/* NB SR bits not same position as CR IE bits :-( */
-	iop3xx_adap->biu->SR_enabled = 
-		IOP321_ISR_ALD | IOP321_ISR_BERRD |
-		IOP321_ISR_RXFULL | IOP321_ISR_TXEMPTY;
-
-	cr |= IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
-		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE;
-
-	*iop3xx_adap->biu->CR = cr;
-}
-
-static void iop3xx_adap_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	unsigned cr = *iop3xx_adap->biu->CR;
-	
-	cr &= ~(IOP321_ICR_MSTART | IOP321_ICR_TBYTE | 
-		IOP321_ICR_MSTOP | IOP321_ICR_SCLEN);
-	*iop3xx_adap->biu->CR = cr;
-}
-
-static void iop3xx_adap_final_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	unsigned cr = *iop3xx_adap->biu->CR;
-	
-	cr &= ~(IOP321_ICR_ALDIE | IOP321_ICR_BERRIE |
-		IOP321_ICR_RXFULLIE | IOP321_ICR_TXEMPTYIE);
-	iop3xx_adap->biu->SR_enabled = 0;
-	*iop3xx_adap->biu->CR = cr;
-}
-
-/* 
- * NB: the handler has to clear the source of the interrupt! 
- * Then it passes the SR flags of interest to BH via adap data
- */
-static void iop3xx_i2c_handler(int this_irq, 
-				void *dev_id, 
-				struct pt_regs *regs) 
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id;
-
-	u32 sr = *iop3xx_adap->biu->SR;
-
-	if ((sr &= iop3xx_adap->biu->SR_enabled)) {
-		*iop3xx_adap->biu->SR = sr;
-		iop3xx_adap->biu->SR_received |= sr;
-		wake_up_interruptible(&iop3xx_adap->waitq);
-	}
-}
-
-/* check all error conditions, clear them , report most important */
-static int iop3xx_adap_error(u32 sr)
-{
-	int rc = 0;
-
-	if ((sr&IOP321_ISR_BERRD)) {
-		if ( !rc ) rc = -I2C_ERR_BERR;
-	}
-	if ((sr&IOP321_ISR_ALD)) {
-		if ( !rc ) rc = -I2C_ERR_ALD;		
-	}
-	return rc;	
-}
-
-static inline u32 get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	unsigned long flags;
-	u32 sr;
-
-	spin_lock_irqsave(&iop3xx_adap->lock, flags);
-	sr = iop3xx_adap->biu->SR_received;
-	iop3xx_adap->biu->SR_received = 0;
-	spin_unlock_irqrestore(&iop3xx_adap->lock, flags);
-
-	return sr;
-}
-
-/*
- * sleep until interrupted, then recover and analyse the SR
- * saved by handler
- */
-typedef int (* compare_func)(unsigned test, unsigned mask);
-/* returns 1 on correct comparison */
-
-static int iop3xx_adap_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, 
-				  unsigned flags, unsigned* status,
-				  compare_func compare)
-{
-	unsigned sr = 0;
-	int interrupted;
-	int done;
-	int rc;
-
-	do {
-		interrupted = wait_event_interruptible_timeout (
-			iop3xx_adap->waitq,
-			(done = compare( sr = get_srstat(iop3xx_adap),flags )),
-			iop3xx_adap->timeout
-			);
-		if ((rc = iop3xx_adap_error(sr)) < 0) {
-			*status = sr;
-			return rc;
-		}else if (!interrupted) {
-			*status = sr;
-			return rc = -ETIMEDOUT;
-		}
-	} while(!done);
-
-	*status = sr;
-
-	return rc = 0;
-}
-
-/*
- * Concrete compare_funcs 
- */
-static int all_bits_clear(unsigned test, unsigned mask)
-{
-	return (test & mask) = 0;
-}
-static int any_bits_set(unsigned test, unsigned mask)
-{
-	return (test & mask) != 0;
-}
-
-static int iop3xx_adap_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
-	return iop3xx_adap_wait_event( 
-		iop3xx_adap, 
-	        IOP321_ISR_TXEMPTY|IOP321_ISR_ALD|IOP321_ISR_BERRD,
-		status, any_bits_set);
-}
-
-static int iop3xx_adap_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
-	return iop3xx_adap_wait_event( 
-		iop3xx_adap, 
-		IOP321_ISR_RXFULL|IOP321_ISR_ALD|IOP321_ISR_BERRD,
-		status,	any_bits_set);
-}
-
-static int iop3xx_adap_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status)
-{
-	return iop3xx_adap_wait_event( 
-		iop3xx_adap, IOP321_ISR_UNITBUSY, status, all_bits_clear);
-}
-
-/*
- * Description: This performs the IOP3xx initialization sequence
- * Valid for IOP321. Maybe valid for IOP310?.
- */
-static int iop3xx_adap_init (struct i2c_algo_iop3xx_data *iop3xx_adap)
-{
-	*IOP321_GPOD &= ~(iop3xx_adap->channel=0 ?
-			  IOP321_GPOD_I2C0:
-			  IOP321_GPOD_I2C1);
-
-	iop3xx_adap_reset(iop3xx_adap);
-	iop3xx_adap_set_slave_addr(iop3xx_adap);
-	iop3xx_adap_enable(iop3xx_adap);
-	
-        return 0;
-}
-
-static int iop3xx_adap_send_target_slave_addr(struct i2c_algo_iop3xx_data *iop3xx_adap,
-					      struct i2c_msg* msg)
-{
-	unsigned cr = *iop3xx_adap->biu->CR;
-	int status;
-	int rc;
-
-	*iop3xx_adap->biu->DBR = iic_cook_addr(msg);
-	
-	cr &= ~(IOP321_ICR_MSTOP | IOP321_ICR_NACK);
-	cr |= IOP321_ICR_MSTART | IOP321_ICR_TBYTE;
-
-	*iop3xx_adap->biu->CR = cr;
-	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
-	/* this assert fires every time, contrary to IOP manual	
-	PASSERT((status&IOP321_ISR_UNITBUSY)!=0);
-	*/
-	PASSERT((status&IOP321_ISR_RXREAD)=0);
-	     
-	return rc;
-}
-
-static int iop3xx_adap_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, int stop)
-{
-	unsigned cr = *iop3xx_adap->biu->CR;
-	int status;
-	int rc;
-
-	*iop3xx_adap->biu->DBR = byte;
-	cr &= ~IOP321_ICR_MSTART;
-	if (stop) {
-		cr |= IOP321_ICR_MSTOP;
-	} else {
-		cr &= ~IOP321_ICR_MSTOP;
-	}
-	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
-	rc = iop3xx_adap_wait_tx_done(iop3xx_adap, &status);
-
-	return rc;
-} 
-
-static int iop3xx_adap_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap,
-				 char* byte, int stop)
-{
-	unsigned cr = *iop3xx_adap->biu->CR;
-	int status;
-	int rc;
-
-	cr &= ~IOP321_ICR_MSTART;
-
-	if (stop) {
-		cr |= IOP321_ICR_MSTOP|IOP321_ICR_NACK;
-	} else {
-		cr &= ~(IOP321_ICR_MSTOP|IOP321_ICR_NACK);
-	}
-	*iop3xx_adap->biu->CR = cr |= IOP321_ICR_TBYTE;
-
-	rc = iop3xx_adap_wait_rx_done(iop3xx_adap, &status);
-
-	*byte = *iop3xx_adap->biu->DBR;
-
-	return rc;
-}
-
-static int iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, 
-				 const char *buf, int count)
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
-	int ii;
-	int rc = 0;
-
-	for (ii = 0; rc = 0 && ii != count; ++ii) {
-		rc = iop3xx_adap_write_byte(iop3xx_adap, buf[ii], ii=count-1);
-	}
-	return rc;
-}
-
-static int iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, 
-				char *buf, int count)
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
-	int ii;
-	int rc = 0;
-
-	for (ii = 0; rc = 0 && ii != count; ++ii) {
-		rc = iop3xx_adap_read_byte(iop3xx_adap, &buf[ii], ii=count-1);
-	}
-	return rc;
-}
-
-/*
- * Description:  This function implements combined transactions.  Combined
- * transactions consist of combinations of reading and writing blocks of data.
- * FROM THE SAME ADDRESS
- * Each transfer (i.e. a read or a write) is separated by a repeated start
- * condition.
- */
-static int iop3xx_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) 
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
-	int rc;
-
-	rc = iop3xx_adap_send_target_slave_addr(iop3xx_adap, pmsg);
-	if (rc < 0) {
-		return rc;
-	}
-
-	if ((pmsg->flags&I2C_M_RD)) {
-		return iop3xx_i2c_readbytes(i2c_adap, pmsg->buf, pmsg->len);
-	} else {
-		return iop3xx_i2c_writebytes(i2c_adap, pmsg->buf, pmsg->len);
-	}
-}
-
-/*
- * master_xfer() - main read/write entry
- */
-static int iop3xx_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data;
-	int im = 0;
-	int ret = 0;
-	int status;
-
-	iop3xx_adap_wait_idle(iop3xx_adap, &status);
-	iop3xx_adap_reset(iop3xx_adap);
-	iop3xx_adap_enable(iop3xx_adap);
-
-	for (im = 0; ret = 0 && im != num; ++im) {
-		ret = iop3xx_handle_msg(i2c_adap, &msgs[im]);
-	}
-
-	iop3xx_adap_transaction_cleanup(iop3xx_adap);
-
-	return ret;   
-}
-
-static int algo_control(struct i2c_adapter *adapter, unsigned int cmd,
-			unsigned long arg)
-{
-	return 0;
-}
-
-static u32 iic_func(struct i2c_adapter *adap)
-{
-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
-}
-
-
-/* -----exported algorithm data: -------------------------------------	*/
-
-static struct i2c_algorithm iic_algo = {
-	.name		= "IOP3xx I2C algorithm",
-	.id		= I2C_ALGO_OCP_IOP3XX,
-	.master_xfer	= iop3xx_master_xfer,
-	.algo_control	= algo_control,
-	.functionality	= iic_func,
-};
-
-/* 
- * registering functions to load algorithms at runtime 
- */
-static int i2c_iop3xx_add_bus(struct i2c_adapter *iic_adap)
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
-
-	if (!request_region( REGION_START(iop3xx_adap), 
-			      REGION_LENGTH(iop3xx_adap),
-			      iic_adap->name)) {
-		return -ENODEV;
-	}
-
-	init_waitqueue_head(&iop3xx_adap->waitq);
-	spin_lock_init(&iop3xx_adap->lock);
-
-	if (request_irq( 
-		     iop3xx_adap->biu->irq,
-		     iop3xx_i2c_handler,
-		     /* SA_SAMPLE_RANDOM */ 0,
-		     iic_adap->name,
-		     iop3xx_adap)) {
-		return -ENODEV;
-	}			  
-
-	/* register new iic_adapter to i2c module... */
-	iic_adap->id |= iic_algo.id;
-	iic_adap->algo = &iic_algo;
-
-	iic_adap->timeout = 100;	/* default values, should */
-	iic_adap->retries = 3;		/* be replaced by defines */
-
-	iop3xx_adap_init(iic_adap->algo_data);
-	i2c_add_adapter(iic_adap);
-	return 0;
-}
-
-static int i2c_iop3xx_del_bus(struct i2c_adapter *iic_adap)
-{
-	struct i2c_algo_iop3xx_data *iop3xx_adap = iic_adap->algo_data;
-
-	iop3xx_adap_final_cleanup(iop3xx_adap);
-	free_irq(iop3xx_adap->biu->irq, iop3xx_adap);
-
-	release_region(REGION_START(iop3xx_adap), REGION_LENGTH(iop3xx_adap));
-
-	return i2c_del_adapter(iic_adap);
-}
-
-#ifdef CONFIG_ARCH_IOP321
-
-static struct iop3xx_biu biu0 = {
-	.CR	= IOP321_ICR0,
-	.SR	= IOP321_ISR0,
-	.SAR	= IOP321_ISAR0,
-	.DBR	= IOP321_IDBR0,
-	.BMR	= IOP321_IBMR0,
-	.irq	= IRQ_IOP321_I2C_0,
-};
-
-static struct iop3xx_biu biu1 = {
-	.CR	= IOP321_ICR1,
-	.SR	= IOP321_ISR1,
-	.SAR	= IOP321_ISAR1,
-	.DBR	= IOP321_IDBR1,
-	.BMR	= IOP321_IBMR1,
-	.irq	= IRQ_IOP321_I2C_1,
-};
-
-#define ADAPTER_NAME_ROOT "IOP321 i2c biu adapter "
-#else
-#error Please define the BIU struct iop3xx_biu for your processor arch
-#endif
-
-static struct i2c_algo_iop3xx_data algo_iop3xx_data0 = {
-	.channel		= 0,
-	.biu			= &biu0,
-	.timeout		= 1*HZ,
-};
-static struct i2c_algo_iop3xx_data algo_iop3xx_data1 = {
-	.channel		= 1,
-	.biu			= &biu1,
-	.timeout		= 1*HZ,
-};
-
-static struct i2c_adapter iop3xx_ops0 = {
-	.owner			= THIS_MODULE,
-	.name			= ADAPTER_NAME_ROOT "0",
-	.id			= I2C_HW_IOP321,
-	.algo_data		= &algo_iop3xx_data0,
-};
-static struct i2c_adapter iop3xx_ops1 = {
-	.owner			= THIS_MODULE,
-	.name			= ADAPTER_NAME_ROOT "1",
-	.id			= I2C_HW_IOP321,
-	.algo_data		= &algo_iop3xx_data1,
-};
-
-static int __init i2c_iop3xx_init (void)
-{
-	return i2c_iop3xx_add_bus(&iop3xx_ops0) ||
-		i2c_iop3xx_add_bus(&iop3xx_ops1);
-}
-
-static void __exit i2c_iop3xx_exit (void)
-{
-	i2c_iop3xx_del_bus(&iop3xx_ops0);
-	i2c_iop3xx_del_bus(&iop3xx_ops1);
-}
-
-module_init (i2c_iop3xx_init);
-module_exit (i2c_iop3xx_exit);
-
-MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
-MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM(i2c_debug,"i");
-
-MODULE_PARM_DESC(i2c_debug, "debug level - 0 off; 1 normal; 2,3 more verbose; 9 iic-protocol");
-
diff -Nru a/drivers/i2c/i2c-iop3xx.h b/drivers/i2c/i2c-iop3xx.h
--- a/drivers/i2c/i2c-iop3xx.h	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,118 +0,0 @@
-/* ------------------------------------------------------------------------- */
-/* i2c-iop3xx.h algorithm driver definitions private to i2c-iop3xx.c         */
-/* ------------------------------------------------------------------------- */
-/*   Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd
- *                      <Peter dot Milne at D hyphen TACQ dot com>
-
-    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, version 2.
-
-    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.                */
-/* ------------------------------------------------------------------------- */
-
-
-#ifndef I2C_IOP3XX_H
-#define I2C_IOP3XX_H 1
-
-/*
- * iop321 hardware bit definitions
- */
-#define IOP321_ICR_FAST_MODE	0x8000	/* 1@0kBps, 0\x100kBps */
-#define IOP321_ICR_UNIT_RESET	0x4000	/* 1=RESET */
-#define IOP321_ICR_SADIE	0x2000	/* 1=Slave Detect Interrupt Enable */
-#define IOP321_ICR_ALDIE	0x1000	/* 1=Arb Loss Detect Interrupt Enable */
-#define IOP321_ICR_SSDIE	0x0800	/* 1=Slave STOP Detect Interrupt Enable */
-#define IOP321_ICR_BERRIE	0x0400	/* 1=Bus Error Interrupt Enable */
-#define IOP321_ICR_RXFULLIE	0x0200	/* 1=Receive Full Interrupt Enable */
-#define IOP321_ICR_TXEMPTYIE	0x0100	/* 1=Transmit Empty Interrupt Enable */
-#define IOP321_ICR_GCD		0x0080	/* 1=General Call Disable */
-/*
- * IOP321_ICR_GCD: 1 disables response as slave. "This bit must be set
- * when sending a master mode general call message from the I2C unit"
- */
-#define IOP321_ICR_UE		0x0040	/* 1=Unit Enable */
-/*
- * "NOTE: To avoid I2C bus integrity problems, 
- * the user needs to ensure that the GPIO Output Data Register - 
- * GPOD bits associated with an I2C port are cleared prior to setting 
- * the enable bit for that I2C serial port. 
- * The user prepares to enable I2C port 0 and 
- * I2C port 1 by clearing GPOD bits 7:6 and GPOD bits 5:4, respectively.
- */
-#define IOP321_ICR_SCLEN	0x0020	/* 1=SCL enable for master mode */
-#define IOP321_ICR_MABORT	0x0010	/* 1=Send a STOP with no data 
-					 * NB TBYTE must be clear */
-#define IOP321_ICR_TBYTE	0x0008	/* 1=Send/Receive a byte. i2c clears */
-#define IOP321_ICR_NACK		0x0004	/* 1=reply with NACK */
-#define IOP321_ICR_MSTOP	0x0002	/* 1=send a STOP after next data byte */
-#define IOP321_ICR_MSTART	0x0001	/* 1=initiate a START */
-
-
-#define IOP321_ISR_BERRD	0x0400	/* 1=BUS ERROR Detected */
-#define IOP321_ISR_SAD		0x0200	/* 1=Slave ADdress Detected */
-#define IOP321_ISR_GCAD		0x0100	/* 1=General Call Address Detected */
-#define IOP321_ISR_RXFULL	0x0080	/* 1=Receive Full */
-#define IOP321_ISR_TXEMPTY	0x0040	/* 1=Transmit Empty */
-#define IOP321_ISR_ALD		0x0020	/* 1=Arbitration Loss Detected */
-#define IOP321_ISR_SSD		0x0010	/* 1=Slave STOP Detected */
-#define IOP321_ISR_BBUSY	0x0008	/* 1=Bus BUSY */
-#define IOP321_ISR_UNITBUSY	0x0004	/* 1=Unit Busy */
-#define IOP321_ISR_NACK		0x0002	/* 1=Unit Rx or Tx a NACK */
-#define IOP321_ISR_RXREAD	0x0001	/* 1=READ 0=WRITE (R/W bit of slave addr */
-
-#define IOP321_ISR_CLEARBITS	0x07f0
-
-#define IOP321_ISAR_SAMASK	0x007f
-
-#define IOP321_IDBR_MASK	0x00ff
-
-#define IOP321_IBMR_SCL		0x0002
-#define IOP321_IBMR_SDA		0x0001
-
-#define IOP321_GPOD_I2C0	0x00c0	/* clear these bits to enable ch0 */
-#define IOP321_GPOD_I2C1	0x0030	/* clear these bits to enable ch1 */
-
-#define MYSAR			0x02	/* SWAG a suitable slave address */
-
-#define I2C_ERR			321
-#define I2C_ERR_BERR		(I2C_ERR+0)
-#define I2C_ERR_ALD		(I2C_ERR+1)
-
-
-struct iop3xx_biu {                /* Bus Interface Unit - the hardware */
-/* physical hardware defs - regs*/
-	u32 *CR;
-	u32 *SR;
-	u32 *SAR;
-	u32 *DBR;
-	u32 *BMR;
-/* irq bit vector */
-	u32 irq;
-/* stored flags */
-	u32 SR_enabled, SR_received;
-};
-
-struct i2c_algo_iop3xx_data {
-	int channel;
-
-	wait_queue_head_t waitq;
-	spinlock_t lock;
-	int timeout;
-	struct iop3xx_biu* biu;
-};
-
-#define REGION_START(adap)	((u32)((adap)->biu->CR))
-#define REGION_END(adap)	((u32)((adap)->biu->BMR+1))
-#define REGION_LENGTH(adap)	(REGION_END(adap)-REGION_START(adap))
-
-#define IRQ_STATUS_MASK(adap)	(1<<adap->biu->irq)
-
-#endif /* I2C_IOP3XX_H */
diff -Nru a/drivers/i2c/i2c-keywest.c b/drivers/i2c/i2c-keywest.c
--- a/drivers/i2c/i2c-keywest.c	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,653 +0,0 @@
-/*
-    i2c Support for Apple Keywest I2C Bus Controller
-
-    Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
-
-    Original work by
-    
-    Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-
-    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.
-
-    Changes:
-
-    2001/12/13 BenH	New implementation
-    2001/12/15 BenH	Add support for "byte" and "quick"
-                        transfers. Add i2c_xfer routine.
-
-    My understanding of the various modes supported by keywest are:
-
-     - Dumb mode : not implemented, probably direct tweaking of lines
-     - Standard mode : simple i2c transaction of type
-         S Addr R/W A Data A Data ... T
-     - Standard sub mode : combined 8 bit subaddr write with data read
-         S Addr R/W A SubAddr A Data A Data ... T
-     - Combined mode : Subaddress and Data sequences appended with no stop
-         S Addr R/W A SubAddr S Addr R/W A Data A Data ... T
-
-    Currently, this driver uses only Standard mode for i2c xfer, and
-    smbus byte & quick transfers ; and uses StandardSub mode for
-    other smbus transfers instead of combined as we need that for the
-    sound driver to be happy
-*/
-
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/completion.h>
-#include <linux/interrupt.h>
-
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-
-#include "i2c-keywest.h"
-
-#define DBG(x...) do {\
-	if (debug > 0) \
-		printk(KERN_DEBUG "KW:" x); \
-	} while(0)
-
-
-MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
-MODULE_DESCRIPTION("I2C driver for Apple's Keywest");
-MODULE_LICENSE("GPL");
-MODULE_PARM(probe, "i");
-MODULE_PARM(debug, "i");
-
-int probe = 0;
-int debug = 0;
-
-static void
-do_stop(struct keywest_iface* iface, int result)
-{
-	write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_STOP);
-	iface->state = state_stop;
-	iface->result = result;
-}
-
-/* Main state machine for standard & standard sub mode */
-static int
-handle_interrupt(struct keywest_iface *iface, u8 isr)
-{
-	int ack;
-	int rearm_timer = 1;
-	
-	DBG("handle_interrupt(), got: %x, status: %x, state: %d\n",
-		isr, read_reg(reg_status), iface->state);
-	if (isr = 0 && iface->state != state_stop) {
-		do_stop(iface, -1);
-		return rearm_timer;
-	}
-	if (isr & KW_I2C_IRQ_STOP && iface->state != state_stop) {
-		iface->result = -1;
-		iface->state = state_stop;
-	}
-	switch(iface->state) {
-	case state_addr:
-		if (!(isr & KW_I2C_IRQ_ADDR)) {
-			do_stop(iface, -1);
-			break;
-		}
-		ack = read_reg(reg_status);
-		DBG("ack on set address: %x\n", ack);
-		if ((ack & KW_I2C_STAT_LAST_AAK) = 0) {
-			do_stop(iface, -1);
-			break;
-		}
-		/* Handle rw "quick" mode */
-		if (iface->datalen = 0)
-			do_stop(iface, 0);
-		else if (iface->read_write = I2C_SMBUS_READ) {
-			iface->state = state_read;
-			if (iface->datalen > 1)
-				write_reg(reg_control, read_reg(reg_control)
-					| KW_I2C_CTL_AAK);
-		} else {
-			iface->state = state_write;
-			DBG("write byte: %x\n", *(iface->data));
-			write_reg(reg_data, *(iface->data++));
-			iface->datalen--;
-		}
-		
-		break;
-	case state_read:
-		if (!(isr & KW_I2C_IRQ_DATA)) {
-			do_stop(iface, -1);
-			break;
-		}
-		*(iface->data++) = read_reg(reg_data);
-		DBG("read byte: %x\n", *(iface->data-1));
-		iface->datalen--;
-		if (iface->datalen = 0)
-			iface->state = state_stop;
-		else
-			write_reg(reg_control, 0);
-		break;
-	case state_write:
-		if (!(isr & KW_I2C_IRQ_DATA)) {
-			do_stop(iface, -1);
-			break;
-		}
-		/* Check ack status */
-		ack = read_reg(reg_status);
-		DBG("ack on data write: %x\n", ack);
-		if ((ack & KW_I2C_STAT_LAST_AAK) = 0) {
-			do_stop(iface, -1);
-			break;
-		}
-		if (iface->datalen) {
-			DBG("write byte: %x\n", *(iface->data));
-			write_reg(reg_data, *(iface->data++));
-			iface->datalen--;
-		} else
-			do_stop(iface, 0);
-		break;
-		
-	case state_stop:
-		if (!(isr & KW_I2C_IRQ_STOP) && (++iface->stopretry) < 10)
-			do_stop(iface, -1);
-		else {
-			rearm_timer = 0;
-			iface->state = state_idle;
-			write_reg(reg_control, 0x00);
-			write_reg(reg_ier, 0x00);
-			complete(&iface->complete);
-		}
-		break;
-	}
-	
-	write_reg(reg_isr, isr);
-
-	return rearm_timer;
-}
-
-/* Interrupt handler */
-static irqreturn_t
-keywest_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct keywest_iface *iface = (struct keywest_iface *)dev_id;
-
-	spin_lock(&iface->lock);
-	del_timer(&iface->timeout_timer);
-	if (handle_interrupt(iface, read_reg(reg_isr)))
-		mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
-	spin_unlock(&iface->lock);
-	return IRQ_HANDLED;
-}
-
-static void
-keywest_timeout(unsigned long data)
-{
-	struct keywest_iface *iface = (struct keywest_iface *)data;
-
-	DBG("timeout !\n");
-	spin_lock_irq(&iface->lock);
-	if (handle_interrupt(iface, read_reg(reg_isr)))
-		mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
-	spin_unlock(&iface->lock);
-}
-
-/*
- * SMBUS-type transfer entrypoint
- */
-static s32
-keywest_smbus_xfer(	struct i2c_adapter*	adap,
-			u16			addr,
-			unsigned short		flags,
-			char			read_write,
-			u8			command,
-			int			size,
-			union i2c_smbus_data*	data)
-{
-	struct keywest_chan* chan = i2c_get_adapdata(adap);
-	struct keywest_iface* iface = chan->iface;
-	int len;
-	u8* buffer;
-	u16 cur_word;
-	int rc = 0;
-
-	if (iface->state = state_dead)
-		return -1;
-		
-	/* Prepare datas & select mode */
-	iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
-	switch (size) {
-	    case I2C_SMBUS_QUICK:
-	    	len = 0;
-	    	buffer = NULL;
-	    	iface->cur_mode |= KW_I2C_MODE_STANDARD;
-	    	break;
-	    case I2C_SMBUS_BYTE:
-	    	len = 1;
-	    	buffer = &data->byte;
-	    	iface->cur_mode |= KW_I2C_MODE_STANDARD;
-	    	break;
-	    case I2C_SMBUS_BYTE_DATA:
-	    	len = 1;
-	    	buffer = &data->byte;
-	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
-	    	break;
-	    case I2C_SMBUS_WORD_DATA:
-	    	len = 2;
-	    	cur_word = cpu_to_le16(data->word);
-	    	buffer = (u8 *)&cur_word;
-	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
-		break;
-	    case I2C_SMBUS_BLOCK_DATA:
-	    	len = data->block[0];
-	    	buffer = &data->block[1];
-	    	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
-		break;
-	    default:
-	    	return -1;
-	}
-
-	/* Original driver had this limitation */
-	if (len > 32)
-		len = 32;
-
-	down(&iface->sem);
-
-	DBG("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n",
-		chan->chan_no, addr, len, read_write = I2C_SMBUS_READ);
-
-	iface->data = buffer;
-	iface->datalen = len;
-	iface->state = state_addr;
-	iface->result = 0;
-	iface->stopretry = 0;
-	iface->read_write = read_write;
-	
-	/* Setup channel & clear pending irqs */
-	write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
-	write_reg(reg_isr, read_reg(reg_isr));
-	write_reg(reg_status, 0);
-
-	/* Set up address and r/w bit */
-	write_reg(reg_addr,
-		(addr << 1) | ((read_write = I2C_SMBUS_READ) ? 0x01 : 0x00));
-
-	/* Set up the sub address */
-	if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) = KW_I2C_MODE_STANDARDSUB
-	    || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) = KW_I2C_MODE_COMBINED)
-		write_reg(reg_subaddr, command);
-
-	/* Arm timeout */
-	mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
-
-	/* Start sending address & enable interrupt*/
-	write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR);
-	write_reg(reg_ier, KW_I2C_IRQ_MASK);
-
-	/* Wait interrupt operations completion */
-	wait_for_completion(&iface->complete);	
-
-	rc = iface->result;	
-	DBG("transfer done, result: %d\n", rc);
-
-	if (rc = 0 && size = I2C_SMBUS_WORD_DATA && read_write = I2C_SMBUS_READ)
-	    	data->word = le16_to_cpu(cur_word);
-	
-	/* Release sem */
-	up(&iface->sem);
-	
-	return rc;
-}
-
-/*
- * Generic i2c master transfer entrypoint
- */
-static int
-keywest_xfer(	struct i2c_adapter *adap,
-		struct i2c_msg msgs[], 
-		int num)
-{
-	struct keywest_chan* chan = i2c_get_adapdata(adap);
-	struct keywest_iface* iface = chan->iface;
-	struct i2c_msg *pmsg;
-	int i, completed;
-	int rc = 0;
-
-	down(&iface->sem);
-
-	/* Set adapter to standard mode */
-	iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK;
-	iface->cur_mode |= KW_I2C_MODE_STANDARD;
-
-	completed = 0;
-	for (i = 0; rc >= 0 && i < num;) {
-		u8 addr;
-		
-		pmsg = &msgs[i++];
-		addr = pmsg->addr;
-		if (pmsg->flags & I2C_M_TEN) {
-			printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n");
-			rc = -EINVAL;
-			break;
-		}
-		DBG("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n",
-		     chan->chan_no,
-		     pmsg->flags & I2C_M_RD ? "read" : "write",
-                     pmsg->len, addr, i, num);
-    
-		/* Setup channel & clear pending irqs */
-		write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4));
-		write_reg(reg_isr, read_reg(reg_isr));
-		write_reg(reg_status, 0);
-		
-		iface->data = pmsg->buf;
-		iface->datalen = pmsg->len;
-		iface->state = state_addr;
-		iface->result = 0;
-		iface->stopretry = 0;
-		if (pmsg->flags & I2C_M_RD)
-			iface->read_write = I2C_SMBUS_READ;
-		else
-			iface->read_write = I2C_SMBUS_WRITE;
-
-		/* Set up address and r/w bit */
-		if (pmsg->flags & I2C_M_REV_DIR_ADDR)
-			addr ^= 1;		
-		write_reg(reg_addr,
-			(addr << 1) |
-			((iface->read_write = I2C_SMBUS_READ) ? 0x01 : 0x00));
-
-		/* Arm timeout */
-		mod_timer(&iface->timeout_timer, jiffies + POLL_TIMEOUT);
-
-		/* Start sending address & enable interrupt*/
-		write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR);
-		write_reg(reg_ier, KW_I2C_IRQ_MASK);
-
-		/* Wait interrupt operations completion */
-		wait_for_completion(&iface->complete);	
-
-		rc = iface->result;
-		if (rc = 0)
-			completed++;
-		DBG("transfer done, result: %d\n", rc);
-	}
-
-	/* Release sem */
-	up(&iface->sem);
-
-	return completed;
-}
-
-static u32
-keywest_func(struct i2c_adapter * adapter)
-{
-	return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-	       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-	       I2C_FUNC_SMBUS_BLOCK_DATA;
-}
-
-/* For now, we only handle combined mode (smbus) */
-static struct i2c_algorithm keywest_algorithm = {
-	.name		= "Keywest i2c",
-	.id		= I2C_ALGO_SMBUS,
-	.smbus_xfer	= keywest_smbus_xfer,
-	.master_xfer	= keywest_xfer,
-	.functionality	= keywest_func,
-};
-
-
-static int
-create_iface(struct device_node *np, struct device *dev)
-{
-	unsigned long steps, *psteps, *prate;
-	unsigned bsteps, tsize, i, nchan, addroffset;
-	struct keywest_iface* iface;
-	int rc;
-
-	psteps = (unsigned long *)get_property(np, "AAPL,address-step", NULL);
-	steps = psteps ? (*psteps) : 0x10;
-
-	/* Hrm... maybe we can be smarter here */
-	for (bsteps = 0; (steps & 0x01) = 0; bsteps++)
-		steps >>= 1;
-
-	if (!strcmp(np->parent->name, "uni-n")) {
-		nchan = 2;
-		addroffset = 3;
-	} else {
-		addroffset = 0;
-		nchan = 1;
-	}
-
-	tsize = sizeof(struct keywest_iface) +
-		(sizeof(struct keywest_chan) + 4) * nchan;
-	iface = (struct keywest_iface *) kmalloc(tsize, GFP_KERNEL);
-	if (iface = NULL) {
-		printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n");
-		return -ENOMEM;
-	}
-	memset(iface, 0, tsize);
-	init_MUTEX(&iface->sem);
-	spin_lock_init(&iface->lock);
-	init_completion(&iface->complete);
-	iface->bsteps = bsteps;
-	iface->chan_count = nchan;
-	iface->state = state_idle;
-	iface->irq = np->intrs[0].line;
-	iface->channels = (struct keywest_chan *)
-		(((unsigned long)(iface + 1) + 3UL) & ~3UL);
-	iface->base = (unsigned long)ioremap(np->addrs[0].address + addroffset,
-						np->addrs[0].size);
-	if (iface->base = 0) {
-		printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
-		kfree(iface);
-		return -ENOMEM;
-	}
-
-	init_timer(&iface->timeout_timer);
-	iface->timeout_timer.function = keywest_timeout;
-	iface->timeout_timer.data = (unsigned long)iface;
-
-	/* Select interface rate */
-	iface->cur_mode = KW_I2C_MODE_100KHZ;
-	prate = (unsigned long *)get_property(np, "AAPL,i2c-rate", NULL);
-	if (prate) switch(*prate) {
-	case 100:
-		iface->cur_mode = KW_I2C_MODE_100KHZ;
-		break;
-	case 50:
-		iface->cur_mode = KW_I2C_MODE_50KHZ;
-		break;
-	case 25:
-		iface->cur_mode = KW_I2C_MODE_25KHZ;
-		break;
-	default:
-		printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n",
-			*prate);
-	}
-	
-	/* Select standard sub mode */
-	iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
-	
-	/* Write mode */
-	write_reg(reg_mode, iface->cur_mode);
-	
-	/* Switch interrupts off & clear them*/
-	write_reg(reg_ier, 0x00);
-	write_reg(reg_isr, KW_I2C_IRQ_MASK);
-
-	/* Request chip interrupt */	
-	rc = request_irq(iface->irq, keywest_irq, 0, "keywest i2c", iface);
-	if (rc) {
-		printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq);
-		iounmap((void *)iface->base);
-		kfree(iface);
-		return -ENODEV;
-	}
-
-	dev_set_drvdata(dev, iface);
-	
-	for (i=0; i<nchan; i++) {
-		struct keywest_chan* chan = &iface->channels[i];
-		u8 addr;
-		
-		sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
-		chan->iface = iface;
-		chan->chan_no = i;
-		chan->adapter.id = I2C_ALGO_SMBUS;
-		chan->adapter.algo = &keywest_algorithm;
-		chan->adapter.algo_data = NULL;
-		chan->adapter.client_register = NULL;
-		chan->adapter.client_unregister = NULL;
-		i2c_set_adapdata(&chan->adapter, chan);
-		chan->adapter.dev.parent = dev;
-
-		rc = i2c_add_adapter(&chan->adapter);
-		if (rc) {
-			printk("i2c-keywest.c: Adapter %s registration failed\n",
-				chan->adapter.name);
-			i2c_set_adapdata(&chan->adapter, NULL);
-		}
-		if (probe) {
-			printk("Probe: ");
-			for (addr = 0x00; addr <= 0x7f; addr++) {
-				if (i2c_smbus_xfer(&chan->adapter,addr,
-				    0,0,0,I2C_SMBUS_QUICK,NULL) >= 0)
-					printk("%02x ", addr);
-			}
-			printk("\n");
-		}
-	}
-
-	printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n",
-		np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps);
-		
-	return 0;
-}
-
-static int
-dispose_iface(struct device *dev)
-{
-	struct keywest_iface *iface = dev_get_drvdata(dev);
-	int i, rc;
-	
-	/* Make sure we stop all activity */
-	down(&iface->sem);
-
-	spin_lock_irq(&iface->lock);
-	while (iface->state != state_idle) {
-		spin_unlock_irq(&iface->lock);
-		set_task_state(current,TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ/10);
-		spin_lock_irq(&iface->lock);
-	}
-	iface->state = state_dead;
-	spin_unlock_irq(&iface->lock);
-	free_irq(iface->irq, iface);
-	up(&iface->sem);
-
-	/* Release all channels */
-	for (i=0; i<iface->chan_count; i++) {
-		struct keywest_chan* chan = &iface->channels[i];
-		if (i2c_get_adapdata(&chan->adapter) = NULL)
-			continue;
-		rc = i2c_del_adapter(&chan->adapter);
-		i2c_set_adapdata(&chan->adapter, NULL);
-		/* We aren't that prepared to deal with this... */
-		if (rc)
-			printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n");
-	}
-	iounmap((void *)iface->base);
-	dev_set_drvdata(dev, NULL);
-	kfree(iface);
-
-	return 0;
-}
-
-static int
-create_iface_macio(struct macio_dev* dev, const struct of_match *match)
-{
-	return create_iface(dev->ofdev.node, &dev->ofdev.dev);
-}
-
-static int
-dispose_iface_macio(struct macio_dev* dev)
-{
-	return dispose_iface(&dev->ofdev.dev);
-}
-
-static int
-create_iface_of_platform(struct of_device* dev, const struct of_match *match)
-{
-	return create_iface(dev->node, &dev->dev);
-}
-
-static int
-dispose_iface_of_platform(struct of_device* dev)
-{
-	return dispose_iface(&dev->dev);
-}
-
-static struct of_match i2c_keywest_match[] = 
-{
-	{
-	.name 		= OF_ANY_MATCH,
-	.type		= "i2c",
-	.compatible	= "keywest"
-	},
-	{},
-};
-
-static struct macio_driver i2c_keywest_macio_driver = 
-{
-	.name 		= "i2c-keywest",
-	.match_table	= i2c_keywest_match,
-	.probe		= create_iface_macio,
-	.remove		= dispose_iface_macio
-};
-
-static struct of_platform_driver i2c_keywest_of_platform_driver = 
-{
-	.name 		= "i2c-keywest",
-	.match_table	= i2c_keywest_match,
-	.probe		= create_iface_of_platform,
-	.remove		= dispose_iface_of_platform
-};
-
-static int __init
-i2c_keywest_init(void)
-{
-	macio_register_driver(&i2c_keywest_macio_driver);
-	of_register_driver(&i2c_keywest_of_platform_driver);
-
-	return 0;
-}
-
-static void __exit
-i2c_keywest_cleanup(void)
-{
-	macio_unregister_driver(&i2c_keywest_macio_driver);
-	of_unregister_driver(&i2c_keywest_of_platform_driver);
-}
-
-module_init(i2c_keywest_init);
-module_exit(i2c_keywest_cleanup);
diff -Nru a/drivers/i2c/i2c-keywest.h b/drivers/i2c/i2c-keywest.h
--- a/drivers/i2c/i2c-keywest.h	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,110 +0,0 @@
-#ifndef __I2C_KEYWEST_H__
-#define __I2C_KEYWEST_H__
-
-/* The Tumbler audio equalizer can be really slow sometimes */
-#define POLL_TIMEOUT		(2*HZ)
-
-/* Register indices */
-typedef enum {
-	reg_mode = 0,
-	reg_control,
-	reg_status,
-	reg_isr,
-	reg_ier,
-	reg_addr,
-	reg_subaddr,
-	reg_data
-} reg_t;
-
-
-/* Mode register */
-#define KW_I2C_MODE_100KHZ	0x00
-#define KW_I2C_MODE_50KHZ	0x01
-#define KW_I2C_MODE_25KHZ	0x02
-#define KW_I2C_MODE_DUMB	0x00
-#define KW_I2C_MODE_STANDARD	0x04
-#define KW_I2C_MODE_STANDARDSUB	0x08
-#define KW_I2C_MODE_COMBINED	0x0C
-#define KW_I2C_MODE_MODE_MASK	0x0C
-#define KW_I2C_MODE_CHAN_MASK	0xF0
-
-/* Control register */
-#define KW_I2C_CTL_AAK		0x01
-#define KW_I2C_CTL_XADDR	0x02
-#define KW_I2C_CTL_STOP		0x04
-#define KW_I2C_CTL_START	0x08
-
-/* Status register */
-#define KW_I2C_STAT_BUSY	0x01
-#define KW_I2C_STAT_LAST_AAK	0x02
-#define KW_I2C_STAT_LAST_RW	0x04
-#define KW_I2C_STAT_SDA		0x08
-#define KW_I2C_STAT_SCL		0x10
-
-/* IER & ISR registers */
-#define KW_I2C_IRQ_DATA		0x01
-#define KW_I2C_IRQ_ADDR		0x02
-#define KW_I2C_IRQ_STOP		0x04
-#define KW_I2C_IRQ_START	0x08
-#define KW_I2C_IRQ_MASK		0x0F
-
-/* Physical interface */
-struct keywest_iface
-{
-	unsigned long		base;
-	unsigned		bsteps;
-	int			irq;
-	struct semaphore	sem;
-	spinlock_t		lock;
-	struct keywest_chan*	channels;
-	unsigned		chan_count;
-	u8			cur_mode;
-	char			read_write;
-	u8*			data;
-	unsigned		datalen;
-	int			state;
-	int			result;
-	int			stopretry;
-	struct timer_list	timeout_timer;
-	struct completion	complete;
-};
-
-enum {
-	state_idle,
-	state_addr,
-	state_read,
-	state_write,
-	state_stop,
-	state_dead
-};
-
-/* Channel on an interface */
-struct keywest_chan
-{
-	struct i2c_adapter	adapter;
-	struct keywest_iface*	iface;
-	unsigned		chan_no;
-};
-
-/* Register access */
-
-static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg)
-{
-	return in_8(((volatile u8 *)iface->base)
-		+ (((unsigned)reg) << iface->bsteps));
-}
-
-static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val)
-{
-	out_8(((volatile u8 *)iface->base)
-		+ (((unsigned)reg) << iface->bsteps), val);
-	(void)__read_reg(iface, reg);
-	udelay(10);
-}
-
-#define write_reg(reg, val)	__write_reg(iface, reg, val) 
-#define read_reg(reg)		__read_reg(iface, reg) 
-
-
-
-#endif /* __I2C_KEYWEST_H__ */
diff -Nru a/drivers/i2c/i2c-rpx.c b/drivers/i2c/i2c-rpx.c
--- a/drivers/i2c/i2c-rpx.c	Mon Sep 22 16:12:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,103 +0,0 @@
-/*
- * Embedded Planet RPX Lite MPC8xx CPM I2C interface.
- * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
- *
- * moved into proper i2c interface;
- * Brad Parker (brad@heeltoe.com)
- *
- * RPX lite specific parts of the i2c interface
- * Update:  There actually isn't anything RPXLite-specific about this module.
- * This should work for most any 8xx board.  The console messages have been 
- * changed to eliminate RPXLite references.
- */
-
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/stddef.h>
-#include <linux/parport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-8xx.h>
-#include <asm/mpc8xx.h>
-#include <asm/commproc.h>
-
-
-static void
-rpx_iic_init(struct i2c_algo_8xx_data *data)
-{
-	volatile cpm8xx_t *cp;
-	volatile immap_t *immap;
-
-	cp = cpmp;	/* Get pointer to Communication Processor */
-	immap = (immap_t *)IMAP_ADDR;	/* and to internal registers */
-
-	data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
-
-	/* Check for and use a microcode relocation patch.
-	*/
-	if ((data->reloc = data->iip->iic_rpbase))
-		data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase];
-		
-	data->i2c = (i2c8xx_t *)&(immap->im_i2c);
-	data->cp = cp;
-
-	/* Initialize Port B IIC pins.
-	*/
-	cp->cp_pbpar |= 0x00000030;
-	cp->cp_pbdir |= 0x00000030;
-	cp->cp_pbodr |= 0x00000030;
-
-	/* Allocate space for two transmit and two receive buffer
-	 * descriptors in the DP ram.
-	 */
-	data->dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 4);
-
-	/* ptr to i2c area */
-	data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c);
-}
-
-static int rpx_install_isr(int irq, void (*func)(void *, void *), void *data)
-{
-	/* install interrupt handler */
-	cpm_install_handler(irq, (void (*)(void *, struct pt_regs *)) func, data);
-
-	return 0;
-}
-
-static struct i2c_algo_8xx_data rpx_data = {
-	.setisr = rpx_install_isr
-};
-
-static struct i2c_adapter rpx_ops = {
-	.owner		= THIS_MODULE,
-	.name		= "m8xx",
-	.id		= I2C_HW_MPC8XX_EPON,
-	.algo_data	= &rpx_data,
-};
-
-int __init i2c_rpx_init(void)
-{
-	printk("i2c-rpx.o: i2c MPC8xx module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
-	/* reset hardware to sane state */
-	rpx_iic_init(&rpx_data);
-
-	if (i2c_8xx_add_bus(&rpx_ops) < 0) {
-		printk("i2c-rpx: Unable to register with I2C\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-void __exit i2c_rpx_exit(void)
-{
-	i2c_8xx_del_bus(&rpx_ops);
-}
-
-MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
-MODULE_DESCRIPTION("I2C-Bus adapter routines for MPC8xx boards");
-
-module_init(i2c_rpx_init);
-module_exit(i2c_rpx_exit);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.25, 2003/09/22 15:11:24-07:00, greg@kroah.com

[PATCH] I2C: remove check_region usage and warning from i2c-sensor


 drivers/i2c/i2c-sensor.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/i2c-sensor.c b/drivers/i2c/i2c-sensor.c
--- a/drivers/i2c/i2c-sensor.c	Mon Sep 22 16:11:52 2003
+++ b/drivers/i2c/i2c-sensor.c	Mon Sep 22 16:11:52 2003
@@ -50,8 +50,9 @@
 		return -1;
 
 	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
-		/* XXX: WTF is going on here??? */
-		if ((is_isa && check_region(addr, 1)) ||
+		void *region_used = request_region(addr, 1, "foo");
+		release_region(addr, 1);
+		if ((is_isa && (region_used = NULL)) ||
 		    (!is_isa && i2c_check_addr(adapter, addr)))
 			continue;
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24             ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1381, 2003/09/22 16:03:26-07:00, greg@kroah.com

[PATCH] I2C: remove I2C_VERSION and I2C_DATE as they make no sense in the kernel tree.


 drivers/i2c/busses/i2c-ali1535.c  |    1 -
 drivers/i2c/busses/i2c-ali15x3.c  |    1 -
 drivers/i2c/busses/i2c-elektor.c  |   18 +++++++++---------
 drivers/i2c/busses/i2c-i801.c     |    1 -
 drivers/i2c/busses/i2c-piix4.c    |    1 -
 drivers/i2c/busses/i2c-rpx.c      |    2 +-
 drivers/i2c/busses/i2c-sis5595.c  |    1 -
 drivers/i2c/busses/i2c-sis630.c   |    1 -
 drivers/i2c/busses/i2c-velleman.c |    4 ++--
 drivers/i2c/busses/i2c-via.c      |    1 -
 drivers/i2c/i2c-dev.c             |    3 +--
 include/linux/i2c.h               |    3 ---
 12 files changed, 13 insertions(+), 24 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-ali1535.c	Mon Sep 22 16:11:27 2003
@@ -525,7 +525,6 @@
 
 static int __init i2c_ali1535_init(void)
 {
-	printk(KERN_INFO "i2c-ali1535 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&ali1535_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Mon Sep 22 16:11:27 2003
@@ -517,7 +517,6 @@
 
 static int __init i2c_ali15x3_init(void)
 {
-	printk("i2c-ali15x3.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&ali15x3_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
--- a/drivers/i2c/busses/i2c-elektor.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-elektor.c	Mon Sep 22 16:11:27 2003
@@ -77,7 +77,7 @@
 		val |= I2C_PCF_ENI;
 	}
 
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255));
+	DEB3(printk(KERN_DEBUG "i2c-elektor: Write 0x%X 0x%02X\n", address, val & 255));
 
 	switch (mmapped) {
 	case 0: /* regular I/O */
@@ -98,7 +98,7 @@
 	int address = ctl ? (base + 1) : base;
 	int val = mmapped ? readb(address) : inb(address);
 
-	DEB3(printk(KERN_DEBUG "i2c-elektor.o: Read 0x%X 0x%02X\n", address, val));
+	DEB3(printk(KERN_DEBUG "i2c-elektor: Read 0x%X 0x%02X\n", address, val));
 
 	return (val);
 }
@@ -143,14 +143,14 @@
 	if (!mmapped) {
 		if (!request_region(base, 2, "i2c (isa bus adapter)")) {
 			printk(KERN_ERR
-			       "i2c-elektor.o: requested I/O region (0x%X:2) "
+			       "i2c-elektor: requested I/O region (0x%X:2) "
 			       "is in use.\n", base);
 			return -ENODEV;
 		}
 	}
 	if (irq > 0) {
 		if (request_irq(irq, pcf_isa_handler, 0, "PCF8584", 0) < 0) {
-			printk(KERN_ERR "i2c-elektor.o: Request irq%d failed\n", irq);
+			printk(KERN_ERR "i2c-elektor: Request irq%d failed\n", irq);
 			irq = 0;
 		} else
 			enable_irq(irq);
@@ -196,7 +196,7 @@
 			/* yeap, we've found cypress, let's check config */
 			if (!pci_read_config_byte(cy693_dev, 0x47, &config)) {
 				
-				DEB3(printk(KERN_DEBUG "i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config));
+				DEB3(printk(KERN_DEBUG "i2c-elektor: found cy82c693, config register 0x47 = 0x%02x.\n", config));
 
 				/* UP2000 board has this register set to 0xe1,
                                    but the most significant bit as seems can be 
@@ -218,7 +218,7 @@
 					   8.25 MHz (PCI/4) clock
 					   (this can be read from cypress) */
 					clock = I2C_PCF_CLK | I2C_PCF_TRNS90;
-					printk(KERN_INFO "i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n");
+					printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n");
 				}
 			}
 		}
@@ -227,11 +227,11 @@
 
 	/* sanity checks for mmapped I/O */
 	if (mmapped && base < 0xc8000) {
-		printk(KERN_ERR "i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
+		printk(KERN_ERR "i2c-elektor: incorrect base address (0x%0X) specified for mmapped I/O.\n", base);
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "i2c-elektor.o: i2c pcf8584-isa adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-elektor: i2c pcf8584-isa adapter driver\n");
 
 	if (base = 0) {
 		base = DEFAULT_BASE;
@@ -243,7 +243,7 @@
 	if (i2c_pcf_add_bus(&pcf_isa_ops) < 0)
 		goto fail;
 	
-	printk(KERN_ERR "i2c-elektor.o: found device at %#x.\n", base);
+	printk(KERN_ERR "i2c-elektor: found device at %#x.\n", base);
 
 	return 0;
 
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Mon Sep 22 16:11:27 2003
@@ -616,7 +616,6 @@
 
 static int __init i2c_i801_init(void)
 {
-	printk(KERN_INFO "i2c-i801 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&i801_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-piix4.c	Mon Sep 22 16:11:27 2003
@@ -473,7 +473,6 @@
 
 static int __init i2c_piix4_init(void)
 {
-	printk(KERN_INFO "i2c-piix4 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&piix4_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-rpx.c b/drivers/i2c/busses/i2c-rpx.c
--- a/drivers/i2c/busses/i2c-rpx.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-rpx.c	Mon Sep 22 16:11:27 2003
@@ -78,7 +78,7 @@
 
 int __init i2c_rpx_init(void)
 {
-	printk("i2c-rpx.o: i2c MPC8xx module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-rpx: i2c MPC8xx driver\n");
 
 	/* reset hardware to sane state */
 	rpx_iic_init(&rpx_data);
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-sis5595.c	Mon Sep 22 16:11:27 2003
@@ -399,7 +399,6 @@
 
 static int __init i2c_sis5595_init(void)
 {
-	printk(KERN_INFO "i2c-sis5595 version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&sis5595_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-sis630.c	Mon Sep 22 16:11:27 2003
@@ -474,7 +474,6 @@
 
 static int __init i2c_sis630_init(void)
 {
-	printk("i2c-sis630.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&sis630_driver);
 }
 
diff -Nru a/drivers/i2c/busses/i2c-velleman.c b/drivers/i2c/busses/i2c-velleman.c
--- a/drivers/i2c/busses/i2c-velleman.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-velleman.c	Mon Sep 22 16:11:27 2003
@@ -120,7 +120,7 @@
 
 static int __init i2c_bitvelle_init(void)
 {
-	printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c-velleman: i2c Velleman K8000 driver\n");
 	if (base=0) {
 		/* probe some values */
 		baseÞFAULT_BASE;
@@ -140,7 +140,7 @@
 			return -ENODEV;
 		}
 	}
-	printk(KERN_DEBUG "i2c-velleman.o: found device at %#x.\n",base);
+	printk(KERN_DEBUG "i2c-velleman: found device at %#x.\n",base);
 	return 0;
 }
 
diff -Nru a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- a/drivers/i2c/busses/i2c-via.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/busses/i2c-via.c	Mon Sep 22 16:11:27 2003
@@ -165,7 +165,6 @@
 
 static int __init i2c_vt586b_init(void)
 {
-	printk(KERN_INFO "i2c-via version %s (%s)\n", I2C_VERSION, I2C_DATE);
 	return pci_module_init(&vt586b_driver);
 }
 
diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Mon Sep 22 16:11:27 2003
+++ b/drivers/i2c/i2c-dev.c	Mon Sep 22 16:11:27 2003
@@ -505,8 +505,7 @@
 {
 	int res;
 
-	printk(KERN_INFO "i2c /dev entries driver module version %s (%s)\n",
-		I2C_VERSION, I2C_DATE);
+	printk(KERN_INFO "i2c /dev entries driver\n");
 
 	if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
 		printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h
--- a/include/linux/i2c.h	Mon Sep 22 16:11:27 2003
+++ b/include/linux/i2c.h	Mon Sep 22 16:11:27 2003
@@ -28,9 +28,6 @@
 #ifndef _LINUX_I2C_H
 #define _LINUX_I2C_H
 
-#define I2C_DATE "20021208"
-#define I2C_VERSION "2.7.0"
-
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/i2c-id.h>


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24           ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1315.1.26, 2003/09/22 15:24:36-07:00, arvidjaar@mail.ru

[PATCH] I2C: sysfs sensor nameing inconsistency

> That's what you are going to have to set the name file to in the
> i2c_client structure, much like your patch did.  Then look at the
> different name files in each device directory to see what kind of device
> it is (chip, subclient, etc.)

OK attached patch sets all names to just chip name for chips themselves and
"chipname subclient" when subclient ios registered.


 drivers/i2c/chips/adm1021.c |   11 +----------
 drivers/i2c/chips/it87.c    |    3 ---
 drivers/i2c/chips/lm78.c    |    6 +++---
 drivers/i2c/chips/lm85.c    |    6 +-----
 drivers/i2c/chips/via686a.c |    2 +-
 drivers/i2c/chips/w83781d.c |   24 ++++++++++++------------
 6 files changed, 18 insertions(+), 34 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:11:39 2003
+++ b/drivers/i2c/chips/adm1021.c	Mon Sep 22 16:11:39 2003
@@ -225,7 +225,6 @@
 	struct adm1021_data *data;
 	int err = 0;
 	const char *type_name = "";
-	const char *client_name = "";
 
 	/* Make sure we aren't probing the ISA bus!! This is just a safety check
 	   at this moment; i2c_detect really won't call us. */
@@ -291,28 +290,20 @@
 
 	if (kind = max1617) {
 		type_name = "max1617";
-		client_name = "MAX1617 chip";
 	} else if (kind = max1617a) {
 		type_name = "max1617a";
-		client_name = "MAX1617A chip";
 	} else if (kind = adm1021) {
 		type_name = "adm1021";
-		client_name = "ADM1021 chip";
 	} else if (kind = adm1023) {
 		type_name = "adm1023";
-		client_name = "ADM1023 chip";
 	} else if (kind = thmc10) {
 		type_name = "thmc10";
-		client_name = "THMC10 chip";
 	} else if (kind = lm84) {
 		type_name = "lm84";
-		client_name = "LM84 chip";
 	} else if (kind = gl523sm) {
 		type_name = "gl523sm";
-		client_name = "GL523SM chip";
 	} else if (kind = mc1066) {
 		type_name = "mc1066";
-		client_name = "MC1066 chip";
 	} else {
 		dev_err(&adapter->dev, "Internal error: unknown kind (%d)?!?",
 			kind);
@@ -320,7 +311,7 @@
 	}
 
 	/* Fill in the remaining client fields and put it into the global list */
-	strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
 	data->type = kind;
 
 	new_client->id = adm1021_id++;
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/it87.c	Mon Sep 22 16:11:40 2003
@@ -592,7 +592,6 @@
 	struct it87_data *data;
 	int err = 0;
 	const char *name = "";
-	const char *client_name = "";
 	int is_isa = i2c_is_isa_adapter(adapter);
 
 	if (!is_isa && 
@@ -681,10 +680,8 @@
 
 	if (kind = it87) {
 		name = "it87";
-		client_name = "IT87 chip";
 	} /* else if (kind = it8712) {
 		name = "it8712";
-		client_name = "IT87-J chip";
 	} */ else {
 		dev_dbg(&adapter->dev, "Internal error: unknown kind (%d)?!?",
 			kind);
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/lm78.c	Mon Sep 22 16:11:40 2003
@@ -625,11 +625,11 @@
 	}
 
 	if (kind = lm78) {
-		client_name = "LM78 chip";
+		client_name = "lm78";
 	} else if (kind = lm78j) {
-		client_name = "LM78-J chip";
+		client_name = "lm78-j";
 	} else if (kind = lm79) {
-		client_name = "LM79 chip";
+		client_name = "lm79";
 	} else {
 		dev_dbg(&adapter->dev, "Internal error: unknown kind (%d)?!?",
 			kind);
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/lm85.c	Mon Sep 22 16:11:40 2003
@@ -853,24 +853,20 @@
 	/* Fill in the chip specific driver values */
 	if ( kind = any_chip ) {
 		type_name = "lm85";
-		strlcpy(new_client->name, "Generic LM85", I2C_NAME_SIZE);
 	} else if ( kind = lm85b ) {
 		type_name = "lm85b";
-		strlcpy(new_client->name, "National LM85-B", I2C_NAME_SIZE);
 	} else if ( kind = lm85c ) {
 		type_name = "lm85c";
-		strlcpy(new_client->name, "National LM85-C", I2C_NAME_SIZE);
 	} else if ( kind = adm1027 ) {
 		type_name = "adm1027";
-		strlcpy(new_client->name, "Analog Devices ADM1027", I2C_NAME_SIZE);
 	} else if ( kind = adt7463 ) {
 		type_name = "adt7463";
-		strlcpy(new_client->name, "Analog Devices ADT7463", I2C_NAME_SIZE);
 	} else {
 		dev_dbg(&adapter->dev, "Internal error, invalid kind (%d)!", kind);
 		err = -EFAULT ;
 		goto ERROR1;
 	}
+	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
 
 	/* Fill in the remaining client fields */
 	new_client->id = lm85_id++;
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	Mon Sep 22 16:11:40 2003
+++ b/drivers/i2c/chips/via686a.c	Mon Sep 22 16:11:40 2003
@@ -671,7 +671,7 @@
 	struct i2c_client *new_client;
 	struct via686a_data *data;
 	int err = 0;
-	const char client_name[] = "via686a chip";
+	const char client_name[] = "via686a";
 	u16 val;
 
 	/* Make sure we are probing the ISA bus!!  */
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:11:39 2003
+++ b/drivers/i2c/chips/w83781d.c	Mon Sep 22 16:11:39 2003
@@ -1098,15 +1098,15 @@
 	}
 
 	if (kind = w83781d)
-		client_name = "W83781D subclient";
+		client_name = "w83781d subclient";
 	else if (kind = w83782d)
-		client_name = "W83782D subclient";
+		client_name = "w83782d subclient";
 	else if (kind = w83783s)
-		client_name = "W83783S subclient";
+		client_name = "w83783s subclient";
 	else if (kind = w83627hf)
-		client_name = "W83627HF subclient";
+		client_name = "w83627hf subclient";
 	else if (kind = as99127f)
-		client_name = "AS99127F subclient";
+		client_name = "as99127f subclient";
 	else
 		client_name = "unknown subclient?";
 
@@ -1304,20 +1304,20 @@
 	}
 
 	if (kind = w83781d) {
-		client_name = "W83781D chip";
+		client_name = "w83781d";
 	} else if (kind = w83782d) {
-		client_name = "W83782D chip";
+		client_name = "w83782d";
 	} else if (kind = w83783s) {
-		client_name = "W83783S chip";
+		client_name = "w83783s";
 	} else if (kind = w83627hf) {
 		if (val1 = 0x90)
-			client_name = "W83627THF chip";
+			client_name = "w83627thf";
 		else
-			client_name = "W83627HF chip";
+			client_name = "w83627hf";
 	} else if (kind = as99127f) {
-		client_name = "AS99127F chip";
+		client_name = "as99127f";
 	} else if (kind = w83697hf) {
-		client_name = "W83697HF chip";
+		client_name = "w83697hf";
 	} else {
 		dev_err(&new_client->dev, "Internal error: unknown "
 						"kind (%d)?!?", kind);


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24           ` Christoph Hellwig
  0 siblings, 0 replies; 125+ messages in thread
From: Christoph Hellwig @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, sensors

On Mon, Sep 22, 2003 at 04:30:28PM -0700, Greg KH wrote:
>  	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
> -		/* XXX: WTF is going on here??? */
> -		if ((is_isa && check_region(addr, 1)) ||
> +		void *region_used = request_region(addr, 1, "foo");
> +		release_region(addr, 1);
> +		if ((is_isa && (region_used = NULL)) ||

WTF??  Your papering over bugs again, this doesn't help at all.

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24             ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Christoph Hellwig, linux-kernel, sensors

On Tue, Sep 23, 2003 at 09:16:17AM +0100, Christoph Hellwig wrote:
> On Mon, Sep 22, 2003 at 04:30:28PM -0700, Greg KH wrote:
> >  	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
> > -		/* XXX: WTF is going on here??? */
> > -		if ((is_isa && check_region(addr, 1)) ||
> > +		void *region_used = request_region(addr, 1, "foo");
> > +		release_region(addr, 1);
> > +		if ((is_isa && (region_used = NULL)) ||
> 
> WTF??  Your papering over bugs again, this doesn't help at all.

Why?

Ok, from my reading of this horrible chunk of code it does the
following:
	- if this is a isa based controller, then we check the region
	  that is to be used.
	- If it is already in use by someone else, then we skip it, and
	  move on to the next address.
	- If it is not in use, then we pass the address down to the chip
	  driver and let it try to find the chip at this address (it
	  will do the reserving of the address space on its own.)

So basically, check_region is pretty valid here, as we are trying to see
if something else is already at this address, to try to prevent i2c
drivers from stomping on each other.  I replaced this with a
request_region()/release_region() pair to get rid of the compiler
warning.

Is this your understanding too?  Or do you think we should just get rid
of the request_region() check here all together?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24               ` Christoph Hellwig
  0 siblings, 0 replies; 125+ messages in thread
From: Christoph Hellwig @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, sensors

On Tue, Sep 23, 2003 at 09:19:29AM -0700, Greg KH wrote:
> Ok, from my reading of this horrible chunk of code it does the
> following:
> 	- if this is a isa based controller, then we check the region
> 	  that is to be used.
> 	- If it is already in use by someone else, then we skip it, and
> 	  move on to the next address.
> 	- If it is not in use, then we pass the address down to the chip
> 	  driver and let it try to find the chip at this address (it
> 	  will do the reserving of the address space on its own.)
> 
> So basically, check_region is pretty valid here, as we are trying to see
> if something else is already at this address, to try to prevent i2c
> drivers from stomping on each other.  I replaced this with a
> request_region()/release_region() pair to get rid of the compiler
> warning.
> 
> Is this your understanding too?  Or do you think we should just get rid
> of the request_region() check here all together?

Yes, either we should get rid of it or move claiming the address to
the i2c midlayer (not sure whether that's a good idea).  But an
opencoded check_region doesn't make any more sense than an explicit
one.  And you're also looking at the pointer it returned after it's
already invalid again..


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Christoph Hellwig, linux-kernel, sensors

On Tue, Sep 23, 2003 at 05:22:58PM +0100, Christoph Hellwig wrote:
> On Tue, Sep 23, 2003 at 09:19:29AM -0700, Greg KH wrote:
> > Ok, from my reading of this horrible chunk of code it does the
> > following:
> > 	- if this is a isa based controller, then we check the region
> > 	  that is to be used.
> > 	- If it is already in use by someone else, then we skip it, and
> > 	  move on to the next address.
> > 	- If it is not in use, then we pass the address down to the chip
> > 	  driver and let it try to find the chip at this address (it
> > 	  will do the reserving of the address space on its own.)
> > 
> > So basically, check_region is pretty valid here, as we are trying to see
> > if something else is already at this address, to try to prevent i2c
> > drivers from stomping on each other.  I replaced this with a
> > request_region()/release_region() pair to get rid of the compiler
> > warning.
> > 
> > Is this your understanding too?  Or do you think we should just get rid
> > of the request_region() check here all together?
> 
> Yes, either we should get rid of it or move claiming the address to
> the i2c midlayer (not sure whether that's a good idea).  But an
> opencoded check_region doesn't make any more sense than an explicit
> one.  And you're also looking at the pointer it returned after it's
> already invalid again..

Heh, good point.  Ok, I dug out a box that uses a isa i2c adapter and
tested the patch below.  As the chip drivers are using request_region
properly, taking this check out of i2c-sensor.c makes sense.

thanks,

greg k-h


diff -Nru a/drivers/i2c/i2c-sensor.c b/drivers/i2c/i2c-sensor.c
--- a/drivers/i2c/i2c-sensor.c	Tue Sep 23 12:03:13 2003
+++ b/drivers/i2c/i2c-sensor.c	Tue Sep 23 12:03:13 2003
@@ -50,10 +50,7 @@
 		return -1;
 
 	for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
-		void *region_used = request_region(addr, 1, "foo");
-		release_region(addr, 1);
-		if ((is_isa && (region_used = NULL)) ||
-		    (!is_isa && i2c_check_addr(adapter, addr)))
+		if (!is_isa && i2c_check_addr(adapter, addr))
 			continue;
 
 		/* If it is in one of the force entries, we don't do any

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test5
@ 2005-05-19  6:24                   ` Christoph Hellwig
  0 siblings, 0 replies; 125+ messages in thread
From: Christoph Hellwig @ 2005-05-19  6:24 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, sensors

On Tue, Sep 23, 2003 at 12:04:40PM -0700, Greg KH wrote:
> Heh, good point.  Ok, I dug out a box that uses a isa i2c adapter and
> tested the patch below.  As the chip drivers are using request_region
> properly, taking this check out of i2c-sensor.c makes sense.

Looks better already, but I really wonder WTF this i2c_check_addr
thing is.  It looks at least as racy as check_region..

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24 ` Greg KH
                   ` (5 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Mark M. Hoffman
  -1 siblings, 0 replies; 125+ messages in thread
From: Mark M. Hoffman @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

* Greg KH <greg@kroah.com> [2003-09-22 16:28:47 -0700]:
> Here are some i2c driver fixes and additions for 2.6.0-test5.  I've
> ported almost all of the i2c bus drivers from the 2.4 cvs tree to the
> 2.6 kernel (the one exception is a crazy one that acts like a pci
> hotplug driver in its init function, I'll leave that to someone else...)
> I've also cleaned up the existing i2c bus drivers by moving them into
> the proper directory, and polishing up the Kconfig entries.
> 
> There are a also a few other minor i2c cleanups and fixes in here.

Hi Greg:

To help me digest your patch, I generated some diffs from sensors CVS
to linux-2.6.0-test5 + your patch.  You can find them (and the script
I used to generate them) here:

http://members.dca.net/mhoffman/sensors/diff_cvs-to-lk2.6/

The following quoted diffs are from the above link...

(drivers/i2c/busses/i2c-i810.c)

> -static unsigned long ioaddr;
> +static void *ioaddr;

But later we're doing arithmetic on ioaddr(!)  Apparently the readl/writel
macros are recasting that... but to me this is an obfuscating change.

> @@ -261,49 +225,32 @@
>  {
>         i2c_bit_del_bus(&i810_ddc_adapter);
>         i2c_bit_del_bus(&i810_i2c_adapter);
> +       iounmap(ioaddr);
>  }
>                                                                                                                                             
> -
> -/* Don't register driver to avoid driver conflicts */
> -/*
>  static struct pci_driver i810_driver = {
>         .name           = "i810 smbus",
>         .id_table       = i810_ids,
>         .probe          = i810_probe,
>         .remove         = __devexit_p(i810_remove),
>  };
> -*/
>                                                                                                                                             
>  static int __init i2c_i810_init(void)
>  {
> -       struct pci_dev *dev;
> -       const struct pci_device_id *id;
> -
> -       printk("i2c-i810.o version %s (%s)\n", LM_VERSION, LM_DATE);
> -/*
>         return pci_module_init(&i810_driver);
> -*/
> -       pci_for_each_dev(dev) {
> -               id = pci_match_device(i810_ids, dev);
> -               if(id)
> -                       if(i810_probe(dev, id) >= 0)
> -                               return 0;
> -       }
> -       return -ENODEV;
>  }

Didn't you advise mds earlier that the correct solution here is to
combine this code into the driver with which it now conflicts?  (See
drivers/video/i810/...)  Likewise for i2c-via.c and i2c-voodoo3.c.

Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24 ` Greg KH
                   ` (8 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Greg KH
  -1 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

On Wed, Sep 24, 2003 at 02:01:54AM -0400, Mark M. Hoffman wrote:
> (drivers/i2c/busses/i2c-i810.c)
> 
> > -static unsigned long ioaddr;
> > +static void *ioaddr;
> 
> But later we're doing arithmetic on ioaddr(!)  Apparently the readl/writel
> macros are recasting that... but to me this is an obfuscating change.

I did it this way, as ioremap returns a void *.  And it's ok to do math
on a void pointer, works the same way as math on a char *.  It got rid
of two casts in the driver with this change.

> > @@ -261,49 +225,32 @@
> >  {
> >         i2c_bit_del_bus(&i810_ddc_adapter);
> >         i2c_bit_del_bus(&i810_i2c_adapter);
> > +       iounmap(ioaddr);
> >  }
> >                                                                                                                                             
> > -
> > -/* Don't register driver to avoid driver conflicts */
> > -/*
> >  static struct pci_driver i810_driver = {
> >         .name           = "i810 smbus",
> >         .id_table       = i810_ids,
> >         .probe          = i810_probe,
> >         .remove         = __devexit_p(i810_remove),
> >  };
> > -*/
> >                                                                                                                                             
> >  static int __init i2c_i810_init(void)
> >  {
> > -       struct pci_dev *dev;
> > -       const struct pci_device_id *id;
> > -
> > -       printk("i2c-i810.o version %s (%s)\n", LM_VERSION, LM_DATE);
> > -/*
> >         return pci_module_init(&i810_driver);
> > -*/
> > -       pci_for_each_dev(dev) {
> > -               id = pci_match_device(i810_ids, dev);
> > -               if(id)
> > -                       if(i810_probe(dev, id) >= 0)
> > -                               return 0;
> > -       }
> > -       return -ENODEV;
> >  }
> 
> Didn't you advise mds earlier that the correct solution here is to
> combine this code into the driver with which it now conflicts?  (See
> drivers/video/i810/...)  Likewise for i2c-via.c and i2c-voodoo3.c.

I did say this.  But just "grabbing" the device like you are doing in
2.4 isn't an ok thing to do (the device can disappear underneath you
quite easily in pci hotplug systems.)  It is not safe to do this at all.

So if people complain about both drivers trying to grab the device, then
people will work on merging the drivers properly, and will send me a
patch :)

There are also some devices that these drivers match up to, that do not
match up to some existing video drivers, from what I could tell, so it
isn't a complete overlap.

Thanks for looking over the changes.

greg k-h

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24 ` Greg KH
                   ` (7 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Jean Delvare
  -1 siblings, 0 replies; 125+ messages in thread
From: Jean Delvare @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors


> I did it this way, as ioremap returns a void *.  And it's ok to do
> math on a void pointer, works the same way as math on a char *.  It
> got rid of two casts in the driver with this change.

Not too sure abour that. Gcc wouldn't have a flag (-Wcast-arith) for
this without a reason.

-- 
Jean Delvare
http://www.ensicaen.ismra.fr/~delvare/

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test5
  2005-05-19  6:24 ` Greg KH
                   ` (6 preceding siblings ...)
  (?)
@ 2005-05-19  6:24 ` Mark M. Hoffman
  -1 siblings, 0 replies; 125+ messages in thread
From: Mark M. Hoffman @ 2005-05-19  6:24 UTC (permalink / raw)
  To: lm-sensors

* Greg KH <greg@kroah.com> [2003-09-24 11:09:56 -0700]:
> > I did it this way, as ioremap returns a void *.  And it's ok to do
> > math on a void pointer, works the same way as math on a char *.  It
> > got rid of two casts in the driver with this change.

* Jean Delvare <khali@linux-fr.org> [2003-09-24 22:40:49 +0200]:
> Not too sure abour that. Gcc wouldn't have a flag (-Wcast-arith) for
> this without a reason.

Sorry, at my day job I work with compilers that reject that.  Apparently
gcc will reject it too if you specify -pedantic.  Funny how this is ok
in linux but // comments (legal C99) are vigorously removed. ;)

Regards,

-- 
Mark M. Hoffman
mhoffman@lightlink.com

^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test7
@ 2005-05-19  6:24   ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.1, 2003/10/09 13:33:03-07:00, khali@linux-fr.org

[PATCH] I2C: Chip driver initialization fixes

fixes all chip drivers by moving the initialization before any sysfs
entry is created.


 drivers/i2c/chips/adm1021.c |    6 ++++--
 drivers/i2c/chips/it87.c    |    7 ++++---
 drivers/i2c/chips/lm75.c    |    5 ++++-
 drivers/i2c/chips/lm78.c    |    7 ++++---
 drivers/i2c/chips/lm85.c    |    6 ++++--
 drivers/i2c/chips/via686a.c |    7 ++++---
 drivers/i2c/chips/w83781d.c |    6 ++++--
 7 files changed, 28 insertions(+), 16 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/adm1021.c	Fri Oct 10 16:00:52 2003
@@ -322,6 +322,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto error3;
 
+	/* Initialize the ADM1021 chip */
+	adm1021_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_temp_max1);
 	device_create_file(&new_client->dev, &dev_attr_temp_min1);
 	device_create_file(&new_client->dev, &dev_attr_temp_input1);
@@ -332,8 +336,6 @@
 	if (data->type = adm1021)
 		device_create_file(&new_client->dev, &dev_attr_die_code);
 
-	/* Initialize the ADM1021 chip */
-	adm1021_init_client(new_client);
 	return 0;
 
 error3:
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/it87.c	Fri Oct 10 16:00:52 2003
@@ -701,7 +701,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR1;
 
-	/* register sysfs hooks */
+	/* Initialize the IT87 chip */
+	it87_init_client(new_client, data);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in_input0);
 	device_create_file(&new_client->dev, &dev_attr_in_input1);
 	device_create_file(&new_client->dev, &dev_attr_in_input2);
@@ -750,8 +753,6 @@
 	device_create_file(&new_client->dev, &dev_attr_fan_div3);
 	device_create_file(&new_client->dev, &dev_attr_alarm);
 
-	/* Initialize the IT87 chip */
-	it87_init_client(new_client, data);
 	return 0;
 
 ERROR1:
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/lm75.c	Fri Oct 10 16:00:52 2003
@@ -204,11 +204,14 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto exit_free;
 
+	/* Initialize the LM75 chip */
+	lm75_init_client(new_client);
+	
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_temp_max);
 	device_create_file(&new_client->dev, &dev_attr_temp_min);
 	device_create_file(&new_client->dev, &dev_attr_temp_input);
 
-	lm75_init_client(new_client);
 	return 0;
 
 exit_free:
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/lm78.c	Fri Oct 10 16:00:52 2003
@@ -648,7 +648,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR2;
 
-	/* register sysfs hooks */
+	/* Initialize the LM78 chip */
+	lm78_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in_input0);
 	device_create_file(&new_client->dev, &dev_attr_in_min0);
 	device_create_file(&new_client->dev, &dev_attr_in_max0);
@@ -685,8 +688,6 @@
 	device_create_file(&new_client->dev, &dev_attr_alarms);
 	device_create_file(&new_client->dev, &dev_attr_vid);
 
-	/* Initialize the LM78 chip */
-	lm78_init_client(new_client);
 	return 0;
 
 ERROR2:
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/lm85.c	Fri Oct 10 16:00:52 2003
@@ -888,6 +888,10 @@
 	/* Set the VRM version */
 	data->vrm = LM85_INIT_VRM ;
 
+	/* Initialize the LM85 chip */
+	lm85_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_fan_input1);
 	device_create_file(&new_client->dev, &dev_attr_fan_input2);
 	device_create_file(&new_client->dev, &dev_attr_fan_input3);
@@ -930,8 +934,6 @@
 	device_create_file(&new_client->dev, &dev_attr_vid);
 	device_create_file(&new_client->dev, &dev_attr_alarms);
 
-	/* Initialize the LM85 chip */
-	lm85_init_client(new_client);
 	return 0;
 
 	/* Error out and cleanup code */
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/via686a.c	Fri Oct 10 16:00:52 2003
@@ -735,7 +735,10 @@
 	if ((err = i2c_attach_client(new_client)))
 		goto ERROR3;
 	
-	/* register sysfs hooks */
+	/* Initialize the VIA686A chip */
+	via686a_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file(&new_client->dev, &dev_attr_in_input0);
 	device_create_file(&new_client->dev, &dev_attr_in_input1);
 	device_create_file(&new_client->dev, &dev_attr_in_input2);
@@ -768,8 +771,6 @@
 	device_create_file(&new_client->dev, &dev_attr_fan_div2);
 	device_create_file(&new_client->dev, &dev_attr_alarm);
 
-	/* Initialize the VIA686A chip */
-	via686a_init_client(new_client);
 	return 0;
 
       ERROR3:
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Fri Oct 10 16:00:52 2003
+++ b/drivers/i2c/chips/w83781d.c	Fri Oct 10 16:00:52 2003
@@ -1346,6 +1346,10 @@
 		data->lm75[1] = NULL;
 	}
 
+	/* Initialize the chip */
+	w83781d_init_client(new_client);
+
+	/* Register sysfs hooks */
 	device_create_file_in(new_client, 0);
 	if (kind != w83783s && kind != w83697hf)
 		device_create_file_in(new_client, 1);
@@ -1408,8 +1412,6 @@
 	}
 #endif
 
-	/* Initialize the chip */
-	w83781d_init_client(new_client);
 	return 0;
 
 ERROR3:


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test7
@ 2005-05-19  6:24       ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.3, 2003/10/10 14:11:04-07:00, amalysh@web.de

[PATCH] I2C: i2c-sis630 driver fixes

attached you can find a patch that should fix i2c-sis630 driver for
2.6.0-X kernel. With i2c-sis630 from stock 2.6.0-X we have oops and
driver was not correct registered against i2c-core.

Changes:
	1) fixed a oops while modprobing
	2) added check for buffer overflow for i2c block data read transaction
	3) added 'force' modprobe parameter. It's allow more easily
	   testing for not yet supported SiS chips.


 drivers/i2c/busses/Kconfig      |    4 +-
 drivers/i2c/busses/i2c-sis630.c |   67 ++++++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 22 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig	Fri Oct 10 16:00:43 2003
+++ b/drivers/i2c/busses/Kconfig	Fri Oct 10 16:00:43 2003
@@ -248,11 +248,11 @@
 	  will be called i2c-sis5595.
 
 config I2C_SIS630
-	tristate "SiS 630"
+	tristate "SiS 630/730"
 	depends on I2C && PCI && EXPERIMENTAL
 	help
 	  If you say yes to this option, support will be included for the 
-	  SiS630 SMBus (a subset of I2C) interface.
+	  SiS630 and SiS730 SMBus (a subset of I2C) interface.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-sis630.
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c	Fri Oct 10 16:00:43 2003
+++ b/drivers/i2c/busses/i2c-sis630.c	Fri Oct 10 16:00:43 2003
@@ -25,10 +25,10 @@
    	Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
 	Changed sis630_transaction.(Thanks to Mark M. Hoffman)
    18.09.2002
-	Added SIS730 as supported
+	Added SIS730 as supported.
    21.09.2002
 	Added high_clock module option.If this option is set
-	used Host Master Clock 56KHz (default 14KHz).For now we are save old Host
+	used Host Master Clock 56KHz (default 14KHz).For now we save old Host
 	Master Clock and after transaction completed restore (otherwise
 	it's confuse BIOS and hung Machine).
    24.09.2002
@@ -95,12 +95,22 @@
 
 /* insmod parameters */
 static int high_clock = 0;
+static int force = 0;
 MODULE_PARM(high_clock, "i");
 MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
+MODULE_PARM(force, "i");
+MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
 
-
+/* acpi base address */
 static unsigned short acpi_base = 0;
 
+/* supported chips */
+static int supported[] = {
+	PCI_DEVICE_ID_SI_630,
+	PCI_DEVICE_ID_SI_730,
+	0 /* terminates the list */
+};
+
 static inline u8 sis630_read(u8 reg)
 {
 	return inb(acpi_base + reg);
@@ -277,6 +287,10 @@
 			if (len = 0)
 				data->block[0] = sis630_read(SMB_COUNT);
 
+			/* just to be sure */
+			if (data->block[0] > 32)
+				data->block[0] = 32;
+
 			dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
 
 			for (i=0; i < 8 && len < data->block[0]; i++,len++) {
@@ -372,16 +386,26 @@
 		I2C_FUNC_SMBUS_BLOCK_DATA;
 }
 
-static int sis630_setup(struct pci_dev *dummy)
+static int sis630_setup(struct pci_dev *sis630_dev)
 {
 	unsigned char b;
-	struct pci_dev *sis630_dev = NULL;
-	int retval = -ENODEV;
+	struct pci_dev *dummy = NULL;
+	int retval = -ENODEV, i;
 
-	/* We need ISA bridge and not pci device passed in.  */
-	sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev);
-	if (!sis630_dev) {
-		dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n");
+	/* check for supported SiS devices */
+	for (i=0; supported[i] > 0 ; i++) {
+		if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy)))
+			break; /* found */
+	}
+
+	if (dummy) {
+		pci_dev_put(dummy);
+	}
+        else if (force > 0) {
+		dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but "
+			"loading because of force option enabled\n");
+ 	}
+	else {
 		return -ENODEV;
 	}
 
@@ -389,19 +413,19 @@
 	   Enable ACPI first , so we can accsess reg 74-75
 	   in acpi io space and read acpi base addr
 	*/
-	if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
+	if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
 		dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
 		goto exit;
 	}
-
 	/* if ACPI already enabled , do nothing */
 	if (!(b & 0x80) &&
-	    !pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
+	    pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
 		dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
 		goto exit;
 	}
+
 	/* Determine the ACPI base address */
-	if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
+	if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
 		dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
 		goto exit;
 	}
@@ -418,7 +442,8 @@
 	retval = 0;
 
 exit:
-	pci_dev_put(sis630_dev);
+	if (retval)
+		acpi_base = 0;
 	return retval;
 }
 
@@ -432,19 +457,18 @@
 
 static struct i2c_adapter sis630_adapter = {
 	.owner		= THIS_MODULE,
+	.class		= I2C_ADAP_CLASS_SMBUS,
 	.name		= "unset",
 	.algo		= &smbus_algorithm,
 };
 
 static struct pci_device_id sis630_ids[] __devinitdata = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
 	{ 0, }
 };
 
 static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
-
 	if (sis630_setup(dev)) {
 		dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
 		return -ENODEV;
@@ -461,7 +485,11 @@
 
 static void __devexit sis630_remove(struct pci_dev *dev)
 {
-	i2c_del_adapter(&sis630_adapter);
+	if (acpi_base) {
+		i2c_del_adapter(&sis630_adapter);
+		release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
+		acpi_base = 0;
+	}
 }
 
 
@@ -481,7 +509,6 @@
 static void __exit i2c_sis630_exit(void)
 {
 	pci_unregister_driver(&sis630_driver);
-	release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
 }
 
 


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test7
@ 2005-05-19  6:24     ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.2, 2003/10/09 13:35:09-07:00, khali@linux-fr.org

[PATCH] I2C: correct some errors in i2c/chips/Kconfig


 drivers/i2c/chips/Kconfig |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)


diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	Fri Oct 10 16:00:47 2003
+++ b/drivers/i2c/chips/Kconfig	Fri Oct 10 16:00:47 2003
@@ -15,7 +15,7 @@
 	help
 	  If you say yes here you get support for Analog Devices ADM1021 
 	  and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A,
-	  Genesys Logic GL523SM, National Semi LM84, TI THMC10,
+	  Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10,
 	  and the XEON processor built-in sensor.
 
 	  This driver can also be built as a module.  If so, the module
@@ -34,30 +34,30 @@
 	  will be called eeprom.
 
 config SENSORS_IT87
-	tristate "National Semiconductors IT87 and compatibles"
+	tristate "ITE IT87xx and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
-	  If you say yes here you get support for National Semiconductor IT87
-	  sensor chips and clones: IT8705F, IT8712F and SiS960.
+	  If you say yes here you get support for ITE IT87xx sensor chips
+	  and clones: SiS960.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called it87.
 
 config SENSORS_LM75
-	tristate "National Semiconductors LM75 and compatibles"
+	tristate "National Semiconductor LM75 and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
 	  If you say yes here you get support for National Semiconductor LM75
 	  sensor chips and clones: Dallas Semi DS75 and DS1775, TelCon
-	  TCN75, and National Semi LM77.
+	  TCN75, and National Semiconductor LM77.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called lm75.
 
 config SENSORS_LM78
-	tristate "National Semiconductors LM78 and compatibles"
+	tristate "National Semiconductor LM78 and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help
@@ -69,7 +69,7 @@
 	  will be called lm78.
 
 config SENSORS_LM85
-	tristate "National Semiconductors LM85 and compatibles"
+	tristate "National Semiconductor LM85 and compatibles"
 	depends on I2C && EXPERIMENTAL
 	select I2C_SENSOR
 	help


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [PATCH] i2c driver fixes for 2.6.0-test7
@ 2005-05-19  6:24         ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: linux-kernel, sensors

ChangeSet 1.1337.1.4, 2003/10/10 14:59:18-07:00, greg@kroah.com

[PATCH] I2C: fix i2c-dev class release function bug.

There was no release function, that was the bug :)
It caused bad messages to show up in the syslog whenever a i2c driver was removed, and could
easily oops.


 drivers/i2c/i2c-dev.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)


diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
--- a/drivers/i2c/i2c-dev.c	Fri Oct 10 16:00:34 2003
+++ b/drivers/i2c/i2c-dev.c	Fri Oct 10 16:00:34 2003
@@ -49,6 +49,7 @@
 	int minor;
 	struct i2c_adapter *adap;
 	struct class_device class_dev;
+	struct completion released;	/* FIXME, we need a class_device_unregister() */
 };
 #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
 
@@ -112,7 +113,6 @@
 	spin_lock(&i2c_dev_array_lock);
 	i2c_dev_array[i2c_dev->minor] = NULL;
 	spin_unlock(&i2c_dev_array_lock);
-	kfree(i2c_dev);
 }
 
 static ssize_t show_dev(struct class_device *class_dev, char *buf)
@@ -421,8 +421,15 @@
 	.release	= i2cdev_release,
 };
 
+static void release_i2c_dev(struct class_device *dev)
+{
+	struct i2c_dev *i2c_dev = to_i2c_dev(dev);
+	complete(&i2c_dev->released);
+}
+
 static struct class i2c_dev_class = {
-	.name	= "i2c-dev",
+	.name		= "i2c-dev",
+	.release	= &release_i2c_dev,
 };
 
 static int i2cdev_attach_adapter(struct i2c_adapter *adap)
@@ -453,6 +460,7 @@
 	return 0;
 error:
 	return_i2c_dev(i2c_dev);
+	kfree(i2c_dev);
 	return retval;
 }
 
@@ -464,9 +472,12 @@
 	if (!i2c_dev)
 		return -ENODEV;
 
-	class_device_unregister(&i2c_dev->class_dev);
+	init_completion(&i2c_dev->released);
 	devfs_remove("i2c/%d", i2c_dev->minor);
 	return_i2c_dev(i2c_dev);
+	class_device_unregister(&i2c_dev->class_dev);
+	wait_for_completion(&i2c_dev->released);
+	kfree(i2c_dev);
 
 	dev_dbg(&adap->dev, "Adapter unregistered\n");
 	return 0;


^ permalink raw reply	[flat|nested] 125+ messages in thread

* [BK PATCH] i2c driver fixes for 2.6.0-test7
@ 2005-05-19  6:24 ` Greg KH
  0 siblings, 0 replies; 125+ messages in thread
From: Greg KH @ 2005-05-19  6:24 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, sensors

Hi,

Here are some i2c driver fixes for 2.6.0-test7.  They fix a bug in the
i2c-dev class code, fix oopses in the i2c-sis630 driver, and fix a
potential use-before-initialized error in the i2c chip drivers.

Please pull from:  bk://kernel.bkbits.net/gregkh/linux/i2c-2.6

thanks,

greg k-h

 drivers/i2c/busses/Kconfig      |    4 +-
 drivers/i2c/busses/i2c-sis630.c |   67 ++++++++++++++++++++++++++++------------
 drivers/i2c/chips/Kconfig       |   16 ++++-----
 drivers/i2c/chips/adm1021.c     |    6 ++-
 drivers/i2c/chips/it87.c        |    7 ++--
 drivers/i2c/chips/lm75.c        |    5 ++
 drivers/i2c/chips/lm78.c        |    7 ++--
 drivers/i2c/chips/lm85.c        |    6 ++-
 drivers/i2c/chips/via686a.c     |    7 ++--
 drivers/i2c/chips/w83781d.c     |    6 ++-
 drivers/i2c/i2c-dev.c           |   17 ++++++++--
 11 files changed, 99 insertions(+), 49 deletions(-)
-----

<amalysh:web.de>:
  o I2C: i2c-sis630 driver fixes

Greg Kroah-Hartman:
  o I2C: fix i2c-dev class release function bug

Jean Delvare:
  o I2C: correct some errors in i2c/chips/Kconfig
  o I2C: Chip driver initialization fixes

^ permalink raw reply	[flat|nested] 125+ messages in thread

end of thread, other threads:[~2005-05-19  6:24 UTC | newest]

Thread overview: 125+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-15 18:32 [BK PATCH] i2c driver fixes for 2.6.0-test3 Greg KH
2005-05-19  6:24 ` Greg KH
2003-08-15 18:33 ` [PATCH] i2c driver changes 2.6.0-test3 Greg KH
2005-05-19  6:24   ` Greg KH
2003-08-15 18:33   ` Greg KH
2005-05-19  6:24     ` Greg KH
2003-08-15 18:33     ` Greg KH
2005-05-19  6:24       ` Greg KH
2003-08-15 18:33       ` Greg KH
2005-05-19  6:24         ` Greg KH
2003-08-15 18:33         ` Greg KH
2005-05-19  6:24           ` Greg KH
2003-08-15 18:33           ` Greg KH
2005-05-19  6:24             ` Greg KH
2003-08-15 18:33             ` Greg KH
2005-05-19  6:24               ` Greg KH
2003-08-15 18:33               ` Greg KH
2005-05-19  6:24                 ` Greg KH
2005-05-19  6:24     ` Philip Pokorny
2005-05-19  6:24     ` Greg KH
2005-05-19  6:24     ` Jean Delvare
2005-05-19  6:24     ` Mark D. Studebaker 
2005-05-19  6:24     ` Jean Delvare
  -- strict thread matches above, loose matches on Subject: below --
2003-10-10 23:10 [BK PATCH] i2c driver fixes for 2.6.0-test7 Greg KH
2005-05-19  6:24 ` Greg KH
2003-10-10 23:11 ` [PATCH] " Greg KH
2005-05-19  6:24   ` Greg KH
2003-10-10 23:11   ` Greg KH
2005-05-19  6:24     ` Greg KH
2003-10-10 23:11     ` Greg KH
2005-05-19  6:24       ` Greg KH
2003-10-10 23:11       ` Greg KH
2005-05-19  6:24         ` Greg KH
2003-09-22 23:28 [BK PATCH] i2c driver fixes for 2.6.0-test5 Greg KH
2005-05-19  6:24 ` Greg KH
2003-09-22 23:30 ` [PATCH] " Greg KH
2005-05-19  6:24   ` Greg KH
2003-09-22 23:30   ` Greg KH
2005-05-19  6:24     ` Greg KH
2003-09-22 23:30     ` Greg KH
2005-05-19  6:24       ` Greg KH
2003-09-22 23:30       ` Greg KH
2005-05-19  6:24         ` Greg KH
2003-09-22 23:30         ` Greg KH
2005-05-19  6:24           ` Greg KH
2003-09-22 23:30           ` Greg KH
2005-05-19  6:24             ` Greg KH
2003-09-22 23:30             ` Greg KH
2005-05-19  6:24               ` Greg KH
2003-09-22 23:30               ` Greg KH
2005-05-19  6:24                 ` Greg KH
2003-09-22 23:30                 ` Greg KH
2005-05-19  6:24                   ` Greg KH
2003-09-22 23:30                   ` Greg KH
2005-05-19  6:24                     ` Greg KH
2003-09-22 23:30                     ` Greg KH
2005-05-19  6:24                       ` Greg KH
2003-09-22 23:30                       ` Greg KH
2005-05-19  6:24                         ` Greg KH
2003-09-22 23:30                         ` Greg KH
2005-05-19  6:24                           ` Greg KH
2003-09-22 23:30                           ` Greg KH
2005-05-19  6:24                             ` Greg KH
2003-09-22 23:30                             ` Greg KH
2005-05-19  6:24                               ` Greg KH
2003-09-22 23:30                               ` Greg KH
2005-05-19  6:24                                 ` Greg KH
2003-09-22 23:30                                 ` Greg KH
2005-05-19  6:24                                   ` Greg KH
2003-09-22 23:30                                   ` Greg KH
2005-05-19  6:24                                     ` Greg KH
2003-09-22 23:30                                     ` Greg KH
2005-05-19  6:24                                       ` Greg KH
2003-09-22 23:30                                       ` Greg KH
2005-05-19  6:24                                         ` Greg KH
2003-09-22 23:30                                         ` Greg KH
2005-05-19  6:24                                           ` Greg KH
2003-09-22 23:30                                           ` Greg KH
2005-05-19  6:24                                             ` Greg KH
2003-09-22 23:30                                             ` Greg KH
2005-05-19  6:24                                               ` Greg KH
2003-09-22 23:30                                               ` Greg KH
2005-05-19  6:24                                                 ` Greg KH
2003-09-22 23:30                                                 ` Greg KH
2005-05-19  6:24                                                   ` Greg KH
2003-09-22 23:30                                                   ` Greg KH
2005-05-19  6:24                                                     ` Greg KH
2003-09-22 23:30                                                     ` Greg KH
2005-05-19  6:24                                                       ` Greg KH
2003-09-22 23:30                                                       ` Greg KH
2005-05-19  6:24                                                         ` Greg KH
2003-09-22 23:30                                                         ` Greg KH
2005-05-19  6:24                                                           ` Greg KH
2005-05-19  6:24     ` Greg KH
2003-09-22 23:30       ` Greg KH
2005-05-19  6:24         ` Greg KH
2003-09-22 23:30         ` Greg KH
2005-05-19  6:24           ` Greg KH
2003-09-22 23:30           ` Greg KH
2005-05-19  6:24             ` Greg KH
2003-09-23  8:16         ` Christoph Hellwig
2005-05-19  6:24           ` Christoph Hellwig
2003-09-23 16:19           ` Greg KH
2005-05-19  6:24             ` Greg KH
2003-09-23 16:22             ` Christoph Hellwig
2005-05-19  6:24               ` Christoph Hellwig
2003-09-23 19:04               ` Greg KH
2005-05-19  6:24                 ` Greg KH
2003-09-23 19:08                 ` Christoph Hellwig
2005-05-19  6:24                   ` Christoph Hellwig
2003-08-02  5:29 [BK PATCH] i2c driver fixes for 2.6.0-test2 Greg KH
2005-05-19  6:24 ` Greg KH
2005-05-19  6:24 ` Jean Delvare
2005-05-19  6:24 ` Mark M. Hoffman
2005-05-19  6:24 ` Greg KH
2005-05-19  6:24 ` Greg KH
2005-05-19  6:24 ` Mark M. Hoffman
2003-08-14  5:13   ` Mark M. Hoffman
2005-05-19  6:24     ` Mark M. Hoffman
2003-08-14 21:14     ` Greg KH
2005-05-19  6:24       ` Greg KH
2005-05-19  6:24 ` [BK PATCH] i2c driver fixes for 2.6.0-test5 Mark M. Hoffman
2005-05-19  6:24 ` Mark M. Hoffman
2005-05-19  6:24 ` Jean Delvare
2005-05-19  6:24 ` Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.