Re: Driver for SMSC SCH5627 needed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 12 Mar 2011 12:19:09 +0100, Jean Delvare wrote:
> Anyway, I agree that the non-standard location of the base I/O register
> isn't supported by sensors-detect yet. We already have some code to
> handle non-standard SMSC chips, but the SCH5627 is non-standard in a
> different way. I'll try to come up with something, stay tuned.

Can anyone with access to a SCH5627 chip test the sensors-detect patch
in attachment? Alternatively a pre-patched sensors-detect can be
downloaded at:
  http://khali.linux-fr.org/devel/misc/sensors-detect

It should properly detect the SCH5627, but I can't test it as I don't
have such a chip.

Thanks,
-- 
Jean Delvare
Add detection of the SMSC SCH5627. Some code is needed because the
base I/O registers live at non-standard addresses.

Signed-off-by: Jean Delvare <khali@xxxxxxxxxxxx>
---
 prog/detect/sensors-detect |   60 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 13 deletions(-)

--- lm-sensors.orig/prog/detect/sensors-detect	2011-03-04 15:59:20.000000000 +0100
+++ lm-sensors/prog/detect/sensors-detect	2011-03-12 14:05:38.000000000 +0100
@@ -1402,6 +1402,7 @@ use vars qw(@i2c_adapter_names);
 #	 monitoring registers can only be accessed via the SMBus
 #  devid: The device ID we have to match (base device)
 #  devid_mask (optional): Bitmask to apply before checking the device ID
+#  regs (optional): Register definitions, where they differ from the standard.
 #  logdev: The logical device containing the sensors
 #  check (optional): A function to refine the detection. Will be passed
 #      the index and data ports as parameters. Must return 1 for a matching
@@ -1761,6 +1762,16 @@ use constant FEAT_SMBUS	=> (1 << 7);
 		# No datasheet
 		driver => "not-a-sensor",
 		devid => 0x83,
+	}, {
+		name => "SMSC SCH5627 Super IO",
+		driver => "sch5627",
+		devid => 0xc6,
+		regs => {
+			basereg_lsb => 0x66,
+			basereg_msb => 0x67,
+		},
+		logdev => 0x0c,
+		features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
 	}
 );
 
@@ -2236,6 +2247,20 @@ sub any_list_match
 	return 0;
 }
 
+# $_[0]: Reference to base hash
+# $_[1]: Reference to overlay hash
+# Result: Overlayed hash
+sub overlay_hash
+{
+	my ($base, $overlay) = @_;
+	my %result = %{$base};
+
+	foreach my $key (keys %{$overlay}) {
+		$result{$key} = $overlay->{$key};
+	}
+	return %result;
+}
+
 ###################
 # I/O PORT ACCESS #
 ###################
@@ -3544,7 +3569,7 @@ sub scan_isa_bus
 	$| = 0;
 }
 
-use vars qw(%superio);
+use vars qw(%standard_superio);
 
 # The following are taken from the PNP ISA spec (so it's supposed
 # to be common to all Super I/O chips):
@@ -3552,13 +3577,14 @@ use vars qw(%superio);
 #  logdevreg: The logical device register
 #  actreg: The activation register within the logical device
 #  actmask: The activation bit in the activation register
-#  basereg: The I/O base register within the logical device
-%superio = (
+#  basereg_*: The I/O base registers within the logical device
+%standard_superio = (
 	devidreg => 0x20,
 	logdevreg => 0x07,
 	actreg => 0x30,
 	actmask => 0x01,
-	basereg => 0x60,
+	basereg_msb => 0x60,
+	basereg_lsb => 0x61,
 );
 
 sub exit_superio
@@ -3580,18 +3606,18 @@ sub guess_superio_ld
 	my ($oldldn, $ldn, $addr);
 
 	# Save logical device number
-	outb($addrreg, $superio{logdevreg});
+	outb($addrreg, $standard_superio{logdevreg});
 	$oldldn = inb($datareg);
 
 	for ($ldn = 0; $ldn < 16; $ldn++) {
 		# Select logical device
-		outb($addrreg, $superio{logdevreg});
+		outb($addrreg, $standard_superio{logdevreg});
 		outb($datareg, $ldn);
 
 		# Read base I/O address
-		outb($addrreg, $superio{basereg});
+		outb($addrreg, $standard_superio{basereg_msb});
 		$addr = inb($datareg) << 8;
-		outb($addrreg, $superio{basereg} + 1);
+		outb($addrreg, $standard_superio{basereg_lsb});
 		$addr |= inb($datareg);
 		next unless ($addr & 0xfff8) == $typical_addr;
 
@@ -3601,7 +3627,7 @@ sub guess_superio_ld
 	}
 
 	# Be nice, restore original logical device
-	outb($addrreg, $superio{logdevreg});
+	outb($addrreg, $standard_superio{logdevreg});
 	outb($datareg, $oldldn);
 }
 
@@ -3610,6 +3636,14 @@ sub probe_superio
 {
 	my ($addrreg, $datareg, $chip) = @_;
 	my ($val, $addr);
+	my %superio;
+
+	# Use chip-specific registers if provided
+	if (exists $chip->{regs}) {
+		%superio = overlay_hash(\%standard_superio, $chip->{regs});
+	} else {
+		%superio = %standard_superio;
+	}
 
 	if (exists $chip->{check}) {
 		return 0 unless $chip->{check}($addrreg, $datareg);
@@ -3636,9 +3670,9 @@ sub probe_superio
 	outb($datareg, $chip->{logdev});
 
 	# Get the IO base address
-	outb($addrreg, $superio{basereg});
+	outb($addrreg, $superio{basereg_msb});
 	$addr = inb($datareg);
-	outb($addrreg, $superio{basereg} + 1);
+	outb($addrreg, $superio{basereg_lsb});
 	$addr = ($addr << 8) | inb($datareg);
 
 	# Check the activation register and base address
@@ -3721,9 +3755,9 @@ sub scan_superio
 		}
 
 		# did it work?
-		outb($addrreg, $superio{devidreg});
+		outb($addrreg, $standard_superio{devidreg});
 		$val = inb($datareg);
-		outb($addrreg, $superio{devidreg} + 1);
+		outb($addrreg, $standard_superio{devidreg} + 1);
 		$val = ($val << 8) | inb($datareg);
 		if ($val == 0x0000 || $val == 0xffff) {
 			print "No\n";
_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux