diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-ali1563.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-ali1563.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 6b68074e518..fc3e5b02642 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
| 22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/acpi.h> | ||
| 24 | 25 | ||
| 25 | #define ALI1563_MAX_TIMEOUT 500 | 26 | #define ALI1563_MAX_TIMEOUT 500 |
| 26 | #define ALI1563_SMBBA 0x80 | 27 | #define ALI1563_SMBBA 0x80 |
| @@ -67,6 +68,7 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) | |||
| 67 | { | 68 | { |
| 68 | u32 data; | 69 | u32 data; |
| 69 | int timeout; | 70 | int timeout; |
| 71 | int status = -EIO; | ||
| 70 | 72 | ||
| 71 | dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, " | 73 | dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, " |
| 72 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", | 74 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", |
| @@ -103,13 +105,15 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) | |||
| 103 | /* Issue 'kill' to host controller */ | 105 | /* Issue 'kill' to host controller */ |
| 104 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); | 106 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); |
| 105 | data = inb_p(SMB_HST_STS); | 107 | data = inb_p(SMB_HST_STS); |
| 108 | status = -ETIMEDOUT; | ||
| 106 | } | 109 | } |
| 107 | 110 | ||
| 108 | /* device error - no response, ignore the autodetection case */ | 111 | /* device error - no response, ignore the autodetection case */ |
| 109 | if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { | 112 | if (data & HST_STS_DEVERR) { |
| 110 | dev_err(&a->dev, "Device error!\n"); | 113 | if (size != HST_CNTL2_QUICK) |
| 114 | dev_err(&a->dev, "Device error!\n"); | ||
| 115 | status = -ENXIO; | ||
| 111 | } | 116 | } |
| 112 | |||
| 113 | /* bus collision */ | 117 | /* bus collision */ |
| 114 | if (data & HST_STS_BUSERR) { | 118 | if (data & HST_STS_BUSERR) { |
| 115 | dev_err(&a->dev, "Bus collision!\n"); | 119 | dev_err(&a->dev, "Bus collision!\n"); |
| @@ -122,13 +126,14 @@ static int ali1563_transaction(struct i2c_adapter * a, int size) | |||
| 122 | outb_p(0x0,SMB_HST_CNTL2); | 126 | outb_p(0x0,SMB_HST_CNTL2); |
| 123 | } | 127 | } |
| 124 | 128 | ||
| 125 | return -1; | 129 | return status; |
| 126 | } | 130 | } |
| 127 | 131 | ||
| 128 | static int ali1563_block_start(struct i2c_adapter * a) | 132 | static int ali1563_block_start(struct i2c_adapter * a) |
| 129 | { | 133 | { |
| 130 | u32 data; | 134 | u32 data; |
| 131 | int timeout; | 135 | int timeout; |
| 136 | int status = -EIO; | ||
| 132 | 137 | ||
| 133 | dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, " | 138 | dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, " |
| 134 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", | 139 | "CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n", |
| @@ -164,13 +169,20 @@ static int ali1563_block_start(struct i2c_adapter * a) | |||
| 164 | 169 | ||
| 165 | if (timeout && !(data & HST_STS_BAD)) | 170 | if (timeout && !(data & HST_STS_BAD)) |
| 166 | return 0; | 171 | return 0; |
| 172 | |||
| 173 | if (timeout == 0) | ||
| 174 | status = -ETIMEDOUT; | ||
| 175 | |||
| 176 | if (data & HST_STS_DEVERR) | ||
| 177 | status = -ENXIO; | ||
| 178 | |||
| 167 | dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", | 179 | dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", |
| 168 | timeout ? "Timeout " : "", | 180 | timeout ? "" : "Timeout ", |
| 169 | data & HST_STS_FAIL ? "Transaction Failed " : "", | 181 | data & HST_STS_FAIL ? "Transaction Failed " : "", |
| 170 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | 182 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", |
| 171 | data & HST_STS_DEVERR ? "Device Error " : "", | 183 | data & HST_STS_DEVERR ? "Device Error " : "", |
| 172 | !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); | 184 | !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); |
| 173 | return -1; | 185 | return status; |
| 174 | } | 186 | } |
| 175 | 187 | ||
| 176 | static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw) | 188 | static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw) |
| @@ -235,10 +247,6 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
| 235 | 247 | ||
| 236 | /* Map the size to what the chip understands */ | 248 | /* Map the size to what the chip understands */ |
| 237 | switch (size) { | 249 | switch (size) { |
| 238 | case I2C_SMBUS_PROC_CALL: | ||
| 239 | dev_err(&a->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); | ||
| 240 | error = -EINVAL; | ||
| 241 | break; | ||
| 242 | case I2C_SMBUS_QUICK: | 250 | case I2C_SMBUS_QUICK: |
| 243 | size = HST_CNTL2_QUICK; | 251 | size = HST_CNTL2_QUICK; |
| 244 | break; | 252 | break; |
| @@ -254,6 +262,10 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
| 254 | case I2C_SMBUS_BLOCK_DATA: | 262 | case I2C_SMBUS_BLOCK_DATA: |
| 255 | size = HST_CNTL2_BLOCK; | 263 | size = HST_CNTL2_BLOCK; |
| 256 | break; | 264 | break; |
| 265 | default: | ||
| 266 | dev_warn(&a->dev, "Unsupported transaction %d\n", size); | ||
| 267 | error = -EOPNOTSUPP; | ||
| 268 | goto Done; | ||
| 257 | } | 269 | } |
| 258 | 270 | ||
| 259 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); | 271 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); |
| @@ -345,6 +357,10 @@ static int __devinit ali1563_setup(struct pci_dev * dev) | |||
| 345 | } | 357 | } |
| 346 | } | 358 | } |
| 347 | 359 | ||
| 360 | if (acpi_check_region(ali1563_smba, ALI1563_SMB_IOSIZE, | ||
| 361 | ali1563_pci_driver.name)) | ||
| 362 | goto Err; | ||
| 363 | |||
| 348 | if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE, | 364 | if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE, |
| 349 | ali1563_pci_driver.name)) { | 365 | ali1563_pci_driver.name)) { |
| 350 | dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n", | 366 | dev_err(&dev->dev, "Could not allocate I/O space at 0x%04x\n", |
| @@ -371,7 +387,7 @@ static const struct i2c_algorithm ali1563_algorithm = { | |||
| 371 | static struct i2c_adapter ali1563_adapter = { | 387 | static struct i2c_adapter ali1563_adapter = { |
| 372 | .owner = THIS_MODULE, | 388 | .owner = THIS_MODULE, |
| 373 | .id = I2C_HW_SMBUS_ALI1563, | 389 | .id = I2C_HW_SMBUS_ALI1563, |
| 374 | .class = I2C_CLASS_HWMON, | 390 | .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, |
| 375 | .algo = &ali1563_algorithm, | 391 | .algo = &ali1563_algorithm, |
| 376 | }; | 392 | }; |
| 377 | 393 | ||
