From: "Amaury Decrême" <amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>,
Guenter Roeck
<guenter.roeck-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org>
Cc: "Alexander Malysh" <amalysh-S0/GAf8tV78@public.gmane.org>,
"Mark M. Hoffman"
<mhoffman-xQSgfq/1h4JiLUuM0BA3LQ@public.gmane.org>,
linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
"Amaury Decrême"
<amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: [PATCH] i2c: support for SiS964 south bridge
Date: Tue, 16 Aug 2011 22:59:24 +0200 [thread overview]
Message-ID: <1313528364-13611-1-git-send-email-amaury.decreme@gmail.com> (raw)
This driver implement a support for the SiS964 chipset.
It's a fork of i2c-sis630 modified with the help of datasheets.
Signed-off-by: Amaury Decrême <amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Documentation/i2c/busses/i2c-sis964 | 33 +++
drivers/i2c/busses/Kconfig | 12 +-
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-sis964.c | 544 +++++++++++++++++++++++++++++++++++
include/linux/pci_ids.h | 1 +
5 files changed, 590 insertions(+), 1 deletions(-)
create mode 100644 Documentation/i2c/busses/i2c-sis964
create mode 100644 drivers/i2c/busses/i2c-sis964.c
diff --git a/Documentation/i2c/busses/i2c-sis964 b/Documentation/i2c/busses/i2c-sis964
new file mode 100644
index 0000000..79ed17e
--- /dev/null
+++ b/Documentation/i2c/busses/i2c-sis964
@@ -0,0 +1,33 @@
+Kernel driver i2c-sis964
+
+Supported adapters:
+ * Silicon Integrated Systems Corp (SiS)
+ 964 chipset (Datasheet given under NDA by SiS)
+ * Possible other SiS chipsets with the same registers and clocks
+
+Author: Amaury Decrême <amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+
+Module Parameters
+-----------------
+
+* force = [1|0] Forcibly enable the SIS964. DANGEROUS!
+ This can be interesting for chipsets not named
+ above to check if it works for you chipset, but DANGEROUS!
+
+* low_clock = [1|0] Set Host Master Clock to 28KHz
+
+Description
+-----------
+
+This SMBus driver is known to work on motherboards with the SiS964 chipset.
+
+If you see something like this:
+
+00:02.0 ISA bridge: Silicon Integrated Systems [SiS] SiS964 [MuTIOL Media IO] (rev 36)
+
+in your 'lspci' output , then this driver is for your chipset.
+
+Thank You
+---------
+Alexander Malysh <amalysh-S0/GAf8tV78@public.gmane.org>
+- Most of the code in this driver is a fork of i2c-sis630 which has been written by him
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 646068e..109de39 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -189,8 +189,18 @@ config I2C_SIS630
This driver can also be built as a module. If so, the module
will be called i2c-sis630.
+config I2C_SIS964
+ tristate "SiS 964"
+ depends on PCI && EXPERIMENTAL
+ help
+ If you say yes to this option, support will be included for the SiS
+ 964 SMBus (a subset of I2C) interfaces.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-sis964.
+
config I2C_SIS96X
- tristate "SiS 96x"
+ tristate "SiS 96x (but SiS964)"
depends on PCI
help
If you say yes to this option, support will be included for the SiS
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index e6cf294..f8e230e 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_I2C_NFORCE2_S4985) += i2c-nforce2-s4985.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_SIS964) += i2c-sis964.o
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
obj-$(CONFIG_I2C_VIA) += i2c-via.o
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
diff --git a/drivers/i2c/busses/i2c-sis964.c b/drivers/i2c/busses/i2c-sis964.c
new file mode 100644
index 0000000..f22352e
--- /dev/null
+++ b/drivers/i2c/busses/i2c-sis964.c
@@ -0,0 +1,544 @@
+/*
+ Copyright (c) 2011 Amaury Decrême <amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+
+ 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:
+ 11.08.2011
+ Fork of original i2c-sis630 - Alexander Malysh <amalysh-S0/GAf8tV78@public.gmane.org>
+ Patched for SiS964 with datasheets
+ - Amaury Decrême <amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+*/
+
+/*
+ Supports:
+ SIS 964
+
+ Note: we assume there can only be one device, with one SMBus interface.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/acpi.h>
+#include <linux/io.h>
+
+/* SIS964 SMBus registers */
+#define SMB_STS 0xE0 /* status */
+#define SMB_EN 0xE1 /* status enable */
+#define SMB_CNT 0xE2 /* Control */
+#define SMBHOST_CNT 0xE3 /* Host Control */
+#define SMB_ADDR 0xE4 /* Address */
+#define SMB_CMD 0xE5 /* Command */
+#define SMB_PERRCHK 0xE6 /* Packet Error Check */
+#define SMB_COUNT 0xE7 /* Byte Count */
+#define SMB_BYTE 0xE8 /* ~0x8F data byte field */
+#define SMBDEV_ADDR 0xF0 /* Device Address */
+#define SMB_DB0 0xF1 /* Device byte0 */
+#define SMB_DB1 0xF2 /* Device byte1 */
+#define SMB_SAA 0xF3 /* Host slave alias address */
+#define SMB_PCOUNT 0xF4 /* processed byte count */
+
+/* register count for request_region */
+#define SIS964_SMB_IOREGION 21
+
+/* PCI address constants */
+/* acpi base address register */
+#define SIS964_ACPI_BASE_REG 0x74
+/* bios control register */
+#define SIS964_BIOS_CTL_REG 0x40
+
+/* Other settings */
+#define MAX_TIMEOUT 500
+
+/* SIS964 constants */
+#define SIS964_QUICK 0x00
+#define SIS964_BYTE 0x01
+#define SIS964_BYTE_DATA 0x02
+#define SIS964_WORD_DATA 0x03
+#define SIS964_PCALL 0x04
+#define SIS964_BLOCK_DATA 0x05
+
+static struct pci_driver sis964_driver;
+
+/* insmod parameters */
+static int low_clock;
+static int force;
+module_param(low_clock, bool, 0);
+MODULE_PARM_DESC(low_clock, "Set Host Master Clock to 28KHz (default 56KHz).");
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Forcibly enable the SIS964. DANGEROUS!");
+
+/* acpi base address */
+static unsigned short acpi_base;
+
+/* supported chips */
+static int supported[] = {
+ PCI_DEVICE_ID_SI_964,
+ 0 /* terminates the list */
+};
+
+static inline u8 sis964_read(u8 reg)
+{
+ return inb(acpi_base + reg);
+}
+
+static inline void sis964_write(u8 reg, u8 data)
+{
+ outb(data, acpi_base + reg);
+}
+
+static int sis964_transaction_start(struct i2c_adapter *adap,
+ int ptl, u8 *oldclock)
+{
+ int temp;
+
+ /* Clear status register */
+ sis964_write(SMB_STS, 0xFF);
+
+ /* Make sure the SMBus host is ready to start transmitting. */
+ temp = sis964_read(SMB_CNT);
+ if ((temp & 0x03) != 0x00) {
+ dev_dbg(&adap->dev, "SMBus not ready "
+ "to start transmitting (%02x).Resetting...\n", temp);
+ /* kill smbus transaction */
+ sis964_write(SMBHOST_CNT, 0x20);
+
+ temp = sis964_read(SMB_CNT);
+ if ((temp & 0x03) != 0x00) {
+ dev_dbg(&adap->dev, "Failed! (%02x)\n", temp);
+ return -EBUSY;
+ }
+ }
+
+ /* save old clock, so we can prevent machine for hung */
+ *oldclock = sis964_read(SMB_CNT);
+
+ dev_dbg(&adap->dev, "saved clock 0x%02x\n", *oldclock);
+
+ /* disable timeout interrupt,
+ * set Host Master Clock to 28KHz if requested */
+ if (low_clock)
+ sis964_write(SMB_CNT, 0x20);
+ else
+ sis964_write(SMB_CNT, (*oldclock & 0x20));
+
+ /* start the transaction by setting bit start and protocol */
+ sis964_write(SMBHOST_CNT, 0x10 | (ptl & 0x07));
+ udelay(30);
+
+ return 0;
+}
+
+static int sis964_transaction_wait(struct i2c_adapter *adap, int ptl)
+{
+ int temp, result = 0, timeout = 0;
+
+ /* We will always wait for a fraction of a second! */
+ do {
+ udelay(1000);
+ temp = sis964_read(SMB_STS);
+ /* check if block transmitted */
+ if (ptl == SIS964_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 (%02x)!\n", temp);
+ result = -ETIMEDOUT;
+ }
+
+ /* SMBERR_STS */
+ if (temp & 0x02) {
+ dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
+ result = -ENXIO;
+ }
+
+ /* SMBCOL_STS */
+ if (temp & 0x04) {
+ dev_err(&adap->dev, "Bus collision!\n");
+ sis964_write(SMB_STS, temp & ~0x04);
+ result = -EIO;
+ }
+
+ return result;
+}
+
+static void sis964_transaction_end(struct i2c_adapter *adap, u8 oldclock)
+{
+ /* clear all status "sticky" bits */
+ sis964_write(SMB_STS, 0xFF);
+
+ dev_dbg(&adap->dev, "SMB_CNT before clock restore 0x%02x\n",
+ sis964_read(SMB_CNT));
+
+ /*
+ * restore old Host Master Clock if low_clock is set
+ */
+ if (low_clock)
+ sis964_write(SMB_CNT, oldclock & 0x20);
+
+ dev_dbg(&adap->dev, "SMB_CNT after clock restore 0x%02x\n",
+ sis964_read(SMB_CNT));
+}
+
+static int sis964_transaction(struct i2c_adapter *adap, int ptl)
+{
+ int result = 0, timeout = 0;
+ u8 oldclock = 0;
+
+ do {
+ result = sis964_transaction_start(adap, ptl, &oldclock);
+ if (result)
+ break;
+
+ result = sis964_transaction_wait(adap, ptl);
+ sis964_transaction_end(adap, oldclock);
+ } while (result == -EIO && timeout++ < MAX_TIMEOUT);
+
+ if (timeout > MAX_TIMEOUT) {
+ dev_dbg(&adap->dev, "SMBus Collision Timeout !\n");
+ result = -ETIMEDOUT;
+ }
+
+ return result;
+}
+
+static int sis964_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;
+ sis964_write(SMB_COUNT, len);
+ for (i = 1; i <= len; i++) {
+ dev_dbg(&adap->dev, "set data 0x%02x\n",
+ data->block[i]);
+
+ /* set data */
+ sis964_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 */
+ rc = sis964_transaction_start(adap,
+ SIS964_BLOCK_DATA, &oldclock);
+ if (rc)
+ return rc;
+ } 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
+ */
+ sis964_write(SMB_STS, 0x10);
+ }
+ rc = sis964_transaction_wait(adap,
+ SIS964_BLOCK_DATA);
+ if (rc) {
+ dev_dbg(&adap->dev, "trans_wait failed\n");
+ break;
+ }
+ }
+ }
+ } else {
+ /* read request */
+ data->block[0] = len = 0;
+ rc = sis964_transaction_start(adap,
+ SIS964_BLOCK_DATA, &oldclock);
+ if (rc)
+ return rc;
+ do {
+ rc = sis964_transaction_wait(adap, SIS964_BLOCK_DATA);
+ if (rc) {
+ dev_dbg(&adap->dev, "trans_wait failed\n");
+ break;
+ }
+ /* if this first transaction then read byte count */
+ if (len == 0)
+ data->block[0] = sis964_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++) {
+ dev_dbg(&adap->dev, "read i=%d len=%d\n", i,
+ len);
+ data->block[len+1] = sis964_read(SMB_BYTE+i);
+ }
+
+ dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",
+ len, i);
+
+ /* clear SMBARY_STS */
+ sis964_write(SMB_STS, 0x10);
+ } while (len < data->block[0]);
+ }
+
+ sis964_transaction_end(adap, oldclock);
+
+ return rc;
+}
+
+/* Return negative errno on error. */
+static s32 sis964_access(struct i2c_adapter *adap, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int ptl, union i2c_smbus_data *data)
+{
+ int status;
+
+ switch (ptl) {
+ case I2C_SMBUS_QUICK:
+ sis964_write(SMB_ADDR, ((addr & 0x7f) << 1) |
+ (read_write & 0x01));
+ ptl = SIS964_QUICK;
+ break;
+ case I2C_SMBUS_BYTE:
+ sis964_write(SMB_ADDR, ((addr & 0x7f) << 1) |
+ (read_write & 0x01));
+ if (read_write == I2C_SMBUS_WRITE)
+ sis964_write(SMB_CMD, command);
+ ptl = SIS964_BYTE;
+ break;
+ case I2C_SMBUS_BYTE_DATA:
+ sis964_write(SMB_ADDR, ((addr & 0x7f) << 1) |
+ (read_write & 0x01));
+ sis964_write(SMB_CMD, command);
+ if (read_write == I2C_SMBUS_WRITE)
+ sis964_write(SMB_BYTE, data->byte);
+ ptl = SIS964_BYTE_DATA;
+ break;
+ case I2C_SMBUS_PROC_CALL:
+ case I2C_SMBUS_WORD_DATA:
+ sis964_write(SMB_ADDR, ((addr & 0x7f) << 1) |
+ (read_write & 0x01));
+ sis964_write(SMB_CMD, command);
+ if (read_write == I2C_SMBUS_WRITE) {
+ sis964_write(SMB_BYTE, data->word & 0xff);
+ sis964_write(SMB_BYTE + 1,
+ (data->word & 0xff00) >> 8);
+ }
+ ptl = (ptl == I2C_SMBUS_PROC_CALL ?
+ SIS964_PCALL : SIS964_WORD_DATA);
+ break;
+ case I2C_SMBUS_BLOCK_DATA:
+ sis964_write(SMB_ADDR, ((addr & 0x7f) << 1) |
+ (read_write & 0x01));
+ sis964_write(SMB_CMD, command);
+ ptl = SIS964_BLOCK_DATA;
+ return sis964_block_data(adap, data, read_write);
+ default:
+ dev_warn(&adap->dev, "Unsupported transaction %d\n",
+ ptl);
+ return -EOPNOTSUPP;
+ }
+
+ status = sis964_transaction(adap, ptl);
+ if (status)
+ return status;
+
+ if ((ptl != SIS964_PCALL) &&
+ ((read_write == I2C_SMBUS_WRITE) || (ptl == SIS964_QUICK))) {
+ return 0;
+ }
+
+ switch (ptl) {
+ case SIS964_BYTE:
+ case SIS964_BYTE_DATA:
+ data->byte = sis964_read(SMB_BYTE);
+ break;
+ case SIS964_PCALL:
+ case SIS964_WORD_DATA:
+ data->word = sis964_read(SMB_BYTE) +
+ (sis964_read(SMB_BYTE + 1) << 8);
+ break;
+ }
+
+ return 0;
+}
+
+static u32 sis964_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 __devinit sis964_setup(struct pci_dev *sis964_dev)
+{
+ unsigned char b;
+ struct pci_dev *dummy = NULL;
+ int retval = -ENODEV, i;
+
+ /* check for supported SiS devices */
+ for (i = 0; supported[i] > 0 && dummy == NULL; i++)
+ dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy);
+
+ if (dummy) {
+ pci_dev_put(dummy);
+ } else if (force) {
+ dev_err(&sis964_dev->dev,
+ "WARNING: Can't detect SIS964 compatible device, but "
+ "loading because of force option enabled\n");
+ } else {
+ 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(sis964_dev, SIS964_BIOS_CTL_REG, &b)) {
+ dev_err(&sis964_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(sis964_dev, SIS964_BIOS_CTL_REG, b | 0x80)) {
+ dev_err(&sis964_dev->dev, "Error: Can't enable ACPI\n");
+ goto exit;
+ }
+
+ /* Determine the ACPI base address */
+ if (pci_read_config_word(sis964_dev, SIS964_ACPI_BASE_REG,
+ &acpi_base)) {
+ dev_err(&sis964_dev->dev, "Error: Can't determine ACPI base address\n");
+ goto exit;
+ }
+
+ dev_dbg(&sis964_dev->dev, "ACPI base at 0x%04x\n", acpi_base);
+
+ retval = acpi_check_region(acpi_base + SMB_STS, SIS964_SMB_IOREGION,
+ sis964_driver.name);
+ if (retval)
+ goto exit;
+
+ /* Everything is happy, let's grab the memory and set things up. */
+ if (!request_region(acpi_base + SMB_STS, SIS964_SMB_IOREGION,
+ sis964_driver.name)) {
+ dev_err(&sis964_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:
+ if (retval)
+ acpi_base = 0;
+ return retval;
+}
+
+
+static const struct i2c_algorithm smbus_algorithm = {
+ .smbus_xfer = sis964_access,
+ .functionality = sis964_func,
+};
+
+static struct i2c_adapter sis964_adapter = {
+ .owner = THIS_MODULE,
+ .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
+ .algo = &smbus_algorithm,
+};
+
+static const struct pci_device_id sis964_ids[] __devinitconst = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_964) },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, sis964_ids);
+
+static int __devinit sis964_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ if (sis964_setup(dev)) {
+ dev_err(&dev->dev, "SIS964 comp. bus not detected, module not inserted.\n");
+ return -ENODEV;
+ }
+
+ /* set up the sysfs linkage to our parent device */
+ sis964_adapter.dev.parent = &dev->dev;
+
+ snprintf(sis964_adapter.name, sizeof(sis964_adapter.name),
+ "SMBus SIS964 adapter at %04x", acpi_base + SMB_STS);
+
+ return i2c_add_adapter(&sis964_adapter);
+}
+
+static void __devexit sis964_remove(struct pci_dev *dev)
+{
+ dev_dbg(&dev->dev, "sis964_remove");
+
+ if (acpi_base) {
+ i2c_del_adapter(&sis964_adapter);
+ release_region(acpi_base + SMB_STS, SIS964_SMB_IOREGION);
+ acpi_base = 0;
+ }
+}
+
+
+static struct pci_driver sis964_driver = {
+ .name = "sis964_smbus",
+ .id_table = sis964_ids,
+ .probe = sis964_probe,
+ .remove = __devexit_p(sis964_remove),
+};
+
+static int __init i2c_sis964_init(void)
+{
+ return pci_register_driver(&sis964_driver);
+}
+
+
+static void __exit i2c_sis964_exit(void)
+{
+ pci_unregister_driver(&sis964_driver);
+}
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Amaury Decrême <amaury.decreme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("SiS964 SMBus driver");
+
+module_init(i2c_sis964_init);
+module_exit(i2c_sis964_exit);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ae96bbe..668f7ff 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -695,6 +695,7 @@
#define PCI_DEVICE_ID_SI_961 0x0961
#define PCI_DEVICE_ID_SI_962 0x0962
#define PCI_DEVICE_ID_SI_963 0x0963
+#define PCI_DEVICE_ID_SI_964 0x0964
#define PCI_DEVICE_ID_SI_965 0x0965
#define PCI_DEVICE_ID_SI_966 0x0966
#define PCI_DEVICE_ID_SI_968 0x0968
--
1.7.3.4
reply other threads:[~2011-08-16 20:59 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1313528364-13611-1-git-send-email-amaury.decreme@gmail.com \
--to=amaury.decreme-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
--cc=amalysh-S0/GAf8tV78@public.gmane.org \
--cc=guenter.roeck-IzeFyvvaP7pWk0Htik3J/w@public.gmane.org \
--cc=khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=mhoffman-xQSgfq/1h4JiLUuM0BA3LQ@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).