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

Revision 5476, 148.5 KB (checked in by khali, 4 years ago)

Reindent more functions.

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