Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / i2c / busses / i2c-nforce2.c
index 6d13127..2d80eb2 100644 (file)
@@ -30,6 +30,7 @@
     nForce3 Pro150 MCP         00D4
     nForce3 250Gb MCP          00E4
     nForce4 MCP                        0052
+    nForce4 MCP-04             0034
 
     This driver supports the 2 SMBuses that are included in the MCP of the
     nForce2/3/4 chipsets.
@@ -37,7 +38,6 @@
 
 /* Note: we assume there can only be one nForce2, with two SMBus interfaces */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -98,11 +98,7 @@ struct nforce2_smbus {
 #define NVIDIA_SMB_PRTCL_I2C_BLOCK_DATA                0x4a
 #define NVIDIA_SMB_PRTCL_PEC                   0x80
 
-
-/* Other settings */
-#define MAX_TIMEOUT 256
-
-
+static struct pci_driver nforce2_driver;
 
 static s32 nforce2_access(struct i2c_adapter *adap, u16 addr,
                       unsigned short flags, char read_write,
@@ -111,8 +107,6 @@ static u32 nforce2_func(struct i2c_adapter *adapter);
 
 
 static struct i2c_algorithm smbus_algorithm = {
-       .name = "Non-I2C SMBus adapter",
-       .id = I2C_ALGO_SMBUS,
        .smbus_xfer = nforce2_access,
        .functionality = nforce2_func,
 };
@@ -121,7 +115,6 @@ static struct i2c_adapter nforce2_adapter = {
        .owner          = THIS_MODULE,
        .class          = I2C_CLASS_HWMON,
        .algo           = &smbus_algorithm,
-       .name           = "unset",
 };
 
 /* Return -1 on error. See smbus.h for more information */
@@ -132,7 +125,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
        struct nforce2_smbus *smbus = adap->algo_data;
        unsigned char protocol, pec, temp;
        unsigned char len = 0; /* to keep the compiler quiet */
-       int timeout = 0;
        int i;
 
        protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
@@ -192,36 +184,10 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                case I2C_SMBUS_PROC_CALL:
                        dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
                        return -1;
-                       /*
-                       outb_p(command, NVIDIA_SMB_CMD);
-                       outb_p(data->word, NVIDIA_SMB_DATA);
-                       outb_p(data->word >> 8, NVIDIA_SMB_DATA + 1);
-                       protocol = NVIDIA_SMB_PRTCL_PROC_CALL | pec;
-                       read_write = I2C_SMBUS_READ;
-                       break;
-                        */
 
                case I2C_SMBUS_BLOCK_PROC_CALL:
                        dev_err(&adap->dev, "I2C_SMBUS_BLOCK_PROC_CALL not supported!\n");
                        return -1;
-                       /*
-                       protocol |= pec;
-                       len = min_t(u8, data->block[0], 31);
-                       outb_p(command, NVIDIA_SMB_CMD);
-                       outb_p(len, NVIDIA_SMB_BCNT);
-                       for (i = 0; i < len; i++)
-                               outb_p(data->block[i + 1], NVIDIA_SMB_DATA + i);
-                       protocol = NVIDIA_SMB_PRTCL_BLOCK_PROC_CALL | pec;
-                       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_err(&adap->dev, "Unexpected software PEC transaction %d\n.", size);
-                       return -1;
 
                default:
                        dev_err(&adap->dev, "Unsupported transaction %d\n", size);
@@ -233,12 +199,6 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
 
        temp = inb_p(NVIDIA_SMB_STS);
 
-#if 0
-       do {
-               i2c_do_pause(1);
-               temp = inb_p(NVIDIA_SMB_STS);
-       } while (((temp & NVIDIA_SMB_STS_DONE) == 0) && (timeout++ < MAX_TIMEOUT));
-#endif
        if (~temp & NVIDIA_SMB_STS_DONE) {
                udelay(500);
                temp = inb_p(NVIDIA_SMB_STS);
@@ -248,9 +208,10 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
                temp = inb_p(NVIDIA_SMB_STS);
        }
 
-       if ((timeout >= MAX_TIMEOUT) || (~temp & NVIDIA_SMB_STS_DONE)
-               || (temp & NVIDIA_SMB_STS_STATUS))
+       if ((~temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
+               dev_dbg(&adap->dev, "SMBus Timeout! (0x%02x)\n", temp);
                return -1;
+       }
 
        if (read_write == I2C_SMBUS_WRITE)
                return 0;
@@ -297,6 +258,7 @@ static struct pci_device_id nforce2_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
        { 0 }
 };
 
@@ -318,7 +280,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg,
        smbus->base = iobase & 0xfffc;
        smbus->size = 8;
 
-       if (!request_region(smbus->base, smbus->size, "nForce2 SMBus")) {
+       if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
                dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
                        smbus->base, smbus->base+smbus->size-1, name);
                return -1;
@@ -346,10 +308,8 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
        int res1, res2;
 
        /* we support 2 SMBus adapters */
-       if (!(smbuses = (void *)kmalloc(2*sizeof(struct nforce2_smbus),
-                                       GFP_KERNEL)))
+       if (!(smbuses = kzalloc(2*sizeof(struct nforce2_smbus), GFP_KERNEL)))
                return -ENOMEM;
-       memset (smbuses, 0, 2*sizeof(struct nforce2_smbus));
        pci_set_drvdata(dev, smbuses);
 
        /* SMBus adapter 1 */