aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-ali1563.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-ali1563.c')
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c38
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
128static int ali1563_block_start(struct i2c_adapter * a) 132static 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
176static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw) 188static 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 = {
371static struct i2c_adapter ali1563_adapter = { 387static 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