linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / i2c / busses / scx200_acb.c
index 62b7614..49f8a50 100644 (file)
@@ -24,7 +24,6 @@
 
 */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -45,8 +44,7 @@ MODULE_LICENSE("GPL");
 
 #define MAX_DEVICES 4
 static int base[MAX_DEVICES] = { 0x820, 0x840 };
-static int num_base;
-module_param_array(base, int, num_base, 0);
+module_param_array(base, int, NULL, 0);
 MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
 
 #ifdef DEBUG
@@ -180,21 +178,21 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
                break;
 
        case state_read:
-               /* Set ACK if receiving the last byte */
-               if (iface->len == 1)
+               /* Set ACK if _next_ byte will be the last one */
+               if (iface->len == 2)
                        outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
                else
                        outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
 
-               *iface->ptr++ = inb(ACBSDA);
-               --iface->len;
-
-               if (iface->len == 0) {
+               if (iface->len == 1) {
                        iface->result = 0;
                        iface->state = state_idle;
                        outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
                }
 
+               *iface->ptr++ = inb(ACBSDA);
+               --iface->len;
+
                break;
 
        case state_write:
@@ -318,8 +316,12 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
                cur_word = cpu_to_le16(data->word);
                buffer = (u8 *)&cur_word;
                break;
-       case I2C_SMBUS_BLOCK_DATA:
+       case I2C_SMBUS_I2C_BLOCK_DATA:
+               if (rw == I2C_SMBUS_READ)
+                       data->block[0] = I2C_SMBUS_BLOCK_MAX; /* For now */
                len = data->block[0];
+               if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
+                       return -EINVAL;
                buffer = &data->block[1];
                break;
        default:
@@ -392,20 +394,18 @@ static u32 scx200_acb_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_BLOCK_DATA;
+              I2C_FUNC_SMBUS_I2C_BLOCK;
 }
 
 /* For now, we only handle combined mode (smbus) */
 static struct i2c_algorithm scx200_acb_algorithm = {
-       .name           = "NatSemi SCx200 ACCESS.bus",
-       .id             = I2C_ALGO_SMBUS,
        .smbus_xfer     = scx200_acb_smbus_xfer,
        .functionality  = scx200_acb_func,
 };
 
-struct scx200_acb_iface *scx200_acb_list;
+static struct scx200_acb_iface *scx200_acb_list;
 
-int scx200_acb_probe(struct scx200_acb_iface *iface)
+static int scx200_acb_probe(struct scx200_acb_iface *iface)
 {
        u8 val;
 
@@ -444,28 +444,25 @@ static int  __init scx200_acb_create(int base, int index)
        struct scx200_acb_iface *iface;
        struct i2c_adapter *adapter;
        int rc = 0;
-       char description[64];
 
-       iface = kmalloc(sizeof(*iface), GFP_KERNEL);
+       iface = kzalloc(sizeof(*iface), GFP_KERNEL);
        if (!iface) {
                printk(KERN_ERR NAME ": can't allocate memory\n");
                rc = -ENOMEM;
                goto errout;
        }
 
-       memset(iface, 0, sizeof(*iface));
        adapter = &iface->adapter;
        i2c_set_adapdata(adapter, iface);
        snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
        adapter->owner = THIS_MODULE;
-       adapter->id = I2C_ALGO_SMBUS;
+       adapter->id = I2C_HW_SMBUS_SCX200;
        adapter->algo = &scx200_acb_algorithm;
        adapter->class = I2C_CLASS_HWMON;
 
        init_MUTEX(&iface->sem);
 
-       snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
-       if (request_region(base, 8, description) == 0) {
+       if (!request_region(base, 8, adapter->name)) {
                dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
                        base, base + 8-1);
                rc = -EBUSY;
@@ -503,6 +500,12 @@ static int  __init scx200_acb_create(int base, int index)
        return rc;
 }
 
+static struct pci_device_id scx200[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+       { },
+};
+
 static int __init scx200_acb_init(void)
 {
        int i;
@@ -511,12 +514,7 @@ static int __init scx200_acb_init(void)
        pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
 
        /* Verify that this really is a SCx200 processor */
-       if (pci_find_device(PCI_VENDOR_ID_NS,
-                           PCI_DEVICE_ID_NS_SCx200_BRIDGE,
-                           NULL) == NULL
-           && pci_find_device(PCI_VENDOR_ID_NS,
-                              PCI_DEVICE_ID_NS_SC1100_BRIDGE,
-                              NULL) == NULL)
+       if (pci_dev_present(scx200) == 0)
                return -ENODEV;
 
        rc = -ENXIO;