Fixed the typo in sis630_access (Thanks to Mark M. Hoffman)
Changed sis630_transaction.(Thanks to Mark M. Hoffman)
18.09.2002
- Added SIS730 as supported
+ Added SIS730 as supported.
21.09.2002
Added high_clock module option.If this option is set
- used Host Master Clock 56KHz (default 14KHz).For now we are save old Host
+ used Host Master Clock 56KHz (default 14KHz).For now we save old Host
Master Clock and after transaction completed restore (otherwise
it's confuse BIOS and hung Machine).
24.09.2002
/* insmod parameters */
static int high_clock = 0;
+static int force = 0;
MODULE_PARM(high_clock, "i");
MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
+MODULE_PARM(force, "i");
+MODULE_PARM_DESC(force, "Forcibly enable the SIS630. DANGEROUS!");
-
+/* acpi base address */
static unsigned short acpi_base = 0;
+/* supported chips */
+static int supported[] = {
+ PCI_DEVICE_ID_SI_630,
+ PCI_DEVICE_ID_SI_730,
+ 0 /* terminates the list */
+};
+
static inline u8 sis630_read(u8 reg)
{
return inb(acpi_base + reg);
if (len == 0)
data->block[0] = sis630_read(SMB_COUNT);
+ /* just to be sure */
+ if (data->block[0] > 32)
+ data->block[0] = 32;
+
dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]);
for (i=0; i < 8 && len < data->block[0]; i++,len++) {
I2C_FUNC_SMBUS_BLOCK_DATA;
}
-static int sis630_setup(struct pci_dev *dummy)
+static int sis630_setup(struct pci_dev *sis630_dev)
{
unsigned char b;
- struct pci_dev *sis630_dev = NULL;
- int retval = -ENODEV;
+ struct pci_dev *dummy = NULL;
+ int retval = -ENODEV, i;
+
+ /* check for supported SiS devices */
+ for (i=0; supported[i] > 0 ; i++) {
+ if ((dummy = pci_get_device(PCI_VENDOR_ID_SI, supported[i], dummy)))
+ break; /* found */
+ }
- /* We need ISA bridge and not pci device passed in. */
- sis630_dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis630_dev);
- if (!sis630_dev) {
- dev_err(&dummy->dev, "Error: Can't detect 85C503/5513 ISA bridge!\n");
+ if (dummy) {
+ pci_dev_put(dummy);
+ }
+ else if (force > 0) {
+ dev_err(&sis630_dev->dev, "WARNING: Can't detect SIS630 compatible device, but "
+ "loading because of force option enabled\n");
+ }
+ else {
return -ENODEV;
}
Enable ACPI first , so we can accsess reg 74-75
in acpi io space and read acpi base addr
*/
- if (!pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
+ if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
goto exit;
}
-
/* if ACPI already enabled , do nothing */
if (!(b & 0x80) &&
- !pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
+ pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
goto exit;
}
+
/* Determine the ACPI base address */
- if (!pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
+ if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
goto exit;
}
retval = 0;
exit:
- pci_dev_put(sis630_dev);
+ if (retval)
+ acpi_base = 0;
return retval;
}
static struct i2c_adapter sis630_adapter = {
.owner = THIS_MODULE,
+ .class = I2C_ADAP_CLASS_SMBUS,
.name = "unset",
.algo = &smbus_algorithm,
};
static struct pci_device_id sis630_ids[] __devinitdata = {
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630) },
- { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_730) },
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
{ 0, }
};
static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
-
if (sis630_setup(dev)) {
dev_err(&dev->dev, "SIS630 comp. bus not detected, module not inserted.\n");
return -ENODEV;
static void __devexit sis630_remove(struct pci_dev *dev)
{
- i2c_del_adapter(&sis630_adapter);
+ if (acpi_base) {
+ i2c_del_adapter(&sis630_adapter);
+ release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
+ acpi_base = 0;
+ }
}
static void __exit i2c_sis630_exit(void)
{
pci_unregister_driver(&sis630_driver);
- release_region(acpi_base + SMB_STS, SIS630_SMB_IOREGION);
}