root/lm-sensors/branches/lm-sensors-3.0.0/prog/detect/sensors-detect @ 5429

Revision 5429, 162.2 KB (checked in by khali, 5 years ago)

Drop useless parentheses.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1#!/usr/bin/perl -w
2#
3#    sensors-detect - Detect hardware monitoring chips
4#    Copyright (C) 1998 - 2002  Frodo Looijaard <frodol@dds.nl>
5#    Copyright (C) 2004 - 2008  Jean Delvare <khali@linux-fr.org>
6#
7#    This program is free software; you can redistribute it and/or modify
8#    it under the terms of the GNU General Public License as published by
9#    the Free Software Foundation; either version 2 of the License, or
10#    (at your option) any later version.
11#
12#    This program is distributed in the hope that it will be useful,
13#    but WITHOUT ANY WARRANTY; without even the implied warranty of
14#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15#    GNU General Public License for more details.
16#
17#    You should have received a copy of the GNU General Public License
18#    along with this program; if not, write to the Free Software
19#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20#    MA 02110-1301 USA.
21#
22
23require 5.004;
24
25use strict;
26use Fcntl;
27use POSIX;
28use File::Basename;
29
30# We will call modprobe, which typically lives in either /sbin,
31# /usr/sbin or /usr/local/bin. So make sure these are all in the PATH.
32foreach ('/usr/sbin', '/usr/local/sbin', '/sbin') {
33        $ENV{PATH} = "$_:".$ENV{PATH}
34                unless $ENV{PATH} =~ m/(^|:)$_\/?(:|$)/;
35}
36
37#########################
38# CONSTANT DECLARATIONS #
39#########################
40
41use constant NO_CACHE => 1;
42use vars qw(@pci_adapters @chip_ids $i2c_addresses_to_scan @superio_ids
43            @cpu_ids $revision @i2c_byte_cache);
44
45$revision = '$Revision$ ($Date$)';
46$revision =~ s/\$\w+: (.*?) \$/$1/g;
47$revision =~ s/ \([^()]*\)//;
48
49# This is the list of SMBus or I2C adapters we recognize by their PCI
50# signature. This is an easy and fast way to determine which SMBus or I2C
51# adapters should be present.
52# Each entry must have a vendid (Vendor ID), devid (Device ID) and
53# procid (Device name) and driver (Device driver).
54@pci_adapters = (
55     {
56       vendid => 0x8086,
57       devid  => 0x7113,
58       procid => "Intel 82371AB PIIX4 ACPI",
59       driver => "i2c-piix4",
60     },
61     {
62       vendid => 0x8086,
63       devid  => 0x7603,
64       procid => "Intel 82372FB PIIX5 ACPI",
65       driver => "to-be-tested",
66     },
67     {
68       vendid => 0x8086,
69       devid  => 0x719b,
70       procid => "Intel 82443MX Mobile",
71       driver => "i2c-piix4",
72     },
73     {
74       vendid => 0x8086,
75       devid  => 0x2413,
76       procid => "Intel 82801AA ICH",
77       driver => "i2c-i801",
78     },
79     {
80       vendid => 0x8086,
81       devid  => 0x2423,
82       procid => "Intel 82801AB ICH0",
83       driver => "i2c-i801",
84     },
85     {
86       vendid => 0x8086,
87       devid  => 0x2443,
88       procid => "Intel 82801BA ICH2",
89       driver => "i2c-i801",
90     },
91     {
92       vendid => 0x8086,
93       devid  => 0x2483,
94       procid => "Intel 82801CA/CAM ICH3",
95       driver => "i2c-i801",
96     },
97     {
98       vendid => 0x8086,
99       devid  => 0x24C3,
100       procid => "Intel 82801DB ICH4",
101       driver => "i2c-i801",
102     },
103     {
104       vendid => 0x8086,
105       devid  => 0x24D3,
106       procid => "Intel 82801EB ICH5",
107       driver => "i2c-i801",
108     },
109     {
110       vendid => 0x8086,
111       devid  => 0x25A4,
112       procid => "Intel 6300ESB",
113       driver => "i2c-i801",
114     },
115     {
116       vendid => 0x8086,
117       devid  => 0x269B,
118       procid => "Intel Enterprise Southbridge - ESB2",
119       driver => "i2c-i801",
120     },
121     {
122       vendid => 0x8086,
123       devid  => 0x266A,
124       procid => "Intel 82801FB ICH6",
125       driver => "i2c-i801",
126     },
127     {
128       vendid => 0x8086,
129       devid  => 0x27DA,
130       procid => "Intel 82801G ICH7",
131       driver => "i2c-i801",
132     },
133     {
134       vendid => 0x8086,
135       devid  => 0x283E,
136       procid => "Intel 82801H ICH8",
137       driver => "i2c-i801",
138     },
139     {
140       vendid => 0x8086,
141       devid  => 0x2930,
142       procid => "Intel ICH9",
143       driver => "i2c-i801",
144     },
145     {
146       vendid => 0x8086,
147       devid  => 0x5032,
148       procid => "Intel Tolapai",
149       driver => "i2c-i801",
150     },
151     {
152       vendid => 0x8086,
153       devid  => 0x3A30,
154       procid => "Intel ICH10",
155       driver => "i2c-i801",
156     },
157     {
158       vendid => 0x8086,
159       devid  => 0x3A60,
160       procid => "Intel ICH10",
161       driver => "i2c-i801",
162     },
163     {
164       vendid => 0x8086,
165       devid  => 0x8119,
166       procid => "Intel SCH",
167       driver => "i2c-isch",
168     },
169     {
170       vendid => 0x1106,
171       devid  => 0x3040,
172       procid => "VIA Technologies VT82C586B Apollo ACPI",
173       driver => "i2c-via",
174     },
175     {
176       vendid => 0x1106,
177       devid  => 0x3050,
178       procid => "VIA Technologies VT82C596 Apollo ACPI",
179       driver => "i2c-viapro",
180     },
181     {
182       vendid => 0x1106,
183       devid  => 0x3051,
184       procid => "VIA Technologies VT82C596B ACPI",
185       driver => "i2c-viapro",
186     },
187     {
188       vendid => 0x1106,
189       devid  => 0x3057,
190       procid => "VIA Technologies VT82C686 Apollo ACPI",
191       driver => "i2c-viapro",
192     },
193     {
194       vendid => 0x1106,
195       devid  => 0x3074,
196       procid => "VIA Technologies VT8233 VLink South Bridge",
197       driver => "i2c-viapro",
198     },
199     {
200       vendid => 0x1106,
201       devid  => 0x3147,
202       procid => "VIA Technologies VT8233A South Bridge",
203       driver => "i2c-viapro",
204     },
205     {
206       vendid => 0x1106,
207       devid  => 0x3177,
208       procid => "VIA Technologies VT8233A/8235 South Bridge",
209       driver => "i2c-viapro",
210     },
211     {
212       vendid => 0x1106,
213       devid  => 0x3227,
214       procid => "VIA Technologies VT8237 South Bridge",
215       driver => "i2c-viapro",
216     },
217     {
218       vendid => 0x1106,
219       devid  => 0x3337,
220       procid => "VIA Technologies VT8237A South Bridge",
221       driver => "i2c-viapro",
222     },
223     {
224       vendid => 0x1106,
225       devid  => 0x8235,
226       procid => "VIA Technologies VT8231 South Bridge",
227       driver => "i2c-viapro",
228     },
229     {
230       vendid => 0x1106,
231       devid  => 0x3287,
232       procid => "VIA Technologies VT8251 South Bridge",
233       driver => "i2c-viapro",
234     },
235     {
236       vendid => 0x1106,
237       devid  => 0x8324,
238       procid => "VIA Technologies CX700 South Bridge",
239       driver => "i2c-viapro",
240     },
241     {
242       vendid => 0x1106,
243       devid  => 0x8353,
244       procid => "VIA Technologies VX800/VX820 South Bridge",
245       driver => "i2c-viapro",
246     },
247     {
248       vendid => 0x1039,
249       devid  => 0x0630,
250       procid => "Silicon Integrated Systems SIS630",
251       driver => "i2c-sis630",
252     },
253     {
254       vendid => 0x1039,
255       devid  => 0x0730,
256       procid => "Silicon Integrated Systems SIS730",
257       driver => "i2c-sis630",
258     },
259#
260# Both Ali chips below have same PCI ID. Can't be helped. Only one should load.
261#
262     {
263       vendid => 0x10b9,
264       devid => 0x7101,
265       procid => "Acer Labs 1533/1543",
266       driver => "i2c-ali15x3",
267     },
268     {
269       vendid => 0x10b9,
270       devid => 0x7101,
271       procid => "Acer Labs 1535",
272       driver => "i2c-ali1535",
273     },
274     {
275       vendid => 0x10b9,
276       devid => 0x1563,
277       procid => "Acer Labs 1563",
278       driver => "i2c-ali1563",
279     },
280     {
281       vendid => 0x1022,
282       devid  => 0x740b,
283       procid => "AMD-756 Athlon ACPI",
284       driver => "i2c-amd756",
285     },
286     {
287       vendid => 0x1022,
288       devid  => 0x7413,
289       procid => "AMD-766 Athlon ACPI",
290       driver => "i2c-amd756",
291     },
292     {
293       vendid => 0x1022,
294       devid  => 0x7443,
295       procid => "AMD-768 System Management",
296       driver => "i2c-amd756",
297     },
298     {
299       vendid => 0x1022,
300       devid  => 0x746b,
301       procid => "AMD-8111 ACPI",
302       driver => "i2c-amd756",
303     },
304     {
305       vendid => 0x1022,
306       devid  => 0x746a,
307       procid => "AMD-8111 SMBus 2.0",
308       driver => "i2c-amd8111",
309     },
310     {
311       vendid => 0x10de,
312       devid  => 0x01b4,
313       procid => "nVidia nForce SMBus",
314       driver => "i2c-amd756",
315     },
316     {
317       vendid => 0x10de,
318       devid  => 0x0064,
319       procid => "nVidia Corporation nForce2 SMBus (MCP)",
320       driver => "i2c-nforce2",
321     },
322     {
323       vendid => 0x10de,
324       devid  => 0x0084,
325       procid => "nVidia Corporation nForce2 Ultra 400 SMBus (MCP)",
326       driver => "i2c-nforce2",
327     },
328     {
329       vendid => 0x10de,
330       devid  => 0x00D4,
331       procid => "nVidia Corporation nForce3 Pro150 SMBus (MCP)",
332       driver => "i2c-nforce2",
333     },
334     {
335       vendid => 0x10de,
336       devid  => 0x00E4,
337       procid => "nVidia Corporation nForce3 250Gb SMBus (MCP)",
338       driver => "i2c-nforce2",
339     },
340     {
341       vendid => 0x10de,
342       devid  => 0x0052,
343       procid => "nVidia Corporation nForce4 SMBus (MCP)",
344       driver => "i2c-nforce2",
345     },
346     {
347       vendid => 0x10de,
348       devid => 0x0034,
349       procid => "nVidia Corporation nForce4 SMBus (MCP-04)",
350       driver => "i2c-nforce2",
351     },
352     {
353       vendid => 0x10de,
354       devid => 0x0264,
355       procid => "nVidia Corporation nForce4 SMBus (MCP51)",
356       driver => "i2c-nforce2",
357     },
358     {
359       vendid => 0x10de,
360       devid => 0x0368,
361       procid => "nVidia Corporation nForce4 SMBus (MCP55)",
362       driver => "i2c-nforce2",
363     },
364     {
365       vendid => 0x10de,
366       devid => 0x03eb,
367       procid => "nVidia Corporation nForce4 SMBus (MCP61)",
368       driver => "i2c-nforce2",
369     },
370     {
371       vendid => 0x10de,
372       devid => 0x0446,
373       procid => "nVidia Corporation nForce4 SMBus (MCP65)",
374       driver => "i2c-nforce2",
375     },
376     {
377       vendid => 0x1166,
378       devid  => 0x0200,
379       procid => "ServerWorks OSB4 South Bridge",
380       driver => "i2c-piix4",
381     },
382     {
383       vendid => 0x1055,
384       devid  => 0x9463,
385       procid => "SMSC Victory66 South Bridge",
386       driver => "i2c-piix4",
387     },
388     {
389       vendid => 0x1166,
390       devid  => 0x0201,
391       procid => "ServerWorks CSB5 South Bridge",
392       driver => "i2c-piix4",
393     },
394     {
395       vendid => 0x1166,
396       devid  => 0x0203,
397       procid => "ServerWorks CSB6 South Bridge",
398       driver => "i2c-piix4",
399     },
400     {
401       vendid => 0x1166,
402       devid  => 0x0205,
403       procid => "ServerWorks HT-1000 South Bridge",
404       driver => "i2c-piix4",
405     },
406     {
407       vendid => 0x1002,
408       devid  => 0x4353,
409       procid => "ATI Technologies Inc ATI SMBus",
410       driver => "i2c-piix4",
411     },
412     {
413       vendid => 0x1002,
414       devid  => 0x4363,
415       procid => "ATI Technologies Inc ATI SMBus",
416       driver => "i2c-piix4",
417     },
418     {
419       vendid => 0x1002,
420       devid  => 0x4372,
421       procid => "ATI Technologies Inc IXP SB400 SMBus Controller",
422       driver => "i2c-piix4",
423     },
424     {
425       vendid => 0x1002,
426       devid  => 0x4385,
427       procid => "ATI Technologies Inc SB600 SMBus",
428       driver => "i2c-piix4",
429     },
430     {
431       vendid => 0x100B,
432       devid => 0x0500,
433       procid => "SCx200 Bridge",
434       driver => "scx200_acb",
435     },
436     {
437       vendid => 0x100B,
438       devid => 0x0510,
439       procid => "SC1100 Bridge",
440       driver => "scx200_acb",
441     },
442     {
443       vendid => 0x100B,
444       devid => 0x002B,
445       procid => "CS5535 ISA bridge",
446       driver => "scx200_acb",
447     },
448     {
449       vendid => 0x1022,
450       devid => 0x2090,
451       procid => "CS5536 [Geode companion] ISA",
452       driver => "scx200_acb",
453     },
454);
455
456# The following entries used to appear directly in @pci_adapters.
457# Because of the tendency of SiS chipsets to have their real PCI
458# IDs obscured, we have to qualify these with a custom detection
459# routine before we add them to the @pci_adapters list.
460#
461use vars qw(@pci_adapters_sis5595 @pci_adapters_sis96x);
462@pci_adapters_sis5595 = (
463     {
464       vendid => 0x1039,
465       devid  => 0x0008,
466       procid => "Silicon Integrated Systems SIS5595",
467       driver => "i2c-sis5595",
468     },
469);
470
471@pci_adapters_sis96x = (
472     {
473       vendid => 0x1039,
474       devid  => 0x0016,
475       procid => "Silicon Integrated Systems SMBus Controller",
476       driver => "i2c-sis96x",
477     },
478);
479
480# Look-up table to find out an I2C bus' driver based on the bus name.
481# The match field should contain a regular expression matching the I2C
482# bus name as it would appear in /sys/class/i2c-adapter.
483# Note that new drivers probably don't need to be added to this table
484# if they bind to their device, as we will be able to get the driver name
485# from sysfs directly.
486use vars qw(@i2c_adapter_names);
487@i2c_adapter_names = (
488        { driver => "i2c-piix4",        match => qr/^SMBus PIIX4 adapter at / },
489        { driver => "i2c-i801",         match => qr/^SMBus I801 adapter at / },
490        { driver => "i2c-via",          match => qr/^VIA i2c/ },
491        { driver => "i2c-viapro",       match => qr/^SMBus V(IA|ia) Pro adapter at / },
492        { driver => "i2c-sis5595",      match => qr/^SMBus SIS5595 adapter at / },
493        { driver => "i2c-sis630",       match => qr/^SMBus SIS630 adapter at / },
494        { driver => "i2c-sis96x",       match => qr/^SiS96x SMBus adapter at / },
495        { driver => "i2c-ali15x3",      match => qr/^SMBus ALI15X3 adapter at / },
496        { driver => "i2c-ali1535",      match => qr/^SMBus ALI1535 adapter at/ },
497        { driver => "i2c-ali1563",      match => qr/^SMBus ALi 1563 Adapter @ / },
498        { driver => "i2c-amd756",       match => qr/^SMBus (AMD756|AMD766|AMD768|AMD8111|nVidia nForce) adapter at / },
499        { driver => "i2c-amd8111",      match => qr/^SMBus2 AMD8111 adapter at / },
500        { driver => "i2c-nforce2",      match => qr/^SMBus nForce2 adapter at / },
501        { driver => "scx200_acb",       match => qr/^(NatSemi SCx200 ACCESS\.bus|SCx200 ACB\d+|CS553[56] ACB\d+) / },
502);
503
504# This is a list of all recognized I2C and ISA chips.
505# Each entry must have the following fields:
506#  name: The full chip name
507#  driver: The driver name. Put in exactly:
508#      * "to-be-written" if it is not yet available
509#      * "not-a-sensor" if it is not a hardware monitoring chip
510#      * "use-isa-instead" if no i2c driver will be written
511#  i2c_addrs (optional): For I2C chips, the list of I2C addresses to
512#      probe.
513#  i2c_detect (optional): For I2C chips, the function to call to detect
514#      this chip. The function will be passed two parameters: an open file
515#      descriptor to access the bus, and the I2C address to probe.
516#  isa_addrs (optional): For ISA chips, the list of port addresses to
517#      probe.
518#  isa_detect (optional): For ISA chips, the function to call to detect
519#      this chip. The function will be passed one parameter: the ISA address
520#      to probe.
521#  alias_detect (optional): For chips which can be both on the ISA and the
522#      I2C bus, a function which detects whether two entries are the same.
523#      The function will be passed three parameters: the ISA address, an
524#      open file descriptor to access the I2C bus, and the I2C address.
525@chip_ids = (
526     {
527       name => "Myson MTP008",
528       driver => "mtp008",
529       i2c_addrs => [0x2c..0x2e],
530       i2c_detect => sub { mtp008_detect(@_); },
531     },
532     {
533       name => "National Semiconductor LM78",
534       driver => "lm78",
535       i2c_addrs => [0x28..0x2f],
536       i2c_detect => sub { lm78_detect(@_, 0); },
537       isa_addrs => [0x290],
538       isa_detect => sub { lm78_isa_detect(@_, 0); },
539       alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
540     },
541     {
542       name => "National Semiconductor LM79",
543       driver => "lm78",
544       i2c_addrs => [0x28..0x2f],
545       i2c_detect => sub { lm78_detect(@_, 2); },
546       isa_addrs => [0x290],
547       isa_detect => sub { lm78_isa_detect(@_, 2); },
548       alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
549     },
550     {
551       name => "National Semiconductor LM75",
552       driver => "lm75",
553       i2c_addrs => [0x48..0x4f],
554       i2c_detect => sub { lm75_detect(@_, 0); },
555     },
556     {
557       name => "Dallas Semiconductor DS75",
558       driver => "lm75",
559       i2c_addrs => [0x48..0x4f],
560       i2c_detect => sub { lm75_detect(@_, 1); },
561     },
562     {
563       name => "National Semiconductor LM77",
564       driver => "lm77",
565       i2c_addrs => [0x48..0x4b],
566       i2c_detect => sub { lm77_detect(@_); },
567     },
568     {
569       name => "National Semiconductor LM80",
570       driver => "lm80",
571       i2c_addrs => [0x28..0x2f],
572       i2c_detect => sub { lm80_detect(@_); },
573     },
574     {
575       name => "National Semiconductor LM85",
576       driver => "lm85",
577       i2c_addrs => [0x2c..0x2e],
578       i2c_detect => sub { lm85_detect(@_, 0); },
579     },
580     {
581       name => "National Semiconductor LM96000 or PC8374L",
582       driver => "lm85",
583       i2c_addrs => [0x2c..0x2e],
584       i2c_detect => sub { lm85_detect(@_, 1); },
585     },
586     {
587       name => "Analog Devices ADM1027",
588       driver => "lm85",
589       i2c_addrs => [0x2c..0x2e],
590       i2c_detect => sub { lm85_detect(@_, 2); },
591     },
592     {
593       name => "Analog Devices ADT7460 or ADT7463",
594       driver => "lm85",
595       i2c_addrs => [0x2c..0x2e],
596       i2c_detect => sub { lm85_detect(@_, 3); },
597     },
598     {
599       name => "SMSC EMC6D100 or EMC6D101",
600       driver => "lm85",
601       i2c_addrs => [0x2c..0x2e],
602       i2c_detect => sub { lm85_detect(@_, 4); },
603     },
604     {
605       name => "SMSC EMC6D102",
606       driver => "lm85",
607       i2c_addrs => [0x2c..0x2e],
608       i2c_detect => sub { lm85_detect(@_, 5); },
609     },
610     {
611       name => "SMSC EMC6D103",
612       driver => "lm85",
613       i2c_addrs => [0x2c..0x2e],
614       i2c_detect => sub { lm85_detect(@_, 6); },
615     },
616     {
617       name => "Analog Devices ADT7462",
618       driver => "adt7462",
619       i2c_addrs => [0x5c, 0x58],
620       i2c_detect => sub { adt7467_detect(@_, 2); },
621     },
622     {
623       name => "Analog Devices ADT7466",
624       driver => "to-be-written",
625       i2c_addrs => [0x4c],
626       i2c_detect => sub { adt7467_detect(@_, 3); },
627     },
628     {
629       name => "Analog Devices ADT7467 or ADT7468",
630       driver => "to-be-written",
631       i2c_addrs => [0x2e],
632       i2c_detect => sub { adt7467_detect(@_, 0); },
633     },
634     {
635       name => "Analog Devices ADT7470",
636       driver => "adt7470",
637       i2c_addrs => [0x2c, 0x2e, 0x2f],
638       i2c_detect => sub { adt7467_detect(@_, 4); },
639     },
640     {
641       name => "Analog Devices ADT7473",
642       driver => "adt7473",
643       i2c_addrs => [0x2e],
644       i2c_detect => sub { adt7473_detect(@_, 0); },
645     },
646     {
647       name => "Analog Devices ADT7475",
648       driver => "to-be-written",
649       i2c_addrs => [0x2e],
650       i2c_detect => sub { adt7473_detect(@_, 1); },
651     },
652     {
653       name => "Analog Devices ADT7476",
654       driver => "to-be-written",
655       i2c_addrs => [0x2c..0x2e],
656       i2c_detect => sub { adt7467_detect(@_, 1); },
657     },
658     {
659       name => "Andigilog aSC7511",
660       driver => "to-be-written",
661       i2c_addrs => [0x4c],
662       i2c_detect => sub { andigilog_aSC7511_detect(@_); },
663     },
664     {
665       name => "Andigilog aSC7512",
666       driver => "to-be-written",
667       i2c_addrs => [0x58],
668       i2c_detect => sub { andigilog_detect(@_, 0); },
669     },
670     {
671       name => "Andigilog aSC7611",
672       driver => "to-be-written",
673       i2c_addrs => [0x2c, 0x2d, 0x2e],
674       i2c_detect => sub { andigilog_detect(@_, 1); },
675     },
676     {
677       name => "Andigilog aSC7621",
678       driver => "to-be-written",
679       i2c_addrs => [0x2c, 0x2d, 0x2e],
680       i2c_detect => sub { andigilog_detect(@_, 2); },
681     },
682     {
683       name => "National Semiconductor LM87",
684       driver => "lm87",
685       i2c_addrs => [0x2c..0x2e],
686       i2c_detect => sub { lm87_detect(@_, 0); },
687     },
688     {
689       name => "Analog Devices ADM1024",
690       driver => "lm87",
691       i2c_addrs => [0x2c..0x2e],
692       i2c_detect => sub { lm87_detect(@_, 1); },
693     },
694     {
695       name => "National Semiconductor LM93",
696       driver => "lm93",
697       i2c_addrs => [0x2c..0x2e],
698       i2c_detect => sub { lm93_detect(@_); },
699     },
700     {
701       name => "Winbond W83781D",
702       driver => "w83781d",
703       i2c_detect => sub { w83781d_detect(@_, 0); },
704       i2c_addrs => [0x28..0x2f],
705       isa_addrs => [0x290],
706       isa_detect => sub { w83781d_isa_detect(@_, 0); },
707       alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
708     },
709     {
710       name => "Winbond W83782D",
711       driver => "w83781d",
712       i2c_addrs => [0x28..0x2f],
713       i2c_detect => sub { w83781d_detect(@_, 1); },
714       isa_addrs => [0x290],
715       isa_detect => sub { w83781d_isa_detect(@_, 1); },
716       alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
717     },
718     {
719       name => "Winbond W83783S",
720       driver => "w83781d",
721       i2c_addrs => [0x2d],
722       i2c_detect => sub { w83781d_detect(@_, 2); },
723     },
724     {
725       name => "Winbond W83791D",
726       driver => "w83791d",
727       i2c_addrs => [0x2c..0x2f],
728       i2c_detect => sub { w83781d_detect(@_, 7); },
729     },
730     {
731       name => "Winbond W83792D",
732       driver => "w83792d",
733       i2c_addrs => [0x2c..0x2f],
734       i2c_detect => sub { w83781d_detect(@_, 8); },
735     },
736     {
737       name => "Winbond W83793R/G",
738       driver => "w83793",
739       i2c_addrs => [0x2c..0x2f],
740       i2c_detect => sub { w83793_detect(@_); },
741     },
742     {
743       name => "Winbond W83791SD",
744       driver => "not-a-sensor",
745       i2c_addrs => [0x2c..0x2f],
746       i2c_detect => sub { w83791sd_detect(@_); },
747     },
748     {
749       name => "Winbond W83627HF",
750       driver => "use-isa-instead",
751       i2c_addrs => [0x28..0x2f],
752       i2c_detect => sub { w83781d_detect(@_, 3); },
753     },
754     {
755       name => "Winbond W83627EHF",
756       driver => "use-isa-instead",
757       i2c_addrs => [0x28..0x2f],
758       i2c_detect => sub { w83781d_detect(@_, 9); },
759     },
760     {
761       name => "Winbond W83627DHG",
762       driver => "use-isa-instead",
763       i2c_addrs => [0x28..0x2f],
764       i2c_detect => sub { w83781d_detect(@_, 10); },
765     },
766     {
767       name => "Asus AS99127F (rev.1)",
768       driver => "w83781d",
769       i2c_addrs => [0x28..0x2f],
770       i2c_detect => sub { w83781d_detect(@_, 4); },
771     },
772     {
773       name => "Asus AS99127F (rev.2)",
774       driver => "w83781d",
775       i2c_addrs => [0x28..0x2f],
776       i2c_detect => sub { w83781d_detect(@_, 5); },
777     },
778     {
779       name => "Asus ASB100 Bach",
780       driver => "asb100",
781       i2c_addrs => [0x28..0x2f],
782       i2c_detect => sub { w83781d_detect(@_, 6); },
783     },
784     {
785       name => "Asus Mozart-2",
786       driver => "to-be-written",
787       i2c_addrs => [0x77],
788       i2c_detect => sub { mozart_detect(@_); },
789     },
790     {
791       name => "Winbond W83L784R/AR/G",
792       driver => "to-be-written",
793       i2c_addrs => [0x2d],
794       i2c_detect => sub { w83l784r_detect(@_, 0); },
795     },
796     {
797       name => "Winbond W83L785R/G",
798       driver => "to-be-written",
799       i2c_addrs => [0x2d],
800       i2c_detect => sub { w83l784r_detect(@_, 1); },
801     },
802     {
803       name => "Winbond W83L786NR/NG/R/G",
804       driver => "w83l786ng",
805       i2c_addrs => [0x2e, 0x2f],
806       i2c_detect => sub { w83l784r_detect(@_, 2); },
807     },
808     {
809       name => "Winbond W83L785TS-S",
810       driver => "w83l785ts",
811       i2c_addrs => [0x2e],
812       i2c_detect => sub { w83l784r_detect(@_, 3); },
813     },
814     {
815       name => "Genesys Logic GL518SM",
816       driver => "gl518sm",
817       i2c_addrs => [0x2c, 0x2d],
818       i2c_detect => sub { gl518sm_detect(@_, 0); },
819     },
820     {
821       name => "Genesys Logic GL520SM",
822       driver => "gl520sm",
823       i2c_addrs => [0x2c, 0x2d],
824       i2c_detect => sub { gl518sm_detect(@_, 1); },
825     },
826     {
827       name => "Genesys Logic GL525SM",
828       driver => "to-be-written",
829       i2c_addrs => [0x2d],
830       i2c_detect => sub { gl525sm_detect(@_); },
831     },
832     {
833       name => "Analog Devices ADM9240",
834       driver => "adm9240",
835       i2c_addrs => [0x2c..0x2f],
836       i2c_detect => sub { adm9240_detect(@_, 0); },
837     },
838     {
839       name => "Dallas Semiconductor DS1621/DS1631",
840       driver => "ds1621",
841       i2c_addrs => [0x48..0x4f],
842       i2c_detect => sub { ds1621_detect(@_); },
843     },
844     {
845       name => "Dallas Semiconductor DS1780",
846       driver => "adm9240",
847       i2c_addrs => [0x2c..0x2f],
848       i2c_detect => sub { adm9240_detect(@_, 1); },
849     },
850     {
851       name => "National Semiconductor LM81",
852       driver => "adm9240",
853       i2c_addrs => [0x2c..0x2f],
854       i2c_detect => sub { adm9240_detect(@_, 2); },
855     },
856     {
857       name => "Analog Devices ADM1026",
858       driver => "adm1026",
859       i2c_addrs => [0x2c, 0x2d, 0x2e],
860       i2c_detect => sub { adm1026_detect(@_); },
861     },
862     {
863       name => "Analog Devices ADM1025",
864       driver => "adm1025",
865       i2c_addrs => [0x2c..0x2e],
866       i2c_detect => sub { adm1025_detect(@_, 0); },
867     },
868     {
869       name => "Philips NE1619",
870       driver => "adm1025",
871       i2c_addrs => [0x2c..0x2d],
872       i2c_detect => sub { adm1025_detect(@_, 1); },
873     },
874     {
875       name => "Analog Devices ADM1021",
876       driver => "adm1021",
877       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
878       i2c_detect => sub { adm1021_detect(@_, 0); },
879     },
880     {
881       name => "Analog Devices ADM1021A/ADM1023",
882       driver => "adm1021",
883       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
884       i2c_detect => sub { adm1021_detect(@_, 1); },
885     },
886     {
887       name => "Maxim MAX1617",
888       driver => "adm1021",
889       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
890       i2c_detect => sub { adm1021_detect(@_, 2); },
891     },
892     {
893       name => "Maxim MAX1617A",
894       driver => "adm1021",
895       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
896       i2c_detect => sub { adm1021_detect(@_, 3); },
897     },
898     {
899       name => "Maxim MAX1668",
900       driver => "max1668",
901       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
902       i2c_detect => sub { max1668_detect(@_, 0); },
903     },
904     {
905       name => "Maxim MAX1805",
906       driver => "max1668",
907       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
908       i2c_detect => sub { max1668_detect(@_, 1); },
909     },
910     {
911       name => "Maxim MAX1989",
912       driver => "max1668",
913       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
914       i2c_detect => sub { max1668_detect(@_, 2); },
915     },
916     {
917       name => "Maxim MAX6650/MAX6651",
918       driver => "max6650",
919       i2c_addrs => [0x1b, 0x1f, 0x48, 0x4b],
920       i2c_detect => sub { max6650_detect(@_); },
921     },
922     {
923       name => "Maxim MAX6655/MAX6656",
924       driver => "max6655",
925       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
926       i2c_detect => sub { max6655_detect(@_); },
927     },
928     {
929       name => "TI THMC10",
930       driver => "adm1021",
931       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
932       i2c_detect => sub { adm1021_detect(@_, 4); },
933     },
934     {
935       name => "National Semiconductor LM84",
936       driver => "adm1021",
937       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
938       i2c_detect => sub { adm1021_detect(@_, 5); },
939     },
940     {
941       name => "Genesys Logic GL523SM",
942       driver => "adm1021",
943       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
944       i2c_detect => sub { adm1021_detect(@_, 6); },
945     },
946     {
947       name => "Onsemi MC1066",
948       driver => "adm1021",
949       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
950       i2c_detect => sub { adm1021_detect(@_, 7); },
951     },
952     {
953       name => "Maxim MAX1618",
954       driver => "max1619",
955       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
956       i2c_detect => sub { max1619_detect(@_, 1); },
957     },
958     {
959       name => "Maxim MAX1619",
960       driver => "max1619",
961       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
962       i2c_detect => sub { max1619_detect(@_, 0); },
963     },
964     {
965       name => "National Semiconductor LM82/LM83",
966       driver => "lm83",
967       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
968       i2c_detect => sub { lm83_detect(@_); },
969     },
970     {
971       name => "National Semiconductor LM90",
972       driver => "lm90",
973       i2c_addrs => [0x4c],
974       i2c_detect => sub { lm90_detect(@_, 0); },
975     },
976     {
977       name => "National Semiconductor LM89/LM99",
978       driver => "lm90",
979       i2c_addrs => [0x4c..0x4d],
980       i2c_detect => sub { lm90_detect(@_, 1); },
981     },
982     {
983       name => "National Semiconductor LM86",
984       driver => "lm90",
985       i2c_addrs => [0x4c],
986       i2c_detect => sub { lm90_detect(@_, 2); },
987     },
988     {
989       name => "Analog Devices ADM1032",
990       driver => "lm90",
991       i2c_addrs => [0x4c..0x4d],
992       i2c_detect => sub { lm90_detect(@_, 3); },
993     },
994     {
995       name => "Maxim MAX6654/MAX6690",
996       driver => "to-be-written", # probably lm90
997       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
998       i2c_detect => sub { lm90_detect(@_, 4); },
999     },
1000     {
1001       name => "Maxim MAX6657/MAX6658/MAX6659",
1002       driver => "lm90",
1003       i2c_addrs => [0x4c],
1004       i2c_detect => sub { max6657_detect(@_); },
1005     },
1006     {
1007       name => "Maxim MAX6659",
1008       driver => "lm90",
1009       i2c_addrs => [0x4d..0x4e], # 0x4c is handled above
1010       i2c_detect => sub { max6657_detect(@_); },
1011     },
1012     {
1013       name => "Maxim MAX6646",
1014       driver => "lm90",
1015       i2c_addrs => [0x4d],
1016       i2c_detect => sub { lm90_detect(@_, 6); },
1017     },
1018     {
1019       name => "Maxim MAX6647",
1020       driver => "lm90",
1021       i2c_addrs => [0x4e],
1022       i2c_detect => sub { lm90_detect(@_, 6); },
1023     },
1024     {
1025       name => "Maxim MAX6648/MAX6649/MAX6692",
1026       driver => "lm90",
1027       i2c_addrs => [0x4c],
1028       i2c_detect => sub { lm90_detect(@_, 6); },
1029     },
1030     {
1031       name => "Maxim MAX6680/MAX6681",
1032       driver => "lm90",
1033       i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
1034       i2c_detect => sub { lm90_detect(@_, 7); },
1035     },
1036     {
1037       name => "Winbond W83L771W/G",
1038       driver => "lm90",
1039       i2c_addrs => [0x4c],
1040       i2c_detect => sub { lm90_detect(@_, 8); },
1041     },
1042     {
1043       name => "Texas Instruments TMP401",
1044       driver => "tmp401",
1045       i2c_addrs => [0x4c],
1046       i2c_detect => sub { lm90_detect(@_, 9); },
1047     },
1048     {
1049       name => "Texas Instruments TMP411",
1050       driver => "to-be-written",
1051       i2c_addrs => [0x4c..0x4e],
1052       i2c_detect => sub { lm90_detect(@_, 10); },
1053     },
1054     {
1055       name => "National Semiconductor LM95231",
1056       driver => "to-be-written",
1057       i2c_addrs => [0x2b, 0x19, 0x2a],
1058       i2c_detect => sub { lm95231_detect(@_); },
1059     },
1060     {
1061       name => "National Semiconductor LM63",
1062       driver => "lm63",
1063       i2c_addrs => [0x4c],
1064       i2c_detect => sub { lm63_detect(@_, 1); },
1065     },
1066     {
1067       name => "National Semiconductor LM64",
1068       driver => "to-be-written", # lm63
1069       i2c_addrs => [0x18, 0x4e],
1070       i2c_detect => sub { lm63_detect(@_, 3); },
1071     },
1072     {
1073       name => "Fintek F75363SG",
1074       driver => "lm63", # Not yet
1075       i2c_addrs => [0x4c],
1076       i2c_detect => sub { lm63_detect(@_, 2); },
1077     },
1078     {
1079       name => "National Semiconductor LM92",
1080       driver => "lm92",
1081       i2c_addrs => [0x48..0x4b],
1082       i2c_detect => sub { lm92_detect(@_, 0); },
1083     },
1084     {
1085       name => "National Semiconductor LM76",
1086       driver => "lm92",
1087       i2c_addrs => [0x48..0x4b],
1088       i2c_detect => sub { lm92_detect(@_, 1); },
1089     },
1090     {
1091       name => "Maxim MAX6633/MAX6634/MAX6635",
1092       driver => "lm92",
1093       i2c_addrs => [0x48..0x4f], # The MAX6633 can also use 0x40-0x47 but we
1094                                  # don't want to probe these addresses, it's
1095                                  # dangerous.
1096       i2c_detect => sub { lm92_detect(@_, 2); },
1097     },
1098     {
1099       name => "Analog Devices ADT7461",
1100       driver => "lm90",
1101       i2c_addrs => [0x4c..0x4d],
1102       i2c_detect => sub { lm90_detect(@_, 5); },
1103     },
1104     {
1105       name => "Analog Devices ADT7481",
1106       driver => "to-be-written",
1107       i2c_addrs => [0x4c, 0x4b],
1108       i2c_detect => sub { adt7481_detect(@_); },
1109     },
1110     {
1111       name => "Analog Devices ADM1029",
1112       driver => "adm1029",
1113       i2c_addrs => [0x28..0x2f],
1114       i2c_detect => sub { adm1029_detect(@_); },
1115     },
1116     {
1117       name => "Analog Devices ADM1030",
1118       driver => "adm1031",
1119       i2c_addrs => [0x2c..0x2e],
1120       i2c_detect => sub { adm1031_detect(@_, 0); },
1121     },
1122     {
1123       name => "Analog Devices ADM1031",
1124       driver => "adm1031",
1125       i2c_addrs => [0x2c..0x2e],
1126       i2c_detect => sub { adm1031_detect(@_, 1); },
1127     },
1128     {
1129       name => "Analog Devices ADM1033",
1130       driver => "to-be-written",
1131       i2c_addrs => [0x50..0x53],
1132       i2c_detect => sub { adm1034_detect(@_, 0); },
1133     },
1134     {
1135       name => "Analog Devices ADM1034",
1136       driver => "to-be-written",
1137       i2c_addrs => [0x50..0x53],
1138       i2c_detect => sub { adm1034_detect(@_, 1); },
1139     },
1140     {
1141       name => "Analog Devices ADM1022",
1142       driver => "thmc50",
1143       i2c_addrs => [0x2c..0x2e],
1144       i2c_detect => sub { adm1022_detect(@_, 0); },
1145     },
1146     {
1147       name => "Texas Instruments THMC50",
1148       driver => "thmc50",
1149       i2c_addrs => [0x2c..0x2e],
1150       i2c_detect => sub { adm1022_detect(@_, 1); },
1151     },
1152     {
1153       name => "Analog Devices ADM1028",
1154       driver => "thmc50",
1155       i2c_addrs => [0x2e],
1156       i2c_detect => sub { adm1022_detect(@_, 2); },
1157     },
1158     {
1159       name => "Texas Instruments THMC51",
1160       driver => "to-be-written", # thmc50
1161       i2c_addrs => [0x2e], # At least (no datasheet)
1162       i2c_detect => sub { adm1022_detect(@_, 3); },
1163     },
1164     {
1165       name => "VIA VT1211 (I2C)",
1166       driver => "use-isa-instead",
1167       i2c_addrs => [0x2d],
1168       i2c_detect => sub { vt1211_i2c_detect(@_); },
1169     },
1170     {
1171       name => "ITE IT8712F",
1172       driver => "it87",
1173       i2c_addrs => [0x28..0x2f],
1174       i2c_detect => sub { it8712_i2c_detect(@_); },
1175     },
1176     {
1177       name => "ITE IT8201R/IT8203R/IT8206R/IT8266R",
1178       driver => "not-a-sensor",
1179       i2c_addrs => [0x4e],
1180       i2c_detect => sub { ite_overclock_detect(@_); },
1181     },
1182     {
1183       name => "SPD EEPROM",
1184       driver => "not-a-sensor",
1185       # Can also live at 0x54-0x57, but we don't care: we only check
1186       # for SPD and EDID EEPROMs because some hardware monitoring chips
1187       # can live at 0x50-0x53.
1188       i2c_addrs => [0x50..0x53],
1189       i2c_detect => sub { eeprom_detect(@_); },
1190     },
1191     {
1192       name => "EDID EEPROM",
1193       driver => "not-a-sensor",
1194       i2c_addrs => [0x50..0x53],
1195       i2c_detect => sub { ddcmonitor_detect(@_); },
1196     },
1197     {
1198       name => "FSC Poseidon I",
1199       driver => sub { kernel_version_at_least(2, 6, 24) ? "fschmd" : "fscpos" },
1200       i2c_addrs => [0x73],
1201       i2c_detect => sub { fsc_detect(@_, 0); },
1202     },
1203     {
1204       name => "FSC Poseidon II",
1205       driver => "to-be-written",
1206       i2c_addrs => [0x73],
1207       i2c_detect => sub { fsc_detect(@_, 1); },
1208     },
1209     {
1210       name => "FSC Scylla",
1211       driver => "fschmd",
1212       i2c_addrs => [0x73],
1213       i2c_detect => sub { fsc_detect(@_, 2); },
1214     },
1215     {
1216       name => "FSC Hermes",
1217       driver => sub { kernel_version_at_least(2, 6, 24) ? "fschmd" : "fscher" },
1218       i2c_addrs => [0x73],
1219       i2c_detect => sub { fsc_detect(@_, 3); },
1220     },
1221     {
1222       name => "FSC Heimdal",
1223       driver => "fschmd",
1224       i2c_addrs => [0x73],
1225       i2c_detect => sub { fsc_detect(@_, 4); },
1226     },
1227     {
1228       name => "FSC Heracles",
1229       driver => "fschmd",
1230       i2c_addrs => [0x73],
1231       i2c_detect => sub { fsc_detect(@_, 5); },
1232     },
1233     {
1234       name => "ALi M5879",
1235       driver => "to-be-written",
1236       i2c_addrs => [0x2c..0x2d],
1237       i2c_detect => sub { m5879_detect(@_); },
1238     },
1239     {
1240       name => "SMSC LPC47M15x/192/292/997",
1241       driver => "smsc47m192",
1242       i2c_addrs => [0x2c..0x2d],
1243       i2c_detect => sub { smsc47m192_detect(@_); },
1244     },
1245     {
1246       name => "SMSC DME1737",
1247       driver => "dme1737",
1248       i2c_addrs => [0x2c..0x2e],
1249       i2c_detect => sub { dme1737_detect(@_, 1); },
1250     },
1251     {
1252       name => "SMSC SCH5027D-NW",
1253       driver => "dme1737",
1254       i2c_addrs => [0x2c..0x2e],
1255       i2c_detect => sub { dme1737_detect(@_, 2); },
1256     },
1257     {
1258       name => "Fintek F75111R/RG/N (GPIO)",
1259       driver => "not-a-sensor",
1260       i2c_addrs => [0x4e], # 0x37 not probed
1261       i2c_detect => sub { fintek_detect(@_, 1); },
1262     },
1263     {
1264       name => "Fintek F75121R/F75122R/RG (VID+GPIO)",
1265       driver => "to-be-written",
1266       i2c_addrs => [0x4e], # 0x37 not probed
1267       i2c_detect => sub { fintek_detect(@_, 2); },
1268     },
1269     {
1270       name => "Fintek F75373S/SG",
1271       driver => "f75375s",
1272       i2c_addrs => [0x2d..0x2e],
1273       i2c_detect => sub { fintek_detect(@_, 3); },
1274     },
1275     {
1276       name => "Fintek F75375S/SP",
1277       driver => "f75375s",
1278       i2c_addrs => [0x2d..0x2e],
1279       i2c_detect => sub { fintek_detect(@_, 4); },
1280     },
1281     {
1282       name => "Fintek F75387SG/RG",
1283       driver => "to-be-written",
1284       i2c_addrs => [0x2d..0x2e],
1285       i2c_detect => sub { fintek_detect(@_, 5); },
1286     },
1287     {
1288       name => "Fintek F75383S/M",
1289       driver => "to-be-written",
1290       i2c_addrs => [0x4c],
1291       i2c_detect => sub { fintek_detect(@_, 6); },
1292     },
1293     {
1294       name => "Fintek F75384S/M",
1295       driver => "to-be-written",
1296       i2c_addrs => [0x4d],
1297       i2c_detect => sub { fintek_detect(@_, 6); },
1298     },
1299     {
1300       name => "Fintek custom power control IC",
1301       driver => "to-be-written",
1302       i2c_addrs => [0x2f],
1303       i2c_detect => sub { fintek_detect(@_, 7); },
1304     },
1305     {
1306       name => "Smart Battery",
1307       driver => "smartbatt",
1308       i2c_addrs => [0x0b],
1309       i2c_detect => sub { smartbatt_detect(@_); },
1310     },
1311     {
1312       name => "IPMI BMC KCS",
1313       driver => "ipmisensors",
1314       isa_addrs => [0x0ca0],
1315       isa_detect => sub { ipmi_detect(@_); },
1316     },
1317     {
1318       name => "IPMI BMC SMIC",
1319       driver => "ipmisensors",
1320       isa_addrs => [0x0ca8],
1321       isa_detect => sub { ipmi_detect(@_); },
1322     },
1323);
1324
1325
1326# This is a list of all recognized superio chips.
1327# Each entry must have the following fields:
1328#  name: The full chip name
1329#  driver: The driver name. Put in exactly:
1330#      * "to-be-written" if it is not yet available
1331#      * "not-a-sensor" if the chip doesn't have hardware monitoring
1332#        capabilities (listing such chips here removes the need of manual
1333#        lookup when people report them)
1334#      * "via-smbus-only" if this is a Super-I/O chip whose hardware
1335#        monitoring registers can only be accessed via the SMBus
1336#  devid: The device ID we have to match (base device)
1337#  devid_mask (optional): Bitmask to apply before checking the device ID
1338#  logdev: The logical device containing the sensors
1339#  alias_detect (optional): For chips which can be both on the LPC and the
1340#      I2C bus, a function which detects whether two entries are the same.
1341#      The function will be passed three parameters: the LPC address, an
1342#      open file descriptor to access the I2C bus, and the I2C address.
1343#
1344# Entries are grouped by family. Each family entry has the following fields:
1345#  family: The family name
1346#  guess (optional): Typical logical device address. This lets us do
1347#      generic probing if we fail to recognize the chip.
1348#  enter: The password sequence to write to the address register
1349#  chips: Array of chips
1350# The order of families matters, because we stop as soon as one family
1351# succeeds. So we have to list families with shorter password sequences
1352# first.
1353@superio_ids = (
1354  {
1355    family => "National Semiconductor",
1356    enter =>
1357    {
1358      0x2e => [],
1359      0x4e => [],
1360    },
1361    chips =>
1362    [
1363      {
1364        name => "Nat. Semi. PC8374L Super IO Sensors",
1365        driver => "to-be-written",
1366        devid => 0xf1,
1367        logdev => 0x08,
1368      },
1369      {
1370        name => "Nat. Semi. PC87351 Super IO Fan Sensors",
1371        driver => "to-be-written",
1372        devid => 0xe2,
1373        logdev => 0x08,
1374      },
1375      {
1376        name => "Nat. Semi. PC87360 Super IO Fan Sensors",
1377        driver => "pc87360",
1378        devid => 0xe1,
1379        logdev => 0x09,
1380      },
1381      {
1382        name => "Nat. Semi. PC87363 Super IO Fan Sensors",
1383        driver => "pc87360",
1384        devid => 0xe8,
1385        logdev => 0x09,
1386      },
1387      {
1388        name => "Nat. Semi. PC87364 Super IO Fan Sensors",
1389        driver => "pc87360",
1390        devid => 0xe4,
1391        logdev => 0x09,
1392      },
1393      {
1394        name => "Nat. Semi. PC87365 Super IO Fan Sensors",
1395        driver => "pc87360",
1396        devid => 0xe5,
1397        logdev => 0x09,
1398      },
1399      {
1400        name => "Nat. Semi. PC87365 Super IO Voltage Sensors",
1401        driver => "pc87360",
1402        devid => 0xe5,
1403        logdev => 0x0d,
1404      },
1405      {
1406        name => "Nat. Semi. PC87365 Super IO Thermal Sensors",
1407        driver => "pc87360",
1408        devid => 0xe5,
1409        logdev => 0x0e,
1410      },
1411      {
1412        name => "Nat. Semi. PC87366 Super IO Fan Sensors",
1413        driver => "pc87360",
1414        devid => 0xe9,
1415        logdev => 0x09,
1416      },
1417      {
1418        name => "Nat. Semi. PC87366 Super IO Voltage Sensors",
1419        driver => "pc87360",
1420        devid => 0xe9,
1421        logdev => 0x0d,
1422      },
1423      {
1424        name => "Nat. Semi. PC87366 Super IO Thermal Sensors",
1425        driver => "pc87360",
1426        devid => 0xe9,
1427        logdev => 0x0e,
1428      },
1429      {
1430        name => "Nat. Semi. PC87372 Super IO Fan Sensors",
1431        driver => "to-be-written",
1432        devid => 0xf0,
1433        logdev => 0x09,
1434      },
1435      {
1436        name => "Nat. Semi. PC87373 Super IO Fan Sensors",
1437        driver => "to-be-written",
1438        devid => 0xf3,
1439        logdev => 0x09,
1440      },
1441      {
1442        name => "Nat. Semi. PC87591 Super IO",
1443        driver => "to-be-written",
1444        devid => 0xec,
1445        logdev => 0x0f,
1446      },
1447      {
1448        name => "Nat. Semi. PC87317 Super IO",
1449        driver => "not-a-sensor",
1450        devid => 0xd0,
1451      },
1452      {
1453        name => "Nat. Semi. PC97317 Super IO",
1454        driver => "not-a-sensor",
1455        devid => 0xdf,
1456      },
1457      {
1458        name => "Nat. Semi. PC8739x Super IO",
1459        driver => "not-a-sensor",
1460        devid => 0xea,
1461      },
1462      {
1463        name => "Nat. Semi. PC8741x Super IO",
1464        driver => "not-a-sensor",
1465        devid => 0xee,
1466      },
1467      {
1468        name => "Nat. Semi. PC87427 Super IO Fan Sensors",
1469        driver => "pc87427",
1470        devid => 0xf2,
1471        logdev => 0x09,
1472      },
1473      {
1474        name => "Nat. Semi. PC87427 Super IO Health Sensors",
1475        driver => "to-be-written",
1476        devid => 0xf2,
1477        logdev => 0x14,
1478      },
1479    ],
1480  },
1481  {
1482    family => "SMSC",
1483    enter =>
1484    {
1485      0x2e => [0x55],
1486      0x4e => [0x55],
1487    },
1488    chips =>
1489    [
1490      {
1491        name => "SMSC DME1737 Super IO",
1492        # Hardware monitoring features are accessed on the SMBus
1493        driver => "via-smbus-only",
1494        devid => 0x78,
1495      },
1496      {
1497        name => "SMSC DME1737 Super IO",
1498        # The DME1737 shows up twice in this list because it can return either
1499        # 0x78 or 0x77 as its device ID.
1500        # Hardware monitoring features are accessed on the SMBus
1501        driver => "via-smbus-only",
1502        devid => 0x77,
1503      },
1504      {
1505        name => "SMSC EMC2700LPC Super IO",
1506        # no datasheet
1507        devid => 0x67,
1508      },
1509      {
1510        name => "SMSC FDC37B72x Super IO",
1511        driver => "not-a-sensor",
1512        devid => 0x4c,
1513      },
1514      {
1515        name => "SMSC FDC37B78x Super IO",
1516        driver => "not-a-sensor",
1517        devid => 0x44,
1518      },
1519      {
1520        name => "SMSC FDC37C672 Super IO",
1521        driver => "not-a-sensor",
1522        devid => 0x40,
1523      },
1524      {
1525        name => "SMSC FDC37M707 Super IO",
1526        driver => "not-a-sensor",
1527        devid => 0x42,
1528      },
1529      {
1530        name => "SMSC FDC37M81x Super IO",
1531        driver => "not-a-sensor",
1532        devid => 0x4d,
1533      },
1534      {
1535        name => "SMSC LPC47B27x Super IO Fan Sensors",
1536        driver => "smsc47m1",
1537        devid => 0x51,
1538        logdev => 0x0a,
1539      },
1540      {
1541        name => "SMSC LPC47B34x Super IO",
1542        driver => "not-a-sensor",
1543        devid => 0x56,
1544      },
1545      {
1546        name => "SMSC LPC47B357/M967 Super IO",
1547        driver => "not-a-sensor",
1548        devid => 0x5d,
1549      },
1550      {
1551        name => "SMSC LPC47B367-NC Super IO",
1552        driver => "not-a-sensor",
1553        devid => 0x6d,
1554      },
1555      {
1556        name => "SMSC LPC47B37x Super IO Fan Sensors",
1557        driver => "to-be-written",
1558        devid => 0x52,
1559        logdev => 0x0a,
1560      },
1561      {
1562        name => "SMSC LPC47B397-NC Super IO",
1563        driver => "smsc47b397",
1564        devid => 0x6f,
1565        logdev => 0x08,
1566      },
1567      {
1568        name => "SMSC LPC47M10x/112/13x Super IO Fan Sensors",
1569        driver => "smsc47m1",
1570        devid => 0x59,
1571        logdev => 0x0a,
1572      },
1573      {
1574        name => "SMSC LPC47M14x Super IO Fan Sensors",
1575        driver => "smsc47m1",
1576        devid => 0x5f,
1577        logdev => 0x0a,
1578      },
1579      {
1580        name => "SMSC LPC47M15x/192/997 Super IO Fan Sensors",
1581        driver => "smsc47m1",
1582        devid => 0x60,
1583        logdev => 0x0a,
1584      },
1585      {
1586        name => "SMSC LPC47M172 Super IO Fan Sensors",
1587        driver => "to-be-written",
1588        devid => 0x14,
1589        logdev => 0x0a,
1590      },
1591      {
1592        name => "SMSC LPC47M182 Super IO Fan Sensors",
1593        driver => "to-be-written",
1594        devid => 0x74,
1595        logdev => 0x0a,
1596      },
1597      {
1598        name => "SMSC LPC47M233 Super IO Sensors",
1599        driver => "smsc47m1",
1600        devid => 0x6b80,
1601        devid_mask => 0xff80,
1602        logdev => 0x0a,
1603      },
1604      {
1605        name => "SMSC LPC47M292 Super IO Fan Sensors",
1606        driver => "smsc47m1",
1607        devid => 0x6b00,
1608        devid_mask => 0xff80,
1609        logdev => 0x0a,
1610      },
1611      {
1612        name => "SMSC LPC47M584-NC Super IO",
1613        # No datasheet
1614        devid => 0x76,
1615      },
1616      {
1617        name => "SMSC LPC47N252 Super IO Fan Sensors",
1618        driver => "to-be-written",
1619        devid => 0x0e,
1620        logdev => 0x09,
1621      },
1622      {
1623        name => "SMSC LPC47S42x Super IO Fan Sensors",
1624        driver => "to-be-written",
1625        devid => 0x57,
1626        logdev => 0x0a,
1627      },
1628      {
1629        name => "SMSC LPC47S45x Super IO Fan Sensors",
1630        driver => "to-be-written",
1631        devid => 0x62,
1632        logdev => 0x0a,
1633      },
1634      {
1635        name => "SMSC LPC47U33x Super IO Fan Sensors",
1636        driver => "to-be-written",
1637        devid => 0x54,
1638        logdev => 0x0a,
1639      },
1640      {
1641        name => "SMSC SCH3112 Super IO",
1642        driver => "dme1737",
1643        devid => 0x7c,
1644        logdev => 0x0a,
1645      },
1646      {
1647        name => "SMSC SCH3114 Super IO",
1648        driver => "dme1737",
1649        devid => 0x7d,
1650        logdev => 0x0a,
1651      },
1652      {
1653        name => "SMSC SCH3116 Super IO",
1654        driver => "dme1737",
1655        devid => 0x7f,
1656        logdev => 0x0a,
1657      },
1658      {
1659        name => "SMSC SCH4307 Super IO Fan Sensors",
1660        driver => "to-be-written",
1661        devid => 0x90,
1662        logdev => 0x08,
1663      },
1664      {
1665        name => "SMSC SCH5027D-NW Super IO",
1666        # Hardware monitoring features are accessed on the SMBus
1667        driver => "via-smbus-only",
1668        devid => 0x89,
1669      },
1670      {
1671        name => "SMSC SCH5127 Super IO",
1672        driver => "dme1737",
1673        devid => 0x86,
1674        logdev => 0x0a,
1675      },
1676      {
1677        name => "SMSC SCH5307-NS Super IO",
1678        driver => "smsc47b397",
1679        devid => 0x81,
1680        logdev => 0x08,
1681      },
1682      {
1683        name => "SMSC SCH5317 Super IO",
1684        driver => "smsc47b397",
1685        devid => 0x85,
1686        logdev => 0x08,
1687      },
1688      {
1689        name => "SMSC SCH5317 Super IO",
1690        # The SCH5317 shows up twice in this list because it can return either
1691        # 0x85 or 0x8c as its device ID.
1692        driver => "smsc47b397",
1693        devid => 0x8c,
1694        logdev => 0x08,
1695      },
1696      {
1697        name => "SMSC SCH5504-NS Super IO",
1698        # No datasheet
1699        driver => "not-a-sensor",
1700        devid => 0x79,
1701      },
1702      {
1703        name => "SMSC SCH5514D-NS Super IO",
1704        # No datasheet
1705        driver => "not-a-sensor",
1706        devid => 0x83,
1707      },
1708    ],
1709    # Non-standard SMSC detection callback and chip list. These chips differ
1710    # from the standard ones listed above in that the device ID register
1711    # address is 0x0d instead of 0x20 (as specified by the ISA PNP spec).
1712    ns_detect => \&smsc_ns_detect_superio,
1713    ns_chips =>
1714    [
1715      {
1716        name => "SMSC FDC37C665 Super IO",
1717        driver => "not-a-sensor",
1718        devid => 0x65,
1719      },
1720      {
1721        name => "SMSC FDC37C666 Super IO",
1722        driver => "not-a-sensor",
1723        devid => 0x66,
1724      },
1725      {
1726        name => "SMSC FDC37C669 Super IO",
1727        driver => "not-a-sensor",
1728        devid => 0x03,
1729      },
1730      {
1731        name => "SMSC FDC37N769 Super IO",
1732        driver => "not-a-sensor",
1733        devid => 0x28,
1734      },
1735      {
1736        name => "SMSC LPC47N227 Super IO",
1737        driver => "not-a-sensor",
1738        devid => 0x5a,
1739      },
1740    ],
1741  },
1742  {
1743    family => "VIA/Winbond/Fintek",
1744    guess => 0x290,
1745    enter =>
1746    {
1747      0x2e => [0x87, 0x87],
1748      0x4e => [0x87, 0x87],
1749    },
1750    chips =>
1751    [
1752      {
1753        name => "VIA VT1211 Super IO Sensors",
1754        driver => "vt1211",
1755        devid => 0x3c,
1756        logdev => 0x0b,
1757        alias_detect => sub { vt1211_alias_detect(@_); },
1758      },
1759      {
1760        name => "VIA VT1212 Super IO Lite",   # in 100 pin TQFP package
1761        driver => "not-a-sensor",
1762        devid => 0x3e,
1763      },
1764      {
1765        name => "VIA VT1212 Super IO Lite",   # in 48 pin LQFP package
1766        driver => "not-a-sensor",
1767        devid => 0x3f,
1768      },
1769      {
1770        name => "Winbond W83627HF/F/HG/G Super IO Sensors",
1771        driver => "w83627hf",
1772        devid => 0x52,
1773        logdev => 0x0b,
1774        alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
1775      },
1776      {
1777        name => "Winbond W83627THF/THG Super IO Sensors",
1778        driver => "w83627hf",
1779        devid => 0x82,
1780        logdev => 0x0b,
1781      },
1782      {
1783        name => "Winbond W83637HF/HG Super IO Sensors",
1784        driver => "w83627hf",
1785        devid => 0x70,
1786        logdev => 0x0b,
1787      },
1788      {
1789        name => "Winbond W83687THF Super IO Sensors",
1790        driver => "w83627hf",
1791        devid => 0x85,
1792        logdev => 0x0b,
1793      },
1794      {
1795        name => "Winbond W83697HF/F/HG Super IO Sensors",
1796        driver => "w83627hf",
1797        devid => 0x60,
1798        logdev => 0x0b,
1799      },
1800      {
1801        name => "Winbond W83697SF/UF/UG Super IO PWM",
1802        driver => "to-be-written",
1803        devid => 0x68,
1804        logdev => 0x0b,
1805      },
1806      {
1807        name => "Winbond W83627EHF/EF/EHG/EG Super IO Sensors",
1808        driver => "w83627ehf",
1809        # W83627EHF datasheet says 0x886x but 0x8853 was seen, thus the
1810        # broader mask. W83627EHG was seen with ID 0x8863.
1811        devid => 0x8840,
1812        devid_mask => 0xFFC0,
1813        logdev => 0x0b,
1814        alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3e); },
1815      },
1816      {
1817        name => "Winbond W83627DHG Super IO Sensors",
1818        driver => "w83627ehf",
1819        devid => 0xA020,
1820        devid_mask => 0xFFF0,
1821        logdev => 0x0b,
1822        alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3e); },
1823      },
1824      {
1825        name => "Winbond W83L517D Super IO",
1826        driver => "not-a-sensor",
1827        devid => 0x61,
1828      },
1829      {
1830        name => "Fintek F71805F/FG Super IO Sensors",
1831        driver => "f71805f",
1832        devid => 0x0406,
1833        logdev => 0x04,
1834      },
1835      {
1836        name => "Fintek F71862FG Super IO Sensors",
1837        driver => "to-be-written",
1838        devid => 0x0601,
1839        logdev => 0x04,
1840      },
1841      {
1842        name => "Fintek F71806FG/F71872FG Super IO Sensors",
1843        driver => "f71805f",
1844        devid => 0x0341,
1845        logdev => 0x04,
1846      },
1847      {
1848        name => "Fintek F71858DG Super IO Sensors",
1849        driver => "to-be-written",
1850        devid => 0x0507,
1851        logdev => 0x02,
1852      },
1853      {
1854        name => "Fintek F71882FG/F71883FG Super IO Sensors",
1855        driver => "f71882fg",
1856        devid => 0x0541,
1857        logdev => 0x04,
1858      },
1859      {
1860        name => "Fintek F81216D Super IO",
1861        driver => "not-a-sensor",
1862        devid => 0x0208,
1863      },
1864      {
1865        name => "Fintek F81218D Super IO",
1866        driver => "not-a-sensor",
1867        devid => 0x0206,
1868      },
1869      {
1870        name => "Asus F8000 Super IO",
1871        driver => "f8000",
1872        devid => 0x0581,
1873        logdev => 0x04,
1874      },
1875      {
1876        # Shouldn't be in this family, but seems to be still.
1877        name => "ITE IT8708F Super IO",
1878        driver => "not-a-sensor",
1879        devid => 0x8708,
1880      },
1881    ],
1882  },
1883  {
1884    family => "ITE",
1885    guess => 0x290,
1886    enter =>
1887    {
1888      0x2e => [0x87, 0x01, 0x55, 0x55],
1889      0x4e => [0x87, 0x01, 0x55, 0xaa],
1890    },
1891    chips =>
1892    [
1893      {
1894        name => "ITE IT8702F Super IO Sensors",
1895        driver => "to-be-written",
1896        devid => 0x8702,
1897        logdev => 0x04,
1898      },
1899      {
1900        name => "ITE IT8705F Super IO Sensors",
1901        driver => "it87",
1902        devid => 0x8705,
1903        logdev => 0x04,
1904      },
1905      {
1906        name => "ITE IT8712F Super IO Sensors",
1907        driver => "it87",
1908        devid => 0x8712,
1909        logdev => 0x04,
1910        alias_detect => sub { winbond_alias_detect(@_, 0x30, 0x45); },
1911      },
1912      {
1913        name => "ITE IT8716F Super IO Sensors",
1914        driver => "it87",
1915        devid => 0x8716,
1916        logdev => 0x04,
1917      },
1918      {
1919        name => "ITE IT8718F Super IO Sensors",
1920        driver => "it87",
1921        devid => 0x8718,
1922        logdev => 0x04,
1923      },
1924      {
1925        name => "ITE IT8720F Super IO Sensors",
1926        driver => "it87",
1927        devid => 0x8720,
1928        logdev => 0x04,
1929      },
1930      {
1931        name => "ITE IT8726F Super IO Sensors",
1932        driver => "it87",
1933        devid => 0x8726,
1934        logdev => 0x04,
1935      },
1936    ],
1937  },
1938);
1939
1940# Drivers for CPU embedded sensors
1941# Each entry must have the following fields:
1942#  name: The CPU family name
1943#  driver: The driver name. Put "to-be-written" if no driver is available.
1944#  detect: Detection callback function. No parameter will be passed to
1945#          this function, it must use global lists of PCI devices, CPU,
1946#          etc. It must return a confidence value, undef if no supported
1947#          CPU is found.
1948@cpu_ids = (
1949  {
1950    name => "Silicon Integrated Systems SIS5595",
1951    driver => "sis5595",
1952    detect => sub { sis5595_pci_detect(); },
1953  },
1954  {
1955    name => "VIA VT82C686 Integrated Sensors",
1956    driver => "via686a",
1957    detect => sub { via686a_pci_detect(); },
1958  },
1959  {
1960    name => "VIA VT8231 Integrated Sensors",
1961    driver => "vt8231",
1962    detect => sub { via8231_pci_detect(); },
1963  },
1964  {
1965    name => "AMD K8 thermal sensors",
1966    driver => "k8temp",
1967    detect => sub { k8temp_pci_detect(); },
1968  },
1969  {
1970    name => "AMD K10 thermal sensors",
1971    driver => "to-be-written",
1972    detect => sub { k10temp_pci_detect(); },
1973  },
1974  {
1975    name => "Intel Core family thermal sensor",
1976    driver => "coretemp",
1977    detect => sub { coretemp_detect(); },
1978  },
1979  {
1980    name => "Intel AMB FB-DIMM thermal sensor",
1981    driver => "i5k_amb",
1982    detect => sub { intel_amb_detect(); },
1983  },
1984  {
1985    name => "VIA C7 thermal and voltage sensors",
1986    driver => "c7temp",
1987    detect => sub { c7temp_detect(); },
1988  },
1989);
1990
1991#######################
1992# AUXILIARY FUNCTIONS #
1993#######################
1994
1995sub swap_bytes
1996{
1997  return (($_[0] & 0xff00) >> 8) + (($_[0] & 0x00ff) << 8)
1998}
1999
2000# $_[0] is the sought value
2001# @_[1..] is the list to seek in
2002# Returns: 0 on failure, 1 if found.
2003# Note: Every use of this sub probably indicates the use of the wrong
2004#       datastructure
2005sub contains
2006{
2007  my $sought = shift;
2008  foreach (@_) {
2009    return 1 if $sought eq $_;
2010  }
2011  return 0;
2012}
2013
2014# Address can be decimal or hexadecimal
2015sub valid_address
2016{
2017  my $value = shift;
2018
2019  if ($value !~ m/^(0x[0-9a-f]+|[0-9]+)$/i) {
2020    print "$value is not a valid address, sorry.\n";
2021    exit -1;
2022  }
2023  $value = oct($value) if $value =~ /^0x/i;
2024
2025  return $value;
2026}
2027
2028sub parse_not_to_scan
2029{
2030  my ($min, $max, $to_parse) = @_;
2031  my @ranges = split /\s*, \s*/, $to_parse;
2032  my @res;
2033  my $range;
2034  foreach $range (@ranges) {
2035    my ($start, $end) = split /\s*-\s*/, $range;
2036    $start = valid_address($start);
2037    if (defined $end) {
2038      $end = valid_address($end);
2039      if ($end <= $start) {
2040        print "$start-$end is not a valid range, sorry.\n";
2041        exit -1;
2042      }
2043      $start = $min if $start < $min;
2044      $end = $max if $end > $max;
2045      push @res, ($start..$end);
2046    } else {
2047      push @res, $start if $start >= $min and $start <= $max;
2048    }
2049  }
2050  return sort { $a <=> $b } @res;
2051}
2052
2053# @_[0]: Reference to list 1
2054# @_[1]: Reference to list 2
2055# Result: 0 if they have no elements in common, 1 if they have
2056# Elements must be numeric.
2057sub any_list_match
2058{
2059  my ($list1, $list2) = @_;
2060  my ($el1, $el2);
2061  foreach $el1 (@$list1) {
2062    foreach $el2 (@$list2) {
2063      return 1 if $el1 == $el2;
2064    }
2065  }
2066  return 0;
2067}
2068
2069###################
2070# I/O port access #
2071###################
2072
2073sub initialize_ioports
2074{
2075  sysopen(IOPORTS, "/dev/port", O_RDWR)
2076    or die "/dev/port: $!\n";
2077  binmode(IOPORTS);
2078}
2079
2080sub close_ioports
2081{
2082  close(IOPORTS)
2083    or print "Warning: $!\n";
2084}
2085
2086# $_[0]: port to read
2087# Returns: -1 on failure, read value on success.
2088sub inb
2089{
2090  my ($res, $nrchars);
2091  sysseek(IOPORTS, $_[0], 0) or return -1;
2092  $nrchars = sysread(IOPORTS, $res, 1);
2093  return -1 if not defined $nrchars or $nrchars != 1;
2094  $res = unpack("C", $res);
2095  return $res;
2096}
2097
2098# $_[0]: port to write
2099# $_[1]: value to write
2100# Returns: -1 on failure, 0 on success.
2101sub outb
2102{
2103  my $towrite = pack("C", $_[1]);
2104  sysseek(IOPORTS, $_[0], 0) or return -1;
2105  my $nrchars = syswrite(IOPORTS, $towrite, 1);
2106  return -1 if not defined $nrchars or $nrchars != 1;
2107  return 0;
2108}
2109
2110# $_[0]: Address register
2111# $_[1]: Data register
2112# $_[2]: Register to read
2113# Returns: read value
2114sub isa_read_byte
2115{
2116  outb($_[0], $_[2]);
2117  return inb($_[1]);
2118}
2119
2120# $_[0]: Base address
2121# $_[1]: Register to read
2122# Returns: read value
2123# This one can be used for any ISA chip with index register at
2124# offset 5 and data register at offset 6.
2125sub isa_read_i5d6
2126{
2127  my ($addr, $reg) = @_;
2128  return isa_read_byte($addr + 5, $addr + 6, $reg);
2129}
2130
2131#################
2132# AUTODETECTION #
2133#################
2134
2135use vars qw($dev_i2c $sysfs_root);
2136
2137sub initialize_conf
2138{
2139  my $use_devfs = 0;
2140  open(local *INPUTFILE, "/proc/mounts") or die "Can't access /proc/mounts!";
2141  local $_;
2142  while (<INPUTFILE>) {
2143    if (m@^\w+ /dev devfs @) {
2144      $use_devfs = 1;
2145      $dev_i2c = '/dev/i2c/';
2146    }
2147    if (m@^\S+ (/\w+) sysfs @) {
2148      $sysfs_root = $1;
2149    }
2150  }
2151  close(INPUTFILE);
2152
2153  # We need sysfs for many things
2154  if (!defined $sysfs_root) {
2155      print "Sysfs not mounted?\n";
2156      exit -1;
2157  }
2158
2159  my $use_udev = 0;
2160  if (open(*INPUTFILE, '/etc/udev/udev.conf')) {
2161    while (<INPUTFILE>) {
2162      if (m/^\s*udev_db\s*=\s*\"([^"]*)\"/ || m/^\s*udev_db\s*=\s*(\S+)/) {
2163        if (-e $1) {
2164          $use_udev = 1;
2165          $dev_i2c = '/dev/i2c-';
2166        }
2167        last;
2168      }
2169    }
2170    close(INPUTFILE);
2171  }
2172
2173  if (!$use_udev) {
2174    # Try some known default udev db locations, just in case
2175    if (-e '/dev/.udev.tdb' || -e '/dev/.udev'
2176     || -e '/dev/.udevdb') {
2177      $use_udev = 1;
2178      $dev_i2c = '/dev/i2c-';
2179    }
2180  }
2181
2182  if (!($use_devfs || $use_udev)) {
2183    if (! -c '/dev/i2c-0' && -x '/sbin/MAKEDEV') {
2184      system("/sbin/MAKEDEV i2c");
2185    }
2186    if (! -c '/dev/i2c-0' && -x '/dev/MAKEDEV') {
2187      system("/dev/MAKEDEV i2c");
2188    }
2189    if (-c '/dev/i2c-0') {
2190      $dev_i2c = '/dev/i2c-';
2191    } else { # default
2192      print "No i2c device files found.\n";
2193      exit -1;
2194    }
2195  }
2196}
2197
2198# [0] -> VERSION
2199# [1] -> PATCHLEVEL
2200# [2] -> SUBLEVEL
2201# [3] -> EXTRAVERSION
2202#
2203use vars qw(@kernel_version $kernel_arch);
2204
2205sub initialize_kernel_version
2206{
2207  `uname -r` =~ /(\d+)\.(\d+)\.(\d+)(.*)/;
2208  @kernel_version = ($1, $2, $3, $4);
2209  chomp($kernel_arch = `uname -m`);
2210
2211  # We only support kernels >= 2.6.0
2212  if (!kernel_version_at_least(2, 6, 0)) {
2213      print "Kernel version is unsupported (too old, >= 2.6.0 needed)\n";
2214      exit -1;
2215  }
2216}
2217
2218sub kernel_version_at_least
2219{
2220  my ($vers, $plvl, $slvl) = @_;
2221  return 1 if ($kernel_version[0]  > $vers ||
2222                ($kernel_version[0] == $vers &&
2223                  ($kernel_version[1]  > $plvl ||
2224                    ($kernel_version[1] == $plvl &&
2225                      ($kernel_version[2] >= $slvl)))));
2226  return 0;
2227}
2228
2229# @cpu is a list of reference to hashes, one hash per CPU.
2230# Each entry has the following keys: vendor_id, cpu family, model,
2231# model name and stepping, directly taken from /proc/cpuinfo.
2232use vars qw(@cpu);
2233
2234sub initialize_cpu_list
2235{
2236  open(local *INPUTFILE, "/proc/cpuinfo") or die "Can't access /proc/cpuinfo!";
2237  local $_;
2238  my $entry;
2239
2240  while (<INPUTFILE>) {
2241    if (m/^processor\s*:\s*(\d+)/) {
2242      push @cpu, $entry if scalar keys(%{$entry}); # Previous entry
2243      $entry = {}; # New entry
2244      next;
2245    }
2246    if (m/^(vendor_id|cpu family|model|model name|stepping)\s*:\s*(.+)$/) {
2247      my $k = $1;
2248      my $v = $2;
2249      $v =~ s/\s+/ /g;  # Merge multiple spaces
2250      $v =~ s/ $//;     # Trim trailing space
2251      $entry->{$k} = $v;
2252      next;
2253    }
2254  }
2255  push @cpu, $entry if scalar keys(%{$entry}); # Last entry
2256  close(INPUTFILE);
2257}
2258
2259# @i2c_adapters is a list of references to hashes, one hash per I2C/SMBus
2260# adapter present on the system. Each entry has the following keys: name
2261# (directly taken from /sys/class/i2c-adapter) and driver.
2262use vars qw(@i2c_adapters);
2263
2264sub initialize_i2c_adapters_list
2265{
2266  my $entry;
2267  local $_;
2268
2269  my $class_dir = "${sysfs_root}/class/i2c-adapter";
2270  opendir(local *ADAPTERS, $class_dir) or return;
2271
2272  while (defined($_ = readdir(ADAPTERS))) {
2273    next unless m/^i2c-(\d+)$/;
2274    $entry = {}; # New entry
2275    $entry->{'name'} = sysfs_device_attribute("${class_dir}/i2c-$1", "name")
2276                    || sysfs_device_attribute("${class_dir}/i2c-$1/device", "name");
2277    next if $entry->{'name'} eq "ISA main adapter";
2278
2279    # First try to get the I2C adapter driver name from sysfs, and if it
2280    # fails, fall back to searching our list of known I2C adapters.
2281    $entry->{'driver'} = sysfs_device_driver("${class_dir}/i2c-$1/device")
2282                      || find_i2c_adapter_driver($entry->{'name'})
2283                      || 'UNKNOWN';
2284    $i2c_adapters[$1] = $entry;
2285  }
2286  closedir(ADAPTERS);
2287}
2288
2289###########
2290# MODULES #
2291###########
2292
2293use vars qw(%modules_list %modules_supported);
2294
2295sub initialize_modules_list
2296{
2297  open(local *INPUTFILE, "/proc/modules") or return;
2298  local $_;
2299  while (<INPUTFILE>) {
2300    tr/_/-/;
2301    $modules_list{$1} = 1 if m/^(\S*)/;
2302  }
2303}
2304
2305sub initialize_modules_supported
2306{
2307  foreach my $chip (@chip_ids) {
2308    $modules_supported{$chip->{driver}}++;
2309  }
2310}
2311
2312#################
2313# SYSFS HELPERS #
2314#################
2315
2316# From a sysfs device path, return the driver (module) name, or undef
2317sub sysfs_device_driver($)
2318{
2319  my $device = shift;
2320
2321  my $link = readlink("$device/driver/module");
2322  return unless defined $link;
2323  return basename($link);
2324}
2325
2326# From a sysfs device path and an attribute name, return the attribute
2327# value, or undef
2328sub sysfs_device_attribute($$)
2329{
2330  my ($device, $attr) = @_;
2331  my $value;
2332
2333  open(local *FILE, "$device/$attr") or return;
2334  return unless defined($value = <FILE>);
2335  close(FILE);
2336
2337  chomp($value);
2338  return $value;
2339}
2340
2341##############
2342# PCI ACCESS #
2343##############
2344
2345use vars qw(%pci_list);
2346
2347# This function returns a list of hashes. Each hash has some PCI information:
2348# 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a
2349# computer; 'vendid' and 'devid' uniquely identify a type of device.
2350# 'class' lets us spot unknown SMBus adapters.
2351sub read_sys_dev_pci($)
2352{
2353  my $devices = shift;
2354  my ($dev, @pci_list);
2355
2356  opendir(local *DEVICES, "$devices")
2357    or die "$devices: $!";
2358
2359  while (defined($dev = readdir(DEVICES))) {
2360    my %record;
2361    next unless $dev =~
2362      m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/;
2363
2364    $record{domain} = hex $1;
2365    $record{bus} = hex $2;
2366    $record{slot} = hex $3;
2367    $record{func} = hex $4;
2368
2369    $record{vendid} = oct sysfs_device_attribute("$devices/$dev", "vendor");
2370    $record{devid} = oct sysfs_device_attribute("$devices/$dev", "device");
2371    $record{class} = (oct sysfs_device_attribute("$devices/$dev", "class"))
2372                     >> 8;
2373
2374    push @pci_list, \%record;
2375  }
2376
2377  return \@pci_list;
2378}
2379
2380sub initialize_pci
2381{
2382  my $pci_list;
2383
2384  $pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices");
2385
2386  # Note that we lose duplicate devices at this point, but we don't
2387  # really care. What matters to us is which unique devices are present,
2388  # not how many of each.
2389  %pci_list = map {
2390    sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_
2391  } @{$pci_list};
2392}
2393
2394#####################
2395# ADAPTER DETECTION #
2396#####################
2397
2398sub adapter_pci_detection_sis_96x
2399{
2400  my $driver = "";
2401
2402  # first, determine which driver if any...
2403  if (exists $pci_list{"1039:0016"}) {
2404    $driver = "i2c-sis96x";
2405  } elsif (exists $pci_list{"1039:0008"}) {
2406    $driver = "i2c-sis5595";
2407  }
2408
2409  # then, add the appropriate entries to @pci_adapters
2410  if ($driver eq "i2c-sis5595") {
2411    push @pci_adapters, @pci_adapters_sis5595;
2412  } elsif ($driver eq "i2c-sis96x") {
2413    push @pci_adapters, @pci_adapters_sis96x;
2414  }
2415}
2416
2417# Build and return a PCI device's bus ID
2418sub pci_busid($)
2419{
2420  my $device = shift;
2421  my $busid;
2422
2423  $busid = sprintf("\%02x:\%02x.\%x",
2424                   $device->{bus}, $device->{slot}, $device->{func});
2425  $busid = sprintf("\%04x:", $device->{domain}) . $busid
2426    if defined $device->{domain};
2427
2428  return $busid;
2429}
2430
2431sub adapter_pci_detection
2432{
2433  my ($key, $device, $try, @res, %smbus);
2434  print "Probing for PCI bus adapters...\n";
2435
2436  # Custom detection routine for some SiS chipsets
2437  adapter_pci_detection_sis_96x();
2438
2439  # Build a list of detected SMBus devices
2440  foreach $key (keys %pci_list) {
2441    $device = $pci_list{$key};
2442    $smbus{$key}++
2443      if exists $device->{class} && $device->{class} == 0x0c05; # SMBus
2444  }
2445
2446  # Loop over the known I2C/SMBus adapters
2447  foreach $try (@pci_adapters) {
2448    $key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid});
2449    if (exists $pci_list{$key}) {
2450        $device = $pci_list{$key};
2451        if ($try->{driver} =~ m/^to-be-/) {
2452          printf "No known driver for device \%s: \%s\n",
2453                 pci_busid($device), $try->{procid};
2454
2455          if ($try->{driver} eq "to-be-tested") {
2456            print "\nWe are currently looking for testers for this adapter!\n".
2457                  "Please check http://www.lm-sensors.org/wiki/Devices\n".
2458                  "and/or contact us if you want to help.\n\n";
2459            print "Continue... ";
2460            <STDIN>;
2461            print "\n";
2462          }
2463        } else {
2464          printf "Use driver `\%s' for device \%s: \%s\n",
2465                 $try->{driver}, pci_busid($device), $try->{procid};
2466          push @res, $try->{driver};
2467        }
2468
2469        # Delete from detected SMBus device list
2470        delete $smbus{$key};
2471    }
2472  }
2473
2474  # Now see if there are unknown SMBus devices left
2475  foreach $key (keys %smbus) {
2476    $device = $pci_list{$key};
2477    printf "Found unknown SMBus adapter \%04x:\%04x at \%s.\n",
2478           $device->{vendid}, $device->{devid}, pci_busid($device);
2479  }
2480
2481  if (! @res) {
2482    print "Sorry, no supported PCI bus adapters found.\n";
2483  }
2484  return @res;
2485}
2486
2487# $_[0]: Adapter description as found in /sys/class/i2c-adapter
2488sub find_i2c_adapter_driver
2489{
2490        my $name = shift;
2491        my $entry;
2492
2493        foreach $entry (@i2c_adapter_names) {
2494                return $entry->{driver}
2495                        if $name =~ $entry->{match};
2496        }
2497}
2498
2499#############################
2500# I2C AND SMBUS /DEV ACCESS #
2501#############################
2502
2503# This should really go into a separate module/package.
2504
2505# These are copied from <linux/i2c-dev.h>
2506
2507use constant IOCTL_I2C_SLAVE    => 0x0703;
2508use constant IOCTL_I2C_FUNCS    => 0x0705;
2509use constant IOCTL_I2C_SMBUS    => 0x0720;
2510
2511use constant SMBUS_READ         => 1;
2512use constant SMBUS_WRITE        => 0;
2513
2514use constant SMBUS_QUICK        => 0;
2515use constant SMBUS_BYTE         => 1;
2516use constant SMBUS_BYTE_DATA    => 2;
2517use constant SMBUS_WORD_DATA    => 3;
2518
2519use constant I2C_FUNC_SMBUS_QUICK       => 0x00010000;
2520use constant I2C_FUNC_SMBUS_READ_BYTE   => 0x00020000;
2521
2522# Get the i2c adapter's functionalities
2523# $_[0]: Reference to an opened filehandle
2524# Returns: -1 on failure, functionality bitfield on success.
2525sub i2c_get_funcs($)
2526{
2527  my $file = shift;
2528  my $funcs = pack("L", 0); # Allocate space
2529
2530  ioctl($file, IOCTL_I2C_FUNCS, $funcs) or return -1;
2531  $funcs = unpack("L", $funcs);
2532
2533  return $funcs;
2534}
2535
2536# Select the device to communicate with through its address.
2537# $_[0]: Reference to an opened filehandle
2538# $_[1]: Address to select
2539# Returns: 0 on failure, 1 on success.
2540sub i2c_set_slave_addr
2541{
2542  my ($file, $addr) = @_;
2543
2544  # Reset register data cache
2545  @i2c_byte_cache = ();
2546
2547  $addr += 0; # Make sure it's a number not a string
2548  ioctl($file, IOCTL_I2C_SLAVE, $addr) or return 0;
2549  return 1;
2550}
2551
2552# i2c_smbus_access is based upon the corresponding C function (see
2553# <linux/i2c-dev.h>). You should not need to call this directly.
2554# Exact calling conventions are intricate; read i2c-dev.c if you really need
2555# to know.
2556# $_[0]: Reference to an opened filehandle
2557# $_[1]: SMBUS_READ for reading, SMBUS_WRITE for writing
2558# $_[2]: Command (usually register number)
2559# $_[3]: Transaction kind (SMBUS_BYTE, SMBUS_BYTE_DATA, etc.)
2560# $_[4]: Reference to an array used for input/output of data
2561# Returns: 0 on failure, 1 on success.
2562# Note that we need to get back to Integer boundaries through the 'x2'
2563# in the pack. This is very compiler-dependent; I wish there was some other
2564# way to do this.
2565sub i2c_smbus_access
2566{
2567  my ($file, $read_write, $command, $size, $data) = @_;
2568  my $data_array = pack("C32", @$data);
2569  my $ioctl_data = pack("C2x2Ip", $read_write, $command, $size, $data_array);
2570  ioctl($file, IOCTL_I2C_SMBUS, $ioctl_data) or return 0;
2571  @{$_[4]} = unpack("C32", $data_array);
2572  return 1;
2573}
2574
2575# $_[0]: Reference to an opened filehandle
2576# Returns: -1 on failure, the read byte on success.
2577sub i2c_smbus_read_byte
2578{
2579  my ($file) = @_;
2580  my @data;
2581  i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, \@data)
2582         or return -1;
2583  return $data[0];
2584}
2585
2586# $_[0]: Reference to an opened filehandle
2587# $_[1]: Command byte (usually register number)
2588# Returns: -1 on failure, the read byte on success.
2589# Read byte data values are cached by default. As we keep reading the
2590# same registers over and over again in the detection functions, and
2591# SMBus can be slow, caching results in a big performance boost.
2592sub i2c_smbus_read_byte_data
2593{
2594  my ($file, $command, $nocache) = @_;
2595  my @data;
2596  if (!$nocache && exists $i2c_byte_cache[$command]) {
2597    return $i2c_byte_cache[$command];
2598  }
2599  i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_BYTE_DATA, \@data)
2600         or return -1;
2601  return ($i2c_byte_cache[$command] = $data[0]);
2602}
2603
2604# $_[0]: Reference to an opened filehandle
2605# $_[1]: Command byte (usually register number)
2606# Returns: -1 on failure, the read word on success.
2607# Use this function with care, some devices don't like word reads,
2608# so you should do as much of the detection as possible using byte reads,
2609# and only start using word reads when there is a good chance that
2610# the detection will succeed.
2611# Note: some devices use the wrong endiannes; use swap_bytes to correct for
2612# this.
2613sub i2c_smbus_read_word_data
2614{
2615  my ($file, $command) = @_;
2616  my @data;
2617  i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_WORD_DATA, \@data)
2618         or return -1;
2619  return $data[0] + 256 * $data[1];
2620}
2621
2622# $_[0]: Reference to an opened filehandle
2623# $_[1]: Address
2624# $_[2]: Functionalities of this i2c adapter
2625# Returns: 1 on successful probing, 0 else.
2626# This function is meant to prevent AT24RF08 corruption and write-only
2627# chips locks. This is done by choosing the best probing method depending
2628# on the address range.
2629sub i2c_probe($$$)
2630{
2631  my ($file, $addr, $funcs) = @_;
2632  my $data = [];
2633  if (($addr >= 0x50 && $addr <= 0x5F)
2634   || ($addr >= 0x30 && $addr <= 0x37)) {
2635    # This covers all EEPROMs we know of, including page protection addresses.
2636    # Note that some page protection addresses will not reveal themselves with
2637    # this, because they ack on write only, but this is probably better since
2638    # some EEPROMs write-protect themselves permanently on almost any write to
2639    # their page protection address.
2640    return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE);
2641    return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, $data);
2642  } else {
2643    return 0 unless ($funcs & I2C_FUNC_SMBUS_QUICK);
2644    return i2c_smbus_access($file, SMBUS_WRITE, 0, SMBUS_QUICK, $data);
2645  }
2646}
2647
2648# $_[0]: Reference to an opened file handle
2649# Returns: 1 if the device is safe to access, 0 else.
2650# This function is meant to prevent access to 1-register-only devices,
2651# which are designed to be accessed with SMBus receive byte and SMBus send
2652# byte transactions (i.e. short reads and short writes) and treat SMBus
2653# read byte as a real write followed by a read. The device detection
2654# routines would write random values to the chip with possibly very nasty
2655# results for the hardware. Note that this function won't catch all such
2656# chips, as it assumes that reads and writes relate to the same register,
2657# but that's the best we can do.
2658sub i2c_safety_check
2659{
2660  my ($file) = @_;
2661  my $data;
2662
2663  # First we receive a byte from the chip, and remember it.
2664  $data = i2c_smbus_read_byte($file);
2665  return 1 if ($data < 0);
2666
2667  # We receive a byte again; very likely to be the same for
2668  # 1-register-only devices.
2669  return 1 if (i2c_smbus_read_byte($file) != $data);
2670
2671  # Then we try a standard byte read, with a register offset equal to
2672  # the byte we received; we should receive the same byte value in return.
2673  return 1 if (i2c_smbus_read_byte_data($file, $data) != $data);
2674
2675  # Then we try a standard byte read, with a slightly different register
2676  # offset; we should again receive the same byte value in return.
2677  return 1 if (i2c_smbus_read_byte_data($file, $data ^ 1) != ($data ^ 1));
2678
2679  # Apprently this is a 1-register-only device, restore the original register
2680  # value and leave it alone.
2681  i2c_smbus_read_byte_data($file, $data);
2682  return 0;
2683}
2684
2685####################
2686# ADAPTER SCANNING #
2687####################
2688
2689use vars qw(@chips_detected);
2690
2691# We will build a complicated structure @chips_detected here, being:
2692# A list of
2693#  references to hashes
2694#    with field 'driver', being a string with the driver name for this chip;
2695#    with field 'detected'
2696#      being a reference to a list of
2697#        references to hashes of type 'detect_data';
2698#    with field 'misdetected'
2699#      being a reference to a list of
2700#        references to hashes of type 'detect_data'
2701
2702# Type detect_data:
2703# A hash
2704#   with field 'i2c_adap' containing an adapter string as appearing
2705#        in /sys/class/i2c-adapter (if this is an I2C detection)
2706#  with field 'i2c_devnr', contianing the /dev/i2c-* number of this
2707#       adapter (if this is an I2C detection)
2708#  with field 'i2c_driver', containing the driver name for this adapter
2709#       (if this is an I2C detection)
2710#  with field 'i2c_addr', containing the I2C address of the detection;
2711#       (if this is an I2C detection)
2712#  with field 'i2c_sub_addrs', containing a reference to a list of
2713#       other I2C addresses (if this is an I2C detection)
2714#  with field 'isa_addr' containing the ISA address this chip is on
2715#       (if this is an ISA detection)
2716#  with field 'conf', containing the confidence level of this detection
2717#  with field 'chipname', containing the chip name
2718
2719# This adds a detection to the above structure. We do no alias detection
2720# here; so you should do ISA detections *after* all I2C detections.
2721# Not all possibilities of i2c_addr and i2c_sub_addrs are exhausted.
2722# In all normal cases, it should be all right.
2723# $_[0]: chip driver
2724# $_[1]: reference to data hash
2725# Returns: Nothing
2726sub add_i2c_to_chips_detected
2727{
2728  my ($chipdriver, $datahash) = @_;
2729  my ($i, $new_detected_ref, $new_misdetected_ref, $detected_ref, $misdetected_ref,
2730      $main_entry, $detected_entry, $put_in_detected, @hash_addrs, @entry_addrs,
2731      $do_not_add);
2732
2733  # First determine where the hash has to be added.
2734  for ($i = 0; $i < @chips_detected; $i++) {
2735    last if ($chips_detected[$i]->{driver} eq $chipdriver);
2736  }
2737  if ($i == @chips_detected) {
2738    push @chips_detected, { driver => $chipdriver,
2739                            detected => [],
2740                            misdetected => [] };
2741  }
2742  $new_detected_ref = $chips_detected[$i]->{detected};
2743  $new_misdetected_ref = $chips_detected[$i]->{misdetected};
2744
2745  # Find out whether our new entry should go into the detected or the
2746  # misdetected list. We compare all i2c addresses; if at least one matches,
2747  # but our conf value is lower, we assume this is a misdetect.
2748  @hash_addrs = ($datahash->{i2c_addr});
2749  push @hash_addrs, @{$datahash->{i2c_sub_addrs}}
2750       if exists $datahash->{i2c_sub_addrs};
2751  $put_in_detected = 1;
2752  $do_not_add = 0;
2753  FIND_LOOP:
2754  foreach $main_entry (@chips_detected) {
2755    foreach $detected_entry (@{$main_entry->{detected}}) {
2756      @entry_addrs = ($detected_entry->{i2c_addr});
2757      push @entry_addrs, @{$detected_entry->{i2c_sub_addrs}}
2758               if exists $detected_entry->{i2c_sub_addrs};
2759      if ($detected_entry->{i2c_devnr} == $datahash->{i2c_devnr} and
2760          any_list_match(\@entry_addrs, \@hash_addrs)) {
2761        if ($detected_entry->{conf} >= $datahash->{conf}) {
2762          $put_in_detected = 0;
2763        }
2764        if ($chipdriver eq $main_entry->{driver}) {
2765          $do_not_add = 1;
2766        }
2767        last FIND_LOOP;
2768      }
2769    }
2770  }
2771
2772  if ($put_in_detected) {
2773    # Here, we move all entries from detected to misdetected which
2774    # match at least in one main or sub address. This may not be the
2775    # best idea to do, as it may remove detections without replacing
2776    # them with second-best ones. Too bad.
2777    # (Khali 2003-09-13) If the driver is the same, the "misdetected"
2778    # entry is simply deleted; failing to do so cause the configuration
2779    # lines generated later to look very confusing (the driver will
2780    # be told to ignore valid addresses).
2781    @hash_addrs = ($datahash->{i2c_addr});
2782    push @hash_addrs, @{$datahash->{i2c_sub_addrs}}
2783         if exists $datahash->{i2c_sub_addrs};
2784    foreach $main_entry (@chips_detected) {
2785      $detected_ref = $main_entry->{detected};
2786      $misdetected_ref = $main_entry->{misdetected};
2787      for ($i = @$detected_ref-1; $i >=0; $i--) {
2788        @entry_addrs = ($detected_ref->[$i]->{i2c_addr});
2789        push @entry_addrs, @{$detected_ref->[$i]->{i2c_sub_addrs}}
2790             if exists $detected_ref->[$i]->{i2c_sub_addrs};
2791        if ($detected_ref->[$i]->{i2c_devnr} == $datahash->{i2c_devnr} and
2792            any_list_match(\@entry_addrs, \@hash_addrs)) {
2793          push @$misdetected_ref, $detected_ref->[$i]
2794            unless $chipdriver eq $main_entry->{driver};
2795          splice @$detected_ref, $i, 1;
2796        }
2797      }
2798    }
2799
2800    # Now add the new entry to detected
2801    push @$new_detected_ref, $datahash;
2802  } else {
2803    # No hard work here
2804    push @$new_misdetected_ref, $datahash
2805      unless $do_not_add;
2806  }
2807}
2808
2809# This adds a detection to the above structure. We also do alias detection
2810# here; so you should do ISA detections *after* all I2C detections.
2811# $_[0]: alias detection function
2812# $_[1]: chip driver
2813# $_[2]: reference to data hash
2814# Returns: 0 if it is not an alias, datahash reference if it is.
2815sub add_isa_to_chips_detected
2816{
2817  my ($alias_detect, $chipdriver, $datahash) = @_;
2818  my ($i, $new_detected_ref, $new_misdetected_ref, $detected_ref, $misdetected_ref,
2819      $main_entry, $isalias);
2820
2821  # First determine where the hash has to be added.
2822  $isalias = 0;
2823  for ($i = 0; $i < @chips_detected; $i++) {
2824    last if ($chips_detected[$i]->{driver} eq $chipdriver);
2825  }
2826  if ($i == @chips_detected) {
2827    push @chips_detected, { driver => $chipdriver,
2828                            detected => [],
2829                            misdetected => [] };
2830  }
2831  $new_detected_ref = $chips_detected[$i]->{detected};
2832  $new_misdetected_ref = $chips_detected[$i]->{misdetected};
2833
2834  # Now, we are looking for aliases. An alias can only be the same chiptype.
2835  # If an alias is found in the misdetected list, we add the new information
2836  # and terminate this function. If it is found in the detected list, we
2837  # still have to check whether another chip has claimed this ISA address.
2838  # So we remove the old entry from the detected list and put it in datahash.
2839
2840  # Misdetected alias detection:
2841  for ($i = 0; $i < @$new_misdetected_ref; $i++) {
2842    if (exists $new_misdetected_ref->[$i]->{i2c_addr} and
2843        not exists $new_misdetected_ref->[$i]->{isa_addr} and
2844        defined $alias_detect and
2845        $new_misdetected_ref->[$i]->{chipname} eq $datahash->{chipname}) {
2846      open(local *FILE, "$dev_i2c$new_misdetected_ref->[$i]->{i2c_devnr}") or
2847        print("Can't open $dev_i2c$new_misdetected_ref->[$i]->{i2c_devnr}?!?\n"),
2848        next;
2849      binmode(FILE);
2850      i2c_set_slave_addr(\*FILE, $new_misdetected_ref->[$i]->{i2c_addr}) or
2851           print("Can't set I2C address for ",
2852                 "$dev_i2c$new_misdetected_ref->[$i]->{i2c_devnr}?!?\n"),
2853           next;
2854      if (&$alias_detect ($datahash->{isa_addr}, \*FILE,
2855                          $new_misdetected_ref->[$i]->{i2c_addr})) {
2856        $new_misdetected_ref->[$i]->{isa_addr} = $datahash->{isa_addr};
2857        return $new_misdetected_ref->[$i];
2858      }
2859    }
2860  }
2861
2862  # Detected alias detection:
2863  for ($i = 0; $i < @$new_detected_ref; $i++) {
2864    if (exists $new_detected_ref->[$i]->{i2c_addr} and
2865        not exists $new_detected_ref->[$i]->{isa_addr} and
2866        defined $alias_detect and
2867        $new_detected_ref->[$i]->{chipname} eq $datahash->{chipname}) {
2868      open(local *FILE, "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}") or
2869        print("Can't open $dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"),
2870        next;
2871      binmode(FILE);
2872      i2c_set_slave_addr(\*FILE, $new_detected_ref->[$i]->{i2c_addr}) or
2873           print("Can't set I2C address for ",
2874                 "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"),
2875           next;
2876      if (&$alias_detect ($datahash->{isa_addr}, \*FILE,
2877                          $new_detected_ref->[$i]->{i2c_addr})) {
2878        $new_detected_ref->[$i]->{isa_addr} = $datahash->{isa_addr};
2879        ($datahash) = splice (@$new_detected_ref, $i, 1);
2880        $isalias = 1;
2881        last;
2882      }
2883    }
2884  }
2885
2886
2887  # Find out whether our new entry should go into the detected or the
2888  # misdetected list. We only compare main isa_addr here, of course.
2889  # (Khali 2004-05-12) If the driver is the same, the "misdetected"
2890  # entry is simply deleted; same we do for I2C chips.
2891  foreach $main_entry (@chips_detected) {
2892    $detected_ref = $main_entry->{detected};
2893    $misdetected_ref = $main_entry->{misdetected};
2894    for ($i = 0; $i < @{$main_entry->{detected}}; $i++) {
2895      if (exists $detected_ref->[$i]->{isa_addr} and
2896          exists $datahash->{isa_addr} and
2897          $detected_ref->[$i]->{isa_addr} == $datahash->{isa_addr}) {
2898        if ($detected_ref->[$i]->{conf} >= $datahash->{conf}) {
2899          push @$new_misdetected_ref, $datahash
2900            unless $main_entry->{driver} eq $chipdriver;
2901        } else {
2902          push @$misdetected_ref, $detected_ref->[$i]
2903            unless $main_entry->{driver} eq $chipdriver;
2904          splice @$detected_ref, $i, 1;
2905          push @$new_detected_ref, $datahash;
2906        }
2907        if ($isalias) {
2908          return $datahash;
2909        } else {
2910          return 0;
2911        }
2912      }
2913    }
2914  }
2915
2916  # Not found? OK, put it in the detected list
2917  push @$new_detected_ref, $datahash;
2918  if ($isalias) {
2919    return $datahash;
2920  } else {
2921    return 0;
2922  }
2923}
2924
2925# From the list of known I2C/SMBus devices, build a list of I2C addresses
2926# which are worth probing. There's no point in probing an address for which
2927# we don't know a single device, and probing some addresses has caused
2928# random trouble in the past.
2929sub i2c_addresses_to_scan()
2930{
2931  my @used;
2932  my @addresses;
2933  my $addr;
2934
2935  foreach my $chip (@chip_ids) {
2936    next unless defined $chip->{'i2c_addrs'};
2937    next if $chip->{'driver'} eq 'not-a-sensor';
2938    foreach $addr (@{$chip->{'i2c_addrs'}}) {
2939      $used[$addr]++;
2940    }
2941  }
2942
2943  for ($addr = 0x03; $addr <= 0x77; $addr++) {
2944    push @addresses, $addr if $used[$addr];
2945  }
2946  return \@addresses;
2947}
2948
2949# $_[0]: The number of the adapter to scan
2950# $_[1]: The name of the adapter, as appearing in /sys/class/i2c-adapter
2951# $_[2]: The driver of the adapter
2952# @_[3]: Addresses not to scan (array reference)
2953sub scan_adapter
2954{
2955  my ($adapter_nr, $adapter_name, $adapter_driver, $not_to_scan) = @_;
2956  my ($funcs, $chip, $addr, $conf, @chips, $new_hash, $other_addr);
2957
2958  # As we modify it, we need a copy
2959  my @not_to_scan = @$not_to_scan;
2960
2961  open(local *FILE, "$dev_i2c$adapter_nr") or
2962    (print "Can't open $dev_i2c$adapter_nr\n"), return;
2963  binmode(FILE);
2964
2965  # Can we probe this adapter?
2966  $funcs = i2c_get_funcs(\*FILE);
2967  if ($funcs < 0) {
2968    print "Adapter failed to provide its functionalities, skipping.\n";
2969    return;
2970  }
2971  if (!($funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) {
2972    print "Adapter cannot be probed, skipping.\n";
2973    return;
2974  }
2975  if (~$funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE)) {
2976    print "Adapter doesn't support all probing functions.\n",
2977          "Some addresses won't be probed.\n";
2978  }
2979
2980  # Now scan each address in turn
2981  foreach $addr (@{$i2c_addresses_to_scan}) {
2982    # As the not_to_scan list is sorted, we can check it fast
2983    shift @not_to_scan # User skipped an address which we didn't intend to probe anyway
2984      while (@not_to_scan and $not_to_scan[0] < $addr);
2985    if (@not_to_scan and $not_to_scan[0] == $addr) {
2986      shift @not_to_scan;
2987      next;
2988    }
2989
2990    if (!i2c_set_slave_addr(\*FILE, $addr)) {
2991      # If the address is busy, we can normally find out which driver
2992      # requested it (if the kernel is recent enough, at least 2.6.16
2993      # and later are known to work), and we assume it is the right one.
2994      my ($device, $driver);
2995
2996      $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x",
2997                             $adapter_nr, $addr);
2998      $driver = sysfs_device_driver($device);
2999
3000      if (defined($driver)) {
3001        $new_hash = {
3002          conf => 6, # Arbitrary confidence
3003          i2c_addr => $addr,
3004          chipname => sysfs_device_attribute($device, "name") || "unknown",
3005          i2c_adap => $adapter_name,
3006          i2c_driver => $adapter_driver,
3007          i2c_devnr => $adapter_nr,
3008        };
3009
3010        printf "Client found at address 0x\%02x\n", $addr;
3011        printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n",
3012               $driver, $new_hash->{chipname};
3013
3014        # Only add it to the list if this is something we would have
3015        # detected, else we end up with random i2c chip drivers listed
3016        # (for example media/video drivers.)
3017        if (exists $modules_supported{$driver}) {
3018          add_i2c_to_chips_detected($driver, $new_hash);
3019        } else {
3020          print "    (note: this is probably NOT a sensor chip!)\n";
3021        }
3022      } else {
3023        printf("Client at address 0x%02x can not be probed - ".
3024               "unload all client drivers first!\n", $addr);
3025      }
3026      next;
3027    }
3028
3029    next unless i2c_probe(\*FILE, $addr, $funcs);
3030    printf "Client found at address 0x%02x\n", $addr;
3031    if (!i2c_safety_check(\*FILE)) {
3032      print "Seems to be a 1-register-only device, skipping.\n";
3033      next;
3034    }
3035
3036    $| = 1;
3037    foreach $chip (@chip_ids) {
3038      if (exists $chip->{i2c_addrs} and contains($addr, @{$chip->{i2c_addrs}})) {
3039        printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name}));
3040        if (($conf, @chips) = &{$chip->{i2c_detect}} (\*FILE, $addr)) {
3041          if ($chip->{driver} eq "not-a-sensor") {
3042            print "Yes\n",
3043                  "    (confidence $conf, not a hardware monitoring chip";
3044          } else {
3045            print "Success!\n",
3046                  "    (confidence $conf, driver `$chip->{driver}'";
3047          }
3048          if (@chips) {
3049            print ", other addresses:";
3050            @chips = sort @chips;
3051            foreach $other_addr (@chips) {
3052              printf(" 0x%02x", $other_addr);
3053            }
3054          }
3055          printf ")\n";
3056
3057          next if ($chip->{driver} eq "not-a-sensor"
3058                || $chip->{driver} eq "use-isa-instead");
3059
3060          $new_hash = { conf => $conf,
3061                        i2c_addr => $addr,
3062                        chipname => $chip->{name},
3063                        i2c_adap => $adapter_name,
3064                        i2c_driver => $adapter_driver,
3065                        i2c_devnr => $adapter_nr,
3066                      };
3067          if (@chips) {
3068            my @chips_copy = @chips;
3069            $new_hash->{i2c_sub_addrs} = \@chips_copy;
3070          }
3071          add_i2c_to_chips_detected($chip->{driver}, $new_hash);
3072        } else {
3073          print "No\n";
3074        }
3075      }
3076    }
3077    $| = 0;
3078  }
3079}
3080
3081sub scan_isa_bus
3082{
3083  my ($chip, $addr, $conf);
3084  $| = 1;
3085  foreach $chip (@chip_ids) {
3086    next if not exists $chip->{isa_addrs} or not exists $chip->{isa_detect};
3087    foreach $addr (@{$chip->{isa_addrs}}) {
3088      printf("\%-60s", sprintf("Probing for `\%s'\ at 0x\%x... ", $chip->{name},
3089                               $addr));
3090      $conf = &{$chip->{isa_detect}} ($addr);
3091      print("No\n"), next if not defined $conf;
3092      print "Success!\n";
3093      printf "    (confidence %d, driver `%s')\n", $conf, $chip->{driver};
3094      my $new_hash = { conf => $conf,
3095                       isa_addr => $addr,
3096                       chipname => $chip->{name}
3097                     };
3098      $new_hash = add_isa_to_chips_detected($chip->{alias_detect}, $chip->{driver},
3099                                            $new_hash);
3100      if ($new_hash) {
3101        printf "    Alias of the chip on I2C bus `%s', address 0x%04x\n",
3102                        $new_hash->{i2c_adap}, $new_hash->{i2c_addr};
3103      }
3104    }
3105  }
3106  $| = 0;
3107}
3108
3109use vars qw(%superio);
3110
3111# The following are taken from the PNP ISA spec (so it's supposed
3112# to be common to all Super I/O chips):
3113#  devidreg: The device ID register(s)
3114#  logdevreg: The logical device register
3115#  actreg: The activation register within the logical device
3116#  actmask: The activation bit in the activation register
3117#  basereg: The I/O base register within the logical device
3118%superio = (
3119  devidreg => 0x20,
3120  logdevreg => 0x07,
3121  actreg => 0x30,
3122  actmask => 0x01,
3123  basereg => 0x60,
3124);
3125
3126sub exit_superio
3127{
3128  my ($addrreg, $datareg) = @_;
3129
3130  # Some chips (SMSC, Winbond) want this
3131  outb($addrreg, 0xaa);
3132
3133  # Return to "Wait For Key" state (PNP-ISA spec)
3134  outb($addrreg, 0x02);
3135  outb($datareg, 0x02);
3136}
3137
3138# Guess if an unknown Super-I/O chip has sensors
3139sub guess_superio_ld($$$)
3140{
3141  my ($addrreg, $datareg, $typical_addr) = @_;
3142  my ($oldldn, $ldn, $addr);
3143
3144  # Save logical device number
3145  outb($addrreg, $superio{logdevreg});
3146  $oldldn = inb($datareg);
3147
3148  for ($ldn = 0; $ldn < 16; $ldn++) {
3149    # Select logical device
3150    outb($addrreg, $superio{logdevreg});
3151    outb($datareg, $ldn);
3152
3153    # Read base I/O address
3154    outb($addrreg, $superio{basereg});
3155    $addr = inb($datareg) << 8;
3156    outb($addrreg, $superio{basereg} + 1);
3157    $addr |= inb($datareg);
3158    next unless ($addr & 0xfff8) == $typical_addr;
3159
3160    printf "    (logical device \%X has address 0x\%x, could be sensors)\n",
3161           $ldn, $addr;
3162    last;
3163  }
3164
3165  # Be nice, restore original logical device
3166  outb($addrreg, $superio{logdevreg});
3167  outb($datareg, $oldldn);
3168}
3169
3170sub probe_superio($$$)
3171{
3172  my ($addrreg, $datareg, $chip) = @_;
3173  my ($val, $addr);
3174
3175  printf "\%-60s",  "Found `$chip->{name}'";
3176
3177  # Does it have hardware monitoring capabilities?
3178  if (!exists $chip->{driver}) {
3179    print "\n    (no information available)\n";
3180    return;
3181  }
3182  if ($chip->{driver} eq "not-a-sensor") {
3183    print "\n    (no hardware monitoring capabilities)\n";
3184    return;
3185  }
3186  if ($chip->{driver} eq "via-smbus-only") {
3187    print "\n    (hardware monitoring capabilities accessible via SMBus only)\n";
3188    return;
3189  }
3190
3191  # Switch to the sensor logical device
3192  outb($addrreg, $superio{logdevreg});
3193  outb($datareg, $chip->{logdev});
3194
3195  # Check the activation register
3196  outb($addrreg, $superio{actreg});
3197  $val = inb($datareg);
3198  if (!($val & $superio{actmask})) {
3199    print "\n    (but not activated)\n";
3200    return;
3201  }
3202
3203  # Get the IO base register
3204  outb($addrreg, $superio{basereg});
3205  $addr = inb($datareg);
3206  outb($addrreg, $superio{basereg} + 1);
3207  $addr = ($addr << 8) | inb($datareg);
3208  if ($addr == 0) {
3209    print "\n    (but no address specified)\n";
3210    return;
3211  }
3212  print "Success!\n";
3213  printf "    (address 0x\%x, driver `%s')\n", $addr, $chip->{driver};
3214  my $new_hash = { conf => 9,
3215                   isa_addr => $addr,
3216                   chipname => $chip->{name}
3217                 };
3218  add_isa_to_chips_detected($chip->{alias_detect}, $chip->{driver},
3219                                        $new_hash);
3220}
3221
3222# Detection routine for non-standard SMSC Super I/O chips
3223# $_[0]: Super I/O LPC config/index port
3224# $_[1]: Super I/O LPC data port
3225# $_[2]: Reference to array of non-standard chips
3226# Return values: 1 if non-standard chip found, 0 otherwise
3227sub smsc_ns_detect_superio
3228{
3229    my ($addrreg, $datareg, $ns_chips) = @_;
3230    my ($val, $chip);
3231
3232    # read alternate device ID register
3233    outb($addrreg, 0x0d);
3234    $val = inb($datareg);
3235    if ($val == 0x00 || $val == 0xff) {
3236        return 0;
3237    }
3238
3239    print "Yes\n";
3240
3241    foreach $chip (@{$ns_chips}) {
3242        if ($chip->{devid} == $val) {
3243            probe_superio($addrreg, $datareg, $chip);
3244            return 1;
3245        }
3246    }
3247
3248    printf("Found unknown non-standard chip with ID 0x%02x\n", $val);
3249    return 1;
3250}
3251
3252sub scan_superio
3253{
3254  my ($addrreg, $datareg) = @_;
3255  my ($val, $found);
3256
3257  printf("Probing for Super-I/O at 0x\%x/0x\%x\n", $addrreg, $datareg);
3258
3259  $| = 1;
3260# reset state to avoid false positives
3261  exit_superio($addrreg, $datareg);
3262  FAMILY:
3263  foreach my $family (@superio_ids) {
3264    printf("\%-60s", "Trying family `$family->{family}'... ");
3265# write the password
3266    foreach $val (@{$family->{enter}->{$addrreg}}) {
3267      outb($addrreg, $val);
3268    }
3269# call the non-standard detection routine first if it exists
3270    if (defined($family->{ns_detect}) &&
3271        &{$family->{ns_detect}}($addrreg, $datareg, $family->{ns_chips})) {
3272      exit_superio($addrreg, $datareg);
3273      last FAMILY;
3274    }
3275# did it work?
3276    outb($addrreg, $superio{devidreg});
3277    $val = inb($datareg);
3278    outb($addrreg, $superio{devidreg} + 1);
3279    $val = ($val << 8) | inb($datareg);
3280    if ($val == 0x0000 || $val == 0xffff) {
3281      print "No\n";
3282      next FAMILY;
3283    }
3284    print "Yes\n";
3285
3286    $found = 0;
3287    foreach my $chip (@{$family->{chips}}) {
3288      if (($chip->{devid} > 0xff && ($val & ($chip->{devid_mask} || 0xffff)) == $chip->{devid})
3289       || ($chip->{devid} <= 0xff && ($val >> 8) == $chip->{devid})) {
3290        probe_superio($addrreg, $datareg, $chip);
3291        $found++;
3292      }
3293    }
3294
3295    if (!$found) {
3296      printf("Found unknown chip with ID 0x%04x\n", $val);
3297      # Guess if a logical device could correspond to sensors
3298      guess_superio_ld($addrreg, $datareg, $family->{guess})
3299        if defined $family->{guess};
3300    }
3301
3302    exit_superio($addrreg, $datareg);
3303    last FAMILY;
3304  }
3305  $| = 0;
3306}
3307
3308
3309sub scan_cpu($)
3310{
3311  my $entry = shift;
3312  my $confidence;
3313
3314  printf("\%-60s", "$entry->{name}... ");
3315  if (defined ($confidence = $entry->{detect}())) {
3316    print "Success!\n";
3317    printf "    (driver `%s')\n", $entry->{driver};
3318    my $new_hash = {
3319      conf => $confidence,
3320      chipname => $entry->{name},
3321    };
3322    add_isa_to_chips_detected(undef, $entry->{driver}, $new_hash);
3323  } else {
3324    print "No\n";
3325  }
3326}
3327
3328
3329##################
3330# CHIP DETECTION #
3331##################
3332
3333# This routine allows you to dynamically update the chip detection list.
3334# The most common use is to allow for different chip to driver mappings
3335# based on different linux kernels
3336sub chip_special_cases
3337{
3338        # Some chip to driver mappings depend on the environment
3339        foreach my $chip (@chip_ids) {
3340                if (ref($chip->{driver}) eq 'CODE') {
3341                        $chip->{driver} = $chip->{driver}->();
3342                }
3343        }
3344}
3345
3346# Each function returns a confidence value. The higher this value, the more
3347# sure we are about this chip. A Winbond W83781D, for example, will be
3348# detected as a LM78 too; but as the Winbond detection has a higher confidence
3349# factor, you should identify it as a Winbond.
3350
3351# Each function returns a list. The first element is the confidence value;
3352# Each element after it is an SMBus address. In this way, we can detect
3353# chips with several SMBus addresses. The SMBus address for which the
3354# function was called is never returned.
3355
3356# All I2C detection functions below take at least 2 parameters:
3357# $_[0]: Reference to the file descriptor to access the chip
3358# $_[1]: Address
3359# Some of these functions which can detect more than one type of device,
3360# take a third parameter:
3361# $_[2]: Chip to detect
3362
3363# Registers used: 0x58
3364sub mtp008_detect
3365{
3366  my ($file, $addr) = @_;
3367  return if i2c_smbus_read_byte_data($file, 0x58) != 0xac;
3368  return 3;
3369}
3370
3371# Chip to detect: 0 = LM78, 2 = LM79
3372# Registers used:
3373#   0x40: Configuration
3374#   0x48: Full I2C Address
3375#   0x49: Device ID
3376sub lm78_detect
3377{
3378  my ($file, $addr, $chip) = @_;
3379  my $reg;
3380  return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
3381  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
3382  $reg = i2c_smbus_read_byte_data($file, 0x49);
3383  return unless ($chip == 0 and ($reg == 0x00 or $reg == 0x20 or $reg == 0x40)) or
3384                    ($chip == 2 and ($reg & 0xfe) == 0xc0);
3385
3386  # Explicitly prevent misdetection of Winbond chips
3387  $reg = i2c_smbus_read_byte_data($file, 0x4f);
3388  return if $reg == 0xa3 || $reg == 0x5c;
3389
3390  return 6;
3391}
3392
3393# Chip to detect: 0 = LM75, 1 = DS75
3394# Registers used:
3395#   0x00: Temperature
3396#   0x01: Configuration
3397#   0x02: Hysteresis
3398#   0x03: Overtemperature Shutdown
3399#   0x04-0x07: No registers
3400# The first detection step is based on the fact that the LM75 has only
3401# four registers, and cycles addresses over 8-byte boundaries. We use the
3402# 0x04-0x07 addresses (unused) to improve the reliability. These are not
3403# real registers and will always return the last returned value. This isn't
3404# documented.
3405# Note that register 0x00 may change, so we can't use the modulo trick on it.
3406# The DS75 is a bit different, it doesn't cycle over 8-byte boundaries, and
3407# all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for
3408# the LM75.
3409# Not all devices enjoy SMBus read word transactions, so we use read byte
3410# transactions even for the 16-bit registers. The low bits aren't very
3411# useful for detection anyway.
3412sub lm75_detect
3413{
3414  my ($file, $addr, $chip) = @_;
3415  my $i;
3416  my $cur = i2c_smbus_read_byte_data($file, 0x00);
3417  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3418
3419  my $hyst = i2c_smbus_read_byte_data($file, 0x02, NO_CACHE);
3420  my $maxreg = $chip == 1 ? 0x0f : 0x07;
3421  for $i (0x04 .. $maxreg) {
3422    return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $hyst;
3423  }
3424
3425  my $os = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3426  for $i (0x04 .. $maxreg) {
3427    return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $os;
3428  }
3429
3430  if ($chip == 0) {
3431    for ($i = 8; $i <= 248; $i += 40) {
3432      return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf
3433             or i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst
3434             or i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
3435    }
3436  }
3437
3438  # All registers hold the same value, obviously a misdetection
3439  return if $conf == $cur and $cur == $hyst and $cur == $os;
3440
3441  # Unused bits
3442  return if $chip == 0 and ($conf & 0xe0);
3443  return if $chip == 1 and ($conf & 0x80);
3444
3445  # Most probable value ranges
3446  return 6 if $cur <= 100 and ($hyst >= 10 && $hyst <= 125)
3447    and ($os >= 20 && $os <= 127) and $hyst < $os;
3448  return 3;
3449}
3450
3451# Registers used:
3452#   0x00: Temperature
3453#   0x01: Configuration
3454#   0x02: Hysteresis
3455#   0x03: Overtemperature Shutdown
3456#   0x04: Low limit
3457#   0x05: High limit
3458#   0x06-0x07: No registers
3459# The first detection step is based on the fact that the LM77 has only
3460# six registers, and cycles addresses over 8-byte boundaries. We use the
3461# 0x06-0x07 addresses (unused) to improve the reliability. These are not
3462# real registers and will always return the last returned value. This isn't
3463# documented.
3464# Note that register 0x00 may change, so we can't use the modulo trick on it.
3465# Not all devices enjoy SMBus read word transactions, so we use read byte
3466# transactions even for the 16-bit registers at first. We only use read word
3467# transactions in the end when we are already almost certain that we have an
3468# LM77 chip.
3469sub lm77_detect
3470{
3471  my ($file, $addr) = @_;
3472  my $i;
3473  my $cur = i2c_smbus_read_byte_data($file, 0x00);
3474  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3475  my $hyst = i2c_smbus_read_byte_data($file, 0x02);
3476  my $os = i2c_smbus_read_byte_data($file, 0x03);
3477
3478  my $low = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
3479  return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $low;
3480  return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $low;
3481
3482  my $high = i2c_smbus_read_byte_data($file, 0x05, NO_CACHE);
3483  return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $high;
3484  return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $high;
3485
3486  for ($i = 8; $i <= 248; $i += 40) {
3487    return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3488    return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
3489    return if i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
3490    return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
3491    return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
3492  }
3493
3494  # All registers hold the same value, obviously a misdetection
3495  return if $conf == $cur and $cur == $hyst
3496    and $cur == $os and $cur == $low and $cur == $high;
3497
3498  # Unused bits
3499  return if ($conf & 0xe0)
3500    or (($cur >> 4) != 0 && ($cur >> 4) != 0xf)
3501    or (($hyst >> 4) != 0 && ($hyst >> 4) != 0xf)
3502    or (($os >> 4) != 0 && ($os >> 4) != 0xf)
3503    or (($low >> 4) != 0 && ($low >> 4) != 0xf)
3504    or (($high >> 4) != 0 && ($high >> 4) != 0xf);
3505
3506  # Make sure the chip supports SMBus read word transactions
3507  $cur = i2c_smbus_read_word_data($file, 0x00);
3508  return if $cur < 0;
3509  $hyst = i2c_smbus_read_word_data($file, 0x02);
3510  return if $hyst < 0;
3511  $os = i2c_smbus_read_word_data($file, 0x03);
3512  return if $os < 0;
3513  $low = i2c_smbus_read_word_data($file, 0x04);
3514  return if $low < 0;
3515  $high = i2c_smbus_read_word_data($file, 0x05);
3516  return if $high < 0;
3517
3518  $cur /= 16;
3519  $hyst /= 16;
3520  $os /= 16;
3521  $high /= 16;
3522  $low /= 16;
3523
3524  # Most probable value ranges
3525  return 6 if $cur <= 100 and $hyst <= 40
3526    and ($os >= 20 && $os <= 127) and ($high >= 20 && $high <= 127);
3527  return 3;
3528}
3529
3530# Chip to detect: 0 = LM92, 1 = LM76, 2 = MAX6633/MAX6634/MAX6635
3531# Registers used:
3532#   0x01: Configuration (National Semiconductor only)
3533#   0x02: Hysteresis
3534#   0x03: Critical Temp
3535#   0x04: Low Limit
3536#   0x05: High Limit
3537#   0x07: Manufacturer ID (LM92 only)
3538# One detection step is based on the fact that the LM92 and clones have a
3539# limited number of registers, which cycle modulo 16 address values.
3540# Note that register 0x00 may change, so we can't use the modulo trick on it.
3541# Not all devices enjoy SMBus read word transactions, so we use read byte
3542# transactions even for the 16-bit registers at first. We only use read
3543# word transactions in the end when we are already almost certain that we
3544# have an LM92 chip or compatible.
3545sub lm92_detect
3546{
3547  my ($file, $addr, $chip) = @_;
3548
3549  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3550  my $hyst = i2c_smbus_read_byte_data($file, 0x02);
3551  my $crit = i2c_smbus_read_byte_data($file, 0x03);
3552  my $low = i2c_smbus_read_byte_data($file, 0x04);
3553  my $high = i2c_smbus_read_byte_data($file, 0x05);
3554
3555  return if $conf == 0 and $hyst == 0 and $crit == 0
3556        and $low == 0 and $high == 0;
3557
3558  # Unused bits
3559  return if ($chip == 0 || $chip == 1)
3560        and ($conf & 0xE0);
3561
3562  for (my $i = 0; $i <= 240; $i += 16) {
3563    return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3564    return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
3565    return if i2c_smbus_read_byte_data($file, $i + 0x03) != $crit;
3566    return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
3567    return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
3568  }
3569
3570  return if $chip == 0
3571        and i2c_smbus_read_word_data($file, 0x07) != 0x0180;
3572
3573  # Make sure the chip supports SMBus read word transactions
3574  $hyst = i2c_smbus_read_word_data($file, 0x02);
3575  return if $hyst < 0;
3576  $crit = i2c_smbus_read_word_data($file, 0x03);
3577  return if $crit < 0;
3578  $low = i2c_smbus_read_word_data($file, 0x04);
3579  return if $low < 0;
3580  $high = i2c_smbus_read_word_data($file, 0x05);
3581  return if $high < 0;
3582
3583  foreach my $temp ($hyst, $crit, $low, $high) {
3584    return if $chip == 2 and ($temp & 0x7F00);
3585    return if $chip != 2 and ($temp & 0x0700);
3586  }
3587
3588  return 4 if $chip == 0;
3589  return 2;
3590}
3591
3592# Registers used:
3593#   0xAA: Temperature
3594#   0xA1: High limit
3595#   0xA2: Low limit
3596#   0xA8: Counter
3597#   0xA9: Slope
3598#   0xAC: Configuration
3599# Detection is weak. We check if bit 4 (NVB) is clear, because it is
3600# unlikely to be set (would mean that EEPROM is currently being accessed).
3601# We also check the value of the counter and slope registers, the datasheet
3602# doesn't mention the possible values but the conversion formula together
3603# with experimental evidence suggest possible sanity checks.
3604# Not all devices enjoy SMBus read word transactions, so we do as much as
3605# possible with read byte transactions first, and only use read word
3606# transactions second.
3607sub ds1621_detect
3608{
3609  my ($file, $addr) = @_;
3610
3611  my $conf = i2c_smbus_read_byte_data($file, 0xAC);
3612  return if ($conf & 0x10);
3613
3614  my $counter = i2c_smbus_read_byte_data($file, 0xA8);
3615  my $slope = i2c_smbus_read_byte_data($file, 0xA9);
3616  return if ($slope != 0x10 || $counter > $slope);
3617
3618  my $temp = i2c_smbus_read_word_data($file, 0xAA);
3619  return if $temp < 0 || ($temp & 0x0f00);
3620  # On the DS1631, the following two checks are too strict in theory,
3621  # but in practice I very much doubt that anyone will set temperature
3622  # limits not a multiple of 0.5 degrees C.
3623  my $high = i2c_smbus_read_word_data($file, 0xA1);
3624  return if $high < 0 || ($high & 0x7f00);
3625  my $low = i2c_smbus_read_word_data($file, 0xA2);
3626  return if $low < 0 || ($low & 0x7f00);
3627
3628  return if ($temp == 0 && $high == 0 && $low == 0 && $conf == 0);
3629
3630  return 3;
3631}
3632
3633# Registers used:
3634#   0x00: Configuration register
3635#   0x02: Interrupt state register
3636#   0x2a-0x3d: Limits registers
3637# This one is easily misdetected since it doesn't provide identification
3638# registers. So we have to use some tricks:
3639#   - 6-bit addressing, so limits readings modulo 0x40 should be unchanged
3640#   - positive temperature limits
3641#   - limits order correctness
3642# Hopefully this should limit the rate of false positives, without increasing
3643# the rate of false negatives.
3644# Thanks to Lennard Klein for testing on a non-LM80 chip, which was
3645# previously misdetected, and isn't anymore. For reference, it scored
3646# a final confidence of 0, and changing from strict limit comparisons
3647# to loose comparisons did not change the score.
3648sub lm80_detect
3649{
3650  my ($file, $addr) = @_;
3651  my ($i, $reg);
3652
3653  return if (i2c_smbus_read_byte_data($file, 0x00) & 0x80) != 0;
3654  return if (i2c_smbus_read_byte_data($file, 0x02) & 0xc0) != 0;
3655
3656  for ($i = 0x2a; $i <= 0x3d; $i++) {
3657    $reg = i2c_smbus_read_byte_data($file, $i);
3658    return if i2c_smbus_read_byte_data($file, $i+0x40) != $reg;
3659    return if i2c_smbus_read_byte_data($file, $i+0x80) != $reg;
3660    return if i2c_smbus_read_byte_data($file, $i+0xc0) != $reg;
3661  }
3662
3663  # Refine a bit by checking wether limits are in the correct order
3664  # (min<max for voltages, hyst<max for temperature). Since it is still
3665  # possible that the chip is an LM80 with limits not properly set,
3666  # a few "errors" are tolerated.
3667  my $confidence = 0;
3668  for ($i = 0x2a; $i <= 0x3a; $i++) {
3669    $confidence++
3670      if i2c_smbus_read_byte_data($file, $i) < i2c_smbus_read_byte_data($file, $i+1);
3671  }
3672  # hot temp<OS temp
3673  $confidence++
3674    if i2c_smbus_read_byte_data($file, 0x38) < i2c_smbus_read_byte_data($file, 0x3a);
3675
3676  # Negative temperature limits are unlikely.
3677  for ($i = 0x3a; $i <= 0x3d; $i++) {
3678    $confidence++ if (i2c_smbus_read_byte_data($file, $i) & 0x80) == 0;
3679  }
3680
3681  # $confidence is between 0 and 14
3682  $confidence = ($confidence >> 1) - 4;
3683  # $confidence is now between -4 and 3
3684
3685  return unless $confidence > 0;
3686
3687  return $confidence;
3688}
3689
3690# Registers used:
3691#   0x02: Status 1
3692#   0x03: Configuration
3693#   0x04: Company ID of LM84
3694#   0x35: Status 2
3695#   0xfe: Manufacturer ID
3696#   0xff: Chip ID / die revision
3697# We can use the LM84 Company ID register because the LM83 and the LM82 are
3698# compatible with the LM84.
3699# The LM83 chip ID is missing from the datasheet and was contributed by
3700# Magnus Forsstrom: 0x03.
3701# At least some revisions of the LM82 seem to be repackaged LM83, so they
3702# have the same chip ID, and temp2/temp4 will be stuck in "OPEN" state.
3703# For this reason, we don't even try to distinguish between both chips.
3704# Thanks to Ben Gardner for reporting.
3705sub lm83_detect
3706{
3707  my ($file, $addr) = @_;
3708  return if i2c_smbus_read_byte_data($file, 0xfe) != 0x01;
3709  my $chipid = i2c_smbus_read_byte_data($file, 0xff);
3710  return if $chipid != 0x01 && $chipid != 0x03;
3711
3712  my $confidence = 4;
3713  $confidence++
3714    if (i2c_smbus_read_byte_data($file, 0x02) & 0xa8) == 0x00;
3715  $confidence++
3716    if (i2c_smbus_read_byte_data($file, 0x03) & 0x41) == 0x00;
3717  $confidence++
3718    if i2c_smbus_read_byte_data($file, 0x04) == 0x00;
3719  $confidence++
3720    if (i2c_smbus_read_byte_data($file, 0x35) & 0x48) == 0x00;
3721
3722  return $confidence;
3723}
3724
3725# Chip to detect: 0 = LM90, 1 = LM89/LM99, 2 = LM86, 3 = ADM1032,
3726#                 4 = MAX6654/MAX6690, 5 = ADT7461,
3727#                 6 = MAX6646/MAX6647/MAX6648/MAX6649/MAX6692,
3728#                 7 = MAX6680/MAX6681, 8 = W83L771W/G, 9 = TMP401, 10 = TMP411
3729# Registers used:
3730#   0x03: Configuration
3731#   0x04: Conversion rate
3732#   0xfe: Manufacturer ID
3733#   0xff: Chip ID / die revision
3734sub lm90_detect
3735{
3736  my ($file, $addr, $chip) = @_;
3737  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3738  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3739  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3740  my $rate = i2c_smbus_read_byte_data($file, 0x04);
3741
3742  if ($chip == 0) {
3743    return if ($conf & 0x2a) != 0;
3744    return if $rate > 0x09;
3745    return if $mid != 0x01;     # National Semiconductor
3746    return 8 if $cid == 0x21;   # LM90
3747    return 6 if ($cid & 0x0f) == 0x20;
3748  }
3749  if ($chip == 1) {
3750    return if ($conf & 0x2a) != 0;
3751    return if $rate > 0x09;
3752    return if $mid != 0x01;     # National Semiconductor
3753    return 8 if $addr == 0x4c and $cid == 0x31; # LM89/LM99
3754    return 8 if $addr == 0x4d and $cid == 0x34; # LM89-1/LM99-1
3755    return 6 if ($cid & 0x0f) == 0x30;
3756  }
3757  if ($chip == 2) {
3758    return if ($conf & 0x2a) != 0;
3759    return if $rate > 0x09;
3760    return if $mid != 0x01;     # National Semiconductor
3761    return 8 if $cid == 0x11;   # LM86
3762    return 6 if ($cid & 0xf0) == 0x10;
3763  }
3764  if ($chip == 3) {
3765    return if ($conf & 0x3f) != 0;
3766    return if $rate > 0x0a;
3767    return if $mid != 0x41;     # Analog Devices
3768    return 6 if ($cid & 0xf0) == 0x40; # ADM1032
3769  }
3770  if ($chip == 4) {
3771    return if ($conf & 0x07) != 0;
3772    return if $rate > 0x07;
3773    return if $mid != 0x4d;     # Maxim
3774    return if $cid != 0x08;     # MAX6654/MAX6690
3775    return 8;
3776  }
3777  if ($chip == 5) {
3778    return if ($conf & 0x1b) != 0;
3779    return if $rate > 0x0a;
3780    return if $mid != 0x41;     # Analog Devices
3781    return 8 if $cid == 0x51;   # ADT7461
3782  }
3783  if ($chip == 6) {
3784    return if ($conf & 0x3f) != 0;
3785    return if $rate > 0x07;
3786    return if $mid != 0x4d;     # Maxim
3787    return if $cid != 0x59;     # MAX6648/MAX6692
3788    return 8;
3789  }
3790  if ($chip == 7) {
3791    return if ($conf & 0x03) != 0;
3792    return if $rate > 0x07;
3793    return if $mid != 0x4d;     # Maxim
3794    return if $cid != 0x01;     # MAX6680/MAX6681
3795    return 8;
3796  }
3797  if ($chip == 8) {
3798    return if ($conf & 0x2a) != 0;
3799    return if $rate > 0x09;
3800    return if $mid != 0x5c;     # Winbond
3801    return if $cid != 0x00;     # W83L771W/G
3802    return 6;
3803  }
3804  if ($chip == 9) {
3805    return if ($conf & 0x1B) != 0;
3806    return if $rate > 0x0F;
3807    return if $mid != 0x55;     # Texas Instruments
3808    return if $cid != 0x11;     # TMP401
3809    return 8;
3810  }
3811  if ($chip == 10) {
3812    return if ($conf & 0x1B) != 0;
3813    return if $rate > 0x0F;
3814    return if $mid != 0x55;     # Texas Instruments
3815    return 6 if ($addr == 0x4c && $cid == 0x12); # TMP411A
3816    return 6 if ($addr == 0x4d && $cid == 0x13); # TMP411B
3817    return 6 if ($addr == 0x4e && $cid == 0x10); # TMP411C
3818    return;
3819  }
3820  return;
3821}
3822
3823# Registers used:
3824#   0x03: Configuration (no low nibble)
3825#   0x04: Conversion rate
3826#   0xfe: Manufacturer ID
3827#   0xff: no register
3828sub max6657_detect
3829{
3830  my ($file, $addr) = @_;
3831  my $mid = i2c_smbus_read_byte_data($file, 0xfe, NO_CACHE);
3832  my $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
3833  my $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3834
3835  return if $mid != 0x4d;     # Maxim
3836  return if ($conf & 0x1f) != 0x0d; # No low nibble,
3837                                    # returns previous low nibble
3838  return if $cid != 0x4d;     # No register, returns previous value
3839
3840  my $rate = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
3841  return if $rate > 0x09;
3842
3843  $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
3844  $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3845  return if ($conf & 0x0f) != $rate; # No low nibble,
3846                                     # returns previous low nibble
3847  return if $cid != $rate;    # No register, returns previous value
3848
3849  return 5;
3850}
3851
3852# Registers used:
3853#   0x03: Configuration
3854#   0xfe: Manufacturer ID
3855#   0xff: Revision ID
3856sub lm95231_detect
3857{
3858  my ($file, $addr) = @_;
3859  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3860  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3861  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3862
3863  return if ($conf & 0x89) != 0;
3864  return if $mid != 0x01;     # National Semiconductor
3865  return if $cid != 0xa1;     # LM95231
3866
3867  return 6;
3868}
3869
3870# Registers used:
3871#   0x03: Configuration 1
3872#   0x24: Configuration 2
3873#   0x3d: Manufacturer ID
3874#   0x3e: Device ID
3875sub adt7481_detect
3876{
3877  my ($file, $addr) = @_;
3878  my $mid = i2c_smbus_read_byte_data($file, 0x3d);
3879  my $cid = i2c_smbus_read_byte_data($file, 0x3e);
3880  my $conf1 = i2c_smbus_read_byte_data($file, 0x03);
3881  my $conf2 = i2c_smbus_read_byte_data($file, 0x24);
3882
3883  return if ($conf1 & 0x10) != 0;
3884  return if ($conf2 & 0x7f) != 0;
3885  return if $mid != 0x41;     # Analog Devices
3886  return if $cid != 0x81;     # ADT7481
3887
3888  return 6;
3889}
3890
3891# Chip to detect: 1 = LM63, 2 = F75363SG, 3 = LM64
3892# Registers used:
3893#   0xfe: Manufacturer ID
3894#   0xff: Chip ID / die revision
3895#   0x03: Configuration (two or three unused bits)
3896#   0x16: Alert mask (two or three unused bits)
3897sub lm63_detect
3898{
3899  my ($file, $addr, $chip) = @_;
3900
3901  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3902  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3903  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3904  my $mask = i2c_smbus_read_byte_data($file, 0x16);
3905
3906  if ($chip == 1) {
3907    return if $mid != 0x01    # National Semiconductor
3908           || $cid != 0x41;   # LM63
3909    return if ($conf & 0x18) != 0x00
3910           || ($mask & 0xa4) != 0xa4;
3911  } elsif ($chip == 2) {
3912    return if $mid != 0x23    # Fintek
3913           || $cid != 0x20;   # F75363SG
3914    return if ($conf & 0x1a) != 0x00
3915           || ($mask & 0x84) != 0x00;
3916  } elsif ($chip == 3) {
3917    return if $mid != 0x01    # National Semiconductor
3918           || $cid != 0x51;   # LM64
3919    return if ($conf & 0x18) != 0x00
3920           || ($mask & 0xa4) != 0xa4;
3921  }
3922
3923  return 6;
3924}
3925
3926# Registers used:
3927#   0x02, 0x03: Fan support
3928#   0x06: Temperature support
3929#   0x07, 0x08, 0x09: Fan config
3930#   0x0d: Manufacturer ID
3931#   0x0e: Chip ID / die revision
3932sub adm1029_detect
3933{
3934  my ($file, $addr) = @_;
3935  my $mid = i2c_smbus_read_byte_data($file, 0x0d);
3936  my $cid = i2c_smbus_read_byte_data($file, 0x0e);
3937  my $cfg;
3938
3939  return unless $mid == 0x41;             # Analog Devices
3940  return unless ($cid & 0xF0) == 0x00;    # ADM1029
3941
3942  # Extra check on unused bits
3943  $cfg = i2c_smbus_read_byte_data($file, 0x02);
3944  return unless $cfg == 0x03;
3945  $cfg = i2c_smbus_read_byte_data($file, 0x06);
3946  return unless ($cfg & 0xF9) == 0x01;
3947  foreach my $reg (0x03, 0x07, 0x08, 0x09) {
3948    $cfg = i2c_smbus_read_byte_data($file, $reg);
3949    return unless ($cfg & 0xFC) == 0x00;
3950  }
3951
3952  return 7;
3953}
3954
3955# Chip to detect: 0 = ADM1030, 1 = ADM1031
3956# Registers used:
3957#   0x01: Config 2
3958#   0x03: Status 2
3959#   0x0d, 0x0e, 0x0f: Temperature offsets
3960#   0x22: Fan speed config
3961#   0x3d: Chip ID
3962#   0x3e: Manufacturer ID
3963#   0x3f: Die revision
3964sub adm1031_detect
3965{
3966  my ($file, $addr, $chip) = @_;
3967  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
3968  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
3969  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
3970  my $conf2 = i2c_smbus_read_byte_data($file, 0x01);
3971  my $stat2 = i2c_smbus_read_byte_data($file, 0x03);
3972  my $fsc = i2c_smbus_read_byte_data($file, 0x22);
3973  my $lto = i2c_smbus_read_byte_data($file, 0x0d);
3974  my $r1to = i2c_smbus_read_byte_data($file, 0x0e);
3975  my $r2to = i2c_smbus_read_byte_data($file, 0x0f);
3976  my $confidence = 3;
3977
3978  if ($chip == 0) {
3979    return if $mid != 0x41;     # Analog Devices
3980    return if $cid != 0x30;     # ADM1030
3981    $confidence++ if ($drev & 0x70) == 0x00;
3982    $confidence++ if ($conf2 & 0x4A) == 0x00;
3983    $confidence++ if ($stat2 & 0x3F) == 0x00;
3984    $confidence++ if ($fsc & 0xF0) == 0x00;
3985    $confidence++ if ($lto & 0x70) == 0x00;
3986    $confidence++ if ($r1to & 0x70) == 0x00;
3987    return $confidence;
3988  }
3989  if ($chip == 1) {
3990    return if $mid != 0x41;     # Analog Devices
3991    return if $cid != 0x31;     # ADM1031
3992    $confidence++ if ($drev & 0x70) == 0x00;
3993    $confidence++ if ($lto & 0x70) == 0x00;
3994    $confidence++ if ($r1to & 0x70) == 0x00;
3995    $confidence++ if ($r2to & 0x70) == 0x00;
3996    return $confidence;
3997  }
3998  return;
3999}
4000
4001# Chip to detect: 0 = ADM1033, 1 = ADM1034
4002# Registers used:
4003#   0x3d: Chip ID
4004#   0x3e: Manufacturer ID
4005#   0x3f: Die revision
4006sub adm1034_detect
4007{
4008  my ($file, $addr, $chip) = @_;
4009  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4010  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4011  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4012
4013  if ($chip == 0) {
4014    return if $mid != 0x41;     # Analog Devices
4015    return if $cid != 0x33;     # ADM1033
4016    return if ($drev & 0xf8) != 0x00;
4017    return 6 if $drev == 0x02;
4018    return 4;
4019  }
4020  if ($chip == 1) {
4021    return if $mid != 0x41;     # Analog Devices
4022    return if $cid != 0x34;     # ADM1034
4023    return if ($drev & 0xf8) != 0x00;
4024    return 6 if $drev == 0x02;
4025    return 4;
4026  }
4027  return
4028}
4029
4030# Chip to detect: 0 = ADT7467/ADT7468, 1 = ADT7476, 2 = ADT7462, 3 = ADT7466,
4031#                 4 = ADT7470
4032# Registers used:
4033#   0x3d: Chip ID
4034#   0x3e: Manufacturer ID
4035#   0x3f: Die revision
4036sub adt7467_detect
4037{
4038  my ($file, $addr, $chip) = @_;
4039  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4040  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4041  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4042
4043  if ($chip == 0) {
4044    return if $mid != 0x41;     # Analog Devices
4045    return if $cid != 0x68;     # ADT7467
4046    return if ($drev & 0xf0) != 0x70;
4047    return 7 if ($drev == 0x71 || $drev == 0x72);
4048    return 5;
4049  }
4050  if ($chip == 1) {
4051    return if $mid != 0x41;     # Analog Devices
4052    return if $cid != 0x76;     # ADT7476
4053    return if ($drev & 0xf0) != 0x60;
4054    return 7 if ($drev == 0x69);
4055    return 5;
4056  }
4057  if ($chip == 2) {
4058    return if $mid != 0x41;     # Analog Devices
4059    return if $cid != 0x62;     # ADT7462
4060    return if ($drev & 0xf0) != 0x00;
4061    return 7 if ($drev == 0x04);
4062    return 5;
4063  }
4064  if ($chip == 3) {
4065    return if $mid != 0x41;     # Analog Devices
4066    return if $cid != 0x66;     # ADT7466
4067    return if ($drev & 0xf0) != 0x00;
4068    return 7 if ($drev == 0x02);
4069    return 5;
4070  }
4071  if ($chip == 4) {
4072    return if $mid != 0x41;     # Analog Devices
4073    return if $cid != 0x70;     # ADT7470
4074    return if ($drev & 0xf0) != 0x00;
4075    return 7 if ($drev == 0x00);
4076    return 5;
4077  }
4078  return
4079}
4080
4081# Chip to detect: 0 = ADT7473, 1 = ADT7475
4082# Registers used:
4083#   0x3d: Chip ID
4084#   0x3e: Manufacturer ID
4085sub adt7473_detect
4086{
4087  my ($file, $addr, $chip) = @_;
4088  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4089  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4090
4091  if ($chip == 0) {
4092    return if $mid != 0x41;     # Analog Devices
4093    return if $cid != 0x73;     # ADT7473
4094    return 5;
4095  }
4096  if ($chip == 1) {
4097    return if $mid != 0x41;     # Analog Devices
4098    return if $cid != 0x75;     # ADT7475
4099    return 5;
4100  }
4101  return
4102}
4103
4104# Chip to detect: 0 = aSC7512, 1 = aSC7611, 2 = aSC7621
4105# Registers used:
4106#   0x3e: Manufacturer ID (0x61)
4107#   0x3f: Version
4108sub andigilog_detect
4109{
4110  my ($file, $addr, $chip) = @_;
4111  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4112  my $cid = i2c_smbus_read_byte_data($file, 0x3f);
4113
4114  return if ($mid != 0x61);
4115
4116  if ($chip == 0) {
4117    return if $cid != 0x62;
4118    return 5;
4119  }
4120
4121  if ($chip == 1) {
4122    return if $cid != 0x69;
4123    return 5;
4124  }
4125
4126  if ($chip == 2) {
4127    return if ($cid != 0x6C && $cid != 0x6D);
4128    return 5;
4129  }
4130
4131  return;
4132}
4133
4134# Registers used:
4135#   0xfe: Manufacturer ID
4136#   0xff: Die Code
4137sub andigilog_aSC7511_detect
4138{
4139  my ($file, $addr) = @_;
4140  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4141  my $die = i2c_smbus_read_byte_data($file, 0xff);
4142
4143  return if $mid != 0x61;     # Andigilog
4144  if ($die == 0x0) {
4145      return 3;
4146  } else {
4147      return 1;
4148  }
4149}
4150
4151# Chip to detect: 0 = LM85, 1 = LM96000, 2 = ADM1027, 3 = ADT7463,
4152#                 4 = EMC6D100/101, 5 = EMC6D102, 6 = EMC6D103
4153# Registers used: 0x3e == Vendor register.
4154#                 0x3d == Device ID register (Analog Devices only).
4155#                 0x3f == Version/Stepping register.
4156sub lm85_detect
4157{
4158  my ($file, $addr, $chip) = @_;
4159  my $vendor = i2c_smbus_read_byte_data($file, 0x3e);
4160  my $verstep = i2c_smbus_read_byte_data($file, 0x3f);
4161
4162  if ($chip == 0) {
4163    return if $vendor != 0x01;  # National Semiconductor
4164    return if $verstep != 0x60  # LM85 C
4165           && $verstep != 0x62; # LM85 B
4166  } elsif ($chip == 1) {
4167    return if $vendor != 0x01;  # National Semiconductor
4168    return if $verstep != 0x68  # LM96000
4169           && $verstep != 0x69; # LM96000
4170  } elsif ($chip == 2) {
4171    return if $vendor != 0x41;  # Analog Devices
4172    return if $verstep != 0x60; # ADM1027
4173  } elsif ($chip == 3) {
4174    return if $vendor != 0x41;  # Analog Devices
4175    return if $verstep != 0x62  # ADT7463
4176           && $verstep != 0x6a; # ADT7463 C
4177  } elsif ($chip == 4) {
4178    return if $vendor != 0x5c;  # SMSC
4179    return if $verstep != 0x60  # EMC6D100/101 A0
4180           && $verstep != 0x61; # EMC6D100/101 A1
4181  } elsif ($chip == 5) {
4182    return if $vendor != 0x5c;  # SMSC
4183    return if $verstep != 0x65; # EMC6D102
4184  } elsif ($chip == 6) {
4185    return if $vendor != 0x5c;  # SMSC
4186    return if $verstep != 0x68; # EMC6D103
4187  }
4188
4189  if ($vendor == 0x41) { # Analog Devices
4190    return if i2c_smbus_read_byte_data($file, 0x3d) != 0x27;
4191    return 8;
4192  }
4193
4194  return 7;
4195}
4196
4197# Chip to detect: 0 = LM87, 1 = ADM1024
4198# Registers used:
4199#   0x3e: Company ID
4200#   0x3f: Revision
4201#   0x40: Configuration
4202sub lm87_detect
4203{
4204  my ($file, $addr, $chip) = @_;
4205  my $cid = i2c_smbus_read_byte_data($file, 0x3e);
4206  my $rev = i2c_smbus_read_byte_data($file, 0x3f);
4207
4208  if ($chip == 0) {
4209    return if $cid != 0x02;     # National Semiconductor
4210    return if ($rev & 0xfc) != 0x04;
4211  }
4212  if ($chip == 1) {
4213    return if $cid != 0x41;     # Analog Devices
4214    return if ($rev & 0xf0) != 0x10;
4215  }
4216
4217  my $cfg = i2c_smbus_read_byte_data($file, 0x40);
4218  return if ($cfg & 0x80) != 0x00;
4219
4220  return 7;
4221}
4222
4223# Chip to detect: 0 = W83781D, 1 = W83782D, 2 = W83783S, 3 = W83627HF,
4224#                 4 = AS99127F (rev.1), 5 = AS99127F (rev.2), 6 = ASB100,
4225#                 7 = W83791D, 8 = W83792D, 9 = W83627EHF, 10 = W83627DHG
4226# Registers used:
4227#   0x48: Full I2C Address
4228#   0x4a: I2C addresses of emulated LM75 chips
4229#   0x4e: Vendor ID byte selection, and bank selection
4230#   0x4f: Vendor ID
4231#   0x58: Device ID (only when in bank 0)
4232# Note: Fails if the W8378xD is not in bank 0!
4233# Note: Asus chips do not have their I2C address at register 0x48?
4234#       AS99127F rev.1 and ASB100 have 0x00, confirmation wanted for
4235#       AS99127F rev.2.
4236sub w83781d_detect
4237{
4238  my ($file, $addr, $chip) = @_;
4239  my ($reg1, $reg2, @res);
4240
4241  return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr)
4242    or ($chip >= 4 && $chip <= 6);
4243
4244  $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4245  $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4246  if ($chip == 4) { # Asus AS99127F (rev.1)
4247    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xc3) or
4248                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x12);
4249  } elsif ($chip == 6) { # Asus ASB100
4250    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0x94) or
4251                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x06);
4252  } else { # Winbond and Asus AS99127F (rev.2)
4253    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
4254                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4255  }
4256
4257  return unless ($reg1 & 0x07) == 0x00;
4258
4259  $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4260  return if $chip == 0 and ($reg1 != 0x10 && $reg1 != 0x11);
4261  return if $chip == 1 and  $reg1 != 0x30;
4262  return if $chip == 2 and  $reg1 != 0x40;
4263  return if $chip == 3 and  $reg1 != 0x21;
4264  return if $chip == 4 and  $reg1 != 0x31;
4265  return if $chip == 5 and  $reg1 != 0x31;
4266  return if $chip == 6 and  $reg1 != 0x31;
4267  return if $chip == 7 and  $reg1 != 0x71;
4268  return if $chip == 8 and  $reg1 != 0x7a;
4269  return if $chip == 9 and ($reg1 != 0x88 && $reg1 != 0xa1);
4270  return if $chip == 10 and  $reg1 != 0xc1;
4271  # Default address is 0x2d
4272  @res = ($addr != 0x2d) ? (7) : (8);
4273  return @res if $chip >= 9; # No subclients
4274
4275  $reg1 = i2c_smbus_read_byte_data($file, 0x4a);
4276  push @res, ($reg1 & 0x07) + 0x48 unless $reg1 & 0x08;
4277  push @res, (($reg1 & 0x70) >> 4) + 0x48 unless ($reg1 & 0x80 or $chip == 2);
4278  return @res;
4279}
4280
4281# Registers used:
4282#   0x0b: Full I2C Address
4283#   0x0c: I2C addresses of emulated LM75 chips
4284#   0x00: Vendor ID byte selection, and bank selection(Bank 0, 1, 2)
4285#   0x0d: Vendor ID(Bank 0, 1, 2)
4286#   0x0e: Device ID(Bank 0, 1, 2)
4287sub w83793_detect
4288{
4289  my ($file, $addr) = @_;
4290  my ($bank, $reg, @res);
4291
4292  $bank = i2c_smbus_read_byte_data($file, 0x00);
4293  $reg = i2c_smbus_read_byte_data($file, 0x0d);
4294
4295  return unless (($bank & 0x80) == 0x00 and $reg == 0xa3) or
4296                (($bank & 0x80) == 0x80 and $reg == 0x5c);
4297
4298  $reg = i2c_smbus_read_byte_data($file, 0x0e);
4299  return if $reg != 0x7b;
4300
4301# If bank 0 is selected, we can do more checks
4302  return 6 unless ($bank & 0x07) == 0;
4303  $reg = i2c_smbus_read_byte_data($file, 0x0b);
4304  return unless ($reg == ($addr << 1));
4305
4306  $reg = i2c_smbus_read_byte_data($file, 0x0c);
4307  @res = (8);
4308  push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4309  push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4310  return @res;
4311}
4312
4313# Registers used:
4314#   0x48: Full I2C Address
4315#   0x4e: Vendor ID byte selection
4316#   0x4f: Vendor ID
4317#   0x58: Device ID
4318# Note that the datasheet was useless and this detection routine
4319# is based on dumps we received from users. Also, the W83781SD is *NOT*
4320# a hardware monitoring chip as far as we know, but we still want to
4321# detect it so that people won't keep reporting it as an unknown chip
4322# we should investigate about.
4323sub w83791sd_detect
4324{
4325  my ($file, $addr) = @_;
4326  my ($reg1, $reg2);
4327
4328  return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr);
4329
4330  $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4331  $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4332  return unless (!($reg1 & 0x80) && $reg2 == 0xa3)
4333             || (($reg1 & 0x80) && $reg2 == 0x5c);
4334
4335  $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4336  return unless $reg1 == 0x72;
4337
4338  return 3;
4339}
4340
4341# Registers used:
4342#   0x4e: Vendor ID high byte
4343#   0x4f: Vendor ID low byte
4344#   0x58: Device ID
4345# Note: The values were given by Alex van Kaam, we don't have datasheets
4346#       to confirm.
4347sub mozart_detect
4348{
4349  my ($file, $addr) = @_;
4350  my ($vid, $dev);
4351
4352  $vid = (i2c_smbus_read_byte_data($file, 0x4e) << 8)
4353       +  i2c_smbus_read_byte_data($file, 0x4f);
4354  $dev = i2c_smbus_read_byte_data($file, 0x58);
4355
4356  return unless ($dev == 0x56 && $vid == 0x9436)  # ASM58
4357             || ($dev == 0x56 && $vid == 0x9406)  # AS2K129R
4358             || ($dev == 0x10 && $vid == 0x5ca3);
4359
4360  return 5;
4361}
4362
4363# Chip to detect: 0 = GL518SM, 1 = GL520SM
4364# Registers used:
4365#   0x00: Device ID
4366#   0x01: Revision ID
4367#   0x03: Configuration
4368sub gl518sm_detect
4369{
4370  my ($file, $addr, $chip) = @_;
4371  my $reg;
4372
4373  $reg = i2c_smbus_read_byte_data($file, 0x00);
4374  return if $chip == 0 && $reg != 0x80;
4375  return if $chip == 1 && $reg != 0x20;
4376
4377  return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
4378  $reg = i2c_smbus_read_byte_data($file, 0x01);
4379  return unless $reg == 0x00 or $reg == 0x80;
4380  return 6;
4381}
4382
4383# Registers used:
4384#   0x00: Device ID
4385#   0x03: Configuration
4386# Mediocre detection
4387sub gl525sm_detect
4388{
4389  my ($file, $addr) = @_;
4390  return unless i2c_smbus_read_byte_data($file, 0x00) == 0x25;
4391  return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
4392  return 5;
4393}
4394
4395# Chip to detect: 0 = ADM9240, 1 = DS1780, 2 = LM81
4396# Registers used:
4397#   0x3e: Company ID
4398#   0x40: Configuration
4399#   0x48: Full I2C Address
4400sub adm9240_detect
4401{
4402  my ($file, $addr, $chip) = @_;
4403  my $reg;
4404  $reg = i2c_smbus_read_byte_data($file, 0x3e);
4405  return unless ($chip == 0 and $reg == 0x23) or
4406                ($chip == 1 and $reg == 0xda) or
4407                ($chip == 2 and $reg == 0x01);
4408  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4409  return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4410
4411  return 7;
4412}
4413
4414# Chip to detect: 0 = ADM1022, 1 = THMC50, 2 = ADM1028, 3 = THMC51
4415# Registers used:
4416#   0x3e: Company ID
4417#   0x3f: Revision
4418#   0x40: Configuration
4419sub adm1022_detect
4420{
4421  my ($file, $addr, $chip) = @_;
4422  my $reg;
4423  $reg = i2c_smbus_read_byte_data($file, 0x3e);
4424  return unless ($chip == 0 and $reg == 0x41) or
4425                ($chip == 1 and $reg == 0x49) or
4426                ($chip == 2 and $reg == 0x41) or
4427                ($chip == 3 and $reg == 0x49);
4428  $reg = i2c_smbus_read_byte_data($file, 0x40);
4429  return if ($reg & 0x10);                      # Soft Reset always reads 0
4430  return if ($chip != 0 and ($reg & 0x80));     # Reserved on THMC50 and ADM1028
4431  $reg = i2c_smbus_read_byte_data($file, 0x3f) & 0xf0;
4432  return unless ($chip == 0 and $reg == 0xc0) or
4433                ($chip == 1 and $reg == 0xc0) or
4434                ($chip == 2 and $reg == 0xd0) or
4435                ($chip == 3 and $reg == 0xd0);
4436  return 8;
4437}
4438
4439# Chip to detect: 0 = ADM1025, 1 = NE1619
4440# Registers used:
4441#   0x3e: Company ID
4442#   0x3f: Revision
4443#   0x40: Configuration
4444#   0x41: Status 1
4445#   0x42: Status 2
4446sub adm1025_detect
4447{
4448  my ($file, $addr, $chip) = @_;
4449  my $reg;
4450
4451  $reg = i2c_smbus_read_byte_data($file, 0x3e);
4452  return if ($chip == 0) and ($reg != 0x41);
4453  return if ($chip == 1) and ($reg != 0xA1);
4454
4455  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4456  return unless (i2c_smbus_read_byte_data($file, 0x41) & 0xC0) == 0x00;
4457  return unless (i2c_smbus_read_byte_data($file, 0x42) & 0xBC) == 0x00;
4458  return unless (i2c_smbus_read_byte_data($file, 0x3f) & 0xf0) == 0x20;
4459
4460  return 8;
4461}
4462
4463# Registers used:
4464#   0x16: Company ID
4465#   0x17: Revision
4466sub adm1026_detect
4467{
4468  my ($file, $addr) = @_;
4469  my $reg;
4470  $reg = i2c_smbus_read_byte_data($file, 0x16);
4471  return unless ($reg == 0x41);
4472  return unless (i2c_smbus_read_byte_data($file, 0x17) & 0xf0) == 0x40;
4473  return 8;
4474}
4475
4476# Chip to detect: 0 = ADM1021, 1 = ADM1021A/ADM1023, 2 = MAX1617, 3 = MAX1617A,
4477#                 4 = THMC10, 5 = LM84, 6 = GL523, 7 = MC1066
4478# Registers used:
4479#   0x04: Company ID (LM84 only)
4480#   0xfe: Company ID (all but LM84 and MAX1617)
4481#   0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A)
4482#   0x02: Status
4483#   0x03: Configuration
4484#   0x04: Conversion rate
4485#   0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84)
4486# Note: Especially the MAX1617 has very bad detection; we give it a low
4487# confidence value.
4488sub adm1021_detect
4489{
4490  my ($file, $addr, $chip) = @_;
4491  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4492  my $rev = i2c_smbus_read_byte_data($file, 0xff);
4493  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4494  my $status = i2c_smbus_read_byte_data($file, 0x02);
4495  my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4496
4497  # Check manufacturer IDs and product revisions when available
4498  return if $chip == 0 and $man_id != 0x41 ||
4499                          ($rev & 0xf0) != 0x00;
4500  return if $chip == 1 and $man_id != 0x41 ||
4501                          ($rev & 0xf0) != 0x30;
4502  return if $chip == 3 and $man_id != 0x4d ||
4503                           $rev != 0x01;
4504  return if $chip == 4 and $man_id != 0x49;
4505  return if $chip == 5 and $convrate != 0x00;
4506  return if $chip == 6 and $man_id != 0x23;
4507  return if $chip == 7 and $man_id != 0x54;
4508
4509  # Check unused bits
4510  if ($chip == 5) { # LM84
4511    return if ($status & 0xab) != 0;
4512    return if ($conf & 0x7f) != 0;
4513  } else {
4514    return if ($status & 0x03) != 0;
4515    return if ($conf & 0x3f) != 0;
4516    return if ($convrate & 0xf8) != 0;
4517  }
4518
4519  # Extra checks for MAX1617 and LM84, since those are often misdetected
4520  # We verify several assertions (6 for the MAX1617, 4 for the LM84) and
4521  # discard the chip if any fail. Note that these checks are not done
4522  # by the adm1021 driver.
4523  if ($chip == 2 || $chip == 5) {
4524    my $lte = i2c_smbus_read_byte_data($file, 0x00);
4525    my $rte = i2c_smbus_read_byte_data($file, 0x01);
4526    my $lhi = i2c_smbus_read_byte_data($file, 0x05);
4527    my $rhi = i2c_smbus_read_byte_data($file, 0x07);
4528    my $llo = i2c_smbus_read_byte_data($file, 0x06);
4529    my $rlo = i2c_smbus_read_byte_data($file, 0x08);
4530
4531    # If all registers hold the same value, it has to be a misdetection
4532    return if $lte == $rte and $lte == $lhi and $lte == $rhi
4533           and $lte == $llo and $lte == $rlo;
4534
4535    # Negative temperatures
4536    return if ($lte & 0x80) or ($rte & 0x80);
4537    # Negative high limits
4538    return if ($lhi & 0x80) or ($rhi & 0x80);
4539    # Low limits over high limits
4540    if ($chip != 5) { # LM84 doesn't have low limits
4541      $llo -= 256 if ($llo & 0x80);
4542      $rlo -= 256 if ($rlo & 0x80);
4543      return if ($llo > $lhi) or ($rlo > $rhi);
4544    }
4545  }
4546
4547  return 3 if ($chip == 2) or ($chip == 5);
4548  return 7 if $chip <= 3;
4549  return 5;
4550}
4551
4552# Chip to detect: 0 = MAX1668, 1 = MAX1805, 2 = MAX1989
4553# Registers used:
4554#   0xfe: Company ID
4555#   0xff: Device ID
4556sub max1668_detect
4557{
4558  my ($file, $addr, $chip) = @_;
4559  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4560  my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4561
4562  return if $man_id != 0x4d;
4563  return if $chip == 0 and $dev_id != 0x03;
4564  return if $chip == 1 and $dev_id != 0x05;
4565  return if $chip == 2 and $dev_id != 0x0b;
4566
4567  return 7;
4568}
4569
4570# Chip to detect: 0 = MAX1619, 1 = MAX1618
4571# Registers used:
4572#   0xfe: Company ID
4573#   0xff: Device ID
4574#   0x02: Status
4575#   0x03: Configuration
4576#   0x04: Conversion rate
4577sub max1619_detect
4578{
4579  my ($file, $addr, $chip) = @_;
4580  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4581  my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4582  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4583  my $status = i2c_smbus_read_byte_data($file, 0x02);
4584  my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4585
4586  if ($chip == 0) {     # MAX1619
4587    return if $man_id != 0x4D
4588      or $dev_id != 0x04
4589      or ($conf & 0x03)
4590      or ($status & 0x61)
4591      or $convrate >= 8;
4592  }
4593  if ($chip == 1) {     # MAX1618
4594    return if $man_id != 0x4D
4595      or $dev_id != 0x02
4596      or ($conf & 0x07)
4597      or ($status & 0x63);
4598  }
4599
4600  return 7;
4601}
4602
4603# Registers used:
4604#   0x28: User ID
4605#   0x29: User ID2
4606sub ite_overclock_detect
4607{
4608  my ($file, $addr) = @_;
4609
4610  my $uid1 = i2c_smbus_read_byte_data($file, 0x28);
4611  my $uid2 = i2c_smbus_read_byte_data($file, 0x29);
4612  return if $uid1 != 0x83
4613         || $uid2 != 0x12;
4614
4615  return 6;
4616}
4617
4618# Registers used:
4619#   0x00: Configuration
4620#   0x48: Full I2C Address
4621#   0x58: Mfr ID
4622#   0x5b: Device ID
4623sub it8712_i2c_detect
4624{
4625  my ($file, $addr) = @_;
4626  my $reg;
4627  return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4628  return unless (i2c_smbus_read_byte_data($file, 0x00) & 0x90) == 0x10;
4629  return unless i2c_smbus_read_byte_data($file, 0x58) == 0x90;
4630  return if i2c_smbus_read_byte_data($file, 0x5b) != 0x12;
4631  return 7 + ($addr == 0x2d);
4632}
4633
4634# Registers used:
4635#   0-63: SPD Data and Checksum
4636sub eeprom_detect
4637{
4638  my ($file, $addr) = @_;
4639  my $checksum = 0;
4640
4641  # Check the checksum for validity (works for most DIMMs and RIMMs)
4642  for (my $i = 0; $i <= 62; $i++) {
4643    $checksum += i2c_smbus_read_byte_data($file, $i);
4644  }
4645  $checksum &= 255;
4646
4647  return 8
4648    if $checksum == i2c_smbus_read_byte_data($file, 63);
4649
4650  return;
4651}
4652
4653# Registers used:
4654#   0x00..0x07: DDC signature
4655sub ddcmonitor_detect
4656{
4657  my ($file, $addr) = @_;
4658
4659  return unless
4660    i2c_smbus_read_byte_data($file, 0x00) == 0x00 and
4661    i2c_smbus_read_byte_data($file, 0x01) == 0xFF and
4662    i2c_smbus_read_byte_data($file, 0x02) == 0xFF and
4663    i2c_smbus_read_byte_data($file, 0x03) == 0xFF and
4664    i2c_smbus_read_byte_data($file, 0x04) == 0xFF and
4665    i2c_smbus_read_byte_data($file, 0x05) == 0xFF and
4666    i2c_smbus_read_byte_data($file, 0x06) == 0xFF and
4667    i2c_smbus_read_byte_data($file, 0x07) == 0x00;
4668
4669  return 8;
4670}
4671
4672# Chip to detect: 0 = Poseidon I, 1 = Poseidon II, 2 = Scylla,
4673#                 3 = Hermes, 4 = Heimdal, 5 = Heracles
4674# Registers used:
4675#   0x00-0x02: Identification (3 capital ASCII letters)
4676sub fsc_detect
4677{
4678  my ($file, $addr, $chip) = @_;
4679  my $id;
4680
4681  $id = chr(i2c_smbus_read_byte_data($file, 0x00))
4682      . chr(i2c_smbus_read_byte_data($file, 0x01))
4683      . chr(i2c_smbus_read_byte_data($file, 0x02));
4684
4685  return if $chip == 0 and $id ne 'PEG';  # Pegasus? aka Poseidon I
4686  return if $chip == 1 and $id ne 'POS';  # Poseidon II
4687  return if $chip == 2 and $id ne 'SCY';  # Scylla
4688  return if $chip == 3 and $id ne 'HER';  # Hermes
4689  return if $chip == 4 and $id ne 'HMD';  # Heimdal
4690  return if $chip == 5 and $id ne 'HRC';  # Heracles
4691
4692  return 8;
4693}
4694
4695# Registers used:
4696#   0x3E: Manufacturer ID
4697#   0x3F: Version/Stepping
4698sub lm93_detect
4699{
4700  my ($file, $addr) = @_;
4701  return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x01
4702            and i2c_smbus_read_byte_data($file, 0x3F) == 0x73;
4703  return 5;
4704}
4705
4706# Registers used:
4707#   0x3F: Revision ID
4708#   0x48: Address
4709#   0x4A, 0x4B, 0x4F, 0x57, 0x58: Reserved bits.
4710# We do not use 0x49's reserved bits on purpose. The register is named
4711# "VID4/Device ID" so it is doubtful bits 7-1 are really unused.
4712sub m5879_detect
4713{
4714  my ($file, $addr) = @_;
4715
4716  return
4717    unless i2c_smbus_read_byte_data($file, 0x3F) == 0x01;
4718
4719  return
4720    unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4721
4722  return
4723    unless (i2c_smbus_read_byte_data($file, 0x4A) & 0x06) == 0
4724       and (i2c_smbus_read_byte_data($file, 0x4B) & 0xFC) == 0
4725       and (i2c_smbus_read_byte_data($file, 0x4F) & 0xFC) == 0
4726       and (i2c_smbus_read_byte_data($file, 0x57) & 0xFE) == 0
4727       and (i2c_smbus_read_byte_data($file, 0x58) & 0xEF) == 0;
4728
4729  return 7;
4730}
4731
4732# Registers used:
4733#   0x3E: Manufacturer ID
4734#   0x3F: Version/Stepping
4735#   0x47: VID (3 reserved bits)
4736#   0x49: VID4 (7 reserved bits)
4737sub smsc47m192_detect
4738{
4739  my ($file, $addr) = @_;
4740  return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x55
4741           and (i2c_smbus_read_byte_data($file, 0x3F) & 0xF0) == 0x20
4742           and (i2c_smbus_read_byte_data($file, 0x47) & 0x70) == 0x00
4743           and (i2c_smbus_read_byte_data($file, 0x49) & 0xFE) == 0x80;
4744  return ($addr == 0x2d ? 6 : 5);
4745}
4746
4747# Chip to detect: 1 = DME1737, 2 = SCH5027
4748# Registers used:
4749#   0x3E: Manufacturer ID
4750#   0x3F: Version/Stepping
4751#   0x73: Read-only test register (4 test bits)
4752#   0x8A: Read-only test register (7 test bits)
4753#   0xBA: Read-only test register (8 test bits)
4754sub dme1737_detect
4755{
4756  my ($file, $addr, $chip) = @_;
4757  my $vendor = i2c_smbus_read_byte_data($file, 0x3E);
4758  my $verstep = i2c_smbus_read_byte_data($file, 0x3F);
4759
4760  return unless $vendor == 0x5C; # SMSC
4761
4762  if ($chip == 1) { # DME1737
4763      return unless ($verstep & 0xF8) == 0x88 and
4764          (i2c_smbus_read_byte_data($file, 0x73) & 0x0F) == 0x09 and
4765          (i2c_smbus_read_byte_data($file, 0x8A) & 0x7F) == 0x4D;
4766  } elsif ($chip == 2) { # SCH5027
4767      return unless $verstep >= 0x69 and $verstep <= 0x6F and
4768          i2c_smbus_read_byte_data($file, 0xBA) == 0x0F;
4769  }
4770
4771  return ($addr == 0x2e ? 6 : 5);
4772}
4773
4774# Chip to detect: 1 = F75111R/RG/N, 2 = F75121R/F75122R/RG, 3 = F75373S/SG,
4775#                 4 = F75375S/SP, 5 = F75387SG/RG, 6 = F75383M/S/F75384M/S,
4776#                 7 = custom power control IC
4777# Registers used:
4778#   0x5A-0x5B: Chip ID
4779#   0x5D-0x5E: Vendor ID
4780sub fintek_detect
4781{
4782  my ($file, $addr, $chip) = @_;
4783  my $chipid = (i2c_smbus_read_byte_data($file, 0x5A) << 8)
4784             | i2c_smbus_read_byte_data($file, 0x5B);
4785  my $vendid = (i2c_smbus_read_byte_data($file, 0x5D) << 8)
4786             | i2c_smbus_read_byte_data($file, 0x5E);
4787
4788  return unless $vendid == 0x1934; # Fintek ID
4789
4790  if ($chip == 1) { # F75111R/RG/N
4791    return unless $chipid == 0x0300;
4792  } elsif ($chip == 2) { # F75121R/F75122R/RG
4793    return unless $chipid == 0x0301;
4794  } elsif ($chip == 3) { # F75373S/SG
4795    return unless $chipid == 0x0204;
4796  } elsif ($chip == 4) { # F75375S/SP
4797    return unless $chipid == 0x0306;
4798  } elsif ($chip == 5) { # F75387SG/RG
4799    return unless $chipid == 0x0410;
4800  } elsif ($chip == 6) { # F75383M/S/F75384M/S
4801    # The datasheet has 0x0303, but Fintek say 0x0413 is also possible
4802    return unless $chipid == 0x0303 || $chipid == 0x0413;
4803  } elsif ($chip == 7) { # custom power control IC
4804    return unless $chipid == 0x0302;
4805  }
4806
4807  return 7;
4808}
4809
4810# This checks for non-FFFF values for temperature, voltage, and current.
4811# The address (0x0b) is specified by the SMBus standard so it's likely
4812# that this really is a smart battery.
4813sub smartbatt_detect
4814{
4815  my ($file, $addr) = @_;
4816
4817  return if i2c_smbus_read_word_data($file, 0x08) == 0xffff
4818         || i2c_smbus_read_word_data($file, 0x09) == 0xffff
4819         || i2c_smbus_read_word_data($file, 0x0a) == 0xffff;
4820  return 5;
4821}
4822
4823# Chip to detect: 0 = W83L784R/AR/G, 1 = W83L785R/G, 2 = W83L786NR/NG/R/G,
4824#                 3 = W83L785TS-S
4825# Registers used:
4826#   0x40: Configuration
4827#   0x4a: Full I2C Address (W83L784R only)
4828#   0x4b: I2C addresses of emulated LM75 chips (W83L784R only)
4829#   0x4c: Winbond Vendor ID (Low Byte)
4830#   0x4d: Winbond Vendor ID (High Byte)
4831#   0x4e: Chip ID
4832sub w83l784r_detect
4833{
4834  my ($file, $addr, $chip) = @_;
4835  my ($reg, @res);
4836
4837  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4838  return if $chip == 0
4839    and i2c_smbus_read_byte_data($file, 0x4a) != $addr;
4840  return unless i2c_smbus_read_byte_data($file, 0x4c) == 0xa3;
4841  return unless i2c_smbus_read_byte_data($file, 0x4d) == 0x5c;
4842
4843  $reg = i2c_smbus_read_byte_data($file, 0x4e);
4844  return if $chip == 0 and $reg != 0x50;
4845  return if $chip == 1 and $reg != 0x60;
4846  return if $chip == 2 and $reg != 0x80;
4847  return if $chip == 3 and $reg != 0x70;
4848
4849  return 8 if $chip != 0; # No subclients
4850
4851  @res = (8);
4852  $reg = i2c_smbus_read_byte_data($file, 0x4b);
4853  push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4854  push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4855  return @res;
4856}
4857
4858# The max6650 has no device ID register. However, a few registers have
4859# spare bits, which are documented as being always zero on read. We read
4860# all of these registers check the spare bits. Any non-zero means this
4861# is not a max6650/1.
4862#
4863# The always zero bits are:
4864#   configuration byte register (0x02) - top 2 bits
4865#   gpio status register (0x14) - top 3 bits
4866#   alarm enable register (0x08) - top 3 bits
4867#   alarm status register (0x0A) - top 3 bits
4868#   tachometer count time register (0x16) - top 6 bits
4869# Additionally, not all values are possible for lower 3 bits of
4870# the configuration register.
4871sub max6650_detect
4872{
4873  my ($file, $addr) = @_;
4874
4875  my $conf = i2c_smbus_read_byte_data($file, 0x02);
4876
4877  return if i2c_smbus_read_byte_data($file, 0x16) & 0xFC;
4878  return if i2c_smbus_read_byte_data($file, 0x0A) & 0xE0;
4879  return if i2c_smbus_read_byte_data($file, 0x08) & 0xE0;
4880  return if i2c_smbus_read_byte_data($file, 0x14) & 0xE0;
4881  return if ($conf & 0xC0) or ($conf & 0x07) > 4;
4882
4883  return 3;
4884}
4885
4886sub max6655_detect
4887{
4888  my ($file, $addr) = @_;
4889
4890  # checking RDID (Device ID)
4891  return unless i2c_smbus_read_byte_data($file, 0xfe) == 0x0a;
4892  # checking RDRV (Manufacturer ID)
4893  return unless i2c_smbus_read_byte_data($file, 0xff) == 0x4d;
4894  # checking unused bits (conversion rate, extended temperature)
4895  return unless i2c_smbus_read_byte_data($file, 0x04) & 0xf8;
4896  return unless i2c_smbus_read_byte_data($file, 0x10) & 0x1f;
4897  return unless i2c_smbus_read_byte_data($file, 0x11) & 0x1f;
4898  return unless i2c_smbus_read_byte_data($file, 0x12) & 0x1f;
4899
4900  return 6;
4901}
4902
4903# This isn't very good detection.
4904# Verify the i2c address, and the stepping ID (which is 0xb0 on
4905# my chip but could be different for others...
4906sub vt1211_i2c_detect
4907{
4908  my ($file, $addr) = @_;
4909  return unless (i2c_smbus_read_byte_data($file, 0x48) & 0x7f) == $addr;
4910  return unless i2c_smbus_read_byte_data($file, 0x3f) == 0xb0;
4911  return 2;
4912}
4913
4914# All ISA detection functions below take at least 1 parameter:
4915# $_[0]: Address
4916# Some of these functions which can detect more than one type of device,
4917# take a second parameter:
4918# $_[1]: Chip to detect
4919
4920# Chip to detect: 0 = LM78, 2 = LM79
4921sub lm78_isa_detect
4922{
4923  my ($addr, $chip) = @_;
4924  my $val = inb($addr + 1);
4925  return if inb($addr + 2) != $val or inb($addr + 3) != $val or
4926            inb($addr + 7) != $val;
4927
4928  $val = inb($addr + 5);
4929  outb($addr + 5, ~$val & 0x7f);
4930  if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4931    outb($addr+5, $val);
4932    return;
4933  }
4934
4935  return unless (isa_read_i5d6($addr, 0x40) & 0x80) == 0x00;
4936  my $reg = isa_read_i5d6($addr, 0x49);
4937  return unless ($chip == 0 and ($reg == 0x00 or $reg == 0x20 or $reg == 0x40)) or
4938                ($chip == 2 and ($reg & 0xfe) == 0xc0);
4939
4940  # Explicitly prevent misdetection of Winbond chips
4941  $reg = isa_read_i5d6($addr, 0x4f);
4942  return if $reg == 0xa3 || $reg == 0x5c;
4943
4944  # Explicitly prevent misdetection of ITE chips
4945  $reg = isa_read_i5d6($addr, 0x58);
4946  return if $reg == 0x90;
4947
4948  return 6;
4949}
4950
4951# Chip to detect: 0 = W83781D, 1 = W83782D
4952sub w83781d_isa_detect
4953{
4954  my ($addr, $chip) = @_;
4955  my ($reg1, $reg2);
4956  my $val = inb($addr + 1);
4957  return if inb($addr + 2) != $val or inb($addr + 3) != $val or
4958            inb($addr + 7) != $val;
4959
4960  $val = inb($addr + 5);
4961  outb($addr+5, ~$val & 0x7f);
4962  if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4963    outb($addr+5, $val);
4964    return;
4965  }
4966
4967  $reg1 = isa_read_i5d6($addr, 0x4e);
4968  $reg2 = isa_read_i5d6($addr, 0x4f);
4969  return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
4970                (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4971  return unless ($reg1 & 0x07) == 0x00;
4972  $reg1 = isa_read_i5d6($addr, 0x58);
4973  return if $chip == 0 and  ($reg1 & 0xfe) != 0x10;
4974  return if $chip == 1 and  ($reg1 & 0xfe) != 0x30;
4975
4976  return 8;
4977}
4978
4979# We simply look for a register at standard locations.
4980# For KCS, use the STATUS register. For SMIC, use the FLAGS register.
4981# Incidentally they live at the same offset.
4982sub ipmi_detect
4983{
4984  my ($addr) = @_;
4985  return if inb($addr + 3) == 0xff;
4986  return 4;
4987}
4988
4989###################
4990# ALIAS DETECTION #
4991###################
4992
4993# These functions take at least 3 parameters:
4994# $_[0]: ISA/LPC address
4995# $_[1]: I2C file handle
4996# $_[2]: I2C address
4997# Some of these functions may take extra parameters.
4998# They return 1 if both devices are the same, 0 if not.
4999
5000# Extra parameters:
5001# $_[3]: First limit register to compare
5002# $_[4]: Last limit register to compare
5003sub winbond_alias_detect
5004{
5005  my ($isa_addr, $file, $i2c_addr, $first, $last) = @_;
5006  my $i;
5007
5008  return 0 unless isa_read_i5d6($isa_addr, 0x48) == $i2c_addr;
5009  for ($i = $first; $i <= $last; $i++) {
5010    return 0 unless isa_read_i5d6($isa_addr, $i) == i2c_smbus_read_byte_data($file, $i);
5011  }
5012  return 1;
5013}
5014
5015sub vt1211_alias_detect
5016{
5017  my ($isa_addr, $file, $i2c_addr) = @_;
5018  my $i;
5019
5020  return 0 unless (inb($isa_addr + 0x48) & 0x7f) == $i2c_addr;
5021  for ($i = 0x2b; $i <= 0x3d; $i++) {
5022    return 0 unless inb($isa_addr + $i) == i2c_smbus_read_byte_data($file, $i);
5023  }
5024  return 1;
5025}
5026
5027
5028######################
5029# PCI CHIP DETECTION #
5030######################
5031
5032# Returns: undef if not detected, (9) if detected.
5033# The address is encoded in PCI space. We could decode it and print it.
5034sub sis5595_pci_detect
5035{
5036        return unless exists $pci_list{'1039:0008'};
5037        return 9;
5038}
5039
5040# Returns: undef if not detected, (9) if detected.
5041# The address is encoded in PCI space. We could decode it and print it.
5042sub via686a_pci_detect
5043{
5044        return unless exists $pci_list{'1106:3057'};
5045        return 9;
5046}
5047
5048# Returns: undef if not detected, (9) if detected.
5049# The address is encoded in PCI space. We could decode it and print it.
5050sub via8231_pci_detect
5051{
5052        return unless exists $pci_list{'1106:8235'};
5053        return 9;
5054}
5055
5056# Returns: undef if not detected, (9) if detected.
5057sub k8temp_pci_detect
5058{
5059        return unless exists $pci_list{'1022:1103'};
5060        return 9;
5061}
5062
5063sub k10temp_pci_detect
5064{
5065        return unless exists $pci_list{'1022:1203'};
5066        return 9;
5067}
5068
5069# Returns: undef if not detected, (9) if detected.
5070sub intel_amb_detect
5071{
5072        if ((exists $pci_list{'8086:25f0'}) ||  # Intel 5000
5073            (exists $pci_list{'8086:4030'})) {  # Intel 5400
5074                return 9;
5075        }
5076        return;
5077}
5078
5079# Returns: undef if not detected, (9) if detected.
5080sub coretemp_detect
5081{
5082        my $probecpu;
5083        foreach $probecpu (@cpu) {
5084                if ($probecpu->{'vendor_id'} eq 'GenuineIntel' &&
5085                                $probecpu->{'cpu family'} == 6 &&
5086                                ($probecpu->{'model'} == 14 ||
5087                                 $probecpu->{'model'} == 15 ||
5088                                 $probecpu->{'model'} == 0x16 ||
5089                                 $probecpu->{'model'} == 0x17)) {
5090                        return 9;
5091                }
5092        }
5093        return;
5094}
5095
5096# Returns: undef if not detected, (9) if detected.
5097sub c7temp_detect
5098{
5099        my $probecpu;
5100        foreach $probecpu (@cpu) {
5101                if ($probecpu->{'vendor_id'} eq 'CentaurHauls' &&
5102                                $probecpu->{'cpu family'} == 6 &&
5103                                ($probecpu->{'model'} == 0xa ||
5104                                 $probecpu->{'model'} == 0xd)) {
5105                        return 9;
5106                }
5107        }
5108        return;
5109}
5110
5111################
5112# MAIN PROGRAM #
5113################
5114
5115# $_[0]: reference to a list of chip hashes
5116sub print_chips_report
5117{
5118  my ($listref) = @_;
5119  my $data;
5120
5121  foreach $data (@$listref) {
5122    my $is_i2c = exists $data->{i2c_addr};
5123    my $is_isa = exists $data->{isa_addr};
5124    print "  * ";
5125    if ($is_i2c) {
5126      printf "Bus `%s'\n", $data->{i2c_adap};
5127      printf "    Busdriver `%s', I2C address 0x%02x",
5128             $data->{i2c_driver}, $data->{i2c_addr};
5129      if (exists $data->{i2c_sub_addrs}) {
5130        print " (and";
5131        my $sub_addr;
5132        foreach $sub_addr (@{$data->{i2c_sub_addrs}}) {
5133          printf " 0x%02x", $sub_addr;
5134        }
5135        print ")"
5136      }
5137      print "\n    ";
5138    }
5139    if ($is_isa) {
5140      print "ISA bus";
5141      if ($data->{isa_addr}) {
5142        printf ", address 0x%x", $data->{isa_addr};
5143      }
5144      print " (Busdriver `i2c-isa')"
5145        unless kernel_version_at_least(2, 6, 18);
5146      print "\n    ";
5147    }
5148    printf "Chip `%s' (confidence: %d)\n",
5149           $data->{chipname},  $data->{conf};
5150  }
5151}
5152
5153# We build here an array adapters, indexed on the number the adapter has
5154# at this moment (we assume only loaded adapters are interesting at all;
5155# everything that got scanned also got loaded). Each entry is a reference
5156# to a hash containing:
5157#  driver: Name of the adapter driver
5158#  nr_now: Number of the bus now
5159#  nr_later: Number of the bus when the modprobes are done (not included if the
5160#        driver should not be loaded)
5161# A second array, called
5162sub generate_modprobes
5163{
5164  my ($chip, $detection, $nr, $i, @optionlist, @probelist, $driver, $isa, $adap);
5165  my $ipmi = 0;
5166  my $modprobes = "";
5167  my $configfile;
5168
5169  # Collect all adapters used
5170  $nr = 0;
5171  $isa = 0;
5172  foreach $chip (@chips_detected) {
5173    foreach $detection (@{$chip->{detected}}) {
5174      # If there is more than one bus detected by a driver, they are
5175      # still all added. So we number them in the correct order
5176      if (exists $detection->{i2c_driver} and
5177          not exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later} and
5178          not exists $detection->{isa_addr}) { # Always use ISA access if possible
5179         foreach $adap (@i2c_adapters) {
5180           next unless exists $adap->{driver};
5181           $adap->{nr_later} = $nr++ if $adap->{driver} eq $detection->{i2c_driver};
5182         }
5183      }
5184      if (exists $detection->{isa_addr}) {
5185           $isa = 1;
5186      }
5187      if ($chip->{driver} eq "bmcsensors" ||
5188          $chip->{driver} eq "ipmisensors") {
5189           $ipmi = 1;
5190      }
5191    }
5192  }
5193
5194  $modprobes .= "# I2C adapter drivers\n" if $nr;
5195  for ($i = 0; $i < $nr; $i++) {
5196    foreach $adap (@i2c_adapters) {
5197      next unless exists $adap->{nr_later} and $adap->{nr_later} == $i;
5198      if ($adap->{driver} eq "UNKNOWN") {
5199        $modprobes .= "# modprobe unknown adapter ".$adap->{name}."\n";
5200      } else {
5201        $modprobes .= "modprobe $adap->{driver}\n"
5202          unless $modprobes =~ /modprobe $adap->{driver}\n/;
5203      }
5204      last;
5205    }
5206  }
5207  # i2c-isa is loaded automatically (as a dependency) since 2.6.14,
5208  # and will soon be gone.
5209  $modprobes .= "modprobe i2c-isa\n" if ($isa && !kernel_version_at_least(2, 6, 18));
5210  if ($ipmi) {
5211    $modprobes .= "# You must also install and load the IPMI modules\n";
5212    $modprobes .= "modprobe ipmi-si\n";
5213  }
5214
5215  # Now determine the chip probe lines
5216  $modprobes .= "# Chip drivers\n";
5217  foreach $chip (@chips_detected) {
5218    next if not @{$chip->{detected}};
5219    if ($chip->{driver} eq "to-be-written") {
5220      $modprobes .= "# no driver for $chip->{detected}[0]{chipname} yet\n";
5221    } else {
5222       open(local *INPUTFILE, "modprobe -l $chip->{driver} 2>/dev/null |");
5223       local $_;
5224       my $modulefound = 0;
5225       while (<INPUTFILE>) {
5226         if (m@/@) {
5227           $modulefound = 1;
5228           last;
5229         }
5230       }
5231       close(INPUTFILE);
5232       #check return value from modprobe in case modprobe -l isn't supported
5233       if ((($? >> 8) == 0) && ! $modulefound) {
5234         $modprobes .= "# Warning: the required module $chip->{driver} is not currently installed\n".
5235                       "# on your system. For status of 2.6 kernel ports check\n".
5236                       "# http://www.lm-sensors.org/wiki/Devices. If driver is built\n".
5237                       "# into the kernel, or unavailable, comment out the following line.\n";
5238       }
5239       $modprobes .= "modprobe $chip->{driver}\n";
5240    }
5241
5242    # Handle misdetects
5243    foreach $detection (@{$chip->{misdetected}}) {
5244      push @optionlist, $i2c_adapters[$detection->{i2c_devnr}]->{nr_later},
5245                       $detection->{i2c_addr}
5246           if exists $detection->{i2c_addr} and
5247              exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later};
5248      push @optionlist, -1, $detection->{isa_addr}
5249           if exists $detection->{isa_addr};
5250    }
5251
5252    # Handle aliases
5253    foreach $detection (@{$chip->{detected}}) {
5254      if (exists $detection->{i2c_driver} and
5255          exists $detection->{isa_addr} and
5256          exists $i2c_adapters[$detection->{i2c_devnr}]->{nr_later}) {
5257        push @optionlist, $i2c_adapters[$detection->{i2c_devnr}]->{nr_later},
5258                          $detection->{i2c_addr};
5259      }
5260    }
5261
5262    next if not (@probelist or @optionlist);
5263    $configfile = "# hwmon module options\n" unless defined $configfile;
5264    $configfile .= "options $chip->{driver}";
5265    $configfile .= sprintf(" ignore=%d,0x%02x", shift @optionlist,
5266                                               shift @optionlist)
5267                  if @optionlist;
5268    $configfile .= sprintf(",%d,0x%02x", shift @optionlist, shift @optionlist)
5269                  while @optionlist;
5270    $configfile .= sprintf(" probe=%d,0x%02x", shift @probelist,
5271                                              shift @probelist)
5272                  if @probelist;
5273    $configfile .= sprintf(",%d,0x%02x", shift @probelist, shift @probelist)
5274                  while @probelist;
5275    $configfile .= "\n";
5276  }
5277
5278  return ($modprobes, $configfile);
5279
5280}
5281
5282sub main
5283{
5284  my (@adapters, $res, $did_adapter_detection, $adapter);
5285
5286  # We won't go very far if not root
5287  unless ($> == 0) {
5288    print "You need to be root to run this script.\n";
5289    exit -1;
5290  }
5291
5292  if (-x "/sbin/service" && -f "/etc/init.d/lm_sensors" &&
5293      -f "/var/lock/subsys/lm_sensors") {
5294    system("/sbin/service", "lm_sensors", "stop");
5295  }
5296
5297  initialize_kernel_version();
5298  initialize_conf();
5299  initialize_pci();
5300  initialize_modules_list();
5301  # make sure any special case chips are added to the chip_ids list before
5302  # making the support modules list
5303  chip_special_cases();
5304  initialize_modules_supported();
5305  initialize_cpu_list();
5306
5307  print "# sensors-detect revision $revision\n\n";
5308
5309  print "This program will help you determine which kernel modules you need\n",
5310        "to load to use lm_sensors most effectively. It is generally safe\n",
5311        "and recommended to accept the default answers to all questions,\n",
5312        "unless you know what you're doing.\n";
5313  print "\n";
5314
5315  print "We can start with probing for (PCI) I2C or SMBus adapters.\n";
5316  print "Do you want to probe now? (YES/no): ";
5317  @adapters = adapter_pci_detection()
5318                        if ($did_adapter_detection = not <STDIN> =~ /\s*[Nn]/);
5319  print "\n";
5320
5321  if (not $did_adapter_detection) {
5322    print "As you skipped adapter detection, we will only scan already loaded\n".
5323          "adapter modules.\n";
5324  } else {
5325    print "We will now try to load each adapter module in turn.\n"
5326      if (@adapters);
5327    foreach $adapter (@adapters) {
5328      if (exists($modules_list{$adapter})) {
5329        print "Module `$adapter' already loaded.\n";
5330      } else {
5331        print "Load `$adapter' (say NO if built into your kernel)? (YES/no): ";
5332        unless (<STDIN> =~ /^\s*[Nn]/) {
5333          if (system("modprobe", $adapter)) {
5334            print "Loading failed... skipping.\n";
5335          } else {
5336            print "Module loaded successfully.\n";
5337          }
5338        }
5339      }
5340    }
5341  }
5342
5343  print "If you have undetectable or unsupported I2C/SMBus adapters, you can have\n".
5344        "them scanned by manually loading the modules before running this script.\n\n";
5345  initialize_i2c_adapters_list();
5346
5347  if (! -e "$sysfs_root/class/i2c-dev") {
5348    print "To continue, we need module `i2c-dev' to be loaded.\n";
5349    print "Do you want to load `i2c-dev' now? (YES/no): ";
5350    if (<STDIN> =~ /^\s*n/i) {
5351      print "Well, you will know best.\n";
5352    } elsif (system("modprobe", "i2c-dev")) {
5353      print "Loading failed, expect problems later on.\n";
5354    } else {
5355      print "Module loaded successfully.\n";
5356    }
5357    print "\n";
5358  }
5359
5360  $i2c_addresses_to_scan = i2c_addresses_to_scan();
5361
5362  print "We are now going to do the I2C/SMBus adapter probings. Some chips may\n",
5363        "be double detected; we choose the one with the highest confidence\n",
5364        "value in that case.\n",
5365        "If you found that the adapter hung after probing a certain address,\n",
5366        "you can specify that address to remain unprobed.\n";
5367
5368  my ($inp, @not_to_scan, $inp2);
5369  for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
5370    next unless exists $i2c_adapters[$dev_nr];
5371    my $adap = $i2c_adapters[$dev_nr]->{'name'};
5372    print "\n";
5373    print "Next adapter: $adap (i2c-$dev_nr)\n";
5374    print "Do you want to scan it? (YES/no/selectively): ";
5375
5376    $inp = <STDIN>;
5377    if ($inp =~ /^\s*[Ss]/) {
5378      print "Please enter one or more addresses not to scan. Separate them ",
5379            "with comma's.\n",
5380            "You can specify a range by using dashes. Addresses may be ",
5381            "decimal (like 54)\n",
5382            "or hexadecimal (like 0x33).\n",
5383            "Addresses: ";
5384      $inp2 = <STDIN>;
5385      chop($inp2);
5386      @not_to_scan = parse_not_to_scan(0x03, 0x77, $inp2);
5387    }
5388    scan_adapter($dev_nr, $adap, $i2c_adapters[$dev_nr]->{'driver'},
5389                 \@not_to_scan) unless $inp =~ /^\s*[Nn]/;
5390  }
5391  print "\n";
5392
5393  # Skip "random" I/O port probing on PPC
5394  if ($kernel_arch ne 'ppc'
5395   && $kernel_arch ne 'ppc64') {
5396    print "Some chips are also accessible through the ISA I/O ports. We have to\n".
5397          "write to arbitrary I/O ports to probe them. This is usually safe though.\n".
5398          "Yes, you do have ISA I/O ports even if you do not have any ISA slots!\n";
5399    print "Do you want to scan the ISA I/O ports? (YES/no): ";
5400    unless (<STDIN> =~ /^\s*n/i) {
5401      initialize_ioports();
5402      scan_isa_bus();
5403      close_ioports();
5404    }
5405    print "\n";
5406
5407    print "Some Super I/O chips may also contain sensors. We have to write to\n".
5408          "standard I/O ports to probe them. This is usually safe.\n";
5409    print "Do you want to scan for Super I/O sensors? (YES/no): ";
5410    unless (<STDIN> =~ /^\s*n/i) {
5411      initialize_ioports();
5412      scan_superio(0x2e, 0x2f);
5413      scan_superio(0x4e, 0x4f);
5414      close_ioports();
5415    }
5416    print "\n";
5417  }
5418
5419  print "Some south bridges, CPUs or memory controllers may also contain\n";
5420  print "embedded sensors. Do you want to scan for them? (YES/no): ";
5421  unless (<STDIN> =~ /^\s*n/i) {
5422    $| = 1;
5423    foreach my $entry (@cpu_ids) {
5424      scan_cpu($entry);
5425    }
5426    $| = 0;
5427  }
5428  print "\n";
5429
5430  if (! @chips_detected) {
5431    print "Sorry, no sensors were detected.\n",
5432          "Either your sensors are not supported, or they are connected to an\n",
5433          "I2C or SMBus adapter that is not supported. See\n",
5434          "http://www.lm-sensors.org/wiki/FAQ/Chapter3 for further information.\n",
5435          "If you find out what chips are on your board, check\n",
5436          "http://www.lm-sensors.org/wiki/Devices for driver status.\n";
5437    exit;
5438  }
5439
5440  print "Now follows a summary of the probes I have just done.\n".
5441        "Just press ENTER to continue: ";
5442  <STDIN>;
5443
5444  my ($chip, $data);
5445  foreach $chip (@chips_detected) {
5446    print "\nDriver `$chip->{driver}' ";
5447    if (@{$chip->{detected}}) {
5448      if (@{$chip->{misdetected}}) {
5449        print "(should be inserted but causes problems):\n";
5450      } else {
5451        print "(should be inserted):\n";
5452      }
5453    } else {
5454      if (@{$chip->{misdetected}}) {
5455        print "(may not be inserted):\n";
5456      } else {
5457        print "(should not be inserted, but is harmless):\n";
5458      }
5459    }
5460    if (@{$chip->{detected}}) {
5461      print "  Detects correctly:\n";
5462      print_chips_report($chip->{detected});
5463    }
5464    if (@{$chip->{misdetected}}) {
5465      print "  Misdetects:\n";
5466      print_chips_report($chip->{misdetected});
5467    }
5468  }
5469  print "\n";
5470
5471  my ($modprobes, $configfile) = generate_modprobes();
5472
5473  if (defined $configfile) {
5474    my $have_modprobe_d = -d '/etc/modprobe.d';
5475    printf "Do you want to \%s /etc/modprobe.d/lm_sensors? (\%s): ",
5476           (-e '/etc/modprobe.d/lm_sensors' ? 'overwrite' : 'generate'),
5477           ($have_modprobe_d ? 'YES/no' : 'yes/NO');
5478    $_ = <STDIN>;
5479    if (($have_modprobe_d and not m/^\s*n/i) or m/^\s*y/i) {
5480      unless ($have_modprobe_d) {
5481        mkdir('/etc/modprobe.d', 0777)
5482          or die "Sorry, can't create /etc/modprobe.d ($!)";
5483      }
5484      open(local *MODPROBE_D, ">/etc/modprobe.d/lm_sensors")
5485        or die "Sorry, can't create /etc/modprobe.d/lm_sensors ($!)";
5486      print MODPROBE_D
5487        "# Generated by sensors-detect on " . scalar localtime() . "\n";
5488      print MODPROBE_D $configfile;
5489      close(MODPROBE_D);
5490    } else {
5491      print "To make the sensors modules behave correctly, add these lines to\n".
5492            "/etc/modprobe.conf:\n\n";
5493      print "#----cut here----\n".
5494            $configfile.
5495            "#----cut here----\n\n";
5496    }
5497  }
5498
5499  my $have_sysconfig = -d '/etc/sysconfig';
5500  printf "Do you want to \%s /etc/sysconfig/lm_sensors? (\%s): ",
5501         (-e '/etc/sysconfig/lm_sensors' ? 'overwrite' : 'generate'),
5502         ($have_sysconfig ? 'YES/no' : 'yes/NO');
5503  $_ = <STDIN>;
5504  if (($have_sysconfig and not m/^\s*n/i) or m/^\s*y/i) {
5505    unless ($have_sysconfig) {
5506      mkdir('/etc/sysconfig', 0777)
5507        or die "Sorry, can't create /etc/sysconfig ($!)";
5508    }
5509    open(local *SYSCONFIG, ">/etc/sysconfig/lm_sensors")
5510      or die "Sorry, can't create /etc/sysconfig/lm_sensors ($!)";
5511    print SYSCONFIG <<'EOT';
5512#    /etc/sysconfig/lm_sensors - Defines modules loaded by
5513#                                /etc/init.d/lm_sensors
5514#    Copyright (c) 1998 - 2001  Frodo Looijaard <frodol@dds.nl>
5515#
5516#    This program is free software; you can redistribute it and/or modify
5517#    it under the terms of the GNU General Public License as published by
5518#    the Free Software Foundation; either version 2 of the License, or
5519#    (at your option) any later version.
5520#
5521#    This program is distributed in the hope that it will be useful,
5522#    but WITHOUT ANY WARRANTY; without even the implied warranty of
5523#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5524#    GNU General Public License for more details.
5525#
5526#    You should have received a copy of the GNU General Public License
5527#    along with this program; if not, write to the Free Software
5528#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
5529#    MA 02110-1301 USA.
5530#
5531#
5532# See also the lm_sensors homepage at:
5533#     http://www.lm-sensors.org/
5534#
5535# This file is used by /etc/init.d/lm_sensors and defines the modules to
5536# be loaded/unloaded. This file is sourced into /etc/init.d/lm_sensors.
5537#
5538# The format of this file is a shell script that simply defines the modules
5539# in order as normal variables with the special names:
5540#    MODULE_0, MODULE_1, MODULE_2, etc.
5541#
5542# List the modules that are to be loaded for your system
5543#
5544EOT
5545    print SYSCONFIG
5546      "# Generated by sensors-detect on " . scalar localtime() . "\n";
5547    my @modules = grep /^modprobe /, split "\n", $modprobes;
5548    my $i = 0;
5549    my $sysconfig = "";
5550    foreach (@modules) {
5551      s/^modprobe //;
5552      $sysconfig .= "MODULE_$i=$_\n";
5553      $i++;
5554    }
5555    print SYSCONFIG $sysconfig;
5556    close(SYSCONFIG);
5557
5558    print "Copy prog/init/lm_sensors.init to /etc/init.d/lm_sensors\n".
5559          "for initialization at boot time.\n"
5560      unless -f "/etc/init.d/lm_sensors";
5561
5562    if (-x "/sbin/insserv" && -f "/etc/init.d/lm_sensors") {
5563      system("/sbin/insserv", "/etc/init.d/lm_sensors");
5564    } elsif (-x "/sbin/chkconfig" && -f "/etc/init.d/lm_sensors") {
5565      system("/sbin/chkconfig", "lm_sensors", "on");
5566      if (-x "/sbin/service") {
5567        system("/sbin/service", "lm_sensors", "start");
5568      }
5569    } else {
5570      print "You should now start the lm_sensors service to load the required\n".
5571            "kernel modules.\n\n";
5572    }
5573  } else {
5574    print "To load everything that is needed, add this to one of the system\n".
5575          "initialization scripts (e.g. /etc/rc.d/rc.local):\n\n";
5576    print "#----cut here----\n".
5577          $modprobes.
5578          (-e '/usr/bin/sensors' ?
5579            "/usr/bin/sensors -s\n" :
5580            "/usr/local/bin/sensors -s\n") .
5581          "#----cut here----\n\n";
5582
5583    print "If you have some drivers built into your kernel, the list above will\n".
5584          "contain too many modules. Skip the appropriate ones! You really\n".
5585          "should try these commands right now to make sure everything is\n".
5586          "working properly. Monitoring programs won't work until the needed\n".
5587          "modules are loaded.\n\n";
5588  }
5589}
5590
5591main;
Note: See TracBrowser for help on using the browser.