aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-i801.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-i801.c')
-rw-r--r--drivers/i2c/busses/i2c-i801.c284
1 files changed, 136 insertions, 148 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index b0f771fe4326..dc7ea32b69a8 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -1,10 +1,8 @@
1/* 1/*
2 i2c-i801.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>, 2 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
5 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker 3 Philip Edelbrock <phil@netroedge.com>, and Mark D. Studebaker
6 <mdsxyz123@yahoo.com> 4 <mdsxyz123@yahoo.com>
7 Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> 5 Copyright (C) 2007, 2008 Jean Delvare <khali@linux-fr.org>
8 6
9 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
@@ -64,6 +62,7 @@
64#include <linux/ioport.h> 62#include <linux/ioport.h>
65#include <linux/init.h> 63#include <linux/init.h>
66#include <linux/i2c.h> 64#include <linux/i2c.h>
65#include <linux/acpi.h>
67#include <asm/io.h> 66#include <asm/io.h>
68 67
69/* I801 SMBus address offsets */ 68/* I801 SMBus address offsets */
@@ -121,6 +120,10 @@
121#define SMBHSTSTS_INTR 0x02 120#define SMBHSTSTS_INTR 0x02
122#define SMBHSTSTS_HOST_BUSY 0x01 121#define SMBHSTSTS_HOST_BUSY 0x01
123 122
123#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_FAILED | \
124 SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \
125 SMBHSTSTS_INTR)
126
124static unsigned long i801_smba; 127static unsigned long i801_smba;
125static unsigned char i801_original_hstcfg; 128static unsigned char i801_original_hstcfg;
126static struct pci_driver i801_driver; 129static struct pci_driver i801_driver;
@@ -132,105 +135,137 @@ static struct pci_dev *I801_dev;
132#define FEATURE_I2C_BLOCK_READ (1 << 3) 135#define FEATURE_I2C_BLOCK_READ (1 << 3)
133static unsigned int i801_features; 136static unsigned int i801_features;
134 137
135static int i801_transaction(int xact) 138/* Make sure the SMBus host is ready to start transmitting.
139 Return 0 if it is, -EBUSY if it is not. */
140static int i801_check_pre(void)
136{ 141{
137 int temp; 142 int status;
138 int result = 0;
139 int timeout = 0;
140 143
141 dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " 144 status = inb_p(SMBHSTSTS);
142 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), 145 if (status & SMBHSTSTS_HOST_BUSY) {
143 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 146 dev_err(&I801_dev->dev, "SMBus is busy, can't use it!\n");
144 inb_p(SMBHSTDAT1)); 147 return -EBUSY;
145 148 }
146 /* Make sure the SMBus host is ready to start transmitting */ 149
147 /* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */ 150 status &= STATUS_FLAGS;
148 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { 151 if (status) {
149 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting...\n", 152 dev_dbg(&I801_dev->dev, "Clearing status flags (%02x)\n",
150 temp); 153 status);
151 outb_p(temp, SMBHSTSTS); 154 outb_p(status, SMBHSTSTS);
152 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { 155 status = inb_p(SMBHSTSTS) & STATUS_FLAGS;
153 dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp); 156 if (status) {
154 return -1; 157 dev_err(&I801_dev->dev,
155 } else { 158 "Failed clearing status flags (%02x)\n",
156 dev_dbg(&I801_dev->dev, "Successful!\n"); 159 status);
160 return -EBUSY;
157 } 161 }
158 } 162 }
159 163
160 /* the current contents of SMBHSTCNT can be overwritten, since PEC, 164 return 0;
161 * INTREN, SMBSCMD are passed in xact */ 165}
162 outb_p(xact | I801_START, SMBHSTCNT);
163 166
164 /* We will always wait for a fraction of a second! */ 167/* Convert the status register to an error code, and clear it. */
165 do { 168static int i801_check_post(int status, int timeout)
166 msleep(1); 169{
167 temp = inb_p(SMBHSTSTS); 170 int result = 0;
168 } while ((temp & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
169 171
170 /* If the SMBus is still busy, we give up */ 172 /* If the SMBus is still busy, we give up */
171 if (timeout >= MAX_TIMEOUT) { 173 if (timeout) {
172 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n"); 174 dev_err(&I801_dev->dev, "Transaction timeout\n");
173 result = -1;
174 /* try to stop the current command */ 175 /* try to stop the current command */
175 dev_dbg(&I801_dev->dev, "Terminating the current operation\n"); 176 dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
176 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT); 177 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
177 msleep(1); 178 msleep(1);
178 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT); 179 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL), SMBHSTCNT);
179 }
180 180
181 if (temp & SMBHSTSTS_FAILED) { 181 /* Check if it worked */
182 result = -1; 182 status = inb_p(SMBHSTSTS);
183 dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n"); 183 if ((status & SMBHSTSTS_HOST_BUSY) ||
184 !(status & SMBHSTSTS_FAILED))
185 dev_err(&I801_dev->dev,
186 "Failed terminating the transaction\n");
187 outb_p(STATUS_FLAGS, SMBHSTSTS);
188 return -ETIMEDOUT;
184 } 189 }
185 190
186 if (temp & SMBHSTSTS_BUS_ERR) { 191 if (status & SMBHSTSTS_FAILED) {
187 result = -1; 192 result = -EIO;
188 dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked " 193 dev_err(&I801_dev->dev, "Transaction failed\n");
189 "until next hard reset. (sorry!)\n");
190 /* Clock stops and slave is stuck in mid-transmission */
191 } 194 }
192 195 if (status & SMBHSTSTS_DEV_ERR) {
193 if (temp & SMBHSTSTS_DEV_ERR) { 196 result = -ENXIO;
194 result = -1; 197 dev_dbg(&I801_dev->dev, "No response\n");
195 dev_dbg(&I801_dev->dev, "Error: no response!\n"); 198 }
199 if (status & SMBHSTSTS_BUS_ERR) {
200 result = -EAGAIN;
201 dev_dbg(&I801_dev->dev, "Lost arbitration\n");
196 } 202 }
197 203
198 if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00) 204 if (result) {
199 outb_p(inb(SMBHSTSTS), SMBHSTSTS); 205 /* Clear error flags */
200 206 outb_p(status & STATUS_FLAGS, SMBHSTSTS);
201 if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { 207 status = inb_p(SMBHSTSTS) & STATUS_FLAGS;
202 dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " 208 if (status) {
203 "(%02x)\n", temp); 209 dev_warn(&I801_dev->dev, "Failed clearing status "
210 "flags at end of transaction (%02x)\n",
211 status);
212 }
204 } 213 }
205 dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " 214
206 "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
207 inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
208 inb_p(SMBHSTDAT1));
209 return result; 215 return result;
210} 216}
211 217
218static int i801_transaction(int xact)
219{
220 int status;
221 int result;
222 int timeout = 0;
223
224 result = i801_check_pre();
225 if (result < 0)
226 return result;
227
228 /* the current contents of SMBHSTCNT can be overwritten, since PEC,
229 * INTREN, SMBSCMD are passed in xact */
230 outb_p(xact | I801_START, SMBHSTCNT);
231
232 /* We will always wait for a fraction of a second! */
233 do {
234 msleep(1);
235 status = inb_p(SMBHSTSTS);
236 } while ((status & SMBHSTSTS_HOST_BUSY) && (timeout++ < MAX_TIMEOUT));
237
238 result = i801_check_post(status, timeout >= MAX_TIMEOUT);
239 if (result < 0)
240 return result;
241
242 outb_p(SMBHSTSTS_INTR, SMBHSTSTS);
243 return 0;
244}
245
212/* wait for INTR bit as advised by Intel */ 246/* wait for INTR bit as advised by Intel */
213static void i801_wait_hwpec(void) 247static void i801_wait_hwpec(void)
214{ 248{
215 int timeout = 0; 249 int timeout = 0;
216 int temp; 250 int status;
217 251
218 do { 252 do {
219 msleep(1); 253 msleep(1);
220 temp = inb_p(SMBHSTSTS); 254 status = inb_p(SMBHSTSTS);
221 } while ((!(temp & SMBHSTSTS_INTR)) 255 } while ((!(status & SMBHSTSTS_INTR))
222 && (timeout++ < MAX_TIMEOUT)); 256 && (timeout++ < MAX_TIMEOUT));
223 257
224 if (timeout >= MAX_TIMEOUT) { 258 if (timeout >= MAX_TIMEOUT) {
225 dev_dbg(&I801_dev->dev, "PEC Timeout!\n"); 259 dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
226 } 260 }
227 outb_p(temp, SMBHSTSTS); 261 outb_p(status, SMBHSTSTS);
228} 262}
229 263
230static int i801_block_transaction_by_block(union i2c_smbus_data *data, 264static int i801_block_transaction_by_block(union i2c_smbus_data *data,
231 char read_write, int hwpec) 265 char read_write, int hwpec)
232{ 266{
233 int i, len; 267 int i, len;
268 int status;
234 269
235 inb_p(SMBHSTCNT); /* reset the data buffer index */ 270 inb_p(SMBHSTCNT); /* reset the data buffer index */
236 271
@@ -242,14 +277,15 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data,
242 outb_p(data->block[i+1], SMBBLKDAT); 277 outb_p(data->block[i+1], SMBBLKDAT);
243 } 278 }
244 279
245 if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 | 280 status = i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
246 I801_PEC_EN * hwpec)) 281 I801_PEC_EN * hwpec);
247 return -1; 282 if (status)
283 return status;
248 284
249 if (read_write == I2C_SMBUS_READ) { 285 if (read_write == I2C_SMBUS_READ) {
250 len = inb_p(SMBHSTDAT0); 286 len = inb_p(SMBHSTDAT0);
251 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) 287 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
252 return -1; 288 return -EPROTO;
253 289
254 data->block[0] = len; 290 data->block[0] = len;
255 for (i = 0; i < len; i++) 291 for (i = 0; i < len; i++)
@@ -264,10 +300,13 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
264{ 300{
265 int i, len; 301 int i, len;
266 int smbcmd; 302 int smbcmd;
267 int temp; 303 int status;
268 int result = 0; 304 int result;
269 int timeout; 305 int timeout;
270 unsigned char errmask; 306
307 result = i801_check_pre();
308 if (result < 0)
309 return result;
271 310
272 len = data->block[0]; 311 len = data->block[0];
273 312
@@ -291,36 +330,6 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
291 } 330 }
292 outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); 331 outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);
293 332
294 dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
295 "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
296 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
297 inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
298
299 /* Make sure the SMBus host is ready to start transmitting */
300 temp = inb_p(SMBHSTSTS);
301 if (i == 1) {
302 /* Erroneous conditions before transaction:
303 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
304 errmask = 0x9f;
305 } else {
306 /* Erroneous conditions during transaction:
307 * Failed, Bus_Err, Dev_Err, Intr */
308 errmask = 0x1e;
309 }
310 if (temp & errmask) {
311 dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
312 "Resetting...\n", temp);
313 outb_p(temp, SMBHSTSTS);
314 if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
315 dev_err(&I801_dev->dev,
316 "Reset failed! (%02x)\n", temp);
317 return -1;
318 }
319 if (i != 1)
320 /* if die in middle of block transaction, fail */
321 return -1;
322 }
323
324 if (i == 1) 333 if (i == 1)
325 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); 334 outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);
326 335
@@ -328,41 +337,28 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
328 timeout = 0; 337 timeout = 0;
329 do { 338 do {
330 msleep(1); 339 msleep(1);
331 temp = inb_p(SMBHSTSTS); 340 status = inb_p(SMBHSTSTS);
332 } 341 }
333 while ((!(temp & SMBHSTSTS_BYTE_DONE)) 342 while ((!(status & SMBHSTSTS_BYTE_DONE))
334 && (timeout++ < MAX_TIMEOUT)); 343 && (timeout++ < MAX_TIMEOUT));
335 344
336 /* If the SMBus is still busy, we give up */ 345 result = i801_check_post(status, timeout >= MAX_TIMEOUT);
337 if (timeout >= MAX_TIMEOUT) { 346 if (result < 0)
338 /* try to stop the current command */ 347 return result;
339 dev_dbg(&I801_dev->dev, "Terminating the current "
340 "operation\n");
341 outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
342 msleep(1);
343 outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
344 SMBHSTCNT);
345 result = -1;
346 dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
347 }
348
349 if (temp & SMBHSTSTS_FAILED) {
350 result = -1;
351 dev_dbg(&I801_dev->dev,
352 "Error: Failed bus transaction\n");
353 } else if (temp & SMBHSTSTS_BUS_ERR) {
354 result = -1;
355 dev_err(&I801_dev->dev, "Bus collision!\n");
356 } else if (temp & SMBHSTSTS_DEV_ERR) {
357 result = -1;
358 dev_dbg(&I801_dev->dev, "Error: no response!\n");
359 }
360 348
361 if (i == 1 && read_write == I2C_SMBUS_READ 349 if (i == 1 && read_write == I2C_SMBUS_READ
362 && command != I2C_SMBUS_I2C_BLOCK_DATA) { 350 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
363 len = inb_p(SMBHSTDAT0); 351 len = inb_p(SMBHSTDAT0);
364 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) 352 if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
365 return -1; 353 dev_err(&I801_dev->dev,
354 "Illegal SMBus block read size %d\n",
355 len);
356 /* Recover */
357 while (inb_p(SMBHSTSTS) & SMBHSTSTS_HOST_BUSY)
358 outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS);
359 outb_p(SMBHSTSTS_INTR, SMBHSTSTS);
360 return -EPROTO;
361 }
366 data->block[0] = len; 362 data->block[0] = len;
367 } 363 }
368 364
@@ -371,30 +367,19 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
371 data->block[i] = inb_p(SMBBLKDAT); 367 data->block[i] = inb_p(SMBBLKDAT);
372 if (read_write == I2C_SMBUS_WRITE && i+1 <= len) 368 if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
373 outb_p(data->block[i+1], SMBBLKDAT); 369 outb_p(data->block[i+1], SMBBLKDAT);
374 if ((temp & 0x9e) != 0x00)
375 outb_p(temp, SMBHSTSTS); /* signals SMBBLKDAT ready */
376
377 if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
378 dev_dbg(&I801_dev->dev,
379 "Bad status (%02x) at end of transaction\n",
380 temp);
381 }
382 dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
383 "ADD=%02x, DAT0=%02x, DAT1=%02x, BLKDAT=%02x\n", i,
384 inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
385 inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1), inb_p(SMBBLKDAT));
386 370
387 if (result < 0) 371 /* signals SMBBLKDAT ready */
388 return result; 372 outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS);
389 } 373 }
390 return result; 374
375 return 0;
391} 376}
392 377
393static int i801_set_block_buffer_mode(void) 378static int i801_set_block_buffer_mode(void)
394{ 379{
395 outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL); 380 outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
396 if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0) 381 if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
397 return -1; 382 return -EIO;
398 return 0; 383 return 0;
399} 384}
400 385
@@ -414,7 +399,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
414 } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) { 399 } else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
415 dev_err(&I801_dev->dev, 400 dev_err(&I801_dev->dev,
416 "I2C block read is unsupported!\n"); 401 "I2C block read is unsupported!\n");
417 return -1; 402 return -EOPNOTSUPP;
418 } 403 }
419 } 404 }
420 405
@@ -449,7 +434,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
449 return result; 434 return result;
450} 435}
451 436
452/* Return -1 on error. */ 437/* Return negative errno on error. */
453static s32 i801_access(struct i2c_adapter * adap, u16 addr, 438static s32 i801_access(struct i2c_adapter * adap, u16 addr,
454 unsigned short flags, char read_write, u8 command, 439 unsigned short flags, char read_write, u8 command,
455 int size, union i2c_smbus_data * data) 440 int size, union i2c_smbus_data * data)
@@ -511,10 +496,9 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
511 outb_p(command, SMBHSTCMD); 496 outb_p(command, SMBHSTCMD);
512 block = 1; 497 block = 1;
513 break; 498 break;
514 case I2C_SMBUS_PROC_CALL:
515 default: 499 default:
516 dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size); 500 dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
517 return -1; 501 return -EOPNOTSUPP;
518 } 502 }
519 503
520 if (hwpec) /* enable/disable hardware PEC */ 504 if (hwpec) /* enable/disable hardware PEC */
@@ -537,7 +521,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
537 if(block) 521 if(block)
538 return ret; 522 return ret;
539 if(ret) 523 if(ret)
540 return -1; 524 return ret;
541 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK)) 525 if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
542 return 0; 526 return 0;
543 527
@@ -572,7 +556,7 @@ static const struct i2c_algorithm smbus_algorithm = {
572static struct i2c_adapter i801_adapter = { 556static struct i2c_adapter i801_adapter = {
573 .owner = THIS_MODULE, 557 .owner = THIS_MODULE,
574 .id = I2C_HW_SMBUS_I801, 558 .id = I2C_HW_SMBUS_I801,
575 .class = I2C_CLASS_HWMON, 559 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
576 .algo = &smbus_algorithm, 560 .algo = &smbus_algorithm,
577}; 561};
578 562
@@ -639,6 +623,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
639 goto exit; 623 goto exit;
640 } 624 }
641 625
626 err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
627 if (err)
628 goto exit;
629
642 err = pci_request_region(dev, SMBBAR, i801_driver.name); 630 err = pci_request_region(dev, SMBBAR, i801_driver.name);
643 if (err) { 631 if (err) {
644 dev_err(&dev->dev, "Failed to request SMBus region " 632 dev_err(&dev->dev, "Failed to request SMBus region "