aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-nforce2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-nforce2.c')
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 43c9f8df9509..3b19bc41a60b 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -51,6 +51,7 @@
51#include <linux/i2c.h> 51#include <linux/i2c.h>
52#include <linux/delay.h> 52#include <linux/delay.h>
53#include <linux/dmi.h> 53#include <linux/dmi.h>
54#include <linux/acpi.h>
54#include <asm/io.h> 55#include <asm/io.h>
55 56
56MODULE_LICENSE("GPL"); 57MODULE_LICENSE("GPL");
@@ -124,6 +125,20 @@ static struct dmi_system_id __devinitdata nforce2_dmi_blacklist2[] = {
124 125
125static struct pci_driver nforce2_driver; 126static struct pci_driver nforce2_driver;
126 127
128/* For multiplexing support, we need a global reference to the 1st
129 SMBus channel */
130#if defined CONFIG_I2C_NFORCE2_S4985 || defined CONFIG_I2C_NFORCE2_S4985_MODULE
131struct i2c_adapter *nforce2_smbus;
132EXPORT_SYMBOL_GPL(nforce2_smbus);
133
134static void nforce2_set_reference(struct i2c_adapter *adap)
135{
136 nforce2_smbus = adap;
137}
138#else
139static inline void nforce2_set_reference(struct i2c_adapter *adap) { }
140#endif
141
127static void nforce2_abort(struct i2c_adapter *adap) 142static void nforce2_abort(struct i2c_adapter *adap)
128{ 143{
129 struct nforce2_smbus *smbus = adap->algo_data; 144 struct nforce2_smbus *smbus = adap->algo_data;
@@ -158,16 +173,16 @@ static int nforce2_check_status(struct i2c_adapter *adap)
158 dev_dbg(&adap->dev, "SMBus Timeout!\n"); 173 dev_dbg(&adap->dev, "SMBus Timeout!\n");
159 if (smbus->can_abort) 174 if (smbus->can_abort)
160 nforce2_abort(adap); 175 nforce2_abort(adap);
161 return -1; 176 return -ETIMEDOUT;
162 } 177 }
163 if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) { 178 if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
164 dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp); 179 dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp);
165 return -1; 180 return -EIO;
166 } 181 }
167 return 0; 182 return 0;
168} 183}
169 184
170/* Return -1 on error */ 185/* Return negative errno on error */
171static s32 nforce2_access(struct i2c_adapter * adap, u16 addr, 186static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
172 unsigned short flags, char read_write, 187 unsigned short flags, char read_write,
173 u8 command, int size, union i2c_smbus_data * data) 188 u8 command, int size, union i2c_smbus_data * data)
@@ -175,7 +190,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
175 struct nforce2_smbus *smbus = adap->algo_data; 190 struct nforce2_smbus *smbus = adap->algo_data;
176 unsigned char protocol, pec; 191 unsigned char protocol, pec;
177 u8 len; 192 u8 len;
178 int i; 193 int i, status;
179 194
180 protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ : 195 protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
181 NVIDIA_SMB_PRTCL_WRITE; 196 NVIDIA_SMB_PRTCL_WRITE;
@@ -219,7 +234,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
219 "Transaction failed " 234 "Transaction failed "
220 "(requested block size: %d)\n", 235 "(requested block size: %d)\n",
221 len); 236 len);
222 return -1; 237 return -EINVAL;
223 } 238 }
224 outb_p(len, NVIDIA_SMB_BCNT); 239 outb_p(len, NVIDIA_SMB_BCNT);
225 for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++) 240 for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
@@ -231,14 +246,15 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
231 246
232 default: 247 default:
233 dev_err(&adap->dev, "Unsupported transaction %d\n", size); 248 dev_err(&adap->dev, "Unsupported transaction %d\n", size);
234 return -1; 249 return -EOPNOTSUPP;
235 } 250 }
236 251
237 outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR); 252 outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
238 outb_p(protocol, NVIDIA_SMB_PRTCL); 253 outb_p(protocol, NVIDIA_SMB_PRTCL);
239 254
240 if (nforce2_check_status(adap)) 255 status = nforce2_check_status(adap);
241 return -1; 256 if (status)
257 return status;
242 258
243 if (read_write == I2C_SMBUS_WRITE) 259 if (read_write == I2C_SMBUS_WRITE)
244 return 0; 260 return 0;
@@ -260,7 +276,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
260 dev_err(&adap->dev, "Transaction failed " 276 dev_err(&adap->dev, "Transaction failed "
261 "(received block size: 0x%02x)\n", 277 "(received block size: 0x%02x)\n",
262 len); 278 len);
263 return -1; 279 return -EPROTO;
264 } 280 }
265 for (i = 0; i < len; i++) 281 for (i = 0; i < len; i++)
266 data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i); 282 data->block[i+1] = inb_p(NVIDIA_SMB_DATA + i);
@@ -321,21 +337,26 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
321 != PCIBIOS_SUCCESSFUL) { 337 != PCIBIOS_SUCCESSFUL) {
322 dev_err(&dev->dev, "Error reading PCI config for %s\n", 338 dev_err(&dev->dev, "Error reading PCI config for %s\n",
323 name); 339 name);
324 return -1; 340 return -EIO;
325 } 341 }
326 342
327 smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK; 343 smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
328 smbus->size = 64; 344 smbus->size = 64;
329 } 345 }
330 346
347 error = acpi_check_region(smbus->base, smbus->size,
348 nforce2_driver.name);
349 if (error)
350 return -1;
351
331 if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { 352 if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
332 dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", 353 dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
333 smbus->base, smbus->base+smbus->size-1, name); 354 smbus->base, smbus->base+smbus->size-1, name);
334 return -1; 355 return -EBUSY;
335 } 356 }
336 smbus->adapter.owner = THIS_MODULE; 357 smbus->adapter.owner = THIS_MODULE;
337 smbus->adapter.id = I2C_HW_SMBUS_NFORCE2; 358 smbus->adapter.id = I2C_HW_SMBUS_NFORCE2;
338 smbus->adapter.class = I2C_CLASS_HWMON; 359 smbus->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
339 smbus->adapter.algo = &smbus_algorithm; 360 smbus->adapter.algo = &smbus_algorithm;
340 smbus->adapter.algo_data = smbus; 361 smbus->adapter.algo_data = smbus;
341 smbus->adapter.dev.parent = &dev->dev; 362 smbus->adapter.dev.parent = &dev->dev;
@@ -346,7 +367,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
346 if (error) { 367 if (error) {
347 dev_err(&smbus->adapter.dev, "Failed to register adapter.\n"); 368 dev_err(&smbus->adapter.dev, "Failed to register adapter.\n");
348 release_region(smbus->base, smbus->size); 369 release_region(smbus->base, smbus->size);
349 return -1; 370 return error;
350 } 371 }
351 dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base); 372 dev_info(&smbus->adapter.dev, "nForce2 SMBus adapter at %#x\n", smbus->base);
352 return 0; 373 return 0;
@@ -398,6 +419,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_
398 return -ENODEV; 419 return -ENODEV;
399 } 420 }
400 421
422 nforce2_set_reference(&smbuses[0].adapter);
401 return 0; 423 return 0;
402} 424}
403 425
@@ -406,6 +428,7 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
406{ 428{
407 struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev); 429 struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev);
408 430
431 nforce2_set_reference(NULL);
409 if (smbuses[0].base) { 432 if (smbuses[0].base) {
410 i2c_del_adapter(&smbuses[0].adapter); 433 i2c_del_adapter(&smbuses[0].adapter);
411 release_region(smbuses[0].base, smbuses[0].size); 434 release_region(smbuses[0].base, smbuses[0].size);