/* If force is set to anything different from 0, we forcibly enable the
VT596. DANGEROUS! */ staticbool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Forcibly enable the SMBus. DANGEROUS!");
/* If force_addr is set to anything different from 0, we forcibly enable
the VT596 at the given address. VERY DANGEROUS! */ static u16 force_addr;
module_param_hw(force_addr, ushort, ioport, 0);
MODULE_PARM_DESC(force_addr, "Forcibly enable the SMBus at the given address. " "EXTREMELY DANGEROUS!");
/* Determine the address of the SMBus areas */ if (force_addr) {
vt596_smba = force_addr & 0xfff0;
force = 0; goto found;
}
if ((pci_read_config_word(pdev, id->driver_data, &vt596_smba)) ||
!(vt596_smba & 0x0001)) { /* try 2nd address and config reg. for 596 */ if (id->device == PCI_DEVICE_ID_VIA_82C596_3 &&
!pci_read_config_word(pdev, SMBBA2, &vt596_smba) &&
(vt596_smba & 0x0001)) {
SMBHSTCFG = 0x84;
} else { /* no matches at all */ return dev_err_probe(&pdev->dev, -ENODEV, "Cannot configure " "SMBus I/O Base address\n");
}
}
vt596_smba &= 0xfff0; if (vt596_smba == 0) return dev_err_probe(&pdev->dev, -ENODEV, "SMBus base address " "uninitialized - upgrade BIOS or use " "force_addr=0xaddr\n");
found:
error = acpi_check_region(vt596_smba, 8, vt596_driver.name); if (error) return -ENODEV;
if (!request_region(vt596_smba, 8, vt596_driver.name)) return dev_err_probe(&pdev->dev, -ENODEV, "SMBus region 0x%x already in use!\n",
vt596_smba);
pci_read_config_byte(pdev, SMBHSTCFG, &temp); /* If force_addr is set, we program the new address here. Just to make
sure, we disable the VT596 first. */ if (force_addr) {
pci_write_config_byte(pdev, SMBHSTCFG, temp & 0xfe);
pci_write_config_word(pdev, id->driver_data, vt596_smba);
pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
dev_warn(&pdev->dev, "WARNING: SMBus interface set to new " "address 0x%04x!\n", vt596_smba);
} elseif (!(temp & 0x01)) { if (force) { /* NOTE: This assumes I/O space and other allocations * WERE done by the Bios! Don't complain if your * hardware does weird things after enabling this. * :') Check for Bios updates before resorting to * this.
*/
pci_write_config_byte(pdev, SMBHSTCFG, temp | 0x01);
dev_info(&pdev->dev, "Enabling SMBus device\n");
} else {
error = dev_err_probe(&pdev->dev, -ENODEV, "SMBUS: Error: Host SMBus " "controller not enabled! - " "upgrade BIOS or use force=1\n"); goto release_region;
}
}
switch (pdev->device) { case PCI_DEVICE_ID_VIA_CX700: case PCI_DEVICE_ID_VIA_VX800: case PCI_DEVICE_ID_VIA_VX855: case PCI_DEVICE_ID_VIA_VX900: case PCI_DEVICE_ID_VIA_8251: case PCI_DEVICE_ID_VIA_8237: case PCI_DEVICE_ID_VIA_8237A: case PCI_DEVICE_ID_VIA_8237S: case PCI_DEVICE_ID_VIA_8235: case PCI_DEVICE_ID_VIA_8233A: case PCI_DEVICE_ID_VIA_8233_0:
vt596_features |= FEATURE_I2CBLOCK; break; case PCI_DEVICE_ID_VIA_82C686_4: /* The VT82C686B (rev 0x40) does support I2C block
transactions, but the VT82C686A (rev 0x30) doesn't */ if (pdev->revision >= 0x40)
vt596_features |= FEATURE_I2CBLOCK; break;
}
vt596_adapter.dev.parent = &pdev->dev;
snprintf(vt596_adapter.name, sizeof(vt596_adapter.name), "SMBus Via Pro adapter at %04x", vt596_smba);
/* Always return failure here. This is to allow other drivers to bind * to this pci device. We don't really want to have control over the * pci device, we only wanted to read as few register values from it.
*/ return -ENODEV;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.