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

Revision 5477, 148.7 KB (checked in by khali, 4 years ago)

Split scan_i2c_adapter into subfunctions to make it easier to read.

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