X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fi2c%2Fbusses%2Fscx200_acb.c;h=49f8a50205e7402d4a5cb7d67777d8311cd49dcb;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=61ddd65e53ca60d3d990196c7388cbc2ec22eb73;hpb=bc77d24c47b89f1e0efed0b8e4be5f8aad102883;p=linux-2.6.git diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 61ddd65e5..49f8a5020 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -24,7 +24,6 @@ */ -#include #include #include #include @@ -32,6 +31,7 @@ #include #include #include +#include #include #include @@ -43,8 +43,8 @@ MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); MODULE_LICENSE("GPL"); #define MAX_DEVICES 4 -static int base[MAX_DEVICES] = { 0x840 }; -MODULE_PARM(base, "1-4i"); +static int base[MAX_DEVICES] = { 0x820, 0x840 }; +module_param_array(base, int, NULL, 0); MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers"); #ifdef DEBUG @@ -178,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: @@ -254,7 +254,7 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) scx200_acb_machine(iface, status); return; } - schedule_timeout(HZ/100+1); + msleep(10); } scx200_acb_timeout(iface); @@ -316,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: @@ -390,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; @@ -442,27 +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; @@ -500,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; @@ -508,9 +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) + if (pci_dev_present(scx200) == 0) return -ENODEV; rc = -ENXIO;