How did you know that the nForce was compatible with the amd756? How much testing have you done (what chips are on the bus - what drivers are you using)? i2cdetect and i2cdump work? Csaba Hal?sz wrote: > > Hi! > > I have modified the amd756 driver to support the nVidia nForce SMBus > controller. > > There is of course no technical documentation (this is an nVidia product > after all :-), so this is just guesswork. > > The base address is hardwired at 0x5500, because the original code does not > work, and reverse engineering the windows software shows that they have > hardcoded it as well. > > It might be a good idea to change the amdsetup member in the sd struct to be > a pointer to a device specific setup function, so that it will be easier to > add new devices later on. > > I have just made up a device id, I don't know the proper way to do it. > > I hope that the code still works with the true amd chips. > I have only tested it on a single computer, so I have no idea whether it > will function properly for others. > > Greets, > Csaba Halasz > hcs at ics2.ics.tvnet.hu > jester01 at freemail.hu (use if above does not work) > > diff -u -r -N lm_sensors2.orig/kernel/busses/i2c-amd756.c > lm_sensors2/kernel/busses/i2c-amd756.c > --- lm_sensors2.orig/kernel/busses/i2c-amd756.c Sat Dec 29 01:20:47 2001 > +++ lm_sensors2/kernel/busses/i2c-amd756.c Thu Apr 25 03:23:11 2002 > @@ -25,7 +25,11 @@ > */ > > /* > - Supports AMD756, AMD766, and AMD768. > + 2002-04-08: Added nForce support. (Csaba Halasz) > +*/ > + > +/* > + Supports AMD756, AMD766, AMD768 and nVidia nForce > Note: we assume there can only be one device, with one SMBus interface. > */ > > @@ -51,11 +55,31 @@ > #ifndef PCI_DEVICE_ID_AMD_766 > #define PCI_DEVICE_ID_AMD_766 0x7413 > #endif > +#ifndef PCI_DEVICE_ID_AMD_768 > +#define PCI_DEVICE_ID_AMD_768 0x7443 > +#endif > +#ifndef PCI_VENDOR_ID_NVIDIA > +#define PCI_VENDOR_ID_NVIDIA 0x10DE > +#endif > +#ifndef PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS > +#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01B4 > +#endif > + > +struct sd { > + const unsigned short vendor; > + const unsigned short device; > + const unsigned short function; > + const char* name; > + int amdsetup:1; > +}; > > -static int supported[] = {PCI_DEVICE_ID_AMD_756, > - PCI_DEVICE_ID_AMD_766, > - 0x7443, /* AMD768 */ > - 0 }; > +static struct sd supported[] = { > + {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_756, 3, "AMD756", 1}, > + {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_766, 3, "AMD766", 1}, > + {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_768, 3, "AMD768", 1}, > + {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS, 1, "nVidia > nForce", 0}, > + {0, 0, 0} > +}; > > /* AMD756 SMBus address offsets */ > #define SMB_ADDR_OFFSET 0xE0 > @@ -149,7 +173,7 @@ > int amd756_setup(void) > { > unsigned char temp; > - int *num = supported; > + struct sd *currdev; > struct pci_dev *AMD756_dev = NULL; > > if (pci_present() == 0) { > @@ -157,38 +181,41 @@ > return(-ENODEV); > } > > - /* Look for the AMD756, function 3 */ > - /* Note: we keep on searching until we have found 'function 3' */ > - do { > - if((AMD756_dev = pci_find_device(PCI_VENDOR_ID_AMD, > - *num, AMD756_dev))) { > - if(PCI_FUNC(AMD756_dev->devfn) != 3) > - continue; > - break; > + /* Look for a supported chip */ > + for(currdev = supported; currdev->vendor; ) { > + AMD756_dev = pci_find_device(currdev->vendor, > + currdev->device, AMD756_dev); > + if (AMD756_dev != NULL) { > + if (PCI_FUNC(AMD756_dev->devfn) == currdev->function) > + break; > + } else { > + currdev++; > } > - num++; > - } while (*num != 0); > + } > > if (AMD756_dev == NULL) { > printk > - ("i2c-amd756.o: Error: Can't detect AMD756, function 3!\n"); > + ("i2c-amd756.o: Error: No AMD756 or compatible device detected!\n"); > return(-ENODEV); > } > - > - > - pci_read_config_byte(AMD756_dev, SMBGCFG, &temp); > - if ((temp & 128) == 0) { > - printk > - ("i2c-amd756.o: Error: SMBus controller I/O not enabled!\n"); > + printk(KERN_INFO "i2c-amd756.o: Found %s SMBus controller.\n", > currdev->name); > + > + if (currdev->amdsetup) > + { > + pci_read_config_byte(AMD756_dev, SMBGCFG, &temp); > + if ((temp & 128) == 0) { > + printk("i2c-amd756.o: Error: SMBus controller I/O not enabled!\n"); > + } > return(-ENODEV); > - } > - > - /* Determine the address of the SMBus areas */ > - /* Technically it is a dword but... */ > - pci_read_config_word(AMD756_dev, SMBBA, &amd756_smba); > - amd756_smba &= 0xff00; > - amd756_smba += SMB_ADDR_OFFSET; > > + /* Determine the address of the SMBus areas */ > + /* Technically it is a dword but... */ > + pci_read_config_word(AMD756_dev, SMBBA, &amd756_smba); > + amd756_smba &= 0xff00; > + amd756_smba += SMB_ADDR_OFFSET; > + } else { > + amd756_smba = 0x5500; > + } > if (check_region(amd756_smba, SMB_IOSIZE)) { > printk > ("i2c-amd756.o: SMB region 0x%x already in use!\n", > diff -u -r -N lm_sensors2.orig/prog/detect/sensors-detect > lm_sensors2/prog/detect/sensors-detect > --- lm_sensors2.orig/prog/detect/sensors-detect Tue Apr 2 04:08:56 2002 > +++ lm_sensors2/prog/detect/sensors-detect Thu Apr 25 03:23:11 2002 > @@ -514,7 +514,8 @@ > devid => 0x01b4, > func => 1, > procid => "nVidia nForce SMBus", > - match => sub { $_[0] =~ /dontmatchthis/ }, > + driver => "i2c-amd756", > + match => sub { $_[0] =~ /^SMBus AMD7X6 adapter at [0-9,a-f]{4}/ }, > } , > { > vendid => 0x1166,