diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-28 17:04:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-28 17:04:53 -0400 |
commit | 07d43ba98621f08e252a48c96b258b4d572b0257 (patch) | |
tree | c5dd8be6b2032b02fb2a27a91b02a55d54ed702d /drivers/i2c/busses/i2c-piix4.c | |
parent | 0fe41b8982001cd14ee2c77cd776735a5024e98b (diff) | |
parent | 09b8ce0a691d8e76f14a16ac6cbfde899f6c68e3 (diff) |
Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
i2c-core: Some style cleanups
i2c-piix4: Add support for the Broadcom HT1100 chipset
i2c-piix4: Add support to SB800 SMBus changes
i2c-pca-platform: Use defaults if no platform_data given
i2c-algo-pca: Use timeout for checking the state machine
i2c-algo-pca: Rework waiting for a free bus
i2c-algo-pca: Add PCA9665 support
i2c: Adapt debug macros for KERN_* constants
i2c-davinci: Fix timeout handling
i2c: Adapter timeout is in jiffies
i2c: Set a default timeout value for all adapters
i2c: Add missing KERN_* constants to printks
i2c-algo-pcf: Handle timeout correctly
i2c-algo-pcf: Style cleanups
eeprom/at24: Remove EXPERIMENTAL
i2c-nforce2: Add support for MCP67, MCP73, MCP78S and MCP79
i2c: Clarify which clients are auto-removed
i2c: Let checkpatch shout on users of the legacy model
i2c: Document the different ways to instantiate i2c devices
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 761f9dd53620..0249a7d762b9 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -20,7 +20,7 @@ | |||
20 | /* | 20 | /* |
21 | Supports: | 21 | Supports: |
22 | Intel PIIX4, 440MX | 22 | Intel PIIX4, 440MX |
23 | Serverworks OSB4, CSB5, CSB6, HT-1000 | 23 | Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100 |
24 | ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 | 24 | ATI IXP200, IXP300, IXP400, SB600, SB700, SB800 |
25 | SMSC Victory66 | 25 | SMSC Victory66 |
26 | 26 | ||
@@ -226,6 +226,70 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, | ||
230 | const struct pci_device_id *id) | ||
231 | { | ||
232 | unsigned short smba_idx = 0xcd6; | ||
233 | u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; | ||
234 | |||
235 | /* SB800 SMBus does not support forcing address */ | ||
236 | if (force || force_addr) { | ||
237 | dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support " | ||
238 | "forcing address!\n"); | ||
239 | return -EINVAL; | ||
240 | } | ||
241 | |||
242 | /* Determine the address of the SMBus areas */ | ||
243 | if (!request_region(smba_idx, 2, "smba_idx")) { | ||
244 | dev_err(&PIIX4_dev->dev, "SMBus base address index region " | ||
245 | "0x%x already in use!\n", smba_idx); | ||
246 | return -EBUSY; | ||
247 | } | ||
248 | outb_p(smb_en, smba_idx); | ||
249 | smba_en_lo = inb_p(smba_idx + 1); | ||
250 | outb_p(smb_en + 1, smba_idx); | ||
251 | smba_en_hi = inb_p(smba_idx + 1); | ||
252 | release_region(smba_idx, 2); | ||
253 | |||
254 | if ((smba_en_lo & 1) == 0) { | ||
255 | dev_err(&PIIX4_dev->dev, | ||
256 | "Host SMBus controller not enabled!\n"); | ||
257 | return -ENODEV; | ||
258 | } | ||
259 | |||
260 | piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; | ||
261 | if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) | ||
262 | return -EBUSY; | ||
263 | |||
264 | if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { | ||
265 | dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", | ||
266 | piix4_smba); | ||
267 | return -EBUSY; | ||
268 | } | ||
269 | |||
270 | /* Request the SMBus I2C bus config region */ | ||
271 | if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { | ||
272 | dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " | ||
273 | "0x%x already in use!\n", piix4_smba + i2ccfg_offset); | ||
274 | release_region(piix4_smba, SMBIOSIZE); | ||
275 | piix4_smba = 0; | ||
276 | return -EBUSY; | ||
277 | } | ||
278 | i2ccfg = inb_p(piix4_smba + i2ccfg_offset); | ||
279 | release_region(piix4_smba + i2ccfg_offset, 1); | ||
280 | |||
281 | if (i2ccfg & 1) | ||
282 | dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n"); | ||
283 | else | ||
284 | dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n"); | ||
285 | |||
286 | dev_info(&PIIX4_dev->dev, | ||
287 | "SMBus Host Controller at 0x%x, revision %d\n", | ||
288 | piix4_smba, i2ccfg >> 4); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
229 | static int piix4_transaction(void) | 293 | static int piix4_transaction(void) |
230 | { | 294 | { |
231 | int temp; | 295 | int temp; |
@@ -423,6 +487,8 @@ static struct pci_device_id piix4_ids[] = { | |||
423 | PCI_DEVICE_ID_SERVERWORKS_CSB6) }, | 487 | PCI_DEVICE_ID_SERVERWORKS_CSB6) }, |
424 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, | 488 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, |
425 | PCI_DEVICE_ID_SERVERWORKS_HT1000SB) }, | 489 | PCI_DEVICE_ID_SERVERWORKS_HT1000SB) }, |
490 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, | ||
491 | PCI_DEVICE_ID_SERVERWORKS_HT1100LD) }, | ||
426 | { 0, } | 492 | { 0, } |
427 | }; | 493 | }; |
428 | 494 | ||
@@ -433,7 +499,14 @@ static int __devinit piix4_probe(struct pci_dev *dev, | |||
433 | { | 499 | { |
434 | int retval; | 500 | int retval; |
435 | 501 | ||
436 | retval = piix4_setup(dev, id); | 502 | if ((dev->vendor == PCI_VENDOR_ID_ATI) && |
503 | (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) && | ||
504 | (dev->revision >= 0x40)) | ||
505 | /* base address location etc changed in SB800 */ | ||
506 | retval = piix4_setup_sb800(dev, id); | ||
507 | else | ||
508 | retval = piix4_setup(dev, id); | ||
509 | |||
437 | if (retval) | 510 | if (retval) |
438 | return retval; | 511 | return retval; |
439 | 512 | ||