aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorOleg Ryjkov <olegr@google.com>2007-07-12 08:12:31 -0400
committerJean Delvare <khali@hyperion.delvare>2007-07-12 08:12:31 -0400
commitca8b9e32a11a7cbfecbef00c8451a79fe1af392e (patch)
treeae5404a18928769a9d956a810c34239a4201749f /drivers/i2c
parenta92c344d8c640a812c7a9f5a5202d862cd052a0f (diff)
i2c-i801: Various cleanups
* Use defines instead of raw numbers for register bits * Fix several wrong indentations and trailing whitespace * Move hwpec timeout checking to a separate function Signed-off-by: Oleg Ryjkov <olegr@google.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-i801.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 611b57192c96..d5e12a4f01b0 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -22,10 +22,10 @@
22 22
23/* 23/*
24 SUPPORTED DEVICES PCI ID 24 SUPPORTED DEVICES PCI ID
25 82801AA 2413 25 82801AA 2413
26 82801AB 2423 26 82801AB 2423
27 82801BA 2443 27 82801BA 2443
28 82801CA/CAM 2483 28 82801CA/CAM 2483
29 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported) 29 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported)
30 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported) 30 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported)
31 6300ESB 25A4 31 6300ESB 25A4
@@ -74,6 +74,13 @@
74#define SMBHSTCFG_SMB_SMI_EN 2 74#define SMBHSTCFG_SMB_SMI_EN 2
75#define SMBHSTCFG_I2C_EN 4 75#define SMBHSTCFG_I2C_EN 4
76 76
77/* Auxillary control register bits, ICH4+ only */
78#define SMBAUXCTL_CRC 1
79#define SMBAUXCTL_E32B 2
80
81/* kill bit for SMBHSTCNT */
82#define SMBHSTCNT_KILL 2
83
77/* Other settings */ 84/* Other settings */
78#define MAX_TIMEOUT 100 85#define MAX_TIMEOUT 100
79#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */ 86#define ENABLE_INT9 0 /* set to 0x01 to enable - untested */
@@ -91,10 +98,15 @@
91#define I801_START 0x40 98#define I801_START 0x40
92#define I801_PEC_EN 0x80 /* ICH4 only */ 99#define I801_PEC_EN 0x80 /* ICH4 only */
93 100
94 101/* I801 Hosts Status register bits */
95static int i801_transaction(void); 102#define SMBHSTSTS_BYTE_DONE 0x80
96static int i801_block_transaction(union i2c_smbus_data *data, char read_write, 103#define SMBHSTSTS_INUSE_STS 0x40
97 int command, int hwpec); 104#define SMBHSTSTS_SMBALERT_STS 0x20
105#define SMBHSTSTS_FAILED 0x10
106#define SMBHSTSTS_BUS_ERR 0x08
107#define SMBHSTSTS_DEV_ERR 0x04
108#define SMBHSTSTS_INTR 0x02
109#define SMBHSTSTS_HOST_BUSY 0x01
98 110
99static unsigned long i801_smba; 111static unsigned long i801_smba;
100static unsigned char i801_original_hstcfg; 112static unsigned char i801_original_hstcfg;
@@ -133,27 +145,32 @@ static int i801_transaction(void)
133 do { 145 do {
134 msleep(1); 146 msleep(1);
135 temp = inb_p(SMBHSTSTS); 147 temp = inb_p(SMBHSTSTS);
136 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); 148 } while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
137 149
138 /* If the SMBus is still busy, we give up */ 150 /* If the SMBus is still busy, we give up */
139 if (timeout >= MAX_TIMEOUT) { 151 if (timeout >= MAX_TIMEOUT) {
140 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); 152 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
141 result = -1; 153 result = -1;
154 /* try to stop the current command */
155 dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
156 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
157 msleep(1);
158 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
142 } 159 }
143 160
144 if (temp & 0x10) { 161 if (temp & SMBHSTSTS_FAILED) {
145 result = -1; 162 result = -1;
146 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); 163 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
147 } 164 }
148 165
149 if (temp & 0x08) { 166 if (temp & SMBHSTSTS_BUS_ERR) {
150 result = -1; 167 result = -1;
151 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " 168 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
152 "until next hard reset. (sorry!)\n"); 169 "until next hard reset. (sorry!)\n");
153 /* Clock stops and slave is stuck in mid-transmission */ 170 /* Clock stops and slave is stuck in mid-transmission */
154 } 171 }
155 172
156 if (temp & 0x04) { 173 if (temp & SMBHSTSTS_DEV_ERR) {
157 result = -1; 174 result = -1;
158 dev_dbg(&I801_dev->dev, "Error: no response!\n"); 175 dev_dbg(&I801_dev->dev, "Error: no response!\n");
159 } 176 }
@@ -172,6 +189,24 @@ static int i801_transaction(void)
172 return result; 189 return result;
173} 190}
174 191
192/* wait for INTR bit as advised by Intel */
193static void i801_wait_hwpec(void)
194{
195 int timeout = 0;
196 int temp;
197
198 do {
199 msleep(1);
200 temp = inb_p(SMBHSTSTS);
201 } while ((!(temp & SMBHSTSTS_INTR))
202 && (timeout++ < MAX_TIMEOUT));
203
204 if (timeout >= MAX_TIMEOUT) {
205 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
206 }
207 outb_p(temp, SMBHSTSTS);
208}
209
175/* All-inclusive block transaction function */ 210/* All-inclusive block transaction function */
176static int i801_block_transaction(union i2c_smbus_data *data, char read_write, 211static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
177 int command, int hwpec) 212 int command, int hwpec)
@@ -227,13 +262,13 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
227 /* Make sure the SMBus host is ready to start transmitting */ 262 /* Make sure the SMBus host is ready to start transmitting */
228 temp = inb_p(SMBHSTSTS); 263 temp = inb_p(SMBHSTSTS);
229 if (i == 1) { 264 if (i == 1) {
230 /* Erronenous conditions before transaction: 265 /* Erronenous conditions before transaction:
231 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ 266 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
232 errmask=0x9f; 267 errmask = 0x9f;
233 } else { 268 } else {
234 /* Erronenous conditions during transaction: 269 /* Erronenous conditions during transaction:
235 * Failed, Bus_Err, Dev_Err, Intr */ 270 * Failed, Bus_Err, Dev_Err, Intr */
236 errmask=0x1e; 271 errmask = 0x1e;
237 } 272 }
238 if (temp & errmask) { 273 if (temp & errmask) {
239 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). " 274 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
@@ -243,7 +278,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
243 dev_err(&I801_dev->dev, 278 dev_err(&I801_dev->dev,
244 "Reset failed! (%02x)\n", temp); 279 "Reset failed! (%02x)\n", temp);
245 result = -1; 280 result = -1;
246 goto END; 281 goto END;
247 } 282 }
248 if (i != 1) { 283 if (i != 1) {
249 /* if die in middle of block transaction, fail */ 284 /* if die in middle of block transaction, fail */
@@ -261,33 +296,40 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
261 msleep(1); 296 msleep(1);
262 temp = inb_p(SMBHSTSTS); 297 temp = inb_p(SMBHSTSTS);
263 } 298 }
264 while ((!(temp & 0x80)) 299 while ((!(temp & SMBHSTSTS_BYTE_DONE))
265 && (timeout++ < MAX_TIMEOUT)); 300 && (timeout++ < MAX_TIMEOUT));
266 301
267 /* If the SMBus is still busy, we give up */ 302 /* If the SMBus is still busy, we give up */
268 if (timeout >= MAX_TIMEOUT) { 303 if (timeout >= MAX_TIMEOUT) {
304 /* try to stop the current command */
305 dev_dbg(&I801_dev->dev, "Terminating the current "
306 "operation\n");
307 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
308 msleep(1);
309 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
310 SMBHSTCNT);
269 result = -1; 311 result = -1;
270 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); 312 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
271 } 313 }
272 314
273 if (temp & 0x10) { 315 if (temp & SMBHSTSTS_FAILED) {
274 result = -1; 316 result = -1;
275 dev_dbg(&I801_dev->dev, 317 dev_dbg(&I801_dev->dev,
276 "Error: Failed bus transaction\n"); 318 "Error: Failed bus transaction\n");
277 } else if (temp & 0x08) { 319 } else if (temp & SMBHSTSTS_BUS_ERR) {
278 result = -1; 320 result = -1;
279 dev_err(&I801_dev->dev, "Bus collision!\n"); 321 dev_err(&I801_dev->dev, "Bus collision!\n");
280 } else if (temp & 0x04) { 322 } else if (temp & SMBHSTSTS_DEV_ERR) {
281 result = -1; 323 result = -1;
282 dev_dbg(&I801_dev->dev, "Error: no response!\n"); 324 dev_dbg(&I801_dev->dev, "Error: no response!\n");
283 } 325 }
284 326
285 if (i == 1 && read_write == I2C_SMBUS_READ) { 327 if (i == 1 && read_write == I2C_SMBUS_READ) {
286 len = inb_p(SMBHSTDAT0); 328 len = inb_p(SMBHSTDAT0);
287 if (len < 1) 329 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
288 len = 1; 330 result = -1;
289 if (len > 32) 331 goto END;
290 len = 32; 332 }
291 data->block[0] = len; 333 data->block[0] = len;
292 } 334 }
293 335
@@ -313,20 +355,9 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
313 goto END; 355 goto END;
314 } 356 }
315 357
316 if (hwpec) { 358 if (hwpec)
317 /* wait for INTR bit as advised by Intel */ 359 i801_wait_hwpec();
318 timeout = 0;
319 do {
320 msleep(1);
321 temp = inb_p(SMBHSTSTS);
322 } while ((!(temp & 0x02))
323 && (timeout++ < MAX_TIMEOUT));
324 360
325 if (timeout >= MAX_TIMEOUT) {
326 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
327 }
328 outb_p(temp, SMBHSTSTS);
329 }
330 result = 0; 361 result = 0;
331END: 362END:
332 if (command == I2C_SMBUS_I2C_BLOCK_DATA) { 363 if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
@@ -393,7 +424,10 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
393 return -1; 424 return -1;
394 } 425 }
395 426
396 outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */ 427 if (hwpec) /* enable/disable hardware PEC */
428 outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_CRC, SMBAUXCTL);
429 else
430 outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
397 431
398 if(block) 432 if(block)
399 ret = i801_block_transaction(data, read_write, size, hwpec); 433 ret = i801_block_transaction(data, read_write, size, hwpec);
@@ -405,7 +439,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
405 /* Some BIOSes don't like it when PEC is enabled at reboot or resume 439 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
406 time, so we forcibly disable it after every transaction. */ 440 time, so we forcibly disable it after every transaction. */
407 if (hwpec) 441 if (hwpec)
408 outb_p(0, SMBAUXCTL); 442 outb_p(inb_p(SMBAUXCTL) & (~SMBAUXCTL_CRC), SMBAUXCTL);
409 443
410 if(block) 444 if(block)
411 return ret; 445 return ret;