diff --git a/CHANGES b/CHANGES
index d80b4f36..b5e1c5ba 100644
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,60 @@ lm_sensors CHANGES file
-----------------------
SVN HEAD
+ File sensors.conf.eg: Add a dme1737 section
+ Library: Clean up pwm symbol names translation
+ Add dme1737 support
+ Program isadump: Detect when address bit 7 is a busy flag
+ Program sensors: Drop ddcmon and eeprom support
+ Add dme1737 support
+ Program sensors-detect: Stop Super-I/O probe after first family success
+ Fix SMSC DME1737 detection
+
+
+2.10.3 (20070319)
+ Library: Do not skip i2c adapters with only a class device and no
+ physical device. This change is required to survive the
+ planned struct class_dev removal from future 2.6 kernels.
+ Add support for the SMSC LPC47M292 fans (prefix smsc47m2)
+ Recognize i2c-isa-based devices as such even after class_dev
+ is gone
+ Compile with -D_REENTRANT
+ Fix support of Linux 2.6's max6650 driver
+ Fix max1619 support
+ Man page i2cdetect.8: Scanning range can be restricted
+ Module bmcsensors: Fix debugging messages
+ Module i2c-ali1563: Improve the status messages (2.6 backport)
+ Fix device initialization (2.6 backport)
+ Module i2c-amd8111: Cleanups (2.6 backport)
+ Fix initialization race (2.6 backport)
+ Module i2c-nforce2: Drop unused reference to pci_dev (2.6 backport)
+ Module i2c-piix4: Add ATI SB600 support (2.6 backport)
+ Module i2c-viapro: Add CX700 support (2.6 backport)
+ Module smsc47m1: Add SMSC LPC47M292 support
+ Get rid of a useless semaphore (2.6 backport)
+ Programs i2cdetect, i2cdump, isadump: Flush output in real time
+ Program i2cdump: Cleaner output in SMBus block read mode
+ Program fancontrol.pl: Fix pwmN_enable access (#2190)
+ Program sensors: Add smsc47m2 support (fans)
+ Fix -A option (hide adapter name) on error
+ Program sensors-detect: Only probe relevant I2C addresses
+ Drop ARP-capable device detection
+ Add Maxim MAX6655/MAX6656 detection
+ (Olexiy Avramchenko)
+ Add Maxim MAX1668, MAX1805, MAX1989 detection
+ Add VIA CX700 detection
+ Drop legacy W83627HF ISA detection
+ Don't bufferize stdout during probes
+ Speed up the LM75 and LM77 detection
+ Clean up the EEPROM detection
+ Add Dallas DS75 detection
+ Add SMSC LPC47M292 detection
+ Add nVidia MCP61 and MCP65 detection
+ Fix ADM1028 detection
+ Add Nat. Semi. PC8347L Super-I/O detection
+ Add SMSC SCH5504 Super-I/O detection (no sensors)
+ Make the LM78 and W83781D detection safer
+
2.10.2 (20070115)
RPM: Obsolete, removed
diff --git a/Makefile b/Makefile
index 66ee504d..65665e9d 100644
--- a/Makefile
+++ b/Makefile
@@ -279,7 +279,7 @@ LIBCPPFLAGS := $(ALL_CPPFLAGS)
ifdef SYSFS_SUPPORT
LIBCPPFLAGS := $(LIBCPPFLAGS) -DSYSFS_SUPPORT
endif
-LIBCFLAGS := -fpic $(ALL_CFLAGS)
+LIBCFLAGS := -fpic -D_REENTRANT $(ALL_CFLAGS)
.PHONY: all user clean install user_install uninstall user_uninstall version package
diff --git a/README b/README
index 7d7c262f..c8fc488b 100644
--- a/README
+++ b/README
@@ -47,7 +47,7 @@ At least the following I2C/SMBus adapters are supported:
AMD 756, 766, 768 and 8111
AMD 8111 SMBus 2.0
Apple Hydra (used on some PPC machines)
- ATI IXP200, IXP300, IXP400
+ ATI IXP200, IXP300, IXP400, SB600
DEC 21272/21274 (Tsunami/Typhoon - on Alpha boards)
Intel ICH/ICH0/ICH2/ICH3/ICH4/ICH5/ICH6/ICH7/ICH8/ICH9 (82801xx)
Intel 6300ESB, 631xESB/632xESB (ESB2)
@@ -60,7 +60,7 @@ At least the following I2C/SMBus adapters are supported:
SMSC Victory66
3Dfx Voodoo 3 and Banshee
VIA Technologies VT82C586B, VT82C596A/B, VT82C686A/B, VT8231,
- VT8233, VT8233A, VT8235, VT8237R/A and VT8251
+ VT8233, VT8233A, VT8235, VT8237R/A, VT8251, CX700
At least the following hardware sensor chips are supported:
diff --git a/doc/busses/i2c-piix4 b/doc/busses/i2c-piix4
index bf3e29ff..d7cce66e 100644
--- a/doc/busses/i2c-piix4
+++ b/doc/busses/i2c-piix4
@@ -9,7 +9,7 @@ Supported adapters:
Datasheet: Publicly available at the Intel website
* ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
Datasheet: Only available via NDA from ServerWorks
- * ATI IXP southbridges IXP200, IXP300, IXP400
+ * ATI IXP200, IXP300, IXP400 and SB600 southbridges
Datasheet: Not publicly available
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com
diff --git a/doc/busses/i2c-viapro b/doc/busses/i2c-viapro
index f3491804..375d305d 100644
--- a/doc/busses/i2c-viapro
+++ b/doc/busses/i2c-viapro
@@ -10,7 +10,10 @@ Supported adapters:
Datasheet: Sometimes available at the VIA website
* VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R/A, VT8251
- Datasheet: available on request from Via
+ Datasheet: available on request and under NDA from VIA
+
+ * VIA Technologies, Inc. CX700
+ Datasheet: available on request and under NDA from VIA
Authors:
Kyösti Mälkki
@@ -45,6 +48,7 @@ Your /proc/pci or lspci -n listing must show one of these :
device 1106:3227 (VT8237R)
device 1106:3337 (VT8237A)
device 1106:3287 (VT8251)
+ device 1106:8324 (CX700)
If none of these show up, you should look in the BIOS for settings like
enable ACPI / SMBus or even USB.
@@ -52,3 +56,6 @@ enable ACPI / SMBus or even USB.
Except for the oldest chips (VT82C596A/B, VT82C686A and most probably
VT8231), this driver supports I2C block transactions. Such transactions
are mainly useful to read from and write to EEPROMs.
+
+The CX700 additionally appears to support SMBus PEC, although this driver
+doesn't implement it.
diff --git a/doc/chips/SUMMARY b/doc/chips/SUMMARY
index cc05196e..ca5afe4e 100644
--- a/doc/chips/SUMMARY
+++ b/doc/chips/SUMMARY
@@ -220,6 +220,8 @@ smsc47m1
smsc47m15x - - 2 2 no yes (LPC)
smsc47m192 - - 2 2 no yes (LPC)
smsc47m997 - - 2 2 no yes (LPC)
+ (reported as a "smsc47m2")
+ smsc47m292 - - 3 3 no yes (LPC)
thmc50
adm1022 3 2 - 1 dac yes no
diff --git a/doc/chips/lm90 b/doc/chips/lm90
index ffa58cc5..75a174aa 100644
--- a/doc/chips/lm90
+++ b/doc/chips/lm90
@@ -176,7 +176,7 @@ SMBus Read Byte, and PEC will work properly.
Additionally, the ADM1032 doesn't support SMBus Send Byte with PEC.
Instead, it will try to write the PEC value to the register (because the
SMBus Send Byte transaction with PEC is similar to a Write Byte transaction
-without PEC), which is not what we want. Thus, PEC is explicitely disabled
+without PEC), which is not what we want. Thus, PEC is explicitly disabled
on SMBus Send Byte transactions in the lm90 driver.
PEC on byte data transactions represents a significant increase in bandwidth
diff --git a/doc/chips/max6650 b/doc/chips/max6650
index a2564021..bbd63d6c 100644
--- a/doc/chips/max6650
+++ b/doc/chips/max6650
@@ -4,7 +4,7 @@ Sensors chip driver for MAXIM MAX6650 / MAX6651 fan controllers
Chip notes
----------
-The MAX6551 is a fan controller. It has two distinct functions:
+The MAX6651 is a fan controller. It has two distinct functions:
1) Speed control, with feedback, for a single fan. The code can write
to a register requesting that the fan run at a certain speed, and the
@@ -14,7 +14,7 @@ The MAX6551 is a fan controller. It has two distinct functions:
2) Speed measurement (tachometers) for up to four fans, including the
controlled one.
-The MAX6550 is similar but only has one measurement tachometer.
+The MAX6650 is similar but only has one measurement tachometer.
Both chips have a few general purpose i/o pins, some of which can be
configured to have special functions. At the time of writing an overview
@@ -22,7 +22,7 @@ of the chip, with links to the datasheet, can be seen at:
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2296/ln/en
-If that has moved searching for MAX6550 from Maxim's home page should
+If that has moved searching for MAX6650 from Maxim's home page should
work.
Driver state
@@ -79,9 +79,9 @@ Bugs
configuration dynamically instead of assuming that some other code has
done it.
- o It does not differentiate between a MAX6550 and a MAX6551, as I can
- see no obvious way to do this. It has only been tested with a MAX6551
- so if anyone gets a board with a MAX6550 to test with maybe something
+ o It does not differentiate between a MAX6650 and a MAX6651, as I can
+ see no obvious way to do this. It has only been tested with a MAX6651
+ so if anyone gets a board with a MAX6650 to test with maybe something
will be revealed, such as the three missing tachometer registers
returning all ones or something. (OK, so maybe I should have called
this driver max6651, and ignored the max6650 totally...)
@@ -96,13 +96,13 @@ The module will autodetect the presence of a max6650 or max6651 at any
of the four possible I2C addresses for these devices. There is no ID
register, but there are several registers with all zero bits at the
high end. The driver checks that all of these are in fact zero before
-declaring the chip to be a MAX6550/1.
+declaring the chip to be a MAX6650/1.
sensors-detect
--------------
Support for MAX6650/1 has been added to sensors-detect. It has been
-tested as correctly detecting a MAX6551 at I2C address 0x1B. Like the
+tested as correctly detecting a MAX6651 at I2C address 0x1B. Like the
driver, it cannot yet distinguish a MAX6650 and MAX6651.
prog/sensors
diff --git a/doc/chips/smsc47m1 b/doc/chips/smsc47m1
index 0863e57c..6c1c35ae 100644
--- a/doc/chips/smsc47m1
+++ b/doc/chips/smsc47m1
@@ -16,6 +16,10 @@ Supported chips:
http://www.smsc.com/main/datasheets/47m14x.pdf
http://www.smsc.com/main/tools/discontinued/47m15x.pdf
http://www.smsc.com/main/datasheets/47m192.pdf
+ * SMSC LPC47M292
+ Prefix: 'smsc47m2'
+ Addresses scanned: none, address read from Super I/O config space
+ Datasheet: Not public
* SMSC LPC47M997
Addresses scanned: none, address read from Super I/O config space
Prefix: 'smsc47m1'
@@ -41,9 +45,9 @@ Description
The Standard Microsystems Corporation (SMSC) 47M1xx Super I/O chips
contain monitoring and PWM control circuitry for two fans.
-The 47M15x and 47M192 chips contain a full 'hardware monitoring block'
-in addition to the fan monitoring and control. The hardware monitoring
-block is not supported by the driver.
+The LPC47M15x, LPC47M192 and LPC47M292 chips contain a full 'hardware
+monitoring block' in addition to the fan monitoring and control. The
+hardware monitoring block is not supported by the driver.
No documentation is available for the 47M997, but it has the same device
ID as the 47M15x and 47M192 chips and seems to be compatible therewith.
diff --git a/doc/useful_addresses.html b/doc/useful_addresses.html
index 2bd20574..073ea0a1 100644
--- a/doc/useful_addresses.html
+++ b/doc/useful_addresses.html
@@ -156,8 +156,11 @@ implementations. Please report any other references you have found!
As far we know only one motherboard manufacturer provides sensors.conf files:
Personal collections:
diff --git a/etc/sensors.conf.eg b/etc/sensors.conf.eg
index a958989b..ff89cfd7 100644
--- a/etc/sensors.conf.eg
+++ b/etc/sensors.conf.eg
@@ -2813,3 +2813,70 @@ chip "k8temp-*"
label temp2 "Core0 Temp"
label temp3 "Core1 Temp"
label temp4 "Core1 Temp"
+
+
+#
+# Sample configuration for the SMSC DME1737 and ASUS A8000
+#
+chip "dme1737-*"
+
+# Voltage inputs
+ label in0 "V5stby"
+ label in1 "Vccp"
+ label in2 "V3.3"
+ label in3 "V5"
+ label in4 "V12"
+ label in5 "V3.3stby"
+ label in6 "Vbat"
+
+# Temperature inputs
+ label temp1 "RD1 Temp"
+ label temp2 "Int Temp"
+ label temp3 "CPU Temp"
+
+# Fan inputs
+ label fan1 "CPU_Fan"
+ label fan2 "Fan2"
+ label fan3 "Fan3"
+ label fan4 "Fan4"
+ label fan5 "Fan5"
+ label fan6 "Fan6"
+
+# PWM Outputs
+ label pwm1 "CPU_PWM"
+ label pwm2 "Fan2_PWM"
+ label pwm3 "Fan3_PWM"
+ label pwm5 "Fan5_PWM"
+ label pwm6 "Fan6_PWM"
+
+# Set voltage limits
+# set in0_min 5.0 * 0.95
+# set in0_max 5.0 * 1.05
+# set in1_min 1.4 * 0.95
+# set in1_max 1.4 * 1.05
+# set in2_min 3.3 * 0.95
+# set in2_max 3.3 * 1.05
+# set in3_min 5.0 * 0.95
+# set in3_max 5.0 * 1.05
+# set in4_min 12.0 * 0.95
+# set in4_max 12.0 * 1.05
+# set in5_min 3.3 * 0.95
+# set in5_max 3.3 * 1.05
+# set in6_min 3.0 * 0.95
+# set in6_max 3.0 * 1.05
+
+# Set Temp Limits
+# set temp1_min 10
+# set temp1_max 75
+# set temp2_min 10
+# set temp2_max 75
+# set temp3_min 10
+# set temp3_max 75
+
+# Set Fan limits
+# set fan1_min 1000
+# set fan2_min 1000
+# set fan3_min 1000
+# set fan4_min 1000
+# set fan5_min 1000
+# set fan6_min 1000
diff --git a/kernel/busses/i2c-ali1563.c b/kernel/busses/i2c-ali1563.c
index 50bb9c9a..87cc2d2c 100644
--- a/kernel/busses/i2c-ali1563.c
+++ b/kernel/busses/i2c-ali1563.c
@@ -326,35 +326,11 @@ static u32 ali1563_func(struct i2c_adapter * a)
}
-static void ali1563_enable(struct pci_dev * dev)
-{
- u16 ctrl;
-
- pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
- ctrl |= 0x7;
- pci_write_config_word(dev,ALI1563_SMBBA,ctrl);
-}
-
static int __devinit ali1563_setup(struct pci_dev * dev)
{
u16 ctrl;
pci_read_config_word(dev,ALI1563_SMBBA,&ctrl);
- printk(KERN_DEBUG "ali1563: SMBus control = %04x\n",ctrl);
-
- /* Check if device is even enabled first */
- if (!(ctrl & ALI1563_SMB_IOEN)) {
- printk(KERN_WARNING "ali1563: I/O space not enabled, trying manually\n");
- ali1563_enable(dev);
- }
- if (!(ctrl & ALI1563_SMB_IOEN)) {
- printk(KERN_WARNING "ali1563: I/O space still not enabled, giving up\n");
- goto Err;
- }
- if (!(ctrl & ALI1563_SMB_HOSTEN)) {
- printk(KERN_WARNING "ali1563: Host Controller not enabled\n");
- goto Err;
- }
/* SMB I/O Base in high 12 bits and must be aligned with the
* size of the I/O space. */
@@ -363,11 +339,32 @@ static int __devinit ali1563_setup(struct pci_dev * dev)
printk(KERN_WARNING "ali1563: ali1563_smba Uninitialized\n");
goto Err;
}
- if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
- ali1563_pci_driver.name)) {
- printk(KERN_WARNING "ali1563: Could not allocate I/O space");
+
+ /* Check if device is enabled */
+ if (!(ctrl & ALI1563_SMB_HOSTEN)) {
+ printk(KERN_WARNING "ali1563: Host Controller not enabled\n");
goto Err;
}
+ if (!(ctrl & ALI1563_SMB_IOEN)) {
+ printk(KERN_WARNING "I/O space not enabled, trying manually\n");
+ pci_write_config_word(dev, ALI1563_SMBBA,
+ ctrl | ALI1563_SMB_IOEN);
+ pci_read_config_word(dev, ALI1563_SMBBA, &ctrl);
+ if (!(ctrl & ALI1563_SMB_IOEN)) {
+ printk(KERN_WARNING "I/O space still not enabled, "
+ "giving up\n");
+ goto Err;
+ }
+ }
+
+ if (!request_region(ali1563_smba, ALI1563_SMB_IOSIZE,
+ ali1563_pci_driver.name)) {
+ printk(KERN_WARNING "ali1563: Could not allocate I/O space "
+ "at 0x%04x\n", ali1563_smba);
+ goto Err;
+ }
+ printk(KERN_INFO "ali1563: Found ALi1563 SMBus at 0x%04x\n",
+ ali1563_smba);
return 0;
Err:
@@ -411,14 +408,15 @@ static int __devinit ali1563_probe(struct pci_dev * dev,
{
int error;
- if ((error = ali1563_setup(dev))){
+ if ((error = ali1563_setup(dev))) {
+ printk(KERN_WARNING "ali1563: ALi1563 SMBus probe failed "
+ "(%d)\n", error);
return error;
}
sprintf(ali1563_adapter.name,"SMBus ALi 1563 Adapter @ %04x",
ali1563_smba);
if ((error = i2c_add_adapter(&ali1563_adapter)))
ali1563_shutdown(dev);
- printk(KERN_DEBUG "%s: Returning %d\n",__FUNCTION__,error);
return error;
}
diff --git a/kernel/busses/i2c-amd8111.c b/kernel/busses/i2c-amd8111.c
index 50517ec7..a6bc973a 100644
--- a/kernel/busses/i2c-amd8111.c
+++ b/kernel/busses/i2c-amd8111.c
@@ -215,7 +215,7 @@ s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
case I2C_SMBUS_WORD_DATA:
amd_ec_write(smbus, AMD_SMB_CMD, command);
if (read_write == I2C_SMBUS_WRITE) {
- amd_ec_write(smbus, AMD_SMB_DATA, data->word);
+ amd_ec_write(smbus, AMD_SMB_DATA, data->word & 0xff);
amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
}
protocol |= AMD_SMB_PRTCL_WORD_DATA | pec;
@@ -224,7 +224,7 @@ s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
case I2C_SMBUS_BLOCK_DATA:
amd_ec_write(smbus, AMD_SMB_CMD, command);
if (read_write == I2C_SMBUS_WRITE) {
- len = min_t(u8, data->block[0], 32);
+ len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
amd_ec_write(smbus, AMD_SMB_BCNT, len);
for (i = 0; i < len; i++)
amd_ec_write(smbus, AMD_SMB_DATA + i, data->block[i + 1]);
@@ -233,7 +233,7 @@ s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
- len = min_t(u8, data->block[0], 32);
+ len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
amd_ec_write(smbus, AMD_SMB_CMD, command);
amd_ec_write(smbus, AMD_SMB_BCNT, len);
if (read_write == I2C_SMBUS_WRITE)
@@ -244,14 +244,14 @@ s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
case I2C_SMBUS_PROC_CALL:
amd_ec_write(smbus, AMD_SMB_CMD, command);
- amd_ec_write(smbus, AMD_SMB_DATA, data->word);
+ amd_ec_write(smbus, AMD_SMB_DATA, data->word & 0xff);
amd_ec_write(smbus, AMD_SMB_DATA + 1, data->word >> 8);
protocol = AMD_SMB_PRTCL_PROC_CALL | pec;
read_write = I2C_SMBUS_READ;
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
- len = min_t(u8, data->block[0], 31);
+ len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX - 1);
amd_ec_write(smbus, AMD_SMB_CMD, command);
amd_ec_write(smbus, AMD_SMB_BCNT, len);
for (i = 0; i < len; i++)
@@ -303,7 +303,7 @@ s32 amd8111_access(struct i2c_adapter * adap, u16 addr, unsigned short flags,
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_BLOCK_PROC_CALL:
amd_ec_read(smbus, AMD_SMB_BCNT, &len);
- len = min_t(u8, len, 32);
+ len = min_t(u8, len, I2C_SMBUS_BLOCK_MAX);
case I2C_SMBUS_I2C_BLOCK_DATA:
for (i = 0; i < len; i++)
amd_ec_read(smbus, AMD_SMB_DATA + i, data->block + i + 1);
@@ -354,11 +354,11 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
struct amd_smbus *smbus;
int error;
- if (~pci_resource_flags(dev, 0) & IORESOURCE_IO)
- return -1;
+ if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO))
+ return -ENODEV;
if (!(smbus = kmalloc(sizeof(struct amd_smbus), GFP_KERNEL)))
- return -1;
+ return -ENOMEM;
memset(smbus, 0, sizeof(struct amd_smbus));
pci_set_drvdata(dev, smbus);
@@ -368,7 +368,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
kfree(smbus);
- return -1;
+ return -EBUSY;
}
sprintf(smbus->adapter.name, "SMBus2 AMD8111 adapter at %04x", smbus->base);
@@ -378,16 +378,16 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_
smbus->adapter.inc_use = amd8111_inc;
smbus->adapter.dec_use = amd8111_dec;
+ pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
+
error = i2c_add_adapter(&smbus->adapter);
if (error) {
printk(KERN_WARNING "i2c-amd8111.c: Failed to register adapter.\n");
release_region(smbus->base, smbus->size);
kfree(smbus);
- return -1;
+ return error;
}
- pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0);
-
printk(KERN_INFO "i2c-amd8111.c: AMD8111 SMBus 2.0 adapter at %#x\n", smbus->base);
return 0;
}
diff --git a/kernel/busses/i2c-nforce2.c b/kernel/busses/i2c-nforce2.c
index 4f976fba..b8ed6cf0 100644
--- a/kernel/busses/i2c-nforce2.c
+++ b/kernel/busses/i2c-nforce2.c
@@ -82,7 +82,6 @@ MODULE_DESCRIPTION("nForce2 SMBus driver");
struct nforce2_smbus {
- struct pci_dev *dev;
struct i2c_adapter adapter;
int base;
int size;
@@ -336,7 +335,6 @@ static int __devinit nforce2_probe_smb(struct pci_dev *dev, int bar,
smbus->base = iobase & PCI_BASE_ADDRESS_IO_MASK;
smbus->size = 8;
}
- smbus->dev = dev;
if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
printk (KERN_ERR "i2c-nforce2.o: Error requesting region %02x .. %02X for %s\n", smbus->base, smbus->base+smbus->size-1, name);
diff --git a/kernel/busses/i2c-piix4.c b/kernel/busses/i2c-piix4.c
index 90309ffa..94a4c301 100644
--- a/kernel/busses/i2c-piix4.c
+++ b/kernel/busses/i2c-piix4.c
@@ -23,7 +23,7 @@
Supports:
Intel PIIX4, 440MX
Serverworks OSB4, CSB5, CSB6, HT-1000
- ATI IXP200, IXP300, IXP400
+ ATI IXP200, IXP300, IXP400, SB600
SMSC Victory66
Note: we assume there can only be one device, with one SMBus interface.
@@ -438,6 +438,7 @@ static struct i2c_adapter piix4_adapter = {
#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353
#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363
#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372
+#define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
#ifndef PCI_DEVICE_ID_SERVERWORKS_CSB6
#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203
@@ -474,6 +475,13 @@ static struct pci_device_id piix4_ids[] __devinitdata = {
.subdevice = PCI_ANY_ID,
.driver_data = 0,
},
+ {
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_IXP600_SMBUS,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = 0,
+ },
{
.vendor = PCI_VENDOR_ID_SERVERWORKS,
.device = PCI_DEVICE_ID_SERVERWORKS_OSB4,
diff --git a/kernel/busses/i2c-viapro.c b/kernel/busses/i2c-viapro.c
index ac0536b7..3a6d70f2 100644
--- a/kernel/busses/i2c-viapro.c
+++ b/kernel/busses/i2c-viapro.c
@@ -4,7 +4,7 @@
Copyright (c) 1998 - 2002 Frodo Looijaard ,
Philip Edelbrock , Kyösti Mälkki ,
Mark D. Studebaker
- Copyright (C) 2005 Jean Delvare
+ Copyright (C) 2005 - 2007 Jean Delvare
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
VT8237R 0x3227 yes
VT8237A 0x3337 yes
VT8251 0x3287 yes
+ CX700 0x8324 yes
Note: we assume there can only be one device, with one SMBus interface.
*/
@@ -63,14 +64,18 @@
#ifndef PCI_DEVICE_ID_VIA_8237
#define PCI_DEVICE_ID_VIA_8237 0x3227
#endif
-/* 8237A is undefined as for the kernel 2.4.33 */
+/* 8237A is undefined */
#ifndef PCI_DEVICE_ID_VIA_8237A
#define PCI_DEVICE_ID_VIA_8237A 0x3337
#endif
-/* 8251 is undefined as for the kernel 2.4.33 */
+/* 8251 is undefined */
#ifndef PCI_DEVICE_ID_VIA_8251
#define PCI_DEVICE_ID_VIA_8251 0x3287
#endif
+/* CX700 is undefined */
+#ifndef PCI_DEVICE_ID_VIA_CX700
+#define PCI_DEVICE_ID_VIA_CX700 0x8324
+#endif
#define SMBBA1 0x90
#define SMBBA2 0x80
@@ -418,6 +423,7 @@ found:
dev_dbg(pdev, "VT596_smba = 0x%X\n", vt596_smba);
switch (id->device) {
+ case PCI_DEVICE_ID_VIA_CX700:
case PCI_DEVICE_ID_VIA_8251:
case PCI_DEVICE_ID_VIA_8237:
case PCI_DEVICE_ID_VIA_8237A:
@@ -516,6 +522,13 @@ static struct pci_device_id vt596_ids[] __initdata = {
.subdevice = PCI_ANY_ID,
.driver_data = SMBBA3
},
+ {
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_CX700,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .driver_data = SMBBA3
+ },
{ 0, }
};
diff --git a/kernel/chips/adm1024.c b/kernel/chips/adm1024.c
index e93ca127..18ff22c7 100644
--- a/kernel/chips/adm1024.c
+++ b/kernel/chips/adm1024.c
@@ -143,8 +143,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
205-(val)*5)
-/* For each registered ADM1024, we need to keep some data in memory. That
- data is pointed to by adm1024_list[NR]->data. The structure itself is
+/* For each registered ADM1024, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new adm1024 client is
allocated. */
struct adm1024_data {
diff --git a/kernel/chips/adm1025.c b/kernel/chips/adm1025.c
index 8a19bfba..22151e12 100644
--- a/kernel/chips/adm1025.c
+++ b/kernel/chips/adm1025.c
@@ -112,8 +112,7 @@ SENSORS_INSMOD_2(adm1025, ne1619);
#define ALARMS_FROM_REG(val) (val)
-/* For each registered ADM1025, we need to keep some data in memory. That
- data is pointed to by adm1025_list[NR]->data. The structure itself is
+/* For each registered ADM1025, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new adm1025 client is
allocated. */
struct adm1025_data {
diff --git a/kernel/chips/adm1026.c b/kernel/chips/adm1026.c
index 27b38e4b..6fd62d29 100644
--- a/kernel/chips/adm1026.c
+++ b/kernel/chips/adm1026.c
@@ -298,7 +298,6 @@ static int adm1026_scaling[] = { /* .001 Volts */
struct adm1026_data {
struct i2c_client client;
- struct semaphore lock;
int sysctl_id;
enum chips type;
diff --git a/kernel/chips/bmcsensors.c b/kernel/chips/bmcsensors.c
index 16b963d7..00077e15 100644
--- a/kernel/chips/bmcsensors.c
+++ b/kernel/chips/bmcsensors.c
@@ -38,7 +38,6 @@
*/
struct bmcsensors_data {
- struct semaphore lock;
int sysctl_id;
struct semaphore update_lock;
@@ -880,7 +879,7 @@ static void bmcsensors_update_client(struct i2c_client *client)
if(state != STATE_READING) {
state = STATE_READING;
#ifdef DEBUG
- printk(KERN_DEBUG "bmcsensors.o: starting update\n", j);
+ printk(KERN_DEBUG "bmcsensors.o: starting update\n");
#endif
bmcsensors_get_reading(client, 0);
}
@@ -888,7 +887,7 @@ static void bmcsensors_update_client(struct i2c_client *client)
while(state == STATE_READING && j++ < 100)
bmc_do_pause(HZ / 25);
#ifdef DEBUG
- printk("bmcsensors.o: update complete; j = %d\n", j);
+ printk(KERN_DEBUG "bmcsensors.o: update complete; j = %d\n", j);
#endif
data->last_updated = jiffies;
data->valid = 1;
diff --git a/kernel/chips/fscher.c b/kernel/chips/fscher.c
index a7b082e0..8fd77ada 100644
--- a/kernel/chips/fscher.c
+++ b/kernel/chips/fscher.c
@@ -103,8 +103,7 @@ SENSORS_INSMOD_1(fscher);
/* Initial limits */
-/* For each registered FSCHER, we need to keep some data in memory. That
- data is pointed to by fscher_list[NR]->data. The structure itself is
+/* For each registered FSCHER, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new fscher client is
allocated. */
struct fscher_data {
diff --git a/kernel/chips/fscpos.c b/kernel/chips/fscpos.c
index 55d20074..0bb4858e 100644
--- a/kernel/chips/fscpos.c
+++ b/kernel/chips/fscpos.c
@@ -107,8 +107,7 @@ SENSORS_INSMOD_1(fscpos);
/* Initial limits */
-/* For each registered FSCPOS, we need to keep some data in memory. That
- data is pointed to by fscpos_list[NR]->data. The structure itself is
+/* For each registered FSCPOS, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new fscpos client is
allocated. */
struct fscpos_data {
diff --git a/kernel/chips/fscscy.c b/kernel/chips/fscscy.c
index 7679f4c3..559a106b 100644
--- a/kernel/chips/fscscy.c
+++ b/kernel/chips/fscscy.c
@@ -151,8 +151,7 @@ SENSORS_INSMOD_1(fscscy);
/* Initial limits */
-/* For each registered FSCSCY, we need to keep some data in memory. That
- data is pointed to by fscscy_list[NR]->data. The structure itself is
+/* For each registered FSCSCY, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new fscscy client is
allocated. */
struct fscscy_data {
diff --git a/kernel/chips/it87.c b/kernel/chips/it87.c
index 88a5a9d8..01286a7e 100644
--- a/kernel/chips/it87.c
+++ b/kernel/chips/it87.c
@@ -215,8 +215,7 @@ extern inline u8 DIV_TO_REG(long val)
}
#define DIV_FROM_REG(val) (1 << (val))
-/* For each registered IT87, we need to keep some data in memory. That
- data is pointed to by it87_list[NR]->data. The structure itself is
+/* For each registered IT87, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new it87 client is
allocated. */
struct it87_data {
diff --git a/kernel/chips/lm78.c b/kernel/chips/lm78.c
index 0b08e973..6598170a 100644
--- a/kernel/chips/lm78.c
+++ b/kernel/chips/lm78.c
@@ -111,8 +111,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
bad. Quite a lot of bookkeeping is done. A real driver can often cut
some corners. */
-/* For each registered LM78, we need to keep some data in memory. That
- data is pointed to by lm78_list[NR]->data. The structure itself is
+/* For each registered LM78, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new lm78 client is
allocated. */
struct lm78_data {
diff --git a/kernel/chips/lm85.c b/kernel/chips/lm85.c
index 15ec9ac9..4f45e892 100644
--- a/kernel/chips/lm85.c
+++ b/kernel/chips/lm85.c
@@ -373,7 +373,6 @@ struct lm85_autofan {
struct lm85_data {
struct i2c_client client;
- struct semaphore lock;
int sysctl_id;
enum chips type;
diff --git a/kernel/chips/lm90.c b/kernel/chips/lm90.c
index c6e4f3c0..9e5e38d1 100644
--- a/kernel/chips/lm90.c
+++ b/kernel/chips/lm90.c
@@ -302,7 +302,7 @@ static ctl_table adm1032_dir_table_template[] =
*/
/* The ADM1032 supports PEC but not on write byte transactions, so we need
- to explicitely ask for a transaction without PEC. */
+ to explicitly ask for a transaction without PEC. */
static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value)
{
return i2c_smbus_xfer(client->adapter, client->addr,
diff --git a/kernel/chips/maxilife.c b/kernel/chips/maxilife.c
index 2b630391..7eab4be5 100644
--- a/kernel/chips/maxilife.c
+++ b/kernel/chips/maxilife.c
@@ -233,8 +233,7 @@ enum maxi_type { cristal, cognac, ashaki, nba };
enum sensor_type { fan, temp, vid, pll, lcd, alarm };
/* For each registered MaxiLife controller, we need to keep some data in
- memory. That data is pointed to by maxi_list[NR]->data. The structure
- itself is dynamically allocated, at the same time when a new MaxiLife
+ memory. It is dynamically allocated, at the same time when a new MaxiLife
client is allocated. We assume MaxiLife will only be present on the
SMBus and not on the ISA bus. */
struct maxi_data {
diff --git a/kernel/chips/mic74.c b/kernel/chips/mic74.c
index 080a38ed..b04a6bbe 100644
--- a/kernel/chips/mic74.c
+++ b/kernel/chips/mic74.c
@@ -54,8 +54,7 @@ SENSORS_INSMOD_1(mic74);
/* Initial values */
/* All registers are 0, except for MIC74_REG_DATA which is 0xFF */
-/* For each registered MIC74, we need to keep some data in memory. That
- data is pointed to by mic74_list[NR]->data. The structure itself is
+/* For each registered MIC74, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new mic74 client is
allocated. */
struct mic74_data {
diff --git a/kernel/chips/sis5595.c b/kernel/chips/sis5595.c
index 20de1540..6c2e58ec 100644
--- a/kernel/chips/sis5595.c
+++ b/kernel/chips/sis5595.c
@@ -161,8 +161,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
#define DIV_FROM_REG(val) (1 << (val))
#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
-/* For the SIS5595, we need to keep some data in memory. That
- data is pointed to by sis5595_list[NR]->data. The structure itself is
+/* For the SIS5595, we need to keep some data in memory. It is
dynamically allocated, at the time when the new sis5595 client is
allocated. */
struct sis5595_data {
diff --git a/kernel/chips/smsc47m1.c b/kernel/chips/smsc47m1.c
index 2e82615e..e464e9c9 100644
--- a/kernel/chips/smsc47m1.c
+++ b/kernel/chips/smsc47m1.c
@@ -38,7 +38,8 @@ static unsigned short normal_i2c_range[] = { SENSORS_I2C_END };
static unsigned int normal_isa[] = { 0x0000, SENSORS_ISA_END };
static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
-SENSORS_INSMOD_1(smsc47m1);
+SENSORS_INSMOD_2(smsc47m1, smsc47m2);
+static u8 devid;
/* modified from kernel/include/traps.c */
#define REG 0x2e /* The register to read/write */
@@ -87,8 +88,13 @@ superio_exit(void)
* can do much more besides (device id 0x60).
* The LPC47M997 is undocumented, but seems to be compatible with
* the LPC47M192, and has the same device id.
+ * The LPC47M292 (device id 0x6B) is somewhat compatible, but it
+ * supports a 3rd fan, and the pin configuration registers are
+ * unfortunately different.
*/
-#define SMSC_DEVID_MATCH(id) ((id) == 0x51 || (id) == 0x59 || (id) == 0x5F || (id) == 0x60)
+#define SMSC_DEVID_MATCH(id) ((id) == 0x51 || (id) == 0x59 || \
+ (id) == 0x5F || (id) == 0x60 || \
+ (id) == 0x6B)
#define SMSC_ACT_REG 0x30
#define SMSC_BASE_REG 0x60
@@ -99,10 +105,17 @@ superio_exit(void)
#define SMSC47M1_REG_TPIN2 0x33
#define SMSC47M1_REG_TPIN1 0x34
#define SMSC47M1_REG_PPIN(nr) (0x37 - (nr))
-#define SMSC47M1_REG_PWM(nr) (0x55 + (nr))
#define SMSC47M1_REG_FANDIV 0x58
-#define SMSC47M1_REG_FAN(nr) (0x58 + (nr))
-#define SMSC47M1_REG_FAN_MIN(nr) (0x5a + (nr))
+
+static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 };
+static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b };
+static const u8 SMSC47M1_REG_FAN_MIN[3] = { 0x5b, 0x5c, 0x6c };
+
+#define SMSC47M2_REG_ALARM6 0x09
+#define SMSC47M2_REG_TPIN3 0x2d
+#define SMSC47M2_REG_TPIN2 0x37
+#define SMSC47M2_REG_TPIN1 0x38
+#define SMSC47M2_REG_FANDIV3 0x6a
static inline u8 MIN_TO_REG(long rpm, int div)
{
@@ -125,18 +138,18 @@ static inline u8 MIN_TO_REG(long rpm, int div)
struct smsc47m1_data {
struct i2c_client client;
- struct semaphore lock;
int sysctl_id;
+ enum chips type;
struct semaphore update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
- u8 fan[2]; /* Register value */
- u8 fan_min[2]; /* Register value */
- u8 fan_div[2]; /* Register encoding, shifted right */
+ u8 fan[3]; /* Register value */
+ u8 fan_min[3]; /* Register value */
+ u8 fan_div[3]; /* Register encoding, shifted right */
u8 alarms; /* Register encoding */
- u8 pwm[2]; /* Register value (bit 0 is disable) */
+ u8 pwm[3]; /* Register value (bit 0 is disable) */
};
@@ -144,10 +157,6 @@ static int smsc47m1_attach_adapter(struct i2c_adapter *adapter);
static int smsc47m1_detect(struct i2c_adapter *adapter, int address,
unsigned short flags, int kind);
static int smsc47m1_detach_client(struct i2c_client *client);
-
-static int smsc47m1_read_value(struct i2c_client *client, u8 register);
-static int smsc47m1_write_value(struct i2c_client *client, u8 register,
- u8 value);
static void smsc47m1_update_client(struct i2c_client *client);
static void smsc47m1_init_client(struct i2c_client *client);
@@ -172,13 +181,16 @@ static struct i2c_driver smsc47m1_driver = {
/* -- SENSORS SYSCTL START -- */
#define SMSC47M1_SYSCTL_FAN1 1101 /* Rotations/min */
#define SMSC47M1_SYSCTL_FAN2 1102
+#define SMSC47M1_SYSCTL_FAN3 1103
#define SMSC47M1_SYSCTL_PWM1 1401
#define SMSC47M1_SYSCTL_PWM2 1402
+#define SMSC47M1_SYSCTL_PWM3 1403
#define SMSC47M1_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */
#define SMSC47M1_SYSCTL_ALARMS 2004 /* bitvector */
#define SMSC47M1_ALARM_FAN1 0x0001
#define SMSC47M1_ALARM_FAN2 0x0002
+#define SMSC47M1_ALARM_FAN3 0x0004
/* -- SENSORS SYSCTL END -- */
@@ -198,6 +210,26 @@ static ctl_table smsc47m1_dir_table_template[] = {
{0}
};
+static ctl_table smsc47m2_dir_table_template[] = {
+ {SMSC47M1_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_fan},
+ {SMSC47M1_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_fan},
+ {SMSC47M1_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_fan},
+ {SMSC47M1_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_fan_div},
+ {SMSC47M1_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_alarms},
+ {SMSC47M1_SYSCTL_PWM1, "pwm1", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_pwm},
+ {SMSC47M1_SYSCTL_PWM2, "pwm2", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_pwm},
+ {SMSC47M1_SYSCTL_PWM3, "pwm3", NULL, 0, 0644, NULL, &i2c_proc_real,
+ &i2c_sysctl_real, NULL, &smsc47m1_pwm},
+ {0}
+};
+
static int smsc47m1_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_detect(adapter, &addr_data, smsc47m1_detect);
@@ -208,8 +240,8 @@ static int __init smsc47m1_find(int *address)
u16 val;
superio_enter();
- val= superio_inb(DEVID);
- if (!SMSC_DEVID_MATCH(val)) {
+ devid = superio_inb(DEVID);
+ if (!SMSC_DEVID_MATCH(devid)) {
superio_exit();
return -ENODEV;
}
@@ -237,8 +269,8 @@ int smsc47m1_detect(struct i2c_adapter *adapter, int address,
struct i2c_client *new_client;
struct smsc47m1_data *data;
int err = 0;
- const char *type_name = "smsc47m1";
- const char *client_name = "47M1xx chip";
+ const char *type_name;
+ const char *client_name;
if (!i2c_is_isa_adapter(adapter)) {
return 0;
@@ -263,9 +295,35 @@ int smsc47m1_detect(struct i2c_adapter *adapter, int address,
return -ENOMEM;
}
+ switch (devid) {
+ case 0x51:
+ kind = smsc47m1;
+ type_name = "smsc47m1";
+ client_name = "LPC47B27x chip";
+ break;
+ case 0x5F:
+ kind = smsc47m1;
+ type_name = "smsc47m1";
+ client_name = "LPC47M14x chip";
+ break;
+ case 0x60:
+ kind = smsc47m1;
+ type_name = "smsc47m1";
+ client_name = "LPC47M192 chip";
+ break;
+ case 0x6B:
+ kind = smsc47m2;
+ type_name = "smsc47m2";
+ client_name = "LPC47M292 chip";
+ break;
+ default:
+ kind = smsc47m1;
+ type_name = "smsc47m1";
+ client_name = "LPC47M1xx chip";
+ }
+
new_client = &data->client;
new_client->addr = address;
- init_MUTEX(&data->lock);
new_client->data = data;
new_client->adapter = adapter;
new_client->driver = &smsc47m1_driver;
@@ -273,6 +331,7 @@ int smsc47m1_detect(struct i2c_adapter *adapter, int address,
request_region(address, SMSC_EXTENT, "smsc47m1-fans");
strcpy(new_client->name, client_name);
+ data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
@@ -281,7 +340,9 @@ int smsc47m1_detect(struct i2c_adapter *adapter, int address,
if ((i = i2c_register_entry((struct i2c_client *) new_client,
type_name,
- smsc47m1_dir_table_template,
+ kind == smsc47m2 ?
+ smsc47m2_dir_table_template :
+ smsc47m1_dir_table_template,
THIS_MODULE)) < 0) {
err = i;
goto ERROR4;
@@ -318,47 +379,64 @@ static int smsc47m1_detach_client(struct i2c_client *client)
return 0;
}
-static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
+static inline int smsc47m1_read_value(struct i2c_client *client, u8 reg)
{
- int res;
-
- down(&(((struct smsc47m1_data *) (client->data))->lock));
- res = inb_p(client->addr + reg);
- up(&(((struct smsc47m1_data *) (client->data))->lock));
- return res;
+ return inb_p(client->addr + reg);
}
-static int smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
+static inline void smsc47m1_write_value(struct i2c_client *client, u8 reg,
+ u8 value)
{
- down(&(((struct smsc47m1_data *) (client->data))->lock));
outb_p(value, client->addr + reg);
- up(&(((struct smsc47m1_data *) (client->data))->lock));
- return 0;
}
static void smsc47m1_init_client(struct i2c_client *client)
{
- /* configure pins for tach function */
- smsc47m1_write_value(client, SMSC47M1_REG_TPIN1, 0x05);
- smsc47m1_write_value(client, SMSC47M1_REG_TPIN2, 0x05);
+ struct smsc47m1_data *data = client->data;
+ u8 reg;
+
+ switch (data->type) {
+ case smsc47m2:
+ /* For the new LPC47M292 chip, I prefer to play it safe and
+ only report the pin configuration */
+ reg = smsc47m1_read_value(client, SMSC47M2_REG_TPIN1);
+ if ((reg & 0x0d) != 0x09)
+ printk(KERN_NOTICE "smsc47m1: GP35 not configured for "
+ "fan input, ignore fan1 values\n");
+ reg = smsc47m1_read_value(client, SMSC47M2_REG_TPIN2);
+ if ((reg & 0x0d) != 0x09)
+ printk(KERN_NOTICE "smsc47m1: GP34 not configured for "
+ "fan input, ignore fan2 values\n");
+ reg = smsc47m1_read_value(client, SMSC47M2_REG_TPIN3);
+ if ((reg & 0x0d) != 0x0d)
+ printk(KERN_NOTICE "smsc47m1: GP33 not configured for "
+ "fan input, ignore fan3 values\n");
+ break;
+ default:
+ /* configure pins for tach function */
+ smsc47m1_write_value(client, SMSC47M1_REG_TPIN1, 0x05);
+ smsc47m1_write_value(client, SMSC47M1_REG_TPIN2, 0x05);
+ }
}
static void smsc47m1_update_client(struct i2c_client *client)
{
struct smsc47m1_data *data = client->data;
- int i;
down(&data->update_lock);
if ((jiffies - data->last_updated > HZ + HZ / 2) ||
(jiffies < data->last_updated) || !data->valid) {
- for (i = 1; i <= 2; i++) {
- data->fan[i - 1] =
- smsc47m1_read_value(client, SMSC47M1_REG_FAN(i));
- data->fan_min[i - 1] =
- smsc47m1_read_value(client, SMSC47M1_REG_FAN_MIN(i));
- data->pwm[i - 1] =
- smsc47m1_read_value(client, SMSC47M1_REG_PWM(i));
+ int i, fan_nr;
+ fan_nr = data->type == smsc47m2 ? 3 : 2;
+
+ for (i = 0; i < fan_nr; i++) {
+ data->fan[i] =
+ smsc47m1_read_value(client, SMSC47M1_REG_FAN[i]);
+ data->fan_min[i] =
+ smsc47m1_read_value(client, SMSC47M1_REG_FAN_MIN[i]);
+ data->pwm[i] =
+ smsc47m1_read_value(client, SMSC47M1_REG_PWM[i]);
}
i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
@@ -368,6 +446,18 @@ static void smsc47m1_update_client(struct i2c_client *client)
smsc47m1_read_value(client, SMSC47M1_REG_ALARM1) >> 6;
if(data->alarms)
smsc47m1_write_value(client, SMSC47M1_REG_ALARM1, 0xc0);
+
+ if (fan_nr >= 3) {
+ data->fan_div[2] = (smsc47m1_read_value(client,
+ SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
+ data->alarms |= (smsc47m1_read_value(client,
+ SMSC47M2_REG_ALARM6) & 0x40) >> 4;
+ if (data->alarms & 0x04)
+ smsc47m1_write_value(client,
+ SMSC47M2_REG_ALARM6,
+ 0x40);
+ }
+
data->last_updated = jiffies;
data->valid = 1;
}
@@ -380,26 +470,24 @@ void smsc47m1_fan(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct smsc47m1_data *data = client->data;
- int nr = ctl_name - SMSC47M1_SYSCTL_FAN1 + 1;
+ int nr = ctl_name - SMSC47M1_SYSCTL_FAN1;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
smsc47m1_update_client(client);
- results[0] = MIN_FROM_REG(data->fan_min[nr - 1],
- DIV_FROM_REG(data->fan_div[nr - 1]));
- results[1] = FAN_FROM_REG(data->fan[nr - 1],
- DIV_FROM_REG(data->fan_div[nr - 1]),
- data->fan_min[nr - 1]);
+ results[0] = MIN_FROM_REG(data->fan_min[nr],
+ DIV_FROM_REG(data->fan_div[nr]));
+ results[1] = FAN_FROM_REG(data->fan[nr],
+ DIV_FROM_REG(data->fan_div[nr]),
+ data->fan_min[nr]);
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
- data->fan_min[nr - 1] = MIN_TO_REG(results[0],
- DIV_FROM_REG
- (data->
- fan_div[nr-1]));
- smsc47m1_write_value(client, SMSC47M1_REG_FAN_MIN(nr),
- data->fan_min[nr - 1]);
+ data->fan_min[nr] = MIN_TO_REG(results[0],
+ DIV_FROM_REG(data->fan_div[nr]));
+ smsc47m1_write_value(client, SMSC47M1_REG_FAN_MIN[nr],
+ data->fan_min[nr]);
}
}
}
@@ -433,6 +521,13 @@ void smsc47m1_fan_div(struct i2c_client *client, int operation,
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
old = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
+ if (*nrels_mag >= 3 && data->type == smsc47m2) {
+ data->fan_div[2] = DIV_TO_REG(results[2]);
+ smsc47m1_write_value(client, SMSC47M2_REG_FANDIV3,
+ (smsc47m1_read_value(client,
+ SMSC47M2_REG_FANDIV3) & 0xcf)
+ | (data->fan_div[2] << 4));
+ }
if (*nrels_mag >= 2) {
data->fan_div[1] = DIV_TO_REG(results[1]);
old = (old & 0x3f) | (data->fan_div[1] << 6);
@@ -449,31 +544,31 @@ void smsc47m1_pwm(struct i2c_client *client, int operation, int ctl_name,
int *nrels_mag, long *results)
{
struct smsc47m1_data *data = client->data;
- int nr = 1 + ctl_name - SMSC47M1_SYSCTL_PWM1;
+ int nr = ctl_name - SMSC47M1_SYSCTL_PWM1;
if (operation == SENSORS_PROC_REAL_INFO)
*nrels_mag = 0;
else if (operation == SENSORS_PROC_REAL_READ) {
smsc47m1_update_client(client);
- results[0] = PWM_FROM_REG(data->pwm[nr - 1]);
- results[1] = !(data->pwm[nr - 1] & 0x01);
+ results[0] = PWM_FROM_REG(data->pwm[nr]);
+ results[1] = !(data->pwm[nr] & 0x01);
*nrels_mag = 2;
} else if (operation == SENSORS_PROC_REAL_WRITE) {
if (*nrels_mag >= 1) {
- data->pwm[nr - 1] = smsc47m1_read_value(client,
- SMSC47M1_REG_PWM(nr)) & 0x81;
- data->pwm[nr - 1] |= PWM_TO_REG(results[0]);
+ data->pwm[nr] = smsc47m1_read_value(client,
+ SMSC47M1_REG_PWM[nr]) & 0x81;
+ data->pwm[nr] |= PWM_TO_REG(results[0]);
if (*nrels_mag >= 2) {
if (results[1]) {
/* enable PWM */
- data->pwm[nr - 1] &= 0xfe;
+ data->pwm[nr] &= 0xfe;
} else {
/* disable PWM */
- data->pwm[nr - 1] |= 0x01;
+ data->pwm[nr] |= 0x01;
}
}
- smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
- data->pwm[nr - 1]);
+ smsc47m1_write_value(client, SMSC47M1_REG_PWM[nr],
+ data->pwm[nr]);
}
}
}
diff --git a/kernel/chips/w83627hf.c b/kernel/chips/w83627hf.c
index 4c69ded4..f4054615 100644
--- a/kernel/chips/w83627hf.c
+++ b/kernel/chips/w83627hf.c
@@ -281,8 +281,7 @@ static inline u8 DIV_TO_REG(long val)
return ((u8) i);
}
-/* For each registered chip, we need to keep some data in memory. That
- data is pointed to by w83627hf_list[NR]->data. The structure itself is
+/* For each registered chip, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new client is allocated. */
struct w83627hf_data {
struct i2c_client client;
diff --git a/kernel/chips/w83781d.c b/kernel/chips/w83781d.c
index 2f3d124e..73ceec28 100644
--- a/kernel/chips/w83781d.c
+++ b/kernel/chips/w83781d.c
@@ -246,8 +246,7 @@ static inline u8 DIV_TO_REG(long val, enum chips type)
bad. Quite a lot of bookkeeping is done. A real driver can often cut
some corners. */
-/* For each registered W83781D, we need to keep some data in memory. That
- data is pointed to by w83781d_list[NR]->data. The structure itself is
+/* For each registered W83781D, we need to keep some data in memory. It is
dynamically allocated, at the same time when a new w83781d client is
allocated. */
struct w83781d_data {
diff --git a/lib/Module.mk b/lib/Module.mk
index b053b385..dc51fb0a 100644
--- a/lib/Module.mk
+++ b/lib/Module.mk
@@ -33,7 +33,7 @@ LIBMAN5FILES := $(MODULE_DIR)/sensors.conf.5
# the public header files - in this case they are error.h, sensors.h,
# chips.h.
LIBMAINVER := 3
-LIBMINORVER := 1.2
+LIBMINORVER := 1.3
LIBVER := $(LIBMAINVER).$(LIBMINORVER)
# The static lib name, the shared lib name, and the internal ('so') name of
diff --git a/lib/chips.c b/lib/chips.c
index 0d68c89e..8d78b28d 100644
--- a/lib/chips.c
+++ b/lib/chips.c
@@ -4664,6 +4664,34 @@ static sensors_chip_feature smsc47m1_features[] =
{ { 0 }, 0 }
};
+static sensors_chip_feature smsc47m2_features[] =
+ {
+ { { SENSORS_SMSC47M1_FAN1, "fan1", NOMAP, NOMAP, R },
+ SMSC47M1_SYSCTL_FAN1, VALUE(2), 0 },
+ { { SENSORS_SMSC47M1_FAN2, "fan2", NOMAP, NOMAP, R },
+ SMSC47M1_SYSCTL_FAN2, VALUE(2), 0 },
+ { { SENSORS_SMSC47M1_FAN3, "fan3", NOMAP, NOMAP, R },
+ SMSC47M1_SYSCTL_FAN3, VALUE(2), 0 },
+ { { SENSORS_SMSC47M1_FAN1_MIN, "fan1_min", SENSORS_SMSC47M1_FAN1,
+ SENSORS_SMSC47M1_FAN1, RW },
+ SMSC47M1_SYSCTL_FAN1, VALUE(1), 0 },
+ { { SENSORS_SMSC47M1_FAN2_MIN, "fan2_min", SENSORS_SMSC47M1_FAN2,
+ SENSORS_SMSC47M1_FAN2, RW },
+ SMSC47M1_SYSCTL_FAN2, VALUE(1), 0 },
+ { { SENSORS_SMSC47M1_FAN3_MIN, "fan3_min", SENSORS_SMSC47M1_FAN3,
+ SENSORS_SMSC47M1_FAN3, RW },
+ SMSC47M1_SYSCTL_FAN3, VALUE(1), 0 },
+ { { SENSORS_SMSC47M1_FAN1_DIV, "fan1_div", SENSORS_SMSC47M1_FAN1, NOMAP, RW },
+ SMSC47M1_SYSCTL_FAN_DIV, VALUE(1), 0 },
+ { { SENSORS_SMSC47M1_FAN2_DIV, "fan2_div", SENSORS_SMSC47M1_FAN2, NOMAP, RW },
+ SMSC47M1_SYSCTL_FAN_DIV, VALUE(2), 0 },
+ { { SENSORS_SMSC47M1_FAN3_DIV, "fan3_div", SENSORS_SMSC47M1_FAN3, NOMAP, RW },
+ SMSC47M1_SYSCTL_FAN_DIV, VALUE(3), 0 },
+ { { SENSORS_SMSC47M1_ALARMS, "alarms", NOMAP, NOMAP, R },
+ SMSC47M1_SYSCTL_ALARMS, VALUE(1), 0 },
+ { { 0 }, 0 }
+ };
+
static sensors_chip_feature smsc47m192_features[] =
{
{ { SENSORS_SMSC47M192_IN(0), "in0", NOMAP, NOMAP, R },
@@ -5638,13 +5666,17 @@ static sensors_chip_feature max1619_features[] =
MAX1619_SYSCTL_LOCAL_TEMP, VALUE(1), 0 },
{ { SENSORS_MAX1619_REMOTE_TEMP, "temp2", NOMAP, NOMAP, R },
MAX1619_SYSCTL_REMOTE_TEMP, VALUE(3), 0 },
- { { SENSORS_MAX1619_REMOTE_HIGH, "temp2_min", NOMAP, NOMAP, RW },
- MAX1619_SYSCTL_REMOTE_TEMP, VALUE(2), 0 },
- { { SENSORS_MAX1619_REMOTE_LOW, "temp2_max", NOMAP, NOMAP, RW },
- MAX1619_SYSCTL_REMOTE_TEMP, VALUE(1), 0 },
- { { SENSORS_MAX1619_REMOTE_MAX, "temp2_crit", NOMAP, NOMAP, RW },
+ { { SENSORS_MAX1619_REMOTE_LOW, "temp2_min", SENSORS_MAX1619_REMOTE_TEMP,
+ SENSORS_MAX1619_REMOTE_TEMP, RW },
+ MAX1619_SYSCTL_REMOTE_TEMP, VALUE(2), 0 },
+ { { SENSORS_MAX1619_REMOTE_HIGH, "temp2_max", SENSORS_MAX1619_REMOTE_TEMP,
+ SENSORS_MAX1619_REMOTE_TEMP, RW },
+ MAX1619_SYSCTL_REMOTE_TEMP, VALUE(1), 0 },
+ { { SENSORS_MAX1619_REMOTE_MAX, "temp2_crit", SENSORS_MAX1619_REMOTE_TEMP,
+ SENSORS_MAX1619_REMOTE_TEMP, RW },
MAX1619_SYSCTL_REMOTE_CRIT, VALUE(1), 0 },
- { { SENSORS_MAX1619_REMOTE_HYST, "temp2_hyst", NOMAP, NOMAP, RW },
+ { { SENSORS_MAX1619_REMOTE_HYST, "temp2_hyst", SENSORS_MAX1619_REMOTE_TEMP,
+ SENSORS_MAX1619_REMOTE_TEMP, RW },
MAX1619_SYSCTL_REMOTE_CRIT, VALUE(2), 0,
"temp2_crit_hyst", 3 },
{ { SENSORS_MAX1619_ALARMS, "alarms", NOMAP, NOMAP, R },
@@ -5662,8 +5694,10 @@ static sensors_chip_feature max6650_features[] =
MAX6650_SYSCTL_FAN3, VALUE(1), 0 },
{ { SENSORS_MAX6650_FAN4_TACH, "fan4", NOMAP, NOMAP, R },
MAX6650_SYSCTL_FAN4, VALUE(1), 0 },
- { { SENSORS_MAX6650_SPEED, "speed", NOMAP, NOMAP, RW },
- MAX6650_SYSCTL_SPEED, VALUE(1), 0 },
+ { { SENSORS_MAX6650_SPEED, "speed", SENSORS_MAX6650_FAN1_TACH,
+ SENSORS_MAX6650_FAN1_TACH, RW },
+ MAX6650_SYSCTL_SPEED, VALUE(1), 0,
+ "fan1_target", 0 },
{ { 0 }, 0 }
};
@@ -5931,6 +5965,89 @@ static sensors_chip_feature coretemp_features[] =
{ { 0 }, 0 }
};
+#define SENSORS_DME1737_IN_FEATURES(nr) \
+ { { SENSORS_DME1737_IN(nr), "in" #nr, \
+ NOMAP, NOMAP, R }, \
+ NOSYSCTL, VALUE(3), 3 }, \
+ { { SENSORS_DME1737_IN_MIN(nr), "in" #nr "_min", \
+ SENSORS_DME1737_IN(nr), SENSORS_DME1737_IN(nr), RW }, \
+ NOSYSCTL, VALUE(1), 3 }, \
+ { { SENSORS_DME1737_IN_MAX(nr), "in" #nr "_max", \
+ SENSORS_DME1737_IN(nr), SENSORS_DME1737_IN(nr), RW }, \
+ NOSYSCTL, VALUE(2), 3 }, \
+ { { SENSORS_DME1737_IN_ALARM(nr), "in" #nr "_alarm", \
+ SENSORS_DME1737_IN(nr), NOMAP, R }, \
+ NOSYSCTL, VALUE(1), 0 }
+
+#define SENSORS_DME1737_TEMP_FEATURES(nr) \
+ { { SENSORS_DME1737_TEMP(nr), "temp" #nr, \
+ NOMAP, NOMAP, R }, \
+ NOSYSCTL, VALUE(3), 3 }, \
+ { { SENSORS_DME1737_TEMP_MIN(nr), "temp" #nr "_min", \
+ SENSORS_DME1737_TEMP(nr), SENSORS_DME1737_TEMP(nr), RW }, \
+ NOSYSCTL, VALUE(2), 3 }, \
+ { { SENSORS_DME1737_TEMP_MAX(nr), "temp" #nr "_max", \
+ SENSORS_DME1737_TEMP(nr), SENSORS_DME1737_TEMP(nr), RW }, \
+ NOSYSCTL, VALUE(1), 3 }, \
+ { { SENSORS_DME1737_TEMP_ALARM(nr), "temp" #nr "_alarm", \
+ SENSORS_DME1737_TEMP(nr), NOMAP, R }, \
+ NOSYSCTL, VALUE(1), 0 }, \
+ { { SENSORS_DME1737_TEMP_FAULT(nr), "temp" #nr "_fault", \
+ SENSORS_DME1737_TEMP(nr), NOMAP, R }, \
+ NOSYSCTL, VALUE(2), 0 }
+
+#define SENSORS_DME1737_FAN_FEATURES(nr) \
+ { { SENSORS_DME1737_FAN(nr), "fan" #nr, \
+ NOMAP, NOMAP, R }, \
+ NOSYSCTL, VALUE(2), 0 }, \
+ { { SENSORS_DME1737_FAN_MIN(nr), "fan" #nr "_min", \
+ SENSORS_DME1737_FAN(nr), SENSORS_DME1737_FAN(nr), RW }, \
+ NOSYSCTL, VALUE(1), 0 }, \
+ { { SENSORS_DME1737_FAN_ALARM(nr), "fan" #nr "_alarm", \
+ SENSORS_DME1737_FAN(nr), NOMAP, R }, \
+ NOSYSCTL, VALUE(1), 0 }
+
+#define SENSORS_DME1737_PWM_FEATURES(nr) \
+ { { SENSORS_DME1737_PWM(nr), "pwm" #nr, \
+ NOMAP, NOMAP, RW }, \
+ NOSYSCTL, VALUE(1), 0 }, \
+ { { SENSORS_DME1737_PWM_ENABLE(nr), "pwm" #nr "_enable", \
+ SENSORS_DME1737_PWM(nr), SENSORS_DME1737_PWM(nr), RW }, \
+ NOSYSCTL, VALUE(2), 0 }, \
+ { { SENSORS_DME1737_PWM_FREQ(nr), "pwm" #nr "_freq", \
+ SENSORS_DME1737_PWM(nr), SENSORS_DME1737_PWM(nr), RW }, \
+ NOSYSCTL, VALUE(3), 0 }
+
+static sensors_chip_feature dme1737_features[] =
+{
+ SENSORS_DME1737_IN_FEATURES(0),
+ SENSORS_DME1737_IN_FEATURES(1),
+ SENSORS_DME1737_IN_FEATURES(2),
+ SENSORS_DME1737_IN_FEATURES(3),
+ SENSORS_DME1737_IN_FEATURES(4),
+ SENSORS_DME1737_IN_FEATURES(5),
+ SENSORS_DME1737_IN_FEATURES(6),
+ SENSORS_DME1737_TEMP_FEATURES(1),
+ SENSORS_DME1737_TEMP_FEATURES(2),
+ SENSORS_DME1737_TEMP_FEATURES(3),
+ SENSORS_DME1737_FAN_FEATURES(1),
+ SENSORS_DME1737_FAN_FEATURES(2),
+ SENSORS_DME1737_FAN_FEATURES(3),
+ SENSORS_DME1737_FAN_FEATURES(4),
+ SENSORS_DME1737_FAN_FEATURES(5),
+ SENSORS_DME1737_FAN_FEATURES(6),
+ SENSORS_DME1737_PWM_FEATURES(1),
+ SENSORS_DME1737_PWM_FEATURES(2),
+ SENSORS_DME1737_PWM_FEATURES(3),
+ SENSORS_DME1737_PWM_FEATURES(5),
+ SENSORS_DME1737_PWM_FEATURES(6),
+ { { SENSORS_DME1737_VID, "cpu0_vid", NOMAP, NOMAP, R },
+ NOSYSCTL, VALUE(1), 3 },
+ { { SENSORS_DME1737_VRM, "vrm", NOMAP, NOMAP, RW },
+ NOSYSCTL, VALUE(1), 1 },
+ { { 0 }, 0 }
+};
+
sensors_chip_features sensors_chip_features_list[] =
{
{ SENSORS_LM78_PREFIX, lm78_features },
@@ -6005,6 +6122,7 @@ sensors_chip_features sensors_chip_features_list[] =
{ SENSORS_VT1211_PREFIX, vt1211_features },
{ SENSORS_SMSC47M192_PREFIX, smsc47m192_features },
{ SENSORS_SMSC47M1_PREFIX, smsc47m1_features },
+ { SENSORS_SMSC47M2_PREFIX, smsc47m2_features },
{ SENSORS_PC87360_PREFIX, pc87360_features },
{ SENSORS_PC87363_PREFIX, pc87360_features },
{ SENSORS_PC87364_PREFIX, pc87360_features },
@@ -6042,5 +6160,6 @@ sensors_chip_features sensors_chip_features_list[] =
{ SENSORS_ABITUGURU_PREFIX, abituguru_features },
{ SENSORS_K8TEMP_PREFIX, k8temp_features },
{ SENSORS_CORETEMP_PREFIX, coretemp_features },
+ { SENSORS_DME1737_PREFIX, dme1737_features },
{ 0 }
};
diff --git a/lib/chips.h b/lib/chips.h
index 123753d4..e2d5cff1 100644
--- a/lib/chips.h
+++ b/lib/chips.h
@@ -1834,13 +1834,17 @@
#define SENSORS_VT1211_UCH 84 /* RW */
#define SENSORS_SMSC47M1_PREFIX "smsc47m1"
+#define SENSORS_SMSC47M2_PREFIX "smsc47m2"
#define SENSORS_SMSC47M1_FAN1 31 /* R */
#define SENSORS_SMSC47M1_FAN2 32 /* R */
+#define SENSORS_SMSC47M1_FAN3 33 /* R */
#define SENSORS_SMSC47M1_FAN1_MIN 41 /* RW */
#define SENSORS_SMSC47M1_FAN2_MIN 42 /* RW */
+#define SENSORS_SMSC47M1_FAN3_MIN 43 /* RW */
#define SENSORS_SMSC47M1_FAN1_DIV 75 /* RW */
#define SENSORS_SMSC47M1_FAN2_DIV 76 /* RW */
+#define SENSORS_SMSC47M1_FAN3_DIV 77 /* RW */
#define SENSORS_SMSC47M1_ALARMS 81 /* R */
#define SENSORS_SMSC47M192_PREFIX "smsc47m192"
@@ -2258,4 +2262,34 @@
#define SENSORS_CORETEMP_TEMP1_CRIT 0x02 /* R */
#define SENSORS_CORETEMP_TEMP1_CRIT_ALARM 0x03 /* R */
+/* DME1737 */
+
+#define SENSORS_DME1737_PREFIX "dme1737"
+
+/* in n from 0 to 6 */
+#define SENSORS_DME1737_IN(n) (0x01 + (n)) /* R */
+#define SENSORS_DME1737_IN_MIN(n) (0x11 + (n)) /* RW */
+#define SENSORS_DME1737_IN_MAX(n) (0x21 + (n)) /* RW */
+#define SENSORS_DME1737_IN_ALARM(n) (0x31 + (n)) /* R */
+
+/* temp n from 1 to 3*/
+#define SENSORS_DME1737_TEMP(n) (0x41 + (n)) /* R */
+#define SENSORS_DME1737_TEMP_MIN(n) (0x51 + (n)) /* RW */
+#define SENSORS_DME1737_TEMP_MAX(n) (0x61 + (n)) /* RW */
+#define SENSORS_DME1737_TEMP_ALARM(n) (0x71 + (n)) /* R */
+#define SENSORS_DME1737_TEMP_FAULT(n) (0x81 + (n)) /* R */
+
+/* fan n from 1 to 6 */
+#define SENSORS_DME1737_FAN(n) (0x91 + (n)) /* R */
+#define SENSORS_DME1737_FAN_MIN(n) (0xa1 + (n)) /* RW */
+#define SENSORS_DME1737_FAN_ALARM(n) (0xb1 + (n)) /* R */
+
+/* pwm n from 1 to 3 and 5 to 6 */
+#define SENSORS_DME1737_PWM(n) (0xc1 + (n)) /* RW */
+#define SENSORS_DME1737_PWM_ENABLE(n) (0xd1 + (n)) /* RW */
+#define SENSORS_DME1737_PWM_FREQ(n) (0xe1 + (n)) /* RW */
+
+#define SENSORS_DME1737_VID (0xf0) /* R */
+#define SENSORS_DME1737_VRM (0xf1) /* RW */
+
#endif /* def LIB_SENSORS_CHIPS_H */
diff --git a/lib/proc.c b/lib/proc.c
index a100fac4..3b1253ec 100644
--- a/lib/proc.c
+++ b/lib/proc.c
@@ -247,7 +247,7 @@ struct match {
static const struct match matches[] = {
{ "beeps", "beep_mask", 0 },
- { "pwm", "fan1_pwm", 0 },
+ { "pwm", "pwm1", 0, "fan1_pwm" },
{ "vid", "cpu0_vid", INMAG, "in0_ref" },
{ "remote_temp", "temp2_input", TEMPMAG },
{ "remote_temp_hyst", "temp2_max_hyst", TEMPMAG },
@@ -259,14 +259,6 @@ static const struct match matches[] = {
{ "temp_over", "temp1_max", TEMPMAG },
{ "temp_high", "temp1_max", TEMPMAG },
{ "temp_crit", "temp1_crit", TEMPMAG },
- { "pwm1", "pwm1", 0, "fan1_pwm" },
- { "pwm2", "pwm2", 0, "fan2_pwm" },
- { "pwm3", "pwm3", 0, "fan3_pwm" },
- { "pwm4", "pwm4", 0, "fan4_pwm" },
- { "pwm1_enable", "pwm1_enable", 0, "fan1_pwm_enable" },
- { "pwm2_enable", "pwm2_enable", 0, "fan2_pwm_enable" },
- { "pwm3_enable", "pwm3_enable", 0, "fan3_pwm_enable" },
- { "pwm4_enable", "pwm4_enable", 0, "fan4_pwm_enable" },
{ NULL, NULL }
};
@@ -357,13 +349,15 @@ static int getsysname(const sensors_chip_feature *feature, char *sysname,
return 0;
}
if(sscanf(name, "pwm%d%c", &num, &check) == 1) {
- sprintf(sysname, "fan%d_pwm", num);
+ strcpy(sysname, name);
*sysmag = 0;
+ sprintf(altsysname, "fan%d_pwm", num);
return 0;
}
if(sscanf(name, "pwm%d_enabl%c%c", &num, &last, &check) == 2 && last == 'e') {
- sprintf(sysname, "fan%d_pwm_enable", num);
+ strcpy(sysname, name);
*sysmag = 0;
+ sprintf(altsysname, "fan%d_pwm_enable", num);
return 0;
}
diff --git a/lib/sysfs.c b/lib/sysfs.c
index b2d06683..bbb2b735 100644
--- a/lib/sysfs.c
+++ b/lib/sysfs.c
@@ -75,18 +75,23 @@ static int sensors_read_one_sysfs_chip(struct sysfs_device *dev)
if (sscanf(dev->name, "%d-%x", &entry.name.bus, &entry.name.addr) == 2) {
/* find out if legacy ISA or not */
- snprintf(bus_path, sizeof(bus_path),
+ if (entry.name.bus == 9191)
+ entry.name.bus = SENSORS_CHIP_NAME_BUS_ISA;
+ else {
+ snprintf(bus_path, sizeof(bus_path),
"%s/class/i2c-adapter/i2c-%d/device/name",
sensors_sysfs_mount, entry.name.bus);
- if ((bus_attr = sysfs_open_attribute(bus_path))) {
- if (sysfs_read_attribute(bus_attr))
- return -SENSORS_ERR_PARSE;
+ if ((bus_attr = sysfs_open_attribute(bus_path))) {
+ if (sysfs_read_attribute(bus_attr))
+ return -SENSORS_ERR_PARSE;
- if (bus_attr->value && !strncmp(bus_attr->value, "ISA ", 4))
- entry.name.bus = SENSORS_CHIP_NAME_BUS_ISA;
+ if (bus_attr->value
+ && !strncmp(bus_attr->value, "ISA ", 4))
+ entry.name.bus = SENSORS_CHIP_NAME_BUS_ISA;
- sysfs_close_attribute(bus_attr);
+ sysfs_close_attribute(bus_attr);
+ }
}
} else if (sscanf(dev->name, "%*[a-z0-9_].%d", &entry.name.addr) == 1) {
/* must be new ISA (platform driver) */
@@ -195,13 +200,12 @@ int sensors_read_sysfs_bus(void)
struct sysfs_device *dev;
struct sysfs_attribute *attr;
- if (!(dev = sysfs_get_classdev_device(clsdev)))
- continue;
/* Get the adapter name from the classdev "name" attribute
* (Linux 2.6.20 and later). If it fails, fall back to
* the device "name" attribute (for older kernels). */
if (!(attr = sysfs_get_classdev_attr(clsdev, "name"))
- && !(attr = sysfs_get_device_attr(dev, "name")))
+ && !((dev = sysfs_get_classdev_device(clsdev)) &&
+ (attr = sysfs_get_device_attr(dev, "name"))))
continue;
/* NB: attr->value[attr->len-1] == '\n'; chop that off */
diff --git a/lm_sensors.lsm b/lm_sensors.lsm
index d5fefc3d..13d37e4c 100644
--- a/lm_sensors.lsm
+++ b/lm_sensors.lsm
@@ -1,6 +1,6 @@
Begin3
Title: lm_sensors
-Version: 2.10.2
+Version: 2.10.3
Entered-date: 29DEC98
Description: Hardware health monitoring package for Linux. It consists of
kernel modules to access sensor chips and SMBus hardware,
diff --git a/mkpatch/mkpatch.pl b/mkpatch/mkpatch.pl
index adaf4cad..2ab14c71 100755
--- a/mkpatch/mkpatch.pl
+++ b/mkpatch/mkpatch.pl
@@ -224,9 +224,11 @@ Intel 82371AB PIIX4(E), ServerWorks OSB4, CSB5, CSB6, HT-1000
CONFIG_I2C_PIIX4
If you say yes to this option, support will be included for the
Intel PIIX4, PIIX4E, 443MX, Serverworks OSB4, CSB5, CSB6 and
- HT-1000, ATI IXP200, IXP300 and IXP400, and SMSC Victory66 mainboard
- I2C interfaces. This can also be built as a module which can be
- inserted and removed while the kernel is running.
+ HT-1000, ATI IXP200, IXP300, IXP400 and SB600, and SMSC Victory66
+ mainboard SMBus interfaces.
+
+ This can also be built as a module which can be inserted and removed
+ while the kernel is running.
Nvidia Nforce2/3/4 based Mainboard
CONFIG_I2C_NFORCE2
@@ -264,7 +266,7 @@ CONFIG_I2C_VIA
be built as a module which can be inserted and removed while the
kernel is running.
-VIA Technologies, Inc. VT82C596, 596B, 686A/B, 8233, 8235, 8237R/A, 8251
+VIA Technologies, Inc. VT82C596/82C686/82xx and CX700
CONFIG_I2C_VIAPRO
If you say yes to this option, support will be included for the VIA
Technologies I2C adapter on these chips. For integrated sensors on the
@@ -985,7 +987,7 @@ sub gen_drivers_i2c_Config_in
dep_tristate ' SiS 645/961,645DX/961,735' CONFIG_I2C_SIS645 $CONFIG_I2C $CONFIG_HOTPLUG
dep_tristate ' Savage 4' CONFIG_I2C_SAVAGE4 $CONFIG_I2C_ALGOBIT
dep_tristate ' VIA Technologies, Inc. VT82C586B' CONFIG_I2C_VIA $CONFIG_I2C_ALGOBIT
- dep_tristate ' VIA Technologies, Inc. VT596A/B, 686A/B, 8231, 8233, 8233A, 8235, 8237R/A, 8251' CONFIG_I2C_VIAPRO $CONFIG_I2C
+ dep_tristate ' VIA Technologies, Inc. VT82C596/82C686/82xx and CX700' CONFIG_I2C_VIAPRO $CONFIG_I2C
dep_tristate ' Voodoo3 I2C interface' CONFIG_I2C_VOODOO3 $CONFIG_I2C_ALGOBIT
dep_tristate ' Pseudo ISA adapter (for some hardware sensors)' CONFIG_I2C_ISA $CONFIG_I2C
fi
diff --git a/prog/detect/i2cdetect.8 b/prog/detect/i2cdetect.8
index c9a7ce43..806f4a3f 100644
--- a/prog/detect/i2cdetect.8
+++ b/prog/detect/i2cdetect.8
@@ -8,6 +8,7 @@ i2cdetect \- detect I2C chips
.RI [ -a ]
.RI [ -q | -r ]
.I i2cbus
+.RI [ "first last" ]
.br
.B i2cdetect
.I -F
@@ -24,6 +25,8 @@ i2cdetect is a userspace program to scan an I2C bus for devices. It
outputs a table with the list of detected devices on the specified bus.
\fIi2cbus\fR indicates the number of the I2C bus to be scanned, and
should correspond to one of the busses listed by \fIi2cdetect -l\fR.
+The optional parameters \fIfirst\fR and \fIlast\fR restrict the scanning
+range (default: from 0x03 to 0x77).
.PP
i2cdetect can also be used to query the functionalities of an I2C bus
(see option \fB-F\fP.)
diff --git a/prog/detect/i2cdetect.c b/prog/detect/i2cdetect.c
index c5e33e72..7bae2f8e 100644
--- a/prog/detect/i2cdetect.c
+++ b/prog/detect/i2cdetect.c
@@ -61,6 +61,8 @@ int scan_i2c_bus(int file, const int mode, const int first, const int last)
for (i = 0; i < 128; i += 16) {
printf("%02x: ", i);
for(j = 0; j < 16; j++) {
+ fflush(stdout);
+
/* Skip unwanted addresses */
if (i+j < first || i+j > last) {
printf(" ");
diff --git a/prog/detect/sensors-detect b/prog/detect/sensors-detect
index 440ee6e3..9add80d7 100755
--- a/prog/detect/sensors-detect
+++ b/prog/detect/sensors-detect
@@ -47,7 +47,8 @@ $ENV{PATH} = '/usr/local/sbin:'.$ENV{PATH}
# CONSTANT DECLARATIONS #
#########################
-use vars qw(@pci_adapters @chip_ids @superio_ids @cpu_ids $revision);
+use vars qw(@pci_adapters @chip_ids $i2c_addresses_to_scan @superio_ids
+ @cpu_ids $revision);
$revision = '$Revision$ ($Date$)';
$revision =~ s/\$\w+: (.*?) \$/$1/g;
@@ -245,6 +246,13 @@ $revision =~ s/ \([^()]*\)//;
driver => "i2c-viapro",
match => qr/^SMBus V(IA|ia) Pro adapter at/,
} ,
+ {
+ vendid => 0x1106,
+ devid => 0x8324,
+ procid => "VIA Technologies CX700 South Bridge",
+ driver => "i2c-viapro",
+ match => qr/^SMBus V(IA|ia) Pro adapter at/,
+ },
{
vendid => 0x1039,
devid => 0x5597,
@@ -529,14 +537,14 @@ $revision =~ s/ \([^()]*\)//;
vendid => 0x10de,
devid => 0x03eb,
procid => "nVidia Corporation nForce4 SMBus (MCP61)",
- driver => "to-be-tested",
+ driver => "i2c-nforce2",
match => qr/^SMBus nForce2 adapter at /,
},
{
vendid => 0x10de,
devid => 0x0446,
procid => "nVidia Corporation nForce4 SMBus (MCP65)",
- driver => "to-be-tested",
+ driver => "i2c-nforce2",
match => qr/^SMBus nForce2 adapter at /,
},
{
@@ -811,8 +819,14 @@ use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
name => "National Semiconductor LM75",
driver => "lm75",
i2c_addrs => [0x48..0x4f],
- i2c_detect => sub { lm75_detect(@_); },
- } ,
+ i2c_detect => sub { lm75_detect(0, @_); },
+ },
+ {
+ name => "Dallas Semiconductor DS75",
+ driver => "lm75",
+ i2c_addrs => [0x48..0x4f],
+ i2c_detect => sub { lm75_detect(1, @_); },
+ },
{
name => "National Semiconductor LM77",
driver => "lm77",
@@ -967,13 +981,10 @@ use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
},
{
name => "Winbond W83627HF",
- driver => "w83781d",
- i2c_addrs => [0x20..0x2f],
+ driver => "use-isa-instead",
+ i2c_addrs => [0x28..0x2f],
i2c_detect => sub { w83781d_detect(3, @_); },
- isa_addrs => [0x290],
- isa_detect => sub { w83781d_isa_detect(3, @_); },
- alias_detect => sub { w83781d_alias_detect(3, @_); },
- } ,
+ },
{
name => "Winbond W83627EHF",
driver => "use-isa-instead",
@@ -1136,12 +1147,36 @@ use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
i2c_addrs => [0x18..0x1a,0x29..0x2b,0x4c..0x4e],
i2c_detect => sub { adm1021_detect(3, @_); },
},
+ {
+ name => "Maxim MAX1668",
+ driver => "max1668",
+ i2c_addrs => [0x18..0x1a,0x29..0x2b,0x4c..0x4e],
+ i2c_detect => sub { max1668_detect(0, @_); },
+ },
+ {
+ name => "Maxim MAX1805",
+ driver => "max1668",
+ i2c_addrs => [0x18..0x1a,0x29..0x2b,0x4c..0x4e],
+ i2c_detect => sub { max1668_detect(1, @_); },
+ },
+ {
+ name => "Maxim MAX1989",
+ driver => "max1668",
+ i2c_addrs => [0x18..0x1a,0x29..0x2b,0x4c..0x4e],
+ i2c_detect => sub { max1668_detect(2, @_); },
+ },
{
name => "Maxim MAX6650/MAX6651",
driver => "max6650",
i2c_addrs => [0x1b,0x1f,0x48,0x4b],
i2c_detect => sub { max6650_detect(0, @_); },
},
+ {
+ name => "Maxim MAX6655/MAX6656",
+ driver => "max6655",
+ i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
+ i2c_detect => sub { max6655_detect(0, @_); },
+ },
{
name => "TI THMC10",
driver => "adm1021",
@@ -1352,13 +1387,6 @@ use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
i2c_addrs => [0x57],
i2c_detect => sub { eeprom_detect(1, @_); },
},
-# Disabled by default (potentially dangerous)
-# {
-# name => "SPD EEPROM with Software Write-Protect",
-# driver => "eeprom",
-# i2c_addrs => [0x50..0x57],
-# i2c_detect => sub { eeprom_detect(2, @_); },
-# },
{
name => "EDID EEPROM",
driver => "eeprom",
@@ -1390,14 +1418,14 @@ use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
i2c_detect => sub { m5879_detect(@_); },
},
{
- name => "SMSC LPC47M15x, LPC47M192 or LPC47M997",
+ name => "SMSC LPC47M15x/192/292/997",
driver => "smsc47m192",
i2c_addrs => [0x2c..0x2d],
i2c_detect => sub { smsc47m192_detect(@_); },
},
{
name => "SMSC DME1737",
- driver => "to-be-written",
+ driver => "dme1737",
i2c_addrs => [0x2c..0x2e],
i2c_detect => sub { dme1737_detect(@_); },
},
@@ -1469,16 +1497,10 @@ use vars qw(@pci_adapters_sis5595 @pci_adapters_sis645 @pci_adapters_sis96x);
},
{
name => "Maxim MAX6900",
- driver => "to-be-written",
+ driver => "not-a-sensor",
i2c_addrs => [0x50],
i2c_detect => sub { max6900_detect(@_); },
},
- {
- name => "SMBus 2.0 ARP-Capable Device",
- driver => "not-a-sensor",
- i2c_addrs => [0x61],
- i2c_detect => sub { arp_detect(@_); },
- },
{
name => "IPMI BMC KCS",
driver => "bmcsensors",
@@ -1536,6 +1558,8 @@ $chip_kern26_w83791d = {
# Put in "not-a-sensor" if the chip doesn't have hardware monitoring
# capabilities (listing such chips here removes the need of manual
# lookup when people report them).
+# Put in exactly "via-smbus-only" if this is a Super-I/O chip whose
+# hardware monitoring registers can only be accessed via the SMBus.
# devid: The device ID(s) we have to match (base device)
# devid_mask (optional): Bitmask to apply before checking the device ID
# logdev: The logical device containing the sensors
@@ -1549,50 +1573,10 @@ $chip_kern26_w83791d = {
# generic probing if we fail to recognize the chip.
# enter: The password sequence to write to the address register
# chips: Array of chips
+# The order of families matters, because we stop as soon as one family
+# succeeds. So we have to list families with shorter password sequences
+# first.
@superio_ids = (
- {
- family => "ITE",
- guess => 0x290,
- enter =>
- {
- 0x2e => [0x87, 0x01, 0x55, 0x55],
- 0x4e => [0x87, 0x01, 0x55, 0xaa],
- },
- chips =>
- [
- {
- name => "ITE IT8702F Super IO Sensors",
- driver => "to-be-written",
- devid => 0x8702,
- logdev => 0x04,
- },
- {
- name => "ITE IT8705F Super IO Sensors",
- driver => "it87",
- devid => 0x8705,
- logdev => 0x04,
- },
- {
- name => "ITE IT8712F Super IO Sensors",
- driver => "it87",
- devid => 0x8712,
- logdev => 0x04,
- alias_detect => sub { ite_alias_detect(0, @_); },
- },
- {
- name => "ITE IT8716F Super IO Sensors",
- driver => "it87",
- devid => 0x8716,
- logdev => 0x04,
- },
- {
- name => "ITE IT8718F Super IO Sensors",
- driver => "it87",
- devid => 0x8718,
- logdev => 0x04,
- },
- ],
- },
{
family => "National Semiconductor",
enter =>
@@ -1602,6 +1586,12 @@ $chip_kern26_w83791d = {
},
chips =>
[
+ {
+ name => "Nat. Semi. PC8374L Super IO Sensors",
+ driver => "to-be-written",
+ devid => 0xf1,
+ logdev => 0x08,
+ },
{
name => "Nat. Semi. PC87351 Super IO Fan Sensors",
driver => "to-be-written",
@@ -1747,6 +1737,12 @@ $chip_kern26_w83791d = {
devid => 0x60,
logdev => 0x0a,
},
+ {
+ name => "SMSC LPC47M292 Super IO Fan Sensors",
+ driver => "smsc47m1",
+ devid => 0x6b,
+ logdev => 0x0a,
+ },
{
name => "SMSC LPC47S42x Super IO Fan Sensors",
driver => "to-be-written",
@@ -1783,6 +1779,12 @@ $chip_kern26_w83791d = {
devid => 0x81,
logdev => 0x08,
},
+ {
+ name => "SMSC SCH5504-NS Super IO",
+ # No datasheet
+ driver => "not-a-sensor",
+ devid => 0x79,
+ },
{
name => "SMSC LPC47M584-NC Super IO",
# No datasheet
@@ -1791,9 +1793,17 @@ $chip_kern26_w83791d = {
{
name => "SMSC DME1737 Super IO",
# Hardware monitoring features are accessed on the SMBus
- driver => "not-a-sensor",
+ driver => "via-smbus-only",
devid => 0x78,
},
+ {
+ name => "SMSC DME1737 Super IO",
+ # The DME1737 shows up twice in this list because it can return either
+ # 0x78 or 0x77 as its device ID.
+ # Hardware monitoring features are accessed on the SMBus
+ driver => "via-smbus-only",
+ devid => 0x77,
+ },
],
},
{
@@ -1818,6 +1828,7 @@ $chip_kern26_w83791d = {
driver => "w83627hf",
devid => 0x52,
logdev => 0x0b,
+ alias_detect => sub { w83781d_alias_detect(3, @_); },
},
{
name => "Winbond W83627THF Super IO Sensors",
@@ -1903,6 +1914,49 @@ $chip_kern26_w83791d = {
},
],
},
+ {
+ family => "ITE",
+ guess => 0x290,
+ enter =>
+ {
+ 0x2e => [0x87, 0x01, 0x55, 0x55],
+ 0x4e => [0x87, 0x01, 0x55, 0xaa],
+ },
+ chips =>
+ [
+ {
+ name => "ITE IT8702F Super IO Sensors",
+ driver => "to-be-written",
+ devid => 0x8702,
+ logdev => 0x04,
+ },
+ {
+ name => "ITE IT8705F Super IO Sensors",
+ driver => "it87",
+ devid => 0x8705,
+ logdev => 0x04,
+ },
+ {
+ name => "ITE IT8712F Super IO Sensors",
+ driver => "it87",
+ devid => 0x8712,
+ logdev => 0x04,
+ alias_detect => sub { ite_alias_detect(0, @_); },
+ },
+ {
+ name => "ITE IT8716F Super IO Sensors",
+ driver => "it87",
+ devid => 0x8716,
+ logdev => 0x04,
+ },
+ {
+ name => "ITE IT8718F Super IO Sensors",
+ driver => "it87",
+ devid => 0x8718,
+ logdev => 0x04,
+ },
+ ],
+ },
);
# Drivers for CPU embedded sensors
@@ -2477,6 +2531,7 @@ sub i2c_get_funcs($)
sub i2c_set_slave_addr
{
my ($file,$addr) = @_;
+ $addr += 0; # Make sure it's a number not a string
ioctl $file, IOCTL_I2C_SLAVE, $addr or return 0;
return 1;
}
@@ -2819,6 +2874,30 @@ sub add_isa_to_chips_detected
}
}
+# From the list of known I2C/SMBus devices, build a list of I2C addresses
+# which are worth probing. There's no point in probing an address for which
+# we don't know a single device, and probing some addresses has caused
+# random trouble in the past.
+sub i2c_addresses_to_scan()
+{
+ my @used;
+ my @addresses;
+ my $addr;
+
+ foreach my $chip (@chip_ids) {
+ next unless defined $chip->{'i2c_addrs'};
+ next if $chip->{'driver'} eq 'not-a-sensor';
+ foreach $addr (@{$chip->{'i2c_addrs'}}) {
+ $used[$addr]++;
+ }
+ }
+
+ for ($addr = 0x03; $addr <= 0x77; $addr++) {
+ push @addresses, $addr if $used[$addr];
+ }
+ return \@addresses;
+}
+
# $_[0]: The number of the adapter to scan
# $_[1]: The name of the adapter, as appearing in /proc/bus/i2c
# $_[2]: The driver of the adapter
@@ -2851,7 +2930,7 @@ sub scan_adapter
}
# Now scan each address in turn
- foreach $addr (0x03..0x77) {
+ foreach $addr (@{$i2c_addresses_to_scan}) {
# As the not_to_scan list is sorted, we can check it fast
if (@not_to_scan and $not_to_scan[0] == $addr) {
shift @not_to_scan;
@@ -2900,6 +2979,7 @@ sub scan_adapter
next unless i2c_probe(\*FILE, $addr, $funcs);
printf "Client found at address 0x%02x\n",$addr;
+ $| = 1;
foreach $chip (@chip_ids) {
if (exists $chip->{i2c_addrs} and contains $addr, @{$chip->{i2c_addrs}}) {
printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name}));
@@ -2931,12 +3011,14 @@ sub scan_adapter
}
}
}
+ $| = 0;
}
}
sub scan_isa_bus
{
my ($chip,$addr,$conf);
+ $| = 1;
foreach $chip (@chip_ids) {
next if not exists $chip->{isa_addrs} or not exists $chip->{isa_detect};
foreach $addr (@{$chip->{isa_addrs}}) {
@@ -2958,6 +3040,7 @@ sub scan_isa_bus
}
}
}
+ $| = 0;
}
use vars qw(%superio);
@@ -3037,6 +3120,10 @@ sub probe_superio($$$)
print "\n (no hardware monitoring capabilities)\n";
return;
}
+ if ($chip->{driver} eq "via-smbus-only") {
+ print "\n (hardware monitoring capabilities accessible via SMBus only)\n";
+ return;
+ }
# Switch to the sensor logical device
outb($addrreg, $superio{logdevreg});
@@ -3076,6 +3163,9 @@ sub scan_superio
printf("Probing for Super-I/O at 0x\%x/0x\%x\n", $addrreg, $datareg);
+ $| = 1;
+# reset state to avoid false positives
+ exit_superio($addrreg, $datareg);
FAMILY:
foreach my $family (@superio_ids) {
printf("\%-60s", "Trying family `$family->{family}'... ");
@@ -3099,7 +3189,7 @@ sub scan_superio
if (($chip->{devid} > 0xff && ($val & ($chip->{devid_mask} || 0xffff)) == $chip->{devid})
|| ($chip->{devid} <= 0xff && ($val >> 8) == $chip->{devid})) {
probe_superio($addrreg, $datareg, $chip);
- $found++;
+ $found++;
}
}
@@ -3111,7 +3201,9 @@ sub scan_superio
}
exit_superio($addrreg, $datareg);
+ last FAMILY;
}
+ $| = 0;
}
@@ -3170,7 +3262,6 @@ sub chip_special_cases
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (7) if detected.
# Registers used: 0x58
@@ -3183,7 +3274,6 @@ sub mtp008_detect
# $_[0]: Chip to detect (0 = LM78, 1 = LM78-J, 2 = LM79)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (6) if detected.
# Registers used:
@@ -3216,8 +3306,8 @@ sub lm78_isa_detect
return if inb ($addr + 2) != $val or inb ($addr + 3) != $val or
inb ($addr + 7) != $val;
- $val = inb($addr + 5) & 0x7f;
- outb($addr + 5, ~$val & 0xff);
+ $val = inb($addr + 5);
+ outb($addr + 5, ~$val & 0x7f);
if ((inb ($addr+5) & 0x7f) != (~ $val & 0x7f)) {
outb($addr+5,$val);
return;
@@ -3229,11 +3319,11 @@ sub lm78_isa_detect
($chip == 1 and $reg == 0x40) or
($chip == 2 and ($reg & 0xfe) == 0xc0);
- # Explicitely prevent misdetection of Winbond chips
+ # Explicitly prevent misdetection of Winbond chips
$reg = &$readproc(0x4f);
return if $reg == 0xa3 || $reg == 0x5c;
- # Explicitely prevent misdetection of ITE chips
+ # Explicitly prevent misdetection of ITE chips
$reg = &$readproc(0x58);
return if $reg == 0x90;
@@ -3257,9 +3347,9 @@ sub lm78_alias_detect
return 1;
}
-# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
-# $_[1]: Address
+# $_[0]: Chip to detect (0 = LM75, 1 = DS75)
+# $_[1]: A reference to the file descriptor to access this chip.
+# $_[2]: Address (unused)
# Returns: undef if not detected, 3 or 6 if detected;
# 6 means that the temperatures make sense;
# 3 means that the temperatures look strange;
@@ -3275,52 +3365,45 @@ sub lm78_alias_detect
# real registers and will always return the last returned value. This isn't
# documented.
# Note that register 0x00 may change, so we can't use the modulo trick on it.
+# The DS75 is a bit different, it doesn't cycle over 8-byte boundaries, and
+# all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for
+# the LM75.
sub lm75_detect
{
my $i;
- my ($file,$addr) = @_;
+ my ($chip, $file, $addr) = @_;
my $cur = i2c_smbus_read_word_data($file,0x00);
- my $cur_varies = 0;
my $conf = i2c_smbus_read_byte_data($file,0x01);
my $hyst = i2c_smbus_read_word_data($file,0x02);
- return if i2c_smbus_read_word_data($file,0x04) != $hyst;
- return if i2c_smbus_read_word_data($file,0x05) != $hyst;
- return if i2c_smbus_read_word_data($file,0x06) != $hyst;
- return if i2c_smbus_read_word_data($file,0x07) != $hyst;
+ my $maxreg = $chip == 1 ? 0x0f : 0x07;
+ for $i (0x04 .. $maxreg) {
+ return if i2c_smbus_read_word_data($file, $i) != $hyst;
+ }
my $os = i2c_smbus_read_word_data($file,0x03);
- return if i2c_smbus_read_word_data($file,0x04) != $os;
- return if i2c_smbus_read_word_data($file,0x05) != $os;
- return if i2c_smbus_read_word_data($file,0x06) != $os;
- return if i2c_smbus_read_word_data($file,0x07) != $os;
+ for $i (0x04 .. $maxreg) {
+ return if i2c_smbus_read_word_data($file, $i) != $os;
+ }
- for ($i = 0x00; $i < 0xff; $i += 8) {
- return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
- return if i2c_smbus_read_word_data($file, $i + 0x02) != $hyst;
- return if i2c_smbus_read_word_data($file, $i + 0x04) != $hyst;
- return if i2c_smbus_read_word_data($file, $i + 0x05) != $hyst;
- return if i2c_smbus_read_word_data($file, $i + 0x06) != $hyst;
- return if i2c_smbus_read_word_data($file, $i + 0x07) != $hyst;
- return if i2c_smbus_read_word_data($file, $i + 0x03) != $os;
- return if i2c_smbus_read_word_data($file, $i + 0x04) != $os;
- return if i2c_smbus_read_word_data($file, $i + 0x05) != $os;
- return if i2c_smbus_read_word_data($file, $i + 0x06) != $os;
- return if i2c_smbus_read_word_data($file, $i + 0x07) != $os;
- $cur_varies = 1
- if (! $cur_varies) and
- i2c_smbus_read_word_data($file, $i) != $cur;
+ if ($chip == 0) {
+ for ($i = 8; $i <= 248; $i += 40) {
+ return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf
+ or i2c_smbus_read_word_data($file, $i + 0x02) != $hyst
+ or i2c_smbus_read_word_data($file, $i + 0x03) != $os;
+ }
}
# All registers hold the same value, obviously a misdetection
- return if (! $cur_varies) and $conf == ($cur & 0xff) and $cur == $hyst
+ return if $conf == ($cur & 0xff) and $cur == $hyst
and $cur == $os;
$cur = swap_bytes($cur);
$hyst = swap_bytes($hyst);
$os = swap_bytes($os);
# Unused bits
- return if ($conf & 0xe0);
+ return if $chip == 0 and ($conf & 0xe0);
+ return if $chip == 1 and ($conf & 0x80);
$cur = $cur >> 8;
$hyst = $hyst >> 8;
@@ -3332,7 +3415,6 @@ sub lm75_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 3 or 6 if detected;
# 6 means that the temperatures make sense;
@@ -3356,7 +3438,6 @@ sub lm77_detect
my $i;
my ($file,$addr) = @_;
my $cur = i2c_smbus_read_word_data($file,0x00);
- my $cur_varies = 0;
my $conf = i2c_smbus_read_byte_data($file,0x01);
my $hyst = i2c_smbus_read_word_data($file,0x02);
my $os = i2c_smbus_read_word_data($file,0x03);
@@ -3369,23 +3450,16 @@ sub lm77_detect
return if i2c_smbus_read_word_data($file,0x06) != $high;
return if i2c_smbus_read_word_data($file,0x07) != $high;
- for ($i = 0x00; $i < 0xff; $i += 8) {
+ for ($i = 8; $i <= 248; $i += 40) {
return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
return if i2c_smbus_read_word_data($file, $i + 0x02) != $hyst;
return if i2c_smbus_read_word_data($file, $i + 0x03) != $os;
return if i2c_smbus_read_word_data($file, $i + 0x04) != $low;
- return if i2c_smbus_read_word_data($file, $i + 0x06) != $low;
- return if i2c_smbus_read_word_data($file, $i + 0x07) != $low;
return if i2c_smbus_read_word_data($file, $i + 0x05) != $high;
- return if i2c_smbus_read_word_data($file, $i + 0x06) != $high;
- return if i2c_smbus_read_word_data($file, $i + 0x07) != $high;
- $cur_varies = 1
- if (! $cur_varies) and
- i2c_smbus_read_word_data($file, $i) != $cur;
}
# All registers hold the same value, obviously a misdetection
- return if (! $cur_varies) and $conf == ($cur & 0xff) and $cur == $hyst
+ return if $conf == ($cur & 0xff) and $cur == $hyst
and $cur == $os and $cur == $low and $cur == $high;
$cur = swap_bytes($cur);
@@ -3415,7 +3489,6 @@ sub lm77_detect
# $_[0]: Chip to detect (0 = LM92, 1 = LM76, 2 = MAX6633/MAX6634/MAX6635)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 2 or 4 if detected;
# Registers used:
@@ -3465,7 +3538,6 @@ sub lm92_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 3 if detected
# Registers used:
@@ -3492,7 +3564,6 @@ sub ds1621_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 1 to 3 if detected.
# Registers used:
@@ -3555,7 +3626,6 @@ sub lm80_detect
# $_[0]: Chip to detect
# (0 = LM82/LM83)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 4 to 8 if detected.
# Registers used:
@@ -3597,7 +3667,6 @@ sub lm83_detect
# (0 = LM90, 1=LM89/LM99, 2=LM86, 3=ADM1032, 4=MAX6657/MAX6658/MAX6659,
# 5 = ADT7461, 6 = MAX6648/MAX6692)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 4, 6 or 8 if detected.
# The Maxim chips have a low confidence value (4)
@@ -3670,7 +3739,6 @@ sub lm90_detect
# $_[0]: Chip to detect
# (1 = LM63, 2 = F75363SG)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address (unused)
# Returns: undef if not detected, 8 if detected.
# Registers used:
@@ -3751,7 +3819,6 @@ sub adm1029_detect
# $_[0]: Chip to detect
# (0 = ADM1030, 1=ADM1031)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 3 to 7 (ADM1031) or 9 (ADM1030)
# if detected.
@@ -3837,7 +3904,6 @@ sub adm1034_detect
# (0 = ADT7467/ADT7468, 1 = ADT7476, 2 = ADT7462, 3 = ADT7466,
# 4 = ADT7470)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 5 or 7 if detected.
# Registers used:
@@ -4005,7 +4071,6 @@ sub lm85_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (7) if detected.
# Registers used: 0x3E, 0x3F
@@ -4023,7 +4088,6 @@ sub lm87_detect
# 5 = AS99127F (rev.2), 6 = ASB100, 7 = W83791D,
# 8 = W83792D, 9 = W83627EHF 10 = W83627DHG)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (8,addr1,addr2) if detected, but only
# if the LM75 chip emulation is enabled.
@@ -4122,7 +4186,6 @@ sub w83793_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 3 if detected
# Registers used:
@@ -4196,7 +4259,7 @@ sub w83781d_alias_detect
return 1;
}
-# $_[0]: Chip to detect (0 = W83781D, 1 = W83782D, 3 = W83627HF)
+# $_[0]: Chip to detect (0 = W83781D, 1 = W83782D)
# $_[1]: Address
# Returns: undef if not detected, (8) if detected.
sub w83781d_isa_detect
@@ -4207,8 +4270,8 @@ sub w83781d_isa_detect
return if inb ($addr + 2) != $val or inb ($addr + 3) != $val or
inb ($addr + 7) != $val;
- $val = inb($addr + 5) & 0x7f;
- outb($addr+5, ~$val & 0xff);
+ $val = inb($addr + 5);
+ outb($addr+5, ~$val & 0x7f);
if ((inb ($addr+5) & 0x7f) != (~ $val & 0x7f)) {
outb($addr+5,$val);
return;
@@ -4223,14 +4286,12 @@ sub w83781d_isa_detect
$reg1 = &$read_proc(0x58);
return if $chip == 0 and ($reg1 & 0xfe) != 0x10;
return if $chip == 1 and ($reg1 & 0xfe) != 0x30;
- return if $chip == 3 and ($reg1 & 0xfe) != 0x20;
return 8;
}
# $_[0]: Chip to detect (0 = Revision 0x00, 1 = Revision 0x80)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (6) if detected.
# Registers used:
@@ -4251,7 +4312,6 @@ sub gl518sm_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (5) if detected.
# Registers used:
@@ -4270,7 +4330,6 @@ sub gl520sm_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (5) if detected.
# Registers used:
@@ -4285,7 +4344,6 @@ sub gl525sm_detect
# $_[0]: Chip to detect (0 = ADM9240, 1 = DS1780, 2 = LM81)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (7) if detected.
# Registers used:
@@ -4309,7 +4367,6 @@ sub adm9240_detect
# $_[0]: Chip to detect (0 = ADM1022, 1 = THMC50, 2 = ADM1028)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4326,16 +4383,15 @@ sub adm1022_detect
($chip == 1 and $reg == 0x49) or
($chip == 2 and $reg == 0x41);
return unless (i2c_smbus_read_byte_data($file,0x40) & 0x80) == 0x00;
- $reg = i2c_smbus_read_byte_data($file, 0x3f);
- return unless ($reg & 0xc0) == 0xc0;
- return if $chip == 0 and ($reg & 0xc0) != 0xc0;
- return if $chip == 2 and ($reg & 0xc0) == 0xc0;
+ $reg = i2c_smbus_read_byte_data($file, 0x3f) & 0xf0;
+ return unless ($chip == 0 and $reg == 0xc0) or
+ ($chip == 1 and $reg == 0xc0) or
+ ($chip == 2 and $reg == 0xd0);
return (8);
}
# $_[0]: Chip to detect (0 = ADM1025, 1 = NE1619)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4364,7 +4420,6 @@ sub adm1025_detect
# $_[0]: Chip to detect (0 = ADM1026)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4382,7 +4437,6 @@ sub adm1026_detect
# $_[0]: Chip to detect (0 = ADM1024)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4404,7 +4458,6 @@ sub adm1024_detect
# (0 = ADM1021, 1 = ADM1021A/ADM1023, 2 = MAX1617, 3 = MAX1617A, 4 = THMC10,
# 5 = LM84, 6 = GL523, 7 = MC1066)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 3 if simply detected, 5 if detected and
# manufacturer ID matches, 7 if detected and manufacturer ID and
@@ -4489,7 +4542,7 @@ sub adm1021_detect
}
# $_[0]: Chip to detect
-# (0 = MAX1619)
+# (0 = MAX1668, 1 = MAX1805, 2 = MAX1989)
# $_[1]: A reference to the file descriptor to access this chip.
# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
@@ -4497,6 +4550,28 @@ sub adm1021_detect
# Registers used:
# 0xfe: Company ID
# 0xff: Device ID
+sub max1668_detect
+{
+ my ($chip, $file, $addr) = @_;
+ my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
+ my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
+
+ return if $man_id != 0x4d;
+ return if $chip == 0 and $dev_id != 0x03;
+ return if $chip == 1 and $dev_id != 0x05;
+ return if $chip == 2 and $dev_id != 0x0b;
+
+ return 7;
+}
+
+# $_[0]: Chip to detect
+# (0 = MAX1619)
+# $_[1]: A reference to the file descriptor to access this chip.
+# $_[2]: Address
+# Returns: undef if not detected, 7 if detected
+# Registers used:
+# 0xfe: Company ID
+# 0xff: Device ID
# 0x02: Status
# 0x03: Configuration
# 0x04: Conversion rate
@@ -4540,7 +4615,6 @@ sub ite_overclock_detect
# $_[0]: Chip to detect (0 = IT8712F)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 7 or 8 if detected (tops LM78).
# Registers used:
@@ -4578,13 +4652,11 @@ sub ite_alias_detect
return 1;
}
-# $_[0]: Chip to detect (0 = SPD EEPROM, 1 = Sony Vaio EEPROM,
-# 2 = SPD EEPROM with Software Write Protect)
+# $_[0]: Chip to detect (0 = SPD EEPROM, 1 = Sony Vaio EEPROM)
# $_[1]: A reference to the file descriptor to access this chip
# $_[2]: Address
-# Returns: 8 for a memory eeprom (9 if write-protect register found),
-# 4 to 9 for a Sony Vaio eeprom,
-# 1 for an unknown eeprom (2 if write-protect register found)
+# Returns: 8 for a memory eeprom
+# 4 to 9 for a Sony Vaio eeprom
# Registers used:
# 0-63: SPD Data and Checksum
# 0x80-0x83: Sony Vaio Data ("PCG-")
@@ -4598,34 +4670,14 @@ sub eeprom_detect
my $checksum = 0;
# Check the checksum for validity (works for most DIMMs and RIMMs)
- if ($chip != 1) {
- for (my $i = 0; $i <= 62; $i ++) {
- $checksum += i2c_smbus_read_byte_data($file,$i);
- }
- $checksum &= 255;
- $checksum -= i2c_smbus_read_byte_data($file,63);
- }
if ($chip == 0) {
- if($checksum == 0) {
- return 8;
- } else {
- return 1;
+ for (my $i = 0; $i <= 62; $i++) {
+ $checksum += i2c_smbus_read_byte_data($file, $i);
}
- }
- if ($chip == 2) {
- # check for 'shadow' write-protect register at 0x30-0x37
- # could be dangerous
- i2c_set_slave_addr($file,$addr - 0x20);
- if(i2c_smbus_write_quick($file, SMBUS_WRITE) >= 0 &&
- i2c_smbus_read_byte_data($file,0x80) == -1) {
- i2c_set_slave_addr($file,$addr);
- if($checksum == 0) {
- return (9, $addr - 0x20);
- } else {
- return (2, $addr - 0x20);
- }
- }
- i2c_set_slave_addr($file,$addr);
+ $checksum &= 255;
+
+ return 8
+ if $checksum == i2c_smbus_read_byte_data($file, 63);
return;
}
@@ -4656,17 +4708,13 @@ sub eeprom_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
-# Returns: undef if not detected, (1) if detected.
+# Returns: undef if not detected, 8 if detected.
# Registers used:
# 0x00..0x07: DDC signature
-# 0x08..0x7E: checksumed area
-# 0x7F: checksum
sub ddcmonitor_detect
{
my ($file,$addr) = @_;
- my $i;
return unless
i2c_smbus_read_byte_data($file,0x00) == 0x00 and
@@ -4678,21 +4726,10 @@ sub ddcmonitor_detect
i2c_smbus_read_byte_data($file,0x06) == 0xFF and
i2c_smbus_read_byte_data($file,0x07) == 0x00;
- # Check the checksum for validity.
- my $checksum = 0;
- for ($i = 0; $i <= 127; $i = $i + 1) {
- $checksum = $checksum + i2c_smbus_read_byte_data($file,$i);
- }
- $checksum=$checksum & 255;
- if ($checksum != 0) {
- # I have one such monitor...
- return (2,$addr+1,$addr+2,$addr+3,$addr+4,$addr+5,$addr+6,$addr+7);
- }
return (8,$addr+1,$addr+2,$addr+3,$addr+4,$addr+5,$addr+6,$addr+7);
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4714,7 +4751,6 @@ sub fscpos_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4736,7 +4772,6 @@ sub fscscy_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (8) if detected.
# Registers used:
@@ -4758,7 +4793,6 @@ sub fscher_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[1]: Address (unused)
# Returns: undef if not detected, 5 if detected.
# Registers used:
@@ -4773,7 +4807,6 @@ sub lm93_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, (7) if detected.
# Registers used:
@@ -4803,7 +4836,6 @@ sub m5879_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 5 or 6 if detected.
# Registers used:
@@ -4822,23 +4854,20 @@ sub smsc47m192_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 5 or 6 if detected.
# Registers used:
# 0x3E: Manufacturer ID
# 0x3F: Version/Stepping
-# 0x40: Configuration (2 reserved bits)
-# 0x42: Interrupt Status 2 (1 reserved bit)
-# 0x43: VID (2 reserved bits)
+# 0x73: Read-only test register (4 test bits)
+# 0x8A: Read-only test register (7 test bits)
sub dme1737_detect
{
my ($file, $addr) = @_;
- return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x55
+ return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x5c
and (i2c_smbus_read_byte_data($file, 0x3F) & 0xF8) == 0x88
- and (i2c_smbus_read_byte_data($file, 0x40) & 0xC4) == 0x04
- and (i2c_smbus_read_byte_data($file, 0x42) & 0x02) == 0x00
- and (i2c_smbus_read_byte_data($file, 0x43) & 0xC0) == 0x00;
+ and (i2c_smbus_read_byte_data($file, 0x73) & 0x0F) == 0x09
+ and (i2c_smbus_read_byte_data($file, 0x8A) & 0x7F) == 0x4D;
return ($addr == 0x2e ? 6 : 5);
}
@@ -4847,7 +4876,6 @@ sub dme1737_detect
# 4 = F75375S/SP, 5 = F75387SG/RG, 6 = F75383M/S/F75384M/S,
# 7 = custom power control IC)
# $_[1]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[2]: Address (unused)
# Returns: undef if not detected, 7 if detected.
# Registers used:
@@ -4884,7 +4912,6 @@ sub fintek_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 4 or 7 if detected
# Detection is based on the fact that the SAA1064 has only one readable
@@ -4907,7 +4934,6 @@ sub saa1064_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 1 if detected
# Detection is rather difficult, since the PCA9540 has a single register.
@@ -4926,7 +4952,6 @@ sub pca9540_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We assume an i2c_set_slave_addr was already done.
# $_[1]: Address (unused)
# Returns: undef if not detected, 1 if detected
# Detection is rather difficult, since the PCA9556 only has 4 registers
@@ -4955,7 +4980,6 @@ sub pca9556_detect
}
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: undef if not detected, 3 if detected
sub max6900_detect
@@ -5021,23 +5045,10 @@ sub max6900_detect
return 3;
}
-# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
-# $_[1]: Address
-# Returns: 1
-# This is a placeholder so we get a report if any device responds
-# to the SMBus Device Default Address (0x61), which is used for
-# ARP in SMBus 2.0.
-sub arp_detect
-{
- return (1);
-}
-
# This checks for non-FFFF values for SpecInfo and Status.
# The address (0x09) is specified by the SMBus standard so it's likely
# that this really is a smart battery charger.
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: 5
sub smartbatt_chgr_detect
@@ -5057,7 +5068,6 @@ sub smartbatt_chgr_detect
# The address (0x0a) is specified by the SMBus standard so it's likely
# that this really is a smart battery manager/selector.
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: 5
sub smartbatt_mgr_detect
@@ -5077,7 +5087,6 @@ sub smartbatt_mgr_detect
# The address (0x0b) is specified by the SMBus standard so it's likely
# that this really is a smart battery.
# $_[0]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[1]: Address
# Returns: 5
sub smartbatt_detect
@@ -5152,7 +5161,6 @@ sub w83l784r_detect
# $_[0]: Chip to detect (0 = W83L785TS-S)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 8 if detected
# Registers used:
@@ -5171,7 +5179,6 @@ sub w83l785ts_detect
# $_[0]: Chip to detect. Always zero for now, but available for future use
# if somebody finds a way to distinguish MAX6650 and MAX6651.
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
# Returns: undef if not detected, 4 if detected.
#
@@ -5203,9 +5210,30 @@ sub max6650_detect
return 4;
}
+# $_[0]: Chip to detect. Always zero.
+# $_[1]: A reference to the file descriptor to access this chip.
+# $_[2]: Address.
+#
+# Returns: undef if not detected, 6 if detected.
+sub max6655_detect
+{
+ my ($chip, $file, $addr) = @_;
+
+ # checking RDID (Device ID)
+ return unless i2c_smbus_read_byte_data($file, 0xfe) == 0x0a;
+ # checking RDRV (Manufacturer ID)
+ return unless i2c_smbus_read_byte_data($file, 0xff) == 0x4d;
+ # checking unused bits (conversion rate, extended temperature)
+ return unless i2c_smbus_read_byte_data($file, 0x04) & 0xf8;
+ return unless i2c_smbus_read_byte_data($file, 0x10) & 0x1f;
+ return unless i2c_smbus_read_byte_data($file, 0x11) & 0x1f;
+ return unless i2c_smbus_read_byte_data($file, 0x12) & 0x1f;
+
+ return 6;
+}
+
# $_[0]: Chip to detect (0 = VT1211)
# $_[1]: A reference to the file descriptor to access this chip.
-# We may assume an i2c_set_slave_addr was already done.
# $_[2]: Address
#
# This isn't very good detection.
@@ -5581,6 +5609,7 @@ sub main
# Before looking for chips, make sure any special case chips are
# added to the chip_ids list
chip_special_cases();
+ $i2c_addresses_to_scan = i2c_addresses_to_scan();
print "We are now going to do the I2C/SMBus adapter probings. Some chips may\n",
"be double detected; we choose the one with the highest confidence\n",
@@ -5641,9 +5670,11 @@ sub main
print "Some CPUs or memory controllers may also contain embedded sensors.\n";
print "Do you want to scan for them? (YES/no): ";
unless ( =~ /^\s*n/i) {
+ $| = 1;
foreach my $entry (@cpu_ids) {
scan_cpu($entry);
}
+ $| = 0;
}
print "\n";
diff --git a/prog/dump/i2cdump.c b/prog/dump/i2cdump.c
index e46943c2..ddcb65cd 100644
--- a/prog/dump/i2cdump.c
+++ b/prog/dump/i2cdump.c
@@ -57,7 +57,7 @@ int main(int argc, char *argv[])
int bank = 0, bankreg = 0x4E, old_bank = 0;
char filename[20];
unsigned long funcs;
- int block[256];
+ int block[256], s_length = 0;
int pec = 0, even = 0;
int flags = 0;
int yes = 0, version = 0;
@@ -310,6 +310,9 @@ int main(int argc, char *argv[])
if (size == I2C_SMBUS_BLOCK_DATA) {
res = i2c_smbus_read_block_data(file, bank,
cblock);
+ /* Remember returned block length for a nicer
+ display later */
+ s_length = res;
} else {
for (res = 0; res < 256; res += i) {
i = i2c_smbus_read_i2c_block_data(file,
@@ -327,8 +330,9 @@ int main(int argc, char *argv[])
res = 256;
for (i = 0; i < res; i++)
block[i] = cblock[i];
- for (i = res; i < 256; i++)
- block[i] = -1;
+ if (size != I2C_SMBUS_BLOCK_DATA)
+ for (i = res; i < 256; i++)
+ block[i] = -1;
}
if (size == I2C_SMBUS_BYTE) {
@@ -343,8 +347,11 @@ int main(int argc, char *argv[])
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f"
" 0123456789abcdef\n");
for (i = 0; i < 256; i+=16) {
+ if (size == I2C_SMBUS_BLOCK_DATA && i >= s_length)
+ break;
printf("%02x: ", i);
for (j = 0; j < 16; j++) {
+ fflush(stdout);
if (size == I2C_SMBUS_BYTE_DATA) {
block[i+j] = res =
i2c_smbus_read_byte_data(file, i+j);
@@ -364,7 +371,10 @@ int main(int argc, char *argv[])
} else
res = block[i+j];
- if (res < 0) {
+ if (size == I2C_SMBUS_BLOCK_DATA
+ && i+j >= s_length) {
+ printf(" ");
+ } else if (res < 0) {
printf("XX ");
if (size == I2C_SMBUS_WORD_DATA)
printf("XX ");
@@ -377,7 +387,12 @@ int main(int argc, char *argv[])
j++;
}
printf(" ");
+
for (j = 0; j < 16; j++) {
+ if (size == I2C_SMBUS_BLOCK_DATA
+ && i+j >= s_length)
+ break;
+
res = block[i+j];
if (res < 0)
printf("X");
@@ -393,8 +408,6 @@ int main(int argc, char *argv[])
printf("%c", res & 0xff);
}
printf("\n");
- if (size == I2C_SMBUS_BLOCK_DATA && i == 16)
- break;
}
} else {
printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n");
diff --git a/prog/dump/isadump.c b/prog/dump/isadump.c
index 7a89abe6..5031e783 100644
--- a/prog/dump/isadump.c
+++ b/prog/dump/isadump.c
@@ -47,16 +47,6 @@
unsigned long isa_io_base = 0; /* XXX for now */
#endif /* __powerpc__ */
-char hexchar(int i)
-{
- if ((i >= 0) && (i <= 9))
- return '0' + i;
- else if (i <= 15)
- return 'a' - 10 + i;
- else
- return 'X';
-}
-
void help(void)
{
fprintf(stderr,
@@ -298,13 +288,18 @@ int main(int argc, char *argv[])
superio_write_key(addrreg, enter_key);
for (j = 0; j < 16; j++) {
+ fflush(stdout);
if (flat) {
res = inb(addrreg + i + j);
} else {
outb(i+j, addrreg);
+ if (i+j == 0 && (inb(addrreg) & 0x80)) {
+ /* Bit 7 appears to be a busy flag */
+ range = 128;
+ }
res = inb(datareg);
}
- printf("%c%c ", hexchar(res/16), hexchar(res%16));
+ printf("%02x ", res);
}
printf("\n");
}
diff --git a/prog/pwm/fancontrol.pl b/prog/pwm/fancontrol.pl
index 83c2a920..cb7327bc 100755
--- a/prog/pwm/fancontrol.pl
+++ b/prog/pwm/fancontrol.pl
@@ -234,7 +234,7 @@ sub pwmdisable($)
else
{ die("$dir/$p : $!"); }
- my $enable = "$dir/$p/pwm/pwm_enable";
+ my $enable = "$dir/${p}_enable";
if (-f $enable)
{
if (open(F, ">$enable"))
@@ -243,7 +243,7 @@ sub pwmdisable($)
close(F);
}
else
- { die("$dir/$p/pwm/pwm_enable : $!"); }
+ { die("$enable : $!"); }
}
}
else
@@ -267,7 +267,7 @@ sub pwmenable($)
if ($sysfs == 1)
{
- my $enable = "$dir/$p/pwm/pwm_enable";
+ my $enable = "$dir/${p}_enable";
if (-f $enable)
{
if (open(F, ">$enable"))
@@ -276,7 +276,7 @@ sub pwmenable($)
close(F);
}
else
- { die("$dir/$p : $!\n"); }
+ { die("$enable : $!\n"); }
}
}
else
diff --git a/prog/sensors/chips.c b/prog/sensors/chips.c
index 09ca593f..9f3eefdb 100644
--- a/prog/sensors/chips.c
+++ b/prog/sensors/chips.c
@@ -2896,7 +2896,7 @@ void print_w83627ehf(const sensors_chip_name *name)
{
char *label;
int i, valid, num_in;
- double cur, min, div, max, alarm, over, hyst;
+ double cur, min, fdiv, max, alarm, over, hyst;
if (!strcmp(name->prefix, "w83627dhg"))
num_in = 9;
@@ -2929,8 +2929,8 @@ void print_w83627ehf(const sensors_chip_name *name)
if (valid) {
print_label(label,10);
printf("%4.0f RPM (min = %4.0f RPM", cur, min);
- if (!sensors_get_feature(*name, SENSORS_W83627EHF_FAN1_DIV+i, &div))
- printf(", div = %1.0f", div);
+ if (!sensors_get_feature(*name, SENSORS_W83627EHF_FAN1_DIV+i, &fdiv))
+ printf(", div = %1.0f", fdiv);
printf(")");
if (!sensors_get_feature(*name, SENSORS_W83627EHF_FAN1_ALARM+i,
&alarm) && alarm)
@@ -3216,417 +3216,6 @@ void print_maxilife(const sensors_chip_name *name)
free(label);
}
-void print_ddcmon(const sensors_chip_name *name)
-{
- char *label;
- double a, b, c;
- int valid, i;
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_MAN_ID, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_MAN_ID, &a)) {
- if (valid) {
- i = (int) a;
- print_label(label, 24);
- printf("%c%c%c\n",
- ((i >> 10) & 0x1f) + 'A' - 1, ((i >> 5) & 0x1f) + 'A' - 1,
- (i & 0x1f) + 'A' - 1);
- }
- } else
- printf("ERROR: data 1\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_PROD_ID, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_PROD_ID, &a)) {
- if (valid) {
- i = (int) a;
- print_label(label, 24);
- printf("0x%04X\n", i);
- }
- } else
- printf("ERROR: data 2\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_SERIAL, &label,&valid) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_SERIAL, &a)) {
- if (valid) {
- print_label(label, 24);
- printf("%d\n", (int) a);
- }
- } else
- printf("ERROR: data 3\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_YEAR, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_YEAR, &a)
- && !sensors_get_feature(*name, SENSORS_DDCMON_WEEK, &b)) {
- if (valid) {
- print_label(label, 24);
- printf("%d-W%d\n", (int) a, (int) b);
- }
- } else
- printf("ERROR: data 4\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_EDID_VER, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_EDID_VER, &a)
- && !sensors_get_feature(*name, SENSORS_DDCMON_EDID_REV, &b)) {
- if (valid) {
- print_label(label, 24);
- printf("%d.%d\n", (int) a, (int) b);
- }
- } else
- printf("ERROR: data 5\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_VERSIZE, &label,&valid) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_VERSIZE, &a) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_HORSIZE, &b)) {
- if (valid) {
- print_label(label, 24);
- printf("%dx%d\n", (int) a, (int) b);
- }
- } else
- printf("ERROR: data 6\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_GAMMA, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_GAMMA, &a)) {
- if (valid) {
- print_label(label, 24);
- printf("%.02f\n", a);
- }
- } else
- printf("ERROR: data 7\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_DPMS, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_DPMS, &a)) {
- if (valid) {
- i = (int) a;
- print_label(label, 24);
- if (i & 0xe0) {
- printf("%s%s%s%s%s\n",
- i & 0x20 ? "Active Off" : "",
- (i & 0x40) && (i & 0x20) ? ", ": "",
- i & 0x40 ? "Suspend" : "",
- (i & 0x80) && (i & 0x60) ? ", ": "",
- i & 0x80 ? "Standby" : "");
- } else {
- printf("None supported\n");
- }
- }
- } else
- printf("ERROR: data 8\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_TIMINGS, &label,&valid) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_TIMINGS, &a)) {
- if (valid) {
- i = (int) a;
- if (i & 0x03) { /* 720x400 */
- print_label(label, 24);
- printf("720x400 @ %s%s%s Hz\n",
- i & 0x01 ? "70" : "",
- (i & 0x02) && (i & 0x01) ? "/" : "",
- i & 0x02 ? "88" : "");
- }
- if (i & 0x3c) { /* 640x480 */
- print_label(label, 24);
- printf("640x480 @ %s%s%s%s%s%s%s Hz\n",
- i & 0x04 ? "60" : "",
- (i & 0x08) && (i & 0x04) ? "/" : "",
- i & 0x08 ? "67" : "",
- (i & 0x10) && (i & 0x0c) ? "/" : "",
- i & 0x10 ? "72" : "",
- (i & 0x20) && (i & 0x1c) ? "/" : "",
- i & 0x20 ? "75" : "");
- }
- i >>= 6;
- if (i & 0x0f) { /* 800x600 */
- print_label(label, 24);
- printf("800x600 @ %s%s%s%s%s%s%s Hz\n",
- i & 0x01 ? "56" : "",
- (i & 0x02) && (i & 0x01) ? "/" : "",
- i & 0x02 ? "60" : "",
- (i & 0x04) && (i & 0x03) ? "/" : "",
- i & 0x04 ? "72" : "",
- (i & 0x08) && (i & 0x07) ? "/" : "",
- i & 0x08 ? "75" : "");
- }
- if (i & 0x10) { /* 832x624 */
- print_label(label, 24);
- printf("832x624 @ 75 Hz\n");
- }
- i >>= 5;
- if (i & 0x0f) { /* 1024x768 */
- print_label(label, 24);
- printf("1024x768 @ %s%s%s%s%s%s%s Hz\n",
- i & 0x01 ? "87i" : "",
- (i & 0x02) && (i & 0x01) ? "/" : "",
- i & 0x02 ? "60" : "",
- (i & 0x04) && (i & 0x03) ? "/" : "",
- i & 0x04 ? "70" : "",
- (i & 0x08) && (i & 0x07) ? "/" : "",
- i & 0x08 ? "75" : "");
- }
- if (i & 0x100) { /* 1152x870 */
- print_label(label, 24);
- printf("1152x870 @ 75 Hz\n");
- }
- if (i & 0x10) { /* 1280x1024 */
- print_label(label, 24);
- printf("1280x1024 @ 75 Hz\n");
- }
- }
- } else
- printf("ERROR: data 9\n");
- free(label);
-
- for(i = 0; i < 8; i++) {
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_TIMING1_HOR + i * 3, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_TIMING1_HOR + i * 3, &a)
- && !sensors_get_feature(*name, SENSORS_DDCMON_TIMING1_VER + i * 3, &b)
- && !sensors_get_feature(*name, SENSORS_DDCMON_TIMING1_REF + i * 3, &c)) {
- if (valid && ((int) a) != 0) {
- print_label(label, 24);
- printf("%dx%d @ %d Hz\n", (int) a, (int) b, (int) c);
- }
- } else
- printf("ERROR: data 10-%d\n", i+1);
- free(label);
- }
-
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_VERSYNCMIN, &label,&valid) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_VERSYNCMIN, &a) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_VERSYNCMAX, &b)) {
- if (valid && ((int) a) != 0) {
- print_label(label, 24);
- printf("%d-%d\n", (int) a, (int) b);
- }
- } else
- printf("ERROR: data 11\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_HORSYNCMIN, &label,&valid) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_HORSYNCMIN, &a) &&
- !sensors_get_feature(*name, SENSORS_DDCMON_HORSYNCMAX, &b)) {
- if (valid && ((int) a) != 0) {
- print_label(label, 24);
- printf("%d-%d\n", (int) a, (int) b);
- }
- } else
- printf("ERROR: data 12\n");
- free(label);
-
- if (!sensors_get_label_and_valid(*name, SENSORS_DDCMON_MAXCLOCK, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_DDCMON_MAXCLOCK, &a)) {
- if (valid && ((int) a) != 0) {
- print_label(label, 24);
- printf("%d\n", (int) a);
- }
- } else
- printf("ERROR: data 13\n");
- free(label);
-
- printf("Note that the ddcmon driver is deprecated and will be deleted soon.\n");
- printf("Please use the eeprom driver and the ddcmon and/or decode-edid.pl\n"
- "scripts instead.\n");
-}
-
-/*
- * (Khali, 2003-07-17) Almost entierly rewritten. Reindented for clarity,
- * simplified at some places, added support for EDID EEPROMs (well,
- * redirection more than support).
- * (Khali, 2003-08-09) Rewrote Sony Vaio EEPROMs detection, and move it
- * to the top. This should prevent such EEPROMs from being accidentally
- * detected as valid memory modules.
- * (Khali, 2004-02-23) Add support for Shuttle EEPROMs, which contain
- * MAC ethernet addresses.
- */
-void print_eeprom(const sensors_chip_name *name)
-{
- char *label;
- double a, b, c, d;
- int valid, i, type;
-
- /* handle Sony Vaio EEPROMs first */
- if (name->addr == 0x57) {
- char buffer[33];
-
- /* first make sure it is a Sony Vaio EEPROM */
- if (!sensors_get_label_and_valid(*name, SENSORS_EEPROM_VAIO_NAME, &label, &valid)
- && valid) {
- for (i = 0; i < 4; i++)
- if (!sensors_get_feature(*name, SENSORS_EEPROM_VAIO_NAME+i, &a))
- buffer[i] = (char) a;
- if (strncmp(buffer, "PCG-", 4) == 0
- || strncmp(buffer, "VGN-", 4) == 0) {
- /* must be a real Sony Vaio EEPROM */
- memset(buffer + 4, '\0', 29);
- for (a = 1; i < 32 && a != 0; i++) /* stop at first zero */
- if (!sensors_get_feature(*name, SENSORS_EEPROM_VAIO_NAME+i, &a)
- && a != 0)
- buffer[i] = (char) a;
- print_label(label, 24);
- printf("%s\n", buffer);
- free(label);
-
- memset(buffer, '\0', i);
- if (!sensors_get_label_and_valid(*name, SENSORS_EEPROM_VAIO_SERIAL, &label, &valid)
- && valid) {
- for (i = 0, a = 1; i < 32 && a != 0; i++) /* stop at first zero */
- if (!sensors_get_feature(*name, SENSORS_EEPROM_VAIO_SERIAL+i, &a)
- && a != 0)
- buffer[i] = (char) a;
- print_label(label, 24);
- printf("%s\n", buffer);
- } else
- printf("ERROR: data Vaio 3\n");
- free(label);
-
- printf("Note that eeprom support will be dropped from "
- "libsensors soon.\nPlease use the decode-vaio.pl "
- "script instead.\n");
- return;
- }
- } else
- printf("ERROR: data Vaio 2\n");
- free(label);
- }
-
- /* then Shuttle EEPROMs */
- if (name->addr == 0x53) {
- unsigned char buffer[6];
-
- /* first make sure it is a Shuttle EEPROM */
- if (!sensors_get_label_and_valid(*name, SENSORS_EEPROM_SHUTTLE, &label, &valid)
- && valid) {
- for (i = 0; i < 3; i++)
- if (!sensors_get_feature(*name, SENSORS_EEPROM_SHUTTLE+i, &a))
- buffer[i] = (unsigned char) a;
- if (buffer[0] == 0x00
- && buffer[1] == 0x30
- && buffer[2] == 0x1b)
- {
- /* must be a real Shuttle EEPROM */
- for (i = 4; i < 6; i++)
- if (!sensors_get_feature(*name, SENSORS_EEPROM_SHUTTLE+i, &a))
- buffer[i] = (unsigned char) a;
-
- print_label(label, 24);
- printf("%02X:%02X:%02X:%02X:%02X:%02X\n", buffer[0],
- buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
- free(label);
-
- return;
- }
- } else
- printf("ERROR: data Shuttle\n");
- free(label);
- }
-
- if (!sensors_get_label_and_valid(*name, SENSORS_EEPROM_TYPE, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_EEPROM_TYPE, &a)) {
- if (valid) {
- type = (int) a;
- switch (type) {
- case 1:
- print_label(label, 24);
- printf("DRDRAM RIMM\n");
- break;
- case 2:
- print_label(label, 24);
- printf("EDO\n");
- break;
- case 4:
- print_label(label, 24);
- printf("SDR SDRAM DIMM\n");
- break;
- case 7:
- print_label(label, 24);
- printf("DDR SDRAM DIMM\n");
- break;
- case 8:
- print_label(label, 24);
- printf("DDR2 SDRAM DIMM\n");
- break;
- case 17:
- print_label(label, 24);
- printf("RAMBUS RIMM\n");
- break;
- case 255: /* EDID EEPROM? */
- break;
- default:
- printf("Unknown EEPROM type (%d)\n", type);
- free(label);
- return;
- }
- } else {
- free(label);
- return;
- }
- } else {
- free(label);
- printf("Memory type: Unavailable\n");
- return;
- }
- free(label);
-
- if (type == 255) { /* EDID EEPROM */
- /* make sure it is an EDID EEPROM */
- if (!sensors_get_feature(*name, SENSORS_EEPROM_ROWADDR, &a)
- && !sensors_get_feature(*name, SENSORS_EEPROM_COLADDR, &b)
- && !sensors_get_feature(*name, SENSORS_EEPROM_NUMROWS, &c)
- && !sensors_get_feature(*name, SENSORS_EEPROM_EDID_HEADER, &d)) {
- if (((int) a) != 255 || ((int) b) != 255 || ((int) c) != 255
- || ((int) d) != 0)
- printf("Unknown EEPROM type (255).\n");
- else if (name->addr == 0x50)
- /* must be an EDID EEPROM */
- printf("Use the ddcmon and/or decode-edid.pl scripts.\n");
- } else
- printf("ERROR: data EDID\n");
- return;
- }
-
- /* regular memory chips */
- if (!sensors_get_label_and_valid(*name, SENSORS_EEPROM_ROWADDR, &label, &valid)
- && !sensors_get_feature(*name, SENSORS_EEPROM_ROWADDR, &a)
- && !sensors_get_feature(*name, SENSORS_EEPROM_COLADDR, &b)
- && !sensors_get_feature(*name, SENSORS_EEPROM_NUMROWS, &c)
- && !sensors_get_feature(*name, SENSORS_EEPROM_BANKS, &d)
- && valid) {
- int k = 0; /* multiplier, 0 if invalid */
- print_label(label, 24);
- if (type == 17) { /* RAMBUS */
- i = (((int) a) & 0x0f) + (((int) a) >> 4) + (((int) c) & 0x07) - 13;
- k = 1;
- } else if (type == 1) { /* DRDRAM */
- i = (((int) b) & 0x0f) + (((int) b) >> 4) + (((int) c) & 0x07) - 13;
- k = 1;
- } else if (type == 8) { /* DDR2 */
- i = (((int) a) & 0x0f) + (((int) b) & 0x0f) - 17;
- k = ((((int) c) & 0x7) + 1) * ((int) d);
- } else { /* SDRAM */
- i = (((int) a) & 0x0f) + (((int) b) & 0x0f) - 17;
- if (((int) c) <= 8 && ((int) d) <= 8)
- k = ((int) c) * ((int) d);
- }
- if(i > 0 && i <= 12 && k > 0)
- printf("%d\n", (1 << i) * k);
- else
- printf("invalid (%d %d %d %d)\n",
- (int) a, (int) b, (int) c, (int) d);
- } else
- printf("ERROR: data 2\n");
- free(label);
-
- printf("Note that eeprom support will be dropped from "
- "libsensors soon.\nPlease use the decode-dimms.pl "
- "script instead.\n");
-}
-
void print_it87(const sensors_chip_name *name)
{
char *label;
@@ -4593,8 +4182,9 @@ void print_vt1211(const sensors_chip_name *name)
void print_smsc47m1(const sensors_chip_name *name)
{
char *label;
- double cur, min, div;
+ double cur, min, fdiv;
int alarms, valid, i;
+ int is_m2 = !strcmp(name->prefix, "smsc47m2");
if (!sensors_get_feature(*name,SENSORS_SMSC47M1_ALARMS,&cur))
alarms = cur + 0.5;
@@ -4603,15 +4193,15 @@ void print_smsc47m1(const sensors_chip_name *name)
alarms = 0;
}
- for (i=0; i<2; i++) { /* 2 fans */
+ for (i = 0; i < (is_m2 ? 3 : 2); i++) { /* 2 or 3 fans */
if (!sensors_get_label_and_valid(*name, SENSORS_SMSC47M1_FAN1+i, &label, &valid)
&& !sensors_get_feature(*name, SENSORS_SMSC47M1_FAN1+i, &cur)
- && !sensors_get_feature(*name, SENSORS_SMSC47M1_FAN1_DIV+i, &div)
+ && !sensors_get_feature(*name, SENSORS_SMSC47M1_FAN1_DIV+i, &fdiv)
&& !sensors_get_feature(*name, SENSORS_SMSC47M1_FAN1_MIN+i, &min)) {
if (valid) {
print_label(label, 10);
printf("%4.0f RPM (min = %4.0f RPM, div = %1.0f) %s\n",
- cur, min, div, alarms&(SMSC47M1_ALARM_FAN1<prefix, 7);
@@ -5558,10 +5148,10 @@ void print_adm1031(const sensors_chip_name *name)
&label, &valid)
&& !sensors_get_feature(*name, SENSORS_ADM1031_FAN1+i*10, &cur)
&& !sensors_get_feature(*name, SENSORS_ADM1031_FAN1_MIN+i*10, &low)
- && !sensors_get_feature(*name, SENSORS_ADM1031_FAN1_DIV+i*10, &div)) {
+ && !sensors_get_feature(*name, SENSORS_ADM1031_FAN1_DIV+i*10, &fdiv)) {
if (valid) {
print_label(label, 10);
- printf("%4.0f RPM (min = %4.0f RPM, div = %1.0f)", cur, low, div);
+ printf("%4.0f RPM (min = %4.0f RPM, div = %1.0f)", cur, low, fdiv);
printf(" %s\n",
alarms&(ADM1031_ALARM_FAN1_FLT<<(i*8))?"FAULT":
alarms&(ADM1031_ALARM_FAN1_MIN<<(i*8))?"ALARM":"");
@@ -5740,7 +5330,7 @@ void print_max6650(const sensors_chip_name *name)
static const struct
{
int tag;
- char *name;
+ const char *name;
}
tach_list[] =
{
@@ -5817,17 +5407,17 @@ static void print_asb100_fan(const sensors_chip_name *name, int alarm,
int fan, int fan_div, int fan_min)
{
char *label;
- double cur, div, min;
+ double cur, fdiv, min;
int valid;
if (!sensors_get_label_and_valid(*name,fan,&label,&valid) &&
!sensors_get_feature(*name,fan,&cur) &&
- !sensors_get_feature(*name,fan_div,&div) &&
+ !sensors_get_feature(*name,fan_div, &fdiv) &&
!sensors_get_feature(*name,fan_min,&min)) {
if (valid) {
print_label(label,10);
printf("%4.0f RPM (min = %4.0f RPM, div = %1.0f) %s\n",
- cur, min, div, alarm ? "ALARM" : "");
+ cur, min, fdiv, alarm ? "ALARM" : "");
}
} else
printf("ERROR: Can't get FAN data! (0x%04x)\n", fan);
@@ -6336,6 +5926,121 @@ void print_coretemp(const sensors_chip_name *name)
free(label);
}
+static void print_dme1737_in(const sensors_chip_name *name, int i)
+{
+ char *label;
+ double cur, min, max, alarm;
+ int valid;
+
+ if (!sensors_get_label_and_valid(*name, SENSORS_DME1737_IN(i), &label,
+ &valid) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_IN(i), &cur) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_IN_MIN(i), &min) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_IN_MAX(i), &max) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_IN_ALARM(i), &alarm)) {
+ if (valid) {
+ print_label(label, 10);
+ printf("%+6.2f V (min = %+6.2f V, max = %+6.2f V) %s\n",
+ cur, min, max, alarm ? "ALARM" : "");
+ }
+ } else {
+ printf("ERROR: Can't get in%d data!\n", i);
+ }
+ free(label);
+}
+
+static void print_dme1737_temp(const sensors_chip_name *name, int i)
+{
+ char *label;
+ double cur, min, max, alarm, fault;
+ int valid;
+
+ if (!sensors_get_label_and_valid(*name, SENSORS_DME1737_TEMP(i), &label,
+ &valid) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_TEMP(i), &cur) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_TEMP_MIN(i), &min) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_TEMP_MAX(i), &max) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_TEMP_ALARM(i), &alarm) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_TEMP_FAULT(i), &fault)) {
+ if (valid) {
+ print_label(label, 10);
+ print_temp_info(cur, max, min, MINMAX, 0, 0);
+ printf("%s %s\n", fault ? "FAULT" : "", alarm ? "ALARM" : "");
+ }
+ } else {
+ printf("ERROR: Can't get temp%d data!\n", i);
+ }
+ free(label);
+}
+
+static void print_dme1737_fan(const sensors_chip_name *name, int i)
+{
+ char *label;
+ double cur, min, alarm;
+ int valid;
+
+ if (!sensors_get_label_and_valid(*name, SENSORS_DME1737_FAN(i), &label,
+ &valid) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_FAN(i), &cur) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_FAN_MIN(i), &min) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_FAN_ALARM(i), &alarm)) {
+ if (valid) {
+ print_label(label, 10);
+ printf("%4.0f RPM (min = %4.0f RPM) %s\n",
+ cur, min, alarm ? "ALARM" : "");
+ }
+ } else {
+ printf("ERROR: Can't get fan%d data!\n", i);
+ }
+ free(label);
+}
+
+static void print_dme1737_pwm(const sensors_chip_name *name, int i)
+{
+ char *label;
+ double cur, enable, freq;
+ int valid;
+
+ if (!sensors_get_label_and_valid(*name, SENSORS_DME1737_PWM(i), &label,
+ &valid) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_PWM(i), &cur) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_PWM_ENABLE(i), &enable) &&
+ !sensors_get_feature(*name, SENSORS_DME1737_PWM_FREQ(i), &freq)) {
+ if (valid) {
+ print_label(label, 10);
+ printf("%4.0f (enable = %1.0f, freq = %6.0f Hz)\n", cur, enable, freq);
+ }
+ } else {
+ printf("ERROR: Can't get pwm%d data!\n", i);
+ }
+ free(label);
+}
+
+void print_dme1737(const sensors_chip_name *name)
+{
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ print_dme1737_in(name, i);
+ }
+
+ for (i = 1; i < 4; i++) {
+ print_dme1737_temp(name, i);
+ }
+
+ for (i = 1; i < 7; i++) {
+ print_dme1737_fan(name, i);
+ }
+
+ for (i = 1; i < 7; i++) {
+ if (i == 4)
+ continue;
+ print_dme1737_pwm(name, i);
+ }
+
+ print_vid_info(name, SENSORS_DME1737_VID, SENSORS_DME1737_VRM);
+}
+
void print_unknown_chip(const sensors_chip_name *name)
{
int a,b,valid;
diff --git a/prog/sensors/chips.h b/prog/sensors/chips.h
index 88341745..d2cac286 100644
--- a/prog/sensors/chips.h
+++ b/prog/sensors/chips.h
@@ -46,8 +46,6 @@ extern void print_w83793(const sensors_chip_name *name);
extern void print_w83l785ts(const sensors_chip_name *name);
extern void print_w83627ehf(const sensors_chip_name *name);
extern void print_maxilife(const sensors_chip_name *name);
-extern void print_ddcmon(const sensors_chip_name *name);
-extern void print_eeprom(const sensors_chip_name *name);
extern void print_lm87(const sensors_chip_name *name);
extern void print_it87(const sensors_chip_name *name);
extern void print_fscpos(const sensors_chip_name *name);
@@ -78,5 +76,6 @@ extern void print_f71805f(const sensors_chip_name *name);
extern void print_abituguru(const sensors_chip_name *name);
extern void print_k8temp(const sensors_chip_name *name);
extern void print_coretemp(const sensors_chip_name *name);
+extern void print_dme1737(const sensors_chip_name *name);
#endif /* def PROG_SENSORS_CHIPS_H */
diff --git a/prog/sensors/main.c b/prog/sensors/main.c
index 15678382..e2fa91b9 100644
--- a/prog/sensors/main.c
+++ b/prog/sensors/main.c
@@ -382,8 +382,6 @@ struct match matches[] = {
{ "it8712", print_it87 },
{ "it8716", print_it87 },
{ "it8718", print_it87 },
- { "ddcmon", print_ddcmon },
- { "eeprom", print_eeprom },
{ "fscpos", print_fscpos },
{ "fscscy", print_fscscy },
{ "fscher", print_fscher },
@@ -391,6 +389,7 @@ struct match matches[] = {
{ "vt1211", print_vt1211 },
{ "smsc47m192", print_smsc47m192 },
{ "smsc47m1", print_smsc47m1 },
+ { "smsc47m2", print_smsc47m1 },
{ "pc87360", print_pc87360 },
{ "pc87363", print_pc87360 },
{ "pc87364", print_pc87364 },
@@ -422,12 +421,12 @@ struct match matches[] = {
{ "abituguru", print_abituguru },
{ "k8temp", print_k8temp },
{ "coretemp", print_coretemp },
+ { "dme1737", print_dme1737 },
{ NULL, NULL }
};
void do_a_print(sensors_chip_name name)
{
- const char *adap;
struct match *m;
/* do we know how to display it? */
@@ -439,11 +438,13 @@ void do_a_print(sensors_chip_name name)
return;
printf("%s\n",sprintf_chip_name(name));
- adap = sensors_get_adapter_name(name.bus);
- if (adap && !hide_adapter)
- printf("Adapter: %s\n",adap);
- if (!adap)
- fprintf(stderr, "Can't get adapter name for bus %d\n", name.bus);
+ if (!hide_adapter) {
+ const char *adap = sensors_get_adapter_name(name.bus);
+ if (adap)
+ printf("Adapter: %s\n", adap);
+ else
+ fprintf(stderr, "Can't get adapter name for bus %d\n", name.bus);
+ }
if (do_unknown)
print_unknown_chip(&name);
else {
diff --git a/version.h b/version.h
index a3319392..13bc5cd7 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
-#define LM_DATE "2007????"
-#define LM_VERSION "2.10.2-SVN"
+#define LM_DATE "20070319"
+#define LM_VERSION "2.10.3"