Lines Matching +full:smbus +full:- +full:timeout +full:- +full:disable
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl> and
11 Serverworks OSB4, CSB5, CSB6, HT-1000, HT-1100
13 AMD Hudson-2, ML, CZ
18 SMBus interfaces.
32 #include <linux/i2c-smbus.h>
38 #include "i2c-piix4.h"
61 /* Multi-port constants */
75 * Hudson-2/Bolton port is always selected by bits 2:1 of register 0x2f.
116 DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
130 on Intel-based systems */
162 if (mmio_cfg->use_mmio) { in piix4_sb800_region_request()
169 "SMBus base address memory region 0x%x already in use.\n", in piix4_sb800_region_request()
171 return -EBUSY; in piix4_sb800_region_request()
179 dev_err(dev, "SMBus base address mapping failed.\n"); in piix4_sb800_region_request()
180 return -ENOMEM; in piix4_sb800_region_request()
183 mmio_cfg->addr = addr; in piix4_sb800_region_request()
191 "SMBus base address index region 0x%x already in use.\n", in piix4_sb800_region_request()
193 return -EBUSY; in piix4_sb800_region_request()
202 if (mmio_cfg->use_mmio) { in piix4_sb800_region_release()
203 iounmap(mmio_cfg->addr); in piix4_sb800_region_release()
217 * w/ SMBus PCI revision ID 0x51 or greater. MMIO is supported on in piix4_sb800_use_mmio()
220 return (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && in piix4_sb800_use_mmio()
221 PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && in piix4_sb800_use_mmio()
222 PIIX4_dev->revision >= 0x51); in piix4_sb800_use_mmio()
231 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) && in piix4_setup()
232 (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5)) in piix4_setup()
235 /* On some motherboards, it was reported that accessing the SMBus in piix4_setup()
238 dev_err(&PIIX4_dev->dev, in piix4_setup()
239 "Accessing the SMBus on this system is unsafe!\n"); in piix4_setup()
240 return -EPERM; in piix4_setup()
243 /* Don't access SMBus on IBM systems which get corrupted eeproms */ in piix4_setup()
245 PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { in piix4_setup()
246 dev_err(&PIIX4_dev->dev, "IBM system detected; this module " in piix4_setup()
249 return -EPERM; in piix4_setup()
252 /* Determine the address of the SMBus areas */ in piix4_setup()
260 dev_err(&PIIX4_dev->dev, "SMBus base address " in piix4_setup()
261 "uninitialized - upgrade BIOS or use " in piix4_setup()
263 return -ENODEV; in piix4_setup()
268 return -ENODEV; in piix4_setup()
271 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", in piix4_setup()
273 return -EBUSY; in piix4_setup()
279 sure, we disable the PIIX4 first. */ in piix4_setup()
284 dev_info(&PIIX4_dev->dev, "WARNING: SMBus interface set to " in piix4_setup()
289 * noted that many Dell machines have the SMBus in piix4_setup()
298 dev_notice(&PIIX4_dev->dev, in piix4_setup()
299 "WARNING: SMBus interface has been FORCEFULLY ENABLED!\n"); in piix4_setup()
301 dev_err(&PIIX4_dev->dev, in piix4_setup()
302 "SMBus Host Controller not enabled!\n"); in piix4_setup()
304 return -ENODEV; in piix4_setup()
309 dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n"); in piix4_setup()
311 dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n"); in piix4_setup()
313 dev_err(&PIIX4_dev->dev, "Illegal Interrupt configuration " in piix4_setup()
317 dev_info(&PIIX4_dev->dev, in piix4_setup()
318 "SMBus Host Controller at 0x%x, revision %d\n", in piix4_setup()
336 retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); in piix4_setup_sb800_smba()
350 piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); in piix4_setup_sb800_smba()
363 dev_err(&PIIX4_dev->dev, in piix4_setup_sb800_smba()
364 "SMBus Host Controller not enabled!\n"); in piix4_setup_sb800_smba()
365 return -ENODEV; in piix4_setup_sb800_smba()
380 /* SB800 and later SMBus does not support forcing address */ in piix4_setup_sb800()
382 dev_err(&PIIX4_dev->dev, "SMBus does not support " in piix4_setup_sb800()
384 return -EINVAL; in piix4_setup_sb800()
387 /* Determine the address of the SMBus areas */ in piix4_setup_sb800()
388 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && in piix4_setup_sb800()
389 PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && in piix4_setup_sb800()
390 PIIX4_dev->revision >= 0x41) || in piix4_setup_sb800()
391 (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD && in piix4_setup_sb800()
392 PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS && in piix4_setup_sb800()
393 PIIX4_dev->revision >= 0x49) || in piix4_setup_sb800()
394 (PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON && in piix4_setup_sb800()
395 PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) in piix4_setup_sb800()
407 return -ENODEV; in piix4_setup_sb800()
410 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", in piix4_setup_sb800()
412 return -EBUSY; in piix4_setup_sb800()
415 /* Aux SMBus does not support IRQ information */ in piix4_setup_sb800()
417 dev_info(&PIIX4_dev->dev, in piix4_setup_sb800()
418 "Auxiliary SMBus Host Controller at 0x%x\n", in piix4_setup_sb800()
423 /* Request the SMBus I2C bus config region */ in piix4_setup_sb800()
425 dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " in piix4_setup_sb800()
428 return -EBUSY; in piix4_setup_sb800()
434 dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus\n"); in piix4_setup_sb800()
436 dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus\n"); in piix4_setup_sb800()
438 dev_info(&PIIX4_dev->dev, in piix4_setup_sb800()
439 "SMBus Host Controller at 0x%x, revision %d\n", in piix4_setup_sb800()
443 if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD || in piix4_setup_sb800()
444 PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON) { in piix4_setup_sb800()
445 if (PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS || in piix4_setup_sb800()
446 (PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && in piix4_setup_sb800()
447 PIIX4_dev->revision >= 0x1F)) { in piix4_setup_sb800()
458 retval = piix4_sb800_region_request(&PIIX4_dev->dev, &mmio_cfg); in piix4_setup_sb800()
471 piix4_sb800_region_release(&PIIX4_dev->dev, &mmio_cfg); in piix4_setup_sb800()
474 dev_info(&PIIX4_dev->dev, in piix4_setup_sb800()
475 "Using register 0x%02x for SMBus port selection\n", in piix4_setup_sb800()
485 /* Set up auxiliary SMBus controllers found on some in piix4_setup_aux()
490 /* Read address of auxiliary SMBus controller */ in piix4_setup_aux()
493 dev_dbg(&PIIX4_dev->dev, in piix4_setup_aux()
494 "Auxiliary SMBus controller not enabled\n"); in piix4_setup_aux()
495 return -ENODEV; in piix4_setup_aux()
500 dev_dbg(&PIIX4_dev->dev, in piix4_setup_aux()
501 "Auxiliary SMBus base address uninitialized\n"); in piix4_setup_aux()
502 return -ENODEV; in piix4_setup_aux()
506 return -ENODEV; in piix4_setup_aux()
509 dev_err(&PIIX4_dev->dev, "Auxiliary SMBus region 0x%x " in piix4_setup_aux()
511 return -EBUSY; in piix4_setup_aux()
514 dev_info(&PIIX4_dev->dev, in piix4_setup_aux()
515 "Auxiliary SMBus Host Controller at 0x%x\n", in piix4_setup_aux()
525 int timeout = 0; in piix4_transaction() local
527 dev_dbg(&piix4_adapter->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " in piix4_transaction()
532 /* Make sure the SMBus host is ready to start transmitting */ in piix4_transaction()
534 dev_dbg(&piix4_adapter->dev, "SMBus busy (%02x). " in piix4_transaction()
538 dev_err(&piix4_adapter->dev, "Failed! (%02x)\n", temp); in piix4_transaction()
539 return -EBUSY; in piix4_transaction()
541 dev_dbg(&piix4_adapter->dev, "Successful!\n"); in piix4_transaction()
554 while ((++timeout < MAX_TIMEOUT) && in piix4_transaction()
558 /* If the SMBus is still busy, we give up */ in piix4_transaction()
559 if (timeout == MAX_TIMEOUT) { in piix4_transaction()
560 dev_err(&piix4_adapter->dev, "SMBus Timeout!\n"); in piix4_transaction()
561 result = -ETIMEDOUT; in piix4_transaction()
565 result = -EIO; in piix4_transaction()
566 dev_err(&piix4_adapter->dev, "Error: Failed bus transaction\n"); in piix4_transaction()
570 result = -EIO; in piix4_transaction()
571 dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be " in piix4_transaction()
573 /* Clock stops and target is stuck in mid-transmission */ in piix4_transaction()
577 result = -ENXIO; in piix4_transaction()
578 dev_dbg(&piix4_adapter->dev, "Error: no response!\n"); in piix4_transaction()
585 dev_err(&piix4_adapter->dev, "Failed reset at end of " in piix4_transaction()
588 dev_dbg(&piix4_adapter->dev, "Transaction (post): CNT=%02x, CMD=%02x, " in piix4_transaction()
602 unsigned short piix4_smba = adapdata->smba; in piix4_access()
624 outb_p(data->byte, SMBHSTDAT0); in piix4_access()
632 outb_p(data->word & 0xff, SMBHSTDAT0); in piix4_access()
633 outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1); in piix4_access()
642 len = data->block[0]; in piix4_access()
644 return -EINVAL; in piix4_access()
648 outb_p(data->block[i], SMBBLKDAT); in piix4_access()
653 dev_warn(&adap->dev, "Unsupported transaction %d\n", size); in piix4_access()
654 return -EOPNOTSUPP; in piix4_access()
670 data->byte = inb_p(SMBHSTDAT0); in piix4_access()
673 data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8); in piix4_access()
676 data->block[0] = inb_p(SMBHSTDAT0); in piix4_access()
677 if (data->block[0] == 0 || data->block[0] > I2C_SMBUS_BLOCK_MAX) in piix4_access()
678 return -EPROTO; in piix4_access()
680 for (i = 1; i <= data->block[0]; i++) in piix4_access()
681 data->block[i] = inb_p(SMBBLKDAT); in piix4_access()
701 int timeout = MAX_TIMEOUT; in piix4_imc_sleep() local
704 return -EBUSY; in piix4_imc_sleep()
713 while (timeout--) { in piix4_imc_sleep()
722 return -ETIMEDOUT; in piix4_imc_sleep()
727 int timeout = MAX_TIMEOUT; in piix4_imc_wakeup() local
739 while (timeout--) { in piix4_imc_wakeup()
752 if (mmio_cfg->use_mmio) { in piix4_sb800_port_sel()
753 smba_en_lo = ioread8(mmio_cfg->addr + piix4_port_sel_sb800); in piix4_sb800_port_sel()
756 iowrite8(val, mmio_cfg->addr + piix4_port_sel_sb800); in piix4_sb800_port_sel()
773 * Handles access to multiple SMBus ports on the SB800.
785 unsigned short piix4_smba = adapdata->smba; in piix4_access_sb800()
791 retval = piix4_sb800_region_request(&adap->dev, &adapdata->mmio_cfg); in piix4_access_sb800()
795 /* Request the SMBUS semaphore, avoid conflicts with the IMC */ in piix4_access_sb800()
806 } while (--retries); in piix4_access_sb800()
807 /* SMBus is still owned by the IMC, we give up */ in piix4_access_sb800()
809 retval = -EBUSY; in piix4_access_sb800()
817 * All this is done through SMBus and can/will collide in piix4_access_sb800()
822 if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) { in piix4_access_sb800()
827 case -EBUSY: in piix4_access_sb800()
828 dev_warn(&adap->dev, in piix4_access_sb800()
832 case -ETIMEDOUT: in piix4_access_sb800()
833 dev_warn(&adap->dev, in piix4_access_sb800()
842 dev_warn(&adap->dev, in piix4_access_sb800()
844 adapdata->notify_imc = false; in piix4_access_sb800()
848 prev_port = piix4_sb800_port_sel(adapdata->port, &adapdata->mmio_cfg); in piix4_access_sb800()
853 piix4_sb800_port_sel(prev_port, &adapdata->mmio_cfg); in piix4_access_sb800()
858 if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) in piix4_access_sb800()
862 piix4_sb800_region_release(&adap->dev, &adapdata->mmio_cfg); in piix4_access_sb800()
925 return -ENOMEM; in piix4_add_adapter()
928 adap->owner = THIS_MODULE; in piix4_add_adapter()
929 adap->class = I2C_CLASS_HWMON; in piix4_add_adapter()
930 adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800 in piix4_add_adapter()
937 return -ENOMEM; in piix4_add_adapter()
940 adapdata->mmio_cfg.use_mmio = piix4_sb800_use_mmio(dev); in piix4_add_adapter()
941 adapdata->smba = smba; in piix4_add_adapter()
942 adapdata->sb800_main = sb800_main; in piix4_add_adapter()
943 adapdata->port = port << piix4_port_shift_sb800; in piix4_add_adapter()
944 adapdata->notify_imc = notify_imc; in piix4_add_adapter()
947 adap->dev.parent = &dev->dev; in piix4_add_adapter()
949 if (has_acpi_companion(&dev->dev)) { in piix4_add_adapter()
950 acpi_preset_companion(&adap->dev, in piix4_add_adapter()
951 ACPI_COMPANION(&dev->dev), in piix4_add_adapter()
955 snprintf(adap->name, sizeof(adap->name), in piix4_add_adapter()
956 "SMBus PIIX4 adapter%s at %04x", name, smba); in piix4_add_adapter()
987 if (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS || in piix4_add_adapters_sb800()
988 (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS && in piix4_add_adapters_sb800()
989 dev->revision >= 0x1F)) { in piix4_add_adapters_sb800()
1009 dev_err(&dev->dev, in piix4_add_adapters_sb800()
1011 while (--port >= 0) { in piix4_add_adapters_sb800()
1013 if (adapdata->smba) { in piix4_add_adapters_sb800()
1032 if ((dev->vendor == PCI_VENDOR_ID_ATI && in piix4_probe()
1033 dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS && in piix4_probe()
1034 dev->revision >= 0x40) || in piix4_probe()
1035 dev->vendor == PCI_VENDOR_ID_AMD || in piix4_probe()
1036 dev->vendor == PCI_VENDOR_ID_HYGON) { in piix4_probe()
1040 if ((dev->vendor == PCI_VENDOR_ID_AMD || in piix4_probe()
1041 dev->vendor == PCI_VENDOR_ID_HYGON) && in piix4_probe()
1042 dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) { in piix4_probe()
1049 pci_bus_read_config_byte(dev->bus, PCI_DEVFN(0x14, 3), in piix4_probe()
1061 * Try to register multiplexed main SMBus adapter, in piix4_probe()
1072 /* Try to register main SMBus adapter, give up if we can't */ in piix4_probe()
1080 /* Check for auxiliary SMBus on some AMD chipsets */ in piix4_probe()
1081 retval = -ENODEV; in piix4_probe()
1083 if (dev->vendor == PCI_VENDOR_ID_ATI && in piix4_probe()
1084 dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) { in piix4_probe()
1085 if (dev->revision < 0x40) { in piix4_probe()
1097 if (dev->vendor == PCI_VENDOR_ID_AMD && in piix4_probe()
1098 (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS || in piix4_probe()
1099 dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) { in piix4_probe()
1120 if (adapdata->smba) { in piix4_adap_remove()
1122 if (adapdata->port == (0 << piix4_port_shift_sb800)) in piix4_adap_remove()
1123 release_region(adapdata->smba, SMBIOSIZE); in piix4_adap_remove()
1133 while (--port >= 0) { in piix4_remove()
1157 MODULE_DESCRIPTION("PIIX4 SMBus driver");