From ca8b9e32a11a7cbfecbef00c8451a79fe1af392e Mon Sep 17 00:00:00 2001
From: Oleg Ryjkov <olegr@google.com>
Date: Thu, 12 Jul 2007 14:12:31 +0200
Subject: i2c-i801: Various cleanups

* Use defines instead of raw numbers for register bits
* Fix several wrong indentations and trailing whitespace
* Move hwpec timeout checking to a separate function

Signed-off-by: Oleg Ryjkov <olegr@google.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
---
 drivers/i2c/busses/i2c-i801.c | 116 +++++++++++++++++++++++++++---------------
 1 file changed, 75 insertions(+), 41 deletions(-)

(limited to 'drivers/i2c')

diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 611b57192c96..d5e12a4f01b0 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -22,10 +22,10 @@
 
 /*
     SUPPORTED DEVICES	PCI ID
-    82801AA		2413           
-    82801AB		2423           
-    82801BA		2443           
-    82801CA/CAM		2483           
+    82801AA		2413
+    82801AB		2423
+    82801BA		2443
+    82801CA/CAM		2483
     82801DB		24C3   (HW PEC supported, 32 byte buffer not supported)
     82801EB		24D3   (HW PEC supported, 32 byte buffer not supported)
     6300ESB		25A4
@@ -74,6 +74,13 @@
 #define SMBHSTCFG_SMB_SMI_EN	2
 #define SMBHSTCFG_I2C_EN	4
 
+/* Auxillary control register bits, ICH4+ only */
+#define SMBAUXCTL_CRC		1
+#define SMBAUXCTL_E32B		2
+
+/* kill bit for SMBHSTCNT */
+#define SMBHSTCNT_KILL		2
+
 /* Other settings */
 #define MAX_TIMEOUT		100
 #define ENABLE_INT9		0	/* set to 0x01 to enable - untested */
@@ -91,10 +98,15 @@
 #define I801_START		0x40
 #define I801_PEC_EN		0x80	/* ICH4 only */
 
-
-static int i801_transaction(void);
-static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
-				  int command, int hwpec);
+/* I801 Hosts Status register bits */
+#define SMBHSTSTS_BYTE_DONE	0x80
+#define SMBHSTSTS_INUSE_STS	0x40
+#define SMBHSTSTS_SMBALERT_STS	0x20
+#define SMBHSTSTS_FAILED	0x10
+#define SMBHSTSTS_BUS_ERR	0x08
+#define SMBHSTSTS_DEV_ERR	0x04
+#define SMBHSTSTS_INTR		0x02
+#define SMBHSTSTS_HOST_BUSY	0x01
 
 static unsigned long i801_smba;
 static unsigned char i801_original_hstcfg;
@@ -133,27 +145,32 @@ static int i801_transaction(void)
 	do {
 		msleep(1);
 		temp = inb_p(SMBHSTSTS);
-	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
+	} while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
 
 	/* If the SMBus is still busy, we give up */
 	if (timeout >= MAX_TIMEOUT) {
 		dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
 		result = -1;
+		/* try to stop the current command */
+		dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
+		outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+		msleep(1);
+		outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
 	}
 
-	if (temp & 0x10) {
+	if (temp & SMBHSTSTS_FAILED) {
 		result = -1;
 		dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
 	}
 
-	if (temp & 0x08) {
+	if (temp & SMBHSTSTS_BUS_ERR) {
 		result = -1;
 		dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
 			"until next hard reset. (sorry!)\n");
 		/* Clock stops and slave is stuck in mid-transmission */
 	}
 
-	if (temp & 0x04) {
+	if (temp & SMBHSTSTS_DEV_ERR) {
 		result = -1;
 		dev_dbg(&I801_dev->dev, "Error: no response!\n");
 	}
@@ -172,6 +189,24 @@ static int i801_transaction(void)
 	return result;
 }
 
+/* wait for INTR bit as advised by Intel */
+static void i801_wait_hwpec(void)
+{
+	int timeout = 0;
+	int temp;
+
+	do {
+		msleep(1);
+		temp = inb_p(SMBHSTSTS);
+	} while ((!(temp & SMBHSTSTS_INTR))
+		 && (timeout++ < MAX_TIMEOUT));
+
+	if (timeout >= MAX_TIMEOUT) {
+		dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
+	}
+	outb_p(temp, SMBHSTSTS);
+}
+
 /* All-inclusive block transaction function */
 static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
 				  int command, int hwpec)
@@ -227,13 +262,13 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
 		/* Make sure the SMBus host is ready to start transmitting */
 		temp = inb_p(SMBHSTSTS);
 		if (i == 1) {
-			/* Erronenous conditions before transaction: 
+			/* Erronenous conditions before transaction:
 			 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
-			errmask=0x9f; 
+			errmask = 0x9f;
 		} else {
-			/* Erronenous conditions during transaction: 
+			/* Erronenous conditions during transaction:
 			 * Failed, Bus_Err, Dev_Err, Intr */
-			errmask=0x1e; 
+			errmask = 0x1e;
 		}
 		if (temp & errmask) {
 			dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
@@ -243,7 +278,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
 				dev_err(&I801_dev->dev,
 					"Reset failed! (%02x)\n", temp);
 				result = -1;
-                                goto END;
+				goto END;
 			}
 			if (i != 1) {
 				/* if die in middle of block transaction, fail */
@@ -261,33 +296,40 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
 			msleep(1);
 			temp = inb_p(SMBHSTSTS);
 		}
-		    while ((!(temp & 0x80))
-			   && (timeout++ < MAX_TIMEOUT));
+		while ((!(temp & SMBHSTSTS_BYTE_DONE))
+		       && (timeout++ < MAX_TIMEOUT));
 
 		/* If the SMBus is still busy, we give up */
 		if (timeout >= MAX_TIMEOUT) {
+			/* try to stop the current command */
+			dev_dbg(&I801_dev->dev, "Terminating the current "
+						"operation\n");
+			outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
+			msleep(1);
+			outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
+				SMBHSTCNT);
 			result = -1;
 			dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
 		}
 
-		if (temp & 0x10) {
+		if (temp & SMBHSTSTS_FAILED) {
 			result = -1;
 			dev_dbg(&I801_dev->dev,
 				"Error: Failed bus transaction\n");
-		} else if (temp & 0x08) {
+		} else if (temp & SMBHSTSTS_BUS_ERR) {
 			result = -1;
 			dev_err(&I801_dev->dev, "Bus collision!\n");
-		} else if (temp & 0x04) {
+		} else if (temp & SMBHSTSTS_DEV_ERR) {
 			result = -1;
 			dev_dbg(&I801_dev->dev, "Error: no response!\n");
 		}
 
 		if (i == 1 && read_write == I2C_SMBUS_READ) {
 			len = inb_p(SMBHSTDAT0);
-			if (len < 1)
-				len = 1;
-			if (len > 32)
-				len = 32;
+			if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
+				result = -1;
+				goto END;
+			}
 			data->block[0] = len;
 		}
 
@@ -313,20 +355,9 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
 			goto END;
 	}
 
-	if (hwpec) {
-		/* wait for INTR bit as advised by Intel */
-		timeout = 0;
-		do {
-			msleep(1);
-			temp = inb_p(SMBHSTSTS);
-		} while ((!(temp & 0x02))
-			   && (timeout++ < MAX_TIMEOUT));
+	if (hwpec)
+		i801_wait_hwpec();
 
-		if (timeout >= MAX_TIMEOUT) {
-			dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
-		}
-		outb_p(temp, SMBHSTSTS); 
-	}
 	result = 0;
 END:
 	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
@@ -393,7 +424,10 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
 		return -1;
 	}
 
-	outb_p(hwpec, SMBAUXCTL);	/* enable/disable hardware PEC */
+	if (hwpec)	/* enable/disable hardware PEC */
+		outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_CRC, SMBAUXCTL);
+	else
+		outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
 
 	if(block)
 		ret = i801_block_transaction(data, read_write, size, hwpec);
@@ -405,7 +439,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
 	/* Some BIOSes don't like it when PEC is enabled at reboot or resume
 	   time, so we forcibly disable it after every transaction. */
 	if (hwpec)
-		outb_p(0, SMBAUXCTL);
+		outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
 
 	if(block)
 		return ret;
-- 
cgit v1.2.3