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

Revision 5471, 149.8 KB (checked in by khali, 5 years ago)

Reindent I2C access functions.

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