Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca8b9e32 authored by Oleg Ryjkov's avatar Oleg Ryjkov Committed by Jean Delvare
Browse files

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: default avatarOleg Ryjkov <olegr@google.com>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent a92c344d
Loading
Loading
Loading
Loading
+75 −41
Original line number Diff line number Diff line
@@ -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)
@@ -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))
		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;