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

Revision 5499, 141.1 KB (checked in by khali, 4 years ago)

Drop redundant comments in PCI / CPU detection section.

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