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

Revision 5449, 157.1 KB (checked in by khali, 4 years ago)

Consistently don't quote hash keys which don't need quotes. Use
single quotes when quotes are needed.

  • 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}
2084
2085# $_[0]: port to read
2086# Returns: -1 on failure, read value on success.
2087sub inb
2088{
2089        my ($res, $nrchars);
2090        sysseek(IOPORTS, $_[0], 0) or return -1;
2091        $nrchars = sysread(IOPORTS, $res, 1);
2092        return -1 if not defined $nrchars or $nrchars != 1;
2093        $res = unpack("C", $res);
2094        return $res;
2095}
2096
2097# $_[0]: port to write
2098# $_[1]: value to write
2099# We assume this can't fail.
2100sub outb
2101{
2102        sysseek(IOPORTS, $_[0], 0);
2103        syswrite(IOPORTS, pack("C", $_[1]), 1);
2104}
2105
2106# $_[0]: Address register
2107# $_[1]: Data register
2108# $_[2]: Register to read
2109# Returns: read value
2110sub isa_read_byte
2111{
2112        outb($_[0], $_[2]);
2113        return inb($_[1]);
2114}
2115
2116# $_[0]: Base address
2117# $_[1]: Register to read
2118# Returns: read value
2119# This one can be used for any ISA chip with index register at
2120# offset 5 and data register at offset 6.
2121sub isa_read_i5d6
2122{
2123        my ($addr, $reg) = @_;
2124        return isa_read_byte($addr + 5, $addr + 6, $reg);
2125}
2126
2127#################
2128# AUTODETECTION #
2129#################
2130
2131use vars qw($dev_i2c $sysfs_root);
2132
2133sub initialize_conf
2134{
2135  my $use_devfs = 0;
2136  open(local *INPUTFILE, "/proc/mounts") or die "Can't access /proc/mounts!";
2137  local $_;
2138  while (<INPUTFILE>) {
2139    if (m@^\w+ /dev devfs @) {
2140      $use_devfs = 1;
2141      $dev_i2c = '/dev/i2c/';
2142    }
2143    if (m@^\S+ (/\w+) sysfs @) {
2144      $sysfs_root = $1;
2145    }
2146  }
2147  close(INPUTFILE);
2148
2149  # We need sysfs for many things
2150  if (!defined $sysfs_root) {
2151      print "Sysfs not mounted?\n";
2152      exit -1;
2153  }
2154
2155  my $use_udev = 0;
2156  if (open(*INPUTFILE, '/etc/udev/udev.conf')) {
2157    while (<INPUTFILE>) {
2158      if (m/^\s*udev_db\s*=\s*\"([^"]*)\"/ || m/^\s*udev_db\s*=\s*(\S+)/) {
2159        if (-e $1) {
2160          $use_udev = 1;
2161          $dev_i2c = '/dev/i2c-';
2162        }
2163        last;
2164      }
2165    }
2166    close(INPUTFILE);
2167  }
2168
2169  if (!$use_udev) {
2170    # Try some known default udev db locations, just in case
2171    if (-e '/dev/.udev.tdb' || -e '/dev/.udev'
2172     || -e '/dev/.udevdb') {
2173      $use_udev = 1;
2174      $dev_i2c = '/dev/i2c-';
2175    }
2176  }
2177
2178  if (!($use_devfs || $use_udev)) {
2179    if (! -c '/dev/i2c-0' && -x '/sbin/MAKEDEV') {
2180      system("/sbin/MAKEDEV i2c");
2181    }
2182    if (! -c '/dev/i2c-0' && -x '/dev/MAKEDEV') {
2183      system("/dev/MAKEDEV i2c");
2184    }
2185    if (-c '/dev/i2c-0') {
2186      $dev_i2c = '/dev/i2c-';
2187    } else { # default
2188      print "No i2c device files found.\n";
2189      exit -1;
2190    }
2191  }
2192}
2193
2194# [0] -> VERSION
2195# [1] -> PATCHLEVEL
2196# [2] -> SUBLEVEL
2197# [3] -> EXTRAVERSION
2198#
2199use vars qw(@kernel_version $kernel_arch);
2200
2201sub initialize_kernel_version
2202{
2203  `uname -r` =~ /(\d+)\.(\d+)\.(\d+)(.*)/;
2204  @kernel_version = ($1, $2, $3, $4);
2205  chomp($kernel_arch = `uname -m`);
2206
2207  # We only support kernels >= 2.6.0
2208  if (!kernel_version_at_least(2, 6, 0)) {
2209      print "Kernel version is unsupported (too old, >= 2.6.0 needed)\n";
2210      exit -1;
2211  }
2212}
2213
2214sub kernel_version_at_least
2215{
2216  my ($vers, $plvl, $slvl) = @_;
2217  return 1 if ($kernel_version[0]  > $vers ||
2218                ($kernel_version[0] == $vers &&
2219                  ($kernel_version[1]  > $plvl ||
2220                    ($kernel_version[1] == $plvl &&
2221                      ($kernel_version[2] >= $slvl)))));
2222  return 0;
2223}
2224
2225# @cpu is a list of reference to hashes, one hash per CPU.
2226# Each entry has the following keys: vendor_id, cpu family, model,
2227# model name and stepping, directly taken from /proc/cpuinfo.
2228use vars qw(@cpu);
2229
2230sub initialize_cpu_list
2231{
2232  open(local *INPUTFILE, "/proc/cpuinfo") or die "Can't access /proc/cpuinfo!";
2233  local $_;
2234  my $entry;
2235
2236  while (<INPUTFILE>) {
2237    if (m/^processor\s*:\s*(\d+)/) {
2238      push @cpu, $entry if scalar keys(%{$entry}); # Previous entry
2239      $entry = {}; # New entry
2240      next;
2241    }
2242    if (m/^(vendor_id|cpu family|model|model name|stepping)\s*:\s*(.+)$/) {
2243      my $k = $1;
2244      my $v = $2;
2245      $v =~ s/\s+/ /g;  # Merge multiple spaces
2246      $v =~ s/ $//;     # Trim trailing space
2247      $entry->{$k} = $v;
2248      next;
2249    }
2250  }
2251  push @cpu, $entry if scalar keys(%{$entry}); # Last entry
2252  close(INPUTFILE);
2253}
2254
2255# @i2c_adapters is a list of references to hashes, one hash per I2C/SMBus
2256# adapter present on the system. Each entry has the following keys: name
2257# (directly taken from /sys/class/i2c-adapter) and driver.
2258use vars qw(@i2c_adapters);
2259
2260sub initialize_i2c_adapters_list
2261{
2262  my $entry;
2263  local $_;
2264
2265  my $class_dir = "${sysfs_root}/class/i2c-adapter";
2266  opendir(local *ADAPTERS, $class_dir) or return;
2267
2268  while (defined($_ = readdir(ADAPTERS))) {
2269    next unless m/^i2c-(\d+)$/;
2270    $entry = {}; # New entry
2271    $entry->{name} = sysfs_device_attribute("${class_dir}/i2c-$1", "name")
2272                  || sysfs_device_attribute("${class_dir}/i2c-$1/device", "name");
2273    next if $entry->{name} eq "ISA main adapter";
2274
2275    # First try to get the I2C adapter driver name from sysfs, and if it
2276    # fails, fall back to searching our list of known I2C adapters.
2277    $entry->{driver} = sysfs_device_driver("${class_dir}/i2c-$1/device")
2278                    || find_i2c_adapter_driver($entry->{name})
2279                    || 'UNKNOWN';
2280    $i2c_adapters[$1] = $entry;
2281  }
2282  closedir(ADAPTERS);
2283}
2284
2285###########
2286# MODULES #
2287###########
2288
2289use vars qw(%modules_list %modules_supported @modules_we_loaded);
2290
2291sub initialize_modules_list
2292{
2293        local $_;
2294
2295        open(local *INPUTFILE, "/proc/modules") or return;
2296        while (<INPUTFILE>) {
2297                tr/-/_/; # Probably not needed
2298                $modules_list{$1} = 1 if m/^(\S*)/;
2299        }
2300}
2301
2302sub is_module_loaded
2303{
2304        my $module = shift;
2305        $module =~ tr/-/_/;
2306        return exists $modules_list{$module}
2307}
2308
2309sub load_module
2310{
2311        my $module = shift;
2312
2313        return if is_module_loaded($module);
2314
2315        system("modprobe", $module);
2316        if (($? >> 8) != 0) {
2317                print "Failed to load module $module.\n";
2318                return -1;
2319        }
2320
2321        print "Module $module loaded successfully.\n";
2322        push @modules_we_loaded, $module;
2323
2324        # Update the list of loaded modules
2325        my $normalized = $module;
2326        $normalized =~ tr/-/_/;
2327        $modules_list{$normalized} = 1;
2328}
2329
2330sub initialize_modules_supported
2331{
2332        foreach my $chip (@chip_ids) {
2333                $modules_supported{$chip->{driver}}++;
2334        }
2335}
2336
2337sub unload_modules
2338{
2339        return unless @modules_we_loaded;
2340
2341        # Attempt to unload all kernel drivers we loaded ourselves
2342        while (my $module = pop @modules_we_loaded) {
2343                print "Unloading $module... ";
2344                system("modprobe -r $module 2> /dev/null");
2345                if (($? >> 8) == 0) {
2346                        print "OK\n";
2347                } else {
2348                        print "failed\n";
2349                }
2350        }
2351        print "\n";
2352}
2353
2354#################
2355# SYSFS HELPERS #
2356#################
2357
2358# From a sysfs device path, return the driver (module) name, or undef
2359sub sysfs_device_driver
2360{
2361        my $device = shift;
2362
2363        my $link = readlink("$device/driver/module");
2364        return unless defined $link;
2365        return basename($link);
2366}
2367
2368# From a sysfs device path and an attribute name, return the attribute
2369# value, or undef
2370sub sysfs_device_attribute
2371{
2372        my ($device, $attr) = @_;
2373        my $value;
2374
2375        open(local *FILE, "$device/$attr") or return;
2376        $value = <FILE>;
2377        close(FILE);
2378        return unless defined $value;
2379
2380        chomp($value);
2381        return $value;
2382}
2383
2384##############
2385# PCI ACCESS #
2386##############
2387
2388use vars qw(%pci_list);
2389
2390# This function returns a list of hashes. Each hash has some PCI information:
2391# 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a
2392# computer; 'vendid' and 'devid' uniquely identify a type of device.
2393# 'class' lets us spot unknown SMBus adapters.
2394sub read_sys_dev_pci
2395{
2396        my $devices = shift;
2397        my ($dev, @pci_list);
2398
2399        opendir(local *DEVICES, "$devices")
2400                or die "$devices: $!";
2401
2402        while (defined($dev = readdir(DEVICES))) {
2403                my %record;
2404                next unless $dev =~
2405                        m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/;
2406
2407                $record{domain} = hex $1;
2408                $record{bus} = hex $2;
2409                $record{slot} = hex $3;
2410                $record{func} = hex $4;
2411
2412                $record{vendid} = oct sysfs_device_attribute("$devices/$dev",
2413                                                             "vendor");
2414                $record{devid} = oct sysfs_device_attribute("$devices/$dev",
2415                                                            "device");
2416                $record{class} = (oct sysfs_device_attribute("$devices/$dev",
2417                                                             "class")) >> 8;
2418
2419                push @pci_list, \%record;
2420        }
2421
2422        return \@pci_list;
2423}
2424
2425sub initialize_pci
2426{
2427        my $pci_list;
2428        local $_;
2429
2430        $pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices");
2431
2432        # Note that we lose duplicate devices at this point, but we don't
2433        # really care. What matters to us is which unique devices are present,
2434        # not how many of each.
2435        %pci_list = map {
2436                sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_
2437        } @{$pci_list};
2438}
2439
2440#####################
2441# ADAPTER DETECTION #
2442#####################
2443
2444sub adapter_pci_detection_sis_96x
2445{
2446  my $driver = "";
2447
2448  # first, determine which driver if any...
2449  if (exists $pci_list{'1039:0016'}) {
2450    $driver = "i2c-sis96x";
2451  } elsif (exists $pci_list{'1039:0008'}) {
2452    $driver = "i2c-sis5595";
2453  }
2454
2455  # then, add the appropriate entries to @pci_adapters
2456  if ($driver eq "i2c-sis5595") {
2457    push @pci_adapters, @pci_adapters_sis5595;
2458  } elsif ($driver eq "i2c-sis96x") {
2459    push @pci_adapters, @pci_adapters_sis96x;
2460  }
2461}
2462
2463# Build and return a PCI device's bus ID
2464sub pci_busid
2465{
2466  my $device = shift;
2467  my $busid;
2468
2469  $busid = sprintf("\%02x:\%02x.\%x",
2470                   $device->{bus}, $device->{slot}, $device->{func});
2471  $busid = sprintf("\%04x:", $device->{domain}) . $busid
2472    if defined $device->{domain};
2473
2474  return $busid;
2475}
2476
2477sub adapter_pci_detection
2478{
2479  my ($key, $device, $try, %smbus, $count);
2480  print "Probing for PCI bus adapters...\n";
2481
2482  # Custom detection routine for some SiS chipsets
2483  adapter_pci_detection_sis_96x();
2484
2485  # Build a list of detected SMBus devices
2486  foreach $key (keys %pci_list) {
2487    $device = $pci_list{$key};
2488    $smbus{$key}++
2489      if exists $device->{class} && $device->{class} == 0x0c05; # SMBus
2490  }
2491
2492  # Loop over the known I2C/SMBus adapters
2493  foreach $try (@pci_adapters) {
2494    $key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid});
2495    if (exists $pci_list{$key}) {
2496        $device = $pci_list{$key};
2497        if ($try->{driver} =~ m/^to-be-/) {
2498          printf "No known driver for device \%s: \%s\n",
2499                 pci_busid($device), $try->{procid};
2500
2501          if ($try->{driver} eq "to-be-tested") {
2502            print "\nWe are currently looking for testers for this adapter!\n".
2503                  "Please check http://www.lm-sensors.org/wiki/Devices\n".
2504                  "and/or contact us if you want to help.\n\n";
2505            print "Continue... ";
2506            <STDIN>;
2507            print "\n";
2508          }
2509        } else {
2510          printf "Using driver `\%s' for device \%s: \%s\n",
2511                 $try->{driver}, pci_busid($device), $try->{procid};
2512          $count++;
2513          load_module($try->{driver});
2514        }
2515
2516        # Delete from detected SMBus device list
2517        delete $smbus{$key};
2518    }
2519  }
2520
2521  # Now see if there are unknown SMBus devices left
2522  foreach $key (keys %smbus) {
2523    $device = $pci_list{$key};
2524    printf "Found unknown SMBus adapter \%04x:\%04x at \%s.\n",
2525           $device->{vendid}, $device->{devid}, pci_busid($device);
2526  }
2527
2528  if (!$count) {
2529    print "Sorry, no supported PCI bus adapters found.\n";
2530  }
2531}
2532
2533# $_[0]: Adapter description as found in /sys/class/i2c-adapter
2534sub find_i2c_adapter_driver
2535{
2536        my $name = shift;
2537        my $entry;
2538
2539        foreach $entry (@i2c_adapter_names) {
2540                return $entry->{driver}
2541                        if $name =~ $entry->{match};
2542        }
2543}
2544
2545#############################
2546# I2C AND SMBUS /DEV ACCESS #
2547#############################
2548
2549# This should really go into a separate module/package.
2550
2551# These are copied from <linux/i2c-dev.h>
2552
2553use constant IOCTL_I2C_SLAVE    => 0x0703;
2554use constant IOCTL_I2C_FUNCS    => 0x0705;
2555use constant IOCTL_I2C_SMBUS    => 0x0720;
2556
2557use constant SMBUS_READ         => 1;
2558use constant SMBUS_WRITE        => 0;
2559
2560use constant SMBUS_QUICK        => 0;
2561use constant SMBUS_BYTE         => 1;
2562use constant SMBUS_BYTE_DATA    => 2;
2563use constant SMBUS_WORD_DATA    => 3;
2564
2565use constant I2C_FUNC_SMBUS_QUICK       => 0x00010000;
2566use constant I2C_FUNC_SMBUS_READ_BYTE   => 0x00020000;
2567
2568# Get the i2c adapter's functionalities
2569# $_[0]: Reference to an opened filehandle
2570# Returns: -1 on failure, functionality bitfield on success.
2571sub i2c_get_funcs
2572{
2573  my $file = shift;
2574  my $funcs = pack("L", 0); # Allocate space
2575
2576  ioctl($file, IOCTL_I2C_FUNCS, $funcs) or return -1;
2577  $funcs = unpack("L", $funcs);
2578
2579  return $funcs;
2580}
2581
2582# Select the device to communicate with through its address.
2583# $_[0]: Reference to an opened filehandle
2584# $_[1]: Address to select
2585# Returns: 0 on failure, 1 on success.
2586sub i2c_set_slave_addr
2587{
2588  my ($file, $addr) = @_;
2589
2590  # Reset register data cache
2591  @i2c_byte_cache = ();
2592
2593  $addr += 0; # Make sure it's a number not a string
2594  ioctl($file, IOCTL_I2C_SLAVE, $addr) or return 0;
2595  return 1;
2596}
2597
2598# i2c_smbus_access is based upon the corresponding C function (see
2599# <linux/i2c-dev.h>). You should not need to call this directly.
2600# Exact calling conventions are intricate; read i2c-dev.c if you really need
2601# to know.
2602# $_[0]: Reference to an opened filehandle
2603# $_[1]: SMBUS_READ for reading, SMBUS_WRITE for writing
2604# $_[2]: Command (usually register number)
2605# $_[3]: Transaction kind (SMBUS_BYTE, SMBUS_BYTE_DATA, etc.)
2606# $_[4]: Reference to an array used for input/output of data
2607# Returns: 0 on failure, 1 on success.
2608# Note that we need to get back to Integer boundaries through the 'x2'
2609# in the pack. This is very compiler-dependent; I wish there was some other
2610# way to do this.
2611sub i2c_smbus_access
2612{
2613  my ($file, $read_write, $command, $size, $data) = @_;
2614  my $data_array = pack("C32", @$data);
2615  my $ioctl_data = pack("C2x2Ip", $read_write, $command, $size, $data_array);
2616  ioctl($file, IOCTL_I2C_SMBUS, $ioctl_data) or return 0;
2617  @{$_[4]} = unpack("C32", $data_array);
2618  return 1;
2619}
2620
2621# $_[0]: Reference to an opened filehandle
2622# Returns: -1 on failure, the read byte on success.
2623sub i2c_smbus_read_byte
2624{
2625  my ($file) = @_;
2626  my @data;
2627  i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, \@data)
2628         or return -1;
2629  return $data[0];
2630}
2631
2632# $_[0]: Reference to an opened filehandle
2633# $_[1]: Command byte (usually register number)
2634# Returns: -1 on failure, the read byte on success.
2635# Read byte data values are cached by default. As we keep reading the
2636# same registers over and over again in the detection functions, and
2637# SMBus can be slow, caching results in a big performance boost.
2638sub i2c_smbus_read_byte_data
2639{
2640  my ($file, $command, $nocache) = @_;
2641  my @data;
2642  if (!$nocache && exists $i2c_byte_cache[$command]) {
2643    return $i2c_byte_cache[$command];
2644  }
2645  i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_BYTE_DATA, \@data)
2646         or return -1;
2647  return ($i2c_byte_cache[$command] = $data[0]);
2648}
2649
2650# $_[0]: Reference to an opened filehandle
2651# $_[1]: Command byte (usually register number)
2652# Returns: -1 on failure, the read word on success.
2653# Use this function with care, some devices don't like word reads,
2654# so you should do as much of the detection as possible using byte reads,
2655# and only start using word reads when there is a good chance that
2656# the detection will succeed.
2657# Note: some devices use the wrong endiannes; use swap_bytes to correct for
2658# this.
2659sub i2c_smbus_read_word_data
2660{
2661  my ($file, $command) = @_;
2662  my @data;
2663  i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_WORD_DATA, \@data)
2664         or return -1;
2665  return $data[0] + 256 * $data[1];
2666}
2667
2668# $_[0]: Reference to an opened filehandle
2669# $_[1]: Address
2670# $_[2]: Functionalities of this i2c adapter
2671# Returns: 1 on successful probing, 0 else.
2672# This function is meant to prevent AT24RF08 corruption and write-only
2673# chips locks. This is done by choosing the best probing method depending
2674# on the address range.
2675sub i2c_probe
2676{
2677  my ($file, $addr, $funcs) = @_;
2678  my $data = [];
2679  if (($addr >= 0x50 && $addr <= 0x5F)
2680   || ($addr >= 0x30 && $addr <= 0x37)) {
2681    # This covers all EEPROMs we know of, including page protection addresses.
2682    # Note that some page protection addresses will not reveal themselves with
2683    # this, because they ack on write only, but this is probably better since
2684    # some EEPROMs write-protect themselves permanently on almost any write to
2685    # their page protection address.
2686    return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE);
2687    return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, $data);
2688  } else {
2689    return 0 unless ($funcs & I2C_FUNC_SMBUS_QUICK);
2690    return i2c_smbus_access($file, SMBUS_WRITE, 0, SMBUS_QUICK, $data);
2691  }
2692}
2693
2694# $_[0]: Reference to an opened file handle
2695# Returns: 1 if the device is safe to access, 0 else.
2696# This function is meant to prevent access to 1-register-only devices,
2697# which are designed to be accessed with SMBus receive byte and SMBus send
2698# byte transactions (i.e. short reads and short writes) and treat SMBus
2699# read byte as a real write followed by a read. The device detection
2700# routines would write random values to the chip with possibly very nasty
2701# results for the hardware. Note that this function won't catch all such
2702# chips, as it assumes that reads and writes relate to the same register,
2703# but that's the best we can do.
2704sub i2c_safety_check
2705{
2706  my ($file) = @_;
2707  my $data;
2708
2709  # First we receive a byte from the chip, and remember it.
2710  $data = i2c_smbus_read_byte($file);
2711  return 1 if ($data < 0);
2712
2713  # We receive a byte again; very likely to be the same for
2714  # 1-register-only devices.
2715  return 1 if (i2c_smbus_read_byte($file) != $data);
2716
2717  # Then we try a standard byte read, with a register offset equal to
2718  # the byte we received; we should receive the same byte value in return.
2719  return 1 if (i2c_smbus_read_byte_data($file, $data) != $data);
2720
2721  # Then we try a standard byte read, with a slightly different register
2722  # offset; we should again receive the same byte value in return.
2723  return 1 if (i2c_smbus_read_byte_data($file, $data ^ 1) != ($data ^ 1));
2724
2725  # Apprently this is a 1-register-only device, restore the original register
2726  # value and leave it alone.
2727  i2c_smbus_read_byte_data($file, $data);
2728  return 0;
2729}
2730
2731####################
2732# ADAPTER SCANNING #
2733####################
2734
2735use vars qw(@chips_detected);
2736
2737# We will build a complicated structure @chips_detected here, being:
2738# A list of
2739#  references to hashes
2740#    with field 'driver', being a string with the driver name for this chip;
2741#    with field 'detected'
2742#      being a reference to a list of
2743#        references to hashes of type 'detect_data';
2744
2745# Type detect_data:
2746# A hash
2747#   with field 'i2c_adap' containing an adapter string as appearing
2748#        in /sys/class/i2c-adapter (if this is an I2C detection)
2749#  with field 'i2c_devnr', contianing the /dev/i2c-* number of this
2750#       adapter (if this is an I2C detection)
2751#  with field 'i2c_driver', containing the driver name for this adapter
2752#       (if this is an I2C detection)
2753#  with field 'i2c_addr', containing the I2C address of the detection;
2754#       (if this is an I2C detection)
2755#  with field 'i2c_sub_addrs', containing a reference to a list of
2756#       other I2C addresses (if this is an I2C detection)
2757#  with field 'isa_addr' containing the ISA address this chip is on
2758#       (if this is an ISA detection)
2759#  with field 'conf', containing the confidence level of this detection
2760#  with field 'chipname', containing the chip name
2761
2762# This adds a detection to the above structure. We do no alias detection
2763# here; so you should do ISA detections *after* all I2C detections.
2764# Not all possibilities of i2c_addr and i2c_sub_addrs are exhausted.
2765# In all normal cases, it should be all right.
2766# $_[0]: chip driver
2767# $_[1]: reference to data hash
2768# Returns: Nothing
2769sub add_i2c_to_chips_detected
2770{
2771  my ($chipdriver, $datahash) = @_;
2772  my ($i, $new_detected_ref, $detected_ref,
2773      $main_entry, $detected_entry, $put_in_detected, @hash_addrs, @entry_addrs);
2774
2775  # First determine where the hash has to be added.
2776  for ($i = 0; $i < @chips_detected; $i++) {
2777    last if ($chips_detected[$i]->{driver} eq $chipdriver);
2778  }
2779  if ($i == @chips_detected) {
2780    push @chips_detected, { driver => $chipdriver,
2781                            detected => [] };
2782  }
2783  $new_detected_ref = $chips_detected[$i]->{detected};
2784
2785  # Find out whether our new entry should go into the detected list
2786  # or not. We compare all i2c addresses; if at least one matches,
2787  # but our confidence value is lower, we assume this is a misdetection,
2788  # in which case we simply discard our new entry.
2789  @hash_addrs = ($datahash->{i2c_addr});
2790  push @hash_addrs, @{$datahash->{i2c_sub_addrs}}
2791       if exists $datahash->{i2c_sub_addrs};
2792  $put_in_detected = 1;
2793  FIND_LOOP:
2794  foreach $main_entry (@chips_detected) {
2795    foreach $detected_entry (@{$main_entry->{detected}}) {
2796      @entry_addrs = ($detected_entry->{i2c_addr});
2797      push @entry_addrs, @{$detected_entry->{i2c_sub_addrs}}
2798               if exists $detected_entry->{i2c_sub_addrs};
2799      if ($detected_entry->{i2c_devnr} == $datahash->{i2c_devnr} and
2800          any_list_match(\@entry_addrs, \@hash_addrs)) {
2801        if ($detected_entry->{conf} >= $datahash->{conf}) {
2802          $put_in_detected = 0;
2803        }
2804        last FIND_LOOP;
2805      }
2806    }
2807  }
2808
2809  if ($put_in_detected) {
2810    # Here, we discard all entries which
2811    # match at least in one main or sub address. This may not be the
2812    # best idea to do, as it may remove detections without replacing
2813    # them with second-best ones. Too bad.
2814    foreach $main_entry (@chips_detected) {
2815      $detected_ref = $main_entry->{detected};
2816      for ($i = @$detected_ref-1; $i >=0; $i--) {
2817        @entry_addrs = ($detected_ref->[$i]->{i2c_addr});
2818        push @entry_addrs, @{$detected_ref->[$i]->{i2c_sub_addrs}}
2819             if exists $detected_ref->[$i]->{i2c_sub_addrs};
2820        if ($detected_ref->[$i]->{i2c_devnr} == $datahash->{i2c_devnr} and
2821            any_list_match(\@entry_addrs, \@hash_addrs)) {
2822          splice @$detected_ref, $i, 1;
2823        }
2824      }
2825    }
2826
2827    # Now add the new entry to detected
2828    push @$new_detected_ref, $datahash;
2829  }
2830}
2831
2832# This adds a detection to the above structure. We also do alias detection
2833# here; so you should do ISA detections *after* all I2C detections.
2834# $_[0]: alias detection function
2835# $_[1]: chip driver
2836# $_[2]: reference to data hash
2837# Returns: 0 if it is not an alias, datahash reference if it is.
2838sub add_isa_to_chips_detected
2839{
2840  my ($alias_detect, $chipdriver, $datahash) = @_;
2841  my ($i, $new_detected_ref, $detected_ref, $main_entry, $isalias);
2842
2843  # First determine where the hash has to be added.
2844  $isalias = 0;
2845  for ($i = 0; $i < @chips_detected; $i++) {
2846    last if ($chips_detected[$i]->{driver} eq $chipdriver);
2847  }
2848  if ($i == @chips_detected) {
2849    push @chips_detected, { driver => $chipdriver,
2850                            detected => [] };
2851  }
2852  $new_detected_ref = $chips_detected[$i]->{detected};
2853
2854  # Now, we are looking for aliases. An alias can only be the same chiptype.
2855  # If it is found in the detected list, we
2856  # still have to check whether another chip has claimed this ISA address.
2857  # So we remove the old entry from the detected list and put it in datahash.
2858  for ($i = 0; $i < @$new_detected_ref; $i++) {
2859    if (exists $new_detected_ref->[$i]->{i2c_addr} and
2860        not exists $new_detected_ref->[$i]->{isa_addr} and
2861        defined $alias_detect and
2862        $new_detected_ref->[$i]->{chipname} eq $datahash->{chipname}) {
2863      open(local *FILE, "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}") or
2864        print("Can't open $dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"),
2865        next;
2866      binmode(FILE);
2867      i2c_set_slave_addr(\*FILE, $new_detected_ref->[$i]->{i2c_addr}) or
2868           print("Can't set I2C address for ",
2869                 "$dev_i2c$new_detected_ref->[$i]->{i2c_devnr}?!?\n"),
2870           next;
2871      if (&$alias_detect ($datahash->{isa_addr}, \*FILE,
2872                          $new_detected_ref->[$i]->{i2c_addr})) {
2873        $new_detected_ref->[$i]->{isa_addr} = $datahash->{isa_addr};
2874        ($datahash) = splice (@$new_detected_ref, $i, 1);
2875        $isalias = 1;
2876        last;
2877      }
2878    }
2879  }
2880
2881  # Find out whether our new entry should go into the detected list
2882  # or not. We only compare main isa_addr here, of course.
2883  foreach $main_entry (@chips_detected) {
2884    $detected_ref = $main_entry->{detected};
2885    for ($i = 0; $i < @{$main_entry->{detected}}; $i++) {
2886      if (exists $detected_ref->[$i]->{isa_addr} and
2887          exists $datahash->{isa_addr} and
2888          $detected_ref->[$i]->{isa_addr} == $datahash->{isa_addr}) {
2889        if ($detected_ref->[$i]->{conf} < $datahash->{conf}) {
2890          splice @$detected_ref, $i, 1;
2891          push @$new_detected_ref, $datahash;
2892        }
2893        if ($isalias) {
2894          return $datahash;
2895        } else {
2896          return 0;
2897        }
2898      }
2899    }
2900  }
2901
2902  # Not found? OK, put it in the detected list
2903  push @$new_detected_ref, $datahash;
2904  if ($isalias) {
2905    return $datahash;
2906  } else {
2907    return 0;
2908  }
2909}
2910
2911# From the list of known I2C/SMBus devices, build a list of I2C addresses
2912# which are worth probing. There's no point in probing an address for which
2913# we don't know a single device, and probing some addresses has caused
2914# random trouble in the past.
2915sub i2c_addresses_to_scan
2916{
2917  my @used;
2918  my @addresses;
2919  my $addr;
2920
2921  foreach my $chip (@chip_ids) {
2922    next unless defined $chip->{i2c_addrs};
2923    next if $chip->{driver} eq 'not-a-sensor';
2924    foreach $addr (@{$chip->{i2c_addrs}}) {
2925      $used[$addr]++;
2926    }
2927  }
2928
2929  for ($addr = 0x03; $addr <= 0x77; $addr++) {
2930    push @addresses, $addr if $used[$addr];
2931  }
2932  return \@addresses;
2933}
2934
2935# $_[0]: The number of the adapter to scan
2936# $_[1]: The name of the adapter, as appearing in /sys/class/i2c-adapter
2937# $_[2]: The driver of the adapter
2938# @_[3]: Addresses not to scan (array reference)
2939sub scan_adapter
2940{
2941  my ($adapter_nr, $adapter_name, $adapter_driver, $not_to_scan) = @_;
2942  my ($funcs, $chip, $addr, $conf, @chips, $new_hash, $other_addr);
2943
2944  # As we modify it, we need a copy
2945  my @not_to_scan = @$not_to_scan;
2946
2947  open(local *FILE, "$dev_i2c$adapter_nr") or
2948    (print "Can't open $dev_i2c$adapter_nr\n"), return;
2949  binmode(FILE);
2950
2951  # Can we probe this adapter?
2952  $funcs = i2c_get_funcs(\*FILE);
2953  if ($funcs < 0) {
2954    print "Adapter failed to provide its functionalities, skipping.\n";
2955    return;
2956  }
2957  if (!($funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) {
2958    print "Adapter cannot be probed, skipping.\n";
2959    return;
2960  }
2961  if (~$funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE)) {
2962    print "Adapter doesn't support all probing functions.\n",
2963          "Some addresses won't be probed.\n";
2964  }
2965
2966  # Now scan each address in turn
2967  foreach $addr (@{$i2c_addresses_to_scan}) {
2968    # As the not_to_scan list is sorted, we can check it fast
2969    shift @not_to_scan # User skipped an address which we didn't intend to probe anyway
2970      while (@not_to_scan and $not_to_scan[0] < $addr);
2971    if (@not_to_scan and $not_to_scan[0] == $addr) {
2972      shift @not_to_scan;
2973      next;
2974    }
2975
2976    if (!i2c_set_slave_addr(\*FILE, $addr)) {
2977      # If the address is busy, we can normally find out which driver
2978      # requested it (if the kernel is recent enough, at least 2.6.16
2979      # and later are known to work), and we assume it is the right one.
2980      my ($device, $driver);
2981
2982      $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x",
2983                             $adapter_nr, $addr);
2984      $driver = sysfs_device_driver($device);
2985
2986      if (defined($driver)) {
2987        $new_hash = {
2988          conf => 6, # Arbitrary confidence
2989          i2c_addr => $addr,
2990          chipname => sysfs_device_attribute($device, "name") || "unknown",
2991          i2c_adap => $adapter_name,
2992          i2c_driver => $adapter_driver,
2993          i2c_devnr => $adapter_nr,
2994        };
2995
2996        printf "Client found at address 0x\%02x\n", $addr;
2997        printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n",
2998               $driver, $new_hash->{chipname};
2999
3000        # Only add it to the list if this is something we would have
3001        # detected, else we end up with random i2c chip drivers listed
3002        # (for example media/video drivers.)
3003        if (exists $modules_supported{$driver}) {
3004          add_i2c_to_chips_detected($driver, $new_hash);
3005        } else {
3006          print "    (note: this is probably NOT a sensor chip!)\n";
3007        }
3008      } else {
3009        printf("Client at address 0x%02x can not be probed - ".
3010               "unload all client drivers first!\n", $addr);
3011      }
3012      next;
3013    }
3014
3015    next unless i2c_probe(\*FILE, $addr, $funcs);
3016    printf "Client found at address 0x%02x\n", $addr;
3017    if (!i2c_safety_check(\*FILE)) {
3018      print "Seems to be a 1-register-only device, skipping.\n";
3019      next;
3020    }
3021
3022    $| = 1;
3023    foreach $chip (@chip_ids) {
3024      if (exists $chip->{i2c_addrs} and contains($addr, @{$chip->{i2c_addrs}})) {
3025        printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name}));
3026        if (($conf, @chips) = &{$chip->{i2c_detect}} (\*FILE, $addr)) {
3027          if ($chip->{driver} eq "not-a-sensor") {
3028            print "Yes\n",
3029                  "    (confidence $conf, not a hardware monitoring chip";
3030          } else {
3031            print "Success!\n",
3032                  "    (confidence $conf, driver `$chip->{driver}'";
3033          }
3034          if (@chips) {
3035            print ", other addresses:";
3036            @chips = sort @chips;
3037            foreach $other_addr (@chips) {
3038              printf(" 0x%02x", $other_addr);
3039            }
3040          }
3041          printf ")\n";
3042
3043          next if ($chip->{driver} eq "not-a-sensor"
3044                || $chip->{driver} eq "use-isa-instead");
3045
3046          $new_hash = { conf => $conf,
3047                        i2c_addr => $addr,
3048                        chipname => $chip->{name},
3049                        i2c_adap => $adapter_name,
3050                        i2c_driver => $adapter_driver,
3051                        i2c_devnr => $adapter_nr,
3052                      };
3053          if (@chips) {
3054            my @chips_copy = @chips;
3055            $new_hash->{i2c_sub_addrs} = \@chips_copy;
3056          }
3057          add_i2c_to_chips_detected($chip->{driver}, $new_hash);
3058        } else {
3059          print "No\n";
3060        }
3061      }
3062    }
3063    $| = 0;
3064  }
3065}
3066
3067sub scan_isa_bus
3068{
3069  my ($chip, $addr, $conf);
3070  $| = 1;
3071  foreach $chip (@chip_ids) {
3072    next if not exists $chip->{isa_addrs} or not exists $chip->{isa_detect};
3073    foreach $addr (@{$chip->{isa_addrs}}) {
3074      printf("\%-60s", sprintf("Probing for `\%s'\ at 0x\%x... ", $chip->{name},
3075                               $addr));
3076      $conf = &{$chip->{isa_detect}} ($addr);
3077      print("No\n"), next if not defined $conf;
3078      print "Success!\n";
3079      printf "    (confidence %d, driver `%s')\n", $conf, $chip->{driver};
3080      my $new_hash = { conf => $conf,
3081                       isa_addr => $addr,
3082                       chipname => $chip->{name}
3083                     };
3084      $new_hash = add_isa_to_chips_detected($chip->{alias_detect}, $chip->{driver},
3085                                            $new_hash);
3086      if ($new_hash) {
3087        printf "    Alias of the chip on I2C bus `%s', address 0x%02x\n",
3088                        $new_hash->{i2c_adap}, $new_hash->{i2c_addr};
3089      }
3090    }
3091  }
3092  $| = 0;
3093}
3094
3095use vars qw(%superio);
3096
3097# The following are taken from the PNP ISA spec (so it's supposed
3098# to be common to all Super I/O chips):
3099#  devidreg: The device ID register(s)
3100#  logdevreg: The logical device register
3101#  actreg: The activation register within the logical device
3102#  actmask: The activation bit in the activation register
3103#  basereg: The I/O base register within the logical device
3104%superio = (
3105  devidreg => 0x20,
3106  logdevreg => 0x07,
3107  actreg => 0x30,
3108  actmask => 0x01,
3109  basereg => 0x60,
3110);
3111
3112sub exit_superio
3113{
3114  my ($addrreg, $datareg) = @_;
3115
3116  # Some chips (SMSC, Winbond) want this
3117  outb($addrreg, 0xaa);
3118
3119  # Return to "Wait For Key" state (PNP-ISA spec)
3120  outb($addrreg, 0x02);
3121  outb($datareg, 0x02);
3122}
3123
3124# Guess if an unknown Super-I/O chip has sensors
3125sub guess_superio_ld
3126{
3127  my ($addrreg, $datareg, $typical_addr) = @_;
3128  my ($oldldn, $ldn, $addr);
3129
3130  # Save logical device number
3131  outb($addrreg, $superio{logdevreg});
3132  $oldldn = inb($datareg);
3133
3134  for ($ldn = 0; $ldn < 16; $ldn++) {
3135    # Select logical device
3136    outb($addrreg, $superio{logdevreg});
3137    outb($datareg, $ldn);
3138
3139    # Read base I/O address
3140    outb($addrreg, $superio{basereg});
3141    $addr = inb($datareg) << 8;
3142    outb($addrreg, $superio{basereg} + 1);
3143    $addr |= inb($datareg);
3144    next unless ($addr & 0xfff8) == $typical_addr;
3145
3146    printf "    (logical device \%X has address 0x\%x, could be sensors)\n",
3147           $ldn, $addr;
3148    last;
3149  }
3150
3151  # Be nice, restore original logical device
3152  outb($addrreg, $superio{logdevreg});
3153  outb($datareg, $oldldn);
3154}
3155
3156sub probe_superio
3157{
3158  my ($addrreg, $datareg, $chip) = @_;
3159  my ($val, $addr);
3160
3161  printf "\%-60s",  "Found `$chip->{name}'";
3162
3163  # Does it have hardware monitoring capabilities?
3164  if (!exists $chip->{driver}) {
3165    print "\n    (no information available)\n";
3166    return;
3167  }
3168  if ($chip->{driver} eq "not-a-sensor") {
3169    print "\n    (no hardware monitoring capabilities)\n";
3170    return;
3171  }
3172  if ($chip->{driver} eq "via-smbus-only") {
3173    print "\n    (hardware monitoring capabilities accessible via SMBus only)\n";
3174    return;
3175  }
3176
3177  # Switch to the sensor logical device
3178  outb($addrreg, $superio{logdevreg});
3179  outb($datareg, $chip->{logdev});
3180
3181  # Check the activation register
3182  outb($addrreg, $superio{actreg});
3183  $val = inb($datareg);
3184  if (!($val & $superio{actmask})) {
3185    print "\n    (but not activated)\n";
3186    return;
3187  }
3188
3189  # Get the IO base register
3190  outb($addrreg, $superio{basereg});
3191  $addr = inb($datareg);
3192  outb($addrreg, $superio{basereg} + 1);
3193  $addr = ($addr << 8) | inb($datareg);
3194  if ($addr == 0) {
3195    print "\n    (but no address specified)\n";
3196    return;
3197  }
3198  print "Success!\n";
3199  printf "    (address 0x\%x, driver `%s')\n", $addr, $chip->{driver};
3200  my $new_hash = { conf => 9,
3201                   isa_addr => $addr,
3202                   chipname => $chip->{name}
3203                 };
3204  add_isa_to_chips_detected($chip->{alias_detect}, $chip->{driver},
3205                                        $new_hash);
3206}
3207
3208# Detection routine for non-standard SMSC Super I/O chips
3209# $_[0]: Super I/O LPC config/index port
3210# $_[1]: Super I/O LPC data port
3211# $_[2]: Reference to array of non-standard chips
3212# Return values: 1 if non-standard chip found, 0 otherwise
3213sub smsc_ns_detect_superio
3214{
3215    my ($addrreg, $datareg, $ns_chips) = @_;
3216    my ($val, $chip);
3217
3218    # read alternate device ID register
3219    outb($addrreg, 0x0d);
3220    $val = inb($datareg);
3221    if ($val == 0x00 || $val == 0xff) {
3222        return 0;
3223    }
3224
3225    print "Yes\n";
3226
3227    foreach $chip (@{$ns_chips}) {
3228        if ($chip->{devid} == $val) {
3229            probe_superio($addrreg, $datareg, $chip);
3230            return 1;
3231        }
3232    }
3233
3234    printf("Found unknown non-standard chip with ID 0x%02x\n", $val);
3235    return 1;
3236}
3237
3238sub scan_superio
3239{
3240  my ($addrreg, $datareg) = @_;
3241  my ($val, $found);
3242
3243  printf("Probing for Super-I/O at 0x\%x/0x\%x\n", $addrreg, $datareg);
3244
3245  $| = 1;
3246# reset state to avoid false positives
3247  exit_superio($addrreg, $datareg);
3248  FAMILY:
3249  foreach my $family (@superio_ids) {
3250    printf("\%-60s", "Trying family `$family->{family}'... ");
3251# write the password
3252    foreach $val (@{$family->{enter}->{$addrreg}}) {
3253      outb($addrreg, $val);
3254    }
3255# call the non-standard detection routine first if it exists
3256    if (defined($family->{ns_detect}) &&
3257        &{$family->{ns_detect}}($addrreg, $datareg, $family->{ns_chips})) {
3258      exit_superio($addrreg, $datareg);
3259      last FAMILY;
3260    }
3261# did it work?
3262    outb($addrreg, $superio{devidreg});
3263    $val = inb($datareg);
3264    outb($addrreg, $superio{devidreg} + 1);
3265    $val = ($val << 8) | inb($datareg);
3266    if ($val == 0x0000 || $val == 0xffff) {
3267      print "No\n";
3268      next FAMILY;
3269    }
3270    print "Yes\n";
3271
3272    $found = 0;
3273    foreach my $chip (@{$family->{chips}}) {
3274      if (($chip->{devid} > 0xff && ($val & ($chip->{devid_mask} || 0xffff)) == $chip->{devid})
3275       || ($chip->{devid} <= 0xff && ($val >> 8) == $chip->{devid})) {
3276        probe_superio($addrreg, $datareg, $chip);
3277        $found++;
3278      }
3279    }
3280
3281    if (!$found) {
3282      printf("Found unknown chip with ID 0x%04x\n", $val);
3283      # Guess if a logical device could correspond to sensors
3284      guess_superio_ld($addrreg, $datareg, $family->{guess})
3285        if defined $family->{guess};
3286    }
3287
3288    exit_superio($addrreg, $datareg);
3289    last FAMILY;
3290  }
3291  $| = 0;
3292}
3293
3294
3295sub scan_cpu
3296{
3297  my $entry = shift;
3298  my $confidence;
3299
3300  printf("\%-60s", "$entry->{name}... ");
3301  if (defined ($confidence = $entry->{detect}())) {
3302    print "Success!\n";
3303    printf "    (driver `%s')\n", $entry->{driver};
3304    my $new_hash = {
3305      conf => $confidence,
3306      chipname => $entry->{name},
3307    };
3308    add_isa_to_chips_detected(undef, $entry->{driver}, $new_hash);
3309  } else {
3310    print "No\n";
3311  }
3312}
3313
3314
3315##################
3316# CHIP DETECTION #
3317##################
3318
3319# This routine allows you to dynamically update the chip detection list.
3320# The most common use is to allow for different chip to driver mappings
3321# based on different linux kernels
3322sub chip_special_cases
3323{
3324        # Some chip to driver mappings depend on the environment
3325        foreach my $chip (@chip_ids) {
3326                if (ref($chip->{driver}) eq 'CODE') {
3327                        $chip->{driver} = $chip->{driver}->();
3328                }
3329        }
3330}
3331
3332# Each function returns a confidence value. The higher this value, the more
3333# sure we are about this chip. This may help overrule false positives,
3334# although we also attempt to prevent false positives in the first place.
3335
3336# Each function returns a list. The first element is the confidence value;
3337# Each element after it is an SMBus address. In this way, we can detect
3338# chips with several SMBus addresses. The SMBus address for which the
3339# function was called is never returned.
3340
3341# All I2C detection functions below take at least 2 parameters:
3342# $_[0]: Reference to the file descriptor to access the chip
3343# $_[1]: Address
3344# Some of these functions which can detect more than one type of device,
3345# take a third parameter:
3346# $_[2]: Chip to detect
3347
3348# Registers used: 0x58
3349sub mtp008_detect
3350{
3351  my ($file, $addr) = @_;
3352  return if i2c_smbus_read_byte_data($file, 0x58) != 0xac;
3353  return 3;
3354}
3355
3356# Chip to detect: 0 = LM78, 2 = LM79
3357# Registers used:
3358#   0x40: Configuration
3359#   0x48: Full I2C Address
3360#   0x49: Device ID
3361sub lm78_detect
3362{
3363  my ($file, $addr, $chip) = @_;
3364  my $reg;
3365  return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
3366  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
3367  $reg = i2c_smbus_read_byte_data($file, 0x49);
3368  return unless ($chip == 0 and ($reg == 0x00 or $reg == 0x20 or $reg == 0x40)) or
3369                    ($chip == 2 and ($reg & 0xfe) == 0xc0);
3370
3371  # Explicitly prevent misdetection of Winbond chips
3372  $reg = i2c_smbus_read_byte_data($file, 0x4f);
3373  return if $reg == 0xa3 || $reg == 0x5c;
3374
3375  return 6;
3376}
3377
3378# Chip to detect: 0 = LM75, 1 = DS75
3379# Registers used:
3380#   0x00: Temperature
3381#   0x01: Configuration
3382#   0x02: Hysteresis
3383#   0x03: Overtemperature Shutdown
3384#   0x04-0x07: No registers
3385# The first detection step is based on the fact that the LM75 has only
3386# four registers, and cycles addresses over 8-byte boundaries. We use the
3387# 0x04-0x07 addresses (unused) to improve the reliability. These are not
3388# real registers and will always return the last returned value. This isn't
3389# documented.
3390# Note that register 0x00 may change, so we can't use the modulo trick on it.
3391# The DS75 is a bit different, it doesn't cycle over 8-byte boundaries, and
3392# all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for
3393# the LM75.
3394# Not all devices enjoy SMBus read word transactions, so we use read byte
3395# transactions even for the 16-bit registers. The low bits aren't very
3396# useful for detection anyway.
3397sub lm75_detect
3398{
3399  my ($file, $addr, $chip) = @_;
3400  my $i;
3401  my $cur = i2c_smbus_read_byte_data($file, 0x00);
3402  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3403
3404  my $hyst = i2c_smbus_read_byte_data($file, 0x02, NO_CACHE);
3405  my $maxreg = $chip == 1 ? 0x0f : 0x07;
3406  for $i (0x04 .. $maxreg) {
3407    return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $hyst;
3408  }
3409
3410  my $os = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3411  for $i (0x04 .. $maxreg) {
3412    return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $os;
3413  }
3414
3415  if ($chip == 0) {
3416    for ($i = 8; $i <= 248; $i += 40) {
3417      return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf
3418             or i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst
3419             or i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
3420    }
3421  }
3422
3423  # All registers hold the same value, obviously a misdetection
3424  return if $conf == $cur and $cur == $hyst and $cur == $os;
3425
3426  # Unused bits
3427  return if $chip == 0 and ($conf & 0xe0);
3428  return if $chip == 1 and ($conf & 0x80);
3429
3430  # Most probable value ranges
3431  return 6 if $cur <= 100 and ($hyst >= 10 && $hyst <= 125)
3432    and ($os >= 20 && $os <= 127) and $hyst < $os;
3433  return 3;
3434}
3435
3436# Registers used:
3437#   0x00: Temperature
3438#   0x01: Configuration
3439#   0x02: Hysteresis
3440#   0x03: Overtemperature Shutdown
3441#   0x04: Low limit
3442#   0x05: High limit
3443#   0x06-0x07: No registers
3444# The first detection step is based on the fact that the LM77 has only
3445# six registers, and cycles addresses over 8-byte boundaries. We use the
3446# 0x06-0x07 addresses (unused) to improve the reliability. These are not
3447# real registers and will always return the last returned value. This isn't
3448# documented.
3449# Note that register 0x00 may change, so we can't use the modulo trick on it.
3450# Not all devices enjoy SMBus read word transactions, so we use read byte
3451# transactions even for the 16-bit registers at first. We only use read word
3452# transactions in the end when we are already almost certain that we have an
3453# LM77 chip.
3454sub lm77_detect
3455{
3456  my ($file, $addr) = @_;
3457  my $i;
3458  my $cur = i2c_smbus_read_byte_data($file, 0x00);
3459  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3460  my $hyst = i2c_smbus_read_byte_data($file, 0x02);
3461  my $os = i2c_smbus_read_byte_data($file, 0x03);
3462
3463  my $low = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
3464  return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $low;
3465  return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $low;
3466
3467  my $high = i2c_smbus_read_byte_data($file, 0x05, NO_CACHE);
3468  return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $high;
3469  return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $high;
3470
3471  for ($i = 8; $i <= 248; $i += 40) {
3472    return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3473    return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
3474    return if i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
3475    return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
3476    return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
3477  }
3478
3479  # All registers hold the same value, obviously a misdetection
3480  return if $conf == $cur and $cur == $hyst
3481    and $cur == $os and $cur == $low and $cur == $high;
3482
3483  # Unused bits
3484  return if ($conf & 0xe0)
3485    or (($cur >> 4) != 0 && ($cur >> 4) != 0xf)
3486    or (($hyst >> 4) != 0 && ($hyst >> 4) != 0xf)
3487    or (($os >> 4) != 0 && ($os >> 4) != 0xf)
3488    or (($low >> 4) != 0 && ($low >> 4) != 0xf)
3489    or (($high >> 4) != 0 && ($high >> 4) != 0xf);
3490
3491  # Make sure the chip supports SMBus read word transactions
3492  $cur = i2c_smbus_read_word_data($file, 0x00);
3493  return if $cur < 0;
3494  $hyst = i2c_smbus_read_word_data($file, 0x02);
3495  return if $hyst < 0;
3496  $os = i2c_smbus_read_word_data($file, 0x03);
3497  return if $os < 0;
3498  $low = i2c_smbus_read_word_data($file, 0x04);
3499  return if $low < 0;
3500  $high = i2c_smbus_read_word_data($file, 0x05);
3501  return if $high < 0;
3502
3503  $cur /= 16;
3504  $hyst /= 16;
3505  $os /= 16;
3506  $high /= 16;
3507  $low /= 16;
3508
3509  # Most probable value ranges
3510  return 6 if $cur <= 100 and $hyst <= 40
3511    and ($os >= 20 && $os <= 127) and ($high >= 20 && $high <= 127);
3512  return 3;
3513}
3514
3515# Chip to detect: 0 = LM92, 1 = LM76, 2 = MAX6633/MAX6634/MAX6635
3516# Registers used:
3517#   0x01: Configuration (National Semiconductor only)
3518#   0x02: Hysteresis
3519#   0x03: Critical Temp
3520#   0x04: Low Limit
3521#   0x05: High Limit
3522#   0x07: Manufacturer ID (LM92 only)
3523# One detection step is based on the fact that the LM92 and clones have a
3524# limited number of registers, which cycle modulo 16 address values.
3525# Note that register 0x00 may change, so we can't use the modulo trick on it.
3526# Not all devices enjoy SMBus read word transactions, so we use read byte
3527# transactions even for the 16-bit registers at first. We only use read
3528# word transactions in the end when we are already almost certain that we
3529# have an LM92 chip or compatible.
3530sub lm92_detect
3531{
3532  my ($file, $addr, $chip) = @_;
3533
3534  my $conf = i2c_smbus_read_byte_data($file, 0x01);
3535  my $hyst = i2c_smbus_read_byte_data($file, 0x02);
3536  my $crit = i2c_smbus_read_byte_data($file, 0x03);
3537  my $low = i2c_smbus_read_byte_data($file, 0x04);
3538  my $high = i2c_smbus_read_byte_data($file, 0x05);
3539
3540  return if $conf == 0 and $hyst == 0 and $crit == 0
3541        and $low == 0 and $high == 0;
3542
3543  # Unused bits
3544  return if ($chip == 0 || $chip == 1)
3545        and ($conf & 0xE0);
3546
3547  for (my $i = 0; $i <= 240; $i += 16) {
3548    return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3549    return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
3550    return if i2c_smbus_read_byte_data($file, $i + 0x03) != $crit;
3551    return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
3552    return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
3553  }
3554
3555  return if $chip == 0
3556        and i2c_smbus_read_word_data($file, 0x07) != 0x0180;
3557
3558  # Make sure the chip supports SMBus read word transactions
3559  $hyst = i2c_smbus_read_word_data($file, 0x02);
3560  return if $hyst < 0;
3561  $crit = i2c_smbus_read_word_data($file, 0x03);
3562  return if $crit < 0;
3563  $low = i2c_smbus_read_word_data($file, 0x04);
3564  return if $low < 0;
3565  $high = i2c_smbus_read_word_data($file, 0x05);
3566  return if $high < 0;
3567
3568  foreach my $temp ($hyst, $crit, $low, $high) {
3569    return if $chip == 2 and ($temp & 0x7F00);
3570    return if $chip != 2 and ($temp & 0x0700);
3571  }
3572
3573  return 4 if $chip == 0;
3574  return 2;
3575}
3576
3577# Registers used:
3578#   0xAA: Temperature
3579#   0xA1: High limit
3580#   0xA2: Low limit
3581#   0xA8: Counter
3582#   0xA9: Slope
3583#   0xAC: Configuration
3584# Detection is weak. We check if bit 4 (NVB) is clear, because it is
3585# unlikely to be set (would mean that EEPROM is currently being accessed).
3586# We also check the value of the counter and slope registers, the datasheet
3587# doesn't mention the possible values but the conversion formula together
3588# with experimental evidence suggest possible sanity checks.
3589# Not all devices enjoy SMBus read word transactions, so we do as much as
3590# possible with read byte transactions first, and only use read word
3591# transactions second.
3592sub ds1621_detect
3593{
3594  my ($file, $addr) = @_;
3595
3596  my $conf = i2c_smbus_read_byte_data($file, 0xAC);
3597  return if ($conf & 0x10);
3598
3599  my $counter = i2c_smbus_read_byte_data($file, 0xA8);
3600  my $slope = i2c_smbus_read_byte_data($file, 0xA9);
3601  return if ($slope != 0x10 || $counter > $slope);
3602
3603  my $temp = i2c_smbus_read_word_data($file, 0xAA);
3604  return if $temp < 0 || ($temp & 0x0f00);
3605  # On the DS1631, the following two checks are too strict in theory,
3606  # but in practice I very much doubt that anyone will set temperature
3607  # limits not a multiple of 0.5 degrees C.
3608  my $high = i2c_smbus_read_word_data($file, 0xA1);
3609  return if $high < 0 || ($high & 0x7f00);
3610  my $low = i2c_smbus_read_word_data($file, 0xA2);
3611  return if $low < 0 || ($low & 0x7f00);
3612
3613  return if ($temp == 0 && $high == 0 && $low == 0 && $conf == 0);
3614
3615  return 3;
3616}
3617
3618# Registers used:
3619#   0x00: Configuration register
3620#   0x02: Interrupt state register
3621#   0x2a-0x3d: Limits registers
3622# This one is easily misdetected since it doesn't provide identification
3623# registers. So we have to use some tricks:
3624#   - 6-bit addressing, so limits readings modulo 0x40 should be unchanged
3625#   - positive temperature limits
3626#   - limits order correctness
3627# Hopefully this should limit the rate of false positives, without increasing
3628# the rate of false negatives.
3629# Thanks to Lennard Klein for testing on a non-LM80 chip, which was
3630# previously misdetected, and isn't anymore. For reference, it scored
3631# a final confidence of 0, and changing from strict limit comparisons
3632# to loose comparisons did not change the score.
3633sub lm80_detect
3634{
3635  my ($file, $addr) = @_;
3636  my ($i, $reg);
3637
3638  return if (i2c_smbus_read_byte_data($file, 0x00) & 0x80) != 0;
3639  return if (i2c_smbus_read_byte_data($file, 0x02) & 0xc0) != 0;
3640
3641  for ($i = 0x2a; $i <= 0x3d; $i++) {
3642    $reg = i2c_smbus_read_byte_data($file, $i);
3643    return if i2c_smbus_read_byte_data($file, $i+0x40) != $reg;
3644    return if i2c_smbus_read_byte_data($file, $i+0x80) != $reg;
3645    return if i2c_smbus_read_byte_data($file, $i+0xc0) != $reg;
3646  }
3647
3648  # Refine a bit by checking wether limits are in the correct order
3649  # (min<max for voltages, hyst<max for temperature). Since it is still
3650  # possible that the chip is an LM80 with limits not properly set,
3651  # a few "errors" are tolerated.
3652  my $confidence = 0;
3653  for ($i = 0x2a; $i <= 0x3a; $i++) {
3654    $confidence++
3655      if i2c_smbus_read_byte_data($file, $i) < i2c_smbus_read_byte_data($file, $i+1);
3656  }
3657  # hot temp<OS temp
3658  $confidence++
3659    if i2c_smbus_read_byte_data($file, 0x38) < i2c_smbus_read_byte_data($file, 0x3a);
3660
3661  # Negative temperature limits are unlikely.
3662  for ($i = 0x3a; $i <= 0x3d; $i++) {
3663    $confidence++ if (i2c_smbus_read_byte_data($file, $i) & 0x80) == 0;
3664  }
3665
3666  # $confidence is between 0 and 14
3667  $confidence = ($confidence >> 1) - 4;
3668  # $confidence is now between -4 and 3
3669
3670  return unless $confidence > 0;
3671
3672  return $confidence;
3673}
3674
3675# Registers used:
3676#   0x02: Status 1
3677#   0x03: Configuration
3678#   0x04: Company ID of LM84
3679#   0x35: Status 2
3680#   0xfe: Manufacturer ID
3681#   0xff: Chip ID / die revision
3682# We can use the LM84 Company ID register because the LM83 and the LM82 are
3683# compatible with the LM84.
3684# The LM83 chip ID is missing from the datasheet and was contributed by
3685# Magnus Forsstrom: 0x03.
3686# At least some revisions of the LM82 seem to be repackaged LM83, so they
3687# have the same chip ID, and temp2/temp4 will be stuck in "OPEN" state.
3688# For this reason, we don't even try to distinguish between both chips.
3689# Thanks to Ben Gardner for reporting.
3690sub lm83_detect
3691{
3692  my ($file, $addr) = @_;
3693  return if i2c_smbus_read_byte_data($file, 0xfe) != 0x01;
3694  my $chipid = i2c_smbus_read_byte_data($file, 0xff);
3695  return if $chipid != 0x01 && $chipid != 0x03;
3696
3697  my $confidence = 4;
3698  $confidence++
3699    if (i2c_smbus_read_byte_data($file, 0x02) & 0xa8) == 0x00;
3700  $confidence++
3701    if (i2c_smbus_read_byte_data($file, 0x03) & 0x41) == 0x00;
3702  $confidence++
3703    if i2c_smbus_read_byte_data($file, 0x04) == 0x00;
3704  $confidence++
3705    if (i2c_smbus_read_byte_data($file, 0x35) & 0x48) == 0x00;
3706
3707  return $confidence;
3708}
3709
3710# Chip to detect: 0 = LM90, 1 = LM89/LM99, 2 = LM86, 3 = ADM1032,
3711#                 4 = MAX6654/MAX6690, 5 = ADT7461,
3712#                 6 = MAX6646/MAX6647/MAX6648/MAX6649/MAX6692,
3713#                 7 = MAX6680/MAX6681, 8 = W83L771W/G, 9 = TMP401, 10 = TMP411
3714# Registers used:
3715#   0x03: Configuration
3716#   0x04: Conversion rate
3717#   0xfe: Manufacturer ID
3718#   0xff: Chip ID / die revision
3719sub lm90_detect
3720{
3721  my ($file, $addr, $chip) = @_;
3722  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3723  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3724  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3725  my $rate = i2c_smbus_read_byte_data($file, 0x04);
3726
3727  if ($chip == 0) {
3728    return if ($conf & 0x2a) != 0;
3729    return if $rate > 0x09;
3730    return if $mid != 0x01;     # National Semiconductor
3731    return 8 if $cid == 0x21;   # LM90
3732    return 6 if ($cid & 0x0f) == 0x20;
3733  }
3734  if ($chip == 1) {
3735    return if ($conf & 0x2a) != 0;
3736    return if $rate > 0x09;
3737    return if $mid != 0x01;     # National Semiconductor
3738    return 8 if $addr == 0x4c and $cid == 0x31; # LM89/LM99
3739    return 8 if $addr == 0x4d and $cid == 0x34; # LM89-1/LM99-1
3740    return 6 if ($cid & 0x0f) == 0x30;
3741  }
3742  if ($chip == 2) {
3743    return if ($conf & 0x2a) != 0;
3744    return if $rate > 0x09;
3745    return if $mid != 0x01;     # National Semiconductor
3746    return 8 if $cid == 0x11;   # LM86
3747    return 6 if ($cid & 0xf0) == 0x10;
3748  }
3749  if ($chip == 3) {
3750    return if ($conf & 0x3f) != 0;
3751    return if $rate > 0x0a;
3752    return if $mid != 0x41;     # Analog Devices
3753    return 6 if ($cid & 0xf0) == 0x40; # ADM1032
3754  }
3755  if ($chip == 4) {
3756    return if ($conf & 0x07) != 0;
3757    return if $rate > 0x07;
3758    return if $mid != 0x4d;     # Maxim
3759    return if $cid != 0x08;     # MAX6654/MAX6690
3760    return 8;
3761  }
3762  if ($chip == 5) {
3763    return if ($conf & 0x1b) != 0;
3764    return if $rate > 0x0a;
3765    return if $mid != 0x41;     # Analog Devices
3766    return 8 if $cid == 0x51;   # ADT7461
3767  }
3768  if ($chip == 6) {
3769    return if ($conf & 0x3f) != 0;
3770    return if $rate > 0x07;
3771    return if $mid != 0x4d;     # Maxim
3772    return if $cid != 0x59;     # MAX6648/MAX6692
3773    return 8;
3774  }
3775  if ($chip == 7) {
3776    return if ($conf & 0x03) != 0;
3777    return if $rate > 0x07;
3778    return if $mid != 0x4d;     # Maxim
3779    return if $cid != 0x01;     # MAX6680/MAX6681
3780    return 8;
3781  }
3782  if ($chip == 8) {
3783    return if ($conf & 0x2a) != 0;
3784    return if $rate > 0x09;
3785    return if $mid != 0x5c;     # Winbond
3786    return if $cid != 0x00;     # W83L771W/G
3787    return 6;
3788  }
3789  if ($chip == 9) {
3790    return if ($conf & 0x1B) != 0;
3791    return if $rate > 0x0F;
3792    return if $mid != 0x55;     # Texas Instruments
3793    return if $cid != 0x11;     # TMP401
3794    return 8;
3795  }
3796  if ($chip == 10) {
3797    return if ($conf & 0x1B) != 0;
3798    return if $rate > 0x0F;
3799    return if $mid != 0x55;     # Texas Instruments
3800    return 6 if ($addr == 0x4c && $cid == 0x12); # TMP411A
3801    return 6 if ($addr == 0x4d && $cid == 0x13); # TMP411B
3802    return 6 if ($addr == 0x4e && $cid == 0x10); # TMP411C
3803    return;
3804  }
3805  return;
3806}
3807
3808# Registers used:
3809#   0x03: Configuration (no low nibble)
3810#   0x04: Conversion rate
3811#   0xfe: Manufacturer ID
3812#   0xff: no register
3813sub max6657_detect
3814{
3815  my ($file, $addr) = @_;
3816  my $mid = i2c_smbus_read_byte_data($file, 0xfe, NO_CACHE);
3817  my $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
3818  my $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3819
3820  return if $mid != 0x4d;     # Maxim
3821  return if ($conf & 0x1f) != 0x0d; # No low nibble,
3822                                    # returns previous low nibble
3823  return if $cid != 0x4d;     # No register, returns previous value
3824
3825  my $rate = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
3826  return if $rate > 0x09;
3827
3828  $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
3829  $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3830  return if ($conf & 0x0f) != $rate; # No low nibble,
3831                                     # returns previous low nibble
3832  return if $cid != $rate;    # No register, returns previous value
3833
3834  return 5;
3835}
3836
3837# Registers used:
3838#   0x03: Configuration
3839#   0xfe: Manufacturer ID
3840#   0xff: Revision ID
3841sub lm95231_detect
3842{
3843  my ($file, $addr) = @_;
3844  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3845  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3846  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3847
3848  return if ($conf & 0x89) != 0;
3849  return if $mid != 0x01;     # National Semiconductor
3850  return if $cid != 0xa1;     # LM95231
3851
3852  return 6;
3853}
3854
3855# Registers used:
3856#   0x03: Configuration 1
3857#   0x24: Configuration 2
3858#   0x3d: Manufacturer ID
3859#   0x3e: Device ID
3860sub adt7481_detect
3861{
3862  my ($file, $addr) = @_;
3863  my $mid = i2c_smbus_read_byte_data($file, 0x3d);
3864  my $cid = i2c_smbus_read_byte_data($file, 0x3e);
3865  my $conf1 = i2c_smbus_read_byte_data($file, 0x03);
3866  my $conf2 = i2c_smbus_read_byte_data($file, 0x24);
3867
3868  return if ($conf1 & 0x10) != 0;
3869  return if ($conf2 & 0x7f) != 0;
3870  return if $mid != 0x41;     # Analog Devices
3871  return if $cid != 0x81;     # ADT7481
3872
3873  return 6;
3874}
3875
3876# Chip to detect: 1 = LM63, 2 = F75363SG, 3 = LM64
3877# Registers used:
3878#   0xfe: Manufacturer ID
3879#   0xff: Chip ID / die revision
3880#   0x03: Configuration (two or three unused bits)
3881#   0x16: Alert mask (two or three unused bits)
3882sub lm63_detect
3883{
3884  my ($file, $addr, $chip) = @_;
3885
3886  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3887  my $cid = i2c_smbus_read_byte_data($file, 0xff);
3888  my $conf = i2c_smbus_read_byte_data($file, 0x03);
3889  my $mask = i2c_smbus_read_byte_data($file, 0x16);
3890
3891  if ($chip == 1) {
3892    return if $mid != 0x01    # National Semiconductor
3893           || $cid != 0x41;   # LM63
3894    return if ($conf & 0x18) != 0x00
3895           || ($mask & 0xa4) != 0xa4;
3896  } elsif ($chip == 2) {
3897    return if $mid != 0x23    # Fintek
3898           || $cid != 0x20;   # F75363SG
3899    return if ($conf & 0x1a) != 0x00
3900           || ($mask & 0x84) != 0x00;
3901  } elsif ($chip == 3) {
3902    return if $mid != 0x01    # National Semiconductor
3903           || $cid != 0x51;   # LM64
3904    return if ($conf & 0x18) != 0x00
3905           || ($mask & 0xa4) != 0xa4;
3906  }
3907
3908  return 6;
3909}
3910
3911# Registers used:
3912#   0x02, 0x03: Fan support
3913#   0x06: Temperature support
3914#   0x07, 0x08, 0x09: Fan config
3915#   0x0d: Manufacturer ID
3916#   0x0e: Chip ID / die revision
3917sub adm1029_detect
3918{
3919  my ($file, $addr) = @_;
3920  my $mid = i2c_smbus_read_byte_data($file, 0x0d);
3921  my $cid = i2c_smbus_read_byte_data($file, 0x0e);
3922  my $cfg;
3923
3924  return unless $mid == 0x41;             # Analog Devices
3925  return unless ($cid & 0xF0) == 0x00;    # ADM1029
3926
3927  # Extra check on unused bits
3928  $cfg = i2c_smbus_read_byte_data($file, 0x02);
3929  return unless $cfg == 0x03;
3930  $cfg = i2c_smbus_read_byte_data($file, 0x06);
3931  return unless ($cfg & 0xF9) == 0x01;
3932  foreach my $reg (0x03, 0x07, 0x08, 0x09) {
3933    $cfg = i2c_smbus_read_byte_data($file, $reg);
3934    return unless ($cfg & 0xFC) == 0x00;
3935  }
3936
3937  return 7;
3938}
3939
3940# Chip to detect: 0 = ADM1030, 1 = ADM1031
3941# Registers used:
3942#   0x01: Config 2
3943#   0x03: Status 2
3944#   0x0d, 0x0e, 0x0f: Temperature offsets
3945#   0x22: Fan speed config
3946#   0x3d: Chip ID
3947#   0x3e: Manufacturer ID
3948#   0x3f: Die revision
3949sub adm1031_detect
3950{
3951  my ($file, $addr, $chip) = @_;
3952  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
3953  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
3954  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
3955  my $conf2 = i2c_smbus_read_byte_data($file, 0x01);
3956  my $stat2 = i2c_smbus_read_byte_data($file, 0x03);
3957  my $fsc = i2c_smbus_read_byte_data($file, 0x22);
3958  my $lto = i2c_smbus_read_byte_data($file, 0x0d);
3959  my $r1to = i2c_smbus_read_byte_data($file, 0x0e);
3960  my $r2to = i2c_smbus_read_byte_data($file, 0x0f);
3961  my $confidence = 3;
3962
3963  if ($chip == 0) {
3964    return if $mid != 0x41;     # Analog Devices
3965    return if $cid != 0x30;     # ADM1030
3966    $confidence++ if ($drev & 0x70) == 0x00;
3967    $confidence++ if ($conf2 & 0x4A) == 0x00;
3968    $confidence++ if ($stat2 & 0x3F) == 0x00;
3969    $confidence++ if ($fsc & 0xF0) == 0x00;
3970    $confidence++ if ($lto & 0x70) == 0x00;
3971    $confidence++ if ($r1to & 0x70) == 0x00;
3972    return $confidence;
3973  }
3974  if ($chip == 1) {
3975    return if $mid != 0x41;     # Analog Devices
3976    return if $cid != 0x31;     # ADM1031
3977    $confidence++ if ($drev & 0x70) == 0x00;
3978    $confidence++ if ($lto & 0x70) == 0x00;
3979    $confidence++ if ($r1to & 0x70) == 0x00;
3980    $confidence++ if ($r2to & 0x70) == 0x00;
3981    return $confidence;
3982  }
3983  return;
3984}
3985
3986# Chip to detect: 0 = ADM1033, 1 = ADM1034
3987# Registers used:
3988#   0x3d: Chip ID
3989#   0x3e: Manufacturer ID
3990#   0x3f: Die revision
3991sub adm1034_detect
3992{
3993  my ($file, $addr, $chip) = @_;
3994  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
3995  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
3996  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
3997
3998  if ($chip == 0) {
3999    return if $mid != 0x41;     # Analog Devices
4000    return if $cid != 0x33;     # ADM1033
4001    return if ($drev & 0xf8) != 0x00;
4002    return 6 if $drev == 0x02;
4003    return 4;
4004  }
4005  if ($chip == 1) {
4006    return if $mid != 0x41;     # Analog Devices
4007    return if $cid != 0x34;     # ADM1034
4008    return if ($drev & 0xf8) != 0x00;
4009    return 6 if $drev == 0x02;
4010    return 4;
4011  }
4012  return
4013}
4014
4015# Chip to detect: 0 = ADT7467/ADT7468, 1 = ADT7476, 2 = ADT7462, 3 = ADT7466,
4016#                 4 = ADT7470
4017# Registers used:
4018#   0x3d: Chip ID
4019#   0x3e: Manufacturer ID
4020#   0x3f: Die revision
4021sub adt7467_detect
4022{
4023  my ($file, $addr, $chip) = @_;
4024  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4025  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4026  my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4027
4028  if ($chip == 0) {
4029    return if $mid != 0x41;     # Analog Devices
4030    return if $cid != 0x68;     # ADT7467
4031    return if ($drev & 0xf0) != 0x70;
4032    return 7 if ($drev == 0x71 || $drev == 0x72);
4033    return 5;
4034  }
4035  if ($chip == 1) {
4036    return if $mid != 0x41;     # Analog Devices
4037    return if $cid != 0x76;     # ADT7476
4038    return if ($drev & 0xf0) != 0x60;
4039    return 7 if ($drev == 0x69);
4040    return 5;
4041  }
4042  if ($chip == 2) {
4043    return if $mid != 0x41;     # Analog Devices
4044    return if $cid != 0x62;     # ADT7462
4045    return if ($drev & 0xf0) != 0x00;
4046    return 7 if ($drev == 0x04);
4047    return 5;
4048  }
4049  if ($chip == 3) {
4050    return if $mid != 0x41;     # Analog Devices
4051    return if $cid != 0x66;     # ADT7466
4052    return if ($drev & 0xf0) != 0x00;
4053    return 7 if ($drev == 0x02);
4054    return 5;
4055  }
4056  if ($chip == 4) {
4057    return if $mid != 0x41;     # Analog Devices
4058    return if $cid != 0x70;     # ADT7470
4059    return if ($drev & 0xf0) != 0x00;
4060    return 7 if ($drev == 0x00);
4061    return 5;
4062  }
4063  return
4064}
4065
4066# Chip to detect: 0 = ADT7473, 1 = ADT7475
4067# Registers used:
4068#   0x3d: Chip ID
4069#   0x3e: Manufacturer ID
4070sub adt7473_detect
4071{
4072  my ($file, $addr, $chip) = @_;
4073  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4074  my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4075
4076  if ($chip == 0) {
4077    return if $mid != 0x41;     # Analog Devices
4078    return if $cid != 0x73;     # ADT7473
4079    return 5;
4080  }
4081  if ($chip == 1) {
4082    return if $mid != 0x41;     # Analog Devices
4083    return if $cid != 0x75;     # ADT7475
4084    return 5;
4085  }
4086  return
4087}
4088
4089# Chip to detect: 0 = aSC7512, 1 = aSC7611, 2 = aSC7621
4090# Registers used:
4091#   0x3e: Manufacturer ID (0x61)
4092#   0x3f: Version
4093sub andigilog_detect
4094{
4095  my ($file, $addr, $chip) = @_;
4096  my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4097  my $cid = i2c_smbus_read_byte_data($file, 0x3f);
4098
4099  return if ($mid != 0x61);
4100
4101  if ($chip == 0) {
4102    return if $cid != 0x62;
4103    return 5;
4104  }
4105
4106  if ($chip == 1) {
4107    return if $cid != 0x69;
4108    return 5;
4109  }
4110
4111  if ($chip == 2) {
4112    return if ($cid != 0x6C && $cid != 0x6D);
4113    return 5;
4114  }
4115
4116  return;
4117}
4118
4119# Registers used:
4120#   0xfe: Manufacturer ID
4121#   0xff: Die Code
4122sub andigilog_aSC7511_detect
4123{
4124  my ($file, $addr) = @_;
4125  my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4126  my $die = i2c_smbus_read_byte_data($file, 0xff);
4127
4128  return if $mid != 0x61;     # Andigilog
4129  if ($die == 0x0) {
4130      return 3;
4131  } else {
4132      return 1;
4133  }
4134}
4135
4136# Chip to detect: 0 = LM85, 1 = LM96000, 2 = ADM1027, 3 = ADT7463,
4137#                 4 = EMC6D100/101, 5 = EMC6D102, 6 = EMC6D103
4138# Registers used: 0x3e == Vendor register.
4139#                 0x3d == Device ID register (Analog Devices only).
4140#                 0x3f == Version/Stepping register.
4141sub lm85_detect
4142{
4143  my ($file, $addr, $chip) = @_;
4144  my $vendor = i2c_smbus_read_byte_data($file, 0x3e);
4145  my $verstep = i2c_smbus_read_byte_data($file, 0x3f);
4146
4147  if ($chip == 0) {
4148    return if $vendor != 0x01;  # National Semiconductor
4149    return if $verstep != 0x60  # LM85 C
4150           && $verstep != 0x62; # LM85 B
4151  } elsif ($chip == 1) {
4152    return if $vendor != 0x01;  # National Semiconductor
4153    return if $verstep != 0x68  # LM96000
4154           && $verstep != 0x69; # LM96000
4155  } elsif ($chip == 2) {
4156    return if $vendor != 0x41;  # Analog Devices
4157    return if $verstep != 0x60; # ADM1027
4158  } elsif ($chip == 3) {
4159    return if $vendor != 0x41;  # Analog Devices
4160    return if $verstep != 0x62  # ADT7463
4161           && $verstep != 0x6a; # ADT7463 C
4162  } elsif ($chip == 4) {
4163    return if $vendor != 0x5c;  # SMSC
4164    return if $verstep != 0x60  # EMC6D100/101 A0
4165           && $verstep != 0x61; # EMC6D100/101 A1
4166  } elsif ($chip == 5) {
4167    return if $vendor != 0x5c;  # SMSC
4168    return if $verstep != 0x65; # EMC6D102
4169  } elsif ($chip == 6) {
4170    return if $vendor != 0x5c;  # SMSC
4171    return if $verstep != 0x68; # EMC6D103
4172  }
4173
4174  if ($vendor == 0x41) { # Analog Devices
4175    return if i2c_smbus_read_byte_data($file, 0x3d) != 0x27;
4176    return 8;
4177  }
4178
4179  return 7;
4180}
4181
4182# Chip to detect: 0 = LM87, 1 = ADM1024
4183# Registers used:
4184#   0x3e: Company ID
4185#   0x3f: Revision
4186#   0x40: Configuration
4187sub lm87_detect
4188{
4189  my ($file, $addr, $chip) = @_;
4190  my $cid = i2c_smbus_read_byte_data($file, 0x3e);
4191  my $rev = i2c_smbus_read_byte_data($file, 0x3f);
4192
4193  if ($chip == 0) {
4194    return if $cid != 0x02;     # National Semiconductor
4195    return if ($rev & 0xfc) != 0x04;
4196  }
4197  if ($chip == 1) {
4198    return if $cid != 0x41;     # Analog Devices
4199    return if ($rev & 0xf0) != 0x10;
4200  }
4201
4202  my $cfg = i2c_smbus_read_byte_data($file, 0x40);
4203  return if ($cfg & 0x80) != 0x00;
4204
4205  return 7;
4206}
4207
4208# Chip to detect: 0 = W83781D, 1 = W83782D, 2 = W83783S, 3 = W83627HF,
4209#                 4 = AS99127F (rev.1), 5 = AS99127F (rev.2), 6 = ASB100,
4210#                 7 = W83791D, 8 = W83792D, 9 = W83627EHF, 10 = W83627DHG
4211# Registers used:
4212#   0x48: Full I2C Address
4213#   0x4a: I2C addresses of emulated LM75 chips
4214#   0x4e: Vendor ID byte selection, and bank selection
4215#   0x4f: Vendor ID
4216#   0x58: Device ID (only when in bank 0)
4217# Note: Fails if the W8378xD is not in bank 0!
4218# Note: Asus chips do not have their I2C address at register 0x48?
4219#       AS99127F rev.1 and ASB100 have 0x00, confirmation wanted for
4220#       AS99127F rev.2.
4221sub w83781d_detect
4222{
4223  my ($file, $addr, $chip) = @_;
4224  my ($reg1, $reg2, @res);
4225
4226  return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr)
4227    or ($chip >= 4 && $chip <= 6);
4228
4229  $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4230  $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4231  if ($chip == 4) { # Asus AS99127F (rev.1)
4232    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xc3) or
4233                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x12);
4234  } elsif ($chip == 6) { # Asus ASB100
4235    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0x94) or
4236                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x06);
4237  } else { # Winbond and Asus AS99127F (rev.2)
4238    return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
4239                  (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4240  }
4241
4242  return unless ($reg1 & 0x07) == 0x00;
4243
4244  $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4245  return if $chip == 0 and ($reg1 != 0x10 && $reg1 != 0x11);
4246  return if $chip == 1 and  $reg1 != 0x30;
4247  return if $chip == 2 and  $reg1 != 0x40;
4248  return if $chip == 3 and  $reg1 != 0x21;
4249  return if $chip == 4 and  $reg1 != 0x31;
4250  return if $chip == 5 and  $reg1 != 0x31;
4251  return if $chip == 6 and  $reg1 != 0x31;
4252  return if $chip == 7 and  $reg1 != 0x71;
4253  return if $chip == 8 and  $reg1 != 0x7a;
4254  return if $chip == 9 and ($reg1 != 0x88 && $reg1 != 0xa1);
4255  return if $chip == 10 and  $reg1 != 0xc1;
4256  # Default address is 0x2d
4257  @res = ($addr != 0x2d) ? (7) : (8);
4258  return @res if $chip >= 9; # No subclients
4259
4260  $reg1 = i2c_smbus_read_byte_data($file, 0x4a);
4261  push @res, ($reg1 & 0x07) + 0x48 unless $reg1 & 0x08;
4262  push @res, (($reg1 & 0x70) >> 4) + 0x48 unless ($reg1 & 0x80 or $chip == 2);
4263  return @res;
4264}
4265
4266# Registers used:
4267#   0x0b: Full I2C Address
4268#   0x0c: I2C addresses of emulated LM75 chips
4269#   0x00: Vendor ID byte selection, and bank selection(Bank 0, 1, 2)
4270#   0x0d: Vendor ID(Bank 0, 1, 2)
4271#   0x0e: Device ID(Bank 0, 1, 2)
4272sub w83793_detect
4273{
4274  my ($file, $addr) = @_;
4275  my ($bank, $reg, @res);
4276
4277  $bank = i2c_smbus_read_byte_data($file, 0x00);
4278  $reg = i2c_smbus_read_byte_data($file, 0x0d);
4279
4280  return unless (($bank & 0x80) == 0x00 and $reg == 0xa3) or
4281                (($bank & 0x80) == 0x80 and $reg == 0x5c);
4282
4283  $reg = i2c_smbus_read_byte_data($file, 0x0e);
4284  return if $reg != 0x7b;
4285
4286# If bank 0 is selected, we can do more checks
4287  return 6 unless ($bank & 0x07) == 0;
4288  $reg = i2c_smbus_read_byte_data($file, 0x0b);
4289  return unless ($reg == ($addr << 1));
4290
4291  $reg = i2c_smbus_read_byte_data($file, 0x0c);
4292  @res = (8);
4293  push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4294  push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4295  return @res;
4296}
4297
4298# Registers used:
4299#   0x48: Full I2C Address
4300#   0x4e: Vendor ID byte selection
4301#   0x4f: Vendor ID
4302#   0x58: Device ID
4303# Note that the datasheet was useless and this detection routine
4304# is based on dumps we received from users. Also, the W83781SD is *NOT*
4305# a hardware monitoring chip as far as we know, but we still want to
4306# detect it so that people won't keep reporting it as an unknown chip
4307# we should investigate about.
4308sub w83791sd_detect
4309{
4310  my ($file, $addr) = @_;
4311  my ($reg1, $reg2);
4312
4313  return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr);
4314
4315  $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4316  $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4317  return unless (!($reg1 & 0x80) && $reg2 == 0xa3)
4318             || (($reg1 & 0x80) && $reg2 == 0x5c);
4319
4320  $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4321  return unless $reg1 == 0x72;
4322
4323  return 3;
4324}
4325
4326# Registers used:
4327#   0x4e: Vendor ID high byte
4328#   0x4f: Vendor ID low byte
4329#   0x58: Device ID
4330# Note: The values were given by Alex van Kaam, we don't have datasheets
4331#       to confirm.
4332sub mozart_detect
4333{
4334  my ($file, $addr) = @_;
4335  my ($vid, $dev);
4336
4337  $vid = (i2c_smbus_read_byte_data($file, 0x4e) << 8)
4338       +  i2c_smbus_read_byte_data($file, 0x4f);
4339  $dev = i2c_smbus_read_byte_data($file, 0x58);
4340
4341  return unless ($dev == 0x56 && $vid == 0x9436)  # ASM58
4342             || ($dev == 0x56 && $vid == 0x9406)  # AS2K129R
4343             || ($dev == 0x10 && $vid == 0x5ca3);
4344
4345  return 5;
4346}
4347
4348# Chip to detect: 0 = GL518SM, 1 = GL520SM
4349# Registers used:
4350#   0x00: Device ID
4351#   0x01: Revision ID
4352#   0x03: Configuration
4353sub gl518sm_detect
4354{
4355  my ($file, $addr, $chip) = @_;
4356  my $reg;
4357
4358  $reg = i2c_smbus_read_byte_data($file, 0x00);
4359  return if $chip == 0 && $reg != 0x80;
4360  return if $chip == 1 && $reg != 0x20;
4361
4362  return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
4363  $reg = i2c_smbus_read_byte_data($file, 0x01);
4364  return unless $reg == 0x00 or $reg == 0x80;
4365  return 6;
4366}
4367
4368# Registers used:
4369#   0x00: Device ID
4370#   0x03: Configuration
4371# Mediocre detection
4372sub gl525sm_detect
4373{
4374  my ($file, $addr) = @_;
4375  return unless i2c_smbus_read_byte_data($file, 0x00) == 0x25;
4376  return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
4377  return 5;
4378}
4379
4380# Chip to detect: 0 = ADM9240, 1 = DS1780, 2 = LM81
4381# Registers used:
4382#   0x3e: Company ID
4383#   0x40: Configuration
4384#   0x48: Full I2C Address
4385sub adm9240_detect
4386{
4387  my ($file, $addr, $chip) = @_;
4388  my $reg;
4389  $reg = i2c_smbus_read_byte_data($file, 0x3e);
4390  return unless ($chip == 0 and $reg == 0x23) or
4391                ($chip == 1 and $reg == 0xda) or
4392                ($chip == 2 and $reg == 0x01);
4393  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4394  return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4395
4396  return 7;
4397}
4398
4399# Chip to detect: 0 = ADM1022, 1 = THMC50, 2 = ADM1028, 3 = THMC51
4400# Registers used:
4401#   0x3e: Company ID
4402#   0x3f: Revision
4403#   0x40: Configuration
4404sub adm1022_detect
4405{
4406  my ($file, $addr, $chip) = @_;
4407  my $reg;
4408  $reg = i2c_smbus_read_byte_data($file, 0x3e);
4409  return unless ($chip == 0 and $reg == 0x41) or
4410                ($chip == 1 and $reg == 0x49) or
4411                ($chip == 2 and $reg == 0x41) or
4412                ($chip == 3 and $reg == 0x49);
4413  $reg = i2c_smbus_read_byte_data($file, 0x40);
4414  return if ($reg & 0x10);                      # Soft Reset always reads 0
4415  return if ($chip != 0 and ($reg & 0x80));     # Reserved on THMC50 and ADM1028
4416  $reg = i2c_smbus_read_byte_data($file, 0x3f) & 0xf0;
4417  return unless ($chip == 0 and $reg == 0xc0) or
4418                ($chip == 1 and $reg == 0xc0) or
4419                ($chip == 2 and $reg == 0xd0) or
4420                ($chip == 3 and $reg == 0xd0);
4421  return 8;
4422}
4423
4424# Chip to detect: 0 = ADM1025, 1 = NE1619
4425# Registers used:
4426#   0x3e: Company ID
4427#   0x3f: Revision
4428#   0x40: Configuration
4429#   0x41: Status 1
4430#   0x42: Status 2
4431sub adm1025_detect
4432{
4433  my ($file, $addr, $chip) = @_;
4434  my $reg;
4435
4436  $reg = i2c_smbus_read_byte_data($file, 0x3e);
4437  return if ($chip == 0) and ($reg != 0x41);
4438  return if ($chip == 1) and ($reg != 0xA1);
4439
4440  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4441  return unless (i2c_smbus_read_byte_data($file, 0x41) & 0xC0) == 0x00;
4442  return unless (i2c_smbus_read_byte_data($file, 0x42) & 0xBC) == 0x00;
4443  return unless (i2c_smbus_read_byte_data($file, 0x3f) & 0xf0) == 0x20;
4444
4445  return 8;
4446}
4447
4448# Registers used:
4449#   0x16: Company ID
4450#   0x17: Revision
4451sub adm1026_detect
4452{
4453  my ($file, $addr) = @_;
4454  my $reg;
4455  $reg = i2c_smbus_read_byte_data($file, 0x16);
4456  return unless ($reg == 0x41);
4457  return unless (i2c_smbus_read_byte_data($file, 0x17) & 0xf0) == 0x40;
4458  return 8;
4459}
4460
4461# Chip to detect: 0 = ADM1021, 1 = ADM1021A/ADM1023, 2 = MAX1617, 3 = MAX1617A,
4462#                 4 = THMC10, 5 = LM84, 6 = GL523, 7 = MC1066
4463# Registers used:
4464#   0x04: Company ID (LM84 only)
4465#   0xfe: Company ID (all but LM84 and MAX1617)
4466#   0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A)
4467#   0x02: Status
4468#   0x03: Configuration
4469#   0x04: Conversion rate
4470#   0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84)
4471# Note: Especially the MAX1617 has very bad detection; we give it a low
4472# confidence value.
4473sub adm1021_detect
4474{
4475  my ($file, $addr, $chip) = @_;
4476  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4477  my $rev = i2c_smbus_read_byte_data($file, 0xff);
4478  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4479  my $status = i2c_smbus_read_byte_data($file, 0x02);
4480  my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4481
4482  # Check manufacturer IDs and product revisions when available
4483  return if $chip == 0 and $man_id != 0x41 ||
4484                          ($rev & 0xf0) != 0x00;
4485  return if $chip == 1 and $man_id != 0x41 ||
4486                          ($rev & 0xf0) != 0x30;
4487  return if $chip == 3 and $man_id != 0x4d ||
4488                           $rev != 0x01;
4489  return if $chip == 4 and $man_id != 0x49;
4490  return if $chip == 5 and $convrate != 0x00;
4491  return if $chip == 6 and $man_id != 0x23;
4492  return if $chip == 7 and $man_id != 0x54;
4493
4494  # Check unused bits
4495  if ($chip == 5) { # LM84
4496    return if ($status & 0xab) != 0;
4497    return if ($conf & 0x7f) != 0;
4498  } else {
4499    return if ($status & 0x03) != 0;
4500    return if ($conf & 0x3f) != 0;
4501    return if ($convrate & 0xf8) != 0;
4502  }
4503
4504  # Extra checks for MAX1617 and LM84, since those are often misdetected
4505  # We verify several assertions (6 for the MAX1617, 4 for the LM84) and
4506  # discard the chip if any fail. Note that these checks are not done
4507  # by the adm1021 driver.
4508  if ($chip == 2 || $chip == 5) {
4509    my $lte = i2c_smbus_read_byte_data($file, 0x00);
4510    my $rte = i2c_smbus_read_byte_data($file, 0x01);
4511    my $lhi = i2c_smbus_read_byte_data($file, 0x05);
4512    my $rhi = i2c_smbus_read_byte_data($file, 0x07);
4513    my $llo = i2c_smbus_read_byte_data($file, 0x06);
4514    my $rlo = i2c_smbus_read_byte_data($file, 0x08);
4515
4516    # If all registers hold the same value, it has to be a misdetection
4517    return if $lte == $rte and $lte == $lhi and $lte == $rhi
4518           and $lte == $llo and $lte == $rlo;
4519
4520    # Negative temperatures
4521    return if ($lte & 0x80) or ($rte & 0x80);
4522    # Negative high limits
4523    return if ($lhi & 0x80) or ($rhi & 0x80);
4524    # Low limits over high limits
4525    if ($chip != 5) { # LM84 doesn't have low limits
4526      $llo -= 256 if ($llo & 0x80);
4527      $rlo -= 256 if ($rlo & 0x80);
4528      return if ($llo > $lhi) or ($rlo > $rhi);
4529    }
4530  }
4531
4532  return 3 if ($chip == 2) or ($chip == 5);
4533  return 7 if $chip <= 3;
4534  return 5;
4535}
4536
4537# Chip to detect: 0 = MAX1668, 1 = MAX1805, 2 = MAX1989
4538# Registers used:
4539#   0xfe: Company ID
4540#   0xff: Device ID
4541sub max1668_detect
4542{
4543  my ($file, $addr, $chip) = @_;
4544  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4545  my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4546
4547  return if $man_id != 0x4d;
4548  return if $chip == 0 and $dev_id != 0x03;
4549  return if $chip == 1 and $dev_id != 0x05;
4550  return if $chip == 2 and $dev_id != 0x0b;
4551
4552  return 7;
4553}
4554
4555# Chip to detect: 0 = MAX1619, 1 = MAX1618
4556# Registers used:
4557#   0xfe: Company ID
4558#   0xff: Device ID
4559#   0x02: Status
4560#   0x03: Configuration
4561#   0x04: Conversion rate
4562sub max1619_detect
4563{
4564  my ($file, $addr, $chip) = @_;
4565  my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4566  my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4567  my $conf = i2c_smbus_read_byte_data($file, 0x03);
4568  my $status = i2c_smbus_read_byte_data($file, 0x02);
4569  my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4570
4571  if ($chip == 0) {     # MAX1619
4572    return if $man_id != 0x4D
4573      or $dev_id != 0x04
4574      or ($conf & 0x03)
4575      or ($status & 0x61)
4576      or $convrate >= 8;
4577  }
4578  if ($chip == 1) {     # MAX1618
4579    return if $man_id != 0x4D
4580      or $dev_id != 0x02
4581      or ($conf & 0x07)
4582      or ($status & 0x63);
4583  }
4584
4585  return 7;
4586}
4587
4588# Registers used:
4589#   0x28: User ID
4590#   0x29: User ID2
4591sub ite_overclock_detect
4592{
4593  my ($file, $addr) = @_;
4594
4595  my $uid1 = i2c_smbus_read_byte_data($file, 0x28);
4596  my $uid2 = i2c_smbus_read_byte_data($file, 0x29);
4597  return if $uid1 != 0x83
4598         || $uid2 != 0x12;
4599
4600  return 6;
4601}
4602
4603# Registers used:
4604#   0x00: Configuration
4605#   0x48: Full I2C Address
4606#   0x58: Mfr ID
4607#   0x5b: Device ID
4608sub it8712_i2c_detect
4609{
4610  my ($file, $addr) = @_;
4611  my $reg;
4612  return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4613  return unless (i2c_smbus_read_byte_data($file, 0x00) & 0x90) == 0x10;
4614  return unless i2c_smbus_read_byte_data($file, 0x58) == 0x90;
4615  return if i2c_smbus_read_byte_data($file, 0x5b) != 0x12;
4616  return 7 + ($addr == 0x2d);
4617}
4618
4619# Registers used:
4620#   0-63: SPD Data and Checksum
4621sub eeprom_detect
4622{
4623  my ($file, $addr) = @_;
4624  my $checksum = 0;
4625
4626  # Check the checksum for validity (works for most DIMMs and RIMMs)
4627  for (my $i = 0; $i <= 62; $i++) {
4628    $checksum += i2c_smbus_read_byte_data($file, $i);
4629  }
4630  $checksum &= 255;
4631
4632  return 8
4633    if $checksum == i2c_smbus_read_byte_data($file, 63);
4634
4635  return;
4636}
4637
4638# Registers used:
4639#   0x00..0x07: DDC signature
4640sub ddcmonitor_detect
4641{
4642  my ($file, $addr) = @_;
4643
4644  return unless
4645    i2c_smbus_read_byte_data($file, 0x00) == 0x00 and
4646    i2c_smbus_read_byte_data($file, 0x01) == 0xFF and
4647    i2c_smbus_read_byte_data($file, 0x02) == 0xFF and
4648    i2c_smbus_read_byte_data($file, 0x03) == 0xFF and
4649    i2c_smbus_read_byte_data($file, 0x04) == 0xFF and
4650    i2c_smbus_read_byte_data($file, 0x05) == 0xFF and
4651    i2c_smbus_read_byte_data($file, 0x06) == 0xFF and
4652    i2c_smbus_read_byte_data($file, 0x07) == 0x00;
4653
4654  return 8;
4655}
4656
4657# Chip to detect: 0 = Poseidon I, 1 = Poseidon II, 2 = Scylla,
4658#                 3 = Hermes, 4 = Heimdal, 5 = Heracles
4659# Registers used:
4660#   0x00-0x02: Identification (3 capital ASCII letters)
4661sub fsc_detect
4662{
4663  my ($file, $addr, $chip) = @_;
4664  my $id;
4665
4666  $id = chr(i2c_smbus_read_byte_data($file, 0x00))
4667      . chr(i2c_smbus_read_byte_data($file, 0x01))
4668      . chr(i2c_smbus_read_byte_data($file, 0x02));
4669
4670  return if $chip == 0 and $id ne 'PEG';  # Pegasus? aka Poseidon I
4671  return if $chip == 1 and $id ne 'POS';  # Poseidon II
4672  return if $chip == 2 and $id ne 'SCY';  # Scylla
4673  return if $chip == 3 and $id ne 'HER';  # Hermes
4674  return if $chip == 4 and $id ne 'HMD';  # Heimdal
4675  return if $chip == 5 and $id ne 'HRC';  # Heracles
4676
4677  return 8;
4678}
4679
4680# Registers used:
4681#   0x3E: Manufacturer ID
4682#   0x3F: Version/Stepping
4683sub lm93_detect
4684{
4685  my ($file, $addr) = @_;
4686  return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x01
4687            and i2c_smbus_read_byte_data($file, 0x3F) == 0x73;
4688  return 5;
4689}
4690
4691# Registers used:
4692#   0x3F: Revision ID
4693#   0x48: Address
4694#   0x4A, 0x4B, 0x4F, 0x57, 0x58: Reserved bits.
4695# We do not use 0x49's reserved bits on purpose. The register is named
4696# "VID4/Device ID" so it is doubtful bits 7-1 are really unused.
4697sub m5879_detect
4698{
4699  my ($file, $addr) = @_;
4700
4701  return
4702    unless i2c_smbus_read_byte_data($file, 0x3F) == 0x01;
4703
4704  return
4705    unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4706
4707  return
4708    unless (i2c_smbus_read_byte_data($file, 0x4A) & 0x06) == 0
4709       and (i2c_smbus_read_byte_data($file, 0x4B) & 0xFC) == 0
4710       and (i2c_smbus_read_byte_data($file, 0x4F) & 0xFC) == 0
4711       and (i2c_smbus_read_byte_data($file, 0x57) & 0xFE) == 0
4712       and (i2c_smbus_read_byte_data($file, 0x58) & 0xEF) == 0;
4713
4714  return 7;
4715}
4716
4717# Registers used:
4718#   0x3E: Manufacturer ID
4719#   0x3F: Version/Stepping
4720#   0x47: VID (3 reserved bits)
4721#   0x49: VID4 (7 reserved bits)
4722sub smsc47m192_detect
4723{
4724  my ($file, $addr) = @_;
4725  return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x55
4726           and (i2c_smbus_read_byte_data($file, 0x3F) & 0xF0) == 0x20
4727           and (i2c_smbus_read_byte_data($file, 0x47) & 0x70) == 0x00
4728           and (i2c_smbus_read_byte_data($file, 0x49) & 0xFE) == 0x80;
4729  return ($addr == 0x2d ? 6 : 5);
4730}
4731
4732# Chip to detect: 1 = DME1737, 2 = SCH5027
4733# Registers used:
4734#   0x3E: Manufacturer ID
4735#   0x3F: Version/Stepping
4736#   0x73: Read-only test register (4 test bits)
4737#   0x8A: Read-only test register (7 test bits)
4738#   0xBA: Read-only test register (8 test bits)
4739sub dme1737_detect
4740{
4741  my ($file, $addr, $chip) = @_;
4742  my $vendor = i2c_smbus_read_byte_data($file, 0x3E);
4743  my $verstep = i2c_smbus_read_byte_data($file, 0x3F);
4744
4745  return unless $vendor == 0x5C; # SMSC
4746
4747  if ($chip == 1) { # DME1737
4748      return unless ($verstep & 0xF8) == 0x88 and
4749          (i2c_smbus_read_byte_data($file, 0x73) & 0x0F) == 0x09 and
4750          (i2c_smbus_read_byte_data($file, 0x8A) & 0x7F) == 0x4D;
4751  } elsif ($chip == 2) { # SCH5027
4752      return unless $verstep >= 0x69 and $verstep <= 0x6F and
4753          i2c_smbus_read_byte_data($file, 0xBA) == 0x0F;
4754  }
4755
4756  return ($addr == 0x2e ? 6 : 5);
4757}
4758
4759# Chip to detect: 1 = F75111R/RG/N, 2 = F75121R/F75122R/RG, 3 = F75373S/SG,
4760#                 4 = F75375S/SP, 5 = F75387SG/RG, 6 = F75383M/S/F75384M/S,
4761#                 7 = custom power control IC
4762# Registers used:
4763#   0x5A-0x5B: Chip ID
4764#   0x5D-0x5E: Vendor ID
4765sub fintek_detect
4766{
4767  my ($file, $addr, $chip) = @_;
4768  my $chipid = (i2c_smbus_read_byte_data($file, 0x5A) << 8)
4769             | i2c_smbus_read_byte_data($file, 0x5B);
4770  my $vendid = (i2c_smbus_read_byte_data($file, 0x5D) << 8)
4771             | i2c_smbus_read_byte_data($file, 0x5E);
4772
4773  return unless $vendid == 0x1934; # Fintek ID
4774
4775  if ($chip == 1) { # F75111R/RG/N
4776    return unless $chipid == 0x0300;
4777  } elsif ($chip == 2) { # F75121R/F75122R/RG
4778    return unless $chipid == 0x0301;
4779  } elsif ($chip == 3) { # F75373S/SG
4780    return unless $chipid == 0x0204;
4781  } elsif ($chip == 4) { # F75375S/SP
4782    return unless $chipid == 0x0306;
4783  } elsif ($chip == 5) { # F75387SG/RG
4784    return unless $chipid == 0x0410;
4785  } elsif ($chip == 6) { # F75383M/S/F75384M/S
4786    # The datasheet has 0x0303, but Fintek say 0x0413 is also possible
4787    return unless $chipid == 0x0303 || $chipid == 0x0413;
4788  } elsif ($chip == 7) { # custom power control IC
4789    return unless $chipid == 0x0302;
4790  }
4791
4792  return 7;
4793}
4794
4795# This checks for non-FFFF values for temperature, voltage, and current.
4796# The address (0x0b) is specified by the SMBus standard so it's likely
4797# that this really is a smart battery.
4798sub smartbatt_detect
4799{
4800  my ($file, $addr) = @_;
4801
4802  return if i2c_smbus_read_word_data($file, 0x08) == 0xffff
4803         || i2c_smbus_read_word_data($file, 0x09) == 0xffff
4804         || i2c_smbus_read_word_data($file, 0x0a) == 0xffff;
4805  return 5;
4806}
4807
4808# Chip to detect: 0 = W83L784R/AR/G, 1 = W83L785R/G, 2 = W83L786NR/NG/R/G,
4809#                 3 = W83L785TS-S
4810# Registers used:
4811#   0x40: Configuration
4812#   0x4a: Full I2C Address (W83L784R only)
4813#   0x4b: I2C addresses of emulated LM75 chips (W83L784R only)
4814#   0x4c: Winbond Vendor ID (Low Byte)
4815#   0x4d: Winbond Vendor ID (High Byte)
4816#   0x4e: Chip ID
4817sub w83l784r_detect
4818{
4819  my ($file, $addr, $chip) = @_;
4820  my ($reg, @res);
4821
4822  return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4823  return if $chip == 0
4824    and i2c_smbus_read_byte_data($file, 0x4a) != $addr;
4825  return unless i2c_smbus_read_byte_data($file, 0x4c) == 0xa3;
4826  return unless i2c_smbus_read_byte_data($file, 0x4d) == 0x5c;
4827
4828  $reg = i2c_smbus_read_byte_data($file, 0x4e);
4829  return if $chip == 0 and $reg != 0x50;
4830  return if $chip == 1 and $reg != 0x60;
4831  return if $chip == 2 and $reg != 0x80;
4832  return if $chip == 3 and $reg != 0x70;
4833
4834  return 8 if $chip != 0; # No subclients
4835
4836  @res = (8);
4837  $reg = i2c_smbus_read_byte_data($file, 0x4b);
4838  push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4839  push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4840  return @res;
4841}
4842
4843# The max6650 has no device ID register. However, a few registers have
4844# spare bits, which are documented as being always zero on read. We read
4845# all of these registers check the spare bits. Any non-zero means this
4846# is not a max6650/1.
4847#
4848# The always zero bits are:
4849#   configuration byte register (0x02) - top 2 bits
4850#   gpio status register (0x14) - top 3 bits
4851#   alarm enable register (0x08) - top 3 bits
4852#   alarm status register (0x0A) - top 3 bits
4853#   tachometer count time register (0x16) - top 6 bits
4854# Additionally, not all values are possible for lower 3 bits of
4855# the configuration register.
4856sub max6650_detect
4857{
4858  my ($file, $addr) = @_;
4859
4860  my $conf = i2c_smbus_read_byte_data($file, 0x02);
4861
4862  return if i2c_smbus_read_byte_data($file, 0x16) & 0xFC;
4863  return if i2c_smbus_read_byte_data($file, 0x0A) & 0xE0;
4864  return if i2c_smbus_read_byte_data($file, 0x08) & 0xE0;
4865  return if i2c_smbus_read_byte_data($file, 0x14) & 0xE0;
4866  return if ($conf & 0xC0) or ($conf & 0x07) > 4;
4867
4868  return 3;
4869}
4870
4871sub max6655_detect
4872{
4873  my ($file, $addr) = @_;
4874
4875  # checking RDID (Device ID)
4876  return unless i2c_smbus_read_byte_data($file, 0xfe) == 0x0a;
4877  # checking RDRV (Manufacturer ID)
4878  return unless i2c_smbus_read_byte_data($file, 0xff) == 0x4d;
4879  # checking unused bits (conversion rate, extended temperature)
4880  return unless i2c_smbus_read_byte_data($file, 0x04) & 0xf8;
4881  return unless i2c_smbus_read_byte_data($file, 0x10) & 0x1f;
4882  return unless i2c_smbus_read_byte_data($file, 0x11) & 0x1f;
4883  return unless i2c_smbus_read_byte_data($file, 0x12) & 0x1f;
4884
4885  return 6;
4886}
4887
4888# This isn't very good detection.
4889# Verify the i2c address, and the stepping ID (which is 0xb0 on
4890# my chip but could be different for others...
4891sub vt1211_i2c_detect
4892{
4893  my ($file, $addr) = @_;
4894  return unless (i2c_smbus_read_byte_data($file, 0x48) & 0x7f) == $addr;
4895  return unless i2c_smbus_read_byte_data($file, 0x3f) == 0xb0;
4896  return 2;
4897}
4898
4899# All ISA detection functions below take at least 1 parameter:
4900# $_[0]: Address
4901# Some of these functions which can detect more than one type of device,
4902# take a second parameter:
4903# $_[1]: Chip to detect
4904
4905# Chip to detect: 0 = LM78, 2 = LM79
4906sub lm78_isa_detect
4907{
4908  my ($addr, $chip) = @_;
4909  my $val = inb($addr + 1);
4910  return if inb($addr + 2) != $val or inb($addr + 3) != $val or
4911            inb($addr + 7) != $val;
4912
4913  $val = inb($addr + 5);
4914  outb($addr + 5, ~$val & 0x7f);
4915  if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4916    outb($addr+5, $val);
4917    return;
4918  }
4919
4920  return unless (isa_read_i5d6($addr, 0x40) & 0x80) == 0x00;
4921  my $reg = isa_read_i5d6($addr, 0x49);
4922  return unless ($chip == 0 and ($reg == 0x00 or $reg == 0x20 or $reg == 0x40)) or
4923                ($chip == 2 and ($reg & 0xfe) == 0xc0);
4924
4925  # Explicitly prevent misdetection of Winbond chips
4926  $reg = isa_read_i5d6($addr, 0x4f);
4927  return if $reg == 0xa3 || $reg == 0x5c;
4928
4929  # Explicitly prevent misdetection of ITE chips
4930  $reg = isa_read_i5d6($addr, 0x58);
4931  return if $reg == 0x90;
4932
4933  return 6;
4934}
4935
4936# Chip to detect: 0 = W83781D, 1 = W83782D
4937sub w83781d_isa_detect
4938{
4939  my ($addr, $chip) = @_;
4940  my ($reg1, $reg2);
4941  my $val = inb($addr + 1);
4942  return if inb($addr + 2) != $val or inb($addr + 3) != $val or
4943            inb($addr + 7) != $val;
4944
4945  $val = inb($addr + 5);
4946  outb($addr+5, ~$val & 0x7f);
4947  if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4948    outb($addr+5, $val);
4949    return;
4950  }
4951
4952  $reg1 = isa_read_i5d6($addr, 0x4e);
4953  $reg2 = isa_read_i5d6($addr, 0x4f);
4954  return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
4955                (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4956  return unless ($reg1 & 0x07) == 0x00;
4957  $reg1 = isa_read_i5d6($addr, 0x58);
4958  return if $chip == 0 and  ($reg1 & 0xfe) != 0x10;
4959  return if $chip == 1 and  ($reg1 & 0xfe) != 0x30;
4960
4961  return 8;
4962}
4963
4964# We simply look for a register at standard locations.
4965# For KCS, use the STATUS register. For SMIC, use the FLAGS register.
4966# Incidentally they live at the same offset.
4967sub ipmi_detect
4968{
4969  my ($addr) = @_;
4970  return if inb($addr + 3) == 0xff;
4971  return 4;
4972}
4973
4974###################
4975# ALIAS DETECTION #
4976###################
4977
4978# These functions take at least 3 parameters:
4979# $_[0]: ISA/LPC address
4980# $_[1]: I2C file handle
4981# $_[2]: I2C address
4982# Some of these functions may take extra parameters.
4983# They return 1 if both devices are the same, 0 if not.
4984
4985# Extra parameters:
4986# $_[3]: First limit register to compare
4987# $_[4]: Last limit register to compare
4988sub winbond_alias_detect
4989{
4990  my ($isa_addr, $file, $i2c_addr, $first, $last) = @_;
4991  my $i;
4992
4993  return 0 unless isa_read_i5d6($isa_addr, 0x48) == $i2c_addr;
4994  for ($i = $first; $i <= $last; $i++) {
4995    return 0 unless isa_read_i5d6($isa_addr, $i) == i2c_smbus_read_byte_data($file, $i);
4996  }
4997  return 1;
4998}
4999
5000sub vt1211_alias_detect
5001{
5002  my ($isa_addr, $file, $i2c_addr) = @_;
5003  my $i;
5004
5005  return 0 unless (inb($isa_addr + 0x48) & 0x7f) == $i2c_addr;
5006  for ($i = 0x2b; $i <= 0x3d; $i++) {
5007    return 0 unless inb($isa_addr + $i) == i2c_smbus_read_byte_data($file, $i);
5008  }
5009  return 1;
5010}
5011
5012
5013######################
5014# PCI CHIP DETECTION #
5015######################
5016
5017# Returns: undef if not detected, (9) if detected.
5018# The address is encoded in PCI space. We could decode it and print it.
5019sub sis5595_pci_detect
5020{
5021        return unless exists $pci_list{'1039:0008'};
5022        return 9;
5023}
5024
5025# Returns: undef if not detected, (9) if detected.
5026# The address is encoded in PCI space. We could decode it and print it.
5027sub via686a_pci_detect
5028{
5029        return unless exists $pci_list{'1106:3057'};
5030        return 9;
5031}
5032
5033# Returns: undef if not detected, (9) if detected.
5034# The address is encoded in PCI space. We could decode it and print it.
5035sub via8231_pci_detect
5036{
5037        return unless exists $pci_list{'1106:8235'};
5038        return 9;
5039}
5040
5041# Returns: undef if not detected, (9) if detected.
5042sub k8temp_pci_detect
5043{
5044        return unless exists $pci_list{'1022:1103'};
5045        return 9;
5046}
5047
5048sub k10temp_pci_detect
5049{
5050        return unless exists $pci_list{'1022:1203'};
5051        return 9;
5052}
5053
5054# Returns: undef if not detected, (9) if detected.
5055sub intel_amb_detect
5056{
5057        if ((exists $pci_list{'8086:25f0'}) ||  # Intel 5000
5058            (exists $pci_list{'8086:4030'})) {  # Intel 5400
5059                return 9;
5060        }
5061        return;
5062}
5063
5064# Returns: undef if not detected, (9) if detected.
5065sub coretemp_detect
5066{
5067        my $probecpu;
5068        foreach $probecpu (@cpu) {
5069                if ($probecpu->{vendor_id} eq 'GenuineIntel' &&
5070                                $probecpu->{cpu_family} == 6 &&
5071                                ($probecpu->{model} == 14 ||
5072                                 $probecpu->{model} == 15 ||
5073                                 $probecpu->{model} == 0x16 ||
5074                                 $probecpu->{model} == 0x17)) {
5075                        return 9;
5076                }
5077        }
5078        return;
5079}
5080
5081# Returns: undef if not detected, (9) if detected.
5082sub c7temp_detect
5083{
5084        my $probecpu;
5085        foreach $probecpu (@cpu) {
5086                if ($probecpu->{vendor_id} eq 'CentaurHauls' &&
5087                                $probecpu->{cpu_family} == 6 &&
5088                                ($probecpu->{model} == 0xa ||
5089                                 $probecpu->{model} == 0xd)) {
5090                        return 9;
5091                }
5092        }
5093        return;
5094}
5095
5096################
5097# MAIN PROGRAM #
5098################
5099
5100# $_[0]: reference to a list of chip hashes
5101sub print_chips_report
5102{
5103  my ($listref) = @_;
5104  my $data;
5105
5106  foreach $data (@$listref) {
5107    my $is_i2c = exists $data->{i2c_addr};
5108    my $is_isa = exists $data->{isa_addr};
5109    print "  * ";
5110    if ($is_i2c) {
5111      printf "Bus `%s'\n", $data->{i2c_adap};
5112      printf "    Busdriver `%s', I2C address 0x%02x",
5113             $data->{i2c_driver}, $data->{i2c_addr};
5114      if (exists $data->{i2c_sub_addrs}) {
5115        print " (and";
5116        my $sub_addr;
5117        foreach $sub_addr (@{$data->{i2c_sub_addrs}}) {
5118          printf " 0x%02x", $sub_addr;
5119        }
5120        print ")"
5121      }
5122      print "\n    ";
5123    }
5124    if ($is_isa) {
5125      print "ISA bus";
5126      if ($data->{isa_addr}) {
5127        printf ", address 0x%x", $data->{isa_addr};
5128      }
5129      print " (Busdriver `i2c-isa')"
5130        unless kernel_version_at_least(2, 6, 18);
5131      print "\n    ";
5132    }
5133    printf "Chip `%s' (confidence: %d)\n",
5134           $data->{chipname},  $data->{conf};
5135  }
5136}
5137
5138sub generate_modprobes
5139{
5140  my ($chip, $detection, @optionlist, $adap);
5141  my ($isa, $ipmi);
5142  my ($modprobes, $configfile);
5143
5144  foreach $chip (@chips_detected) {
5145    foreach $detection (@{$chip->{detected}}) {
5146      # Tag adapters which host hardware monitoring chips we want to access
5147      if (exists $detection->{i2c_devnr}
5148       && !exists $detection->{isa_addr}) {
5149           $i2c_adapters[$detection->{i2c_devnr}]->{used}++;
5150      }
5151
5152      if (exists $detection->{isa_addr}) {
5153           $isa = 1;
5154      }
5155    }
5156    if ($chip->{driver} eq "ipmisensors") {
5157         $ipmi = 1;
5158    }
5159  }
5160
5161  # Handle aliases
5162  # As of kernel 2.6.28, alias detection is handled by kernel drivers
5163  # directly, so module options are no longer needed.
5164  unless (kernel_version_at_least(2, 6, 28)) {
5165    foreach $chip (@chips_detected) {
5166      @optionlist = ();
5167      foreach $detection (@{$chip->{detected}}) {
5168        if (exists $detection->{i2c_driver} and
5169            exists $detection->{isa_addr} and
5170            $i2c_adapters[$detection->{i2c_devnr}]->{used}) {
5171          push @optionlist, $detection->{i2c_devnr},
5172                            $detection->{i2c_addr};
5173        }
5174      }
5175
5176      next if not @optionlist;
5177      $configfile = "# hwmon module options\n" unless defined $configfile;
5178      $configfile .= "options $chip->{driver}";
5179      $configfile .= sprintf(" ignore=%d,0x%02x", shift @optionlist,
5180                                                  shift @optionlist);
5181      $configfile .= sprintf(",%d,0x%02x", shift @optionlist,
5182                             shift @optionlist) while @optionlist;
5183      $configfile .= "\n";
5184    }
5185  }
5186
5187  # If we added any module option to handle aliases, we need to load all
5188  # the adapter drivers so that the numbers will be the same. If not, then
5189  # we only load the adapter drivers which are useful.
5190  foreach $adap (@i2c_adapters) {
5191    next unless contains($adap->{driver}, @modules_we_loaded);
5192    next if not defined $configfile and not $adap->{used};
5193    $modprobes .= "# I2C adapter drivers\n" unless defined $modprobes;
5194    $modprobes .= "modprobe $adap->{driver}\n"
5195      unless $modprobes =~ /modprobe $adap->{driver}\n/;
5196  }
5197
5198  # i2c-isa is loaded automatically (as a dependency) since 2.6.14,
5199  # and will soon be gone.
5200  $modprobes .= "modprobe i2c-isa\n" if ($isa && !kernel_version_at_least(2, 6, 18));
5201  if ($ipmi) {
5202    $modprobes .= "# You must also install and load the IPMI modules\n";
5203    $modprobes .= "modprobe ipmi-si\n";
5204  }
5205
5206  # Now determine the chip probe lines
5207  $modprobes .= "# Chip drivers\n";
5208  foreach $chip (@chips_detected) {
5209    next if not @{$chip->{detected}};
5210    if ($chip->{driver} eq "to-be-written") {
5211      $modprobes .= "# no driver for $chip->{detected}[0]{chipname} yet\n";
5212    } else {
5213       open(local *INPUTFILE, "modprobe -l $chip->{driver} 2>/dev/null |");
5214       local $_;
5215       my $modulefound = 0;
5216       while (<INPUTFILE>) {
5217         if (m@/@) {
5218           $modulefound = 1;
5219           last;
5220         }
5221       }
5222       close(INPUTFILE);
5223       #check return value from modprobe in case modprobe -l isn't supported
5224       if ((($? >> 8) == 0) && ! $modulefound) {
5225         $modprobes .= "# Warning: the required module $chip->{driver} is not currently installed\n".
5226                       "# on your system. For status of 2.6 kernel ports check\n".
5227                       "# http://www.lm-sensors.org/wiki/Devices. If driver is built\n".
5228                       "# into the kernel, or unavailable, comment out the following line.\n";
5229       }
5230       $modprobes .= "modprobe $chip->{driver}\n";
5231    }
5232  }
5233
5234  return ($modprobes, $configfile);
5235
5236}
5237
5238sub main
5239{
5240  # We won't go very far if not root
5241  unless ($> == 0) {
5242    print "You need to be root to run this script.\n";
5243    exit -1;
5244  }
5245
5246  if (-x "/sbin/service" && -f "/etc/init.d/lm_sensors" &&
5247      -f "/var/lock/subsys/lm_sensors") {
5248    system("/sbin/service", "lm_sensors", "stop");
5249  }
5250
5251  initialize_kernel_version();
5252  initialize_conf();
5253  initialize_pci();
5254  initialize_modules_list();
5255  # make sure any special case chips are added to the chip_ids list before
5256  # making the support modules list
5257  chip_special_cases();
5258  initialize_modules_supported();
5259  initialize_cpu_list();
5260
5261  print "# sensors-detect revision $revision\n\n";
5262
5263  print "This program will help you determine which kernel modules you need\n",
5264        "to load to use lm_sensors most effectively. It is generally safe\n",
5265        "and recommended to accept the default answers to all questions,\n",
5266        "unless you know what you're doing.\n";
5267  print "\n";
5268
5269  adapter_pci_detection();
5270  print "\n";
5271
5272  print "If you have undetectable or unsupported I2C/SMBus adapters, you can have\n".
5273        "them scanned by manually loading the modules before running this script.\n\n";
5274  initialize_i2c_adapters_list();
5275
5276  load_module("i2c-dev") unless -e "$sysfs_root/class/i2c-dev";
5277
5278  $i2c_addresses_to_scan = i2c_addresses_to_scan();
5279
5280  print "We are now going to do the I2C/SMBus adapter probings. Some chips may\n",
5281        "be double detected; we choose the one with the highest confidence\n",
5282        "value in that case.\n",
5283        "If you found that the adapter hung after probing a certain address,\n",
5284        "you can specify that address to remain unprobed.\n";
5285
5286  my ($inp, @not_to_scan, $inp2);
5287  for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
5288    next unless exists $i2c_adapters[$dev_nr];
5289    my $adap = $i2c_adapters[$dev_nr]->{name};
5290    print "\n";
5291    print "Next adapter: $adap (i2c-$dev_nr)\n";
5292    print "Do you want to scan it? (YES/no/selectively): ";
5293
5294    $inp = <STDIN>;
5295    if ($inp =~ /^\s*[Ss]/) {
5296      print "Please enter one or more addresses not to scan. Separate them ",
5297            "with comma's.\n",
5298            "You can specify a range by using dashes. Addresses may be ",
5299            "decimal (like 54)\n",
5300            "or hexadecimal (like 0x33).\n",
5301            "Addresses: ";
5302      $inp2 = <STDIN>;
5303      chop($inp2);
5304      @not_to_scan = parse_not_to_scan(0x03, 0x77, $inp2);
5305    }
5306    scan_adapter($dev_nr, $adap, $i2c_adapters[$dev_nr]->{driver},
5307                 \@not_to_scan) unless $inp =~ /^\s*[Nn]/;
5308  }
5309  print "\n";
5310
5311  # Skip "random" I/O port probing on PPC
5312  if ($kernel_arch ne 'ppc'
5313   && $kernel_arch ne 'ppc64') {
5314    print "Some chips are also accessible through the ISA I/O ports. We have to\n".
5315          "write to arbitrary I/O ports to probe them. This is usually safe though.\n".
5316          "Yes, you do have ISA I/O ports even if you do not have any ISA slots!\n";
5317    print "Do you want to scan the ISA I/O ports? (YES/no): ";
5318    unless (<STDIN> =~ /^\s*n/i) {
5319      initialize_ioports();
5320      scan_isa_bus();
5321      close_ioports();
5322    }
5323    print "\n";
5324
5325    print "Some Super I/O chips may also contain sensors. We have to write to\n".
5326          "standard I/O ports to probe them. This is usually safe.\n";
5327    print "Do you want to scan for Super I/O sensors? (YES/no): ";
5328    unless (<STDIN> =~ /^\s*n/i) {
5329      initialize_ioports();
5330      scan_superio(0x2e, 0x2f);
5331      scan_superio(0x4e, 0x4f);
5332      close_ioports();
5333    }
5334    print "\n";
5335  }
5336
5337  print "Some south bridges, CPUs or memory controllers may also contain\n";
5338  print "embedded sensors. Do you want to scan for them? (YES/no): ";
5339  unless (<STDIN> =~ /^\s*n/i) {
5340    $| = 1;
5341    foreach my $entry (@cpu_ids) {
5342      scan_cpu($entry);
5343    }
5344    $| = 0;
5345  }
5346  print "\n";
5347
5348  if (! @chips_detected) {
5349    print "Sorry, no sensors were detected.\n",
5350          "Either your sensors are not supported, or they are connected to an\n",
5351          "I2C or SMBus adapter that is not supported. See\n",
5352          "http://www.lm-sensors.org/wiki/FAQ/Chapter3 for further information.\n",
5353          "If you find out what chips are on your board, check\n",
5354          "http://www.lm-sensors.org/wiki/Devices for driver status.\n";
5355    exit;
5356  }
5357
5358  print "Now follows a summary of the probes I have just done.\n".
5359        "Just press ENTER to continue: ";
5360  <STDIN>;
5361
5362  my ($chip, $data);
5363  foreach $chip (@chips_detected) {
5364    next unless @{$chip->{detected}};
5365    print "\nDriver `$chip->{driver}':\n";
5366    print_chips_report($chip->{detected});
5367  }
5368  print "\n";
5369
5370  my ($modprobes, $configfile) = generate_modprobes();
5371
5372  if (defined $configfile) {
5373    my $have_modprobe_d = -d '/etc/modprobe.d';
5374    printf "Do you want to \%s /etc/modprobe.d/lm_sensors? (\%s): ",
5375           (-e '/etc/modprobe.d/lm_sensors' ? 'overwrite' : 'generate'),
5376           ($have_modprobe_d ? 'YES/no' : 'yes/NO');
5377    $_ = <STDIN>;
5378    if (($have_modprobe_d and not m/^\s*n/i) or m/^\s*y/i) {
5379      unless ($have_modprobe_d) {
5380        mkdir('/etc/modprobe.d', 0777)
5381          or die "Sorry, can't create /etc/modprobe.d ($!)";
5382      }
5383      open(local *MODPROBE_D, ">/etc/modprobe.d/lm_sensors")
5384        or die "Sorry, can't create /etc/modprobe.d/lm_sensors ($!)";
5385      print MODPROBE_D
5386        "# Generated by sensors-detect on " . scalar localtime() . "\n";
5387      print MODPROBE_D $configfile;
5388      close(MODPROBE_D);
5389    } else {
5390      print "To make the sensors modules behave correctly, add these lines to\n".
5391            "/etc/modprobe.conf:\n\n";
5392      print "#----cut here----\n".
5393            $configfile.
5394            "#----cut here----\n\n";
5395    }
5396  }
5397
5398  my $have_sysconfig = -d '/etc/sysconfig';
5399  printf "Do you want to \%s /etc/sysconfig/lm_sensors? (\%s): ",
5400         (-e '/etc/sysconfig/lm_sensors' ? 'overwrite' : 'generate'),
5401         ($have_sysconfig ? 'YES/no' : 'yes/NO');
5402  $_ = <STDIN>;
5403  if (($have_sysconfig and not m/^\s*n/i) or m/^\s*y/i) {
5404    unless ($have_sysconfig) {
5405      mkdir('/etc/sysconfig', 0777)
5406        or die "Sorry, can't create /etc/sysconfig ($!)";
5407    }
5408    open(local *SYSCONFIG, ">/etc/sysconfig/lm_sensors")
5409      or die "Sorry, can't create /etc/sysconfig/lm_sensors ($!)";
5410    print SYSCONFIG <<'EOT';
5411#    /etc/sysconfig/lm_sensors - Defines modules loaded by
5412#                                /etc/init.d/lm_sensors
5413#    Copyright (c) 1998 - 2001  Frodo Looijaard <frodol@dds.nl>
5414#
5415#    This program is free software; you can redistribute it and/or modify
5416#    it under the terms of the GNU General Public License as published by
5417#    the Free Software Foundation; either version 2 of the License, or
5418#    (at your option) any later version.
5419#
5420#    This program is distributed in the hope that it will be useful,
5421#    but WITHOUT ANY WARRANTY; without even the implied warranty of
5422#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5423#    GNU General Public License for more details.
5424#
5425#    You should have received a copy of the GNU General Public License
5426#    along with this program; if not, write to the Free Software
5427#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
5428#    MA 02110-1301 USA.
5429#
5430#
5431# See also the lm_sensors homepage at:
5432#     http://www.lm-sensors.org/
5433#
5434# This file is used by /etc/init.d/lm_sensors and defines the modules to
5435# be loaded/unloaded. This file is sourced into /etc/init.d/lm_sensors.
5436#
5437# The format of this file is a shell script that simply defines the modules
5438# in order as normal variables with the special names:
5439#    MODULE_0, MODULE_1, MODULE_2, etc.
5440#
5441# List the modules that are to be loaded for your system
5442#
5443EOT
5444    print SYSCONFIG
5445      "# Generated by sensors-detect on " . scalar localtime() . "\n";
5446    my @modules = grep /^modprobe /, split "\n", $modprobes;
5447    my $i = 0;
5448    my $sysconfig = "";
5449    foreach (@modules) {
5450      s/^modprobe //;
5451      $sysconfig .= "MODULE_$i=$_\n";
5452      $i++;
5453    }
5454    print SYSCONFIG $sysconfig;
5455    close(SYSCONFIG);
5456
5457    print "Copy prog/init/lm_sensors.init to /etc/init.d/lm_sensors\n".
5458          "for initialization at boot time.\n"
5459      unless -f "/etc/init.d/lm_sensors";
5460
5461    if (-x "/sbin/insserv" && -f "/etc/init.d/lm_sensors") {
5462      system("/sbin/insserv", "/etc/init.d/lm_sensors");
5463    } elsif (-x "/sbin/chkconfig" && -f "/etc/init.d/lm_sensors") {
5464      system("/sbin/chkconfig", "lm_sensors", "on");
5465      if (-x "/sbin/service") {
5466        system("/sbin/service", "lm_sensors", "start");
5467      }
5468    } else {
5469      print "You should now start the lm_sensors service to load the required\n".
5470            "kernel modules.\n\n";
5471    }
5472  } else {
5473    print "To load everything that is needed, add this to one of the system\n".
5474          "initialization scripts (e.g. /etc/rc.d/rc.local):\n\n";
5475    print "#----cut here----\n".
5476          $modprobes.
5477          (-e '/usr/bin/sensors' ?
5478            "/usr/bin/sensors -s\n" :
5479            "/usr/local/bin/sensors -s\n") .
5480          "#----cut here----\n\n";
5481
5482    print "If you have some drivers built into your kernel, the list above will\n".
5483          "contain too many modules. Skip the appropriate ones! You really\n".
5484          "should try these commands right now to make sure everything is\n".
5485          "working properly. Monitoring programs won't work until the needed\n".
5486          "modules are loaded.\n\n";
5487  }
5488
5489  unload_modules();
5490}
5491
5492sub cleanup_on_int
5493{
5494  print "\n";
5495  unload_modules();
5496  exit;
5497}
5498
5499$SIG{INT} = \&cleanup_on_int;
5500
5501main;
Note: See TracBrowser for help on using the browser.