aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-piix4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
-rw-r--r--drivers/i2c/busses/i2c-piix4.c73
1 files changed, 33 insertions, 40 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index ac9165968587..eaa9b387543e 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -1,6 +1,4 @@
1/* 1/*
2 piix4.c - Part of lm_sensors, Linux kernel modules for hardware
3 monitoring
4 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and 2 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
5 Philip Edelbrock <phil@netroedge.com> 3 Philip Edelbrock <phil@netroedge.com>
6 4
@@ -39,16 +37,10 @@
39#include <linux/i2c.h> 37#include <linux/i2c.h>
40#include <linux/init.h> 38#include <linux/init.h>
41#include <linux/dmi.h> 39#include <linux/dmi.h>
40#include <linux/acpi.h>
42#include <asm/io.h> 41#include <asm/io.h>
43 42
44 43
45struct sd {
46 const unsigned short mfr;
47 const unsigned short dev;
48 const unsigned char fn;
49 const char *name;
50};
51
52/* PIIX4 SMBus address offsets */ 44/* PIIX4 SMBus address offsets */
53#define SMBHSTSTS (0 + piix4_smba) 45#define SMBHSTSTS (0 + piix4_smba)
54#define SMBHSLVSTS (1 + piix4_smba) 46#define SMBHSLVSTS (1 + piix4_smba)
@@ -101,8 +93,6 @@ MODULE_PARM_DESC(force_addr,
101 "Forcibly enable the PIIX4 at the given address. " 93 "Forcibly enable the PIIX4 at the given address. "
102 "EXTREMELY DANGEROUS!"); 94 "EXTREMELY DANGEROUS!");
103 95
104static int piix4_transaction(void);
105
106static unsigned short piix4_smba; 96static unsigned short piix4_smba;
107static int srvrworks_csb5_delay; 97static int srvrworks_csb5_delay;
108static struct pci_driver piix4_driver; 98static struct pci_driver piix4_driver;
@@ -141,8 +131,6 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
141{ 131{
142 unsigned char temp; 132 unsigned char temp;
143 133
144 dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
145
146 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && 134 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
147 (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) 135 (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
148 srvrworks_csb5_delay = 1; 136 srvrworks_csb5_delay = 1;
@@ -172,17 +160,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
172 pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba); 160 pci_read_config_word(PIIX4_dev, SMBBA, &piix4_smba);
173 piix4_smba &= 0xfff0; 161 piix4_smba &= 0xfff0;
174 if(piix4_smba == 0) { 162 if(piix4_smba == 0) {
175 dev_err(&PIIX4_dev->dev, "SMB base address " 163 dev_err(&PIIX4_dev->dev, "SMBus base address "
176 "uninitialized - upgrade BIOS or use " 164 "uninitialized - upgrade BIOS or use "
177 "force_addr=0xaddr\n"); 165 "force_addr=0xaddr\n");
178 return -ENODEV; 166 return -ENODEV;
179 } 167 }
180 } 168 }
181 169
170 if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
171 return -EBUSY;
172
182 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { 173 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
183 dev_err(&PIIX4_dev->dev, "SMB region 0x%x already in use!\n", 174 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
184 piix4_smba); 175 piix4_smba);
185 return -ENODEV; 176 return -EBUSY;
186 } 177 }
187 178
188 pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp); 179 pci_read_config_byte(PIIX4_dev, SMBHSTCFG, &temp);
@@ -228,13 +219,13 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
228 "(or code out of date)!\n"); 219 "(or code out of date)!\n");
229 220
230 pci_read_config_byte(PIIX4_dev, SMBREV, &temp); 221 pci_read_config_byte(PIIX4_dev, SMBREV, &temp);
231 dev_dbg(&PIIX4_dev->dev, "SMBREV = 0x%X\n", temp); 222 dev_info(&PIIX4_dev->dev,
232 dev_dbg(&PIIX4_dev->dev, "SMBA = 0x%X\n", piix4_smba); 223 "SMBus Host Controller at 0x%x, revision %d\n",
224 piix4_smba, temp);
233 225
234 return 0; 226 return 0;
235} 227}
236 228
237/* Another internally used function */
238static int piix4_transaction(void) 229static int piix4_transaction(void)
239{ 230{
240 int temp; 231 int temp;
@@ -253,7 +244,7 @@ static int piix4_transaction(void)
253 outb_p(temp, SMBHSTSTS); 244 outb_p(temp, SMBHSTSTS);
254 if ((temp = inb_p(SMBHSTSTS)) != 0x00) { 245 if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
255 dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp); 246 dev_err(&piix4_adapter.dev, "Failed! (%02x)\n", temp);
256 return -1; 247 return -EBUSY;
257 } else { 248 } else {
258 dev_dbg(&piix4_adapter.dev, "Successful!\n"); 249 dev_dbg(&piix4_adapter.dev, "Successful!\n");
259 } 250 }
@@ -275,23 +266,23 @@ static int piix4_transaction(void)
275 /* If the SMBus is still busy, we give up */ 266 /* If the SMBus is still busy, we give up */
276 if (timeout >= MAX_TIMEOUT) { 267 if (timeout >= MAX_TIMEOUT) {
277 dev_err(&piix4_adapter.dev, "SMBus Timeout!\n"); 268 dev_err(&piix4_adapter.dev, "SMBus Timeout!\n");
278 result = -1; 269 result = -ETIMEDOUT;
279 } 270 }
280 271
281 if (temp & 0x10) { 272 if (temp & 0x10) {
282 result = -1; 273 result = -EIO;
283 dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n"); 274 dev_err(&piix4_adapter.dev, "Error: Failed bus transaction\n");
284 } 275 }
285 276
286 if (temp & 0x08) { 277 if (temp & 0x08) {
287 result = -1; 278 result = -EIO;
288 dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be " 279 dev_dbg(&piix4_adapter.dev, "Bus collision! SMBus may be "
289 "locked until next hard reset. (sorry!)\n"); 280 "locked until next hard reset. (sorry!)\n");
290 /* Clock stops and slave is stuck in mid-transmission */ 281 /* Clock stops and slave is stuck in mid-transmission */
291 } 282 }
292 283
293 if (temp & 0x04) { 284 if (temp & 0x04) {
294 result = -1; 285 result = -ENXIO;
295 dev_dbg(&piix4_adapter.dev, "Error: no response!\n"); 286 dev_dbg(&piix4_adapter.dev, "Error: no response!\n");
296 } 287 }
297 288
@@ -309,31 +300,29 @@ static int piix4_transaction(void)
309 return result; 300 return result;
310} 301}
311 302
312/* Return -1 on error. */ 303/* Return negative errno on error. */
313static s32 piix4_access(struct i2c_adapter * adap, u16 addr, 304static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
314 unsigned short flags, char read_write, 305 unsigned short flags, char read_write,
315 u8 command, int size, union i2c_smbus_data * data) 306 u8 command, int size, union i2c_smbus_data * data)
316{ 307{
317 int i, len; 308 int i, len;
309 int status;
318 310
319 switch (size) { 311 switch (size) {
320 case I2C_SMBUS_PROC_CALL:
321 dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
322 return -1;
323 case I2C_SMBUS_QUICK: 312 case I2C_SMBUS_QUICK:
324 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 313 outb_p((addr << 1) | read_write,
325 SMBHSTADD); 314 SMBHSTADD);
326 size = PIIX4_QUICK; 315 size = PIIX4_QUICK;
327 break; 316 break;
328 case I2C_SMBUS_BYTE: 317 case I2C_SMBUS_BYTE:
329 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 318 outb_p((addr << 1) | read_write,
330 SMBHSTADD); 319 SMBHSTADD);
331 if (read_write == I2C_SMBUS_WRITE) 320 if (read_write == I2C_SMBUS_WRITE)
332 outb_p(command, SMBHSTCMD); 321 outb_p(command, SMBHSTCMD);
333 size = PIIX4_BYTE; 322 size = PIIX4_BYTE;
334 break; 323 break;
335 case I2C_SMBUS_BYTE_DATA: 324 case I2C_SMBUS_BYTE_DATA:
336 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 325 outb_p((addr << 1) | read_write,
337 SMBHSTADD); 326 SMBHSTADD);
338 outb_p(command, SMBHSTCMD); 327 outb_p(command, SMBHSTCMD);
339 if (read_write == I2C_SMBUS_WRITE) 328 if (read_write == I2C_SMBUS_WRITE)
@@ -341,7 +330,7 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
341 size = PIIX4_BYTE_DATA; 330 size = PIIX4_BYTE_DATA;
342 break; 331 break;
343 case I2C_SMBUS_WORD_DATA: 332 case I2C_SMBUS_WORD_DATA:
344 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 333 outb_p((addr << 1) | read_write,
345 SMBHSTADD); 334 SMBHSTADD);
346 outb_p(command, SMBHSTCMD); 335 outb_p(command, SMBHSTCMD);
347 if (read_write == I2C_SMBUS_WRITE) { 336 if (read_write == I2C_SMBUS_WRITE) {
@@ -351,15 +340,13 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
351 size = PIIX4_WORD_DATA; 340 size = PIIX4_WORD_DATA;
352 break; 341 break;
353 case I2C_SMBUS_BLOCK_DATA: 342 case I2C_SMBUS_BLOCK_DATA:
354 outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), 343 outb_p((addr << 1) | read_write,
355 SMBHSTADD); 344 SMBHSTADD);
356 outb_p(command, SMBHSTCMD); 345 outb_p(command, SMBHSTCMD);
357 if (read_write == I2C_SMBUS_WRITE) { 346 if (read_write == I2C_SMBUS_WRITE) {
358 len = data->block[0]; 347 len = data->block[0];
359 if (len < 0) 348 if (len == 0 || len > I2C_SMBUS_BLOCK_MAX)
360 len = 0; 349 return -EINVAL;
361 if (len > 32)
362 len = 32;
363 outb_p(len, SMBHSTDAT0); 350 outb_p(len, SMBHSTDAT0);
364 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 351 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
365 for (i = 1; i <= len; i++) 352 for (i = 1; i <= len; i++)
@@ -367,12 +354,16 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
367 } 354 }
368 size = PIIX4_BLOCK_DATA; 355 size = PIIX4_BLOCK_DATA;
369 break; 356 break;
357 default:
358 dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
359 return -EOPNOTSUPP;
370 } 360 }
371 361
372 outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); 362 outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
373 363
374 if (piix4_transaction()) /* Error in transaction */ 364 status = piix4_transaction();
375 return -1; 365 if (status)
366 return status;
376 367
377 if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK)) 368 if ((read_write == I2C_SMBUS_WRITE) || (size == PIIX4_QUICK))
378 return 0; 369 return 0;
@@ -388,6 +379,8 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
388 break; 379 break;
389 case PIIX4_BLOCK_DATA: 380 case PIIX4_BLOCK_DATA:
390 data->block[0] = inb_p(SMBHSTDAT0); 381 data->block[0] = inb_p(SMBHSTDAT0);
382 if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
383 return -EPROTO;
391 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ 384 i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
392 for (i = 1; i <= data->block[0]; i++) 385 for (i = 1; i <= data->block[0]; i++)
393 data->block[i] = inb_p(SMBBLKDAT); 386 data->block[i] = inb_p(SMBBLKDAT);
@@ -411,7 +404,7 @@ static const struct i2c_algorithm smbus_algorithm = {
411static struct i2c_adapter piix4_adapter = { 404static struct i2c_adapter piix4_adapter = {
412 .owner = THIS_MODULE, 405 .owner = THIS_MODULE,
413 .id = I2C_HW_SMBUS_PIIX4, 406 .id = I2C_HW_SMBUS_PIIX4,
414 .class = I2C_CLASS_HWMON, 407 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
415 .algo = &smbus_algorithm, 408 .algo = &smbus_algorithm,
416}; 409};
417 410