diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/i2c-ali1563.c | 46 |
1 files changed, 31 insertions, 15 deletions
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 35710818fe47..fdd881aee618 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge | 2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Patrick Mochel | 4 | * Copyright (C) 2004 Patrick Mochel |
5 | * 2005 Rudolf Marek <r.marek@sh.cvut.cz> | ||
5 | * | 6 | * |
6 | * The 1563 southbridge is deceptively similar to the 1533, with a | 7 | * The 1563 southbridge is deceptively similar to the 1533, with a |
7 | * few notable exceptions. One of those happens to be the fact they | 8 | * few notable exceptions. One of those happens to be the fact they |
@@ -57,10 +58,11 @@ | |||
57 | #define HST_CNTL2_BLOCK 0x05 | 58 | #define HST_CNTL2_BLOCK 0x05 |
58 | 59 | ||
59 | 60 | ||
61 | #define HST_CNTL2_SIZEMASK 0x38 | ||
60 | 62 | ||
61 | static unsigned short ali1563_smba; | 63 | static unsigned short ali1563_smba; |
62 | 64 | ||
63 | static int ali1563_transaction(struct i2c_adapter * a) | 65 | static int ali1563_transaction(struct i2c_adapter * a, int size) |
64 | { | 66 | { |
65 | u32 data; | 67 | u32 data; |
66 | int timeout; | 68 | int timeout; |
@@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
73 | 75 | ||
74 | data = inb_p(SMB_HST_STS); | 76 | data = inb_p(SMB_HST_STS); |
75 | if (data & HST_STS_BAD) { | 77 | if (data & HST_STS_BAD) { |
76 | dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); | 78 | dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); |
77 | outb_p(data | HST_STS_BAD,SMB_HST_STS); | 79 | outb_p(data | HST_STS_BAD,SMB_HST_STS); |
78 | data = inb_p(SMB_HST_STS); | 80 | data = inb_p(SMB_HST_STS); |
79 | if (data & HST_STS_BAD) | 81 | if (data & HST_STS_BAD) |
@@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
94 | 96 | ||
95 | if (timeout && !(data & HST_STS_BAD)) | 97 | if (timeout && !(data & HST_STS_BAD)) |
96 | return 0; | 98 | return 0; |
97 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | ||
98 | timeout ? "Timeout " : "", | ||
99 | data & HST_STS_FAIL ? "Transaction Failed " : "", | ||
100 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | ||
101 | data & HST_STS_DEVERR ? "Device Error " : "", | ||
102 | !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); | ||
103 | 99 | ||
104 | if (!(data & HST_STS_DONE)) | 100 | if (!timeout) { |
101 | dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n"); | ||
105 | /* Issue 'kill' to host controller */ | 102 | /* Issue 'kill' to host controller */ |
106 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); | 103 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); |
107 | else | 104 | data = inb_p(SMB_HST_STS); |
108 | /* Issue timeout to reset all devices on bus */ | 105 | } |
106 | |||
107 | /* device error - no response, ignore the autodetection case */ | ||
108 | if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { | ||
109 | dev_err(&a->dev, "Device error!\n"); | ||
110 | } | ||
111 | |||
112 | /* bus collision */ | ||
113 | if (data & HST_STS_BUSERR) { | ||
114 | dev_err(&a->dev, "Bus collision!\n"); | ||
115 | /* Issue timeout, hoping it helps */ | ||
109 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); | 116 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); |
117 | } | ||
118 | |||
119 | if (data & HST_STS_FAIL) { | ||
120 | dev_err(&a->dev, "Cleaning fail after KILL!\n"); | ||
121 | outb_p(0x0,SMB_HST_CNTL2); | ||
122 | } | ||
123 | |||
110 | return -1; | 124 | return -1; |
111 | } | 125 | } |
112 | 126 | ||
@@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a) | |||
149 | 163 | ||
150 | if (timeout && !(data & HST_STS_BAD)) | 164 | if (timeout && !(data & HST_STS_BAD)) |
151 | return 0; | 165 | return 0; |
152 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | 166 | dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", |
153 | timeout ? "Timeout " : "", | 167 | timeout ? "Timeout " : "", |
154 | data & HST_STS_FAIL ? "Transaction Failed " : "", | 168 | data & HST_STS_FAIL ? "Transaction Failed " : "", |
155 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | 169 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", |
@@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
242 | } | 256 | } |
243 | 257 | ||
244 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); | 258 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); |
245 | outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2); | 259 | outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); |
246 | 260 | ||
247 | /* Write the command register */ | 261 | /* Write the command register */ |
262 | |||
248 | switch(size) { | 263 | switch(size) { |
249 | case HST_CNTL2_BYTE: | 264 | case HST_CNTL2_BYTE: |
250 | if (rw== I2C_SMBUS_WRITE) | 265 | if (rw== I2C_SMBUS_WRITE) |
251 | outb_p(cmd, SMB_HST_CMD); | 266 | /* Beware it uses DAT0 register and not CMD! */ |
267 | outb_p(cmd, SMB_HST_DAT0); | ||
252 | break; | 268 | break; |
253 | case HST_CNTL2_BYTE_DATA: | 269 | case HST_CNTL2_BYTE_DATA: |
254 | outb_p(cmd, SMB_HST_CMD); | 270 | outb_p(cmd, SMB_HST_CMD); |
@@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
268 | goto Done; | 284 | goto Done; |
269 | } | 285 | } |
270 | 286 | ||
271 | if ((error = ali1563_transaction(a))) | 287 | if ((error = ali1563_transaction(a, size))) |
272 | goto Done; | 288 | goto Done; |
273 | 289 | ||
274 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) | 290 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) |