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

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

Move IPMI interface detection to its own section. IPMI is really different
from legacy ISA monitoring chips.

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