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

Revision 5500, 140.9 KB (checked in by khali, 5 years ago)

Move some code from main() to scan_i2c_adapter() as it makes more sense
that way.

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