diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-i801.c')
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 284 |
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 | |||
124 | static unsigned long i801_smba; | 127 | static unsigned long i801_smba; |
125 | static unsigned char i801_original_hstcfg; | 128 | static unsigned char i801_original_hstcfg; |
126 | static struct pci_driver i801_driver; | 129 | static 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) |
133 | static unsigned int i801_features; | 136 | static unsigned int i801_features; |
134 | 137 | ||
135 | static 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. */ | ||
140 | static 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 { | 168 | static 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 | ||
218 | static 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 */ |
213 | static void i801_wait_hwpec(void) | 247 | static 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 | ||
230 | static int i801_block_transaction_by_block(union i2c_smbus_data *data, | 264 | static 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 | ||
393 | static int i801_set_block_buffer_mode(void) | 378 | static 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. */ |
453 | static s32 i801_access(struct i2c_adapter * adap, u16 addr, | 438 | static 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 = { | |||
572 | static struct i2c_adapter i801_adapter = { | 556 | static 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 " |