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

Revision 5472, 149.8 KB (checked in by khali, 4 years ago)

Minor clean-up in i2c_probe.

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