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 6b68074e518a..fc3e5b026423 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 | ||