aboutsummaryrefslogtreecommitdiffstats
path: root/i2c
diff options
context:
space:
mode:
authorGreg KH <greg@press.(none)>2005-10-27 17:54:25 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-27 17:54:25 -0700
commitd303dfd6695485a8ad35534873952e8405c1825a (patch)
treeafaeedf35ea61f07b01a79540cc480076878d191 /i2c
parentfab486cd4f178aba2163a6db00ad8b282956e09a (diff)
downloadpatches-d303dfd6695485a8ad35534873952e8405c1825a.tar.gz
more i2c and 2 usb patches
Diffstat (limited to 'i2c')
-rw-r--r--i2c/hwmon-lm90-01-separate-read-reg.patch170
-rw-r--r--i2c/hwmon-lm90-02-add-pec-adm1032.patch182
-rw-r--r--i2c/hwmon-lm90-03-new-addresses.patch91
-rw-r--r--i2c/hwmon-smsc47m1-mention-47m997.patch72
-rw-r--r--i2c/i2c-i801-simplify-hwpec-tests.patch75
-rw-r--r--i2c/i2c-smbus-pec-02-swpec-rewrite.patch333
-rw-r--r--i2c/i2c-smbus-pec-03-drop-swpec-sizes.patch116
7 files changed, 1039 insertions, 0 deletions
diff --git a/i2c/hwmon-lm90-01-separate-read-reg.patch b/i2c/hwmon-lm90-01-separate-read-reg.patch
new file mode 100644
index 0000000000000..ab20208607e27
--- /dev/null
+++ b/i2c/hwmon-lm90-01-separate-read-reg.patch
@@ -0,0 +1,170 @@
+From khali@linux-fr.org Wed Oct 26 12:37:30 2005
+Date: Wed, 26 Oct 2005 21:37:52 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Subject: [PATCH 13/16] hwmon: Separate the lm90 register read function
+Message-Id: <20051026213752.3a3e2715.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-lm90-01-separate-read-reg.patch
+
+Preparatory patch to add PEC support to the lm90 driver. We need a
+centralized function to read register values, where the PEC code will
+be later inserted. A positive side effect is that read errors are now
+handled properly.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hwmon/lm90.c | 107 +++++++++++++++++++++++++--------------------------
+ 1 file changed, 53 insertions(+), 54 deletions(-)
+
+--- gregkh-2.6.orig/drivers/hwmon/lm90.c
++++ gregkh-2.6/drivers/hwmon/lm90.c
+@@ -349,6 +349,22 @@ static DEVICE_ATTR(alarms, S_IRUGO, show
+ * Real code
+ */
+
++static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
++{
++ int err;
++
++ err = i2c_smbus_read_byte_data(client, reg);
++
++ if (err < 0) {
++ dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
++ reg, err);
++ return err;
++ }
++ *value = err;
++
++ return 0;
++}
++
+ static int lm90_attach_adapter(struct i2c_adapter *adapter)
+ {
+ if (!(adapter->class & I2C_CLASS_HWMON))
+@@ -402,20 +418,22 @@ static int lm90_detect(struct i2c_adapte
+ if (kind < 0) { /* detection and identification */
+ u8 man_id, chip_id, reg_config1, reg_convrate;
+
+- man_id = i2c_smbus_read_byte_data(new_client,
+- LM90_REG_R_MAN_ID);
+- chip_id = i2c_smbus_read_byte_data(new_client,
+- LM90_REG_R_CHIP_ID);
+- reg_config1 = i2c_smbus_read_byte_data(new_client,
+- LM90_REG_R_CONFIG1);
+- reg_convrate = i2c_smbus_read_byte_data(new_client,
+- LM90_REG_R_CONVRATE);
++ if (lm90_read_reg(new_client, LM90_REG_R_MAN_ID,
++ &man_id) < 0
++ || lm90_read_reg(new_client, LM90_REG_R_CHIP_ID,
++ &chip_id) < 0
++ || lm90_read_reg(new_client, LM90_REG_R_CONFIG1,
++ &reg_config1) < 0
++ || lm90_read_reg(new_client, LM90_REG_R_CONVRATE,
++ &reg_convrate) < 0)
++ goto exit_free;
+
+ if (man_id == 0x01) { /* National Semiconductor */
+ u8 reg_config2;
+
+- reg_config2 = i2c_smbus_read_byte_data(new_client,
+- LM90_REG_R_CONFIG2);
++ if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2,
++ &reg_config2) < 0)
++ goto exit_free;
+
+ if ((reg_config1 & 0x2A) == 0x00
+ && (reg_config2 & 0xF8) == 0x00
+@@ -547,7 +565,10 @@ static void lm90_init_client(struct i2c_
+ */
+ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE,
+ 5); /* 2 Hz */
+- config = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG1);
++ if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) {
++ dev_warn(&client->dev, "Initialization failed!\n");
++ return;
++ }
+ if (config & 0x40)
+ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+ config & 0xBF); /* run */
+@@ -575,21 +596,15 @@ static struct lm90_data *lm90_update_dev
+ down(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+- u8 oldh, newh;
++ u8 oldh, newh, l;
+
+ dev_dbg(&client->dev, "Updating lm90 data.\n");
+- data->temp8[0] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_LOCAL_TEMP);
+- data->temp8[1] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_LOCAL_LOW);
+- data->temp8[2] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_LOCAL_HIGH);
+- data->temp8[3] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_LOCAL_CRIT);
+- data->temp8[4] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_CRIT);
+- data->temp_hyst = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_TCRIT_HYST);
++ lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]);
++ lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]);
++ lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]);
++ lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]);
++ lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]);
++ lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
+
+ /*
+ * There is a trick here. We have to read two registers to
+@@ -605,36 +620,20 @@ static struct lm90_data *lm90_update_dev
+ * then we have a valid reading. Else we have to read the low
+ * byte again, and now we believe we have a correct reading.
+ */
+- oldh = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_TEMPH);
+- data->temp11[0] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_TEMPL);
+- newh = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_TEMPH);
+- if (newh != oldh) {
+- data->temp11[0] = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_TEMPL);
+-#ifdef DEBUG
+- oldh = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_TEMPH);
+- /* oldh is actually newer */
+- if (newh != oldh)
+- dev_warn(&client->dev, "Remote temperature may be "
+- "wrong.\n");
+-#endif
+- }
+- data->temp11[0] |= (newh << 8);
+-
+- data->temp11[1] = (i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_LOWH) << 8) +
+- i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_LOWL);
+- data->temp11[2] = (i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_HIGHH) << 8) +
+- i2c_smbus_read_byte_data(client,
+- LM90_REG_R_REMOTE_HIGHL);
+- data->alarms = i2c_smbus_read_byte_data(client,
+- LM90_REG_R_STATUS);
++ if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0
++ && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0
++ && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0
++ && (newh == oldh
++ || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0))
++ data->temp11[0] = (newh << 8) | l;
++
++ if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0
++ && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0)
++ data->temp11[1] = (newh << 8) | l;
++ if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0
++ && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0)
++ data->temp11[2] = (newh << 8) | l;
++ lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
diff --git a/i2c/hwmon-lm90-02-add-pec-adm1032.patch b/i2c/hwmon-lm90-02-add-pec-adm1032.patch
new file mode 100644
index 0000000000000..cbf073ea29c67
--- /dev/null
+++ b/i2c/hwmon-lm90-02-add-pec-adm1032.patch
@@ -0,0 +1,182 @@
+From khali@linux-fr.org Wed Oct 26 12:42:47 2005
+Date: Wed, 26 Oct 2005 21:39:40 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Subject: [PATCH 14/16] hwmon: Add PEC support to the lm90 driver
+Message-Id: <20051026213940.601406a8.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-lm90-02-add-pec-adm1032.patch
+
+Add PEC support to the lm90 driver. Only the ADM1032 chip supports it,
+and in a rather tricky way, which is why this patch comes with
+documentation reinforcements. At least, this demonstrates that the new
+PEC support logic in i2c-core can properly deal with chips with partial
+PEC support.
+
+As enabling PEC causes a significant performance drop, it can be
+disabled through a sysfs file (unsurprisingly named "pec").
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/hwmon/lm90 | 39 +++++++++++++++++++++++-
+ Documentation/hwmon/sysfs-interface | 3 +
+ drivers/hwmon/lm90.c | 57 +++++++++++++++++++++++++++++++++++-
+ 3 files changed, 96 insertions(+), 3 deletions(-)
+
+--- gregkh-2.6.orig/drivers/hwmon/lm90.c
++++ gregkh-2.6/drivers/hwmon/lm90.c
+@@ -345,15 +345,63 @@ static SENSOR_DEVICE_ATTR(temp1_crit_hys
+ static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
+ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
++/* pec used for ADM1032 only */
++static ssize_t show_pec(struct device *dev, struct device_attribute *dummy,
++ char *buf)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ return sprintf(buf, "%d\n", !!(client->flags & I2C_CLIENT_PEC));
++}
++
++static ssize_t set_pec(struct device *dev, struct device_attribute *dummy,
++ const char *buf, size_t count)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ long val = simple_strtol(buf, NULL, 10);
++
++ switch (val) {
++ case 0:
++ client->flags &= ~I2C_CLIENT_PEC;
++ break;
++ case 1:
++ client->flags |= I2C_CLIENT_PEC;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return count;
++}
++
++static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec);
++
+ /*
+ * Real code
+ */
+
++/* The ADM1032 supports PEC but not on write byte transactions, so we need
++ to explicitely ask for a transaction without PEC. */
++static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
++{
++ return i2c_smbus_xfer(client->adapter, client->addr,
++ client->flags & ~I2C_CLIENT_PEC,
++ I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
++}
++
++/* It is assumed that client->update_lock is held (unless we are in
++ detection or initialization steps). This matters when PEC is enabled,
++ because we don't want the address pointer to change between the write
++ byte and the read byte transactions. */
+ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
+ {
+ int err;
+
+- err = i2c_smbus_read_byte_data(client, reg);
++ if (client->flags & I2C_CLIENT_PEC) {
++ err = adm1032_write_byte(client, reg);
++ if (err >= 0)
++ err = i2c_smbus_read_byte(client);
++ } else
++ err = i2c_smbus_read_byte_data(client, reg);
+
+ if (err < 0) {
+ dev_warn(&client->dev, "Register %#02x read failed (%d)\n",
+@@ -494,6 +542,10 @@ static int lm90_detect(struct i2c_adapte
+ name = "lm90";
+ } else if (kind == adm1032) {
+ name = "adm1032";
++ /* The ADM1032 supports PEC, but only if combined
++ transactions are not used. */
++ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
++ new_client->flags |= I2C_CLIENT_PEC;
+ } else if (kind == lm99) {
+ name = "lm99";
+ } else if (kind == lm86) {
+@@ -546,6 +598,9 @@ static int lm90_detect(struct i2c_adapte
+ &sensor_dev_attr_temp2_crit_hyst.dev_attr);
+ device_create_file(&new_client->dev, &dev_attr_alarms);
+
++ if (new_client->flags & I2C_CLIENT_PEC)
++ device_create_file(&new_client->dev, &dev_attr_pec);
++
+ return 0;
+
+ exit_detach:
+--- gregkh-2.6.orig/Documentation/hwmon/lm90
++++ gregkh-2.6/Documentation/hwmon/lm90
+@@ -71,8 +71,8 @@ increased resolution of the remote tempe
+
+ The different chipsets of the family are not strictly identical, although
+ very similar. This driver doesn't handle any specific feature for now,
+-but could if there ever was a need for it. For reference, here comes a
+-non-exhaustive list of specific features:
++with the exception of SMBus PEC. For reference, here comes a non-exhaustive
++list of specific features:
+
+ LM90:
+ * Filter and alert configuration register at 0xBF.
+@@ -91,6 +91,7 @@ ADM1032:
+ * Conversion averaging.
+ * Up to 64 conversions/s.
+ * ALERT is triggered by open remote sensor.
++ * SMBus PEC support for Write Byte and Receive Byte transactions.
+
+ ADT7461
+ * Extended temperature range (breaks compatibility)
+@@ -119,3 +120,37 @@ The lm90 driver will not update its valu
+ other second; reading them more often will do no harm, but will return
+ 'old' values.
+
++PEC Support
++-----------
++
++The ADM1032 is the only chip of the family which supports PEC. It does
++not support PEC on all transactions though, so some care must be taken.
++
++When reading a register value, the PEC byte is computed and sent by the
++ADM1032 chip. However, in the case of a combined transaction (SMBus Read
++Byte), the ADM1032 computes the CRC value over only the second half of
++the message rather than its entirety, because it thinks the first half
++of the message belongs to a different transaction. As a result, the CRC
++value differs from what the SMBus master expects, and all reads fail.
++
++For this reason, the lm90 driver will enable PEC for the ADM1032 only if
++the bus supports the SMBus Send Byte and Receive Byte transaction types.
++These transactions will be used to read register values, instead of
++SMBus Read Byte, and PEC will work properly.
++
++Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC.
++Instead, it will try to write the PEC value to the register (because the
++SMBus Send Byte transaction with PEC is similar to a Write Byte transaction
++without PEC), which is not what we want. Thus, PEC is explicitely disabled
++on SMBus Send Byte transactions in the lm90 driver.
++
++PEC on byte data transactions represents a significant increase in bandwidth
++usage (+33% for writes, +25% for reads) in normal conditions. With the need
++to use two SMBus transaction for reads, this overhead jumps to +50%. Worse,
++two transactions will typically mean twice as much delay waiting for
++transaction completion, effectively doubling the register cache refresh time.
++I guess reliability comes at a price, but it's quite expensive this time.
++
++So, as not everyone might enjoy the slowdown, PEC can be disabled through
++sysfs. Just write 0 to the "pec" file and PEC will be disabled. Write 1
++to that file to enable PEC again.
+--- gregkh-2.6.orig/Documentation/hwmon/sysfs-interface
++++ gregkh-2.6/Documentation/hwmon/sysfs-interface
+@@ -272,3 +272,6 @@ beep_mask Bitmask for beep.
+
+ eeprom Raw EEPROM data in binary form.
+ Read only.
++
++pec Enable or disable PEC (SMBus only)
++ Read/Write
diff --git a/i2c/hwmon-lm90-03-new-addresses.patch b/i2c/hwmon-lm90-03-new-addresses.patch
new file mode 100644
index 0000000000000..8ccebf1418ecc
--- /dev/null
+++ b/i2c/hwmon-lm90-03-new-addresses.patch
@@ -0,0 +1,91 @@
+From khali@linux-fr.org Wed Oct 26 13:21:58 2005
+Date: Wed, 26 Oct 2005 22:20:21 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Subject: [PATCH 15/16] hwmon: lm90 documentation update
+Message-Id: <20051026222021.39cc28bd.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-lm90-03-new-addresses.patch
+
+Update the I2C addresses for the ADM1032 and ADT7461 chips.
+Also update the links to the Analog Devices web site.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/hwmon/lm90 | 8 ++++----
+ drivers/hwmon/lm90.c | 16 +++++++---------
+ 2 files changed, 11 insertions(+), 13 deletions(-)
+
+--- gregkh-2.6.orig/Documentation/hwmon/lm90
++++ gregkh-2.6/Documentation/hwmon/lm90
+@@ -24,14 +24,14 @@ Supported chips:
+ http://www.national.com/pf/LM/LM86.html
+ * Analog Devices ADM1032
+ Prefix: 'adm1032'
+- Addresses scanned: I2C 0x4c
++ Addresses scanned: I2C 0x4c and 0x4d
+ Datasheet: Publicly available at the Analog Devices website
+- http://products.analog.com/products/info.asp?product=ADM1032
++ http://www.analog.com/en/prod/0,2877,ADM1032,00.html
+ * Analog Devices ADT7461
+ Prefix: 'adt7461'
+- Addresses scanned: I2C 0x4c
++ Addresses scanned: I2C 0x4c and 0x4d
+ Datasheet: Publicly available at the Analog Devices website
+- http://products.analog.com/products/info.asp?product=ADT7461
++ http://www.analog.com/en/prod/0,2877,ADT7461,00.html
+ Note: Only if in ADM1032 compatibility mode
+ * Maxim MAX6657
+ Prefix: 'max6657'
+--- gregkh-2.6.orig/drivers/hwmon/lm90.c
++++ gregkh-2.6/drivers/hwmon/lm90.c
+@@ -31,7 +31,7 @@
+ * Devices. That chip is similar to the LM90, with a few differences
+ * that are not handled by this driver. Complete datasheet can be
+ * obtained from Analog's website at:
+- * http://products.analog.com/products/info.asp?product=ADM1032
++ * http://www.analog.com/en/prod/0,2877,ADM1032,00.html
+ * Among others, it has a higher accuracy than the LM90, much like the
+ * LM86 does.
+ *
+@@ -49,7 +49,7 @@
+ * register values are decoded differently) it is ignored by this
+ * driver. Complete datasheet can be obtained from Analog's website
+ * at:
+- * http://products.analog.com/products/info.asp?product=ADT7461
++ * http://www.analog.com/en/prod/0,2877,ADT7461,00.html
+ *
+ * Since the LM90 was the first chipset supported by this driver, most
+ * comments will refer to this chipset, but are actually general and
+@@ -83,10 +83,10 @@
+ * Addresses to scan
+ * Address is fully defined internally and cannot be changed except for
+ * MAX6659.
+- * LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
+- * LM89-1, and LM99-1 have address 0x4d.
++ * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
++ * have address 0x4c.
++ * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
+ * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
+- * ADT7461 always has address 0x4c.
+ */
+
+ static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
+@@ -500,14 +500,12 @@ static int lm90_detect(struct i2c_adapte
+ }
+ } else
+ if (man_id == 0x41) { /* Analog Devices */
+- if (address == 0x4C
+- && (chip_id & 0xF0) == 0x40 /* ADM1032 */
++ if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
+ && (reg_config1 & 0x3F) == 0x00
+ && reg_convrate <= 0x0A) {
+ kind = adm1032;
+ } else
+- if (address == 0x4c
+- && chip_id == 0x51 /* ADT7461 */
++ if (chip_id == 0x51 /* ADT7461 */
+ && (reg_config1 & 0x1F) == 0x00 /* check compat mode */
+ && reg_convrate <= 0x0A) {
+ kind = adt7461;
diff --git a/i2c/hwmon-smsc47m1-mention-47m997.patch b/i2c/hwmon-smsc47m1-mention-47m997.patch
new file mode 100644
index 0000000000000..9d217c17f7647
--- /dev/null
+++ b/i2c/hwmon-smsc47m1-mention-47m997.patch
@@ -0,0 +1,72 @@
+From khali@linux-fr.org Wed Oct 26 13:22:04 2005
+Date: Wed, 26 Oct 2005 22:21:24 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Subject: [PATCH 16/16] hwmon: smsc47m1 documentation update
+Message-Id: <20051026222124.66f6138e.khali@linux-fr.org>
+Content-Disposition: inline; filename=hwmon-smsc47m1-mention-47m997.patch
+
+The SMSC LPC47M997 Super-I/O chip seems to be compatible with the
+LPC47M192, so it is supported by the smsc47m1 driver.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/hwmon/smsc47m1 | 7 +++++++
+ drivers/hwmon/smsc47m1.c | 7 +++++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/Documentation/hwmon/smsc47m1
++++ gregkh-2.6/Documentation/hwmon/smsc47m1
+@@ -12,6 +12,10 @@ Supported chips:
+ http://www.smsc.com/main/datasheets/47m14x.pdf
+ http://www.smsc.com/main/tools/discontinued/47m15x.pdf
+ http://www.smsc.com/main/datasheets/47m192.pdf
++ * SMSC LPC47M997
++ Addresses scanned: none, address read from Super I/O config space
++ Prefix: 'smsc47m1'
++ Datasheet: none
+
+ Authors:
+ Mark D. Studebaker <mdsxyz123@yahoo.com>,
+@@ -30,6 +34,9 @@ The 47M15x and 47M192 chips contain a fu
+ in addition to the fan monitoring and control. The hardware monitoring
+ block is not supported by the driver.
+
++No documentation is available for the 47M997, but it has the same device
++ID as the 47M15x and 47M192 chips and seems to be compatible.
++
+ Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+ triggered if the rotation speed has dropped below a programmable limit. Fan
+ readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+--- gregkh-2.6.orig/drivers/hwmon/smsc47m1.c
++++ gregkh-2.6/drivers/hwmon/smsc47m1.c
+@@ -3,7 +3,7 @@
+ for hardware monitoring
+
+ Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
+- LPC47M15x and LPC47M192 Super-I/O chips.
++ LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
+
+ Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+ Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
+@@ -356,6 +356,8 @@ static int __init smsc47m1_find(unsigned
+ * 0x5F) and LPC47B27x (device id 0x51) have fan control.
+ * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
+ * can do much more besides (device id 0x60).
++ * The LPC47M997 is undocumented, but seems to be compatible with
++ * the LPC47M192, and has the same device id.
+ */
+ if (val == 0x51)
+ printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
+@@ -364,7 +366,8 @@ static int __init smsc47m1_find(unsigned
+ else if (val == 0x5F)
+ printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
+ else if (val == 0x60)
+- printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n");
++ printk(KERN_INFO "smsc47m1: Found SMSC "
++ "LPC47M15x/LPC47M192/LPC47M997\n");
+ else {
+ superio_exit();
+ return -ENODEV;
diff --git a/i2c/i2c-i801-simplify-hwpec-tests.patch b/i2c/i2c-i801-simplify-hwpec-tests.patch
new file mode 100644
index 0000000000000..51ccf8e78426b
--- /dev/null
+++ b/i2c/i2c-i801-simplify-hwpec-tests.patch
@@ -0,0 +1,75 @@
+From khali@linux-fr.org Wed Oct 26 12:37:23 2005
+Date: Wed, 26 Oct 2005 21:34:42 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Subject: [PATCH 12/16] i2c: i2c-i801 PEC code cleanups
+Message-Id: <20051026213442.30f013ec.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-i801-simplify-hwpec-tests.patch
+
+The tests leading to the use of hardware PEC in the i2c-i801 driver
+can be simplified.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-i801.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -388,7 +388,7 @@ static int i801_block_transaction(union
+ goto END;
+ }
+
+- if (hwpec && command == I2C_SMBUS_BLOCK_DATA) {
++ if (hwpec) {
+ /* wait for INTR bit as advised by Intel */
+ timeout = 0;
+ do {
+@@ -416,12 +416,13 @@ static s32 i801_access(struct i2c_adapte
+ unsigned short flags, char read_write, u8 command,
+ int size, union i2c_smbus_data * data)
+ {
+- int hwpec = 0;
++ int hwpec;
+ int block = 0;
+ int ret, xact = 0;
+
+- if(isich4)
+- hwpec = (flags & I2C_CLIENT_PEC) != 0;
++ hwpec = isich4 && (flags & I2C_CLIENT_PEC)
++ && size != I2C_SMBUS_QUICK
++ && size != I2C_SMBUS_I2C_BLOCK_DATA;
+
+ switch (size) {
+ case I2C_SMBUS_QUICK:
+@@ -467,11 +468,9 @@ static s32 i801_access(struct i2c_adapte
+ return -1;
+ }
+
+- if(isich4 && hwpec) {
+- if(size != I2C_SMBUS_QUICK &&
+- size != I2C_SMBUS_I2C_BLOCK_DATA)
+- outb_p(1, SMBAUXCTL); /* enable HW PEC */
+- }
++ if (hwpec)
++ outb_p(1, SMBAUXCTL); /* enable hardware PEC */
++
+ if(block)
+ ret = i801_block_transaction(data, read_write, size, hwpec);
+ else {
+@@ -479,11 +478,8 @@ static s32 i801_access(struct i2c_adapte
+ ret = i801_transaction();
+ }
+
+- if(isich4 && hwpec) {
+- if(size != I2C_SMBUS_QUICK &&
+- size != I2C_SMBUS_I2C_BLOCK_DATA)
+- outb_p(0, SMBAUXCTL);
+- }
++ if (hwpec)
++ outb_p(0, SMBAUXCTL); /* disable hardware PEC */
+
+ if(block)
+ return ret;
diff --git a/i2c/i2c-smbus-pec-02-swpec-rewrite.patch b/i2c/i2c-smbus-pec-02-swpec-rewrite.patch
new file mode 100644
index 0000000000000..2d2673523d2f3
--- /dev/null
+++ b/i2c/i2c-smbus-pec-02-swpec-rewrite.patch
@@ -0,0 +1,333 @@
+From khali@linux-fr.org Wed Oct 26 12:31:49 2005
+Date: Wed, 26 Oct 2005 21:28:55 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Cc: Hideki Iwamoto <h-iwamoto@kit.hi-ho.ne.jp>
+Subject: [PATCH 10/16] i2c: SMBus PEC support rewrite, 2 of 3
+Message-Id: <20051026212855.027a76f4.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-smbus-pec-02-swpec-rewrite.patch
+
+This is my rewrite of the SMBus PEC support. The original
+implementation was known to have bugs (credits go to Hideki Iwamoto
+for reporting many of them recently), and was incomplete due to a
+conceptual limitation.
+
+The rewrite affects only software PEC. Hardware PEC needs very little
+code and is mostly untouched.
+
+Technically, both implementations differ in that the original one
+was emulating PEC in software by modifying the contents of an
+i2c_smbus_data union (changing the transaction to a different type),
+while the new one works one level lower, on i2c_msg structures (working
+on message contents). Due to the definition of the i2c_smbus_data union,
+not all SMBus transactions could be handled (at least not without
+changing the definition of this union, which would break user-space
+compatibility), and those which could had to be implemented
+individually. At the opposite, adding PEC to an i2c_msg structure
+can be done on any SMBus transaction with common code.
+
+Advantages of the new implementation:
+
+* It's about twice as small (from ~136 lines before to ~70 now, only
+ counting i2c-core, including blank and comment lines). The memory
+ used by i2c-core is down by ~640 bytes (~3.5%).
+
+* Easier to validate, less tricky code. The code being common to all
+ transactions by design, the risk that a bug can stay uncovered is
+ lower.
+
+* All SMBus transactions have PEC support in I2C emulation mode
+ (providing the non-PEC transaction is also implemented). Transactions
+ which have no emulation code right now will get PEC support for free
+ when they finally get implemented.
+
+* Allows for code simplifications in header files and bus drivers
+ (patch follows).
+
+Drawbacks (I guess there had to be at least one):
+
+* PEC emulation for non-PEC capable non-I2C SMBus masters was dropped.
+ It was based on SMBus tricks and doesn't quite fit in the new design.
+ I don't think it's really a problem, as the benefit was certainly
+ not worth the additional complexity, but it's only fair that I at
+ least mention it.
+
+Lastly, let's note that the new implementation does slightly affect
+compatibility (both in kernel and user-space), but doesn't actually
+break it. Some defines will be dropped, but the code can always be
+changed in a way that will work with both the old and the new
+implementations. It shouldn't be a problem as there doesn't seem to be
+many users of SMBus PEC to date anyway.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/i2c-core.c | 162 ++++++++++++++-----------------------------------
+ include/linux/i2c.h | 2
+ 2 files changed, 49 insertions(+), 115 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/i2c-core.c
++++ gregkh-2.6/drivers/i2c/i2c-core.c
+@@ -19,7 +19,8 @@
+
+ /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
+ All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
+- SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> */
++ SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
++ Jean Delvare <khali@linux-fr.org> */
+
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+@@ -830,101 +831,44 @@ crc8(u16 data)
+ return (u8)(data >> 8);
+ }
+
+-/* CRC over count bytes in the first array plus the bytes in the rest
+- array if it is non-null. rest[0] is the (length of rest) - 1
+- and is included. */
+-static u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest)
++/* Incremental CRC8 over count bytes in the array pointed to by p */
++static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)
+ {
+ int i;
+
+ for(i = 0; i < count; i++)
+- crc = crc8((crc ^ first[i]) << 8);
+- if(rest != NULL)
+- for(i = 0; i <= rest[0]; i++)
+- crc = crc8((crc ^ rest[i]) << 8);
++ crc = crc8((crc ^ p[i]) << 8);
+ return crc;
+ }
+
+-static u8 i2c_smbus_pec(int count, u8 *first, u8 *rest)
++/* Assume a 7-bit address, which is reasonable for SMBus */
++static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)
+ {
+- return i2c_smbus_partial_pec(0, count, first, rest);
++ /* The address will be sent first */
++ u8 addr = (msg->addr << 1) | !!(msg->flags & I2C_M_RD);
++ pec = i2c_smbus_pec(pec, &addr, 1);
++
++ /* The data buffer follows */
++ return i2c_smbus_pec(pec, msg->buf, msg->len);
+ }
+
+-/* Returns new "size" (transaction type)
+- Note that we convert byte to byte_data and byte_data to word_data
+- rather than invent new xxx_PEC transactions. */
+-static int i2c_smbus_add_pec(u16 addr, u8 command, int size,
+- union i2c_smbus_data *data)
++/* Used for write only transactions */
++static inline void i2c_smbus_add_pec(struct i2c_msg *msg)
+ {
+- u8 buf[3];
+-
+- buf[0] = addr << 1;
+- buf[1] = command;
+- switch(size) {
+- case I2C_SMBUS_BYTE:
+- data->byte = i2c_smbus_pec(2, buf, NULL);
+- size = I2C_SMBUS_BYTE_DATA;
+- break;
+- case I2C_SMBUS_BYTE_DATA:
+- buf[2] = data->byte;
+- data->word = buf[2] |
+- (i2c_smbus_pec(3, buf, NULL) << 8);
+- size = I2C_SMBUS_WORD_DATA;
+- break;
+- case I2C_SMBUS_WORD_DATA:
+- /* unsupported */
+- break;
+- case I2C_SMBUS_BLOCK_DATA:
+- data->block[data->block[0] + 1] =
+- i2c_smbus_pec(2, buf, data->block);
+- size = I2C_SMBUS_BLOCK_DATA_PEC;
+- break;
+- }
+- return size;
++ msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg);
++ msg->len++;
+ }
+
+-static int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial,
+- union i2c_smbus_data *data)
++/* Return <0 on CRC error
++ If there was a write before this read (most cases) we need to take the
++ partial CRC from the write part into account.
++ Note that this function does modify the message (we need to decrease the
++ message length to hide the CRC byte from the caller). */
++static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
+ {
+- u8 buf[3], rpec, cpec;
++ u8 rpec = msg->buf[--msg->len];
++ cpec = i2c_smbus_msg_pec(cpec, msg);
+
+- buf[1] = command;
+- switch(size) {
+- case I2C_SMBUS_BYTE_DATA:
+- buf[0] = (addr << 1) | 1;
+- cpec = i2c_smbus_pec(2, buf, NULL);
+- rpec = data->byte;
+- break;
+- case I2C_SMBUS_WORD_DATA:
+- buf[0] = (addr << 1) | 1;
+- buf[2] = data->word & 0xff;
+- cpec = i2c_smbus_pec(3, buf, NULL);
+- rpec = data->word >> 8;
+- break;
+- case I2C_SMBUS_WORD_DATA_PEC:
+- /* unsupported */
+- cpec = rpec = 0;
+- break;
+- case I2C_SMBUS_PROC_CALL_PEC:
+- /* unsupported */
+- cpec = rpec = 0;
+- break;
+- case I2C_SMBUS_BLOCK_DATA_PEC:
+- buf[0] = (addr << 1);
+- buf[2] = (addr << 1) | 1;
+- cpec = i2c_smbus_pec(3, buf, data->block);
+- rpec = data->block[data->block[0] + 1];
+- break;
+- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+- buf[0] = (addr << 1) | 1;
+- rpec = i2c_smbus_partial_pec(partial, 1,
+- buf, data->block);
+- cpec = data->block[data->block[0] + 1];
+- break;
+- default:
+- cpec = rpec = 0;
+- break;
+- }
+ if (rpec != cpec) {
+ pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
+ rpec, cpec);
+@@ -951,9 +895,8 @@ s32 i2c_smbus_read_byte(struct i2c_clien
+
+ s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value)
+ {
+- union i2c_smbus_data data; /* only for PEC */
+ return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
+- I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,&data);
++ I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL);
+ }
+
+ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
+@@ -1043,6 +986,7 @@ static s32 i2c_smbus_xfer_emulated(struc
+ { addr, flags | I2C_M_RD, 0, msgbuf1 }
+ };
+ int i;
++ u8 partial_pec = 0;
+
+ msgbuf0[0] = command;
+ switch(size) {
+@@ -1085,7 +1029,6 @@ static s32 i2c_smbus_xfer_emulated(struc
+ msgbuf0[2] = (data->word >> 8) & 0xff;
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+- case I2C_SMBUS_BLOCK_DATA_PEC:
+ if (read_write == I2C_SMBUS_READ) {
+ dev_err(&adapter->dev, "Block read not supported "
+ "under I2C emulation!\n");
+@@ -1098,14 +1041,11 @@ static s32 i2c_smbus_xfer_emulated(struc
+ data->block[0]);
+ return -1;
+ }
+- if(size == I2C_SMBUS_BLOCK_DATA_PEC)
+- (msg[0].len)++;
+ for (i = 1; i < msg[0].len; i++)
+ msgbuf0[i] = data->block[i-1];
+ }
+ break;
+ case I2C_SMBUS_BLOCK_PROC_CALL:
+- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+ dev_dbg(&adapter->dev, "Block process call not supported "
+ "under I2C emulation!\n");
+ return -1;
+@@ -1130,9 +1070,30 @@ static s32 i2c_smbus_xfer_emulated(struc
+ return -1;
+ }
+
++ i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK
++ && size != I2C_SMBUS_I2C_BLOCK_DATA);
++ if (i) {
++ /* Compute PEC if first message is a write */
++ if (!(msg[0].flags & I2C_M_RD)) {
++ if (num == 1) /* Write only */
++ i2c_smbus_add_pec(&msg[0]);
++ else /* Write followed by read */
++ partial_pec = i2c_smbus_msg_pec(0, &msg[0]);
++ }
++ /* Ask for PEC if last message is a read */
++ if (msg[num-1].flags & I2C_M_RD)
++ msg[num-1].len++;
++ }
++
+ if (i2c_transfer(adapter, msg, num) < 0)
+ return -1;
+
++ /* Check PEC if last message is a read */
++ if (i && (msg[num-1].flags & I2C_M_RD)) {
++ if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0)
++ return -1;
++ }
++
+ if (read_write == I2C_SMBUS_READ)
+ switch(size) {
+ case I2C_SMBUS_BYTE:
+@@ -1161,28 +1122,8 @@ s32 i2c_smbus_xfer(struct i2c_adapter *
+ union i2c_smbus_data * data)
+ {
+ s32 res;
+- int swpec = 0;
+- u8 partial = 0;
+
+ flags &= I2C_M_TEN | I2C_CLIENT_PEC;
+- if((flags & I2C_CLIENT_PEC) &&
+- !(i2c_check_functionality(adapter, I2C_FUNC_SMBUS_HWPEC_CALC))) {
+- swpec = 1;
+- if(read_write == I2C_SMBUS_READ &&
+- size == I2C_SMBUS_BLOCK_DATA)
+- size = I2C_SMBUS_BLOCK_DATA_PEC;
+- else if(size == I2C_SMBUS_PROC_CALL)
+- size = I2C_SMBUS_PROC_CALL_PEC;
+- else if(size == I2C_SMBUS_BLOCK_PROC_CALL) {
+- i2c_smbus_add_pec(addr, command,
+- I2C_SMBUS_BLOCK_DATA, data);
+- partial = data->block[data->block[0] + 1];
+- size = I2C_SMBUS_BLOCK_PROC_CALL_PEC;
+- } else if(read_write == I2C_SMBUS_WRITE &&
+- size != I2C_SMBUS_QUICK &&
+- size != I2C_SMBUS_I2C_BLOCK_DATA)
+- size = i2c_smbus_add_pec(addr, command, size, data);
+- }
+
+ if (adapter->algo->smbus_xfer) {
+ down(&adapter->bus_lock);
+@@ -1193,13 +1134,6 @@ s32 i2c_smbus_xfer(struct i2c_adapter *
+ res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
+ command,size,data);
+
+- if(res >= 0 && swpec &&
+- size != I2C_SMBUS_QUICK && size != I2C_SMBUS_I2C_BLOCK_DATA &&
+- (read_write == I2C_SMBUS_READ || size == I2C_SMBUS_PROC_CALL_PEC ||
+- size == I2C_SMBUS_BLOCK_PROC_CALL_PEC)) {
+- if(i2c_smbus_check_pec(addr, command, size, partial, data))
+- return -1;
+- }
+ return res;
+ }
+
+--- gregkh-2.6.orig/include/linux/i2c.h
++++ gregkh-2.6/include/linux/i2c.h
+@@ -435,7 +435,7 @@ union i2c_smbus_data {
+ __u8 byte;
+ __u16 word;
+ __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
+- /* and one more for PEC */
++ /* and one more for user-space compatibility */
+ };
+
+ /* smbus_access read or write markers */
diff --git a/i2c/i2c-smbus-pec-03-drop-swpec-sizes.patch b/i2c/i2c-smbus-pec-03-drop-swpec-sizes.patch
new file mode 100644
index 0000000000000..4b592a0e809b4
--- /dev/null
+++ b/i2c/i2c-smbus-pec-03-drop-swpec-sizes.patch
@@ -0,0 +1,116 @@
+From khali@linux-fr.org Wed Oct 26 12:32:07 2005
+Date: Wed, 26 Oct 2005 21:31:15 +0200
+From: Jean Delvare <khali@linux-fr.org>
+To: Greg KH <greg@kroah.com>
+Subject: [PATCH 11/16] i2c: SMBus PEC support rewrite, 3 of 3
+Message-Id: <20051026213115.19b83fee.khali@linux-fr.org>
+Content-Disposition: inline; filename=i2c-smbus-pec-03-drop-swpec-sizes.patch
+
+The new SMBus PEC implementation doesn't support PEC emulation on
+non-PEC non-I2C SMBus masters, so we can drop all related code.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/busses/i2c-amd8111.c | 7 -------
+ drivers/i2c/busses/i2c-i801.c | 13 +++++--------
+ drivers/i2c/busses/i2c-nforce2.c | 7 -------
+ include/linux/i2c.h | 4 ----
+ 4 files changed, 5 insertions(+), 26 deletions(-)
+
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-amd8111.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-amd8111.c
+@@ -253,13 +253,6 @@ static s32 amd8111_access(struct i2c_ada
+ read_write = I2C_SMBUS_READ;
+ break;
+
+- case I2C_SMBUS_WORD_DATA_PEC:
+- case I2C_SMBUS_BLOCK_DATA_PEC:
+- case I2C_SMBUS_PROC_CALL_PEC:
+- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+- dev_warn(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
+- return -1;
+-
+ default:
+ dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
+ return -1;
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-nforce2.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-nforce2.c
+@@ -188,13 +188,6 @@ static s32 nforce2_access(struct i2c_ada
+ dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
+ return -1;
+
+- case I2C_SMBUS_WORD_DATA_PEC:
+- case I2C_SMBUS_BLOCK_DATA_PEC:
+- case I2C_SMBUS_PROC_CALL_PEC:
+- case I2C_SMBUS_BLOCK_PROC_CALL_PEC:
+- dev_err(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
+- return -1;
+-
+ default:
+ dev_err(&adap->dev, "Unsupported transaction %d\n", size);
+ return -1;
+--- gregkh-2.6.orig/include/linux/i2c.h
++++ gregkh-2.6/include/linux/i2c.h
+@@ -452,10 +452,6 @@ union i2c_smbus_data {
+ #define I2C_SMBUS_BLOCK_DATA 5
+ #define I2C_SMBUS_I2C_BLOCK_DATA 6
+ #define I2C_SMBUS_BLOCK_PROC_CALL 7 /* SMBus 2.0 */
+-#define I2C_SMBUS_BLOCK_DATA_PEC 8 /* SMBus 2.0 */
+-#define I2C_SMBUS_PROC_CALL_PEC 9 /* SMBus 2.0 */
+-#define I2C_SMBUS_BLOCK_PROC_CALL_PEC 10 /* SMBus 2.0 */
+-#define I2C_SMBUS_WORD_DATA_PEC 11 /* SMBus 2.0 */
+
+
+ /* ----- commands for the ioctl like i2c_command call:
+--- gregkh-2.6.orig/drivers/i2c/busses/i2c-i801.c
++++ gregkh-2.6/drivers/i2c/busses/i2c-i801.c
+@@ -102,8 +102,8 @@ MODULE_PARM_DESC(force_addr,
+ "EXTREMELY DANGEROUS!");
+
+ static int i801_transaction(void);
+-static int i801_block_transaction(union i2c_smbus_data *data,
+- char read_write, int command);
++static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
++ int command, int hwpec);
+
+ static unsigned short i801_smba;
+ static struct pci_driver i801_driver;
+@@ -249,7 +249,7 @@ static int i801_transaction(void)
+
+ /* All-inclusive block transaction function */
+ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
+- int command)
++ int command, int hwpec)
+ {
+ int i, len;
+ int smbcmd;
+@@ -388,7 +388,7 @@ static int i801_block_transaction(union
+ goto END;
+ }
+
+- if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
++ if (hwpec && command == I2C_SMBUS_BLOCK_DATA) {
+ /* wait for INTR bit as advised by Intel */
+ timeout = 0;
+ do {
+@@ -456,9 +456,6 @@ static s32 i801_access(struct i2c_adapte
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+ case I2C_SMBUS_I2C_BLOCK_DATA:
+- case I2C_SMBUS_BLOCK_DATA_PEC:
+- if(hwpec && size == I2C_SMBUS_BLOCK_DATA)
+- size = I2C_SMBUS_BLOCK_DATA_PEC;
+ outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
+ SMBHSTADD);
+ outb_p(command, SMBHSTCMD);
+@@ -476,7 +473,7 @@ static s32 i801_access(struct i2c_adapte
+ outb_p(1, SMBAUXCTL); /* enable HW PEC */
+ }
+ if(block)
+- ret = i801_block_transaction(data, read_write, size);
++ ret = i801_block_transaction(data, read_write, size, hwpec);
+ else {
+ outb_p(xact | ENABLE_INT9, SMBHSTCNT);
+ ret = i801_transaction();