root/lm-sensors/trunk/prog/detect/sensors-detect

Revision 6019, 191.0 KB (checked in by khali, 8 days ago)

Fix typo.

  • 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 - 2011  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 qw(:DEFAULT :seek);
27use File::Basename;
28
29# We will call modprobe, which typically lives in either /sbin,
30# /usr/sbin or /usr/local/bin. So make sure these are all in the PATH.
31foreach ('/usr/sbin', '/usr/local/sbin', '/sbin') {
32        $ENV{PATH} = "$_:".$ENV{PATH}
33                unless $ENV{PATH} =~ m/(^|:)$_\/?(:|$)/;
34}
35
36#########################
37# CONSTANT DECLARATIONS #
38#########################
39
40use constant NO_CACHE => 1;
41use vars qw(@pci_adapters @chip_ids @ipmi_ifs @non_hwmon_chip_ids
42            $i2c_addresses_to_scan $revision @i2c_byte_cache);
43
44$revision = '$Revision$ ($Date$)';
45$revision =~ s/\$\w+: (.*?) \$/$1/g;
46$revision =~ s/ \([^()]*\)//;
47
48# This is the list of SMBus or I2C adapters we recognize by their PCI
49# signature. This is an easy and fast way to determine which SMBus or I2C
50# adapters should be present.
51# Each entry must have a vendid (Vendor ID), devid (Device ID) and
52# procid (Device name) and driver (Device driver).
53@pci_adapters = (
54        {
55                vendid  => 0x8086,
56                devid   => 0x7113,
57                procid  => "Intel 82371AB PIIX4 ACPI",
58                driver  => "i2c-piix4",
59        }, {
60                vendid  => 0x8086,
61                devid   => 0x7603,
62                procid  => "Intel 82372FB PIIX5 ACPI",
63                driver  => "to-be-written",
64        }, {
65                vendid  => 0x8086,
66                devid   => 0x719b,
67                procid  => "Intel 82443MX Mobile",
68                driver  => "i2c-piix4",
69        }, {
70                vendid  => 0x8086,
71                devid   => 0x2413,
72                procid  => "Intel 82801AA ICH",
73                driver  => "i2c-i801",
74        }, {
75                vendid  => 0x8086,
76                devid   => 0x2423,
77                procid  => "Intel 82801AB ICH0",
78                driver  => "i2c-i801",
79        }, {
80                vendid  => 0x8086,
81                devid   => 0x2443,
82                procid  => "Intel 82801BA ICH2",
83                driver  => "i2c-i801",
84        }, {
85                vendid  => 0x8086,
86                devid   => 0x2483,
87                procid  => "Intel 82801CA/CAM ICH3",
88                driver  => "i2c-i801",
89        }, {
90                vendid  => 0x8086,
91                devid   => 0x24C3,
92                procid  => "Intel 82801DB ICH4",
93                driver  => "i2c-i801",
94        }, {
95                vendid  => 0x8086,
96                devid   => 0x24D3,
97                procid  => "Intel 82801EB ICH5",
98                driver  => "i2c-i801",
99        }, {
100                vendid  => 0x8086,
101                devid   => 0x25A4,
102                procid  => "Intel 6300ESB",
103                driver  => "i2c-i801",
104        }, {
105                vendid  => 0x8086,
106                devid   => 0x269B,
107                procid  => "Intel Enterprise Southbridge - ESB2",
108                driver  => "i2c-i801",
109        }, {
110                vendid  => 0x8086,
111                devid   => 0x266A,
112                procid  => "Intel 82801FB ICH6",
113                driver  => "i2c-i801",
114        }, {
115                vendid  => 0x8086,
116                devid   => 0x27DA,
117                procid  => "Intel 82801G ICH7",
118                driver  => "i2c-i801",
119        }, {
120                vendid  => 0x8086,
121                devid   => 0x283E,
122                procid  => "Intel 82801H ICH8",
123                driver  => "i2c-i801",
124        }, {
125                vendid  => 0x8086,
126                devid   => 0x2930,
127                procid  => "Intel ICH9",
128                driver  => "i2c-i801",
129        }, {
130                vendid  => 0x8086,
131                devid   => 0x5032,
132                procid  => "Intel Tolapai",
133                driver  => "i2c-i801",
134        }, {
135                vendid  => 0x8086,
136                devid   => 0x3A30,
137                procid  => "Intel ICH10",
138                driver  => "i2c-i801",
139        }, {
140                vendid  => 0x8086,
141                devid   => 0x3A60,
142                procid  => "Intel ICH10",
143                driver  => "i2c-i801",
144        }, {
145                vendid  => 0x8086,
146                devid   => 0x3B30,
147                procid  => "Intel 3400/5 Series (PCH)",
148                driver  => "i2c-i801",
149        }, {
150                vendid  => 0x8086,
151                devid   => 0x1C22,
152                procid  => "Intel Cougar Point (PCH)",
153                driver  => "i2c-i801",
154        }, {
155                vendid  => 0x8086,
156                devid   => 0x1D22,
157                procid  => "Intel Patsburg (PCH)",
158                driver  => "i2c-i801",
159        }, {
160                vendid  => 0x8086,
161                devid   => 0x2330,
162                procid  => "Intel DH89xxCC (PCH)",
163                driver  => "i2c-i801",
164        }, {
165                vendid  => 0x8086,
166                devid   => 0x1E22,
167                procid  => "Intel Panther Point (PCH)",
168                driver  => "i2c-i801",
169        }, {
170                vendid  => 0x8086,
171                devid   => 0x8C22,
172                procid  => "Intel Lynx Point (PCH)",
173                driver  => "i2c-i801",
174        }, {
175                vendid  => 0x8086,
176                devid   => 0x8119,
177                procid  => "Intel SCH",
178                driver  => "i2c-isch",
179        }, {
180                vendid  => 0x1106,
181                devid   => 0x3040,
182                procid  => "VIA Technologies VT82C586B Apollo ACPI",
183                driver  => "i2c-via",
184        }, {
185                vendid  => 0x1106,
186                devid   => 0x3050,
187                procid  => "VIA Technologies VT82C596 Apollo ACPI",
188                driver  => "i2c-viapro",
189        }, {
190                vendid  => 0x1106,
191                devid   => 0x3051,
192                procid  => "VIA Technologies VT82C596B ACPI",
193                driver  => "i2c-viapro",
194        }, {
195                vendid  => 0x1106,
196                devid   => 0x3057,
197                procid  => "VIA Technologies VT82C686 Apollo ACPI",
198                driver  => "i2c-viapro",
199        }, {
200                vendid  => 0x1106,
201                devid   => 0x3074,
202                procid  => "VIA Technologies VT8233 VLink South Bridge",
203                driver  => "i2c-viapro",
204        }, {
205                vendid  => 0x1106,
206                devid   => 0x3147,
207                procid  => "VIA Technologies VT8233A South Bridge",
208                driver  => "i2c-viapro",
209        }, {
210                vendid  => 0x1106,
211                devid   => 0x3177,
212                procid  => "VIA Technologies VT8233A/8235 South Bridge",
213                driver  => "i2c-viapro",
214        }, {
215                vendid  => 0x1106,
216                devid   => 0x3227,
217                procid  => "VIA Technologies VT8237 South Bridge",
218                driver  => "i2c-viapro",
219        }, {
220                vendid  => 0x1106,
221                devid   => 0x3337,
222                procid  => "VIA Technologies VT8237A South Bridge",
223                driver  => "i2c-viapro",
224        }, {
225                vendid  => 0x1106,
226                devid   => 0x8235,
227                procid  => "VIA Technologies VT8231 South Bridge",
228                driver  => "i2c-viapro",
229        }, {
230                vendid  => 0x1106,
231                devid   => 0x3287,
232                procid  => "VIA Technologies VT8251 South Bridge",
233                driver  => "i2c-viapro",
234        }, {
235                vendid  => 0x1106,
236                devid   => 0x8324,
237                procid  => "VIA Technologies CX700 South Bridge",
238                driver  => "i2c-viapro",
239        }, {
240                vendid  => 0x1106,
241                devid   => 0x8353,
242                procid  => "VIA Technologies VX800/VX820 South Bridge",
243                driver  => "i2c-viapro",
244        }, {
245                vendid  => 0x1039,
246                devid   => 0x0008,
247                procid  => "Silicon Integrated Systems SIS5595",
248                driver  => "i2c-sis5595",
249        }, {
250                vendid  => 0x1039,
251                devid   => 0x0630,
252                procid  => "Silicon Integrated Systems SIS630",
253                driver  => "i2c-sis630",
254        }, {
255                vendid  => 0x1039,
256                devid   => 0x0730,
257                procid  => "Silicon Integrated Systems SIS730",
258                driver  => "i2c-sis630",
259        }, {
260                vendid  => 0x1039,
261                devid   => 0x0016,
262                procid  => "Silicon Integrated Systems SMBus Controller",
263                driver  => "i2c-sis96x",
264        }, {
265                # Both Ali chips below have same PCI ID. Can't be helped. Only one should load.
266                vendid  => 0x10b9,
267                devid   => 0x7101,
268                procid  => "Acer Labs 1533/1543",
269                driver  => "i2c-ali15x3",
270        }, {
271                vendid  => 0x10b9,
272                devid   => 0x7101,
273                procid  => "Acer Labs 1535",
274                driver  => "i2c-ali1535",
275        }, {
276                vendid  => 0x10b9,
277                devid   => 0x1563,
278                procid  => "Acer Labs 1563",
279                driver  => "i2c-ali1563",
280        }, {
281                vendid  => 0x1022,
282                devid   => 0x740b,
283                procid  => "AMD-756 Athlon ACPI",
284                driver  => "i2c-amd756",
285        }, {
286                vendid  => 0x1022,
287                devid   => 0x7413,
288                procid  => "AMD-766 Athlon ACPI",
289                driver  => "i2c-amd756",
290        }, {
291                vendid  => 0x1022,
292                devid   => 0x7443,
293                procid  => "AMD-768 System Management",
294                driver  => "i2c-amd756",
295        }, {
296                vendid  => 0x1022,
297                devid   => 0x746b,
298                procid  => "AMD-8111 ACPI",
299                driver  => "i2c-amd756",
300        }, {
301                vendid  => 0x1022,
302                devid   => 0x746a,
303                procid  => "AMD-8111 SMBus 2.0",
304                driver  => "i2c-amd8111",
305        }, {
306                vendid  => 0x10de,
307                devid   => 0x01b4,
308                procid  => "nVidia nForce SMBus",
309                driver  => "i2c-amd756",
310        }, {
311                vendid  => 0x10de,
312                devid   => 0x0064,
313                procid  => "nVidia Corporation nForce2 SMBus (MCP)",
314                driver  => "i2c-nforce2",
315        }, {
316                vendid  => 0x10de,
317                devid   => 0x0084,
318                procid  => "nVidia Corporation nForce2 Ultra 400 SMBus (MCP)",
319                driver  => "i2c-nforce2",
320        }, {
321                vendid  => 0x10de,
322                devid   => 0x00D4,
323                procid  => "nVidia Corporation nForce3 Pro150 SMBus (MCP)",
324                driver  => "i2c-nforce2",
325        }, {
326                vendid  => 0x10de,
327                devid   => 0x00E4,
328                procid  => "nVidia Corporation nForce3 250Gb SMBus (MCP)",
329                driver  => "i2c-nforce2",
330        }, {
331                vendid  => 0x10de,
332                devid   => 0x0052,
333                procid  => "nVidia Corporation nForce4 SMBus (MCP)",
334                driver  => "i2c-nforce2",
335        }, {
336                vendid  => 0x10de,
337                devid   => 0x0034,
338                procid  => "nVidia Corporation nForce4 SMBus (MCP-04)",
339                driver  => "i2c-nforce2",
340        }, {
341                vendid  => 0x10de,
342                devid   => 0x0264,
343                procid  => "nVidia Corporation nForce SMBus (MCP51)",
344                driver  => "i2c-nforce2",
345        }, {
346                vendid  => 0x10de,
347                devid   => 0x0368,
348                procid  => "nVidia Corporation nForce SMBus (MCP55)",
349                driver  => "i2c-nforce2",
350        }, {
351                vendid  => 0x10de,
352                devid   => 0x03eb,
353                procid  => "nVidia Corporation nForce SMBus (MCP61)",
354                driver  => "i2c-nforce2",
355        }, {
356                vendid  => 0x10de,
357                devid   => 0x0446,
358                procid  => "nVidia Corporation nForce SMBus (MCP65)",
359                driver  => "i2c-nforce2",
360        }, {
361                vendid  => 0x10de,
362                devid   => 0x0542,
363                procid  => "nVidia Corporation nForce SMBus (MCP67)",
364                driver  => "i2c-nforce2",
365        }, {
366                vendid  => 0x10de,
367                devid   => 0x07d8,
368                procid  => "nVidia Corporation nForce SMBus (MCP73)",
369                driver  => "i2c-nforce2",
370        }, {
371                vendid  => 0x10de,
372                devid   => 0x0752,
373                procid  => "nVidia Corporation nForce SMBus (MCP78S)",
374                driver  => "i2c-nforce2",
375        }, {
376                vendid  => 0x10de,
377                devid   => 0x0aa2,
378                procid  => "nVidia Corporation nForce SMBus (MCP79)",
379                driver  => "i2c-nforce2",
380        }, {
381                vendid  => 0x1166,
382                devid   => 0x0200,
383                procid  => "ServerWorks OSB4 South Bridge",
384                driver  => "i2c-piix4",
385        }, {
386                vendid  => 0x1055,
387                devid   => 0x9463,
388                procid  => "SMSC Victory66 South Bridge",
389                driver  => "i2c-piix4",
390        }, {
391                vendid  => 0x1166,
392                devid   => 0x0201,
393                procid  => "ServerWorks CSB5 South Bridge",
394                driver  => "i2c-piix4",
395        }, {
396                vendid  => 0x1166,
397                devid   => 0x0203,
398                procid  => "ServerWorks CSB6 South Bridge",
399                driver  => "i2c-piix4",
400        }, {
401                vendid  => 0x1166,
402                devid   => 0x0205,
403                procid  => "ServerWorks HT-1000 South Bridge",
404                driver  => "i2c-piix4",
405        }, {
406                vendid  => 0x1002,
407                devid   => 0x4353,
408                procid  => "ATI Technologies Inc ATI SMBus",
409                driver  => "i2c-piix4",
410        }, {
411                vendid  => 0x1002,
412                devid   => 0x4363,
413                procid  => "ATI Technologies Inc ATI SMBus",
414                driver  => "i2c-piix4",
415        }, {
416                vendid  => 0x1002,
417                devid   => 0x4372,
418                procid  => "ATI Technologies Inc IXP SB400 SMBus Controller",
419                driver  => "i2c-piix4",
420        }, {
421                vendid  => 0x1002,
422                devid   => 0x4385,
423                procid  => "ATI Technologies Inc SB600/SB700/SB800 SMBus",
424                driver  => "i2c-piix4",
425        }, {
426                vendid  => 0x1022,
427                devid   => 0x780b,
428                procid  => "AMD Hudson-2 SMBus",
429                driver  => "i2c-piix4",
430        }, {
431                vendid  => 0x100B,
432                devid   => 0x0500,
433                procid  => "SCx200 Bridge",
434                driver  => "scx200_acb",
435        }, {
436                vendid  => 0x100B,
437                devid   => 0x0510,
438                procid  => "SC1100 Bridge",
439                driver  => "scx200_acb",
440        }, {
441                vendid  => 0x100B,
442                devid   => 0x002B,
443                procid  => "CS5535 ISA bridge",
444                driver  => "scx200_acb",
445        }, {
446                vendid  => 0x1022,
447                devid   => 0x2090,
448                procid  => "CS5536 [Geode companion] ISA",
449                driver  => "scx200_acb",
450        }
451);
452
453# Look-up table to find out an I2C bus' driver based on the bus name.
454# The match field should contain a regular expression matching the I2C
455# bus name as it would appear in sysfs.
456# Note that new drivers probably don't need to be added to this table
457# if they bind to their device, as we will be able to get the driver name
458# from sysfs directly.
459use vars qw(@i2c_adapter_names);
460@i2c_adapter_names = (
461        { driver => "i2c-piix4",        match => qr/^SMBus PIIX4 adapter at / },
462        { driver => "i2c-i801",         match => qr/^SMBus I801 adapter at / },
463        { driver => "i2c-via",          match => qr/^VIA i2c/ },
464        { driver => "i2c-viapro",       match => qr/^SMBus V(IA|ia) Pro adapter at / },
465        { driver => "i2c-sis5595",      match => qr/^SMBus SIS5595 adapter at / },
466        { driver => "i2c-sis630",       match => qr/^SMBus SIS630 adapter at / },
467        { driver => "i2c-sis96x",       match => qr/^SiS96x SMBus adapter at / },
468        { driver => "i2c-ali15x3",      match => qr/^SMBus ALI15X3 adapter at / },
469        { driver => "i2c-ali1535",      match => qr/^SMBus ALI1535 adapter at/ },
470        { driver => "i2c-ali1563",      match => qr/^SMBus ALi 1563 Adapter @ / },
471        { driver => "i2c-amd756",       match => qr/^SMBus (AMD756|AMD766|AMD768|AMD8111|nVidia nForce) adapter at / },
472        { driver => "i2c-amd8111",      match => qr/^SMBus2 AMD8111 adapter at / },
473        { driver => "i2c-nforce2",      match => qr/^SMBus nForce2 adapter at / },
474        { driver => "scx200_acb",       match => qr/^(NatSemi SCx200 ACCESS\.bus|SCx200 ACB\d+|CS553[56] ACB\d+)/ },
475);
476
477# This is a list of all recognized I2C and ISA chips.
478# Each entry must have the following fields:
479#  name: The full chip name
480#  driver: The driver name. Put in exactly:
481#      * "to-be-written" if it is not yet available
482#      * "use-isa-instead" if no i2c driver will be written
483#  i2c_addrs (optional): For I2C chips, the list of I2C addresses to
484#      probe.
485#  i2c_detect (optional): For I2C chips, the function to call to detect
486#      this chip. The function will be passed two parameters: an open file
487#      descriptor to access the bus, and the I2C address to probe.
488#  isa_addrs (optional): For ISA chips, the list of port addresses to
489#      probe.
490#  isa_detect (optional): For ISA chips, the function to call to detect
491#      this chip. The function will be passed one parameter: the ISA address
492#      to probe.
493#  alias_detect (optional): For chips which can be both on the ISA and the
494#      I2C bus, a function which detects whether two entries are the same.
495#      The function will be passed three parameters: the ISA address, an
496#      open file descriptor to access the I2C bus, and the I2C address.
497@chip_ids = (
498        {
499                name => "Myson MTP008",
500                driver => "mtp008",
501                i2c_addrs => [0x2c..0x2e],
502                i2c_detect => sub { mtp008_detect(@_); },
503        }, {
504                name => "National Semiconductor LM78",
505                driver => "lm78",
506                i2c_addrs => [0x28..0x2f],
507                i2c_detect => sub { lm78_detect(@_, 0); },
508                isa_addrs => [0x290],
509                isa_detect => sub { lm78_isa_detect(@_, 0); },
510                alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
511        }, {
512                name => "National Semiconductor LM79",
513                driver => "lm78",
514                i2c_addrs => [0x28..0x2f],
515                i2c_detect => sub { lm78_detect(@_, 2); },
516                isa_addrs => [0x290],
517                isa_detect => sub { lm78_isa_detect(@_, 2); },
518                alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
519        }, {
520                name => "National Semiconductor LM75",
521                driver => "lm75",
522                i2c_addrs => [0x48..0x4f],
523                i2c_detect => sub { lm75_detect(@_, 0); },
524        }, {
525                name => "National Semiconductor LM75A",
526                driver => "lm75",
527                i2c_addrs => [0x48..0x4f],
528                i2c_detect => sub { lm75_detect(@_, 2); },
529        }, {
530                name => "Dallas Semiconductor DS75",
531                driver => "lm75",
532                i2c_addrs => [0x48..0x4f],
533                i2c_detect => sub { lm75_detect(@_, 1); },
534        }, {
535                name => "National Semiconductor LM77",
536                driver => "lm77",
537                i2c_addrs => [0x48..0x4b],
538                i2c_detect => sub { lm77_detect(@_); },
539        }, {
540                name => "National Semiconductor LM80",
541                driver => "lm80",
542                i2c_addrs => [0x28..0x2f],
543                i2c_detect => sub { lm80_detect(@_, 0); },
544        }, {
545                name => "National Semiconductor LM96080",
546                driver => "lm80",
547                i2c_addrs => [0x28..0x2f],
548                i2c_detect => sub { lm80_detect(@_, 1); },
549        }, {
550                name => "National Semiconductor LM85",
551                driver => "lm85",
552                i2c_addrs => [0x2c..0x2e],
553                i2c_detect => sub { lm85_detect(@_, 0); },
554        }, {
555                name => "National Semiconductor LM96000 or PC8374L",
556                driver => "lm85",
557                i2c_addrs => [0x2c..0x2e],
558                i2c_detect => sub { lm85_detect(@_, 1); },
559        }, {
560                name => "Analog Devices ADM1027",
561                driver => "lm85",
562                i2c_addrs => [0x2c..0x2e],
563                i2c_detect => sub { lm85_detect(@_, 2); },
564        }, {
565                name => "Analog Devices ADT7460 or ADT7463",
566                driver => "lm85",
567                i2c_addrs => [0x2c..0x2e],
568                i2c_detect => sub { lm85_detect(@_, 3); },
569        }, {
570                name => "SMSC EMC6D100 or EMC6D101",
571                driver => "lm85",
572                i2c_addrs => [0x2c..0x2e],
573                i2c_detect => sub { lm85_detect(@_, 4); },
574        }, {
575                name => "SMSC EMC6D102",
576                driver => "lm85",
577                i2c_addrs => [0x2c..0x2e],
578                i2c_detect => sub { lm85_detect(@_, 5); },
579        }, {
580                name => "SMSC EMC6D103",
581                driver => "lm85",
582                i2c_addrs => [0x2c..0x2e],
583                i2c_detect => sub { lm85_detect(@_, 6); },
584        }, {
585                name => "SMSC EMC6D103S or EMC2300",
586                driver => "lm85",
587                i2c_addrs => [0x2c..0x2e],
588                i2c_detect => sub { lm85_detect(@_, 8); },
589        }, {
590                name => "SMSC EMC6W201",
591                driver => "emc6w201",
592                i2c_addrs => [0x2c..0x2e],
593                i2c_detect => sub { emc6w201_detect(@_); },
594        }, {
595                name => "Winbond WPCD377I",
596                driver => "not-a-sensor",
597                i2c_addrs => [0x2c..0x2e],
598                i2c_detect => sub { lm85_detect(@_, 7); },
599        }, {
600                name => "Analog Devices ADT7462",
601                driver => "adt7462",
602                i2c_addrs => [0x5c, 0x58],
603                i2c_detect => sub { adt7467_detect(@_, 2); },
604        }, {
605                name => "Analog Devices ADT7466",
606                driver => "to-be-written",
607                i2c_addrs => [0x4c],
608                i2c_detect => sub { adt7467_detect(@_, 3); },
609        }, {
610                name => "Analog Devices ADT7467 or ADT7468",
611                driver => "lm85",
612                i2c_addrs => [0x2e],
613                i2c_detect => sub { adt7467_detect(@_, 0); },
614        }, {
615                name => "Analog Devices ADT7470",
616                driver => "adt7470",
617                i2c_addrs => [0x2c, 0x2e, 0x2f],
618                i2c_detect => sub { adt7467_detect(@_, 4); },
619        }, {
620                name => "Analog Devices ADT7473",
621                driver => sub { kernel_version_at_least(2, 6, 33) ? "adt7475" : "adt7473" },
622                i2c_addrs => [0x2c..0x2e],
623                i2c_detect => sub { adt7473_detect(@_, 0); },
624        }, {
625                name => "Analog Devices ADT7475",
626                driver => "adt7475",
627                i2c_addrs => [0x2e],
628                i2c_detect => sub { adt7473_detect(@_, 1); },
629        }, {
630                name => "Analog Devices ADT7476",
631                driver => "adt7475",
632                i2c_addrs => [0x2c..0x2e],
633                i2c_detect => sub { adt7467_detect(@_, 1); },
634        }, {
635                name => "Analog Devices ADT7490",
636                driver => "adt7475",
637                i2c_addrs => [0x2c..0x2e],
638                i2c_detect => sub { adt7490_detect(@_); },
639        }, {
640                name => "Analog Devices ADT7410",
641                driver => "to-be-written",
642                i2c_addrs => [0x48..0x4b],
643                i2c_detect => sub { adt7410_detect(@_); },
644        }, {
645                name => "Analog Devices ADT7411",
646                driver => "adt7411",
647                i2c_addrs => [0x48, 0x4a, 0x4b],
648                i2c_detect => sub { adt7411_detect(@_); },
649        }, {
650                name => "Andigilog aSC7511",
651                driver => "to-be-written",
652                i2c_addrs => [0x4c],
653                i2c_detect => sub { andigilog_aSC7511_detect(@_); },
654        }, {
655                name => "Andigilog aSC7512",
656                driver => "to-be-written",
657                i2c_addrs => [0x58],
658                i2c_detect => sub { andigilog_detect(@_, 0); },
659        }, {
660                name => "Andigilog aSC7611",
661                driver => "to-be-written",
662                i2c_addrs => [0x2c..0x2e],
663                i2c_detect => sub { andigilog_detect(@_, 1); },
664        }, {
665                name => "Andigilog aSC7621",
666                driver => "asc7621",
667                i2c_addrs => [0x2c..0x2e],
668                i2c_detect => sub { andigilog_detect(@_, 2); },
669        }, {
670                name => "National Semiconductor LM87",
671                driver => "lm87",
672                i2c_addrs => [0x2c..0x2e],
673                i2c_detect => sub { lm87_detect(@_, 0); },
674        }, {
675                name => "Analog Devices ADM1024",
676                driver => "lm87",
677                i2c_addrs => [0x2c..0x2e],
678                i2c_detect => sub { lm87_detect(@_, 1); },
679        }, {
680                name => "National Semiconductor LM93",
681                driver => "lm93",
682                i2c_addrs => [0x2c..0x2e],
683                i2c_detect => sub { lm93_detect(@_, 0); },
684        }, {
685                name => "National Semiconductor LM94 or LM96194",
686                driver => "lm93",
687                i2c_addrs => [0x2c..0x2e],
688                i2c_detect => sub { lm93_detect(@_, 1); },
689        }, {
690                name => "Winbond W83781D",
691                driver => "w83781d",
692                i2c_addrs => [0x28..0x2f],
693                i2c_detect => sub { w83781d_detect(@_, 0); },
694                isa_addrs => [0x290],
695                isa_detect => sub { w83781d_isa_detect(@_, 0); },
696                alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
697        }, {
698                name => "Winbond W83782D",
699                driver => "w83781d",
700                i2c_addrs => [0x28..0x2f],
701                i2c_detect => sub { w83781d_detect(@_, 1); },
702                isa_addrs => [0x290],
703                isa_detect => sub { w83781d_isa_detect(@_, 1); },
704                alias_detect => sub { winbond_alias_detect(@_, 0x2b, 0x3d); },
705        }, {
706                name => "Winbond W83783S",
707                driver => "w83781d",
708                i2c_addrs => [0x2d],
709                i2c_detect => sub { w83781d_detect(@_, 2); },
710        }, {
711                name => "Winbond W83791D",
712                driver => "w83791d",
713                i2c_addrs => [0x2c..0x2f],
714                i2c_detect => sub { w83781d_detect(@_, 7); },
715        }, {
716                name => "Winbond W83792D",
717                driver => "w83792d",
718                i2c_addrs => [0x2c..0x2f],
719                i2c_detect => sub { w83781d_detect(@_, 8); },
720        }, {
721                name => "Winbond W83793R/G",
722                driver => "w83793",
723                i2c_addrs => [0x2c..0x2f],
724                i2c_detect => sub { w83793_detect(@_); },
725        }, {
726                name => "Nuvoton W83795G/ADG",
727                driver => "w83795",
728                i2c_addrs => [0x2c..0x2f],
729                i2c_detect => sub { w83795_detect(@_); },
730        }, {
731                name => "Winbond W83627HF",
732                driver => "use-isa-instead",
733                i2c_addrs => [0x28..0x2f],
734                i2c_detect => sub { w83781d_detect(@_, 3); },
735        }, {
736                name => "Winbond W83627EHF",
737                driver => "use-isa-instead",
738                i2c_addrs => [0x28..0x2f],
739                i2c_detect => sub { w83781d_detect(@_, 9); },
740        }, {
741                name => "Winbond W83627DHG/W83667HG/W83677HG",
742                driver => "use-isa-instead",
743                i2c_addrs => [0x28..0x2f],
744                i2c_detect => sub { w83781d_detect(@_, 10); },
745        }, {
746                name => "Asus AS99127F (rev.1)",
747                driver => "w83781d",
748                i2c_addrs => [0x28..0x2f],
749                i2c_detect => sub { w83781d_detect(@_, 4); },
750        }, {
751                name => "Asus AS99127F (rev.2)",
752                driver => "w83781d",
753                i2c_addrs => [0x28..0x2f],
754                i2c_detect => sub { w83781d_detect(@_, 5); },
755        }, {
756                name => "Asus ASB100 Bach",
757                driver => "asb100",
758                i2c_addrs => [0x28..0x2f],
759                i2c_detect => sub { w83781d_detect(@_, 6); },
760        }, {
761                name => "Asus Mozart-2",
762                driver => "to-be-written",
763                i2c_addrs => [0x77],
764                i2c_detect => sub { mozart_detect(@_); },
765        }, {
766                name => "Winbond W83L784R/AR/G",
767                driver => "to-be-written",
768                i2c_addrs => [0x2d],
769                i2c_detect => sub { w83l784r_detect(@_, 0); },
770        }, {
771                name => "Winbond W83L785R/G",
772                driver => "to-be-written",
773                i2c_addrs => [0x2d],
774                i2c_detect => sub { w83l784r_detect(@_, 1); },
775        }, {
776                name => "Winbond W83L786NR/NG/R/G",
777                driver => "w83l786ng",
778                i2c_addrs => [0x2e, 0x2f],
779                i2c_detect => sub { w83l784r_detect(@_, 2); },
780        }, {
781                name => "Winbond W83L785TS-S",
782                driver => "w83l785ts",
783                i2c_addrs => [0x2e],
784                i2c_detect => sub { w83l784r_detect(@_, 3); },
785        }, {
786                name => "Genesys Logic GL518SM",
787                driver => "gl518sm",
788                i2c_addrs => [0x2c, 0x2d],
789                i2c_detect => sub { gl518sm_detect(@_, 0); },
790        }, {
791                name => "Genesys Logic GL520SM",
792                driver => "gl520sm",
793                i2c_addrs => [0x2c, 0x2d],
794                i2c_detect => sub { gl518sm_detect(@_, 1); },
795        }, {
796                name => "Genesys Logic GL525SM",
797                driver => "to-be-written",
798                i2c_addrs => [0x2d],
799                i2c_detect => sub { gl525sm_detect(@_); },
800        }, {
801                name => "Analog Devices ADM9240",
802                driver => "adm9240",
803                i2c_addrs => [0x2c..0x2f],
804                i2c_detect => sub { adm9240_detect(@_, 0); },
805        }, {
806                name => "Dallas Semiconductor DS1621/DS1631",
807                driver => "ds1621",
808                i2c_addrs => [0x48..0x4f],
809                i2c_detect => sub { ds1621_detect(@_); },
810        }, {
811                name => "Dallas Semiconductor DS1780",
812                driver => "adm9240",
813                i2c_addrs => [0x2c..0x2f],
814                i2c_detect => sub { adm9240_detect(@_, 1); },
815        }, {
816                name => "National Semiconductor LM81",
817                driver => "adm9240",
818                i2c_addrs => [0x2c..0x2f],
819                i2c_detect => sub { adm9240_detect(@_, 2); },
820        }, {
821                name => "Analog Devices ADM1026",
822                driver => "adm1026",
823                i2c_addrs => [0x2c..0x2e],
824                i2c_detect => sub { adm1026_detect(@_); },
825        }, {
826                name => "Analog Devices ADM1025",
827                driver => "adm1025",
828                i2c_addrs => [0x2c..0x2e],
829                i2c_detect => sub { adm1025_detect(@_, 0); },
830        }, {
831                name => "Philips NE1619",
832                driver => "adm1025",
833                i2c_addrs => [0x2c..0x2d],
834                i2c_detect => sub { adm1025_detect(@_, 1); },
835        }, {
836                name => "Analog Devices ADM1021",
837                driver => "adm1021",
838                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
839                i2c_detect => sub { adm1021_detect(@_, 0); },
840        }, {
841                name => "Analog Devices ADM1021A/ADM1023",
842                driver => "adm1021",
843                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
844                i2c_detect => sub { adm1021_detect(@_, 1); },
845        }, {
846                name => "Global Mixed-mode Technology G781",
847                driver => "lm90",
848                i2c_addrs => [0x4c, 0x4d],
849                i2c_detect => sub { lm90_detect(@_, 15); },
850        }, {
851                name => "Maxim MAX1617",
852                driver => "adm1021",
853                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
854                i2c_detect => sub { adm1021_detect(@_, 2); },
855        }, {
856                name => "Maxim MAX1617A",
857                driver => "adm1021",
858                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
859                i2c_detect => sub { adm1021_detect(@_, 3); },
860        }, {
861                name => "Maxim MAX1668",
862                driver => "max1668",
863                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
864                i2c_detect => sub { max1668_detect(@_, 0); },
865        }, {
866                name => "Maxim MAX1805",
867                driver => "max1668",
868                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
869                i2c_detect => sub { max1668_detect(@_, 1); },
870        }, {
871                name => "Maxim MAX1989",
872                driver => "max1668",
873                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
874                i2c_detect => sub { max1668_detect(@_, 2); },
875        }, {
876                name => "Maxim MAX6639",
877                driver => "max6639",
878                i2c_addrs => [0x2c, 0x2e, 0x2f],
879                i2c_detect => sub { max6639_detect(@_); },
880        }, {
881                name => "Maxim MAX6642",
882                driver => "max6642",
883                i2c_addrs => [0x48..0x4f],
884                i2c_detect => sub { max6642_detect(@_); },
885        }, {
886                name => "Maxim MAX6655/MAX6656",
887                driver => "max6655",
888                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
889                i2c_detect => sub { max6655_detect(@_); },
890        }, {
891                name => "TI THMC10",
892                driver => "adm1021",
893                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
894                i2c_detect => sub { adm1021_detect(@_, 4); },
895        }, {
896                name => "National Semiconductor LM84",
897                driver => "adm1021",
898                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
899                i2c_detect => sub { adm1021_detect(@_, 5); },
900        }, {
901                name => "Genesys Logic GL523SM",
902                driver => "adm1021",
903                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
904                i2c_detect => sub { adm1021_detect(@_, 6); },
905        }, {
906                name => "Onsemi MC1066",
907                driver => "adm1021",
908                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
909                i2c_detect => sub { adm1021_detect(@_, 7); },
910        }, {
911                name => "Maxim MAX1618",
912                driver => "max1619",
913                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
914                i2c_detect => sub { max1619_detect(@_, 1); },
915        }, {
916                name => "Maxim MAX1619",
917                driver => "max1619",
918                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
919                i2c_detect => sub { max1619_detect(@_, 0); },
920        }, {
921                name => "National Semiconductor LM82/LM83",
922                driver => "lm83",
923                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
924                i2c_detect => sub { lm83_detect(@_); },
925        }, {
926                name => "National Semiconductor LM90",
927                driver => "lm90",
928                i2c_addrs => [0x4c],
929                i2c_detect => sub { lm90_detect(@_, 0); },
930        }, {
931                name => "National Semiconductor LM89/LM99",
932                driver => "lm90",
933                i2c_addrs => [0x4c..0x4d],
934                i2c_detect => sub { lm90_detect(@_, 1); },
935        }, {
936                name => "National Semiconductor LM86",
937                driver => "lm90",
938                i2c_addrs => [0x4c],
939                i2c_detect => sub { lm90_detect(@_, 2); },
940        }, {
941                name => "Analog Devices ADM1032",
942                driver => "lm90",
943                i2c_addrs => [0x4c..0x4d],
944                i2c_detect => sub { lm90_detect(@_, 3); },
945        }, {
946                name => "Maxim MAX6654",
947                driver => "to-be-written", # probably lm90
948                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
949                i2c_detect => sub { lm90_detect(@_, 4); },
950        }, {
951                name => "Maxim MAX6690",
952                driver => "to-be-written", # probably lm90
953                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
954                i2c_detect => sub { lm90_detect(@_, 12); },
955        }, {
956                name => "Maxim MAX6657/MAX6658/MAX6659",
957                driver => "lm90",
958                i2c_addrs => [0x4c],
959                i2c_detect => sub { max6657_detect(@_); },
960        }, {
961                name => "Maxim MAX6659",
962                driver => "lm90",
963                i2c_addrs => [0x4d..0x4e], # 0x4c is handled above
964                i2c_detect => sub { max6657_detect(@_); },
965        }, {
966                name => "Maxim MAX6646",
967                driver => "lm90",
968                i2c_addrs => [0x4d],
969                i2c_detect => sub { lm90_detect(@_, 6); },
970        }, {
971                name => "Maxim MAX6647",
972                driver => "lm90",
973                i2c_addrs => [0x4e],
974                i2c_detect => sub { lm90_detect(@_, 6); },
975        }, {
976                name => "Maxim MAX6648/MAX6649/MAX6692",
977                driver => "lm90",
978                i2c_addrs => [0x4c],
979                i2c_detect => sub { lm90_detect(@_, 6); },
980        }, {
981                name => "Maxim MAX6680/MAX6681",
982                driver => "lm90",
983                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
984                i2c_detect => sub { max6680_95_detect(@_, 0); },
985        }, {
986                name => "Maxim MAX6695/MAX6696",
987                driver => "lm90",
988                i2c_addrs => [0x18..0x1a, 0x29..0x2b, 0x4c..0x4e],
989                i2c_detect => sub { max6680_95_detect(@_, 1); },
990        }, {
991                name => "Winbond W83L771W/G",
992                driver => "lm90",
993                i2c_addrs => [0x4c],
994                i2c_detect => sub { lm90_detect(@_, 8); },
995        }, {
996                name => "Winbond W83L771AWG/ASG",
997                driver => "lm90",
998                i2c_addrs => [0x4c],
999                i2c_detect => sub { lm90_detect(@_, 11); },
1000        }, {
1001                name => "Texas Instruments TMP401",
1002                driver => "tmp401",
1003                i2c_addrs => [0x4c],
1004                i2c_detect => sub { lm90_detect(@_, 9); },
1005        }, {
1006                name => "Texas Instruments TMP411",
1007                driver => "tmp401",
1008                i2c_addrs => [0x4c..0x4e],
1009                i2c_detect => sub { lm90_detect(@_, 10); },
1010        }, {
1011                name => "Texas Instruments TMP421",
1012                driver => "tmp421",
1013                i2c_addrs => [0x1c..0x1f, 0x2a, 0x4c..0x4f],
1014                i2c_detect => sub { tmp42x_detect(@_, 0); },
1015        }, {
1016                name => "Texas Instruments TMP422",
1017                driver => "tmp421",
1018                i2c_addrs => [0x4c..0x4f],
1019                i2c_detect => sub { tmp42x_detect(@_, 1); },
1020        }, {
1021                name => "Texas Instruments TMP423",
1022                driver => "tmp421",
1023                i2c_addrs => [0x4c, 0x4d],
1024                i2c_detect => sub { tmp42x_detect(@_, 2); },
1025        }, {
1026                name => "Texas Instruments AMC6821",
1027                driver => "amc6821",
1028                i2c_addrs => [0x18..0x1a, 0x2c..0x2e, 0x4c..0x4e],
1029                i2c_detect => sub { amc6821_detect(@_); },
1030        }, {
1031                name => "National Semiconductor LM95231",
1032                driver => "lm95241",
1033                i2c_addrs => [0x2b, 0x19, 0x2a],
1034                i2c_detect => sub { lm95231_detect(@_, 0); },
1035        }, {
1036                name => "National Semiconductor LM95241",
1037                driver => "lm95241",
1038                i2c_addrs => [0x2b, 0x19, 0x2a],
1039                i2c_detect => sub { lm95231_detect(@_, 1); },
1040        }, {
1041                name => "National Semiconductor LM95245",
1042                driver => "lm95245",
1043                i2c_addrs => [0x18, 0x19, 0x29, 0x4c, 0x4d],
1044                i2c_detect => sub { lm95231_detect(@_, 2); },
1045        }, {
1046                name => "National Semiconductor LM63",
1047                driver => "lm63",
1048                i2c_addrs => [0x4c],
1049                i2c_detect => sub { lm63_detect(@_, 1); },
1050        }, {
1051                name => "National Semiconductor LM64",
1052                driver => "lm63",
1053                i2c_addrs => [0x18, 0x4e],
1054                i2c_detect => sub { lm63_detect(@_, 3); },
1055        }, {
1056                name => "National Semiconductor LM96163",
1057                driver => "lm63",
1058                i2c_addrs => [0x4c],
1059                i2c_detect => sub { lm63_detect(@_, 4); },
1060        }, {
1061                name => "Fintek F75363SG",
1062                driver => "lm63", # Not yet
1063                i2c_addrs => [0x4c],
1064                i2c_detect => sub { lm63_detect(@_, 2); },
1065        }, {
1066                name => "National Semiconductor LM73",
1067                driver => "lm73",
1068                i2c_addrs => [0x48..0x4a, 0x4c..0x4e],
1069                i2c_detect => sub { lm73_detect(@_); },
1070        }, {
1071                name => "National Semiconductor LM92",
1072                driver => "lm92",
1073                i2c_addrs => [0x48..0x4b],
1074                i2c_detect => sub { lm92_detect(@_, 0); },
1075        }, {
1076                name => "National Semiconductor LM76",
1077                driver => "lm92",
1078                i2c_addrs => [0x48..0x4b],
1079                i2c_detect => sub { lm92_detect(@_, 1); },
1080        }, {
1081                name => "Maxim MAX6633/MAX6634/MAX6635",
1082                driver => "lm92",
1083                i2c_addrs => [0x48..0x4f], # The MAX6633 can also use 0x40-0x47 but we
1084                                           # don't want to probe these addresses, it's
1085                                           # dangerous.
1086                i2c_detect => sub { lm92_detect(@_, 2); },
1087        }, {
1088                name => "Analog Devices ADT7461",
1089                driver => "lm90",
1090                i2c_addrs => [0x4c..0x4d],
1091                i2c_detect => sub { lm90_detect(@_, 5); },
1092        }, {
1093                name => "Analog Devices ADT7461A, ON Semiconductor NCT1008",
1094                driver => "lm90",
1095                i2c_addrs => [0x4c..0x4d],
1096                i2c_detect => sub { lm90_detect(@_, 13); },
1097        }, {
1098                name => "NXP/Philips SA56004",
1099                driver => "lm90",
1100                i2c_addrs => [0x48..0x4f],
1101                i2c_detect => sub { lm90_detect(@_, 14); },
1102        }, {
1103                name => "Analog Devices ADT7481",
1104                driver => "to-be-written",
1105                i2c_addrs => [0x4c, 0x4b],
1106                i2c_detect => sub { adt7481_detect(@_); },
1107        }, {
1108                name => "Analog Devices ADM1029",
1109                driver => "adm1029",
1110                i2c_addrs => [0x28..0x2f],
1111                i2c_detect => sub { adm1029_detect(@_); },
1112        }, {
1113                name => "Analog Devices ADM1030",
1114                driver => "adm1031",
1115                i2c_addrs => [0x2c..0x2e],
1116                i2c_detect => sub { adm1031_detect(@_, 0); },
1117        }, {
1118                name => "Analog Devices ADM1031",
1119                driver => "adm1031",
1120                i2c_addrs => [0x2c..0x2e],
1121                i2c_detect => sub { adm1031_detect(@_, 1); },
1122        }, {
1123                name => "Analog Devices ADM1033",
1124                driver => "to-be-written",
1125                i2c_addrs => [0x50..0x53],
1126                i2c_detect => sub { adm1034_detect(@_, 0); },
1127        }, {
1128                name => "Analog Devices ADM1034",
1129                driver => "to-be-written",
1130                i2c_addrs => [0x50..0x53],
1131                i2c_detect => sub { adm1034_detect(@_, 1); },
1132        }, {
1133                name => "Analog Devices ADM1022",
1134                driver => "thmc50",
1135                i2c_addrs => [0x2c..0x2e],
1136                i2c_detect => sub { adm1022_detect(@_, 0); },
1137        }, {
1138                name => "Texas Instruments THMC50",
1139                driver => "thmc50",
1140                i2c_addrs => [0x2c..0x2e],
1141                i2c_detect => sub { adm1022_detect(@_, 1); },
1142        }, {
1143                name => "Analog Devices ADM1028",
1144                driver => "thmc50",
1145                i2c_addrs => [0x2e],
1146                i2c_detect => sub { adm1022_detect(@_, 2); },
1147        }, {
1148                name => "Texas Instruments THMC51",
1149                driver => "to-be-written", # thmc50
1150                i2c_addrs => [0x2e], # At least (no datasheet)
1151                i2c_detect => sub { adm1022_detect(@_, 3); },
1152        }, {
1153                name => "VIA VT1211 (I2C)",
1154                driver => "use-isa-instead",
1155                i2c_addrs => [0x2d],
1156                i2c_detect => sub { vt1211_i2c_detect(@_); },
1157        }, {
1158                name => "ITE IT8712F",
1159                driver => "it87",
1160                i2c_addrs => [0x28..0x2f],
1161                i2c_detect => sub { it8712_i2c_detect(@_); },
1162        }, {
1163                name => "FSC Poseidon I",
1164                driver => sub { kernel_version_at_least(2, 6, 24) ? "fschmd" : "fscpos" },
1165                i2c_addrs => [0x73],
1166                i2c_detect => sub { fsc_detect(@_, 0); },
1167        }, {
1168                name => "FSC Poseidon II",
1169                driver => "to-be-written",
1170                i2c_addrs => [0x73],
1171                i2c_detect => sub { fsc_detect(@_, 1); },
1172        }, {
1173                name => "FSC Scylla",
1174                driver => "fschmd",
1175                i2c_addrs => [0x73],
1176                i2c_detect => sub { fsc_detect(@_, 2); },
1177        }, {
1178                name => "FSC Hermes",
1179                driver => sub { kernel_version_at_least(2, 6, 24) ? "fschmd" : "fscher" },
1180                i2c_addrs => [0x73],
1181                i2c_detect => sub { fsc_detect(@_, 3); },
1182        }, {
1183                name => "FSC Heimdal",
1184                driver => "fschmd",
1185                i2c_addrs => [0x73],
1186                i2c_detect => sub { fsc_detect(@_, 4); },
1187        }, {
1188                name => "FSC Heracles",
1189                driver => "fschmd",
1190                i2c_addrs => [0x73],
1191                i2c_detect => sub { fsc_detect(@_, 5); },
1192        }, {
1193                name => "FSC Hades",
1194                driver => "fschmd",
1195                i2c_addrs => [0x73],
1196                i2c_detect => sub { fsc_detect(@_, 6); },
1197        }, {
1198                name => "FSC Syleus",
1199                driver => "fschmd",
1200                i2c_addrs => [0x73],
1201                i2c_detect => sub { fsc_detect(@_, 7); },
1202        }, {
1203                name => "ALi M5879",
1204                driver => "to-be-written",
1205                i2c_addrs => [0x2c..0x2d],
1206                i2c_detect => sub { m5879_detect(@_); },
1207        }, {
1208                name => "SMSC LPC47M15x/192/292/997",
1209                driver => "smsc47m192",
1210                i2c_addrs => [0x2c..0x2d],
1211                i2c_detect => sub { smsc47m192_detect(@_); },
1212        }, {
1213                name => "SMSC DME1737",
1214                driver => "dme1737",
1215                i2c_addrs => [0x2c..0x2e],
1216                i2c_detect => sub { dme1737_detect(@_, 1); },
1217        }, {
1218                name => "SMSC SCH5027D-NW",
1219                driver => "dme1737",
1220                i2c_addrs => [0x2c..0x2e],
1221                i2c_detect => sub { dme1737_detect(@_, 2); },
1222        }, {
1223                name => "SMSC EMC2103",
1224                driver => "emc2103",
1225                i2c_addrs => [0x2e],
1226                i2c_detect => sub { emc1403_detect(@_, 2); },
1227        }, {
1228                name => "Fintek F75121R/F75122R/RG (VID+GPIO)",
1229                driver => "to-be-written",
1230                i2c_addrs => [0x4e], # 0x37 not probed
1231                i2c_detect => sub { fintek_detect(@_, 2); },
1232        }, {
1233                name => "Fintek F75373S/SG",
1234                driver => "f75375s",
1235                i2c_addrs => [0x2d..0x2e],
1236                i2c_detect => sub { fintek_detect(@_, 3); },
1237        }, {
1238                name => "Fintek F75375S/SP",
1239                driver => "f75375s",
1240                i2c_addrs => [0x2d..0x2e],
1241                i2c_detect => sub { fintek_detect(@_, 4); },
1242        }, {
1243                name => "Fintek F75387SG/RG",
1244                driver => "to-be-written",
1245                i2c_addrs => [0x2d..0x2e],
1246                i2c_detect => sub { fintek_detect(@_, 5); },
1247        }, {
1248                name => "Fintek F75383S/M",
1249                driver => "to-be-written",
1250                i2c_addrs => [0x4c],
1251                i2c_detect => sub { fintek_detect(@_, 6); },
1252        }, {
1253                name => "Fintek F75384S/M",
1254                driver => "to-be-written",
1255                i2c_addrs => [0x4d],
1256                i2c_detect => sub { fintek_detect(@_, 6); },
1257        }, {
1258                name => "Fintek custom power control IC",
1259                driver => "to-be-written",
1260                i2c_addrs => [0x2f],
1261                i2c_detect => sub { fintek_detect(@_, 7); },
1262        }, {
1263                name => "SMSC EMC1002",
1264                driver => "to-be-written",
1265                i2c_addrs => [0x4c, 0x4d], # 0x3c, 0x3d not probed
1266                i2c_detect => sub { emc1403_detect(@_, 4); },
1267        }, {
1268                name => "SMSC EMC1023",
1269                driver => "to-be-written",      # emc1023
1270                i2c_addrs => [0x48, 0x49, 0x4c, 0x4d],
1271                i2c_detect => sub { emc1023_detect(@_, 0); },
1272        }, {
1273                name => "SMSC EMC1033",
1274                driver => "to-be-written",
1275                i2c_addrs => [0x4c, 0x4d], # 0x3c, 0x3d not probed
1276                i2c_detect => sub { emc1403_detect(@_, 5); },
1277        }, {
1278                name => "SMSC EMC1043",
1279                driver => "to-be-written",      # emc1023
1280                i2c_addrs => [0x48, 0x49, 0x4c, 0x4d],
1281                i2c_detect => sub { emc1023_detect(@_, 1); },
1282        }, {
1283                name => "SMSC EMC1046",
1284                driver => "to-be-written",
1285                i2c_addrs => [0x4c, 0x4d],
1286                i2c_detect => sub { emc1403_detect(@_, 6); },
1287        }, {
1288                name => "SMSC EMC1047",
1289                driver => "to-be-written",
1290                i2c_addrs => [0x18], # 0x10 not probed
1291                i2c_detect => sub { emc1403_detect(@_, 7); },
1292        }, {
1293                name => "SMSC EMC1053",
1294                driver => "to-be-written",      # emc1023
1295                i2c_addrs => [0x48, 0x49, 0x4c, 0x4d],
1296                i2c_detect => sub { emc1023_detect(@_, 2); },
1297        }, {
1298                name => "SMSC EMC1063",
1299                driver => "to-be-written",      # emc1023
1300                i2c_addrs => [0x48, 0x49, 0x4c, 0x4d],
1301                i2c_detect => sub { emc1023_detect(@_, 3); },
1302        }, {
1303                name => "SMSC EMC1072",
1304                driver => "to-be-written",
1305                i2c_addrs => [0x1c, 0x4c, 0x5c], # 0x2c, 0x3c, 0x6c, 0x7c not probed
1306                i2c_detect => sub { emc1403_detect(@_, 8); },
1307        }, {
1308                name => "SMSC EMC1073",
1309                driver => "to-be-written",
1310                i2c_addrs => [0x1c, 0x4c, 0x5c], # 0x2c, 0x3c, 0x6c, 0x7c not probed
1311                i2c_detect => sub { emc1403_detect(@_, 9); },
1312        }, {
1313                name => "SMSC EMC1074",
1314                driver => "to-be-written",
1315                i2c_addrs => [0x1c, 0x4c, 0x5c], # 0x2c, 0x3c, 0x6c, 0x7c not probed
1316                i2c_detect => sub { emc1403_detect(@_, 10); },
1317        }, {
1318                name => "SMSC EMC1402",
1319                driver => "to-be-written",
1320                i2c_addrs => [0x18, 0x29, 0x4c, 0x4d],
1321                i2c_detect => sub { emc1403_detect(@_, 11); },
1322        }, {
1323                name => "SMSC EMC1403",
1324                driver => "emc1403",
1325                i2c_addrs => [0x18, 0x29, 0x4c, 0x4d],
1326                i2c_detect => sub { emc1403_detect(@_, 0); },
1327        }, {
1328                name => "SMSC EMC1404",
1329                driver => "to-be-written", # emc1403
1330                i2c_addrs => [0x18, 0x29, 0x4c, 0x4d],
1331                i2c_detect => sub { emc1403_detect(@_, 1); },
1332        }, {
1333                name => "SMSC EMC1423",
1334                driver => "emc1403",
1335                i2c_addrs => [0x4c],
1336                i2c_detect => sub { emc1403_detect(@_, 3); },
1337        }, {
1338                name => "SMSC EMC1424",
1339                driver => "to-be-written",
1340                i2c_addrs => [0x4c],
1341                i2c_detect => sub { emc1403_detect(@_, 12); },
1342        }, {
1343                name => "ST STTS424",
1344                driver => "jc42",
1345                i2c_addrs => [0x18..0x1f],
1346                i2c_detect => sub { jedec_JC42_4_detect(@_, 0); },
1347        }, {
1348                name => "ST STTS424E",
1349                driver => "jc42",
1350                i2c_addrs => [0x18..0x1f],
1351                i2c_detect => sub { jedec_JC42_4_detect(@_, 10); },
1352        }, {
1353                name => "NXP SE97/SE97B",
1354                driver => "jc42",
1355                i2c_addrs => [0x18..0x1f],
1356                i2c_detect => sub { jedec_JC42_4_detect(@_, 1); },
1357        }, {
1358                name => "NXP SE98",
1359                driver => "jc42",
1360                i2c_addrs => [0x18..0x1f],
1361                i2c_detect => sub { jedec_JC42_4_detect(@_, 2); },
1362        }, {
1363                name => "Analog Devices ADT7408",
1364                driver => "jc42",
1365                i2c_addrs => [0x18..0x1f],
1366                i2c_detect => sub { jedec_JC42_4_detect(@_, 3); },
1367        }, {
1368                name => "IDT TS3000/TSE2002",
1369                driver => "jc42",
1370                i2c_addrs => [0x18..0x1f],
1371                i2c_detect => sub { jedec_JC42_4_detect(@_, 4); },
1372        }, {
1373                name => "Maxim MAX6604",
1374                driver => "jc42",
1375                i2c_addrs => [0x18..0x1f],
1376                i2c_detect => sub { jedec_JC42_4_detect(@_, 5); },
1377        }, {
1378                name => "Microchip MCP98242",
1379                driver => "jc42",
1380                i2c_addrs => [0x18..0x1f],
1381                i2c_detect => sub { jedec_JC42_4_detect(@_, 6); },
1382        }, {
1383                name => "Microchip MCP98243",
1384                driver => "jc42",
1385                i2c_addrs => [0x18..0x1f],
1386                i2c_detect => sub { jedec_JC42_4_detect(@_, 7); },
1387        }, {
1388                name => "Microchip MCP9843",
1389                driver => "jc42",
1390                i2c_addrs => [0x18..0x1f],
1391                i2c_detect => sub { jedec_JC42_4_detect(@_, 8); },
1392        }, {
1393                name => "ON CAT6095/CAT34TS02",
1394                driver => "jc42",
1395                i2c_addrs => [0x18..0x1f],
1396                i2c_detect => sub { jedec_JC42_4_detect(@_, 9); },
1397        }
1398);
1399
1400# IPMI interfaces have their own array now
1401@ipmi_ifs = (
1402        {
1403                name => "IPMI BMC KCS",
1404                driver => "to-be-written",      # ipmisensors
1405                isa_addrs => [0x0ca0],
1406                isa_detect => sub { ipmi_detect(@_); },
1407        }, {
1408                name => "IPMI BMC SMIC",
1409                driver => "to-be-written",      # ipmisensors
1410                isa_addrs => [0x0ca8],
1411                isa_detect => sub { ipmi_detect(@_); },
1412        }
1413);
1414
1415# Here is a similar list, but for devices which are not hardware monitoring
1416# chips. We only list popular devices which happen to live at the same I2C
1417# address as recognized hardware monitoring chips. The idea is to make it
1418# clear that the chip in question is of no interest for lm-sensors.
1419@non_hwmon_chip_ids = (
1420        {
1421                name => "Winbond W83791SD",
1422                i2c_addrs => [0x2c..0x2f],
1423                i2c_detect => sub { w83791sd_detect(@_); },
1424        }, {
1425                name => "Fintek F75111R/RG/N (GPIO)",
1426                i2c_addrs => [0x37, 0x4e],
1427                i2c_detect => sub { fintek_detect(@_, 1); },
1428        }, {
1429                name => "ITE IT8201R/IT8203R/IT8206R/IT8266R",
1430                i2c_addrs => [0x4e],
1431                i2c_detect => sub { ite_overclock_detect(@_); },
1432        }, {
1433                name => "SPD EEPROM",
1434                i2c_addrs => [0x50..0x57],
1435                i2c_detect => sub { eeprom_detect(@_); },
1436        }, {
1437                name => "EDID EEPROM",
1438                i2c_addrs => [0x50],
1439                i2c_detect => sub { ddcmonitor_detect(@_); },
1440        }
1441);
1442
1443# This is a list of all recognized superio chips.
1444# Each entry must have the following fields:
1445#  name: The full chip name
1446#  driver: The driver name. Put in exactly:
1447#      * "to-be-written" if it is not yet available
1448#      * "not-a-sensor" if the chip doesn't have hardware monitoring
1449#        capabilities (listing such chips here removes the need of manual
1450#        lookup when people report them)
1451#      * "via-smbus-only" if this is a Super-I/O chip whose hardware
1452#        monitoring registers can only be accessed via the SMBus
1453#  devid: The device ID we have to match (base device)
1454#  devid_mask (optional): Bitmask to apply before checking the device ID
1455#  regs (optional): Register definitions, where they differ from the standard.
1456#  logdev: The logical device containing the sensors
1457#  check (optional): A function to refine the detection. Will be passed
1458#      the index and data ports as parameters. Must return 1 for a matching
1459#      device, 0 otherwise.
1460#  features (optional): Features supported by this device, amongst:
1461#      * FEAT_IN
1462#      * FEAT_FAN
1463#      * FEAT_TEMP
1464use vars qw(@superio_ids_natsemi @superio_ids_smsc @superio_ids_smsc_ns
1465            @superio_ids_winbond @superio_ids_ite @superio_ids);
1466
1467use constant FEAT_IN    => (1 << 0);
1468use constant FEAT_FAN   => (1 << 1);
1469use constant FEAT_TEMP  => (1 << 2);
1470use constant FEAT_SMBUS => (1 << 7);
1471
1472@superio_ids_natsemi = (
1473        {
1474                name => "Nat. Semi. PC8374L Super IO Sensors",  # Also Nuvoton WPCD374L
1475                driver => "to-be-written",
1476                devid => 0xf1,
1477                check => sub {
1478                        outb($_[0], 0x27);
1479                        # Guess work; seen so far: 0x11
1480                        return (inb($_[1]) < 0x80);
1481                },
1482                logdev => 0x08,
1483                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1484        }, {
1485                name => "Nuvoton WPCD377I Super IO",    # Also WPCD376I
1486                driver => "not-a-sensor",
1487                devid => 0xf1,
1488                check => sub {
1489                        outb($_[0], 0x27);
1490                        # Guess work; seen so far: 0x91 (twice)
1491                        return (inb($_[1]) >= 0x80);
1492                },
1493        }, {
1494                name => "Nat. Semi. PC87351 Super IO Fan Sensors",
1495                driver => "to-be-written",
1496                devid => 0xe2,
1497                logdev => 0x08,
1498        }, {
1499                name => "Nat. Semi. PC87360 Super IO Fan Sensors",
1500                driver => "pc87360",
1501                devid => 0xe1,
1502                logdev => 0x09,
1503                features => FEAT_FAN,
1504        }, {
1505                name => "Nat. Semi. PC87363 Super IO Fan Sensors",
1506                driver => "pc87360",
1507                devid => 0xe8,
1508                logdev => 0x09,
1509                features => FEAT_FAN,
1510        }, {
1511                name => "Nat. Semi. PC87364 Super IO Fan Sensors",
1512                driver => "pc87360",
1513                devid => 0xe4,
1514                logdev => 0x09,
1515                features => FEAT_FAN,
1516        }, {
1517                name => "Nat. Semi. PC87365 Super IO Fan Sensors",
1518                driver => "pc87360",
1519                devid => 0xe5,
1520                logdev => 0x09,
1521                features => FEAT_FAN,
1522        }, {
1523                name => "Nat. Semi. PC87365 Super IO Voltage Sensors",
1524                driver => "pc87360",
1525                devid => 0xe5,
1526                logdev => 0x0d,
1527                features => FEAT_IN,
1528        }, {
1529                name => "Nat. Semi. PC87365 Super IO Thermal Sensors",
1530                driver => "pc87360",
1531                devid => 0xe5,
1532                logdev => 0x0e,
1533                features => FEAT_TEMP,
1534        }, {
1535                name => "Nat. Semi. PC87366 Super IO Fan Sensors",
1536                driver => "pc87360",
1537                devid => 0xe9,
1538                logdev => 0x09,
1539                features => FEAT_FAN,
1540        }, {
1541                name => "Nat. Semi. PC87366 Super IO Voltage Sensors",
1542                driver => "pc87360",
1543                devid => 0xe9,
1544                logdev => 0x0d,
1545                features => FEAT_IN,
1546        }, {
1547                name => "Nat. Semi. PC87366 Super IO Thermal Sensors",
1548                driver => "pc87360",
1549                devid => 0xe9,
1550                logdev => 0x0e,
1551                features => FEAT_TEMP,
1552        }, {
1553                name => "Nat. Semi. PC87372 Super IO Fan Sensors",
1554                driver => "to-be-written",
1555                devid => 0xf0,
1556                logdev => 0x09,
1557                features => FEAT_FAN,
1558        }, {
1559                name => "Nat. Semi. PC87373 Super IO Fan Sensors",
1560                driver => "to-be-written",
1561                devid => 0xf3,
1562                logdev => 0x09,
1563                features => FEAT_FAN,
1564        }, {
1565                name => "Nat. Semi. PC87591 Super IO",
1566                driver => "to-be-written",
1567                devid => 0xec,
1568                logdev => 0x0f,
1569        }, {
1570                name => "Nat. Semi. PC87317 Super IO",
1571                driver => "not-a-sensor",
1572                devid => 0xd0,
1573        }, {
1574                name => "Nat. Semi. PC97317 Super IO",
1575                driver => "not-a-sensor",
1576                devid => 0xdf,
1577        }, {
1578                name => "Nat. Semi. PC8739x Super IO",
1579                driver => "not-a-sensor",
1580                devid => 0xea,
1581        }, {
1582                name => "Nat. Semi. PC8741x Super IO",
1583                driver => "not-a-sensor",
1584                devid => 0xee,
1585        }, {
1586                name => "Nat. Semi. PC87427 Super IO Fan Sensors",
1587                driver => "pc87427",
1588                devid => 0xf2,
1589                logdev => 0x09,
1590                features => FEAT_FAN,
1591        }, {
1592                name => "Nat. Semi. PC87427 Super IO Health Sensors",
1593                driver => "to-be-written",
1594                devid => 0xf2,
1595                logdev => 0x14,
1596                features => FEAT_IN | FEAT_TEMP,
1597        }, {
1598                name => "ITE IT8512E/F/G Super IO",
1599                driver => "to-be-written",
1600                devid => 0x8512,
1601                features => FEAT_IN | FEAT_FAN,
1602        }, {
1603                name => "ITE IT8516E/F/G Super IO",
1604                driver => "to-be-written",
1605                devid => 0x8516,
1606                features => FEAT_IN | FEAT_FAN,
1607        }
1608);
1609
1610@superio_ids_smsc = (
1611        {
1612                name => "SMSC DME1737 Super IO",
1613                # Hardware monitoring features are accessed on the SMBus
1614                driver => "via-smbus-only",
1615                devid => 0x78,
1616        }, {
1617                name => "SMSC DME1737 Super IO",
1618                # The DME1737 shows up twice in this list because it can return either
1619                # 0x78 or 0x77 as its device ID.
1620                # Hardware monitoring features are accessed on the SMBus
1621                driver => "via-smbus-only",
1622                devid => 0x77,
1623        }, {
1624                name => "SMSC EMC2700LPC Super IO",
1625                # no datasheet
1626                devid => 0x67,
1627        }, {
1628                name => "SMSC FDC37B72x Super IO",
1629                driver => "not-a-sensor",
1630                devid => 0x4c,
1631        }, {
1632                name => "SMSC FDC37B78x Super IO",
1633                driver => "not-a-sensor",
1634                devid => 0x44,
1635        }, {
1636                name => "SMSC FDC37C672 Super IO",
1637                driver => "not-a-sensor",
1638                devid => 0x40,
1639        }, {
1640                name => "SMSC FDC37M707 Super IO",
1641                driver => "not-a-sensor",
1642                devid => 0x42,
1643        }, {
1644                name => "SMSC FDC37M81x Super IO",
1645                driver => "not-a-sensor",
1646                devid => 0x4d,
1647        }, {
1648                name => "SMSC LPC47B27x Super IO Fan Sensors",
1649                driver => "smsc47m1",
1650                devid => 0x51,
1651                logdev => 0x0a,
1652                features => FEAT_FAN,
1653        }, {
1654                name => "SMSC LPC47B34x Super IO",
1655                driver => "not-a-sensor",
1656                devid => 0x56,
1657        }, {
1658                name => "SMSC LPC47B357/M967 Super IO",
1659                driver => "not-a-sensor",
1660                devid => 0x5d,
1661        }, {
1662                name => "SMSC LPC47B367-NC Super IO",
1663                driver => "not-a-sensor",
1664                devid => 0x6d,
1665        }, {
1666                name => "SMSC LPC47B37x Super IO Fan Sensors",
1667                driver => "to-be-written",
1668                devid => 0x52,
1669                logdev => 0x0a,
1670                features => FEAT_FAN,
1671        }, {
1672                name => "SMSC LPC47B397-NC Super IO",
1673                driver => "smsc47b397",
1674                devid => 0x6f,
1675                logdev => 0x08,
1676                features => FEAT_FAN | FEAT_TEMP,
1677        }, {
1678                name => "SMSC LPC47M10x/112/13x Super IO Fan Sensors",
1679                driver => "smsc47m1",
1680                devid => 0x59,
1681                logdev => 0x0a,
1682                features => FEAT_FAN,
1683        }, {
1684                name => "SMSC LPC47M14x Super IO Fan Sensors",
1685                driver => "smsc47m1",
1686                devid => 0x5f,
1687                logdev => 0x0a,
1688                features => FEAT_FAN,
1689        }, {
1690                name => "SMSC LPC47M15x/192/997 Super IO Fan Sensors",
1691                driver => "smsc47m1",
1692                devid => 0x60,
1693                logdev => 0x0a,
1694                features => FEAT_FAN,
1695        }, {
1696                name => "SMSC LPC47M172 Super IO Fan Sensors",
1697                driver => "to-be-written",
1698                devid => 0x14,
1699                logdev => 0x0a,
1700                features => FEAT_FAN,
1701        }, {
1702                name => "SMSC LPC47M182 Super IO Fan Sensors",
1703                driver => "to-be-written",
1704                devid => 0x74,
1705                logdev => 0x0a,
1706                features => FEAT_FAN,
1707        }, {
1708                name => "SMSC LPC47M233 Super IO Sensors",
1709                driver => "to-be-written",
1710                devid => 0x6b80,
1711                devid_mask => 0xff80,
1712                logdev => 0x0a,
1713                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1714        }, {
1715                name => "SMSC LPC47M292 Super IO Fan Sensors",
1716                driver => "smsc47m1",
1717                devid => 0x6b00,
1718                devid_mask => 0xff80,
1719                logdev => 0x0a,
1720                features => FEAT_FAN,
1721        }, {
1722                name => "SMSC LPC47M584-NC Super IO",
1723                # No datasheet (Dell-specific part). Not compatible with
1724                # smsc47m1 nor dme1737 nor LPC47M233. No evidence that this
1725                # chip can do any hardware monitoring at all.
1726                driver => "not-a-sensor",
1727                devid => 0x76,
1728        }, {
1729                name => "SMSC LPC47N252 Super IO Fan Sensors",
1730                driver => "to-be-written",
1731                devid => 0x0e,
1732                logdev => 0x09,
1733                features => FEAT_FAN,
1734        }, {
1735                name => "SMSC LPC47S42x Super IO Fan Sensors",
1736                driver => "to-be-written",
1737                devid => 0x57,
1738                logdev => 0x0a,
1739                features => FEAT_FAN,
1740        }, {
1741                name => "SMSC LPC47S45x Super IO Fan Sensors",
1742                driver => "to-be-written",
1743                devid => 0x62,
1744                logdev => 0x0a,
1745                features => FEAT_FAN,
1746        }, {
1747                name => "SMSC LPC47U32x Super IO Fan Sensors",
1748                driver => "to-be-written",
1749                devid => 0x58,
1750                logdev => 0x0a,
1751                features => FEAT_FAN,
1752        }, {
1753                name => "SMSC LPC47U33x Super IO Fan Sensors",
1754                driver => "to-be-written",
1755                devid => 0x54,
1756                logdev => 0x0a,
1757                features => FEAT_FAN,
1758        }, {
1759                name => "SMSC SCH3112 Super IO",
1760                driver => "dme1737",
1761                devid => 0x7c,
1762                logdev => 0x0a,
1763                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1764        }, {
1765                name => "SMSC SCH3114 Super IO",
1766                driver => "dme1737",
1767                devid => 0x7d,
1768                logdev => 0x0a,
1769                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1770        }, {
1771                name => "SMSC SCH3116 Super IO",
1772                driver => "dme1737",
1773                devid => 0x7f,
1774                logdev => 0x0a,
1775                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1776        }, {
1777                name => "SMSC SCH4307 Super IO Fan Sensors",
1778                driver => "to-be-written",
1779                devid => 0x90,
1780                logdev => 0x08,
1781                features => FEAT_FAN,
1782        }, {
1783                name => "SMSC SCH5027D-NW Super IO",
1784                # Hardware monitoring features are accessed on the SMBus
1785                driver => "via-smbus-only",
1786                devid => 0x89,
1787        }, {
1788                name => "SMSC SCH5127 Super IO",
1789                driver => "dme1737",
1790                devid => 0x86,
1791                logdev => 0x0a,
1792                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1793        }, {
1794                name => "SMSC SCH5307-NS Super IO",
1795                driver => "smsc47b397",
1796                devid => 0x81,
1797                logdev => 0x08,
1798                features => FEAT_FAN | FEAT_TEMP,
1799        }, {
1800                name => "SMSC SCH5317 Super IO",
1801                driver => "smsc47b397",
1802                devid => 0x85,
1803                logdev => 0x08,
1804                features => FEAT_FAN | FEAT_TEMP,
1805        }, {
1806                name => "SMSC SCH5317 Super IO",
1807                # The SCH5317 shows up twice in this list because it can return either
1808                # 0x85 or 0x8c as its device ID.
1809                driver => "smsc47b397",
1810                devid => 0x8c,
1811                logdev => 0x08,
1812                features => FEAT_FAN | FEAT_TEMP,
1813        }, {
1814                name => "SMSC SCH5504-NS Super IO",
1815                # No datasheet
1816                driver => "not-a-sensor",
1817                devid => 0x79,
1818        }, {
1819                name => "SMSC SCH5514D-NS Super IO",
1820                # No datasheet
1821                driver => "not-a-sensor",
1822                devid => 0x83,
1823        }, {
1824                name => "SMSC SCH5627 Super IO",
1825                driver => "sch5627",
1826                devid => 0xc6,
1827                regs => {
1828                        basereg_lsb => 0x66,
1829                        basereg_msb => 0x67,
1830                },
1831                logdev => 0x0c,
1832                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1833        }, {
1834                name => "SMSC SCH5636 Super IO",
1835                driver => "sch5636",
1836                devid => 0xc7,
1837                regs => {
1838                        basereg_lsb => 0x66,
1839                        basereg_msb => 0x67,
1840                },
1841                logdev => 0x0c,
1842                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1843        }
1844);
1845
1846# Non-standard SMSC chip list. These chips differ from the standard ones
1847# listed above in that the device ID register address is 0x0d instead of
1848# 0x20 (as specified by the ISA PNP spec).
1849@superio_ids_smsc_ns = (
1850        {
1851                name => "SMSC FDC37C665 Super IO",
1852                driver => "not-a-sensor",
1853                devid => 0x65,
1854        }, {
1855                name => "SMSC FDC37C666 Super IO",
1856                driver => "not-a-sensor",
1857                devid => 0x66,
1858        }, {
1859                name => "SMSC FDC37C669 Super IO",
1860                driver => "not-a-sensor",
1861                devid => 0x03,
1862        }, {
1863                name => "SMSC FDC37N769 Super IO",
1864                driver => "not-a-sensor",
1865                devid => 0x28,
1866        }, {
1867                name => "SMSC LPC47N227 Super IO",
1868                driver => "not-a-sensor",
1869                devid => 0x5a,
1870        }, {
1871                name => "SMSC LPC47N237 Super IO",
1872                driver => "not-a-sensor",
1873                devid => 0x13,
1874        }
1875);
1876
1877@superio_ids_winbond = (
1878        {
1879                name => "VIA VT1211 Super IO Sensors",
1880                driver => "vt1211",
1881                devid => 0x3c,
1882                logdev => 0x0b,
1883                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1884        }, {
1885                name => "VIA VT1212 Super IO Lite",     # in 100 pin TQFP package
1886                driver => "not-a-sensor",
1887                devid => 0x3e,
1888        }, {
1889                name => "VIA VT1212 Super IO Lite",     # in 48 pin LQFP package
1890                driver => "not-a-sensor",
1891                devid => 0x3f,
1892        }, {
1893                name => "Winbond W83627HF/F/HG/G Super IO Sensors",
1894                # Also SMSC LPC61W492
1895                driver => "w83627hf",
1896                devid => 0x52,
1897                logdev => 0x0b,
1898                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1899        }, {
1900                name => "Winbond W83627THF/THG Super IO Sensors",
1901                driver => "w83627hf",
1902                devid => 0x82,
1903                logdev => 0x0b,
1904                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1905        }, {
1906                name => "Winbond W83637HF/HG Super IO Sensors",
1907                driver => "w83627hf",
1908                devid => 0x70,
1909                logdev => 0x0b,
1910                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1911        }, {
1912                name => "Winbond W83687THF Super IO Sensors",
1913                driver => "w83627hf",
1914                devid => 0x85,
1915                logdev => 0x0b,
1916                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1917        }, {
1918                name => "Winbond W83697HF/F/HG Super IO Sensors",
1919                driver => "w83627hf",
1920                devid => 0x60,
1921                logdev => 0x0b,
1922                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1923        }, {
1924                name => "Winbond W83697SF/UF/UG Super IO PWM",
1925                driver => "to-be-written",
1926                devid => 0x68,
1927                logdev => 0x0b,
1928                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1929        }, {
1930                name => "Winbond W83627EHF/EF/EHG/EG Super IO Sensors",
1931                driver => "w83627ehf",
1932                # W83627EHF datasheet says 0x886x but 0x8853 was seen, thus the
1933                # broader mask. W83627EHG was seen with ID 0x8863.
1934                devid => 0x8840,
1935                devid_mask => 0xFFC0,
1936                logdev => 0x0b,
1937                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1938        }, {
1939                name => "Winbond W83627DHG Super IO Sensors",
1940                driver => "w83627ehf",
1941                devid => 0xA020,
1942                devid_mask => 0xFFF0,
1943                logdev => 0x0b,
1944                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1945        }, {
1946                name => "Winbond W83627DHG-P/W83527HG Super IO Sensors",
1947                driver => "w83627ehf",
1948                devid => 0xB070,
1949                devid_mask => 0xFFF0,
1950                logdev => 0x0b,
1951                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1952        }, {
1953                name => "Winbond W83627UHG/NCT6627UD Super IO Sensors",
1954                driver => "w83627ehf",
1955                devid => 0xA230,
1956                devid_mask => 0xFFF0,
1957                logdev => 0x0b,
1958                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1959        }, {
1960                name => "Winbond W83667HG Super IO Sensors",
1961                driver => "w83627ehf",
1962                devid => 0xA510,
1963                devid_mask => 0xFFF0,
1964                logdev => 0x0b,
1965                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1966        }, {
1967                name => "Nuvoton W83667HG-B (NCT5571D) Super IO Sensors",
1968                driver => "w83627ehf",
1969                devid => 0xB350,
1970                devid_mask => 0xFFF0,
1971                logdev => 0x0b,
1972                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1973        }, {
1974                name => "Nuvoton W83677HG-I (NCT6771F/NCT6772F/NCT6775F) Super IO Sensors",
1975                driver => "w83627ehf",
1976                devid => 0xB470,
1977                devid_mask => 0xFFF0,
1978                logdev => 0x0b,
1979                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1980        }, {
1981                name => "Winbond W83L517D Super IO",
1982                driver => "not-a-sensor",
1983                devid => 0x61,
1984        }, {
1985                name => "Nuvoton NCT5577D Super IO Sensors",
1986                driver => "to-be-written",
1987                devid => 0xC331,
1988                logdev => 0x0b,
1989                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1990        }, {
1991                name => "Nuvoton NCT6776F Super IO Sensors",
1992                driver => "w83627ehf",
1993                devid => 0xC333,
1994                logdev => 0x0b,
1995                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1996        }, {
1997                name => "Fintek F71805F/FG Super IO Sensors",
1998                driver => "f71805f",
1999                devid => 0x0406,
2000                logdev => 0x04,
2001                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2002        }, {
2003                name => "Fintek F71808E Super IO Sensors",
2004                driver => "f71882fg",
2005                devid => 0x0901,
2006                logdev => 0x04,
2007                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2008        }, {
2009                name => "Fintek F71808A Super IO Sensors",
2010                driver => "f71882fg",
2011                devid => 0x1001,
2012                logdev => 0x04,
2013                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2014        }, {
2015                name => "Fintek F71862FG Super IO Sensors",
2016                driver => "f71882fg",
2017                devid => 0x0601,
2018                logdev => 0x04,
2019                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2020        }, {
2021                name => "Fintek F71869F/E Super IO Sensors",
2022                driver => "f71882fg",
2023                devid => 0x0814,
2024                logdev => 0x04,
2025                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2026        }, {
2027                name => "Fintek F71869A Super IO Sensors",
2028                driver => "f71882fg",
2029                devid => 0x1007,
2030                logdev => 0x04,
2031                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2032        }, {
2033                name => "Fintek F71806FG/F71872FG Super IO Sensors",
2034                driver => "f71805f",
2035                devid => 0x0341,
2036                logdev => 0x04,
2037                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2038        }, {
2039                name => "Fintek F71858DG Super IO Sensors",
2040                driver => "f71882fg",
2041                devid => 0x0507,
2042                logdev => 0x02,
2043                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2044        }, {
2045                name => "Fintek F71882FG/F71883FG Super IO Sensors",
2046                driver => "f71882fg",
2047                devid => 0x0541,
2048                logdev => 0x04,
2049                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2050        }, {
2051                name => "Fintek F71889FG/F81801U Super IO Sensors",
2052                driver => "f71882fg",
2053                devid => 0x0723,
2054                logdev => 0x04,
2055                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2056        }, {
2057                name => "Fintek F71889ED Super IO Sensors",
2058                driver => "f71882fg",
2059                devid => 0x0909,
2060                logdev => 0x04,
2061                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2062        }, {
2063                name => "Fintek F71889A Super IO Sensors",
2064                driver => "f71882fg",
2065                devid => 0x1005,
2066                logdev => 0x04,
2067                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2068        }, {
2069                name => "Fintek F81216D Super IO",
2070                driver => "not-a-sensor",
2071                devid => 0x0208,
2072        }, {
2073                name => "Fintek F81218D Super IO",
2074                driver => "not-a-sensor",
2075                devid => 0x0206,
2076        }, {
2077                name => "Fintek F81865F Super IO Sensors",
2078                driver => "f71882fg",
2079                devid => 0x0704,
2080                logdev => 0x04,
2081                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2082        }, {
2083                name => "Fintek F81866D Super IO Sensors",
2084                driver => "to-be-written",
2085                devid => 0x1010,
2086                logdev => 0x04,
2087                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2088        }, {
2089                name => "Asus F8000 Super IO",
2090                driver => "f71882fg",
2091                devid => 0x0581,
2092                logdev => 0x04,
2093                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2094        }, {
2095                # Shouldn't be in this family, but seems to be still.
2096                name => "ITE IT8708F Super IO",
2097                driver => "not-a-sensor",
2098                devid => 0x8708,
2099        }, {
2100                # Shouldn't be in this family, but seems to be still.
2101                name => "ITE IT8710F Super IO",
2102                driver => "not-a-sensor",
2103                devid => 0x8710,
2104        }
2105);
2106
2107@superio_ids_ite = (
2108        {
2109                name => "ITE IT8702F Super IO Fan Sensors",
2110                driver => "to-be-written",
2111                devid => 0x8702,
2112                logdev => 0x04,
2113                features => FEAT_FAN,
2114        }, {
2115                name => "ITE IT8705F Super IO Sensors",
2116                driver => "it87",
2117                devid => 0x8705,
2118                logdev => 0x04,
2119                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2120        }, {
2121                name => "ITE IT8712F Super IO Sensors",
2122                driver => "it87",
2123                devid => 0x8712,
2124                logdev => 0x04,
2125                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2126        }, {
2127                name => "ITE IT8716F Super IO Sensors",
2128                driver => "it87",
2129                devid => 0x8716,
2130                logdev => 0x04,
2131                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2132        }, {
2133                name => "ITE IT8718F Super IO Sensors",
2134                driver => "it87",
2135                devid => 0x8718,
2136                logdev => 0x04,
2137                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2138        }, {
2139                name => "ITE IT8720F Super IO Sensors",
2140                driver => "it87",
2141                devid => 0x8720,
2142                logdev => 0x04,
2143                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2144        }, {
2145                name => "ITE IT8721F/IT8758E Super IO Sensors",
2146                driver => "it87",
2147                devid => 0x8721,
2148                logdev => 0x04,
2149                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2150        }, {
2151                name => "ITE IT8726F Super IO Sensors",
2152                driver => "it87",
2153                devid => 0x8726,
2154                logdev => 0x04,
2155                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2156        }, {
2157                name => "ITE IT8728F Super IO Sensors",
2158                driver => "it87",
2159                devid => 0x8728,
2160                logdev => 0x04,
2161                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2162        }, {
2163                name => "ITE IT8772E Super IO Sensors",
2164                driver => "to-be-written",      # it87
2165                devid => 0x8772,
2166                logdev => 0x04,
2167                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
2168        }
2169);
2170
2171# Entries are grouped by family. Each family entry has the following fields:
2172#  family: The family name
2173#  guess (optional): Typical logical device address. This lets us do
2174#       generic probing if we fail to recognize the chip.
2175#  enter: The password sequence to write to the address register
2176#  chips: Array of chips
2177# The order of families matters, because we stop as soon as one family
2178# succeeds. So we have to list families with shorter password sequences
2179# first.
2180@superio_ids = (
2181        {
2182                family => "National Semiconductor/ITE",
2183                enter =>
2184                {
2185                        0x2e => [],
2186                        0x4e => [],
2187                },
2188                chips => \@superio_ids_natsemi,
2189        }, {
2190                family => "SMSC",
2191                enter =>
2192                {
2193                        0x2e => [0x55],
2194                        0x4e => [0x55],
2195                },
2196                chips => \@superio_ids_smsc,
2197                ns_detect => \&smsc_ns_detect_superio,
2198                ns_chips => \@superio_ids_smsc_ns,
2199        }, {
2200                family => "VIA/Winbond/Nuvoton/Fintek",
2201                guess => 0x290,
2202                enter =>
2203                {
2204                        0x2e => [0x87, 0x87],
2205                        0x4e => [0x87, 0x87],
2206                },
2207                chips => \@superio_ids_winbond,
2208        }, {
2209                family => "ITE",
2210                guess => 0x290,
2211                enter =>
2212                {
2213                        0x2e => [0x87, 0x01, 0x55, 0x55],
2214                        0x4e => [0x87, 0x01, 0x55, 0xaa],
2215                },
2216                chips => \@superio_ids_ite,
2217        }
2218);
2219
2220# Drivers for bridge, CPU and memory embedded sensors
2221# Each entry must have the following fields:
2222#  name: The device name
2223#  driver: The driver name. Put "to-be-written" if no driver is available.
2224#  detect: Detection callback function. No parameter will be passed to
2225#       this function, it must use global lists of PCI devices, CPU,
2226#       etc. It must return a confidence value, undef if no supported
2227#       CPU is found.
2228use vars qw(@cpu_ids);
2229
2230@cpu_ids = (
2231        {
2232                name => "Silicon Integrated Systems SIS5595",
2233                driver => "sis5595",
2234                detect => \&sis5595_pci_detect,
2235        }, {
2236                name => "VIA VT82C686 Integrated Sensors",
2237                driver => "via686a",
2238                detect => \&via686a_pci_detect,
2239        }, {
2240                name => "VIA VT8231 Integrated Sensors",
2241                driver => "vt8231",
2242                detect => \&via8231_pci_detect,
2243        }, {
2244                name => "AMD K8 thermal sensors",
2245                driver => "k8temp",
2246                detect => sub { amd_pci_detect('1103') },
2247        }, {
2248                name => "AMD Family 10h thermal sensors",
2249                driver => "k10temp",
2250                detect => \&fam10h_pci_detect,
2251        }, {
2252                name => "AMD Family 11h thermal sensors",
2253                driver => "k10temp",
2254                detect => sub { amd_pci_detect('1303') },
2255        }, {
2256                name => "AMD Family 12h and 14h thermal sensors",
2257                driver => "k10temp",
2258                detect => sub { amd_pci_detect('1703') },
2259        }, {
2260                name => "AMD Family 15h thermal sensors",
2261                driver => "k10temp",
2262                detect => sub { amd_pci_detect('1603') },
2263        }, {
2264                name => "AMD Family 15h power sensors",
2265                driver => "fam15h_power",
2266                detect => sub { amd_pci_detect('1604') },
2267        }, {
2268                name => "Intel digital thermal sensor",
2269                driver => "coretemp",
2270                detect => \&coretemp_detect,
2271        }, {
2272                name => "Intel AMB FB-DIMM thermal sensor",
2273                driver => "i5k_amb",
2274                detect => \&intel_amb_detect,
2275        }, {
2276                name => "VIA C7 thermal sensor",
2277                driver => "via-cputemp",
2278                detect => \&via_c7_detect,
2279        }, {
2280                name => "VIA Nano thermal sensor",
2281                driver => "via-cputemp",
2282                detect => \&via_nano_detect,
2283        }
2284);
2285
2286#######################
2287# AUXILIARY FUNCTIONS #
2288#######################
2289
2290# $_[0] is the sought value
2291# $_[1..] is the list to seek in
2292# Returns: 1 if found, 0 if not.
2293sub contains
2294{
2295        my $sought = shift;
2296        local $_;
2297
2298        foreach (@_) {
2299                return 1 if $sought eq $_;
2300        }
2301        return 0;
2302}
2303
2304# Address can be decimal or hexadecimal
2305sub valid_address
2306{
2307        my $value = shift;
2308
2309        if ($value !~ m/^(0x[0-9a-f]+|[0-9]+)$/i) {
2310                print "$value is not a valid address, sorry.\n";
2311                exit -1;
2312        }
2313        $value = oct($value) if $value =~ m/^0x/i;
2314
2315        return $value;
2316}
2317
2318sub parse_not_to_scan
2319{
2320        my ($min, $max, $to_parse) = @_;
2321        my @ranges = split /\s*, \s*/, $to_parse;
2322        my @res;
2323        my $range;
2324
2325        foreach $range (@ranges) {
2326                my ($start, $end) = split /\s*-\s*/, $range;
2327                $start = valid_address($start);
2328                if (defined $end) {
2329                        $end = valid_address($end);
2330                        if ($end <= $start) {
2331                                print "$start-$end is not a valid range, sorry.\n";
2332                                exit -1;
2333                        }
2334                        $start = $min if $start < $min;
2335                        $end = $max if $end > $max;
2336                        push @res, ($start..$end);
2337                } else {
2338                        push @res, $start if $start >= $min and $start <= $max;
2339                }
2340        }
2341
2342        return sort { $a <=> $b } @res;
2343}
2344
2345# $_[0]: Reference to list 1
2346# $_[1]: Reference to list 2
2347# Result: 0 if they have no elements in common, 1 if they have
2348# Elements must be numeric.
2349sub any_list_match
2350{
2351        my ($list1, $list2) = @_;
2352        my ($el1, $el2);
2353
2354        foreach $el1 (@$list1) {
2355                foreach $el2 (@$list2) {
2356                        return 1 if $el1 == $el2;
2357                }
2358        }
2359        return 0;
2360}
2361
2362# $_[0]: Reference to base hash
2363# $_[1]: Reference to overlay hash
2364# Result: Overlayed hash
2365sub overlay_hash
2366{
2367        my ($base, $overlay) = @_;
2368        my %result = %{$base};
2369
2370        foreach my $key (keys %{$overlay}) {
2371                $result{$key} = $overlay->{$key};
2372        }
2373        return %result;
2374}
2375
2376###################
2377# I/O PORT ACCESS #
2378###################
2379
2380sub initialize_ioports
2381{
2382        sysopen(IOPORTS, "/dev/port", O_RDWR)
2383                or die "/dev/port: $!\n";
2384        binmode(IOPORTS);
2385}
2386
2387sub close_ioports
2388{
2389        close(IOPORTS);
2390}
2391
2392# $_[0]: port to read
2393# Returns: -1 on failure, read value on success.
2394sub inb
2395{
2396        my ($res, $nrchars);
2397        sysseek(IOPORTS, $_[0], 0) or return -1;
2398        $nrchars = sysread(IOPORTS, $res, 1);
2399        return -1 if not defined $nrchars or $nrchars != 1;
2400        $res = unpack("C", $res);
2401        return $res;
2402}
2403
2404# $_[0]: port to write
2405# $_[1]: value to write
2406# We assume this can't fail.
2407sub outb
2408{
2409        sysseek(IOPORTS, $_[0], 0);
2410        syswrite(IOPORTS, pack("C", $_[1]), 1);
2411}
2412
2413# $_[0]: Address register
2414# $_[1]: Data register
2415# $_[2]: Register to read
2416# Returns: read value
2417sub isa_read_byte
2418{
2419        outb($_[0], $_[2]);
2420        return inb($_[1]);
2421}
2422
2423# $_[0]: Base address
2424# $_[1]: Register to read
2425# Returns: read value
2426# This one can be used for any ISA chip with index register at
2427# offset 5 and data register at offset 6.
2428sub isa_read_i5d6
2429{
2430        my ($addr, $reg) = @_;
2431        return isa_read_byte($addr + 5, $addr + 6, $reg);
2432}
2433
2434#################
2435# AUTODETECTION #
2436#################
2437
2438use vars qw($dev_i2c $sysfs_root);
2439
2440sub initialize_conf
2441{
2442        my $use_devfs = 0;
2443        open(local *INPUTFILE, "/proc/mounts") or die "Can't access /proc/mounts!";
2444        local $_;
2445        while (<INPUTFILE>) {
2446                if (m@^\w+ /dev devfs @) {
2447                        $use_devfs = 1;
2448                        $dev_i2c = '/dev/i2c/';
2449                }
2450                if (m@^\S+ (/\w+) sysfs @) {
2451                        $sysfs_root = $1;
2452                }
2453        }
2454        close(INPUTFILE);
2455
2456        # We need sysfs for many things
2457        if (!defined $sysfs_root) {
2458                print "Sysfs not mounted?\n";
2459                exit -1;
2460        }
2461
2462        my $use_udev = 0;
2463        if (open(*INPUTFILE, '/etc/udev/udev.conf')) {
2464                while (<INPUTFILE>) {
2465                        next unless m/^\s*udev_db\s*=\s*\"([^"]*)\"/
2466                                 || m/^\s*udev_db\s*=\s*(\S+)/;
2467                        if (-e $1) {
2468                                $use_udev = 1;
2469                                $dev_i2c = '/dev/i2c-';
2470                        }
2471                        last;
2472                }
2473                close(INPUTFILE);
2474          }
2475
2476        if (!$use_udev) {
2477                # Try some known default udev db locations, just in case
2478                if (-e '/dev/.udev.tdb' || -e '/dev/.udev'
2479                 || -e '/dev/.udevdb' || -e '/run/udev') {
2480                        $use_udev = 1;
2481                        $dev_i2c = '/dev/i2c-';
2482                }
2483        }
2484
2485        if (!($use_devfs || $use_udev)) {
2486                if (! -c '/dev/i2c-0' && -x '/sbin/MAKEDEV') {
2487                        system("/sbin/MAKEDEV i2c");
2488                }
2489                if (! -c '/dev/i2c-0' && -x '/dev/MAKEDEV') {
2490                        system("/dev/MAKEDEV i2c");
2491                }
2492                if (-c '/dev/i2c-0') {
2493                        $dev_i2c = '/dev/i2c-';
2494                } else { # default
2495                        print "No i2c device files found.\n";
2496                        exit -1;
2497                }
2498        }
2499}
2500
2501# [0] -> VERSION
2502# [1] -> PATCHLEVEL
2503# [2] -> SUBLEVEL
2504# [3] -> EXTRAVERSION
2505#
2506use vars qw(@kernel_version $kernel_arch);
2507
2508sub initialize_kernel_version
2509{
2510        `uname -r` =~ /(\d+)\.(\d+)\.(\d+)(.*)/;
2511        @kernel_version = ($1, $2, $3, $4);
2512        chomp($kernel_arch = `uname -m`);
2513
2514        # We only support kernels >= 2.6.5
2515        if (!kernel_version_at_least(2, 6, 5)) {
2516                print "Kernel version is unsupported (too old, >= 2.6.5 needed)\n";
2517                exit -1;
2518        }
2519}
2520
2521sub kernel_version_at_least
2522{
2523        my ($vers, $plvl, $slvl) = @_;
2524        return 1 if ($kernel_version[0] > $vers ||
2525                     ($kernel_version[0] == $vers &&
2526                      ($kernel_version[1] > $plvl ||
2527                       ($kernel_version[1] == $plvl &&
2528                        ($kernel_version[2] >= $slvl)))));
2529        return 0;
2530}
2531
2532# @cpu is a list of reference to hashes, one hash per CPU.
2533# Each entry has the following keys: vendor_id, cpu family, model,
2534# model name and stepping, directly taken from /proc/cpuinfo.
2535use vars qw(@cpu);
2536
2537sub initialize_cpu_list
2538{
2539        local $_;
2540        my $entry;
2541
2542        open(local *INPUTFILE, "/proc/cpuinfo") or die "Can't access /proc/cpuinfo!";
2543        while (<INPUTFILE>) {
2544                if (m/^processor\s*:\s*(\d+)/) {
2545                        push @cpu, $entry if scalar keys(%{$entry}); # Previous entry
2546                        $entry = { nr => $1 }; # New entry
2547                        next;
2548                }
2549                if (m/^(vendor_id|cpu family|model|model name|stepping|cpuid level)\s*:\s*(.+)$/) {
2550                        my $k = $1;
2551                        my $v = $2;
2552                        $v =~ s/\s+/ /g;        # Merge multiple spaces
2553                        $v =~ s/ $//;           # Trim trailing space
2554                        $entry->{$k} = $v;
2555                        next;
2556                }
2557        }
2558        close(INPUTFILE);
2559        push @cpu, $entry if scalar keys(%{$entry}); # Last entry
2560}
2561
2562# @i2c_adapters is a list of references to hashes, one hash per I2C/SMBus
2563# adapter present on the system. Each entry has the following keys: path,
2564# parent, name (directly taken from sysfs), driver and autoload.
2565use vars qw(@i2c_adapters);
2566
2567# Find out whether the driver would be automatically loaded by the modalias
2568# mechanism.
2569sub device_driver_autoloads
2570{
2571        my $device = shift;
2572       
2573        my $modalias = sysfs_device_attribute($device, "modalias");
2574        return 0 unless defined($modalias);
2575
2576        # At the moment we only handle PCI and USB drivers. Other driver
2577        # types, most notably platform and i2c drivers, do not follow the
2578        # device driver model to the letter, and often create their own
2579        # devices. Such drivers appear to be autoloaded when they are not.
2580        return 0 unless $modalias =~ m/^(pci|usb):/;
2581
2582        my $result = `modprobe -n -v --first-time $modalias 2>&1`;
2583        return ($result =~ m/^insmod/ ||
2584                $result =~ m/\balready in kernel\b/);
2585}
2586
2587sub initialize_i2c_adapters_list
2588{
2589        my ($entry, $base_dir, $have_i2c_adapter_class);
2590        local $_;
2591
2592        if (-d "${sysfs_root}/class/i2c-adapter") {
2593                $base_dir = "${sysfs_root}/class/i2c-adapter";
2594                $have_i2c_adapter_class = 1;
2595        } else {
2596                $base_dir = "${sysfs_root}/bus/i2c/devices";
2597                $have_i2c_adapter_class = 0;
2598        }
2599        opendir(local *ADAPTERS, $base_dir) or return;
2600
2601        while (defined($_ = readdir(ADAPTERS))) {
2602                next unless m/^i2c-(\d+)$/;
2603                my $nr = $1;
2604                $entry = {}; # New entry
2605
2606                # The layout in sysfs has changed over the years
2607                if ($have_i2c_adapter_class) {
2608                        my $link = readlink("${base_dir}/i2c-$nr/device");
2609                        if (!defined $link) {
2610                                $entry->{path} = "${base_dir}/i2c-$nr";
2611                                $entry->{parent} = "${base_dir}/i2c-$nr";
2612                        } elsif ($link =~ m/^(.*)\/i2c-$nr$/) {
2613                                $entry->{path} = "${base_dir}/i2c-$nr/device";
2614                                $entry->{parent} = "${base_dir}/i2c-$nr/$1";
2615                        } else {
2616                                $entry->{path} = "${base_dir}/i2c-$nr";
2617                                $entry->{parent} = "$entry->{path}/device";
2618                        }
2619                } else {
2620                        my $link = readlink("${base_dir}/i2c-$nr");
2621                        $link =~ s/\/i2c-$nr$//;
2622                        $entry->{path} = "${base_dir}/i2c-$nr";
2623                        $entry->{parent} = "${base_dir}/$link";
2624                }
2625
2626                $entry->{name} = sysfs_device_attribute($entry->{path}, "name");
2627                next if $entry->{name} eq "ISA main adapter";
2628
2629                # First try to get the I2C adapter driver name from sysfs,
2630                # and if it fails, fall back to searching our list of known
2631                # I2C adapters.
2632                $entry->{driver} = sysfs_device_driver($entry->{parent})
2633                                || find_i2c_adapter_driver($entry->{name})
2634                                || 'UNKNOWN';
2635
2636                $entry->{autoload} = device_driver_autoloads($entry->{parent});
2637                $i2c_adapters[$nr] = $entry;
2638        }
2639        closedir(ADAPTERS);
2640}
2641
2642# %hwmon_autoloaded is a list of hwmon drivers which are autoloaded
2643# (typically by udev.) We don't need to load these drivers ourselves.
2644use vars qw(%hwmon_autoloaded);
2645
2646sub initialize_hwmon_autoloaded
2647{
2648        my $class_dir = "${sysfs_root}/class/hwmon";
2649        opendir(local *HWMON, $class_dir) or return;
2650
2651        my ($hwmon, $driver);
2652        while (defined($hwmon = readdir(HWMON))) {
2653                next unless $hwmon =~ m/^hwmon\d+$/;
2654
2655                $driver = sysfs_device_driver("${class_dir}/$hwmon/device");
2656                next unless defined($driver);
2657
2658                if (device_driver_autoloads("${class_dir}/$hwmon/device")) {
2659                        $driver =~ tr/-/_/;
2660                        $hwmon_autoloaded{$driver}++
2661                }
2662        }
2663        closedir(HWMON);
2664}
2665
2666sub hwmon_is_autoloaded
2667{
2668        my $driver = shift;
2669        $driver =~ tr/-/_/;
2670        return exists($hwmon_autoloaded{$driver});
2671}
2672
2673###########
2674# MODULES #
2675###########
2676
2677use vars qw(%modules_list %modules_supported @modules_we_loaded);
2678
2679sub initialize_modules_list
2680{
2681        local $_;
2682
2683        open(local *INPUTFILE, "/proc/modules") or return;
2684        while (<INPUTFILE>) {
2685                tr/-/_/; # Probably not needed
2686                $modules_list{$1} = 1 if m/^(\S*)/;
2687        }
2688}
2689
2690sub is_module_loaded
2691{
2692        my $module = shift;
2693        $module =~ tr/-/_/;
2694        return exists $modules_list{$module}
2695}
2696
2697sub load_module
2698{
2699        my $module = shift;
2700
2701        return if is_module_loaded($module);
2702
2703        system("modprobe", $module);
2704        if (($? >> 8) != 0) {
2705                print "Failed to load module $module.\n";
2706                return -1;
2707        }
2708
2709        print "Module $module loaded successfully.\n";
2710        push @modules_we_loaded, $module;
2711
2712        # Update the list of loaded modules
2713        my $normalized = $module;
2714        $normalized =~ tr/-/_/;
2715        $modules_list{$normalized} = 1;
2716}
2717
2718# udev may take some time to create device nodes when loading modules
2719sub udev_settle
2720{
2721        if (!(-x "/sbin/udevadm" && system("/sbin/udevadm settle") == 0)
2722         && !(-x "/sbin/udevsettle" && system("/sbin/udevsettle") == 0)) {
2723                sleep(1);
2724        }
2725}
2726
2727sub initialize_modules_supported
2728{
2729        foreach my $chip (@chip_ids) {
2730                next if $chip->{driver} eq "to-be-written";
2731                next if $chip->{driver} eq "use-isa-instead";
2732
2733                my $normalized = $chip->{driver};
2734                $normalized =~ tr/-/_/;
2735                $modules_supported{$normalized}++;
2736        }
2737}
2738
2739sub unload_modules
2740{
2741        return unless @modules_we_loaded;
2742
2743        # Attempt to unload all kernel drivers we loaded ourselves
2744        while (my $module = pop @modules_we_loaded) {
2745                print "Unloading $module... ";
2746                system("modprobe -r $module 2> /dev/null");
2747                if (($? >> 8) == 0) {
2748                        print "OK\n";
2749                } else {
2750                        print "failed\n";
2751                }
2752        }
2753        print "\n";
2754}
2755
2756############
2757# DMI DATA #
2758############
2759
2760use vars qw(%dmi $dmidecode_ok);
2761
2762# Returns: 1 if dmidecode is recent enough, 0 if not
2763# Cache the result in case it is needed again later.
2764sub check_dmidecode_version
2765{
2766        return $dmidecode_ok if defined $dmidecode_ok;
2767
2768        my $version;
2769        if (open(local *DMIDECODE, "dmidecode --version 2>/dev/null |")) {
2770                $version = <DMIDECODE>;
2771                close(DMIDECODE);
2772                chomp $version if defined $version;
2773        }
2774
2775        if (!defined $version
2776         || !($version =~ m/^(\d+).(\d+)$/)
2777         || !(($1 == 2 && $2 >= 7) || $1 > 2)) {
2778                print "# DMI data unavailable, please consider installing dmidecode 2.7\n".
2779                      "# or later for better results.\n";
2780                $dmidecode_ok = 0;
2781        } else {
2782                $dmidecode_ok = 1;
2783        }
2784
2785        return $dmidecode_ok;
2786}
2787
2788sub initialize_dmi_data
2789{
2790        my %items = (
2791                # sysfs file name => dmidecode string name
2792                sys_vendor => 'system-manufacturer',
2793                product_name => 'system-product-name',
2794                product_version => 'system-version',
2795                board_vendor => 'baseboard-manufacturer',
2796                board_name => 'baseboard-product-name',
2797                board_version => 'baseboard-product-name',
2798                chassis_type => 'chassis-type',
2799        );
2800        # Many BIOS have broken DMI data, filter it out
2801        my %fake = (
2802                'system manufacturer' => 1,
2803                'system product name' => 1,
2804                'system name' => 1,
2805                'system version' => 1,
2806        );
2807        my $dmi_id_dir;
2808
2809        # First try reading the strings from sysfs if available
2810        if (-d ($dmi_id_dir = "$sysfs_root/devices/virtual/dmi/id")     # kernel >= 2.6.28
2811         || -d ($dmi_id_dir = "$sysfs_root/class/dmi/id")) {
2812                foreach my $k (keys %items) {
2813                        $dmi{$k} = sysfs_device_attribute($dmi_id_dir, $k);
2814                }
2815        } else {
2816                # Else fallback on calling dmidecode
2817                return unless check_dmidecode_version();
2818
2819                foreach my $k (keys %items) {
2820                        next unless open(local *DMIDECODE,
2821                                         "dmidecode -s $items{$k} 2>/dev/null |");
2822                        $dmi{$k} = <DMIDECODE>;
2823                        close(DMIDECODE);
2824                }
2825        }
2826
2827        # Strip trailing white-space, discard empty field
2828        foreach my $k (keys %dmi) {
2829                if (!defined $dmi{$k}) {
2830                        delete $dmi{$k};
2831                        next;
2832                }
2833                $dmi{$k} =~ s/\s*$//;
2834                delete $dmi{$k} if $dmi{$k} eq '' || exists $fake{lc($dmi{$k})};
2835        }
2836}
2837
2838sub print_dmi_summary
2839{
2840        my ($system, $board);
2841        if (defined $dmi{sys_vendor} && defined $dmi{product_name}) {
2842                $system = "$dmi{sys_vendor} $dmi{product_name}";
2843        }
2844        if (defined $dmi{board_vendor} && defined $dmi{board_name}) {
2845                $board = "$dmi{board_vendor} $dmi{board_name}";
2846        }
2847       
2848        if (defined $system) {
2849                print "# System: $system";
2850                print " [$dmi{product_version}]" if defined $dmi{product_version};
2851                print " (laptop)" if (is_laptop());
2852                print "\n";
2853        }
2854        print "# Board: $board\n" if defined $board
2855                                  && (!defined $system || $system ne $board);
2856}
2857
2858sub dmi_match
2859{
2860        my $key = shift;
2861        my $value;
2862
2863        return unless defined $dmi{$key};
2864        while (defined ($value = shift)) {
2865                return 1 if $dmi{$key} =~ m/\b$value\b/i;
2866        }
2867        return 0;
2868}
2869
2870sub is_laptop
2871{
2872        return 0 unless $dmi{chassis_type};
2873        return 1 if $dmi{chassis_type} =~ m/(Portable|Laptop|Notebook|Hand Held)/i;
2874        return 1 if $dmi{chassis_type} =~ m/^(8|9|10|11|14)$/;
2875        return 0;
2876}
2877
2878#################
2879# SYSFS HELPERS #
2880#################
2881
2882# From a sysfs device path, return the driver (module) name, or undef
2883sub sysfs_device_driver
2884{
2885        my $device = shift;
2886
2887        my $link = readlink("$device/driver/module");
2888        return unless defined $link;
2889        return basename($link);
2890}
2891
2892# From a sysfs device path, return the subsystem name, or undef
2893sub sysfs_device_subsystem
2894{
2895        my $device = shift;
2896
2897        my $link = readlink("$device/subsystem");
2898        return unless defined $link;
2899        return basename($link);
2900}
2901
2902# From a sysfs device path and an attribute name, return the attribute
2903# value, or undef
2904sub sysfs_device_attribute
2905{
2906        my ($device, $attr) = @_;
2907        my $value;
2908
2909        open(local *FILE, "$device/$attr") or return;
2910        $value = <FILE>;
2911        close(FILE);
2912        return unless defined $value;
2913
2914        chomp($value);
2915        return $value;
2916}
2917
2918##############
2919# PCI ACCESS #
2920##############
2921
2922use vars qw(%pci_list);
2923
2924# This function returns a list of hashes. Each hash has some PCI information:
2925# 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a
2926# computer; 'vendid' and 'devid' uniquely identify a type of device.
2927# 'class' lets us spot unknown SMBus adapters.
2928sub read_sys_dev_pci
2929{
2930        my $devices = shift;
2931        my ($dev, @pci_list);
2932
2933        opendir(local *DEVICES, "$devices")
2934                or die "$devices: $!";
2935
2936        while (defined($dev = readdir(DEVICES))) {
2937                my %record;
2938                next unless $dev =~
2939                        m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/;
2940
2941                $record{domain} = hex $1;
2942                $record{bus} = hex $2;
2943                $record{slot} = hex $3;
2944                $record{func} = hex $4;
2945
2946                $record{vendid} = oct sysfs_device_attribute("$devices/$dev",
2947                                                             "vendor");
2948                $record{devid} = oct sysfs_device_attribute("$devices/$dev",
2949                                                            "device");
2950                $record{class} = (oct sysfs_device_attribute("$devices/$dev",
2951                                                             "class")) >> 8;
2952
2953                push @pci_list, \%record;
2954        }
2955
2956        return \@pci_list;
2957}
2958
2959sub initialize_pci
2960{
2961        my $pci_list;
2962        local $_;
2963
2964        $pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices");
2965
2966        # Note that we lose duplicate devices at this point, but we don't
2967        # really care. What matters to us is which unique devices are present,
2968        # not how many of each.
2969        %pci_list = map {
2970                sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_
2971        } @{$pci_list};
2972}
2973
2974#####################
2975# ADAPTER DETECTION #
2976#####################
2977
2978# Build and return a PCI device's bus ID
2979sub pci_busid
2980{
2981        my $device = shift;
2982        my $busid;
2983
2984        $busid = sprintf("\%02x:\%02x.\%x",
2985                         $device->{bus}, $device->{slot}, $device->{func});
2986        $busid = sprintf("\%04x:", $device->{domain}) . $busid
2987                if defined $device->{domain};
2988
2989        return $busid;
2990}
2991
2992sub adapter_pci_detection
2993{
2994        my ($key, $device, $try, %smbus, $count);
2995
2996        # Build a list of detected SMBus devices
2997        foreach $key (keys %pci_list) {
2998                $device = $pci_list{$key};
2999                $smbus{$key}++
3000                        if exists $device->{class} &&
3001                           ($device->{class} == 0x0c01 ||       # Access Bus
3002                            $device->{class} == 0x0c05);        # SMBus
3003        }
3004
3005        # Loop over the known I2C/SMBus adapters
3006        foreach $try (@pci_adapters) {
3007                $key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid});
3008                next unless exists $pci_list{$key};
3009
3010                $device = $pci_list{$key};
3011
3012                if ($try->{driver} eq "to-be-written") {
3013                        printf "No known driver for device \%s: \%s\n",
3014                               pci_busid($device), $try->{procid};
3015                } else {
3016                        printf "Using driver `\%s' for device \%s: \%s\n",
3017                               $try->{driver}, pci_busid($device),
3018                               $try->{procid};
3019                        $count++;
3020                        load_module($try->{driver});
3021                }
3022
3023                # Delete from detected SMBus device list
3024                delete $smbus{$key};
3025        }
3026
3027        # Now see if there are unknown SMBus devices left
3028        foreach $key (keys %smbus) {
3029                $device = $pci_list{$key};
3030                printf "Found unknown SMBus adapter \%04x:\%04x at \%s.\n",
3031                       $device->{vendid}, $device->{devid}, pci_busid($device);
3032        }
3033
3034        print "Sorry, no supported PCI bus adapters found.\n"
3035                unless $count;
3036}
3037
3038# $_[0]: Adapter description as found in sysfs
3039sub find_i2c_adapter_driver
3040{
3041        my $name = shift;
3042        my $entry;
3043
3044        foreach $entry (@i2c_adapter_names) {
3045                return $entry->{driver}
3046                        if $name =~ $entry->{match};
3047        }
3048}
3049
3050#############################
3051# I2C AND SMBUS /DEV ACCESS #
3052#############################
3053
3054# This should really go into a separate module/package.
3055
3056# These are copied from <linux/i2c-dev.h>
3057
3058use constant IOCTL_I2C_SLAVE    => 0x0703;
3059use constant IOCTL_I2C_FUNCS    => 0x0705;
3060use constant IOCTL_I2C_SMBUS    => 0x0720;
3061
3062use constant SMBUS_READ         => 1;
3063use constant SMBUS_WRITE        => 0;
3064
3065use constant SMBUS_QUICK        => 0;
3066use constant SMBUS_BYTE         => 1;
3067use constant SMBUS_BYTE_DATA    => 2;
3068use constant SMBUS_WORD_DATA    => 3;
3069
3070use constant I2C_FUNC_SMBUS_QUICK       => 0x00010000;
3071use constant I2C_FUNC_SMBUS_READ_BYTE   => 0x00020000;
3072use constant I2C_FUNC_SMBUS_READ_BYTE_DATA      => 0x00080000;
3073
3074# Get the i2c adapter's functionalities
3075# $_[0]: Reference to an opened filehandle
3076# Returns: -1 on failure, functionality bitfield on success.
3077sub i2c_get_funcs
3078{
3079        my $file = shift;
3080        my $funcs = pack("L", 0); # Allocate space
3081
3082        ioctl($file, IOCTL_I2C_FUNCS, $funcs) or return -1;
3083        $funcs = unpack("L", $funcs);
3084
3085        return $funcs;
3086}
3087
3088# Select the device to communicate with through its address.
3089# $_[0]: Reference to an opened filehandle
3090# $_[1]: Address to select
3091# Returns: 0 on failure, 1 on success.
3092sub i2c_set_slave_addr
3093{
3094        my ($file, $addr) = @_;
3095
3096        # Reset register data cache
3097        @i2c_byte_cache = ();
3098
3099        $addr += 0; # Make sure it's a number not a string
3100        ioctl($file, IOCTL_I2C_SLAVE, $addr) or return 0;
3101        return 1;
3102}
3103
3104# i2c_smbus_access is based upon the corresponding C function (see
3105# <linux/i2c-dev.h>). You should not need to call this directly.
3106# $_[0]: Reference to an opened filehandle
3107# $_[1]: SMBUS_READ for reading, SMBUS_WRITE for writing
3108# $_[2]: Command (usually register number)
3109# $_[3]: Transaction kind (SMBUS_BYTE, SMBUS_BYTE_DATA, etc.)
3110# $_[4]: Reference to an array used for input/output of data
3111# Returns: 0 on failure, 1 on success.
3112# Note that we need to get back to Integer boundaries through the 'x2'
3113# in the pack. This is very compiler-dependent; I wish there was some other
3114# way to do this.
3115sub i2c_smbus_access
3116{
3117        my ($file, $read_write, $command, $size, $data) = @_;
3118        my $data_array = pack("C32", @$data);
3119        my $ioctl_data = pack("C2x2Ip", $read_write, $command, $size,
3120                              $data_array);
3121
3122        ioctl($file, IOCTL_I2C_SMBUS, $ioctl_data) or return 0;
3123        @{$_[4]} = unpack("C32", $data_array);
3124        return 1;
3125}
3126
3127# $_[0]: Reference to an opened filehandle
3128# Returns: -1 on failure, the read byte on success.
3129sub i2c_smbus_read_byte
3130{
3131        my ($file) = @_;
3132        my @data;
3133
3134        i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, \@data)
3135                or return -1;
3136        return $data[0];
3137}
3138
3139# $_[0]: Reference to an opened filehandle
3140# $_[1]: Command byte (usually register number)
3141# Returns: -1 on failure, the read byte on success.
3142# Read byte data values are cached by default. As we keep reading the
3143# same registers over and over again in the detection functions, and
3144# SMBus can be slow, caching results in a big performance boost.
3145sub i2c_smbus_read_byte_data
3146{
3147        my ($file, $command, $nocache) = @_;
3148        my @data;
3149
3150        return $i2c_byte_cache[$command]
3151                if !$nocache && exists $i2c_byte_cache[$command];
3152
3153        i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_BYTE_DATA, \@data)
3154                or return -1;
3155        return ($i2c_byte_cache[$command] = $data[0]);
3156}
3157
3158# $_[0]: Reference to an opened filehandle
3159# $_[1]: Command byte (usually register number)
3160# Returns: -1 on failure, the read word on success.
3161# Use this function with care, some devices don't like word reads,
3162# so you should do as much of the detection as possible using byte reads,
3163# and only start using word reads when there is a good chance that
3164# the detection will succeed.
3165# Note: some devices use the wrong endianness.
3166sub i2c_smbus_read_word_data
3167{
3168        my ($file, $command) = @_;
3169        my @data;
3170        i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_WORD_DATA, \@data)
3171                or return -1;
3172        return $data[0] + 256 * $data[1];
3173}
3174
3175# $_[0]: Reference to an opened filehandle
3176# $_[1]: Address
3177# $_[2]: Functionalities of this i2c adapter
3178# Returns: 1 on successful probing, 0 else.
3179# This function is meant to prevent AT24RF08 corruption and write-only
3180# chips locks. This is done by choosing the best probing method depending
3181# on the address range.
3182sub i2c_probe
3183{
3184        my ($file, $addr, $funcs) = @_;
3185
3186        if (($addr >= 0x50 && $addr <= 0x5F)
3187         || ($addr >= 0x30 && $addr <= 0x37)) {
3188                # This covers all EEPROMs we know of, including page protection
3189                # addresses. Note that some page protection addresses will not
3190                # reveal themselves with this, because they ack on write only,
3191                # but this is probably better since some EEPROMs write-protect
3192                # themselves permanently on almost any write to their page
3193                # protection address.
3194                return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE);
3195                return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, []);
3196        } elsif ($addr == 0x73) {
3197                # Special case for FSC chips, as at least the Syleus locks
3198                # up with our regular probe code. Note that to our current
3199                # knowledge only FSC chips live on this address, and for them
3200                # this probe method is safe.
3201                return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA);
3202                return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE_DATA, []);
3203        } else {
3204                return 0 unless ($funcs & I2C_FUNC_SMBUS_QUICK);
3205                return i2c_smbus_access($file, SMBUS_WRITE, 0, SMBUS_QUICK, []);
3206        }
3207}
3208
3209# $_[0]: Reference to an opened file handle
3210# Returns: 1 if the device is safe to access, 0 else.
3211# This function is meant to prevent access to 1-register-only devices,
3212# which are designed to be accessed with SMBus receive byte and SMBus send
3213# byte transactions (i.e. short reads and short writes) and treat SMBus
3214# read byte as a real write followed by a read. The device detection
3215# routines would write random values to the chip with possibly very nasty
3216# results for the hardware. Note that this function won't catch all such
3217# chips, as it assumes that reads and writes relate to the same register,
3218# but that's the best we can do.
3219sub i2c_safety_check
3220{
3221        my ($file) = @_;
3222        my $data;
3223
3224        # First we receive a byte from the chip, and remember it.
3225        $data = i2c_smbus_read_byte($file);
3226        return 1 if ($data < 0);
3227
3228        # We receive a byte again; very likely to be the same for
3229        # 1-register-only devices.
3230        return 1 if (i2c_smbus_read_byte($file) != $data);
3231
3232        # Then we try a standard byte read, with a register offset equal to
3233        # the byte we received; we should receive the same byte value in return.
3234        return 1 if (i2c_smbus_read_byte_data($file, $data) != $data);
3235
3236        # Then we try a standard byte read, with a slightly different register
3237        # offset; we should again receive the same byte value in return.
3238        return 1 if (i2c_smbus_read_byte_data($file, $data ^ 1) != ($data ^ 1));
3239
3240        # Apprently this is a 1-register-only device, restore the original
3241        # register value and leave it alone.
3242        i2c_smbus_read_byte_data($file, $data);
3243        return 0;
3244}
3245
3246####################
3247# ADAPTER SCANNING #
3248####################
3249
3250use vars qw(%chips_detected);
3251
3252# We will build a complicated structure %chips_detected here, being a hash
3253# where keys are driver names and values are detected chip information in
3254# the form of a list of hashes of type 'detect_data'.
3255
3256# Type detect_data:
3257# A hash
3258#  with field 'i2c_devnr', contianing the /dev/i2c-* number of this
3259#       adapter (if this is an I2C detection)
3260#  with field 'i2c_addr', containing the I2C address of the detection;
3261#       (if this is an I2C detection)
3262#  with field 'i2c_sub_addrs', containing a reference to a list of
3263#       other I2C addresses (if this is an I2C detection)
3264#  with field 'isa_addr' containing the ISA address this chip is on
3265#       (if this is an ISA detection)
3266#  with field 'conf', containing the confidence level of this detection
3267#  with field 'chipname', containing the chip name
3268#  with optional field 'alias_detect', containing a reference to an alias
3269#       detection function for this chip
3270
3271# This adds a detection to the above structure.
3272# Not all possibilities of i2c_addr and i2c_sub_addrs are exhausted.
3273# In all normal cases, it should be all right.
3274# $_[0]: chip driver
3275# $_[1]: reference to data hash
3276# Returns: Nothing
3277sub add_i2c_to_chips_detected
3278{
3279        my ($chipdriver, $datahash) = @_;
3280        my ($i, $detected_ref, $detected_entry, $driver,
3281            $put_in_detected, @hash_addrs, @entry_addrs);
3282
3283        # Find out whether our new entry should go into the detected list
3284        # or not. We compare all i2c addresses; if at least one matches,
3285        # but our confidence value is lower, we assume this is a misdetection,
3286        # in which case we simply discard our new entry.
3287        @hash_addrs = ($datahash->{i2c_addr});
3288        push @hash_addrs, @{$datahash->{i2c_sub_addrs}}
3289                if exists $datahash->{i2c_sub_addrs};
3290        $put_in_detected = 1;
3291 FIND_LOOP:
3292        foreach $detected_ref (values %chips_detected) {
3293                foreach $detected_entry (@{$detected_ref}) {
3294                        next unless defined $detected_entry->{i2c_addr};
3295                        @entry_addrs = ($detected_entry->{i2c_addr});
3296                        push @entry_addrs, @{$detected_entry->{i2c_sub_addrs}}
3297                                if exists $detected_entry->{i2c_sub_addrs};
3298                        if ($detected_entry->{i2c_devnr} == $datahash->{i2c_devnr} &&
3299                            any_list_match(\@entry_addrs, \@hash_addrs)) {
3300                                if ($detected_entry->{conf} >= $datahash->{conf}) {
3301                                        $put_in_detected = 0;
3302                                }
3303                                last FIND_LOOP;
3304                        }
3305                }
3306        }
3307
3308        return unless $put_in_detected;
3309
3310        # Here, we discard all entries which match at least in one main or
3311        # sub address. This may not be the best idea to do, as it may remove
3312        # detections without replacing them with second-best ones. Too bad.
3313        foreach $driver (keys %chips_detected) {
3314                $detected_ref = $chips_detected{$driver};
3315                for ($i = @$detected_ref-1; $i >=0; $i--) {
3316                        next unless defined $detected_ref->[$i]->{i2c_addr};
3317                        @entry_addrs = ($detected_ref->[$i]->{i2c_addr});
3318                        push @entry_addrs, @{$detected_ref->[$i]->{i2c_sub_addrs}}
3319                                if exists $detected_ref->[$i]->{i2c_sub_addrs};
3320                        if ($detected_ref->[$i]->{i2c_devnr} == $datahash->{i2c_devnr} &&
3321                            any_list_match(\@entry_addrs, \@hash_addrs)) {
3322                                splice @$detected_ref, $i, 1;
3323                                delete $chips_detected{$driver}
3324                                        if (!@$detected_ref);
3325                        }
3326                }
3327        }
3328
3329        # Now add the new entry to detected
3330        $chips_detected{$chipdriver} = []
3331                unless exists $chips_detected{$chipdriver};
3332        push @{$chips_detected{$chipdriver}}, $datahash;
3333}
3334
3335# Fake i2c drivers such as "not-a-sensor" or "use-isa-instead" have to be
3336# inserted so that confidence comparison can be performed. But then we have
3337# to filter them out so that the user doesn't get confused.
3338sub filter_out_fake_i2c_drivers
3339{
3340        delete $chips_detected{"not-a-sensor"};
3341        delete $chips_detected{"use-isa-instead"};
3342}
3343
3344# This adds a detection to the above structure.
3345# $_[0]: chip driver
3346# $_[1]: reference to data hash
3347sub add_isa_to_chips_detected
3348{
3349        my ($chipdriver, $datahash) = @_;
3350        my ($i, $new_detected_ref, $detected_ref);
3351
3352        # First determine where the hash has to be added.
3353        $chips_detected{$chipdriver} = []
3354                unless exists $chips_detected{$chipdriver};
3355        $new_detected_ref = $chips_detected{$chipdriver};
3356
3357        # Find out whether our new entry should go into the detected list
3358        # or not. We only compare main isa_addr here, of course.
3359        foreach $detected_ref (values %chips_detected) {
3360                for ($i = 0; $i < @{$detected_ref}; $i++) {
3361                        if (exists $detected_ref->[$i]->{isa_addr} and
3362                            exists $datahash->{isa_addr} and
3363                            $detected_ref->[$i]->{isa_addr} == $datahash->{isa_addr}) {
3364                                if ($detected_ref->[$i]->{conf} < $datahash->{conf}) {
3365                                        splice @$detected_ref, $i, 1;
3366                                        push @$new_detected_ref, $datahash;
3367                                }
3368                                return;
3369                        }
3370                }
3371        }
3372
3373        # Not found? OK, put it in the detected list
3374        push @$new_detected_ref, $datahash;
3375}
3376
3377# $_[0]: reference to an array of chips which may be aliases of each other
3378sub find_aliases
3379{
3380        my $detected = shift;
3381        my ($isa, $i2c, $dev, $alias_detect, $is_alias);
3382
3383        for ($isa = 0; $isa < @{$detected}; $isa++) {
3384                # Look for chips with an ISA address but no I2C address
3385                next unless defined $detected->[$isa];
3386                next unless $detected->[$isa]->{isa_addr};
3387                next if defined $detected->[$isa]->{i2c_addr};
3388                # Additionally, the chip must possibly have I2C aliases
3389                next unless defined $detected->[$isa]->{alias_detect};
3390
3391                for ($i2c = 0; $i2c < @{$detected}; $i2c++) {
3392                        # Look for chips with an I2C address but no ISA address
3393                        next unless defined $detected->[$i2c];
3394                        next unless defined $detected->[$i2c]->{i2c_addr};
3395                        next if $detected->[$i2c]->{isa_addr};
3396                        # Additionally, it must have the same chip name
3397                        next unless $detected->[$i2c]->{chipname} eq
3398                                    $detected->[$isa]->{chipname};
3399
3400                        # We have potential aliases, check if they actually are
3401                        $dev = $dev_i2c.$detected->[$i2c]->{i2c_devnr};
3402                        open(local *FILE, $dev) or
3403                                print("Can't open $dev\n"),
3404                                next;
3405                        binmode(FILE);
3406                        i2c_set_slave_addr(\*FILE, $detected->[$i2c]->{i2c_addr}) or
3407                                print("Can't set I2C address for $dev\n"),
3408                                next;
3409
3410                        initialize_ioports();
3411                        $alias_detect = $detected->[$isa]->{alias_detect};
3412                        $is_alias = &$alias_detect($detected->[$isa]->{isa_addr},
3413                                                   \*FILE,
3414                                                   $detected->[$i2c]->{i2c_addr});
3415                        close(FILE);
3416                        close_ioports();
3417
3418                        next unless $is_alias;
3419                        # This is an alias: copy the I2C data into the ISA
3420                        # entry, then discard the I2C entry
3421                        $detected->[$isa]->{i2c_devnr} = $detected->[$i2c]->{i2c_devnr};
3422                        $detected->[$isa]->{i2c_addr} = $detected->[$i2c]->{i2c_addr};
3423                        $detected->[$isa]->{i2c_sub_addr} = $detected->[$i2c]->{i2c_sub_addr};
3424                        undef $detected->[$i2c];
3425                        last;
3426                }
3427        }
3428
3429        # The loops above may have made the chip list sparse, make it
3430        # compact again
3431        for ($isa = 0; $isa < @{$detected}; ) {
3432                if (defined($detected->[$isa])) {
3433                        $isa++;
3434                } else {
3435                        splice @{$detected}, $isa, 1;
3436                }
3437        }
3438}
3439
3440# From the list of known I2C/SMBus devices, build a list of I2C addresses
3441# which are worth probing. There's no point in probing an address for which
3442# we don't know a single device, and probing some addresses has caused
3443# random trouble in the past.
3444sub i2c_addresses_to_scan
3445{
3446        my @used;
3447        my @addresses;
3448        my $addr;
3449
3450        foreach my $chip (@chip_ids) {
3451                next unless defined $chip->{i2c_addrs};
3452                foreach $addr (@{$chip->{i2c_addrs}}) {
3453                        $used[$addr]++;
3454                }
3455        }
3456
3457        for ($addr = 0x03; $addr <= 0x77; $addr++) {
3458                push @addresses, $addr if $used[$addr];
3459        }
3460        return \@addresses;
3461}
3462
3463# $_[0]: The number of the adapter to scan
3464# $_[1]: Address
3465sub add_busy_i2c_address
3466{
3467        my ($adapter_nr, $addr) = @_;
3468        # If the address is busy, we can normally find out which driver
3469        # requested it (if the kernel is recent enough, at least 2.6.16 and
3470        # later are known to work), and we assume it is the right one.
3471        my ($device, $driver, $new_hash);
3472
3473        $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x",
3474                          $adapter_nr, $addr);
3475        $driver = sysfs_device_driver($device);
3476
3477        if (!defined($driver)) {
3478                printf("Client at address 0x%02x can not be probed - ".
3479                       "unload all client drivers first!\n", $addr);
3480                return;
3481        }
3482
3483        $new_hash = {
3484                conf => 6, # Arbitrary confidence
3485                i2c_addr => $addr,
3486                chipname => sysfs_device_attribute($device, "name")
3487                         || "unknown",
3488                i2c_devnr => $adapter_nr,
3489        };
3490
3491        printf "Client found at address 0x\%02x\n", $addr;
3492        printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n",
3493               $driver, $new_hash->{chipname};
3494
3495        # Only add it to the list if this is something we would have detected,
3496        # else we end up with random i2c chip drivers listed (for example
3497        # media/video drivers.)
3498        if (exists $modules_supported{$driver}) {
3499                add_i2c_to_chips_detected($driver, $new_hash);
3500        } else {
3501                print "    (note: this is probably NOT a sensor chip!)\n";
3502        }
3503}
3504
3505# $_[0]: The number of the adapter to scan
3506# $_[1]: Address
3507# $_[2]: Chip being probed
3508sub probe_free_i2c_address
3509{
3510        my ($adapter_nr, $addr, $chip) = @_;
3511        my ($conf, @other_addr, $new_hash);
3512
3513        printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name}));
3514        if (($conf, @other_addr) = &{$chip->{i2c_detect}} (\*FILE, $addr)) {
3515                if ($chip->{driver} eq "not-a-sensor") {
3516                        print "Yes\n",
3517                              "    (confidence $conf, not a hardware monitoring chip";
3518                } else {
3519                        print "Success!\n",
3520                              "    (confidence $conf, driver `$chip->{driver}'";
3521                }
3522                if (@other_addr) {
3523                        print ", other addresses:";
3524                        @other_addr = sort @other_addr;
3525                        foreach my $other_addr (@other_addr) {
3526                                printf(" 0x%02x", $other_addr);
3527                        }
3528                }
3529                print ")\n";
3530
3531                $new_hash = {
3532                        conf => $conf,
3533                        i2c_addr => $addr,
3534                        chipname => $chip->{name},
3535                        i2c_devnr => $adapter_nr,
3536                };
3537                if (@other_addr) {
3538                        my @other_addr_copy = @other_addr;
3539                        $new_hash->{i2c_sub_addrs} = \@other_addr_copy;
3540                }
3541                add_i2c_to_chips_detected($chip->{driver}, $new_hash);
3542        } else {
3543                print "No\n";
3544        }
3545}
3546
3547# $_[0]: The device to check (PCI or not)
3548# Returns: PCI class of the adapter if available, 0 if not
3549sub get_pci_class
3550{
3551        my ($device) = @_;
3552        my ($subsystem, $class);
3553
3554        $subsystem = sysfs_device_subsystem($device);
3555        return 0 unless defined $subsystem && $subsystem eq "pci";
3556
3557        $class = sysfs_device_attribute($device, "class");
3558        return 0 unless defined $class;
3559        $class = oct($class) if $class =~ /^0/;
3560        return $class >> 8;
3561}
3562
3563# $_[0]: The number of the adapter to scan
3564sub scan_i2c_adapter
3565{
3566        my ($adapter_nr, $smbus_default) = @_;
3567        my ($funcs, $chip, $addr, $class, $default, $input, @not_to_scan);
3568
3569        $class = get_pci_class($i2c_adapters[$adapter_nr]->{parent});
3570        if (($class & 0xff00) == 0x0400) {
3571                # Do not probe adapters on PCI multimedia cards by default
3572                $default = 0;
3573        } elsif ($class == 0x0c01 || $class == 0x0c05
3574              || find_i2c_adapter_driver($i2c_adapters[$adapter_nr]->{name})) {
3575                $default = $smbus_default;
3576        } else {
3577                $default = 1;
3578        }
3579
3580        printf "Next adapter: $i2c_adapters[$adapter_nr]->{name} (i2c-$adapter_nr)\n".
3581               "Do you want to scan it? (\%s/selectively): ",
3582               $default ? "YES/no" : "yes/NO";
3583
3584        $input = <STDIN>;
3585        if ($input =~ /^\s*n/i
3586         || (!$default && $input !~ /^\s*[ys]/i)) {
3587                print "\n";
3588                return;
3589        }
3590
3591        if ($input =~ /^\s*s/i) {
3592                print "Please enter one or more addresses not to scan. Separate them with commas.\n",
3593                      "You can specify a range by using dashes. Example: 0x58-0x5f,0x69.\n",
3594                      "Addresses: ";
3595                $input = <STDIN>;
3596                chomp($input);
3597                @not_to_scan = parse_not_to_scan(0x03, 0x77, $input);
3598        }
3599
3600        open(local *FILE, "$dev_i2c$adapter_nr") or
3601                (print "Can't open $dev_i2c$adapter_nr\n"), return;
3602        binmode(FILE);
3603
3604        # Can we probe this adapter?
3605        $funcs = i2c_get_funcs(\*FILE);
3606        if ($funcs < 0) {
3607                print "Adapter failed to provide its functionalities, skipping.\n";
3608                return;
3609        }
3610        if (!($funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_READ_BYTE_DATA))) {
3611                print "Adapter cannot be probed, skipping.\n";
3612                return;
3613        }
3614        if (~$funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
3615                print "Adapter doesn't support all probing functions.\n",
3616                      "Some addresses won't be probed.\n";
3617        }
3618
3619        # Now scan each address in turn
3620        foreach $addr (@{$i2c_addresses_to_scan}) {
3621                # As the not_to_scan list is sorted, we can check it fast
3622                shift @not_to_scan # User skipped an address which we didn't intend to probe anyway
3623                        while (@not_to_scan and $not_to_scan[0] < $addr);
3624                if (@not_to_scan and $not_to_scan[0] == $addr) {
3625                        shift @not_to_scan;
3626                        next;
3627                }
3628
3629                if (!i2c_set_slave_addr(\*FILE, $addr)) {
3630                        add_busy_i2c_address($adapter_nr, $addr);
3631                        next;
3632                }
3633
3634                next unless i2c_probe(\*FILE, $addr, $funcs);
3635                printf "Client found at address 0x%02x\n", $addr;
3636                if (!i2c_safety_check(\*FILE)) {
3637                        print "Seems to be a 1-register-only device, skipping.\n";
3638                        next;
3639                }
3640
3641                $| = 1;
3642                foreach $chip (@chip_ids, @non_hwmon_chip_ids) {
3643                        next unless exists $chip->{i2c_addrs}
3644                                 && contains($addr, @{$chip->{i2c_addrs}});
3645                        probe_free_i2c_address($adapter_nr, $addr, $chip);
3646                }
3647                $| = 0;
3648        }
3649        print "\n";
3650}
3651
3652sub scan_isa_bus
3653{
3654        my $chip_list_ref = shift;
3655        my ($chip, $addr, $conf);
3656
3657        $| = 1;
3658        foreach $chip (@{$chip_list_ref}) {
3659                next if not exists $chip->{isa_addrs} or not exists $chip->{isa_detect};
3660                foreach $addr (@{$chip->{isa_addrs}}) {
3661                        printf("\%-60s", sprintf("Probing for `\%s' at 0x\%x... ",
3662                                                 $chip->{name}, $addr));
3663                        $conf = &{$chip->{isa_detect}} ($addr);
3664                        print("No\n"), next if not defined $conf;
3665                        print "Success!\n";
3666                        printf "    (confidence %d, driver `%s')\n", $conf, $chip->{driver};
3667                        my $new_hash = {
3668                                conf => $conf,
3669                                isa_addr => $addr,
3670                                chipname => $chip->{name},
3671                                alias_detect => $chip->{alias_detect},
3672                        };
3673                        add_isa_to_chips_detected($chip->{driver}, $new_hash);
3674                }
3675        }
3676        $| = 0;
3677}
3678
3679use vars qw(%standard_superio);
3680
3681# The following are taken from the PNP ISA spec (so it's supposed
3682# to be common to all Super I/O chips):
3683#  devidreg: The device ID register(s)
3684#  logdevreg: The logical device register
3685#  actreg: The activation register within the logical device
3686#  actmask: The activation bit in the activation register
3687#  basereg_*: The I/O base registers within the logical device
3688%standard_superio = (
3689        devidreg => 0x20,
3690        logdevreg => 0x07,
3691        actreg => 0x30,
3692        actmask => 0x01,
3693        basereg_msb => 0x60,
3694        basereg_lsb => 0x61,
3695);
3696
3697sub exit_superio
3698{
3699        my ($addrreg, $datareg) = @_;
3700
3701        # Some chips (SMSC, Winbond) want this
3702        outb($addrreg, 0xaa);
3703
3704        # Return to "Wait For Key" state (PNP-ISA spec)
3705        outb($addrreg, 0x02);
3706        outb($datareg, 0x02);
3707}
3708
3709# Guess if an unknown Super-I/O chip has sensors
3710sub guess_superio_ld
3711{
3712        my ($addrreg, $datareg, $typical_addr) = @_;
3713        my ($oldldn, $ldn, $addr);
3714
3715        # Save logical device number
3716        outb($addrreg, $standard_superio{logdevreg});
3717        $oldldn = inb($datareg);
3718
3719        for ($ldn = 0; $ldn < 16; $ldn++) {
3720                # Select logical device
3721                outb($addrreg, $standard_superio{logdevreg});
3722                outb($datareg, $ldn);
3723
3724                # Read base I/O address
3725                outb($addrreg, $standard_superio{basereg_msb});
3726                $addr = inb($datareg) << 8;
3727                outb($addrreg, $standard_superio{basereg_lsb});
3728                $addr |= inb($datareg);
3729                next unless ($addr & 0xfff8) == $typical_addr;
3730
3731                printf "    (logical device \%X has address 0x\%x, could be sensors)\n",
3732                       $ldn, $addr;
3733                last;
3734        }
3735
3736        # Be nice, restore original logical device
3737        outb($addrreg, $standard_superio{logdevreg});
3738        outb($datareg, $oldldn);
3739}
3740
3741# Returns: features bitmask if device added to chips_detected, 0 if not
3742sub probe_superio
3743{
3744        my ($addrreg, $datareg, $chip) = @_;
3745        my ($val, $addr);
3746        my %superio;
3747
3748        # Use chip-specific registers if provided
3749        if (exists $chip->{regs}) {
3750                %superio = overlay_hash(\%standard_superio, $chip->{regs});
3751        } else {
3752                %superio = %standard_superio;
3753        }
3754
3755        if (exists $chip->{check}) {
3756                return 0 unless $chip->{check}($addrreg, $datareg);
3757        }
3758
3759        printf "\%-60s", "Found `$chip->{name}'";
3760
3761        # Does it have hardware monitoring capabilities?
3762        if (!exists $chip->{driver}) {
3763                print "\n    (no information available)\n";
3764                return 0;
3765        }
3766        if ($chip->{driver} eq "not-a-sensor") {
3767                print "\n    (no hardware monitoring capabilities)\n";
3768                return 0;
3769        }
3770        if ($chip->{driver} eq "via-smbus-only") {
3771                print "\n    (hardware monitoring capabilities accessible via SMBus only)\n";
3772                return FEAT_SMBUS;
3773        }
3774        if (!exists $chip->{logdev}) {
3775                print "\n    (no support yet)\n";
3776                return 0;
3777        }
3778
3779        # Switch to the sensor logical device
3780        outb($addrreg, $superio{logdevreg});
3781        outb($datareg, $chip->{logdev});
3782
3783        # Get the IO base address
3784        outb($addrreg, $superio{basereg_msb});
3785        $addr = inb($datareg);
3786        outb($addrreg, $superio{basereg_lsb});
3787        $addr = ($addr << 8) | inb($datareg);
3788
3789        # Check the activation register and base address
3790        outb($addrreg, $superio{actreg});
3791        $val = inb($datareg);
3792        if (!($val & $superio{actmask})) {
3793                if ($addr && $addr != 0xffff) {
3794                        printf "\n    (address 0x\%x, but not activated)\n", $addr;
3795                } else {
3796                        print "\n    (but not activated)\n";
3797                }
3798                return 0;
3799        }
3800        if ($addr == 0 || $addr == 0xffff) {
3801                print "\n    (but no address specified)\n";
3802                return 0;
3803        }
3804
3805        print "Success!\n";
3806        printf "    (address 0x\%x, driver `%s')\n", $addr, $chip->{driver};
3807        my $new_hash = {
3808                conf => 9,
3809                isa_addr => $addr,
3810                chipname => $chip->{name}
3811        };
3812        add_isa_to_chips_detected($chip->{driver}, $new_hash);
3813        return $chip->{features};
3814}
3815
3816# Detection routine for non-standard SMSC Super I/O chips
3817# $_[0]: Super I/O LPC config/index port
3818# $_[1]: Super I/O LPC data port
3819# $_[2]: Reference to array of non-standard chips
3820# Return values: 1 if non-standard chip found, 0 otherwise
3821sub smsc_ns_detect_superio
3822{
3823        my ($addrreg, $datareg, $ns_chips) = @_;
3824        my ($val, $chip);
3825
3826        # read alternate device ID register
3827        outb($addrreg, 0x0d);
3828        $val = inb($datareg);
3829        return 0 if $val == 0x00 || $val == 0xff;
3830
3831        print "Yes\n";
3832
3833        foreach $chip (@{$ns_chips}) {
3834                if ($chip->{devid} == $val) {
3835                        probe_superio($addrreg, $datareg, $chip);
3836                        return 1;
3837                }
3838        }
3839
3840        printf("Found unknown non-standard chip with ID 0x%02x\n", $val);
3841        return 1;
3842}
3843
3844# Returns: features supported by the device added, if any
3845sub scan_superio
3846{
3847        my ($addrreg, $datareg) = @_;
3848        my ($val, $found);
3849        my $features = 0;
3850
3851        printf("Probing for Super-I/O at 0x\%x/0x\%x\n", $addrreg, $datareg);
3852
3853        $| = 1;
3854        # reset state to avoid false positives
3855        exit_superio($addrreg, $datareg);
3856        foreach my $family (@superio_ids) {
3857                printf("\%-60s", "Trying family `$family->{family}'... ");
3858                # write the password
3859                foreach $val (@{$family->{enter}->{$addrreg}}) {
3860                        outb($addrreg, $val);
3861                }
3862                # call the non-standard detection routine first if it exists
3863                if (defined($family->{ns_detect}) &&
3864                    &{$family->{ns_detect}}($addrreg, $datareg, $family->{ns_chips})) {
3865                        last;
3866                }
3867
3868                # did it work?
3869                outb($addrreg, $standard_superio{devidreg});
3870                $val = inb($datareg);
3871                outb($addrreg, $standard_superio{devidreg} + 1);
3872                $val = ($val << 8) | inb($datareg);
3873                if ($val == 0x0000 || $val == 0xffff) {
3874                        print "No\n";
3875                        next;
3876                }
3877                print "Yes\n";
3878
3879                $found = 0;
3880                foreach my $chip (@{$family->{chips}}) {
3881                        if (($chip->{devid} > 0xff &&
3882                             ($val & ($chip->{devid_mask} || 0xffff)) == $chip->{devid})
3883                         || ($chip->{devid} <= 0xff &&
3884                             ($val >> 8) == $chip->{devid})) {
3885                                $features |= probe_superio($addrreg, $datareg, $chip);
3886                                $found++;
3887                        }
3888                }
3889
3890                if (!$found) {
3891                        printf("Found unknown chip with ID 0x%04x\n", $val);
3892                        # Guess if a logical device could correspond to sensors
3893                        guess_superio_ld($addrreg, $datareg, $family->{guess})
3894                                if defined $family->{guess};
3895                }
3896                last;
3897        }
3898        exit_superio($addrreg, $datareg);
3899        $| = 0;
3900        return $features;
3901}
3902
3903sub scan_cpu
3904{
3905        my $entry = shift;
3906        my $confidence;
3907
3908        printf("\%-60s", "$entry->{name}... ");
3909        if (defined ($confidence = $entry->{detect}())) {
3910                print "Success!\n";
3911                printf "    (driver `%s')\n", $entry->{driver};
3912                my $new_hash = {
3913                        conf => $confidence,
3914                        chipname => $entry->{name},
3915                };
3916                add_isa_to_chips_detected($entry->{driver}, $new_hash);
3917        } else {
3918                print "No\n";
3919        }
3920}
3921
3922##################
3923# CHIP DETECTION #
3924##################
3925
3926# This routine allows you to dynamically update the chip detection list.
3927# The most common use is to allow for different chip to driver mappings
3928# based on different linux kernels
3929sub chip_special_cases
3930{
3931        # Some chip to driver mappings depend on the environment
3932        foreach my $chip (@chip_ids) {
3933                if (ref($chip->{driver}) eq 'CODE') {
3934                        $chip->{driver} = $chip->{driver}->();
3935                }
3936        }
3937
3938        # Also fill the fake driver name of non-hwmon chips
3939        foreach my $chip (@non_hwmon_chip_ids) {
3940                $chip->{driver} = "not-a-sensor";
3941        }
3942}
3943
3944# Each function returns a confidence value. The higher this value, the more
3945# sure we are about this chip. This may help overrule false positives,
3946# although we also attempt to prevent false positives in the first place.
3947
3948# Each function returns a list. The first element is the confidence value;
3949# Each element after it is an SMBus address. In this way, we can detect
3950# chips with several SMBus addresses. The SMBus address for which the
3951# function was called is never returned.
3952
3953# All I2C detection functions below take at least 2 parameters:
3954# $_[0]: Reference to the file descriptor to access the chip
3955# $_[1]: Address
3956# Some of these functions which can detect more than one type of device,
3957# take a third parameter:
3958# $_[2]: Chip to detect
3959
3960# Registers used: 0x58
3961sub mtp008_detect
3962{
3963        my ($file, $addr) = @_;
3964        return if i2c_smbus_read_byte_data($file, 0x58) != 0xac;
3965        return 3;
3966}
3967
3968# Chip to detect: 0 = LM78, 2 = LM79
3969# Registers used:
3970#   0x40: Configuration
3971#   0x48: Full I2C Address
3972#   0x49: Device ID
3973sub lm78_detect
3974{
3975        my ($file, $addr, $chip) = @_;
3976        my $reg;
3977
3978        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
3979        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
3980
3981        $reg = i2c_smbus_read_byte_data($file, 0x49);
3982        return if $chip == 0 && ($reg != 0x00 && $reg != 0x20 && $reg != 0x40);
3983        return if $chip == 2 && ($reg & 0xfe) != 0xc0;
3984
3985        # Explicitly prevent misdetection of Winbond chips
3986        $reg = i2c_smbus_read_byte_data($file, 0x4f);
3987        return if $reg == 0xa3 || $reg == 0x5c;
3988
3989        return 6;
3990}
3991
3992# Chip to detect: 0 = LM75, 1 = DS75, 2 = LM75A
3993# Registers used:
3994#   0x00: Temperature
3995#   0x01: Configuration
3996#   0x02: Hysteresis
3997#   0x03: Overtemperature Shutdown
3998#   0x04-0x07: No registers
3999#   0x07: Device ID (LM75A only)
4000# The first detection step is based on the fact that the LM75 has only
4001# four registers, and cycles addresses over 8-byte boundaries. We use the
4002# 0x04-0x07 addresses (unused) to improve the reliability. These are not
4003# real registers and will always return the last returned value. This isn't
4004# documented.
4005# Note that register 0x00 may change, so we can't use the modulo trick on it.
4006# The DS75 is a bit different, it doesn't cycle over 8-byte boundaries, and
4007# all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for
4008# the LM75.
4009# And the LM75A is again different, it cycles over 8-byte boundaries, but
4010# registers 0x04-0x06 return 0xff. Thankfully it has a device ID register
4011# at 0x07.
4012# Not all devices enjoy SMBus read word transactions, so we use read byte
4013# transactions even for the 16-bit registers. The low bits aren't very
4014# useful for detection anyway.
4015sub lm75_detect
4016{
4017        my ($file, $addr, $chip) = @_;
4018        my $i;
4019        my $cur = i2c_smbus_read_byte_data($file, 0x00);
4020        my $conf = i2c_smbus_read_byte_data($file, 0x01);
4021        my ($maxreg, $hyst, $os, $dev_id);
4022
4023        if ($chip == 2) {       # LM75A
4024                $dev_id = i2c_smbus_read_byte_data($file, 0x07);
4025                return if $dev_id != 0xA1;
4026
4027                $hyst = i2c_smbus_read_byte_data($file, 0x02);
4028                $os = i2c_smbus_read_byte_data($file, 0x03);
4029
4030                for $i (0x04 .. 0x06) {
4031                        return if i2c_smbus_read_byte_data($file, $i) != 0xff;
4032                }
4033        } else {                # LM75 or DS75
4034                $maxreg = $chip == 1 ? 0x0f : 0x07;
4035                $hyst = i2c_smbus_read_byte_data($file, 0x02, NO_CACHE);
4036                for $i (0x04 .. $maxreg) {
4037                        return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $hyst;
4038                }
4039
4040                $os = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
4041                for $i (0x04 .. $maxreg) {
4042                        return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $os;
4043                }
4044        }
4045
4046        if ($chip != 1) {       # LM75 or LM75A
4047                for ($i = 8; $i <= 248; $i += 40) {
4048                        return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf
4049                               or i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst
4050                               or i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
4051                        return if $chip == 2
4052                              and i2c_smbus_read_byte_data($file, $i + 0x07) != $dev_id;
4053                }
4054        }
4055
4056        # All registers hold the same value, obviously a misdetection
4057        return if $conf == $cur and $cur == $hyst and $cur == $os;
4058
4059        # Unused bits
4060        return if $chip != 1 and ($conf & 0xe0);
4061        return if $chip == 1 and ($conf & 0x80);
4062
4063        # Most probable value ranges
4064        return 6 if $cur <= 100 and ($hyst >= 10 && $hyst <= 125)
4065                and ($os >= 20 && $os <= 127) and $hyst < $os;
4066        return 3;
4067}
4068
4069# Registers used:
4070#   0x00: Temperature
4071#   0x01: Configuration
4072#   0x02: High Limit
4073#   0x03: Low Limit
4074#   0x04: Status
4075#   0x07: Manufacturer ID and Product ID
4076sub lm73_detect
4077{
4078        my ($file, $addr) = @_;
4079
4080        my $conf = i2c_smbus_read_byte_data($file, 0x01);
4081        my $status = i2c_smbus_read_byte_data($file, 0x04);
4082
4083        # Bits that always return 0
4084        return if ($conf & 0x0c) or ($status & 0x10);
4085
4086        # Test with byte read first to avoid confusing other chips
4087        return if i2c_smbus_read_byte_data($file, 0x07) != 0x01
4088               or i2c_smbus_read_word_data($file, 0x07) != 0x9001;
4089
4090        # Make sure the chip supports SMBus read word transactions
4091        my $cur = i2c_smbus_read_word_data($file, 0x00);
4092        return if $cur < 0;
4093        my $high = i2c_smbus_read_word_data($file, 0x02);
4094        return if $high < 0;
4095        my $low = i2c_smbus_read_word_data($file, 0x03);
4096        return if $low < 0;
4097        return if ($cur & 0x0300) or (($high | $low) & 0x1f00);
4098
4099        return 3;
4100}
4101
4102# Registers used:
4103#   0x00: Temperature
4104#   0x01: Configuration
4105#   0x02: Hysteresis
4106#   0x03: Overtemperature Shutdown
4107#   0x04: Low limit
4108#   0x05: High limit
4109#   0x06-0x07: No registers
4110# The first detection step is based on the fact that the LM77 has only
4111# six registers, and cycles addresses over 8-byte boundaries. We use the
4112# 0x06-0x07 addresses (unused) to improve the reliability. These are not
4113# real registers and will always return the last returned value. This isn't
4114# documented.
4115# Note that register 0x00 may change, so we can't use the modulo trick on it.
4116# Not all devices enjoy SMBus read word transactions, so we use read byte
4117# transactions even for the 16-bit registers at first. We only use read word
4118# transactions in the end when we are already almost certain that we have an
4119# LM77 chip.
4120sub lm77_detect
4121{
4122        my ($file, $addr) = @_;
4123        my $i;
4124        my $cur = i2c_smbus_read_byte_data($file, 0x00);
4125        my $conf = i2c_smbus_read_byte_data($file, 0x01);
4126        my $hyst = i2c_smbus_read_byte_data($file, 0x02);
4127        my $os = i2c_smbus_read_byte_data($file, 0x03);
4128
4129        my $low = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
4130        return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $low;
4131        return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $low;
4132
4133        my $high = i2c_smbus_read_byte_data($file, 0x05, NO_CACHE);
4134        return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $high;
4135        return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $high;
4136
4137        for ($i = 8; $i <= 248; $i += 40) {
4138                return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
4139                return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
4140                return if i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
4141                return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
4142                return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
4143        }
4144
4145        # All registers hold the same value, obviously a misdetection
4146        return if $conf == $cur and $cur == $hyst
4147              and $cur == $os and $cur == $low and $cur == $high;
4148
4149        # Unused bits
4150        return if ($conf & 0xe0)
4151               or (($cur >> 4) != 0 && ($cur >> 4) != 0xf)
4152               or (($hyst >> 4) != 0 && ($hyst >> 4) != 0xf)
4153               or (($os >> 4) != 0 && ($os >> 4) != 0xf)
4154               or (($low >> 4) != 0 && ($low >> 4) != 0xf)
4155               or (($high >> 4) != 0 && ($high >> 4) != 0xf);
4156
4157        # Make sure the chip supports SMBus read word transactions
4158        foreach $i (0x00, 0x02, 0x03, 0x04, 0x05) {
4159                return if i2c_smbus_read_word_data($file, $i) < 0;
4160        }
4161
4162        return 3;
4163}
4164
4165# Chip to detect: 0 = LM92, 1 = LM76, 2 = MAX6633/MAX6634/MAX6635
4166# Registers used:
4167#   0x01: Configuration (National Semiconductor only)
4168#   0x02: Hysteresis
4169#   0x03: Critical Temp
4170#   0x04: Low Limit
4171#   0x05: High Limit
4172#   0x07: Manufacturer ID (LM92 only)
4173# One detection step is based on the fact that the LM92 and clones have a
4174# limited number of registers, which cycle modulo 16 address values.
4175# Note that register 0x00 may change, so we can't use the modulo trick on it.
4176# Not all devices enjoy SMBus read word transactions, so we use read byte
4177# transactions even for the 16-bit registers at first. We only use read
4178# word transactions in the end when we are already almost certain that we
4179# have an LM92 chip or compatible.
4180sub lm92_detect
4181{
4182        my ($file, $addr, $chip) = @_;
4183
4184        my $conf = i2c_smbus_read_byte_data($file, 0x01);
4185        my $hyst = i2c_smbus_read_byte_data($file, 0x02);
4186        my $crit = i2c_smbus_read_byte_data($file, 0x03);
4187        my $low = i2c_smbus_read_byte_data($file, 0x04);
4188        my $high = i2c_smbus_read_byte_data($file, 0x05);
4189
4190        return if $conf == 0 and $hyst == 0 and $crit == 0
4191                and $low == 0 and $high == 0;
4192
4193        # Unused bits
4194        return if ($chip == 0 || $chip == 1)
4195              and ($conf & 0xE0);
4196
4197        for (my $i = 0; $i <= 240; $i += 16) {
4198                return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
4199                return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
4200                return if i2c_smbus_read_byte_data($file, $i + 0x03) != $crit;
4201                return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
4202                return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
4203        }
4204
4205        return if $chip == 0
4206              and i2c_smbus_read_word_data($file, 0x07) != 0x0180;
4207
4208        # Make sure the chip supports SMBus read word transactions
4209        $hyst = i2c_smbus_read_word_data($file, 0x02);
4210        return if $hyst < 0;
4211        $crit = i2c_smbus_read_word_data($file, 0x03);
4212        return if $crit < 0;
4213        $low = i2c_smbus_read_word_data($file, 0x04);
4214        return if $low < 0;
4215        $high = i2c_smbus_read_word_data($file, 0x05);
4216        return if $high < 0;
4217
4218        foreach my $temp ($hyst, $crit, $low, $high) {
4219                return if $chip == 2 and ($temp & 0x7F00);
4220                return if $chip != 2 and ($temp & 0x0700);
4221        }
4222
4223        return ($chip == 0) ? 4 : 2;
4224}
4225
4226# Registers used:
4227#   0xAA: Temperature
4228#   0xA1: High limit
4229#   0xA2: Low limit
4230#   0xA8: Counter
4231#   0xA9: Slope
4232#   0xAC: Configuration
4233# Detection is weak. We check if bit 4 (NVB) is clear, because it is
4234# unlikely to be set (would mean that EEPROM is currently being accessed).
4235# We also check the value of the counter and slope registers, the datasheet
4236# doesn't mention the possible values but the conversion formula together
4237# with experimental evidence suggest possible sanity checks.
4238# Not all devices enjoy SMBus read word transactions, so we do as much as
4239# possible with read byte transactions first, and only use read word
4240# transactions second.
4241sub ds1621_detect
4242{
4243        my ($file, $addr) = @_;
4244
4245        my $conf = i2c_smbus_read_byte_data($file, 0xAC);
4246        return if ($conf & 0x10);
4247
4248        my $temp = i2c_smbus_read_word_data($file, 0xAA);
4249        return if $temp < 0 || ($temp & 0x0f00);
4250        # On the DS1631, the following two checks are too strict in theory,
4251        # but in practice I very much doubt that anyone will set temperature
4252        # limits not a multiple of 0.5 degrees C.
4253        my $high = i2c_smbus_read_word_data($file, 0xA1);
4254        return if $high < 0 || ($high & 0x7f00);
4255        my $low = i2c_smbus_read_word_data($file, 0xA2);
4256        return if $low < 0 || ($low & 0x7f00);
4257
4258        return if ($temp == 0 && $high == 0 && $low == 0 && $conf == 0);
4259
4260        # Old versions of the DS1621 apparently don't have the counter and
4261        # slope registers (or they return crap)
4262        my $counter = i2c_smbus_read_byte_data($file, 0xA8);
4263        my $slope = i2c_smbus_read_byte_data($file, 0xA9);
4264        return ($slope == 0x10 && $counter <= $slope) ? 3 : 2;
4265}
4266
4267# Chip to detect: 0 = LM80, 1 = LM96080
4268# Registers used:
4269#   0x00: Configuration register
4270#   0x02: Interrupt state register
4271#   0x07: Converstion rate register (LM96080 only)
4272#   0x2a-0x3d: Limits registers (LM80 only)
4273#   0x3e: Manufacturer's ID register (LM96080 only)
4274#   0x3f: Stepping/die revision ID register (LM96080 only)
4275# The LM80 is easily misdetected since it doesn't provide identification
4276# registers. So we have to use some tricks:
4277#   - 6-bit addressing, so limits readings modulo 0x40 should be unchanged
4278#   - positive temperature limits
4279#   - limits order correctness
4280# Hopefully this should limit the rate of false positives, without increasing
4281# the rate of false negatives.
4282# Thanks to Lennard Klein for testing on a non-LM80 chip, which was
4283# previously misdetected, and isn't anymore. For reference, it scored
4284# a final confidence of 0, and changing from strict limit comparisons
4285# to loose comparisons did not change the score.
4286sub lm80_detect
4287{
4288        my ($file, $addr, $chip) = @_;
4289        my ($i, $reg);
4290
4291        return if (i2c_smbus_read_byte_data($file, 0x00) & 0x80) != 0;
4292        return if (i2c_smbus_read_byte_data($file, 0x02) & 0xc0) != 0;
4293
4294        if ($chip == 0) {
4295                for ($i = 0x2a; $i <= 0x3d; $i++) {
4296                        $reg = i2c_smbus_read_byte_data($file, $i);
4297                        return if i2c_smbus_read_byte_data($file, $i+0x40) != $reg;
4298                        return if i2c_smbus_read_byte_data($file, $i+0x80) != $reg;
4299                        return if i2c_smbus_read_byte_data($file, $i+0xc0) != $reg;
4300                }
4301
4302                # Refine a bit by checking whether limits are in the correct order
4303                # (min<max for voltages, hyst<max for temperature). Since it is still
4304                # possible that the chip is an LM80 with limits not properly set,
4305                # a few "errors" are tolerated.
4306                my $confidence = 0;
4307                for ($i = 0x2a; $i <= 0x3a; $i++) {
4308                        $confidence++
4309                                if i2c_smbus_read_byte_data($file, $i) < i2c_smbus_read_byte_data($file, $i+1);
4310                }
4311                # hot temp<OS temp
4312                $confidence++
4313                        if i2c_smbus_read_byte_data($file, 0x38) < i2c_smbus_read_byte_data($file, 0x3a);
4314
4315                # Negative temperature limits are unlikely.
4316                for ($i = 0x3a; $i <= 0x3d; $i++) {
4317                        $confidence++ if (i2c_smbus_read_byte_data($file, $i) & 0x80) == 0;
4318                }
4319
4320                # $confidence is between 0 and 14
4321                $confidence = ($confidence >> 1) - 4;
4322                # $confidence is now between -4 and 3
4323
4324                return unless $confidence > 0;
4325                return $confidence;
4326        } elsif ($chip == 1) {
4327                return if (i2c_smbus_read_byte_data($file, 0x07) & 0xfe) != 0;
4328                return if i2c_smbus_read_byte_data($file, 0x3e) != 0x01;
4329                return if i2c_smbus_read_byte_data($file, 0x3f) != 0x08;
4330
4331                return 6;
4332        }
4333}
4334
4335# Registers used:
4336#   0x02: Status 1
4337#   0x03: Configuration
4338#   0x04: Company ID of LM84
4339#   0x35: Status 2
4340#   0xfe: Manufacturer ID
4341#   0xff: Chip ID / die revision
4342# We can use the LM84 Company ID register because the LM83 and the LM82 are
4343# compatible with the LM84.
4344# The LM83 chip ID is missing from the datasheet and was contributed by
4345# Magnus Forsstrom: 0x03.
4346# At least some revisions of the LM82 seem to be repackaged LM83, so they
4347# have the same chip ID, and temp2/temp4 will be stuck in "OPEN" state.
4348# For this reason, we don't even try to distinguish between both chips.
4349# Thanks to Ben Gardner for reporting.
4350sub lm83_detect
4351{
4352        my ($file, $addr) = @_;
4353        return if i2c_smbus_read_byte_data($file, 0xfe) != 0x01;
4354        my $chipid = i2c_smbus_read_byte_data($file, 0xff);
4355        return if $chipid != 0x01 && $chipid != 0x03;
4356
4357        my $confidence = 4;
4358        $confidence++
4359                if (i2c_smbus_read_byte_data($file, 0x02) & 0xa8) == 0x00;
4360        $confidence++
4361                if (i2c_smbus_read_byte_data($file, 0x03) & 0x41) == 0x00;
4362        $confidence++
4363                if i2c_smbus_read_byte_data($file, 0x04) == 0x00;
4364        $confidence++
4365                if (i2c_smbus_read_byte_data($file, 0x35) & 0x48) == 0x00;
4366
4367        return $confidence;
4368}
4369
4370# Chip to detect: 0 = MAX6680/81, 1 = MAX6695/96
4371# Registers used:
4372#   0x03: Configuration
4373#   0x04: Conversion rate
4374#   0x12: Status2
4375#   0x16: Overtemperature 2
4376#   0xfe: Manufacturer ID
4377#   0xff: Chip ID / die revision
4378sub max6680_95_detect
4379{
4380        my ($file, $addr, $chip) = @_;
4381        my $cid = i2c_smbus_read_byte_data($file, 0xff);
4382        my $conf = i2c_smbus_read_byte_data($file, 0x03);
4383        my $mid = i2c_smbus_read_byte_data($file, 0xfe, NO_CACHE);
4384        my $emerg = i2c_smbus_read_byte_data($file, 0x16, NO_CACHE);
4385        my $rate = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
4386        my $emerg2 = i2c_smbus_read_byte_data($file, 0x16, NO_CACHE);
4387
4388        # Check common conditions
4389        return if $rate > 0x07;
4390        return if $mid != 0x4d;         # Not Maxim
4391        return if $cid != 0x01;         # None of the chips we are looking for
4392
4393        if ($chip == 0) {
4394                return if ($conf & 0x03) != 0;
4395                return 8 if $emerg != $emerg2;  # MAX6680/MAX6681
4396        }
4397        if ($chip == 1) {
4398                my $status2 = i2c_smbus_read_byte_data($file, 0x12);
4399
4400                return if ($conf & 0x10) != 0;
4401                return if ($status2 & 0x01) != 0;
4402                return 8 if $emerg == $emerg2;  # MAX6695/MAX6696
4403        }
4404        return;
4405}
4406
4407# Chip to detect: 0 = LM90, 1 = LM89/LM99, 2 = LM86, 3 = ADM1032,
4408#                 4 = MAX6654, 5 = ADT7461,
4409#                 6 = MAX6646/MAX6647/MAX6648/MAX6649/MAX6692,
4410#                 8 = W83L771W/G, 9 = TMP401, 10 = TMP411,
4411#                 11 = W83L771AWG/ASG, 12 = MAX6690,
4412#                 13 = ADT7461A/NCT1008, 14 = SA56004,
4413#                 15 = G781
4414# Registers used:
4415#   0x03: Configuration
4416#   0x04: Conversion rate
4417#   0xbf: Configuration 2 (National Semiconductor, Winbond, and Philips only)
4418#   0xfe: Manufacturer ID
4419#   0xff: Chip ID / die revision
4420sub lm90_detect
4421{
4422        my ($file, $addr, $chip) = @_;
4423        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4424        my $cid = i2c_smbus_read_byte_data($file, 0xff);
4425        my $conf = i2c_smbus_read_byte_data($file, 0x03);
4426        my $rate = i2c_smbus_read_byte_data($file, 0x04);
4427        my $conf2 = i2c_smbus_read_byte_data($file, 0xbf);
4428
4429        if ($chip == 0) {
4430                return if ($conf & 0x2a) != 0;
4431                return if ($conf2 & 0xf8) != 0;
4432                return if $rate > 0x09;
4433                return if $mid != 0x01;         # National Semiconductor
4434                return 8 if $cid == 0x21;       # LM90
4435                return 6 if ($cid & 0x0f) == 0x20;
4436        }
4437        if ($chip == 1) {
4438                return if ($conf & 0x2a) != 0;
4439                return if ($conf2 & 0xf8) != 0;
4440                return if $rate > 0x09;
4441                return if $mid != 0x01;         # National Semiconductor
4442                return 8 if $addr == 0x4c and $cid == 0x31; # LM89/LM99
4443                return 8 if $addr == 0x4d and $cid == 0x34; # LM89-1/LM99-1
4444                return 6 if ($cid & 0x0f) == 0x30;
4445        }
4446        if ($chip == 2) {
4447                return if ($conf & 0x2a) != 0;
4448                return if ($conf2 & 0xf8) != 0;
4449                return if $rate > 0x09;
4450                return if $mid != 0x01;         # National Semiconductor
4451                return 8 if $cid == 0x11;       # LM86
4452                return 6 if ($cid & 0xf0) == 0x10;
4453        }
4454        if ($chip == 3) {
4455                return if ($conf & 0x3f) != 0;
4456                return if $rate > 0x0a;
4457                return if $mid != 0x41;         # Analog Devices
4458                return 6 if ($cid & 0xf0) == 0x40; # ADM1032
4459        }
4460        if ($chip == 4) {
4461                return if ($conf & 0x07) != 0;
4462                return if $rate > 0x07;
4463                return if $mid != 0x4d;         # Maxim
4464                return 8 if $cid == 0x08;       # MAX6654
4465        }
4466        if ($chip == 5) {
4467                return if ($conf & 0x1b) != 0;
4468                return if $rate > 0x0a;
4469                return if $mid != 0x41;         # Analog Devices
4470                return 8 if $cid == 0x51;       # ADT7461
4471        }
4472        if ($chip == 6) {
4473                return if ($conf & 0x3f) != 0;
4474                return if $rate > 0x07;
4475                return if $mid != 0x4d;         # Maxim
4476                return 8 if $cid == 0x59;       # MAX6648/MAX6692
4477        }
4478        if ($chip == 8) {
4479                return if ($conf & 0x2a) != 0;
4480                return if ($conf2 & 0xf8) != 0;
4481                return if $rate > 0x09;
4482                return if $mid != 0x5c;         # Winbond
4483                return 6 if ($cid & 0xfe) == 0x00; # W83L771W/G
4484        }
4485        if ($chip == 9) {
4486                return if ($conf & 0x1B) != 0;
4487                return if $rate > 0x0F;
4488                return if $mid != 0x55;         # Texas Instruments
4489                return 8 if $cid == 0x11;       # TMP401
4490        }
4491        if ($chip == 10) {
4492                return if ($conf & 0x1B) != 0;
4493                return if $rate > 0x0F;
4494                return if $mid != 0x55;         # Texas Instruments
4495                return 6 if ($addr == 0x4c && $cid == 0x12); # TMP411A
4496                return 6 if ($addr == 0x4d && $cid == 0x13); # TMP411B
4497                return 6 if ($addr == 0x4e && $cid == 0x10); # TMP411C
4498        }
4499        if ($chip == 11) {
4500                return if ($conf & 0x2a) != 0;
4501                return if ($conf2 & 0xf8) != 0;
4502                return if $rate > 0x08;
4503                return if $mid != 0x5c;         # Winbond
4504                return 6 if ($cid & 0xfe) == 0x10; # W83L771AWG/ASG
4505        }
4506        if ($chip == 12) {
4507                return if ($conf & 0x07) != 0;
4508                return if $rate > 0x07;
4509                return if $mid != 0x4d;         # Maxim
4510                return 8 if $cid == 0x09;       # MAX6690
4511        }
4512        if ($chip == 13) {
4513                return if ($conf & 0x1b) != 0;
4514                return if $rate > 0x0a;
4515                return if $mid != 0x41;         # Analog Devices
4516                return 8 if $cid == 0x57;       # ADT7461A, NCT1008
4517        }
4518        if ($chip == 14) {
4519                return if ($conf & 0x2a) != 0;
4520                return if ($conf2 & 0xfe) != 0;
4521                return if $rate > 0x09;
4522                return if $mid != 0xa1;         # NXP Semiconductor/Philips
4523                return 6 if $cid == 0x00;       # SA56004
4524        }
4525        if ($chip == 15) {
4526                return if ($conf & 0x3f) != 0;
4527                return if $rate > 0x08;
4528                return if $mid != 0x47;         # GMT
4529                return 8 if $cid == 0x01;       # G781
4530        }
4531        return;
4532}
4533
4534# Chip to detect: 0 = TMP421, 1 = TMP422, 2 = TMP423
4535# Registers used:
4536#   0xfe: Manufactorer ID
4537#   0xff: Device ID
4538sub tmp42x_detect()
4539{
4540        my ($file, $addr, $chip) = @_;
4541
4542        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4543        my $cid = i2c_smbus_read_byte_data($file, 0xff);
4544
4545        return if ($mid != 0x55);
4546
4547        return 6 if ($chip == 0 && $cid == 0x21); # TMP421
4548        return 6 if ($chip == 1 && $cid == 0x22); # TMP422
4549        return 6 if ($chip == 2 && $cid == 0x23); # TMP423
4550
4551        return;
4552}
4553
4554# Registers used:
4555#   0x3d: Device ID
4556#   0x3e: Company ID
4557sub amc6821_detect()
4558{
4559        my ($file, $addr) = @_;
4560
4561        my $dev_id = i2c_smbus_read_byte_data($file, 0x3d);
4562        my $comp_id = i2c_smbus_read_byte_data($file, 0x3e);
4563
4564        return if ($comp_id != 0x49);           # Texas Instruments
4565
4566        # Bit 7 of register address is ignored
4567        return if i2c_smbus_read_byte_data($file, 0x80 | 0x3d) != $dev_id;
4568        return if i2c_smbus_read_byte_data($file, 0x80 | 0x3e) != $comp_id;
4569
4570        return 6 if ($dev_id == 0x21);          # AMC6821
4571
4572        return;
4573}
4574
4575# Registers used:
4576#   0x03: Configuration (no low nibble, returns the previous low nibble)
4577#   0x04: Conversion rate
4578#   0xfe: Manufacturer ID
4579#   0xff: no register
4580sub max6657_detect
4581{
4582        my ($file, $addr) = @_;
4583        my $mid = i2c_smbus_read_byte_data($file, 0xfe, NO_CACHE);
4584        my $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
4585        my $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
4586
4587        return if $mid != 0x4d;         # Maxim
4588        return if ($conf & 0x1f) != 0x0d;
4589        return if $cid != 0x4d;         # No register, returns previous value
4590
4591        my $rate = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
4592        return if $rate > 0x09;
4593
4594        $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
4595        $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
4596        return if ($conf & 0x0f) != $rate;
4597        return if $cid != $rate;        # No register, returns previous value
4598
4599        return 5;
4600}
4601
4602# Chip to detect: 0 = LM95231, 1 = LM95241, 2 = LM95245
4603# Registers used:
4604#   0x02: Status (3 unused bits)
4605#   0x03: Configuration (3 unused bits)
4606#   0x06: Remote diode filter control (6 unused bits, LM95231 and LM95241)
4607#   0x30: Remote diode model type select (6 unused bits, LM95231 and LM95241)
4608#   0x30: Local Temperature LSB (5 unused bits, LM95245)
4609#   0x33: Status register 2 (6 unused bits, LM95245)
4610#   0xfe: Manufacturer ID
4611#   0xff: Revision ID
4612sub lm95231_detect
4613{
4614        my ($file, $addr, $chip) = @_;
4615        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4616        my $cid = i2c_smbus_read_byte_data($file, 0xff);
4617
4618        return if $mid != 0x01;                         # National Semiconductor
4619
4620        if ($chip == 0 || $chip == 1) {
4621                return if $chip == 0 && $cid != 0xa1;   # LM95231
4622                return if $chip == 1 && $cid != 0xa4;   # LM95241
4623                return if i2c_smbus_read_byte_data($file, 0x02) & 0x70;
4624                return if i2c_smbus_read_byte_data($file, 0x03) & 0x89;
4625                return if i2c_smbus_read_byte_data($file, 0x06) & 0xfa;
4626                return if i2c_smbus_read_byte_data($file, 0x30) & 0xfa;
4627        } elsif ($chip == 2) {
4628                return if $cid != 0xb3;                 # LM95245
4629                return if i2c_smbus_read_byte_data($file, 0x02) & 0x68;
4630                return if i2c_smbus_read_byte_data($file, 0x03) & 0xa1;
4631                return if i2c_smbus_read_byte_data($file, 0x30) & 0x1f;
4632                return if i2c_smbus_read_byte_data($file, 0x33) & 0x3f;
4633        }
4634
4635        return 6;
4636}
4637
4638# Registers used:
4639#   0x03: Configuration 1
4640#   0x24: Configuration 2
4641#   0x3d: Manufacturer ID
4642#   0x3e: Device ID
4643sub adt7481_detect
4644{
4645        my ($file, $addr) = @_;
4646        my $mid = i2c_smbus_read_byte_data($file, 0x3d);
4647        my $cid = i2c_smbus_read_byte_data($file, 0x3e);
4648        my $conf1 = i2c_smbus_read_byte_data($file, 0x03);
4649        my $conf2 = i2c_smbus_read_byte_data($file, 0x24);
4650
4651        return if ($conf1 & 0x10) != 0;
4652        return if ($conf2 & 0x7f) != 0;
4653        return if $mid != 0x41;         # Analog Devices
4654        return if $cid != 0x81;         # ADT7481
4655
4656        return 6;
4657}
4658
4659# Chip to detect: 1 = LM63, 2 = F75363SG, 3 = LM64, 4 = LM96163
4660# Registers used:
4661#   0xfe: Manufacturer ID
4662#   0xff: Chip ID / die revision
4663#   0x03: Configuration (two or three unused bits)
4664#   0x16: Alert mask (two or three unused bits)
4665sub lm63_detect
4666{
4667        my ($file, $addr, $chip) = @_;
4668
4669        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4670        my $cid = i2c_smbus_read_byte_data($file, 0xff);
4671        my $conf = i2c_smbus_read_byte_data($file, 0x03);
4672        my $mask = i2c_smbus_read_byte_data($file, 0x16);
4673
4674        if ($chip == 1) {
4675                return if $mid != 0x01          # National Semiconductor
4676                       || $cid != 0x41;         # LM63
4677                return if ($conf & 0x18) != 0x00
4678                       || ($mask & 0xa4) != 0xa4;
4679        } elsif ($chip == 2) {
4680                return if $mid != 0x23          # Fintek
4681                       || $cid != 0x20;         # F75363SG
4682                return if ($conf & 0x1a) != 0x00
4683                       || ($mask & 0x84) != 0x00;
4684        } elsif ($chip == 3) {
4685                return if $mid != 0x01          # National Semiconductor
4686                       || $cid != 0x51;         # LM64
4687                return if ($conf & 0x18) != 0x00
4688                       || ($mask & 0xa4) != 0xa4;
4689        } elsif ($chip == 4) {
4690                return if $mid != 0x01          # National Semiconductor
4691                       || $cid != 0x49;         # LM96163
4692                return if ($conf & 0x18) != 0x00
4693                       || ($mask & 0xa4) != 0xa4;
4694        }
4695
4696        return 6;
4697}
4698
4699# Registers used:
4700#   0x02, 0x03: Fan support
4701#   0x06: Temperature support
4702#   0x07, 0x08, 0x09: Fan config
4703#   0x0d: Manufacturer ID
4704#   0x0e: Chip ID / die revision
4705sub adm1029_detect
4706{
4707        my ($file, $addr) = @_;
4708        my $mid = i2c_smbus_read_byte_data($file, 0x0d);
4709        my $cid = i2c_smbus_read_byte_data($file, 0x0e);
4710        my $cfg;
4711
4712        return unless $mid == 0x41;             # Analog Devices
4713        return unless ($cid & 0xF0) == 0x00;    # ADM1029
4714
4715        # Extra check on unused bits
4716        $cfg = i2c_smbus_read_byte_data($file, 0x02);
4717        return unless $cfg == 0x03;
4718        $cfg = i2c_smbus_read_byte_data($file, 0x06);
4719        return unless ($cfg & 0xF9) == 0x01;
4720        foreach my $reg (0x03, 0x07, 0x08, 0x09) {
4721                $cfg = i2c_smbus_read_byte_data($file, $reg);
4722                return unless ($cfg & 0xFC) == 0x00;
4723        }
4724
4725        return 7;
4726}
4727
4728# Chip to detect: 0 = ADM1030, 1 = ADM1031
4729# Registers used:
4730#   0x01: Config 2
4731#   0x03: Status 2
4732#   0x0d, 0x0e, 0x0f: Temperature offsets
4733#   0x22: Fan speed config
4734#   0x3d: Chip ID
4735#   0x3e: Manufacturer ID
4736#   0x3f: Die revision
4737sub adm1031_detect
4738{
4739        my ($file, $addr, $chip) = @_;
4740        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4741        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4742        my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4743        my $conf2 = i2c_smbus_read_byte_data($file, 0x01);
4744        my $stat2 = i2c_smbus_read_byte_data($file, 0x03);
4745        my $fsc = i2c_smbus_read_byte_data($file, 0x22);
4746        my $lto = i2c_smbus_read_byte_data($file, 0x0d);
4747        my $r1to = i2c_smbus_read_byte_data($file, 0x0e);
4748        my $r2to = i2c_smbus_read_byte_data($file, 0x0f);
4749        my $confidence = 3;
4750
4751        if ($chip == 0) {
4752                return if $mid != 0x41;         # Analog Devices
4753                return if $cid != 0x30;         # ADM1030
4754                $confidence++ if ($drev & 0x70) == 0x00;
4755                $confidence++ if ($conf2 & 0x4A) == 0x00;
4756                $confidence++ if ($stat2 & 0x3F) == 0x00;
4757                $confidence++ if ($fsc & 0xF0) == 0x00;
4758                $confidence++ if ($lto & 0x70) == 0x00;
4759                $confidence++ if ($r1to & 0x70) == 0x00;
4760                return $confidence;
4761        }
4762        if ($chip == 1) {
4763                return if $mid != 0x41;         # Analog Devices
4764                return if $cid != 0x31;         # ADM1031
4765                $confidence++ if ($drev & 0x70) == 0x00;
4766                $confidence++ if ($lto & 0x70) == 0x00;
4767                $confidence++ if ($r1to & 0x70) == 0x00;
4768                $confidence++ if ($r2to & 0x70) == 0x00;
4769                return $confidence;
4770        }
4771}
4772
4773# Chip to detect: 0 = ADM1033, 1 = ADM1034
4774# Registers used:
4775#   0x3d: Chip ID
4776#   0x3e: Manufacturer ID
4777#   0x3f: Die revision
4778sub adm1034_detect
4779{
4780        my ($file, $addr, $chip) = @_;
4781        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4782        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4783        my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4784
4785        if ($chip == 0) {
4786                return if $mid != 0x41;         # Analog Devices
4787                return if $cid != 0x33;         # ADM1033
4788                return if ($drev & 0xf8) != 0x00;
4789                return 6 if $drev == 0x02;
4790                return 4;
4791        }
4792        if ($chip == 1) {
4793                return if $mid != 0x41;         # Analog Devices
4794                return if $cid != 0x34;         # ADM1034
4795                return if ($drev & 0xf8) != 0x00;
4796                return 6 if $drev == 0x02;
4797                return 4;
4798        }
4799}
4800
4801# Chip to detect: 0 = ADT7467/ADT7468, 1 = ADT7476, 2 = ADT7462, 3 = ADT7466,
4802#                 4 = ADT7470
4803# Registers used:
4804#   0x3d: Chip ID
4805#   0x3e: Manufacturer ID
4806#   0x3f: Die revision
4807sub adt7467_detect
4808{
4809        my ($file, $addr, $chip) = @_;
4810        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4811        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4812        my $drev = i2c_smbus_read_byte_data($file, 0x3f);
4813
4814        return if $mid != 0x41;                 # Analog Devices
4815
4816        if ($chip == 0) {
4817                return if $cid != 0x68;         # ADT7467/ADT7468
4818                return if ($drev & 0xf0) != 0x70;
4819                return 7 if $drev == 0x71 || $drev == 0x72;
4820                return 5;
4821        }
4822        if ($chip == 1) {
4823                return if $cid != 0x76;         # ADT7476
4824                return if ($drev & 0xf0) != 0x60;
4825                return 7 if $drev >= 0x69 && $drev <= 0x6b;
4826                return 5;
4827        }
4828        if ($chip == 2) {
4829                return if $cid != 0x62;         # ADT7462
4830                return if ($drev & 0xf0) != 0x00;
4831                return 7 if $drev == 0x04;
4832                return 5;
4833        }
4834        if ($chip == 3) {
4835                return if $cid != 0x66;         # ADT7466
4836                return if ($drev & 0xf0) != 0x00;
4837                return 7 if $drev == 0x02;
4838                return 5;
4839        }
4840        if ($chip == 4) {
4841                return if $cid != 0x70;         # ADT7470
4842                return if ($drev & 0xf0) != 0x00;
4843                return 7 if $drev == 0x00;
4844                return 5;
4845        }
4846}
4847
4848# Chip to detect: 0 = ADT7473, 1 = ADT7475
4849# Registers used:
4850#   0x3d: Chip ID
4851#   0x3e: Manufacturer ID
4852sub adt7473_detect
4853{
4854        my ($file, $addr, $chip) = @_;
4855        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4856        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4857
4858        return if $mid != 0x41;                 # Analog Devices
4859
4860        return if $chip == 0 && $cid != 0x73;   # ADT7473
4861        return if $chip == 1 && $cid != 0x75;   # ADT7475
4862        return 5;
4863}
4864
4865# Registers used:
4866#   0x3e: Manufacturer ID
4867#   0x3f: Chip ID
4868sub adt7490_detect
4869{
4870        my ($file, $addr) = @_;
4871        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4872        my $cid = i2c_smbus_read_byte_data($file, 0x3f);
4873
4874        return if $mid != 0x41;                 # Analog Devices
4875        return if ($cid & 0xfc) != 0x6c;        # ADT7490
4876        return 5;
4877}
4878
4879# Registers used:
4880#   0x02: Status
4881#   0x0a: Thyst
4882#   0x0b: ID
4883# We also rely on the fact that only the 5 LSB of the address pointer
4884# are considered, so registers cycle over 32 byte boundaries.
4885sub adt7410_detect
4886{
4887        my ($file, $addr) = @_;
4888        my $status = i2c_smbus_read_byte_data($file, 0x02);
4889        my $thyst = i2c_smbus_read_byte_data($file, 0x0a);
4890        my $id = i2c_smbus_read_byte_data($file, 0x0b);
4891
4892        # Unused bits
4893        return if ($status & 0x0f);
4894        return if ($thyst & 0xf0);
4895
4896        # ID register
4897        return if $id != 0xcb;
4898
4899        # Cycling registers
4900        for (my $i = 2; $i < 16; $i *= 2) {
4901                return if i2c_smbus_read_byte_data($file, 0x0a + $i * 16) != $thyst;
4902                return if i2c_smbus_read_byte_data($file, 0x0b + $i * 16) != $id;
4903        }
4904
4905        # Non-existent registers (other devices tend to have ID registers there)
4906        return if i2c_smbus_read_byte_data($file, 0x03e) != 0;
4907        return if i2c_smbus_read_byte_data($file, 0x03f) != 0;
4908        return if i2c_smbus_read_byte_data($file, 0x0fe) != 0;
4909        return if i2c_smbus_read_byte_data($file, 0x0ff) != 0;
4910
4911        return 3;
4912}
4913
4914# Registers used:
4915#   0x4d: Device ID
4916#   0x4e: Manufacturer ID
4917#   0x4e: Silicon revision
4918sub adt7411_detect
4919{
4920        my ($file, $addr) = @_;
4921        my $dev_id = i2c_smbus_read_byte_data($file, 0x4d);
4922        my $man_id = i2c_smbus_read_byte_data($file, 0x4e);
4923        my $revision = i2c_smbus_read_byte_data($file, 0x4f);
4924
4925        return if $man_id != 0x41;              # Analog Devices
4926        return if $dev_id != 0x02;              # ADT7411
4927        # The datasheet suggests that the version is in the high nibble, but
4928        # a dump from a real ADT7411 chip shows that it is in the low nibble.
4929        return if ($revision & 0x0f) != 0x04;   # ADT7411
4930        return 5;
4931}
4932
4933# Chip to detect: 0 = aSC7512, 1 = aSC7611, 2 = aSC7621
4934# Registers used:
4935#   0x3e: Manufacturer ID
4936#   0x3f: Version
4937sub andigilog_detect
4938{
4939        my ($file, $addr, $chip) = @_;
4940        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4941        my $cid = i2c_smbus_read_byte_data($file, 0x3f);
4942
4943        return if $mid != 0x61;         # Andigilog
4944
4945        return if $chip == 0 && $cid != 0x62;
4946        return if $chip == 1 && $cid != 0x69;
4947        return if $chip == 2 && ($cid != 0x6C && $cid != 0x6D);
4948        return 5;
4949}
4950
4951# Registers used:
4952#   0xfe: Manufacturer ID
4953#   0xff: Die Code
4954sub andigilog_aSC7511_detect
4955{
4956        my ($file, $addr) = @_;
4957        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4958        my $die = i2c_smbus_read_byte_data($file, 0xff);
4959
4960        return if $mid != 0x61;         # Andigilog
4961        return if $die != 0x00;
4962        return 3;
4963}
4964
4965# Chip to detect: 0 = LM85, 1 = LM96000, 2 = ADM1027, 3 = ADT7463,
4966#                 4 = EMC6D100/101, 5 = EMC6D102, 6 = EMC6D103,
4967#                 7 = WPCD377I (no sensors), 8 = EMC6D103S/EMC2300
4968# Registers used:
4969#   0x3e: Vendor register
4970#   0x3d: Device ID register (Analog Devices only)
4971#   0x3f: Version/Stepping register
4972sub lm85_detect
4973{
4974        my ($file, $addr, $chip) = @_;
4975        my $vendor = i2c_smbus_read_byte_data($file, 0x3e);
4976        my $verstep = i2c_smbus_read_byte_data($file, 0x3f);
4977
4978        if ($chip == 0) {
4979                return if $vendor != 0x01;      # National Semiconductor
4980                return if $verstep != 0x60      # LM85 C
4981                       && $verstep != 0x62;     # LM85 B
4982        } elsif ($chip == 1 || $chip == 7) {
4983                return if $vendor != 0x01;      # National Semiconductor
4984                return if $verstep != 0x68      # LM96000
4985                       && $verstep != 0x69;     # LM96000
4986        } elsif ($chip == 2) {
4987                return if $vendor != 0x41;      # Analog Devices
4988                return if $verstep != 0x60;     # ADM1027
4989        } elsif ($chip == 3) {
4990                return if $vendor != 0x41;      # Analog Devices
4991                return if $verstep != 0x62      # ADT7463
4992                       && $verstep != 0x6a;     # ADT7463 C
4993        } elsif ($chip == 4) {
4994                return if $vendor != 0x5c;      # SMSC
4995                return if $verstep != 0x60      # EMC6D100/101 A0
4996                       && $verstep != 0x61;     # EMC6D100/101 A1
4997        } elsif ($chip == 5) {
4998                return if $vendor != 0x5c;      # SMSC
4999                return if $verstep != 0x65;     # EMC6D102
5000        } elsif ($chip == 6) {
5001                return if $vendor != 0x5c;      # SMSC
5002                return if $verstep != 0x68      # EMC6D103 A0
5003                       && $verstep != 0x69;     # EMC6D103 A1
5004        } elsif ($chip == 8) {
5005                return if $vendor != 0x5c;      # SMSC
5006                return if $verstep != 0x6a;     # EMC6D103S/EMC2300
5007        }
5008
5009        if ($vendor == 0x41) {                  # Analog Devices
5010                return if i2c_smbus_read_byte_data($file, 0x3d) != 0x27;
5011                return 8;
5012        }
5013
5014        if ($chip == 1 || $chip == 7) {
5015                # Differenciate between real LM96000 and Winbond WPCD377I.
5016                # The latter emulate the former except that it has no
5017                # hardware monitoring function so the readings are always
5018                # 0.
5019                my ($in_temp, $fan, $i);
5020               
5021                for ($i = 0; $i < 8; $i++) {
5022                        $in_temp = i2c_smbus_read_byte_data($file, 0x20 + $i);
5023                        $fan = i2c_smbus_read_byte_data($file, 0x28 + $i);
5024                        if ($in_temp != 0x00 or $fan != 0xff) {
5025                                return 7 if $chip == 1;
5026                                return;
5027                        }
5028                }
5029                return 7 if $chip == 7;
5030                return;
5031        }
5032
5033        return 7;
5034}
5035
5036# Registers used:
5037#   0x3e: Vendor register
5038#   0x3f: Version/Stepping register
5039#   0x40: Configuration register (reserved bits + ready)
5040sub emc6w201_detect
5041{
5042        my ($file, $addr) = @_;
5043        my $vendor = i2c_smbus_read_byte_data($file, 0x3e);
5044        my $verstep = i2c_smbus_read_byte_data($file, 0x3f);
5045        my $conf = i2c_smbus_read_byte_data($file, 0x40);
5046        my $stepping;
5047
5048        return if $vendor != 0x5c;              # SMSC
5049        return if ($verstep & 0xf0) != 0xb0;    # EMC6W201
5050        return if ($conf & 0xf4) != 0x04;
5051
5052        $stepping = $verstep & 0x0f;
5053        return if $stepping > 3;
5054
5055        # So far we've only seen stepping 1 chips
5056        return $stepping <= 1 ? 6 : 3;
5057}
5058
5059# Chip to detect: 0 = LM87, 1 = ADM1024
5060# Registers used:
5061#   0x3e: Company ID
5062#   0x3f: Revision
5063#   0x40: Configuration
5064sub lm87_detect
5065{
5066        my ($file, $addr, $chip) = @_;
5067        my $cid = i2c_smbus_read_byte_data($file, 0x3e);
5068        my $rev = i2c_smbus_read_byte_data($file, 0x3f);
5069
5070        if ($chip == 0) {
5071                return if $cid != 0x02;         # National Semiconductor
5072                return if ($rev & 0xfc) != 0x04; # LM87
5073        }
5074        if ($chip == 1) {
5075                return if $cid != 0x41;         # Analog Devices
5076                return if ($rev & 0xf0) != 0x10; # ADM1024
5077        }
5078
5079        my $cfg = i2c_smbus_read_byte_data($file, 0x40);
5080        return if ($cfg & 0x80) != 0x00;
5081
5082        return 7;
5083}
5084
5085# Chip to detect: 0 = W83781D, 1 = W83782D, 2 = W83783S, 3 = W83627HF,
5086#                 4 = AS99127F (rev.1), 5 = AS99127F (rev.2), 6 = ASB100,
5087#                 7 = W83791D, 8 = W83792D, 9 = W83627EHF,
5088#                 10 = W83627DHG/W83667HG/W83677HG
5089# Registers used:
5090#   0x48: Full I2C Address
5091#   0x4a: I2C addresses of emulated LM75 chips
5092#   0x4e: Vendor ID byte selection, and bank selection
5093#   0x4f: Vendor ID
5094#   0x58: Device ID (only when in bank 0)
5095# Note: Fails if the W8378xD is not in bank 0!
5096# Note: Asus chips do not have their I2C address at register 0x48?
5097#       AS99127F rev.1 and ASB100 have 0x00, confirmation wanted for
5098#       AS99127F rev.2.
5099sub w83781d_detect
5100{
5101        my ($file, $addr, $chip) = @_;
5102        my ($reg1, $reg2, @res);
5103
5104        return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr)
5105                   or ($chip >= 4 && $chip <= 6);
5106
5107        $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
5108        $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
5109        if ($chip == 4) {               # Asus AS99127F (rev.1)
5110                return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xc3) or
5111                              (($reg1 & 0x80) == 0x80 and $reg2 == 0x12);
5112        } elsif ($chip == 6) {          # Asus ASB100
5113                return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0x94) or
5114                              (($reg1 & 0x80) == 0x80 and $reg2 == 0x06);
5115        } else {                        # Winbond and Asus AS99127F (rev.2)
5116                return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
5117                              (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
5118        }
5119
5120        return unless ($reg1 & 0x07) == 0x00;
5121
5122        $reg1 = i2c_smbus_read_byte_data($file, 0x58);
5123        return if $chip == 0 and ($reg1 != 0x10 && $reg1 != 0x11);
5124        return if $chip == 1 and $reg1 != 0x30;
5125        return if $chip == 2 and $reg1 != 0x40;
5126        return if $chip == 3 and $reg1 != 0x21;
5127        return if $chip == 4 and $reg1 != 0x31;
5128        return if $chip == 5 and $reg1 != 0x31;
5129        return if $chip == 6 and $reg1 != 0x31;
5130        return if $chip == 7 and $reg1 != 0x71;
5131        return if $chip == 8 and $reg1 != 0x7a;
5132        return if $chip == 9 and ($reg1 != 0x88 && $reg1 != 0xa1);
5133        return if $chip == 10 and $reg1 != 0xc1;
5134        # Default address is 0x2d
5135        @res = ($addr != 0x2d) ? (7) : (8);
5136        return @res if $chip >= 9; # No subclients
5137
5138        $reg1 = i2c_smbus_read_byte_data($file, 0x4a);
5139        push @res, ($reg1 & 0x07) + 0x48 unless $reg1 & 0x08;
5140        push @res, (($reg1 & 0x70) >> 4) + 0x48
5141                unless ($reg1 & 0x80 or $chip == 2);
5142        return @res;
5143}
5144
5145# Registers used:
5146#   0x0b: Full I2C Address
5147#   0x0c: I2C addresses of emulated LM75 chips
5148#   0x00: Vendor ID byte selection, and bank selection(Bank 0, 1, 2)
5149#   0x0d: Vendor ID(Bank 0, 1, 2)
5150#   0x0e: Device ID(Bank 0, 1, 2)
5151sub w83793_detect
5152{
5153        my ($file, $addr) = @_;
5154        my ($bank, $reg, @res);
5155
5156        $bank = i2c_smbus_read_byte_data($file, 0x00);
5157        $reg = i2c_smbus_read_byte_data($file, 0x0d);
5158
5159        return unless (($bank & 0x80) == 0x00 and $reg == 0xa3) or
5160                      (($bank & 0x80) == 0x80 and $reg == 0x5c);
5161
5162        $reg = i2c_smbus_read_byte_data($file, 0x0e);
5163        return if $reg != 0x7b;
5164
5165        # If bank 0 is selected, we can do more checks
5166        return 6 unless ($bank & 0x07) == 0;
5167        $reg = i2c_smbus_read_byte_data($file, 0x0b);
5168        return unless ($reg == ($addr << 1));
5169
5170        $reg = i2c_smbus_read_byte_data($file, 0x0c);
5171        @res = (8);
5172        push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
5173        push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
5174        return @res;
5175}
5176
5177# Registers used:
5178#   0xfc: Full I2C Address
5179#   0x00: Vendor ID byte selection, and bank selection(Bank 0, 1, 2)
5180#   0xfd: Vendor ID(Bank 0, 1, 2)
5181#   0xfe: Device ID(Bank 0, 1, 2)
5182sub w83795_detect
5183{
5184        my ($bank, $reg);
5185        my ($file, $addr) = @_;
5186
5187        $bank = i2c_smbus_read_byte_data($file, 0x00);
5188        $reg = i2c_smbus_read_byte_data($file, 0xfd);
5189
5190        return unless (($bank & 0x80) == 0x00 and $reg == 0xa3) or
5191                      (($bank & 0x80) == 0x80 and $reg == 0x5c);
5192
5193        $reg = i2c_smbus_read_byte_data($file, 0xfe);
5194        return if $reg != 0x79;
5195
5196        # If bank 0 is selected, we can do more checks
5197        return 6 unless ($bank & 0x07) == 0;
5198        $reg = i2c_smbus_read_byte_data($file, 0xfc) & 0x7f;
5199        return unless ($reg == $addr);
5200
5201        return 8;
5202}
5203
5204# Registers used:
5205#   0x48: Full I2C Address
5206#   0x4e: Vendor ID byte selection
5207#   0x4f: Vendor ID
5208#   0x58: Device ID
5209# Note that the datasheet was useless and this detection routine
5210# is based on dumps we received from users. Also, the W83781SD is *NOT*
5211# a hardware monitoring chip as far as we know, but we still want to
5212# detect it so that people won't keep reporting it as an unknown chip
5213# we should investigate about.
5214sub w83791sd_detect
5215{
5216        my ($file, $addr) = @_;
5217        my ($reg1, $reg2);
5218
5219        return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr);
5220
5221        $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
5222        $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
5223        return unless (!($reg1 & 0x80) && $reg2 == 0xa3)
5224                   || (($reg1 & 0x80) && $reg2 == 0x5c);
5225
5226        $reg1 = i2c_smbus_read_byte_data($file, 0x58);
5227        return unless $reg1 == 0x72;
5228
5229        return 3;
5230}
5231
5232# Registers used:
5233#   0x4e: Vendor ID high byte
5234#   0x4f: Vendor ID low byte
5235#   0x58: Device ID
5236# Note: The values were given by Alex van Kaam, we don't have datasheets
5237#       to confirm.
5238sub mozart_detect
5239{
5240        my ($file, $addr) = @_;
5241        my ($vid, $dev);
5242
5243        $vid = (i2c_smbus_read_byte_data($file, 0x4e) << 8)
5244             + i2c_smbus_read_byte_data($file, 0x4f);
5245        $dev = i2c_smbus_read_byte_data($file, 0x58);
5246
5247        return unless ($dev == 0x56 && $vid == 0x9436)  # ASM58
5248                   || ($dev == 0x56 && $vid == 0x9406)  # AS2K129R
5249                   || ($dev == 0x10 && $vid == 0x5ca3);
5250
5251        return 5;
5252}
5253
5254# Chip to detect: 0 = GL518SM, 1 = GL520SM
5255# Registers used:
5256#   0x00: Device ID
5257#   0x01: Revision ID
5258#   0x03: Configuration
5259sub gl518sm_detect
5260{
5261        my ($file, $addr, $chip) = @_;
5262        my $reg;
5263
5264        $reg = i2c_smbus_read_byte_data($file, 0x00);
5265        return if $chip == 0 && $reg != 0x80;
5266        return if $chip == 1 && $reg != 0x20;
5267
5268        return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
5269        $reg = i2c_smbus_read_byte_data($file, 0x01);
5270        return unless $reg == 0x00 or $reg == 0x80;
5271        return 6;
5272}
5273
5274# Registers used:
5275#   0x00: Device ID
5276#   0x03: Configuration
5277# Mediocre detection
5278sub gl525sm_detect
5279{
5280        my ($file, $addr) = @_;
5281        return unless i2c_smbus_read_byte_data($file, 0x00) == 0x25;
5282        return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
5283        return 5;
5284}
5285
5286# Chip to detect: 0 = ADM9240, 1 = DS1780, 2 = LM81
5287# Registers used:
5288#   0x3e: Company ID
5289#   0x40: Configuration
5290#   0x48: Full I2C Address
5291sub adm9240_detect
5292{
5293        my ($file, $addr, $chip) = @_;
5294        my $reg;
5295        $reg = i2c_smbus_read_byte_data($file, 0x3e);
5296        return unless ($chip == 0 and $reg == 0x23) or
5297                      ($chip == 1 and $reg == 0xda) or
5298                      ($chip == 2 and $reg == 0x01);
5299        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
5300        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
5301
5302        return 7;
5303}
5304
5305# Chip to detect: 0 = ADM1022, 1 = THMC50, 2 = ADM1028, 3 = THMC51
5306# Registers used:
5307#   0x3e: Company ID
5308#   0x3f: Revision
5309#   0x40: Configuration
5310sub adm1022_detect
5311{
5312        my ($file, $addr, $chip) = @_;
5313        my $reg;
5314        $reg = i2c_smbus_read_byte_data($file, 0x3e);
5315        return unless ($chip == 0 and $reg == 0x41) or
5316                      ($chip == 1 and $reg == 0x49) or
5317                      ($chip == 2 and $reg == 0x41) or
5318                      ($chip == 3 and $reg == 0x49);
5319        $reg = i2c_smbus_read_byte_data($file, 0x40);
5320        return if ($reg & 0x10);                        # Soft Reset always reads 0
5321        return if ($chip != 0 and ($reg & 0x80));       # Reserved on THMC50 and ADM1028
5322        $reg = i2c_smbus_read_byte_data($file, 0x3f) & 0xf0;
5323        return unless ($chip == 0 and $reg == 0xc0) or
5324                      ($chip == 1 and $reg == 0xc0) or
5325                      ($chip == 2 and $reg == 0xd0) or
5326                      ($chip == 3 and $reg == 0xd0);
5327        return 8;
5328}
5329
5330# Chip to detect: 0 = ADM1025, 1 = NE1619
5331# Registers used:
5332#   0x3e: Company ID
5333#   0x3f: Revision
5334#   0x40: Configuration
5335#   0x41: Status 1
5336#   0x42: Status 2
5337sub adm1025_detect
5338{
5339        my ($file, $addr, $chip) = @_;
5340        my $reg;
5341
5342        $reg = i2c_smbus_read_byte_data($file, 0x3e);
5343        return if ($chip == 0) and ($reg != 0x41);
5344        return if ($chip == 1) and ($reg != 0xA1);
5345
5346        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
5347        return unless (i2c_smbus_read_byte_data($file, 0x41) & 0xC0) == 0x00;
5348        return unless (i2c_smbus_read_byte_data($file, 0x42) & 0xBC) == 0x00;
5349        return unless (i2c_smbus_read_byte_data($file, 0x3f) & 0xf0) == 0x20;
5350
5351        return 8;
5352}
5353
5354# Registers used:
5355#   0x16: Company ID
5356#   0x17: Revision
5357sub adm1026_detect
5358{
5359        my ($file, $addr) = @_;
5360        my $reg;
5361        $reg = i2c_smbus_read_byte_data($file, 0x16);
5362        return unless ($reg == 0x41);
5363        return unless (i2c_smbus_read_byte_data($file, 0x17) & 0xf0) == 0x40;
5364        return 8;
5365}
5366
5367# Chip to detect: 0 = ADM1021, 1 = ADM1021A/ADM1023, 2 = MAX1617, 3 = MAX1617A,
5368#                 4 = THMC10, 5 = LM84, 6 = GL523, 7 = MC1066
5369# Registers used:
5370#   0x04: Company ID (LM84 only)
5371#   0xfe: Company ID (all but LM84 and MAX1617)
5372#   0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A)
5373#   0x02: Status
5374#   0x03: Configuration
5375#   0x04: Conversion rate
5376#   0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84)
5377# Note: Especially the MAX1617 has very bad detection; we give it a low
5378# confidence value.
5379sub adm1021_detect
5380{
5381        my ($file, $addr, $chip) = @_;
5382        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
5383        my $rev = i2c_smbus_read_byte_data($file, 0xff);
5384        my $conf = i2c_smbus_read_byte_data($file, 0x03);
5385        my $status = i2c_smbus_read_byte_data($file, 0x02);
5386        my $convrate = i2c_smbus_read_byte_data($file, 0x04);
5387
5388        # Check manufacturer IDs and product revisions when available
5389        return if $chip == 0 and $man_id != 0x41 || ($rev & 0xf0) != 0x00;
5390        return if $chip == 1 and $man_id != 0x41 || ($rev & 0xf0) != 0x30;
5391        return if $chip == 3 and $man_id != 0x4d || $rev != 0x01;
5392        return if $chip == 4 and $man_id != 0x49;
5393        return if $chip == 5 and $convrate != 0x00;
5394        return if $chip == 6 and $man_id != 0x23;
5395        return if $chip == 7 and $man_id != 0x54;
5396
5397        # Check unused bits
5398        if ($chip == 5) {       # LM84
5399                return if ($status & 0xab) != 0;
5400                return if ($conf & 0x7f) != 0;
5401        } else {
5402                return if ($status & 0x03) != 0;
5403                return if ($conf & 0x3f) != 0;
5404                return if ($convrate & 0xf8) != 0;
5405        }
5406
5407        # Extra checks for MAX1617 and LM84, since those are often misdetected.
5408        # We verify several assertions (6 for the MAX1617, 4 for the LM84) and
5409        # discard the chip if any fail. Note that these checks are not done
5410        # by the adm1021 driver.
5411        if ($chip == 2 || $chip == 5) {
5412                my $lte = i2c_smbus_read_byte_data($file, 0x00);
5413                my $rte = i2c_smbus_read_byte_data($file, 0x01);
5414                my $lhi = i2c_smbus_read_byte_data($file, 0x05);
5415                my $rhi = i2c_smbus_read_byte_data($file, 0x07);
5416                my $llo = i2c_smbus_read_byte_data($file, 0x06);
5417                my $rlo = i2c_smbus_read_byte_data($file, 0x08);
5418
5419                # If all registers hold the same value, it has to be a misdetection
5420                return if $lte == $rte and $lte == $lhi and $lte == $rhi
5421                      and $lte == $llo and $lte == $rlo;
5422
5423                # Negative temperatures
5424                return if ($lte & 0x80) or ($rte & 0x80);
5425                # Negative high limits
5426                return if ($lhi & 0x80) or ($rhi & 0x80);
5427                # Low limits over high limits
5428                if ($chip == 2) {
5429                        $llo -= 256 if ($llo & 0x80);
5430                        $rlo -= 256 if ($rlo & 0x80);
5431                        return if ($llo > $lhi) or ($rlo > $rhi);
5432                }
5433                return 3;
5434        }
5435
5436        return ($chip <= 3) ? 7 : 5;
5437}
5438
5439# Chip to detect: 0 = MAX1668, 1 = MAX1805, 2 = MAX1989
5440# Registers used:
5441#   0xfe: Company ID
5442#   0xff: Device ID
5443sub max1668_detect
5444{
5445        my ($file, $addr, $chip) = @_;
5446        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
5447        my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
5448
5449        return if $man_id != 0x4d;
5450        return if $chip == 0 and $dev_id != 0x03;
5451        return if $chip == 1 and $dev_id != 0x05;
5452        return if $chip == 2 and $dev_id != 0x0b;
5453
5454        return 7;
5455}
5456
5457# Chip to detect: 0 = MAX1619, 1 = MAX1618
5458# Registers used:
5459#   0xfe: Company ID
5460#   0xff: Device ID
5461#   0x02: Status
5462#   0x03: Configuration
5463#   0x04: Conversion rate
5464sub max1619_detect
5465{
5466        my ($file, $addr, $chip) = @_;
5467        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
5468        my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
5469        my $conf = i2c_smbus_read_byte_data($file, 0x03);
5470        my $status = i2c_smbus_read_byte_data($file, 0x02);
5471        my $convrate = i2c_smbus_read_byte_data($file, 0x04);
5472
5473        return if $man_id != 0x4D;      # Maxim
5474
5475        if ($chip == 0) {               # MAX1619
5476                return if $dev_id != 0x04
5477                       or ($conf & 0x03)
5478                       or ($status & 0x61)
5479                       or $convrate >= 8;
5480        }
5481        if ($chip == 1) {               # MAX1618
5482                return if $dev_id != 0x02
5483                       or ($conf & 0x07)
5484                       or ($status & 0x63);
5485        }
5486
5487        return 7;
5488}
5489
5490# Registers used:
5491#   0x28: User ID
5492#   0x29: User ID2
5493sub ite_overclock_detect
5494{
5495        my ($file, $addr) = @_;
5496
5497        my $uid1 = i2c_smbus_read_byte_data($file, 0x28);
5498        my $uid2 = i2c_smbus_read_byte_data($file, 0x29);
5499        return if $uid1 != 0x83 || $uid2 != 0x12;
5500
5501        return 6;
5502}
5503
5504# Registers used:
5505#   0x00: Configuration
5506#   0x48: Full I2C Address
5507#   0x58: Mfr ID
5508#   0x5b: Device ID
5509sub it8712_i2c_detect
5510{
5511        my ($file, $addr) = @_;
5512        my $reg;
5513        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
5514        return unless (i2c_smbus_read_byte_data($file, 0x00) & 0x90) == 0x10;
5515        return unless i2c_smbus_read_byte_data($file, 0x58) == 0x90;
5516        return if i2c_smbus_read_byte_data($file, 0x5b) != 0x12;
5517        return 7 + ($addr == 0x2d);
5518}
5519
5520# Registers used:
5521#   0-63: SPD Data and Checksum (up to DDR2)
5522#   0-127: SPD data and CRC (DDR3)
5523sub eeprom_detect
5524{
5525        my ($file, $addr) = @_;
5526        my $device_type = i2c_smbus_read_byte_data($file, 2);
5527        my $checksum = 0;
5528
5529        # Check the checksum or CRC16 for validity
5530        if ($device_type >= 1 and $device_type <= 8) {
5531                for (my $i = 0; $i < 63; $i++) {
5532                        $checksum += i2c_smbus_read_byte_data($file, $i);
5533                }
5534                $checksum &= 0xff;
5535
5536                return 8 if $checksum == i2c_smbus_read_byte_data($file, 63);
5537        } elsif ($device_type >= 9 && $device_type <= 11) {
5538                # see JEDEC 21-C 4.1.2.11 2.4
5539                my $crc_coverage = i2c_smbus_read_byte_data($file, 0);
5540                $crc_coverage = ($crc_coverage & 0x80) ? 117 : 126;
5541                for (my $i = 0; $i < $crc_coverage; $i++) {
5542                        $checksum ^= i2c_smbus_read_byte_data($file, $i) << 8;
5543                        for (my $bit = 0; $bit < 8; $bit++) {
5544                                if ($checksum & 0x8000) {
5545                                        $checksum = ($checksum << 1) ^ 0x1021;
5546                                } else {
5547                                        $checksum <<= 1;
5548                                }
5549                        }
5550                }
5551                $checksum &= 0xffff;
5552
5553                return 8 if ($checksum & 0xff) == i2c_smbus_read_byte_data($file, 126) and
5554                            ($checksum >> 8) == i2c_smbus_read_byte_data($file, 127);
5555
5556                # note: if bit 7 of byte 32 is set, a jc42 sensor is at $addr-0x38
5557        }
5558
5559        return;
5560}
5561
5562# Registers used:
5563#   0x00..0x07: DDC signature
5564sub ddcmonitor_detect
5565{
5566        my ($file, $addr) = @_;
5567
5568        return unless
5569                i2c_smbus_read_byte_data($file, 0x00) == 0x00 and
5570                i2c_smbus_read_byte_data($file, 0x01) == 0xFF and
5571                i2c_smbus_read_byte_data($file, 0x02) == 0xFF and
5572                i2c_smbus_read_byte_data($file, 0x03) == 0xFF and
5573                i2c_smbus_read_byte_data($file, 0x04) == 0xFF and
5574                i2c_smbus_read_byte_data($file, 0x05) == 0xFF and
5575                i2c_smbus_read_byte_data($file, 0x06) == 0xFF and
5576                i2c_smbus_read_byte_data($file, 0x07) == 0x00;
5577
5578        return 8;
5579}
5580
5581# Chip to detect: 0 = Poseidon I, 1 = Poseidon II, 2 = Scylla,
5582#                 3 = Hermes, 4 = Heimdal, 5 = Heracles
5583# Registers used:
5584#   0x00-0x02: Identification (3 capital ASCII letters)
5585sub fsc_detect
5586{
5587        my ($file, $addr, $chip) = @_;
5588        my $id;
5589
5590        $id = chr(i2c_smbus_read_byte_data($file, 0x00))
5591            . chr(i2c_smbus_read_byte_data($file, 0x01))
5592            . chr(i2c_smbus_read_byte_data($file, 0x02));
5593
5594        return if $chip == 0 and $id ne 'PEG';  # Pegasus? aka Poseidon I
5595        return if $chip == 1 and $id ne 'POS';  # Poseidon II
5596        return if $chip == 2 and $id ne 'SCY';  # Scylla
5597        return if $chip == 3 and $id ne 'HER';  # Hermes
5598        return if $chip == 4 and $id ne 'HMD';  # Heimdal
5599        return if $chip == 5 and $id ne 'HRC';  # Heracles
5600        return if $chip == 6 and $id ne 'HDS';  # Hades
5601        return if $chip == 7 and $id ne 'SYL';  # Syleus
5602
5603        return 8;
5604}
5605
5606# Chip to detect: 0 = LM93, 1 = LM94
5607# Registers used:
5608#   0x3E: Manufacturer ID
5609#   0x3F: Version/Stepping
5610sub lm93_detect
5611{
5612        my ($file, $addr, $chip) = @_;
5613        my ($man_id, $dev_id);
5614
5615        $man_id = i2c_smbus_read_byte_data($file, 0x3E);
5616        $dev_id = i2c_smbus_read_byte_data($file, 0x3F);
5617       
5618        if ($chip == 0) {
5619                return unless $man_id == 0x01   # National Semiconductor
5620                          and $dev_id == 0x73;  # LM93
5621        }
5622        if ($chip == 1) {
5623                return unless $man_id == 0x01   # National Semiconductor
5624                          and $dev_id >= 0x79
5625                          and $dev_id <= 0x7A;  # LM94
5626        }
5627        return 5;
5628}
5629
5630# Registers used:
5631#   0x3F: Revision ID
5632#   0x48: Address
5633#   0x4A, 0x4B, 0x4F, 0x57, 0x58: Reserved bits.
5634# We do not use 0x49's reserved bits on purpose. The register is named
5635# "VID4/Device ID" so it is doubtful bits 7-1 are really unused.
5636sub m5879_detect
5637{
5638        my ($file, $addr) = @_;
5639
5640        return unless i2c_smbus_read_byte_data($file, 0x3F) == 0x01;
5641        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
5642
5643        return unless (i2c_smbus_read_byte_data($file, 0x4A) & 0x06) == 0
5644                  and (i2c_smbus_read_byte_data($file, 0x4B) & 0xFC) == 0
5645                  and (i2c_smbus_read_byte_data($file, 0x4F) & 0xFC) == 0
5646                  and (i2c_smbus_read_byte_data($file, 0x57) & 0xFE) == 0
5647                  and (i2c_smbus_read_byte_data($file, 0x58) & 0xEF) == 0;
5648
5649        return 7;
5650}
5651
5652# Registers used:
5653#   0x3E: Manufacturer ID
5654#   0x3F: Version/Stepping
5655#   0x47: VID (3 reserved bits)
5656#   0x49: VID4 (7 reserved bits)
5657sub smsc47m192_detect
5658{
5659        my ($file, $addr) = @_;
5660        return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x55
5661                  and (i2c_smbus_read_byte_data($file, 0x3F) & 0xF0) == 0x20
5662                  and (i2c_smbus_read_byte_data($file, 0x47) & 0x70) == 0x00
5663                  and (i2c_smbus_read_byte_data($file, 0x49) & 0xFE) == 0x80;
5664        return ($addr == 0x2d ? 6 : 5);
5665}
5666
5667# Chip to detect: 1 = DME1737, 2 = SCH5027
5668# Registers used:
5669#   0x3E: Manufacturer ID
5670#   0x3F: Version/Stepping
5671#   0x73: Read-only test register (4 test bits)
5672#   0x8A: Read-only test register (7 test bits)
5673#   0xBA: Read-only test register (8 test bits)
5674sub dme1737_detect
5675{
5676        my ($file, $addr, $chip) = @_;
5677        my $vendor = i2c_smbus_read_byte_data($file, 0x3E);
5678        my $verstep = i2c_smbus_read_byte_data($file, 0x3F);
5679
5680        return unless $vendor == 0x5C; # SMSC
5681
5682        if ($chip == 1) { # DME1737
5683                return unless ($verstep & 0xF8) == 0x88 and
5684                              (i2c_smbus_read_byte_data($file, 0x73) & 0x0F) == 0x09 and
5685                              (i2c_smbus_read_byte_data($file, 0x8A) & 0x7F) == 0x4D;
5686        } elsif ($chip == 2) { # SCH5027
5687                return unless $verstep >= 0x69 and $verstep <= 0x6F and
5688                              i2c_smbus_read_byte_data($file, 0xBA) == 0x0F;
5689        }
5690
5691        return ($addr == 0x2e ? 6 : 5);
5692}
5693
5694# Chip to detect: 1 = F75111R/RG/N, 2 = F75121R/F75122R/RG, 3 = F75373S/SG,
5695#                 4 = F75375S/SP, 5 = F75387SG/RG, 6 = F75383M/S/F75384M/S,
5696#                 7 = custom power control IC
5697# Registers used:
5698#   0x5A-0x5B: Chip ID
5699#   0x5D-0x5E: Vendor ID
5700sub fintek_detect
5701{
5702        my ($file, $addr, $chip) = @_;
5703        my $chipid = (i2c_smbus_read_byte_data($file, 0x5A) << 8)
5704                   | i2c_smbus_read_byte_data($file, 0x5B);
5705        my $vendid = (i2c_smbus_read_byte_data($file, 0x5D) << 8)
5706                   | i2c_smbus_read_byte_data($file, 0x5E);
5707
5708        return unless $vendid == 0x1934; # Fintek ID
5709
5710        if ($chip == 1) { # F75111R/RG/N
5711                return unless $chipid == 0x0300;
5712        } elsif ($chip == 2) { # F75121R/F75122R/RG
5713                return unless $chipid == 0x0301;
5714        } elsif ($chip == 3) { # F75373S/SG
5715                return unless $chipid == 0x0204;
5716        } elsif ($chip == 4) { # F75375S/SP
5717                return unless $chipid == 0x0306;
5718        } elsif ($chip == 5) { # F75387SG/RG
5719                return unless $chipid == 0x0410;
5720        } elsif ($chip == 6) { # F75383M/S/F75384M/S
5721                # The datasheet has 0x0303, but Fintek say 0x0413 is also
5722                # possible
5723                return unless $chipid == 0x0303 || $chipid == 0x0413;
5724        } elsif ($chip == 7) { # custom power control IC
5725                return unless $chipid == 0x0302;
5726        }
5727
5728        return 7;
5729}
5730
5731# Chips to detect: 0 = EMC1023, 1 = EMC1043, 2 = EMC1053, 3 = EMC1063
5732# Registers used:
5733#   0xed: Device ID register
5734#   0xfe: Vendor ID register
5735#   0xff: Revision register
5736sub emc1023_detect
5737{
5738        my ($file, $addr, $chip) = @_;
5739        my $dev_id = i2c_smbus_read_byte_data($file, 0xed);
5740        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
5741        my $rev = i2c_smbus_read_byte_data($file, 0xff);
5742
5743        return unless $man_id == 0x5d;  # SMSC
5744        return unless $rev <= 1;
5745
5746        if ($chip == 0) {
5747                return if ($addr == 0x4c) && ($dev_id != 0x04); # EMC1023-1
5748                return if ($addr == 0x4d) && ($dev_id != 0x05); # EMC1023-2
5749                return if ($addr == 0x48) && ($dev_id != 0x06); # EMC1023-3
5750                return if ($addr == 0x49) && ($dev_id != 0x07); # EMC1023-4
5751        } elsif ($chip == 1) {
5752                if ($addr == 0x4c) {                            # EMC1043-1, EMC1043-5
5753                        return unless ($dev_id == 0x0c) || ($dev_id == 0x2c);
5754                }
5755                return if ($addr == 0x4d) && ($dev_id != 0x0d); # EMC1043-2
5756                return if ($addr == 0x48) && ($dev_id != 0x0e); # EMC1043-3
5757                return if ($addr == 0x49) && ($dev_id != 0x0f); # EMC1043-4
5758        } elsif ($chip == 2) {
5759                return if ($addr == 0x4c) && ($dev_id != 0x3c); # EMC1053-1
5760                return if ($addr == 0x4d) && ($dev_id != 0x3d); # EMC1053-2
5761                return if ($addr == 0x48) && ($dev_id != 0x3e); # EMC1053-3
5762                return if ($addr == 0x49) && ($dev_id != 0x3f); # EMC1053-4
5763        } elsif ($chip == 3) {
5764                return if ($addr == 0x4c) && ($dev_id != 0x30); # EMC1063-1
5765                return if ($addr == 0x4d) && ($dev_id != 0x31); # EMC1063-2
5766                return if ($addr == 0x48) && ($dev_id != 0x32); # EMC1063-3
5767                return if ($addr == 0x49) && ($dev_id != 0x33); # EMC1063-4
5768        }
5769
5770        return 7;
5771}
5772
5773# Chip to detect: 0 = EMC1403, 1 = EMC1404, 2 = EMC2103, 3 = EMC1423,
5774#       4 = EMC1002, 5 = EMC1033, 6 = EMC1046, 7 = EMC1047, 8 = EMC1072,
5775#       9 = EMC1073, 10 = EMC1074, 11 = EMC1402, 12 = EMC1424
5776# Registers used:
5777#   0xfd: Device ID register
5778#   0xfe: Vendor ID register
5779#   0xff: Revision register
5780sub emc1403_detect
5781{
5782        my ($file, $addr, $chip) = @_;
5783        my $dev_id = i2c_smbus_read_byte_data($file, 0xfd);
5784        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
5785        my $rev = i2c_smbus_read_byte_data($file, 0xff);
5786
5787        return unless $man_id == 0x5d;  # SMSC
5788
5789        if ($chip == 0) {               # EMC1403
5790                return unless $dev_id == 0x21;
5791                return unless $rev == 0x01;
5792        } elsif ($chip == 1) {          # EMC1404
5793                return unless $dev_id == 0x25;
5794                return unless $rev == 0x01;
5795        } elsif ($chip == 2) {          # EMC2103
5796                return unless ($dev_id == 0x24) || ($dev_id == 0x26);
5797                return unless $rev == 0x01;
5798        } elsif ($chip == 3) {          # EMC1423
5799                return unless $dev_id == 0x23;
5800                return unless $rev == 0x01;
5801        } elsif ($chip == 4) {          # EMC1002
5802                return unless ($dev_id == 0x02) || ($dev_id == 0x03);
5803                return unless $rev == 0x01;
5804        } elsif ($chip == 5) {          # EMC1033
5805                return unless ($dev_id == 0x0a) || ($dev_id == 0x0b);
5806                return unless $rev == 0x01;
5807        } elsif ($chip == 6) {          # EMC1046
5808                return unless $dev_id == 0x1a;
5809                return unless $rev == 0x01;
5810        } elsif ($chip == 7) {          # EMC1047
5811                return unless $dev_id == 0x1c;
5812                return unless $rev == 0x01;
5813        } elsif ($chip == 8) {          # EMC1072
5814                return unless $dev_id == 0x20;
5815                return unless $rev == 0x03;
5816        } elsif ($chip == 9) {          # EMC1073
5817                return unless $dev_id == 0x21;
5818                return unless $rev == 0x03;
5819        } elsif ($chip == 10) {         # EMC1074
5820                return unless $dev_id == 0x25;
5821                return unless $rev == 0x03;
5822        } elsif ($chip == 11) {         # EMC1402
5823                return unless $dev_id == 0x20;
5824                return unless $rev == 0x01;
5825        } elsif ($chip == 12) {         # EMC1424
5826                return unless $dev_id == 0x27;
5827                return unless $rev == 0x01;
5828        }
5829
5830        return 6;
5831}
5832
5833# Chip to detect: 0 = W83L784R/AR/G, 1 = W83L785R/G, 2 = W83L786NR/NG/R/G,
5834#                 3 = W83L785TS-S
5835# Registers used:
5836#   0x40: Configuration
5837#   0x4a: Full I2C Address (W83L784R only)
5838#   0x4b: I2C addresses of emulated LM75 chips (W83L784R only)
5839#   0x4c: Winbond Vendor ID (Low Byte)
5840#   0x4d: Winbond Vendor ID (High Byte)
5841#   0x4e: Chip ID
5842sub w83l784r_detect
5843{
5844        my ($file, $addr, $chip) = @_;
5845        my ($reg, @res);
5846
5847        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
5848        return if $chip == 0
5849              and i2c_smbus_read_byte_data($file, 0x4a) != $addr;
5850        return unless i2c_smbus_read_byte_data($file, 0x4c) == 0xa3;
5851        return unless i2c_smbus_read_byte_data($file, 0x4d) == 0x5c;
5852
5853        $reg = i2c_smbus_read_byte_data($file, 0x4e);
5854        return if $chip == 0 and $reg != 0x50;
5855        return if $chip == 1 and $reg != 0x60;
5856        return if $chip == 2 and $reg != 0x80;
5857        return if $chip == 3 and $reg != 0x70;
5858
5859        return 8 if $chip != 0; # No subclients
5860
5861        @res = (8);
5862        $reg = i2c_smbus_read_byte_data($file, 0x4b);
5863        push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
5864        push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
5865        return @res;
5866}
5867
5868# Chip to detect: MAX6639
5869# Registers used:
5870#   0x3d: Device ID
5871#   0x3e: Manufacturer ID
5872#   0x3f: Chip revision
5873sub max6639_detect
5874{
5875        my ($file, $addr) = @_;
5876        my ($man_id, $dev_id, $rev);
5877
5878        $dev_id = i2c_smbus_read_byte_data($file, 0x3d);
5879        $man_id = i2c_smbus_read_byte_data($file, 0x3e);
5880        $rev = i2c_smbus_read_byte_data($file, 0x3f);
5881       
5882        return unless $man_id == 0x4d;  # Maxim
5883        return unless $dev_id == 0x58;  # MAX6639
5884        return unless $rev == 0x00;
5885
5886        return 6;
5887}
5888
5889# Chip to detect: MAX6642
5890# Registers used:
5891#   0x02: Status register
5892#   0x03: Configuration register
5893#   0xfe: Manufacturer ID
5894#   0x04, 0x06, 0xff: No registers
5895# We use the 0x04, 0x06 and 0xff addresses (unused) to improve reliability.
5896# These are not real registers and will always return the last returned value.
5897# This isn't documented.
5898sub max6642_detect
5899{
5900        my ($file, $addr) = @_;
5901        my ($man_id, $conf, $status);
5902
5903        $man_id = i2c_smbus_read_byte_data($file, 0xfe);
5904        return unless $man_id == 0x4d;  # Maxim
5905        return if i2c_smbus_read_byte_data($file, 0x04, NO_CACHE) != $man_id;
5906        return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $man_id;
5907        return if i2c_smbus_read_byte_data($file, 0xff, NO_CACHE) != $man_id;
5908
5909        $status = i2c_smbus_read_byte_data($file, 0x02);
5910        # Bit 5, 3, 1 and 0 should be zero
5911        return unless ($status & 0x2b) == 0x00;
5912        return if i2c_smbus_read_byte_data($file, 0x04, NO_CACHE) != $status;
5913        return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $status;
5914        return if i2c_smbus_read_byte_data($file, 0xff, NO_CACHE) != $status;
5915
5916        $conf = i2c_smbus_read_byte_data($file, 0x03);
5917        # The 4 lower bits should be zero
5918        return unless ($conf & 0x0f) == 0x00;
5919
5920        return 5;
5921}
5922
5923sub max6655_detect
5924{
5925        my ($file, $addr) = @_;
5926
5927        # checking RDID (Device ID)
5928        return unless i2c_smbus_read_byte_data($file, 0xfe) == 0x0a;
5929        # checking RDRV (Manufacturer ID)
5930        return unless i2c_smbus_read_byte_data($file, 0xff) == 0x4d;
5931        # checking unused bits (conversion rate, extended temperature)
5932        return unless i2c_smbus_read_byte_data($file, 0x04) & 0xf8;
5933        return unless i2c_smbus_read_byte_data($file, 0x10) & 0x1f;
5934        return unless i2c_smbus_read_byte_data($file, 0x11) & 0x1f;
5935        return unless i2c_smbus_read_byte_data($file, 0x12) & 0x1f;
5936
5937        return 6;
5938}
5939
5940# Chip to detect: 0 = STTS424, 1 = SE97/SE97B, 2 = SE98, 3 = ADT7408,
5941#                 4 = TS3000/TSE2002, 5 = MAX6604, 6 = MCP98242,
5942#                 7 = MCP98243, 8 = MCP9843, 9 = CAT6095 / CAT34TS02,
5943#                 10 = STTS424E
5944# Registers used:
5945#   0x00: Capabilities
5946#   0x01: Configuration
5947#   0x06: Manufacturer ID
5948#   0x07: Device ID
5949sub jedec_JC42_4_detect
5950{
5951        my ($file, $addr, $chip) = @_;
5952        my ($reg, $manid, $devid);
5953
5954        # We test the MSB only at first, because not all chips enjoy
5955        # word access.
5956
5957        # Check for unused bits
5958        $reg = i2c_smbus_read_byte_data($file, 0x00);
5959        return if $reg & 0xff;
5960        $reg = i2c_smbus_read_byte_data($file, 0x01);
5961        return if $reg & 0xf8;
5962
5963        # Check for manufacturer and device ID
5964        $manid = i2c_smbus_read_byte_data($file, 0x06);
5965        $devid = i2c_smbus_read_byte_data($file, 0x07);
5966
5967        if ($chip == 0) {
5968                return unless $manid == 0x10;           # STMicrolectronics
5969                return unless $devid == 0x01;           # STTS424
5970        } elsif ($chip == 1) {
5971                return unless $manid == 0x11;           # NXP
5972                return unless $devid == 0xa2;           # SE97
5973        } elsif ($chip == 2) {
5974                return unless $manid == 0x11;           # NXP
5975                return unless $devid == 0xa1;           # SE98
5976        } elsif ($chip == 3) {
5977                return unless $manid == 0x11;           # ADT
5978                return unless $devid == 0x08;           # ADT7408
5979        } elsif ($chip == 4) {
5980                return unless $manid == 0x00;           # IDT
5981                return unless $devid == 0x29;           # TS3000/TSE2002
5982        } elsif ($chip == 5) {
5983                return unless $manid == 0x00;           # MAXIM
5984                return unless $devid == 0x3e;           # MAX6604
5985        } elsif ($chip == 6) {
5986                return unless $manid == 0x00;           # MCP
5987                return unless $devid == 0x20;           # MCP98242
5988        } elsif ($chip == 7) {
5989                return unless $manid == 0x00;           # MCP
5990                return unless $devid == 0x21;           # MCP98243
5991        } elsif ($chip == 8) {
5992                return unless $manid == 0x00;           # MCP
5993                return unless $devid == 0x00;           # MCP9843
5994        } elsif ($chip == 9) {
5995                return unless $manid == 0x1b;           # ONS
5996                return unless $devid == 0x08;           # CAT6095 / CAT34TS02
5997        } elsif ($chip == 10) {
5998                return unless $manid == 0x10;           # STMicrolectronics
5999                return unless $devid == 0x00;           # STTS424E02
6000        }
6001
6002        # Now, do it all again with words. Note that we get
6003        # the MSB first, so all value checks are byte-swapped.
6004
6005        # Check for unused bits
6006        $reg = i2c_smbus_read_word_data($file, 0x00);
6007        return if $reg < 0 || $reg & 0x00ff;
6008
6009        $manid = i2c_smbus_read_word_data($file, 0x06);
6010        $devid = i2c_smbus_read_word_data($file, 0x07);
6011        return if $manid < 0 || $devid < 0;
6012        if ($chip == 0) {
6013                return unless $manid == 0x4a10;         # STMicrolectronics
6014                return unless ($devid & 0xfeff) == 0x0001; # STTS424
6015        } elsif ($chip == 1) {
6016                return unless $manid == 0x3111;         # NXP
6017                return unless ($devid & 0xfcff) == 0x00a2; # SE97
6018        } elsif ($chip == 2) {
6019                return unless $manid == 0x3111;         # NXP
6020                return unless ($devid & 0xfcff) == 0x00a1; # SE98
6021        } elsif ($chip == 3) {
6022                return unless $manid == 0xd411;         # ADT
6023                return unless $devid == 0x0108;         # ADT7408
6024        } elsif ($chip == 4) {
6025                return unless $manid == 0xb300;         # IDT
6026                return unless $devid == 0x0329;         # TS3000/TSE2002
6027        } elsif ($chip == 5) {
6028                return unless $manid == 0x4d00;         # MAXIM
6029                return unless $devid == 0x003e;         # MAX6604
6030        } elsif ($chip == 6) {
6031                return unless $manid == 0x5400;         # MCP
6032                return unless ($devid & 0xfcff) == 0x0020; # MCP98242
6033        } elsif ($chip == 7) {
6034                return unless $manid == 0x5400;         # MCP
6035                return unless ($devid & 0xfcff) == 0x0021; # MCP98243
6036        } elsif ($chip == 8) {
6037                return unless $manid == 0x5400;         # MCP
6038                return unless ($devid & 0xfcff) == 0x0000; # MCP9843
6039        } elsif ($chip == 9) {
6040                return unless $manid == 0x091b;         # ONS
6041                return unless ($devid & 0xe0ff) == 0x0008; # CAT6095 / CAT34TS02
6042        } elsif ($chip == 10) {
6043                return unless $manid == 0x4a10;         # STMicrolectronics
6044                return unless ($devid & 0xfeff) == 0x0000; # STTS424E02
6045        }
6046
6047        return 5;
6048}
6049
6050# This isn't very good detection.
6051# Verify the i2c address, and the stepping ID (which is 0xb0 on
6052# my chip but could be different for others...
6053sub vt1211_i2c_detect
6054{
6055        my ($file, $addr) = @_;
6056        return unless (i2c_smbus_read_byte_data($file, 0x48) & 0x7f) == $addr;
6057        return unless i2c_smbus_read_byte_data($file, 0x3f) == 0xb0;
6058        return 2;
6059}
6060
6061# All ISA detection functions below take at least 1 parameter:
6062# $_[0]: Address
6063# Some of these functions which can detect more than one type of device,
6064# take a second parameter:
6065# $_[1]: Chip to detect
6066
6067# Chip to detect: 0 = LM78, 2 = LM79
6068sub lm78_isa_detect
6069{
6070        my ($addr, $chip) = @_;
6071        my $val = inb($addr + 1);
6072        return if inb($addr + 2) != $val or inb($addr + 3) != $val or
6073                  inb($addr + 7) != $val;
6074
6075        $val = inb($addr + 5);
6076        outb($addr + 5, ~$val & 0x7f);
6077        if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
6078                outb($addr+5, $val);
6079                return;
6080        }
6081
6082        return unless (isa_read_i5d6($addr, 0x40) & 0x80) == 0x00;
6083        my $reg = isa_read_i5d6($addr, 0x49);
6084        return if $chip == 0 && ($reg != 0x00 && $reg != 0x20 && $reg != 0x40);
6085        return if $chip == 2 && ($reg & 0xfe) != 0xc0;
6086
6087        # Explicitly prevent misdetection of Winbond chips
6088        $reg = isa_read_i5d6($addr, 0x4f);
6089        return if $reg == 0xa3 || $reg == 0x5c;
6090
6091        # Explicitly prevent misdetection of ITE chips
6092        $reg = isa_read_i5d6($addr, 0x58);
6093        return if $reg == 0x90;
6094
6095        return 6;
6096}
6097
6098# Chip to detect: 0 = W83781D, 1 = W83782D
6099sub w83781d_isa_detect
6100{
6101        my ($addr, $chip) = @_;
6102        my ($reg1, $reg2);
6103        my $val = inb($addr + 1);
6104        return if inb($addr + 2) != $val or inb($addr + 3) != $val or
6105                  inb($addr + 7) != $val;
6106
6107        $val = inb($addr + 5);
6108        outb($addr+5, ~$val & 0x7f);
6109        if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
6110                outb($addr+5, $val);
6111                return;
6112        }
6113
6114        $reg1 = isa_read_i5d6($addr, 0x4e);
6115        $reg2 = isa_read_i5d6($addr, 0x4f);
6116        return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
6117                      (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
6118        return unless ($reg1 & 0x07) == 0x00;
6119        $reg1 = isa_read_i5d6($addr, 0x58);
6120        return if $chip == 0 && ($reg1 & 0xfe) != 0x10;
6121        return if $chip == 1 && ($reg1 & 0xfe) != 0x30;
6122
6123        return 8;
6124}
6125
6126########
6127# IPMI #
6128########
6129
6130# Returns: number of IPMI interfaces found
6131sub ipmi_from_smbios
6132{
6133        my ($version, $if, @ipmi_if);
6134        my $ipmi_driver = "to-be-written";      # ipmisensors
6135
6136        return 0 unless check_dmidecode_version();
6137
6138        # Parse the output of dmidecode into an array of IPMI interfaces.
6139        # Each entry is a hash with the following keys: type and addr.
6140        $if = -1;
6141        open(local *DMIDECODE, "dmidecode -t 38 2>/dev/null |") or return 0;
6142        while (<DMIDECODE>) {
6143                if (m/^IPMI Device Information/) {
6144                        $if++;
6145                        next;
6146                }
6147                next unless $if >= 0;
6148
6149                if (m/^\tInterface Type: (.*)$/) {
6150                        $ipmi_if[$if]->{type} = "IPMI BMC $1";
6151                        $ipmi_if[$if]->{type} =~ s/ \(.*//;
6152                        next;
6153                }
6154                if (m/^\tBase Address: (0x[0-9A-Fa-f]+) \(I\/O\)$/) {
6155                        $ipmi_if[$if]->{addr} = oct($1);
6156                        next;
6157                }
6158        }
6159        close(DMIDECODE);
6160
6161        foreach $if (@ipmi_if) {
6162                if (exists $if->{addr}) {
6163                        printf("\%-60s", sprintf("Found `\%s' at 0x\%x... ",
6164                                                 $if->{type}, $if->{addr}));
6165                } else {
6166                        printf("\%-60s", sprintf("Found `\%s'... ",
6167                                                 $if->{type}));
6168                }
6169                print "Success!\n".
6170                      "    (confidence 8, driver `$ipmi_driver')\n";
6171                my $new_hash = {
6172                        conf => 8,
6173                        isa_addr => $if->{addr} || 0,
6174                        chipname => $if->{type},
6175                };
6176                add_isa_to_chips_detected($ipmi_driver, $new_hash);
6177        }
6178
6179        return scalar @ipmi_if;
6180}
6181
6182# We simply look for a register at standard locations.
6183# For KCS, use the STATUS register. For SMIC, use the FLAGS register.
6184# Incidentally they live at the same offset.
6185sub ipmi_detect
6186{
6187        my ($addr) = @_;
6188        return if inb($addr + 3) == 0xff;
6189        return 4;
6190}
6191
6192###################
6193# ALIAS DETECTION #
6194###################
6195
6196# These functions take at least 3 parameters:
6197# $_[0]: ISA/LPC address
6198# $_[1]: I2C file handle
6199# $_[2]: I2C address
6200# Some of these functions may take extra parameters.
6201# They return 1 if both devices are the same, 0 if not.
6202
6203# Extra parameters:
6204# $_[3]: First limit register to compare
6205# $_[4]: Last limit register to compare
6206sub winbond_alias_detect
6207{
6208        my ($isa_addr, $file, $i2c_addr, $first, $last) = @_;
6209        my $i;
6210
6211        return 0 unless isa_read_i5d6($isa_addr, 0x48) == $i2c_addr;
6212        for ($i = $first; $i <= $last; $i++) {
6213                return 0 unless isa_read_i5d6($isa_addr, $i) ==
6214                                i2c_smbus_read_byte_data($file, $i);
6215        }
6216        return 1;
6217}
6218
6219############################
6220# PCI CHIP / CPU DETECTION #
6221############################
6222
6223sub sis5595_pci_detect
6224{
6225        return unless exists $pci_list{'1039:0008'};
6226        return 9;
6227}
6228
6229sub via686a_pci_detect
6230{
6231        return unless exists $pci_list{'1106:3057'};
6232        return 9;
6233}
6234
6235sub via8231_pci_detect
6236{
6237        return unless exists $pci_list{'1106:8235'};
6238        return 9;
6239}
6240
6241sub amd_pci_detect
6242{
6243        my $f3_id = shift;
6244        return unless exists $pci_list{"1022:$f3_id"};
6245        return 9;
6246}
6247
6248sub fam10h_pci_detect
6249{
6250        return unless exists $pci_list{'1022:1203'};
6251
6252        # Errata 319 (Inaccurate Temperature Measurement) affects
6253        # revisions DR-BA, DR-B2 and DR-B3, all have model number = 2.
6254        # Revisions RB-C2 and HY-D0 are also affected.
6255        my $probecpu;
6256        foreach $probecpu (@cpu) {
6257                next unless $probecpu->{vendor_id} eq 'AuthenticAMD' &&
6258                            $probecpu->{'cpu family'} == 0x10;
6259
6260                next if $probecpu->{model} < 4;         # DR-B*
6261                next if $probecpu->{model} == 8;        # HY-D0
6262                if ($probecpu->{model} == 4 && $probecpu->{stepping} <= 2) {    # RB-C2
6263                        my @dram_cfg = split /\n/, `setpci -d 1022:1202 94.L 2>/dev/null`;
6264                        next unless @dram_cfg >= 1;
6265                        next unless hex($dram_cfg[0]) & 0x00000100;     # DDR3
6266                }
6267
6268                return 9;
6269        }
6270       
6271        return;
6272}
6273
6274sub intel_amb_detect
6275{
6276        if ((exists $pci_list{'8086:25f0'}) ||  # Intel 5000
6277            (exists $pci_list{'8086:4030'})) {  # Intel 5400
6278                return 9;
6279        }
6280        return;
6281}
6282
6283sub cpuid
6284{
6285        my ($cpu_nr, $eax) = @_;
6286
6287        sysopen(CPUID, "/dev/cpu/$cpu_nr/cpuid", O_RDONLY) or return;
6288        binmode CPUID;
6289        sysseek(CPUID, $eax, SEEK_SET)
6290                or die "Cannot seek /dev/cpu/$cpu_nr/cpuid";
6291        sysread(CPUID, my $data, 16)
6292                or die "Cannot read /dev/cpu/$cpu_nr/cpuid";
6293        close CPUID;
6294
6295        return unpack("L4", $data);
6296}
6297
6298sub coretemp_detect
6299{
6300        my $probecpu;
6301
6302        foreach $probecpu (@cpu) {
6303                next unless $probecpu->{vendor_id} eq 'GenuineIntel' &&
6304                            $probecpu->{'cpuid level'} >= 6;
6305
6306                # Now we check for the DTS flag
6307                my @regs = cpuid($probecpu->{nr}, 6);
6308                return unless @regs == 4;
6309                return 9 if ($regs[0] & (1 << 0));      # eax, bit 0
6310        }
6311        return;
6312}
6313
6314sub via_c7_detect
6315{
6316        my $probecpu;
6317        foreach $probecpu (@cpu) {
6318                if ($probecpu->{vendor_id} eq 'CentaurHauls' &&
6319                                $probecpu->{'cpu family'} == 6 &&
6320                                ($probecpu->{model} == 0xa ||
6321                                 $probecpu->{model} == 0xd)) {
6322                        return 9;
6323                }
6324        }
6325        return;
6326}
6327
6328sub via_nano_detect
6329{
6330        my $probecpu;
6331        foreach $probecpu (@cpu) {
6332                if ($probecpu->{vendor_id} eq 'CentaurHauls' &&
6333                                $probecpu->{'cpu family'} == 6 &&
6334                                $probecpu->{model} == 0xf) {
6335                        return 9;
6336                }
6337        }
6338        return;
6339}
6340
6341#################
6342# SPECIAL MODES #
6343#################
6344
6345sub show_i2c_stats
6346{
6347        my ($chip, $addr, %histo, $chips);
6348
6349        # Gather the data
6350        foreach $chip (@chip_ids) {
6351                next unless defined $chip->{i2c_addrs};
6352                $chips++;
6353                foreach my $addr (@{$chip->{i2c_addrs}}) {
6354                        $histo{$addr}++;
6355                }
6356        }
6357
6358        # Display the data
6359        printf "\%d I2C chips known, \%d I2C addresses probed\n\n",
6360                $chips, scalar keys %histo;
6361        print "     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n".
6362              "00:         ";
6363        for (my $addr = 0x03; $addr <= 0x77; $addr++) {
6364                printf("\n\%02x:", $addr) if ($addr % 16) == 0;
6365                if (defined $histo{$addr}) {
6366                        printf ' %02d', $histo{$addr};
6367                } else {
6368                        print ' --';
6369                }
6370        }
6371        print "\n";
6372}
6373
6374################
6375# MAIN PROGRAM #
6376################
6377
6378# $_[0]: reference to a list of chip hashes
6379sub print_chips_report
6380{
6381        my ($listref) = @_;
6382        my $data;
6383
6384        foreach $data (@$listref) {
6385                my $is_i2c = exists $data->{i2c_addr};
6386                my $is_isa = exists $data->{isa_addr};
6387                print "  * ";
6388                if ($is_i2c) {
6389                        printf "Bus `%s'\n", $i2c_adapters[$data->{i2c_devnr}]->{name};
6390                        printf "    Busdriver `%s', I2C address 0x%02x",
6391                               $i2c_adapters[$data->{i2c_devnr}]->{driver}, $data->{i2c_addr};
6392                        if (exists $data->{i2c_sub_addrs}) {
6393                                print " (and";
6394                                my $sub_addr;
6395                                foreach $sub_addr (@{$data->{i2c_sub_addrs}}) {
6396                                        printf " 0x%02x", $sub_addr;
6397                                }
6398                                print ")"
6399                        }
6400                        print "\n    ";
6401                }
6402                if ($is_isa) {
6403                        print "ISA bus";
6404                        if ($data->{isa_addr}) {
6405                                printf ", address 0x%x", $data->{isa_addr};
6406                        }
6407                        print " (Busdriver `i2c-isa')"
6408                                unless kernel_version_at_least(2, 6, 18);
6409                        print "\n    ";
6410                }
6411                printf "Chip `%s' (confidence: %d)\n",
6412                       $data->{chipname}, $data->{conf};
6413        }
6414}
6415
6416sub generate_modprobes
6417{
6418        my ($driver, $detection, $adap);
6419        my ($configfile, %bus_modules, %hwmon_modules);
6420
6421        foreach $driver (keys %chips_detected) {
6422                foreach $detection (@{$chips_detected{$driver}}) {
6423                        # Tag adapters which host hardware monitoring chips we want to access
6424                        if (exists $detection->{i2c_devnr}
6425                         && !exists $detection->{isa_addr}) {
6426                                $i2c_adapters[$detection->{i2c_devnr}]->{used}++;
6427                        }
6428
6429                        # i2c-isa is loaded automatically (as a dependency)
6430                        # since 2.6.14, and will soon be gone.
6431                        if (exists $detection->{isa_addr}
6432                         && !kernel_version_at_least(2, 6, 18)) {
6433                                $bus_modules{"i2c-isa"}++
6434                        }
6435                }
6436                if ($driver eq "ipmisensors") {
6437                        $bus_modules{"ipmi-si"}++;
6438                }
6439        }
6440
6441        # Handle aliases
6442        # As of kernel 2.6.28, alias detection is handled by kernel drivers
6443        # directly, so module options are no longer needed.
6444        unless (kernel_version_at_least(2, 6, 28)) {
6445                foreach $driver (keys %chips_detected) {
6446                        my @optionlist = ();
6447                        foreach $detection (@{$chips_detected{$driver}}) {
6448                                next unless exists $detection->{i2c_addr}
6449                                         && exists $detection->{isa_addr}
6450                                         && $i2c_adapters[$detection->{i2c_devnr}]->{used};
6451
6452                                push @optionlist, sprintf("%d,0x%02x",
6453                                                          $detection->{i2c_devnr},
6454                                                          $detection->{i2c_addr});
6455                        }
6456
6457                        next if not @optionlist;
6458                        $configfile = "# hwmon module options\n"
6459                                unless defined $configfile;
6460                        $configfile .= "options $driver ignore=".
6461                                       (join ",", @optionlist)."\n";
6462                }
6463        }
6464
6465        # If we added any module option to handle aliases, we need to load all
6466        # the adapter drivers so that the numbers will be the same. If not, then
6467        # we only load the adapter drivers which are useful.
6468        foreach $adap (@i2c_adapters) {
6469                next unless defined $adap;
6470                next if $adap->{autoload};
6471                next if $adap->{driver} eq 'UNKNOWN';
6472                next if not defined $configfile and not $adap->{used};
6473                $bus_modules{$adap->{driver}}++;
6474        }
6475
6476        # Now determine the chip probe lines
6477        foreach $driver (keys %chips_detected) {
6478                next if not @{$chips_detected{$driver}};
6479                if ($driver eq "to-be-written") {
6480                        print "Note: there is no driver for ${$chips_detected{$driver}}[0]{chipname} yet.\n".
6481                              "Check http://www.lm-sensors.org/wiki/Devices for updates.\n\n";
6482                } else {
6483                        open(local *INPUTFILE, "modprobe -l $driver 2>/dev/null |");
6484                        local $_;
6485                        my $modulefound = 0;
6486                        while (<INPUTFILE>) {
6487                                if (m@/@) {
6488                                        $modulefound = 1;
6489                                        last;
6490                                }
6491                        }
6492                        close(INPUTFILE);
6493                        # Check return value from modprobe in case modprobe -l
6494                        # isn't supported
6495                        if ((($? >> 8) == 0) && ! $modulefound) {
6496                                print "Warning: the required module $driver is not currently installed\n".
6497                                      "on your system. If it is built into the kernel then it's OK.\n".
6498                                      "Otherwise, check http://www.lm-sensors.org/wiki/Devices for\n".
6499                                      "driver availability.\n\n";
6500                        } else {
6501                                $hwmon_modules{$driver}++
6502                                        unless hwmon_is_autoloaded($driver);
6503                        }
6504                }
6505        }
6506
6507        my @bus_modules = sort keys %bus_modules;
6508        my @hwmon_modules = sort keys %hwmon_modules;
6509        return ($configfile, \@bus_modules, \@hwmon_modules);
6510}
6511
6512sub write_config
6513{
6514        my ($configfile, $bus_modules, $hwmon_modules) = @_;
6515
6516        if (defined $configfile) {
6517                my $have_modprobe_d = -d '/etc/modprobe.d';
6518                printf "Do you want to \%s /etc/modprobe.d/lm_sensors.conf? (\%s): ",
6519                       (-e '/etc/modprobe.d/lm_sensors.conf' ? 'overwrite' : 'generate'),
6520                       ($have_modprobe_d ? 'YES/no' : 'yes/NO');
6521                $_ = <STDIN>;
6522                if (($have_modprobe_d and not m/^\s*n/i) or m/^\s*y/i) {
6523                        unless ($have_modprobe_d) {
6524                                mkdir('/etc/modprobe.d', 0777)
6525                                        or die "Sorry, can't create /etc/modprobe.d ($!)";
6526                        }
6527                        open(local *MODPROBE_D, ">/etc/modprobe.d/lm_sensors.conf")
6528                                or die "Sorry, can't create /etc/modprobe.d/lm_sensors.conf ($!)";
6529                        print MODPROBE_D "# Generated by sensors-detect on " . scalar localtime() . "\n";
6530                        print MODPROBE_D $configfile;
6531                        close(MODPROBE_D);
6532                } else {
6533                        print "To make the sensors modules behave correctly, add these lines to\n".
6534                              "/etc/modprobe.conf:\n\n";
6535                        print "#----cut here----\n".
6536                              $configfile.
6537                              "#----cut here----\n\n";
6538                }
6539        }
6540
6541        my $have_sysconfig = -d '/etc/sysconfig';
6542        printf "Do you want to \%s /etc/sysconfig/lm_sensors? (\%s): ",
6543               (-e '/etc/sysconfig/lm_sensors' ? 'overwrite' : 'generate'),
6544               ($have_sysconfig ? 'YES/no' : 'yes/NO');
6545        $_ = <STDIN>;
6546        if (($have_sysconfig and not m/^\s*n/i) or m/^\s*y/i) {
6547                unless ($have_sysconfig) {
6548                        mkdir('/etc/sysconfig', 0777)
6549                                or die "Sorry, can't create /etc/sysconfig ($!)";
6550                }
6551                open(local *SYSCONFIG, ">/etc/sysconfig/lm_sensors")
6552                        or die "Sorry, can't create /etc/sysconfig/lm_sensors ($!)";
6553                print SYSCONFIG "# Generated by sensors-detect on " . scalar localtime() . "\n";
6554                print SYSCONFIG <<'EOT';
6555# This file is sourced by /etc/init.d/lm_sensors and defines the modules to
6556# be loaded/unloaded.
6557#
6558# The format of this file is a shell script that simply defines variables:
6559# HWMON_MODULES for hardware monitoring driver modules, and optionally
6560# BUS_MODULES for any required bus driver module (for example for I2C or SPI).
6561
6562EOT
6563                print SYSCONFIG "BUS_MODULES=\"", join(" ", @{$bus_modules}), "\"\n"
6564                        if @{$bus_modules};
6565                print SYSCONFIG "HWMON_MODULES=\"", join(" ", @{$hwmon_modules}), "\"\n";
6566
6567                print SYSCONFIG <<'EOT';
6568
6569# For compatibility reasons, modules are also listed individually as variables
6570#    MODULE_0, MODULE_1, MODULE_2, etc.
6571# You should use BUS_MODULES and HWMON_MODULES instead if possible.
6572
6573EOT
6574                my $i = 0;
6575                foreach (@{$bus_modules}, @{$hwmon_modules}) {
6576                        print SYSCONFIG "MODULE_$i=$_\n";
6577                        $i++;
6578                }
6579                close(SYSCONFIG);
6580
6581                if (-x "/bin/systemctl" && -d "/lib/systemd/system" &&
6582                    ! -f "/lib/systemd/system/lm_sensors.service") {
6583                        print "Copy prog/init/lm_sensors.service to /lib/systemd/system\n".
6584                              "and run 'systemctl enable lm_sensors.service'\n".
6585                              "for initialization at boot time.\n";
6586                        return;
6587                }
6588
6589                if (-x "/bin/systemctl" &&
6590                    -f "/lib/systemd/system/lm_sensors.service") {
6591                        system("/bin/systemctl", "enable", "lm_sensors.service");
6592                        system("/bin/systemctl", "start", "lm_sensors.service");
6593                        # All done, don't check for /etc/init.d/lm_sensors
6594                        return;
6595                }
6596
6597                print "Copy prog/init/lm_sensors.init to /etc/init.d/lm_sensors\n".
6598                      "for initialization at boot time.\n"
6599                        unless -f "/etc/init.d/lm_sensors";
6600
6601                if (-x "/sbin/insserv" && -f "/etc/init.d/lm_sensors") {
6602                        system("/sbin/insserv", "/etc/init.d/lm_sensors");
6603                } elsif (-x "/sbin/chkconfig" && -f "/etc/init.d/lm_sensors") {
6604                        system("/sbin/chkconfig", "lm_sensors", "on");
6605                        if (-x "/sbin/service") {
6606                                system("/sbin/service", "lm_sensors", "start");
6607                        }
6608                } else {
6609                        print "You should now start the lm_sensors service to load the required\n".
6610                              "kernel modules.\n\n";
6611                }
6612        } else {
6613                print "To load everything that is needed, add this to one of the system\n".
6614                      "initialization scripts (e.g. /etc/rc.d/rc.local):\n\n";
6615                print "#----cut here----\n";
6616                if (@{$bus_modules}) {
6617                        print "# Adapter drivers\n";
6618                        print "modprobe $_\n" foreach (@{$bus_modules});
6619                }
6620                print "# Chip drivers\n";
6621                print "modprobe $_\n" foreach (@{$hwmon_modules});
6622                print((-e '/usr/bin/sensors' ?
6623                       "/usr/bin/sensors -s\n" :
6624                       "/usr/local/bin/sensors -s\n").
6625                      "#----cut here----\n\n");
6626
6627                print "If you have some drivers built into your kernel, the list above will\n".
6628                      "contain too many modules. Skip the appropriate ones! You really\n".
6629                      "should try these commands right now to make sure everything is\n".
6630                      "working properly. Monitoring programs won't work until the needed\n".
6631                      "modules are loaded.\n\n";
6632        }
6633
6634}
6635
6636sub main
6637{
6638        my ($input, $superio_features);
6639
6640        # Handle special command line cases first
6641        if (defined $ARGV[0] && $ARGV[0] eq "--stat") {
6642                show_i2c_stats();
6643                exit 0;
6644        }
6645
6646        # We won't go very far if not root
6647        unless ($> == 0) {
6648                print "You need to be root to run this script.\n";
6649                exit -1;
6650        }
6651
6652        if (-x "/bin/systemctl" && -f "/lib/systemd/system/lm_sensors.service") {
6653                system("/bin/systemctl", "stop", "lm_sensors.service");
6654        } elsif (-x "/sbin/service" && -f "/etc/init.d/lm_sensors" &&
6655                 -f "/var/lock/subsys/lm_sensors") {
6656                system("/sbin/service", "lm_sensors", "stop");
6657        }
6658
6659        initialize_kernel_version();
6660        initialize_conf();
6661        initialize_pci();
6662        initialize_modules_list();
6663        # Make sure any special case chips are added to the chip_ids list
6664        # before making the support modules list
6665        chip_special_cases();
6666        initialize_modules_supported();
6667        initialize_cpu_list();
6668
6669        print "# sensors-detect revision $revision\n";
6670        initialize_dmi_data();
6671        print_dmi_summary();
6672        print "\n";
6673        print "This program will help you determine which kernel modules you need\n",
6674              "to load to use lm_sensors most effectively. It is generally safe\n",
6675              "and recommended to accept the default answers to all questions,\n",
6676              "unless you know what you're doing.\n\n";
6677
6678        print "Some south bridges, CPUs or memory controllers contain embedded sensors.\n".
6679              "Do you want to scan for them? This is totally safe. (YES/no): ";
6680        unless (<STDIN> =~ /^\s*n/i) {
6681                # Load the cpuid driver if needed
6682                unless (-e "$sysfs_root/class/cpuid") {
6683                        load_module("cpuid");
6684                        udev_settle();
6685                }
6686
6687                $| = 1;
6688                foreach my $entry (@cpu_ids) {
6689                        scan_cpu($entry);
6690                }
6691                $| = 0;
6692        }
6693        print "\n";
6694
6695        $superio_features = 0;
6696        # Skip "random" I/O port probing on PPC
6697        if ($kernel_arch ne 'ppc'
6698         && $kernel_arch ne 'ppc64') {
6699                print "Some Super I/O chips contain embedded sensors. We have to write to\n".
6700                      "standard I/O ports to probe them. This is usually safe.\n";
6701                print "Do you want to scan for Super I/O sensors? (YES/no): ";
6702                unless (<STDIN> =~ /^\s*n/i) {
6703                        initialize_ioports();
6704                        $superio_features |= scan_superio(0x2e, 0x2f);
6705                        $superio_features |= scan_superio(0x4e, 0x4f);
6706                        close_ioports();
6707                }
6708                print "\n";
6709
6710                unless (is_laptop()) {
6711                        print "Some systems (mainly servers) implement IPMI, a set of common interfaces\n".
6712                              "through which system health data may be retrieved, amongst other things.\n".
6713                              "We first try to get the information from SMBIOS. If we don't find it\n".
6714                              "there, we have to read from arbitrary I/O ports to probe for such\n".
6715                              "interfaces. This is normally safe. Do you want to scan for IPMI\n".
6716                              "interfaces? (YES/no): ";
6717                        unless (<STDIN> =~ /^\s*n/i) {
6718                                if (!ipmi_from_smbios()) {
6719                                        initialize_ioports();
6720                                        scan_isa_bus(\@ipmi_ifs);
6721                                        close_ioports();
6722                                }
6723                        }
6724                        print "\n";
6725                }
6726
6727                printf "Some hardware monitoring chips are accessible through the ISA I/O ports.\n".
6728                       "We have to write to arbitrary I/O ports to probe them. This is usually\n".
6729                       "safe though. Yes, you do have ISA I/O ports even if you do not have any\n".
6730                       "ISA slots! Do you want to scan the ISA I/O ports? (\%s): ",
6731                       $superio_features ? "yes/NO" : "YES/no";
6732                $input = <STDIN>;
6733                unless ($input =~ /^\s*n/i
6734                     || ($superio_features && $input !~ /^\s*y/i)) {
6735                        initialize_ioports();
6736                        scan_isa_bus(\@chip_ids);
6737                        close_ioports();
6738                }
6739                print "\n";
6740        }
6741
6742        print "Lastly, we can probe the I2C/SMBus adapters for connected hardware\n".
6743              "monitoring devices. This is the most risky part, and while it works\n".
6744              "reasonably well on most systems, it has been reported to cause trouble\n".
6745              "on some systems.\n".
6746              "Do you want to probe the I2C/SMBus adapters now? (YES/no): ";
6747
6748        unless (<STDIN> =~ /^\s*n/i) {
6749                adapter_pci_detection();
6750                load_module("i2c-dev") unless -e "$sysfs_root/class/i2c-dev";
6751                initialize_i2c_adapters_list();
6752                $i2c_addresses_to_scan = i2c_addresses_to_scan();
6753                print "\n";
6754
6755                # Skip SMBus probing by default if Super-I/O has all the features
6756                my $by_default = ~$superio_features & (FEAT_IN | FEAT_FAN | FEAT_TEMP);
6757                # Except on Asus and Tyan boards which often have more than
6758                # one hardware monitoring chip
6759                $by_default = 1 if dmi_match('board_vendor', 'asustek', 'tyan',
6760                                             'supermicro');
6761
6762                udev_settle();
6763                for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
6764                        next unless exists $i2c_adapters[$dev_nr];
6765                        scan_i2c_adapter($dev_nr, $by_default);
6766                }
6767                filter_out_fake_i2c_drivers();
6768        }
6769
6770        if (!keys %chips_detected) {
6771                print "Sorry, no sensors were detected.\n";
6772                if (is_laptop() && -d "$sysfs_root/firmware/acpi") {
6773                        print "This is relatively common on laptops, where thermal management is\n".
6774                              "handled by ACPI rather than the OS.\n";
6775                } else {
6776                        print "Either your system has no sensors, or they are not supported, or\n".
6777                              "they are connected to an I2C or SMBus adapter that is not\n".
6778                              "supported. If you find out what chips are on your board, check\n".
6779                              "http://www.lm-sensors.org/wiki/Devices for driver status.\n";
6780                }
6781                exit;
6782        }
6783
6784        print "Now follows a summary of the probes I have just done.\n".
6785              "Just press ENTER to continue: ";
6786        <STDIN>;
6787
6788        initialize_hwmon_autoloaded();
6789        foreach my $driver (keys %chips_detected) {
6790                next unless @{$chips_detected{$driver}};
6791                find_aliases($chips_detected{$driver});
6792                print "\nDriver `$driver'";
6793                print " (autoloaded)" if hwmon_is_autoloaded($driver);
6794                print ":\n";
6795                print_chips_report($chips_detected{$driver});
6796        }
6797        print "\n";
6798
6799        my ($configfile, $bus_modules, $hwmon_modules) = generate_modprobes();
6800
6801        if (@{$hwmon_modules}) {
6802                write_config($configfile, $bus_modules, $hwmon_modules);
6803        } else {
6804                print "No modules to load, skipping modules configuration.\n\n";
6805        }
6806
6807        unload_modules();
6808}
6809
6810sub cleanup_on_int
6811{
6812        print "\n";
6813        unload_modules();
6814        exit;
6815}
6816
6817$SIG{INT} = \&cleanup_on_int;
6818
6819main;
Note: See TracBrowser for help on using the browser.