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

Revision 5588, 150.4 KB (checked in by khali, 4 years ago)

Improve the format of /etc/sysconfig/lm_sensors as generated by
sensors-detect. The new format is more flexible and less error-prone.
The old format is still included for compatibility.

  • 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 W83667HG Super IO Sensors",
1561                driver => "to-be-written",
1562                devid => 0xA510,
1563                devid_mask => 0xFFF0,
1564                logdev => 0x0b,
1565                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1566        }, {
1567                name => "Winbond W83L517D Super IO",
1568                driver => "not-a-sensor",
1569                devid => 0x61,
1570        }, {
1571                name => "Fintek F71805F/FG Super IO Sensors",
1572                driver => "f71805f",
1573                devid => 0x0406,
1574                logdev => 0x04,
1575                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1576        }, {
1577                name => "Fintek F71862FG Super IO Sensors",
1578                driver => "to-be-written",
1579                devid => 0x0601,
1580                logdev => 0x04,
1581                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1582        }, {
1583                name => "Fintek F71806FG/F71872FG Super IO Sensors",
1584                driver => "f71805f",
1585                devid => 0x0341,
1586                logdev => 0x04,
1587                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1588        }, {
1589                name => "Fintek F71858DG Super IO Sensors",
1590                driver => "to-be-written",
1591                devid => 0x0507,
1592                logdev => 0x02,
1593                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1594        }, {
1595                name => "Fintek F71882FG/F71883FG Super IO Sensors",
1596                driver => "f71882fg",
1597                devid => 0x0541,
1598                logdev => 0x04,
1599                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1600        }, {
1601                name => "Fintek F81216D Super IO",
1602                driver => "not-a-sensor",
1603                devid => 0x0208,
1604        }, {
1605                name => "Fintek F81218D Super IO",
1606                driver => "not-a-sensor",
1607                devid => 0x0206,
1608        }, {
1609                name => "Asus F8000 Super IO",
1610                driver => "f71882fg",
1611                devid => 0x0581,
1612                logdev => 0x04,
1613                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1614        }, {
1615                # Shouldn't be in this family, but seems to be still.
1616                name => "ITE IT8708F Super IO",
1617                driver => "not-a-sensor",
1618                devid => 0x8708,
1619        }, {
1620                # Shouldn't be in this family, but seems to be still.
1621                name => "ITE IT8710F Super IO",
1622                driver => "not-a-sensor",
1623                devid => 0x8710,
1624        }
1625);
1626
1627@superio_ids_ite = (
1628        {
1629                name => "ITE IT8702F Super IO Fan Sensors",
1630                driver => "to-be-written",
1631                devid => 0x8702,
1632                logdev => 0x04,
1633                features => FEAT_FAN,
1634        }, {
1635                name => "ITE IT8705F Super IO Sensors",
1636                driver => "it87",
1637                devid => 0x8705,
1638                logdev => 0x04,
1639                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1640        }, {
1641                name => "ITE IT8712F Super IO Sensors",
1642                driver => "it87",
1643                devid => 0x8712,
1644                logdev => 0x04,
1645                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1646        }, {
1647                name => "ITE IT8716F Super IO Sensors",
1648                driver => "it87",
1649                devid => 0x8716,
1650                logdev => 0x04,
1651                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1652        }, {
1653                name => "ITE IT8718F Super IO Sensors",
1654                driver => "it87",
1655                devid => 0x8718,
1656                logdev => 0x04,
1657                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1658        }, {
1659                name => "ITE IT8720F Super IO Sensors",
1660                driver => "it87",
1661                devid => 0x8720,
1662                logdev => 0x04,
1663                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1664        }, {
1665                name => "ITE IT8726F Super IO Sensors",
1666                driver => "it87",
1667                devid => 0x8726,
1668                logdev => 0x04,
1669                features => FEAT_IN | FEAT_FAN | FEAT_TEMP,
1670        }
1671);
1672
1673# Entries are grouped by family. Each family entry has the following fields:
1674#  family: The family name
1675#  guess (optional): Typical logical device address. This lets us do
1676#       generic probing if we fail to recognize the chip.
1677#  enter: The password sequence to write to the address register
1678#  chips: Array of chips
1679# The order of families matters, because we stop as soon as one family
1680# succeeds. So we have to list families with shorter password sequences
1681# first.
1682@superio_ids = (
1683        {
1684                family => "National Semiconductor",
1685                enter =>
1686                {
1687                        0x2e => [],
1688                        0x4e => [],
1689                },
1690                chips => \@superio_ids_natsemi,
1691        }, {
1692                family => "SMSC",
1693                enter =>
1694                {
1695                        0x2e => [0x55],
1696                        0x4e => [0x55],
1697                },
1698                chips => \@superio_ids_smsc,
1699                ns_detect => \&smsc_ns_detect_superio,
1700                ns_chips => \@superio_ids_smsc_ns,
1701        }, {
1702                family => "VIA/Winbond/Fintek",
1703                guess => 0x290,
1704                enter =>
1705                {
1706                        0x2e => [0x87, 0x87],
1707                        0x4e => [0x87, 0x87],
1708                },
1709                chips => \@superio_ids_winbond,
1710        }, {
1711                family => "ITE",
1712                guess => 0x290,
1713                enter =>
1714                {
1715                        0x2e => [0x87, 0x01, 0x55, 0x55],
1716                        0x4e => [0x87, 0x01, 0x55, 0xaa],
1717                },
1718                chips => \@superio_ids_ite,
1719        }
1720);
1721
1722# Drivers for bridge, CPU and memory embedded sensors
1723# Each entry must have the following fields:
1724#  name: The device name
1725#  driver: The driver name. Put "to-be-written" if no driver is available.
1726#  detect: Detection callback function. No parameter will be passed to
1727#       this function, it must use global lists of PCI devices, CPU,
1728#       etc. It must return a confidence value, undef if no supported
1729#       CPU is found.
1730use vars qw(@cpu_ids);
1731
1732@cpu_ids = (
1733        {
1734                name => "Silicon Integrated Systems SIS5595",
1735                driver => "sis5595",
1736                detect => \&sis5595_pci_detect,
1737        }, {
1738                name => "VIA VT82C686 Integrated Sensors",
1739                driver => "via686a",
1740                detect => \&via686a_pci_detect,
1741        }, {
1742                name => "VIA VT8231 Integrated Sensors",
1743                driver => "vt8231",
1744                detect => \&via8231_pci_detect,
1745        }, {
1746                name => "AMD K8 thermal sensors",
1747                driver => "k8temp",
1748                detect => \&k8temp_pci_detect,
1749        }, {
1750                name => "AMD K10 thermal sensors",
1751                driver => "to-be-written",
1752                detect => \&k10temp_pci_detect,
1753        }, {
1754                name => "Intel Core family thermal sensor",
1755                driver => "coretemp",
1756                detect => \&coretemp_detect,
1757        }, {
1758                name => "Intel AMB FB-DIMM thermal sensor",
1759                driver => "i5k_amb",
1760                detect => \&intel_amb_detect,
1761        }, {
1762                name => "VIA C7 thermal and voltage sensors",
1763                driver => "c7temp",
1764                detect => \&c7temp_detect,
1765        }
1766);
1767
1768#######################
1769# AUXILIARY FUNCTIONS #
1770#######################
1771
1772# $_[0] is the sought value
1773# $_[1..] is the list to seek in
1774# Returns: 1 if found, 0 if not.
1775sub contains
1776{
1777        my $sought = shift;
1778        local $_;
1779
1780        foreach (@_) {
1781                return 1 if $sought eq $_;
1782        }
1783        return 0;
1784}
1785
1786# Address can be decimal or hexadecimal
1787sub valid_address
1788{
1789        my $value = shift;
1790
1791        if ($value !~ m/^(0x[0-9a-f]+|[0-9]+)$/i) {
1792                print "$value is not a valid address, sorry.\n";
1793                exit -1;
1794        }
1795        $value = oct($value) if $value =~ m/^0x/i;
1796
1797        return $value;
1798}
1799
1800sub parse_not_to_scan
1801{
1802        my ($min, $max, $to_parse) = @_;
1803        my @ranges = split /\s*, \s*/, $to_parse;
1804        my @res;
1805        my $range;
1806
1807        foreach $range (@ranges) {
1808                my ($start, $end) = split /\s*-\s*/, $range;
1809                $start = valid_address($start);
1810                if (defined $end) {
1811                        $end = valid_address($end);
1812                        if ($end <= $start) {
1813                                print "$start-$end is not a valid range, sorry.\n";
1814                                exit -1;
1815                        }
1816                        $start = $min if $start < $min;
1817                        $end = $max if $end > $max;
1818                        push @res, ($start..$end);
1819                } else {
1820                        push @res, $start if $start >= $min and $start <= $max;
1821                }
1822        }
1823
1824        return sort { $a <=> $b } @res;
1825}
1826
1827# $_[0]: Reference to list 1
1828# $_[1]: Reference to list 2
1829# Result: 0 if they have no elements in common, 1 if they have
1830# Elements must be numeric.
1831sub any_list_match
1832{
1833        my ($list1, $list2) = @_;
1834        my ($el1, $el2);
1835
1836        foreach $el1 (@$list1) {
1837                foreach $el2 (@$list2) {
1838                        return 1 if $el1 == $el2;
1839                }
1840        }
1841        return 0;
1842}
1843
1844###################
1845# I/O PORT ACCESS #
1846###################
1847
1848sub initialize_ioports
1849{
1850        sysopen(IOPORTS, "/dev/port", O_RDWR)
1851                or die "/dev/port: $!\n";
1852        binmode(IOPORTS);
1853}
1854
1855sub close_ioports
1856{
1857        close(IOPORTS);
1858}
1859
1860# $_[0]: port to read
1861# Returns: -1 on failure, read value on success.
1862sub inb
1863{
1864        my ($res, $nrchars);
1865        sysseek(IOPORTS, $_[0], 0) or return -1;
1866        $nrchars = sysread(IOPORTS, $res, 1);
1867        return -1 if not defined $nrchars or $nrchars != 1;
1868        $res = unpack("C", $res);
1869        return $res;
1870}
1871
1872# $_[0]: port to write
1873# $_[1]: value to write
1874# We assume this can't fail.
1875sub outb
1876{
1877        sysseek(IOPORTS, $_[0], 0);
1878        syswrite(IOPORTS, pack("C", $_[1]), 1);
1879}
1880
1881# $_[0]: Address register
1882# $_[1]: Data register
1883# $_[2]: Register to read
1884# Returns: read value
1885sub isa_read_byte
1886{
1887        outb($_[0], $_[2]);
1888        return inb($_[1]);
1889}
1890
1891# $_[0]: Base address
1892# $_[1]: Register to read
1893# Returns: read value
1894# This one can be used for any ISA chip with index register at
1895# offset 5 and data register at offset 6.
1896sub isa_read_i5d6
1897{
1898        my ($addr, $reg) = @_;
1899        return isa_read_byte($addr + 5, $addr + 6, $reg);
1900}
1901
1902#################
1903# AUTODETECTION #
1904#################
1905
1906use vars qw($dev_i2c $sysfs_root);
1907
1908sub initialize_conf
1909{
1910        my $use_devfs = 0;
1911        open(local *INPUTFILE, "/proc/mounts") or die "Can't access /proc/mounts!";
1912        local $_;
1913        while (<INPUTFILE>) {
1914                if (m@^\w+ /dev devfs @) {
1915                        $use_devfs = 1;
1916                        $dev_i2c = '/dev/i2c/';
1917                }
1918                if (m@^\S+ (/\w+) sysfs @) {
1919                        $sysfs_root = $1;
1920                }
1921        }
1922        close(INPUTFILE);
1923
1924        # We need sysfs for many things
1925        if (!defined $sysfs_root) {
1926                print "Sysfs not mounted?\n";
1927                exit -1;
1928        }
1929
1930        my $use_udev = 0;
1931        if (open(*INPUTFILE, '/etc/udev/udev.conf')) {
1932                while (<INPUTFILE>) {
1933                        next unless m/^\s*udev_db\s*=\s*\"([^"]*)\"/
1934                                 || m/^\s*udev_db\s*=\s*(\S+)/;
1935                        if (-e $1) {
1936                                $use_udev = 1;
1937                                $dev_i2c = '/dev/i2c-';
1938                        }
1939                        last;
1940                }
1941                close(INPUTFILE);
1942          }
1943
1944        if (!$use_udev) {
1945                # Try some known default udev db locations, just in case
1946                if (-e '/dev/.udev.tdb' || -e '/dev/.udev'
1947                 || -e '/dev/.udevdb') {
1948                        $use_udev = 1;
1949                        $dev_i2c = '/dev/i2c-';
1950                }
1951        }
1952
1953        if (!($use_devfs || $use_udev)) {
1954                if (! -c '/dev/i2c-0' && -x '/sbin/MAKEDEV') {
1955                        system("/sbin/MAKEDEV i2c");
1956                }
1957                if (! -c '/dev/i2c-0' && -x '/dev/MAKEDEV') {
1958                        system("/dev/MAKEDEV i2c");
1959                }
1960                if (-c '/dev/i2c-0') {
1961                        $dev_i2c = '/dev/i2c-';
1962                } else { # default
1963                        print "No i2c device files found.\n";
1964                        exit -1;
1965                }
1966        }
1967}
1968
1969# [0] -> VERSION
1970# [1] -> PATCHLEVEL
1971# [2] -> SUBLEVEL
1972# [3] -> EXTRAVERSION
1973#
1974use vars qw(@kernel_version $kernel_arch);
1975
1976sub initialize_kernel_version
1977{
1978        `uname -r` =~ /(\d+)\.(\d+)\.(\d+)(.*)/;
1979        @kernel_version = ($1, $2, $3, $4);
1980        chomp($kernel_arch = `uname -m`);
1981
1982        # We only support kernels >= 2.6.5
1983        if (!kernel_version_at_least(2, 6, 5)) {
1984                print "Kernel version is unsupported (too old, >= 2.6.5 needed)\n";
1985                exit -1;
1986        }
1987}
1988
1989sub kernel_version_at_least
1990{
1991        my ($vers, $plvl, $slvl) = @_;
1992        return 1 if ($kernel_version[0] > $vers ||
1993                     ($kernel_version[0] == $vers &&
1994                      ($kernel_version[1] > $plvl ||
1995                       ($kernel_version[1] == $plvl &&
1996                        ($kernel_version[2] >= $slvl)))));
1997        return 0;
1998}
1999
2000# @cpu is a list of reference to hashes, one hash per CPU.
2001# Each entry has the following keys: vendor_id, cpu family, model,
2002# model name and stepping, directly taken from /proc/cpuinfo.
2003use vars qw(@cpu);
2004
2005sub initialize_cpu_list
2006{
2007        local $_;
2008        my $entry;
2009
2010        open(local *INPUTFILE, "/proc/cpuinfo") or die "Can't access /proc/cpuinfo!";
2011        while (<INPUTFILE>) {
2012                if (m/^processor\s*:\s*(\d+)/) {
2013                        push @cpu, $entry if scalar keys(%{$entry}); # Previous entry
2014                        $entry = {}; # New entry
2015                        next;
2016                }
2017                if (m/^(vendor_id|cpu family|model|model name|stepping)\s*:\s*(.+)$/) {
2018                        my $k = $1;
2019                        my $v = $2;
2020                        $v =~ s/\s+/ /g;        # Merge multiple spaces
2021                        $v =~ s/ $//;           # Trim trailing space
2022                        $entry->{$k} = $v;
2023                        next;
2024                }
2025        }
2026        close(INPUTFILE);
2027        push @cpu, $entry if scalar keys(%{$entry}); # Last entry
2028}
2029
2030# @i2c_adapters is a list of references to hashes, one hash per I2C/SMBus
2031# adapter present on the system. Each entry has the following keys: name
2032# (directly taken from /sys/class/i2c-adapter) and driver.
2033use vars qw(@i2c_adapters);
2034
2035sub initialize_i2c_adapters_list
2036{
2037        my $entry;
2038        local $_;
2039
2040        my $class_dir = "${sysfs_root}/class/i2c-adapter";
2041        opendir(local *ADAPTERS, $class_dir) or return;
2042
2043        while (defined($_ = readdir(ADAPTERS))) {
2044                next unless m/^i2c-(\d+)$/;
2045                $entry = {}; # New entry
2046                $entry->{name} = sysfs_device_attribute("${class_dir}/i2c-$1",
2047                                                        "name")
2048                              || sysfs_device_attribute("${class_dir}/i2c-$1/device",
2049                                                        "name");
2050                next if $entry->{name} eq "ISA main adapter";
2051
2052                # First try to get the I2C adapter driver name from sysfs,
2053                # and if it fails, fall back to searching our list of known
2054                # I2C adapters.
2055                $entry->{driver} = sysfs_device_driver("${class_dir}/i2c-$1/device")
2056                                || find_i2c_adapter_driver($entry->{name})
2057                                || 'UNKNOWN';
2058                $i2c_adapters[$1] = $entry;
2059        }
2060        closedir(ADAPTERS);
2061}
2062
2063###########
2064# MODULES #
2065###########
2066
2067use vars qw(%modules_list %modules_supported @modules_we_loaded);
2068
2069sub initialize_modules_list
2070{
2071        local $_;
2072
2073        open(local *INPUTFILE, "/proc/modules") or return;
2074        while (<INPUTFILE>) {
2075                tr/-/_/; # Probably not needed
2076                $modules_list{$1} = 1 if m/^(\S*)/;
2077        }
2078}
2079
2080sub is_module_loaded
2081{
2082        my $module = shift;
2083        $module =~ tr/-/_/;
2084        return exists $modules_list{$module}
2085}
2086
2087sub load_module
2088{
2089        my $module = shift;
2090
2091        return if is_module_loaded($module);
2092
2093        system("modprobe", $module);
2094        if (($? >> 8) != 0) {
2095                print "Failed to load module $module.\n";
2096                return -1;
2097        }
2098
2099        print "Module $module loaded successfully.\n";
2100        push @modules_we_loaded, $module;
2101
2102        # Update the list of loaded modules
2103        my $normalized = $module;
2104        $normalized =~ tr/-/_/;
2105        $modules_list{$normalized} = 1;
2106}
2107
2108sub loaded_by_us
2109{
2110        my $sought = shift;
2111        local $_;
2112
2113        $sought =~ tr/-/_/;
2114        foreach (@modules_we_loaded) {
2115                my $module = $_;
2116                $module =~ tr/-/_/;
2117                return 1 if $module eq $sought;
2118        }
2119        return 0;
2120}
2121
2122sub initialize_modules_supported
2123{
2124        foreach my $chip (@chip_ids) {
2125                next if $chip->{driver} eq "to-be-written";
2126                next if $chip->{driver} eq "use-isa-instead";
2127
2128                my $normalized = $chip->{driver};
2129                $normalized =~ tr/-/_/;
2130                $modules_supported{$normalized}++;
2131        }
2132}
2133
2134sub unload_modules
2135{
2136        return unless @modules_we_loaded;
2137
2138        # Attempt to unload all kernel drivers we loaded ourselves
2139        while (my $module = pop @modules_we_loaded) {
2140                print "Unloading $module... ";
2141                system("modprobe -r $module 2> /dev/null");
2142                if (($? >> 8) == 0) {
2143                        print "OK\n";
2144                } else {
2145                        print "failed\n";
2146                }
2147        }
2148        print "\n";
2149}
2150
2151############
2152# DMI DATA #
2153############
2154
2155use vars qw(%dmi);
2156
2157sub initialize_dmi_data
2158{
2159        my %items = (
2160                # sysfs file name => dmidecode string name
2161                sys_vendor => 'system-manufacturer',
2162                product_name => 'system-product-name',
2163                product_version => 'system-version',
2164                board_vendor => 'baseboard-manufacturer',
2165                board_name => 'baseboard-product-name',
2166                board_version => 'baseboard-product-name',
2167                chassis_type => 'chassis-type',
2168        );
2169        # Many BIOS have broken DMI data, filter it out
2170        my %fake = (
2171                'System Manufacturer' => 1,
2172                'System Name' => 1,
2173        );
2174        my $dmi_id_dir;
2175
2176        # First try reading the strings from sysfs if available
2177        if (-d ($dmi_id_dir = "$sysfs_root/devices/virtual/dmi/id")     # kernel >= 2.6.28
2178         || -d ($dmi_id_dir = "$sysfs_root/class/dmi/id")) {
2179                foreach my $k (keys %items) {
2180                        $dmi{$k} = sysfs_device_attribute($dmi_id_dir, $k);
2181                }
2182        } else {
2183                # Else fallback on calling dmidecode
2184                my $version;
2185                if (open(local *DMIDECODE, "dmidecode --version 2>/dev/null |")) {
2186                        $version = <DMIDECODE>;
2187                        close(DMIDECODE);
2188                        chomp $version if defined $version;
2189                }
2190
2191                if (!defined $version
2192                 || !($version =~ m/^(\d+).(\d+)$/)
2193                 || !(($1 == 2 && $2 >= 7) || $1 > 2)) {
2194                        print "# DMI data unavailable, please consider installing dmidecode 2.7\n".
2195                              "# or later for better results.\n";
2196                        return;
2197                }
2198
2199                foreach my $k (keys %items) {
2200                        next unless open(local *DMIDECODE,
2201                                         "dmidecode -s $items{$k} 2>/dev/null |");
2202                        $dmi{$k} = <DMIDECODE>;
2203                        close(DMIDECODE);
2204                }
2205        }
2206
2207        # Strip trailing white-space, discard empty field
2208        foreach my $k (keys %dmi) {
2209                if (!defined $dmi{$k}) {
2210                        delete $dmi{$k};
2211                        next;
2212                }
2213                $dmi{$k} =~ s/\s*$//;
2214                delete $dmi{$k} if $dmi{$k} eq '' || exists $fake{$dmi{$k}};
2215        }
2216}
2217
2218sub print_dmi_summary
2219{
2220        my ($system, $board);
2221        if (defined $dmi{sys_vendor} && defined $dmi{product_name}) {
2222                $system = "$dmi{sys_vendor} $dmi{product_name}";
2223        }
2224        if (defined $dmi{board_vendor} && defined $dmi{board_name}) {
2225                $board = "$dmi{board_vendor} $dmi{board_name}";
2226        }
2227       
2228        if (defined $system) {
2229                print "# System: $system";
2230                print " (laptop)" if (is_laptop());
2231                print "\n";
2232        }
2233        print "# Board: $board\n" if defined $board
2234                                  && (!defined $system || $system ne $board);
2235}
2236
2237sub dmi_match
2238{
2239        my $key = shift;
2240        my $value;
2241
2242        return unless defined $dmi{$key};
2243        while (defined ($value = shift)) {
2244                return 1 if $dmi{$key} =~ m/\b$value\b/i;
2245        }
2246        return 0;
2247}
2248
2249sub is_laptop
2250{
2251        return 0 unless $dmi{chassis_type};
2252        return 1 if $dmi{chassis_type} =~ m/(Laptop|Notebook|Hand Held)/i;
2253        return 1 if $dmi{chassis_type} =~ m/^(9|10|11|14)$/;
2254        return 0;
2255}
2256
2257#################
2258# SYSFS HELPERS #
2259#################
2260
2261# From a sysfs device path, return the driver (module) name, or undef
2262sub sysfs_device_driver
2263{
2264        my $device = shift;
2265
2266        my $link = readlink("$device/driver/module");
2267        return unless defined $link;
2268        return basename($link);
2269}
2270
2271# From a sysfs device path, return the subsystem name, or undef
2272sub sysfs_device_subsystem
2273{
2274        my $device = shift;
2275
2276        my $link = readlink("$device/subsystem");
2277        return unless defined $link;
2278        return basename($link);
2279}
2280
2281# From a sysfs device path and an attribute name, return the attribute
2282# value, or undef
2283sub sysfs_device_attribute
2284{
2285        my ($device, $attr) = @_;
2286        my $value;
2287
2288        open(local *FILE, "$device/$attr") or return;
2289        $value = <FILE>;
2290        close(FILE);
2291        return unless defined $value;
2292
2293        chomp($value);
2294        return $value;
2295}
2296
2297##############
2298# PCI ACCESS #
2299##############
2300
2301use vars qw(%pci_list);
2302
2303# This function returns a list of hashes. Each hash has some PCI information:
2304# 'domain', 'bus', 'slot' and 'func' uniquely identify a PCI device in a
2305# computer; 'vendid' and 'devid' uniquely identify a type of device.
2306# 'class' lets us spot unknown SMBus adapters.
2307sub read_sys_dev_pci
2308{
2309        my $devices = shift;
2310        my ($dev, @pci_list);
2311
2312        opendir(local *DEVICES, "$devices")
2313                or die "$devices: $!";
2314
2315        while (defined($dev = readdir(DEVICES))) {
2316                my %record;
2317                next unless $dev =~
2318                        m/^(?:([\da-f]+):)?([\da-f]+):([\da-f]+)\.([\da-f]+)$/;
2319
2320                $record{domain} = hex $1;
2321                $record{bus} = hex $2;
2322                $record{slot} = hex $3;
2323                $record{func} = hex $4;
2324
2325                $record{vendid} = oct sysfs_device_attribute("$devices/$dev",
2326                                                             "vendor");
2327                $record{devid} = oct sysfs_device_attribute("$devices/$dev",
2328                                                            "device");
2329                $record{class} = (oct sysfs_device_attribute("$devices/$dev",
2330                                                             "class")) >> 8;
2331
2332                push @pci_list, \%record;
2333        }
2334
2335        return \@pci_list;
2336}
2337
2338sub initialize_pci
2339{
2340        my $pci_list;
2341        local $_;
2342
2343        $pci_list = read_sys_dev_pci("$sysfs_root/bus/pci/devices");
2344
2345        # Note that we lose duplicate devices at this point, but we don't
2346        # really care. What matters to us is which unique devices are present,
2347        # not how many of each.
2348        %pci_list = map {
2349                sprintf("%04x:%04x", $_->{vendid}, $_->{devid}) => $_
2350        } @{$pci_list};
2351}
2352
2353#####################
2354# ADAPTER DETECTION #
2355#####################
2356
2357# Build and return a PCI device's bus ID
2358sub pci_busid
2359{
2360        my $device = shift;
2361        my $busid;
2362
2363        $busid = sprintf("\%02x:\%02x.\%x",
2364                         $device->{bus}, $device->{slot}, $device->{func});
2365        $busid = sprintf("\%04x:", $device->{domain}) . $busid
2366                if defined $device->{domain};
2367
2368        return $busid;
2369}
2370
2371sub adapter_pci_detection
2372{
2373        my ($key, $device, $try, %smbus, $count);
2374
2375        # Build a list of detected SMBus devices
2376        foreach $key (keys %pci_list) {
2377                $device = $pci_list{$key};
2378                $smbus{$key}++
2379                        if exists $device->{class} &&
2380                           $device->{class} == 0x0c05; # SMBus
2381        }
2382
2383        # Loop over the known I2C/SMBus adapters
2384        foreach $try (@pci_adapters) {
2385                $key = sprintf("%04x:%04x", $try->{vendid}, $try->{devid});
2386                next unless exists $pci_list{$key};
2387
2388                $device = $pci_list{$key};
2389                if ($try->{driver} eq "to-be-tested") {
2390                        print "\nWe are currently looking for testers for this adapter!\n".
2391                              "Please check http://www.lm-sensors.org/wiki/Devices\n".
2392                              "and/or contact us if you want to help.\n\n".
2393                              "Continue... ";
2394                        <STDIN>;
2395                        print "\n";
2396                }
2397
2398                if ($try->{driver} =~ m/^to-be-/) {
2399                        printf "No known driver for device \%s: \%s\n",
2400                               pci_busid($device), $try->{procid};
2401                } else {
2402                        printf "Using driver `\%s' for device \%s: \%s\n",
2403                               $try->{driver}, pci_busid($device),
2404                               $try->{procid};
2405                        $count++;
2406                        load_module($try->{driver});
2407                }
2408
2409                # Delete from detected SMBus device list
2410                delete $smbus{$key};
2411        }
2412
2413        # Now see if there are unknown SMBus devices left
2414        foreach $key (keys %smbus) {
2415                $device = $pci_list{$key};
2416                printf "Found unknown SMBus adapter \%04x:\%04x at \%s.\n",
2417                       $device->{vendid}, $device->{devid}, pci_busid($device);
2418        }
2419
2420        print "Sorry, no supported PCI bus adapters found.\n"
2421                unless $count;
2422}
2423
2424# $_[0]: Adapter description as found in /sys/class/i2c-adapter
2425sub find_i2c_adapter_driver
2426{
2427        my $name = shift;
2428        my $entry;
2429
2430        foreach $entry (@i2c_adapter_names) {
2431                return $entry->{driver}
2432                        if $name =~ $entry->{match};
2433        }
2434}
2435
2436#############################
2437# I2C AND SMBUS /DEV ACCESS #
2438#############################
2439
2440# This should really go into a separate module/package.
2441
2442# These are copied from <linux/i2c-dev.h>
2443
2444use constant IOCTL_I2C_SLAVE    => 0x0703;
2445use constant IOCTL_I2C_FUNCS    => 0x0705;
2446use constant IOCTL_I2C_SMBUS    => 0x0720;
2447
2448use constant SMBUS_READ         => 1;
2449use constant SMBUS_WRITE        => 0;
2450
2451use constant SMBUS_QUICK        => 0;
2452use constant SMBUS_BYTE         => 1;
2453use constant SMBUS_BYTE_DATA    => 2;
2454use constant SMBUS_WORD_DATA    => 3;
2455
2456use constant I2C_FUNC_SMBUS_QUICK       => 0x00010000;
2457use constant I2C_FUNC_SMBUS_READ_BYTE   => 0x00020000;
2458
2459# Get the i2c adapter's functionalities
2460# $_[0]: Reference to an opened filehandle
2461# Returns: -1 on failure, functionality bitfield on success.
2462sub i2c_get_funcs
2463{
2464        my $file = shift;
2465        my $funcs = pack("L", 0); # Allocate space
2466
2467        ioctl($file, IOCTL_I2C_FUNCS, $funcs) or return -1;
2468        $funcs = unpack("L", $funcs);
2469
2470        return $funcs;
2471}
2472
2473# Select the device to communicate with through its address.
2474# $_[0]: Reference to an opened filehandle
2475# $_[1]: Address to select
2476# Returns: 0 on failure, 1 on success.
2477sub i2c_set_slave_addr
2478{
2479        my ($file, $addr) = @_;
2480
2481        # Reset register data cache
2482        @i2c_byte_cache = ();
2483
2484        $addr += 0; # Make sure it's a number not a string
2485        ioctl($file, IOCTL_I2C_SLAVE, $addr) or return 0;
2486        return 1;
2487}
2488
2489# i2c_smbus_access is based upon the corresponding C function (see
2490# <linux/i2c-dev.h>). You should not need to call this directly.
2491# $_[0]: Reference to an opened filehandle
2492# $_[1]: SMBUS_READ for reading, SMBUS_WRITE for writing
2493# $_[2]: Command (usually register number)
2494# $_[3]: Transaction kind (SMBUS_BYTE, SMBUS_BYTE_DATA, etc.)
2495# $_[4]: Reference to an array used for input/output of data
2496# Returns: 0 on failure, 1 on success.
2497# Note that we need to get back to Integer boundaries through the 'x2'
2498# in the pack. This is very compiler-dependent; I wish there was some other
2499# way to do this.
2500sub i2c_smbus_access
2501{
2502        my ($file, $read_write, $command, $size, $data) = @_;
2503        my $data_array = pack("C32", @$data);
2504        my $ioctl_data = pack("C2x2Ip", $read_write, $command, $size,
2505                              $data_array);
2506
2507        ioctl($file, IOCTL_I2C_SMBUS, $ioctl_data) or return 0;
2508        @{$_[4]} = unpack("C32", $data_array);
2509        return 1;
2510}
2511
2512# $_[0]: Reference to an opened filehandle
2513# Returns: -1 on failure, the read byte on success.
2514sub i2c_smbus_read_byte
2515{
2516        my ($file) = @_;
2517        my @data;
2518
2519        i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, \@data)
2520                or return -1;
2521        return $data[0];
2522}
2523
2524# $_[0]: Reference to an opened filehandle
2525# $_[1]: Command byte (usually register number)
2526# Returns: -1 on failure, the read byte on success.
2527# Read byte data values are cached by default. As we keep reading the
2528# same registers over and over again in the detection functions, and
2529# SMBus can be slow, caching results in a big performance boost.
2530sub i2c_smbus_read_byte_data
2531{
2532        my ($file, $command, $nocache) = @_;
2533        my @data;
2534
2535        return $i2c_byte_cache[$command]
2536                if !$nocache && exists $i2c_byte_cache[$command];
2537
2538        i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_BYTE_DATA, \@data)
2539                or return -1;
2540        return ($i2c_byte_cache[$command] = $data[0]);
2541}
2542
2543# $_[0]: Reference to an opened filehandle
2544# $_[1]: Command byte (usually register number)
2545# Returns: -1 on failure, the read word on success.
2546# Use this function with care, some devices don't like word reads,
2547# so you should do as much of the detection as possible using byte reads,
2548# and only start using word reads when there is a good chance that
2549# the detection will succeed.
2550# Note: some devices use the wrong endianness.
2551sub i2c_smbus_read_word_data
2552{
2553        my ($file, $command) = @_;
2554        my @data;
2555        i2c_smbus_access($file, SMBUS_READ, $command, SMBUS_WORD_DATA, \@data)
2556                or return -1;
2557        return $data[0] + 256 * $data[1];
2558}
2559
2560# $_[0]: Reference to an opened filehandle
2561# $_[1]: Address
2562# $_[2]: Functionalities of this i2c adapter
2563# Returns: 1 on successful probing, 0 else.
2564# This function is meant to prevent AT24RF08 corruption and write-only
2565# chips locks. This is done by choosing the best probing method depending
2566# on the address range.
2567sub i2c_probe
2568{
2569        my ($file, $addr, $funcs) = @_;
2570
2571        if (($addr >= 0x50 && $addr <= 0x5F)
2572         || ($addr >= 0x30 && $addr <= 0x37)) {
2573                # This covers all EEPROMs we know of, including page protection
2574                # addresses. Note that some page protection addresses will not
2575                # reveal themselves with this, because they ack on write only,
2576                # but this is probably better since some EEPROMs write-protect
2577                # themselves permanently on almost any write to their page
2578                # protection address.
2579                return 0 unless ($funcs & I2C_FUNC_SMBUS_READ_BYTE);
2580                return i2c_smbus_access($file, SMBUS_READ, 0, SMBUS_BYTE, []);
2581        } else {
2582                return 0 unless ($funcs & I2C_FUNC_SMBUS_QUICK);
2583                return i2c_smbus_access($file, SMBUS_WRITE, 0, SMBUS_QUICK, []);
2584        }
2585}
2586
2587# $_[0]: Reference to an opened file handle
2588# Returns: 1 if the device is safe to access, 0 else.
2589# This function is meant to prevent access to 1-register-only devices,
2590# which are designed to be accessed with SMBus receive byte and SMBus send
2591# byte transactions (i.e. short reads and short writes) and treat SMBus
2592# read byte as a real write followed by a read. The device detection
2593# routines would write random values to the chip with possibly very nasty
2594# results for the hardware. Note that this function won't catch all such
2595# chips, as it assumes that reads and writes relate to the same register,
2596# but that's the best we can do.
2597sub i2c_safety_check
2598{
2599        my ($file) = @_;
2600        my $data;
2601
2602        # First we receive a byte from the chip, and remember it.
2603        $data = i2c_smbus_read_byte($file);
2604        return 1 if ($data < 0);
2605
2606        # We receive a byte again; very likely to be the same for
2607        # 1-register-only devices.
2608        return 1 if (i2c_smbus_read_byte($file) != $data);
2609
2610        # Then we try a standard byte read, with a register offset equal to
2611        # the byte we received; we should receive the same byte value in return.
2612        return 1 if (i2c_smbus_read_byte_data($file, $data) != $data);
2613
2614        # Then we try a standard byte read, with a slightly different register
2615        # offset; we should again receive the same byte value in return.
2616        return 1 if (i2c_smbus_read_byte_data($file, $data ^ 1) != ($data ^ 1));
2617
2618        # Apprently this is a 1-register-only device, restore the original
2619        # register value and leave it alone.
2620        i2c_smbus_read_byte_data($file, $data);
2621        return 0;
2622}
2623
2624####################
2625# ADAPTER SCANNING #
2626####################
2627
2628use vars qw(%chips_detected);
2629
2630# We will build a complicated structure %chips_detected here, being a hash
2631# where keys are driver names and values are detected chip information in
2632# the form of a list of hashes of type 'detect_data'.
2633
2634# Type detect_data:
2635# A hash
2636#  with field 'i2c_devnr', contianing the /dev/i2c-* number of this
2637#       adapter (if this is an I2C detection)
2638#  with field 'i2c_addr', containing the I2C address of the detection;
2639#       (if this is an I2C detection)
2640#  with field 'i2c_sub_addrs', containing a reference to a list of
2641#       other I2C addresses (if this is an I2C detection)
2642#  with field 'isa_addr' containing the ISA address this chip is on
2643#       (if this is an ISA detection)
2644#  with field 'conf', containing the confidence level of this detection
2645#  with field 'chipname', containing the chip name
2646#  with optional field 'alias_detect', containing a reference to an alias
2647#       detection function for this chip
2648
2649# This adds a detection to the above structure.
2650# Not all possibilities of i2c_addr and i2c_sub_addrs are exhausted.
2651# In all normal cases, it should be all right.
2652# $_[0]: chip driver
2653# $_[1]: reference to data hash
2654# Returns: Nothing
2655sub add_i2c_to_chips_detected
2656{
2657        my ($chipdriver, $datahash) = @_;
2658        my ($i, $new_detected_ref, $detected_ref, $detected_entry,
2659            $put_in_detected, @hash_addrs, @entry_addrs);
2660
2661        # First determine where the hash has to be added.
2662        $chips_detected{$chipdriver} = []
2663                unless exists $chips_detected{$chipdriver};
2664        $new_detected_ref = $chips_detected{$chipdriver};
2665
2666        # Find out whether our new entry should go into the detected list
2667        # or not. We compare all i2c addresses; if at least one matches,
2668        # but our confidence value is lower, we assume this is a misdetection,
2669        # in which case we simply discard our new entry.
2670        @hash_addrs = ($datahash->{i2c_addr});
2671        push @hash_addrs, @{$datahash->{i2c_sub_addrs}}
2672                if exists $datahash->{i2c_sub_addrs};
2673        $put_in_detected = 1;
2674 FIND_LOOP:
2675        foreach $detected_ref (values %chips_detected) {
2676                foreach $detected_entry (@{$detected_ref}) {
2677                        next unless defined $detected_entry->{i2c_addr};
2678                        @entry_addrs = ($detected_entry->{i2c_addr});
2679                        push @entry_addrs, @{$detected_entry->{i2c_sub_addrs}}
2680                                if exists $detected_entry->{i2c_sub_addrs};
2681                        if ($detected_entry->{i2c_devnr} == $datahash->{i2c_devnr} &&
2682                            any_list_match(\@entry_addrs, \@hash_addrs)) {
2683                                if ($detected_entry->{conf} >= $datahash->{conf}) {
2684                                        $put_in_detected = 0;
2685                                }
2686                                last FIND_LOOP;
2687                        }
2688                }
2689        }
2690
2691        return unless $put_in_detected;
2692
2693        # Here, we discard all entries which match at least in one main or
2694        # sub address. This may not be the best idea to do, as it may remove
2695        # detections without replacing them with second-best ones. Too bad.
2696        foreach $detected_ref (values %chips_detected) {
2697                for ($i = @$detected_ref-1; $i >=0; $i--) {
2698                        next unless defined $detected_ref->[$i]->{i2c_addr};
2699                        @entry_addrs = ($detected_ref->[$i]->{i2c_addr});
2700                        push @entry_addrs, @{$detected_ref->[$i]->{i2c_sub_addrs}}
2701                                if exists $detected_ref->[$i]->{i2c_sub_addrs};
2702                        if ($detected_ref->[$i]->{i2c_devnr} == $datahash->{i2c_devnr} &&
2703                            any_list_match(\@entry_addrs, \@hash_addrs)) {
2704                                splice @$detected_ref, $i, 1;
2705                        }
2706                }
2707        }
2708
2709        # Now add the new entry to detected
2710        push @$new_detected_ref, $datahash;
2711}
2712
2713# This adds a detection to the above structure.
2714# $_[0]: chip driver
2715# $_[1]: reference to data hash
2716sub add_isa_to_chips_detected
2717{
2718        my ($chipdriver, $datahash) = @_;
2719        my ($i, $new_detected_ref, $detected_ref);
2720
2721        # First determine where the hash has to be added.
2722        $chips_detected{$chipdriver} = []
2723                unless exists $chips_detected{$chipdriver};
2724        $new_detected_ref = $chips_detected{$chipdriver};
2725
2726        # Find out whether our new entry should go into the detected list
2727        # or not. We only compare main isa_addr here, of course.
2728        foreach $detected_ref (values %chips_detected) {
2729                for ($i = 0; $i < @{$detected_ref}; $i++) {
2730                        if (exists $detected_ref->[$i]->{isa_addr} and
2731                            exists $datahash->{isa_addr} and
2732                            $detected_ref->[$i]->{isa_addr} == $datahash->{isa_addr}) {
2733                                if ($detected_ref->[$i]->{conf} < $datahash->{conf}) {
2734                                        splice @$detected_ref, $i, 1;
2735                                        push @$new_detected_ref, $datahash;
2736                                }
2737                                return;
2738                        }
2739                }
2740        }
2741
2742        # Not found? OK, put it in the detected list
2743        push @$new_detected_ref, $datahash;
2744}
2745
2746# $_[0]: reference to an array of chips which may be aliases of each other
2747sub find_aliases
2748{
2749        my $detected = shift;
2750        my ($isa, $i2c, $dev, $alias_detect, $is_alias);
2751
2752        for ($isa = 0; $isa < @{$detected}; $isa++) {
2753                # Look for chips with an ISA address but no I2C address
2754                next unless defined $detected->[$isa];
2755                next unless $detected->[$isa]->{isa_addr};
2756                next if defined $detected->[$isa]->{i2c_addr};
2757                # Additionally, the chip must possibly have I2C aliases
2758                next unless defined $detected->[$isa]->{alias_detect};
2759
2760                for ($i2c = 0; $i2c < @{$detected}; $i2c++) {
2761                        # Look for chips with an I2C address but no ISA address
2762                        next unless defined $detected->[$i2c];
2763                        next unless defined $detected->[$i2c]->{i2c_addr};
2764                        next if $detected->[$i2c]->{isa_addr};
2765                        # Additionally, it must have the same chip name
2766                        next unless $detected->[$i2c]->{chipname} eq
2767                                    $detected->[$isa]->{chipname};
2768
2769                        # We have potential aliases, check if they actually are
2770                        $dev = $dev_i2c.$detected->[$i2c]->{i2c_devnr};
2771                        open(local *FILE, $dev) or
2772                                print("Can't open $dev\n"),
2773                                next;
2774                        binmode(FILE);
2775                        i2c_set_slave_addr(\*FILE, $detected->[$i2c]->{i2c_addr}) or
2776                                print("Can't set I2C address for $dev\n"),
2777                                next;
2778
2779                        initialize_ioports();
2780                        $alias_detect = $detected->[$isa]->{alias_detect};
2781                        $is_alias = &$alias_detect($detected->[$isa]->{isa_addr},
2782                                                   \*FILE,
2783                                                   $detected->[$i2c]->{i2c_addr});
2784                        close(FILE);
2785                        close_ioports();
2786
2787                        next unless $is_alias;
2788                        # This is an alias: copy the I2C data into the ISA
2789                        # entry, then discard the I2C entry
2790                        $detected->[$isa]->{i2c_devnr} = $detected->[$i2c]->{i2c_devnr};
2791                        $detected->[$isa]->{i2c_addr} = $detected->[$i2c]->{i2c_addr};
2792                        $detected->[$isa]->{i2c_sub_addr} = $detected->[$i2c]->{i2c_sub_addr};
2793                        undef $detected->[$i2c];
2794                        last;
2795                }
2796        }
2797
2798        # The loops above may have made the chip list sparse, make it
2799        # compact again
2800        for ($isa = 0; $isa < @{$detected}; ) {
2801                if (defined($detected->[$isa])) {
2802                        $isa++;
2803                } else {
2804                        splice @{$detected}, $isa, 1;
2805                }
2806        }
2807}
2808
2809# From the list of known I2C/SMBus devices, build a list of I2C addresses
2810# which are worth probing. There's no point in probing an address for which
2811# we don't know a single device, and probing some addresses has caused
2812# random trouble in the past.
2813sub i2c_addresses_to_scan
2814{
2815        my @used;
2816        my @addresses;
2817        my $addr;
2818
2819        foreach my $chip (@chip_ids) {
2820                next unless defined $chip->{i2c_addrs};
2821                foreach $addr (@{$chip->{i2c_addrs}}) {
2822                        $used[$addr]++;
2823                }
2824        }
2825
2826        for ($addr = 0x03; $addr <= 0x77; $addr++) {
2827                push @addresses, $addr if $used[$addr];
2828        }
2829        return \@addresses;
2830}
2831
2832# $_[0]: The number of the adapter to scan
2833# $_[1]: Address
2834sub add_busy_i2c_address
2835{
2836        my ($adapter_nr, $addr) = @_;
2837        # If the address is busy, we can normally find out which driver
2838        # requested it (if the kernel is recent enough, at least 2.6.16 and
2839        # later are known to work), and we assume it is the right one.
2840        my ($device, $driver, $new_hash);
2841
2842        $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x",
2843                          $adapter_nr, $addr);
2844        $driver = sysfs_device_driver($device);
2845
2846        if (!defined($driver)) {
2847                printf("Client at address 0x%02x can not be probed - ".
2848                       "unload all client drivers first!\n", $addr);
2849                return;
2850        }
2851
2852        $new_hash = {
2853                conf => 6, # Arbitrary confidence
2854                i2c_addr => $addr,
2855                chipname => sysfs_device_attribute($device, "name")
2856                         || "unknown",
2857                i2c_devnr => $adapter_nr,
2858        };
2859
2860        printf "Client found at address 0x\%02x\n", $addr;
2861        printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n",
2862               $driver, $new_hash->{chipname};
2863
2864        # Only add it to the list if this is something we would have detected,
2865        # else we end up with random i2c chip drivers listed (for example
2866        # media/video drivers.)
2867        if (exists $modules_supported{$driver}) {
2868                add_i2c_to_chips_detected($driver, $new_hash);
2869        } else {
2870                print "    (note: this is probably NOT a sensor chip!)\n";
2871        }
2872}
2873
2874# $_[0]: The number of the adapter to scan
2875# $_[1]: Address
2876# $_[2]: Chip being probed
2877sub probe_free_i2c_address
2878{
2879        my ($adapter_nr, $addr, $chip) = @_;
2880        my ($conf, @other_addr, $new_hash);
2881
2882        printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name}));
2883        if (($conf, @other_addr) = &{$chip->{i2c_detect}} (\*FILE, $addr)) {
2884                if ($chip->{driver} eq "not-a-sensor") {
2885                        print "Yes\n",
2886                              "    (confidence $conf, not a hardware monitoring chip";
2887                } else {
2888                        print "Success!\n",
2889                              "    (confidence $conf, driver `$chip->{driver}'";
2890                }
2891                if (@other_addr) {
2892                        print ", other addresses:";
2893                        @other_addr = sort @other_addr;
2894                        foreach my $other_addr (@other_addr) {
2895                                printf(" 0x%02x", $other_addr);
2896                        }
2897                }
2898                print ")\n";
2899
2900                return if ($chip->{driver} eq "not-a-sensor"
2901                        || $chip->{driver} eq "use-isa-instead");
2902
2903                $new_hash = {
2904                        conf => $conf,
2905                        i2c_addr => $addr,
2906                        chipname => $chip->{name},
2907                        i2c_devnr => $adapter_nr,
2908                };
2909                if (@other_addr) {
2910                        my @other_addr_copy = @other_addr;
2911                        $new_hash->{i2c_sub_addrs} = \@other_addr_copy;
2912                }
2913                add_i2c_to_chips_detected($chip->{driver}, $new_hash);
2914        } else {
2915                print "No\n";
2916        }
2917}
2918
2919# $_[0]: The number of the adapter to check
2920# Returns: PCI class of the adapter if available, 0 if not
2921sub get_i2c_adapter_class
2922{
2923        my ($adapter_nr) = @_;
2924        my ($adapter, $subsystem, $class);
2925
2926        $adapter = "$sysfs_root/class/i2c-adapter/i2c-$adapter_nr";
2927        $subsystem = sysfs_device_subsystem("$adapter/device");
2928        return 0 unless defined $subsystem && $subsystem eq "pci";
2929
2930        $class = sysfs_device_attribute("$adapter/device", "class");
2931        return 0 unless defined $class;
2932        $class = oct($class) if $class =~ /^0/;
2933        return $class >> 8;
2934}
2935
2936# $_[0]: The number of the adapter to scan
2937sub scan_i2c_adapter
2938{
2939        my ($adapter_nr, $smbus_default) = @_;
2940        my ($funcs, $chip, $addr, $class, $default, $input, @not_to_scan);
2941
2942        $class = get_i2c_adapter_class($adapter_nr);
2943        if (($class & 0xff00) == 0x0400) {
2944                # Do not probe adapters on PCI multimedia cards by default
2945                $default = 0;
2946        } elsif ($class == 0x0c01 || $class == 0x0c05
2947              || find_i2c_adapter_driver($i2c_adapters[$adapter_nr]->{name})) {
2948                $default = $smbus_default;
2949        } else {
2950                $default = 1;
2951        }
2952
2953        printf "Next adapter: $i2c_adapters[$adapter_nr]->{name} (i2c-$adapter_nr)\n".
2954               "Do you want to scan it? (\%s/selectively): ",
2955               $default ? "YES/no" : "yes/NO";
2956
2957        $input = <STDIN>;
2958        if ($input =~ /^\s*n/i
2959         || (!$default && $input !~ /^\s*[ys]/i)) {
2960                print "\n";
2961                return;
2962        }
2963
2964        if ($input =~ /^\s*s/i) {
2965                print "Please enter one or more addresses not to scan. Separate them with commas.\n",
2966                      "You can specify a range by using dashes. Example: 0x58-0x5f,0x69.\n",
2967                      "Addresses: ";
2968                $input = <STDIN>;
2969                chomp($input);
2970                @not_to_scan = parse_not_to_scan(0x03, 0x77, $input);
2971        }
2972
2973        open(local *FILE, "$dev_i2c$adapter_nr") or
2974                (print "Can't open $dev_i2c$adapter_nr\n"), return;
2975        binmode(FILE);
2976
2977        # Can we probe this adapter?
2978        $funcs = i2c_get_funcs(\*FILE);
2979        if ($funcs < 0) {
2980                print "Adapter failed to provide its functionalities, skipping.\n";
2981                return;
2982        }
2983        if (!($funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) {
2984                print "Adapter cannot be probed, skipping.\n";
2985                return;
2986        }
2987        if (~$funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE)) {
2988                print "Adapter doesn't support all probing functions.\n",
2989                      "Some addresses won't be probed.\n";
2990        }
2991
2992        # Now scan each address in turn
2993        foreach $addr (@{$i2c_addresses_to_scan}) {
2994                # As the not_to_scan list is sorted, we can check it fast
2995                shift @not_to_scan # User skipped an address which we didn't intend to probe anyway
2996                        while (@not_to_scan and $not_to_scan[0] < $addr);
2997                if (@not_to_scan and $not_to_scan[0] == $addr) {
2998                        shift @not_to_scan;
2999                        next;
3000                }
3001
3002                if (!i2c_set_slave_addr(\*FILE, $addr)) {
3003                        add_busy_i2c_address($adapter_nr, $addr);
3004                        next;
3005                }
3006
3007                next unless i2c_probe(\*FILE, $addr, $funcs);
3008                printf "Client found at address 0x%02x\n", $addr;
3009                if (!i2c_safety_check(\*FILE)) {
3010                        print "Seems to be a 1-register-only device, skipping.\n";
3011                        next;
3012                }
3013
3014                $| = 1;
3015                foreach $chip (@chip_ids, @non_hwmon_chip_ids) {
3016                        next unless exists $chip->{i2c_addrs}
3017                                 && contains($addr, @{$chip->{i2c_addrs}});
3018                        probe_free_i2c_address($adapter_nr, $addr, $chip);
3019                }
3020                $| = 0;
3021        }
3022        print "\n";
3023}
3024
3025sub scan_isa_bus
3026{
3027        my $chip_list_ref = shift;
3028        my ($chip, $addr, $conf);
3029
3030        $| = 1;
3031        foreach $chip (@{$chip_list_ref}) {
3032                next if not exists $chip->{isa_addrs} or not exists $chip->{isa_detect};
3033                foreach $addr (@{$chip->{isa_addrs}}) {
3034                        printf("\%-60s", sprintf("Probing for `\%s'\ at 0x\%x... ",
3035                                                 $chip->{name}, $addr));
3036                        $conf = &{$chip->{isa_detect}} ($addr);
3037                        print("No\n"), next if not defined $conf;
3038                        print "Success!\n";
3039                        printf "    (confidence %d, driver `%s')\n", $conf, $chip->{driver};
3040                        my $new_hash = {
3041                                conf => $conf,
3042                                isa_addr => $addr,
3043                                chipname => $chip->{name},
3044                                alias_detect => $chip->{alias_detect},
3045                        };
3046                        add_isa_to_chips_detected($chip->{driver}, $new_hash);
3047                }
3048        }
3049        $| = 0;
3050}
3051
3052use vars qw(%superio);
3053
3054# The following are taken from the PNP ISA spec (so it's supposed
3055# to be common to all Super I/O chips):
3056#  devidreg: The device ID register(s)
3057#  logdevreg: The logical device register
3058#  actreg: The activation register within the logical device
3059#  actmask: The activation bit in the activation register
3060#  basereg: The I/O base register within the logical device
3061%superio = (
3062        devidreg => 0x20,
3063        logdevreg => 0x07,
3064        actreg => 0x30,
3065        actmask => 0x01,
3066        basereg => 0x60,
3067);
3068
3069sub exit_superio
3070{
3071        my ($addrreg, $datareg) = @_;
3072
3073        # Some chips (SMSC, Winbond) want this
3074        outb($addrreg, 0xaa);
3075
3076        # Return to "Wait For Key" state (PNP-ISA spec)
3077        outb($addrreg, 0x02);
3078        outb($datareg, 0x02);
3079}
3080
3081# Guess if an unknown Super-I/O chip has sensors
3082sub guess_superio_ld
3083{
3084        my ($addrreg, $datareg, $typical_addr) = @_;
3085        my ($oldldn, $ldn, $addr);
3086
3087        # Save logical device number
3088        outb($addrreg, $superio{logdevreg});
3089        $oldldn = inb($datareg);
3090
3091        for ($ldn = 0; $ldn < 16; $ldn++) {
3092                # Select logical device
3093                outb($addrreg, $superio{logdevreg});
3094                outb($datareg, $ldn);
3095
3096                # Read base I/O address
3097                outb($addrreg, $superio{basereg});
3098                $addr = inb($datareg) << 8;
3099                outb($addrreg, $superio{basereg} + 1);
3100                $addr |= inb($datareg);
3101                next unless ($addr & 0xfff8) == $typical_addr;
3102
3103                printf "    (logical device \%X has address 0x\%x, could be sensors)\n",
3104                       $ldn, $addr;
3105                last;
3106        }
3107
3108        # Be nice, restore original logical device
3109        outb($addrreg, $superio{logdevreg});
3110        outb($datareg, $oldldn);
3111}
3112
3113# Returns: features bitmask if device added to chips_detected, 0 if not
3114sub probe_superio
3115{
3116        my ($addrreg, $datareg, $chip) = @_;
3117        my ($val, $addr);
3118
3119        printf "\%-60s", "Found `$chip->{name}'";
3120
3121        # Does it have hardware monitoring capabilities?
3122        if (!exists $chip->{driver}) {
3123                print "\n    (no information available)\n";
3124                return 0;
3125        }
3126        if ($chip->{driver} eq "not-a-sensor") {
3127                print "\n    (no hardware monitoring capabilities)\n";
3128                return 0;
3129        }
3130        if ($chip->{driver} eq "via-smbus-only") {
3131                print "\n    (hardware monitoring capabilities accessible via SMBus only)\n";
3132                return FEAT_SMBUS;
3133        }
3134
3135        # Switch to the sensor logical device
3136        outb($addrreg, $superio{logdevreg});
3137        outb($datareg, $chip->{logdev});
3138
3139        # Check the activation register
3140        outb($addrreg, $superio{actreg});
3141        $val = inb($datareg);
3142        if (!($val & $superio{actmask})) {
3143                print "\n    (but not activated)\n";
3144                return 0;
3145        }
3146
3147        # Get the IO base register
3148        outb($addrreg, $superio{basereg});
3149        $addr = inb($datareg);
3150        outb($addrreg, $superio{basereg} + 1);
3151        $addr = ($addr << 8) | inb($datareg);
3152        if ($addr == 0) {
3153                print "\n    (but no address specified)\n";
3154                return 0;
3155        }
3156        print "Success!\n";
3157        printf "    (address 0x\%x, driver `%s')\n", $addr, $chip->{driver};
3158        my $new_hash = {
3159                conf => 9,
3160                isa_addr => $addr,
3161                chipname => $chip->{name}
3162        };
3163        add_isa_to_chips_detected($chip->{driver}, $new_hash);
3164        return $chip->{features};
3165}
3166
3167# Detection routine for non-standard SMSC Super I/O chips
3168# $_[0]: Super I/O LPC config/index port
3169# $_[1]: Super I/O LPC data port
3170# $_[2]: Reference to array of non-standard chips
3171# Return values: 1 if non-standard chip found, 0 otherwise
3172sub smsc_ns_detect_superio
3173{
3174        my ($addrreg, $datareg, $ns_chips) = @_;
3175        my ($val, $chip);
3176
3177        # read alternate device ID register
3178        outb($addrreg, 0x0d);
3179        $val = inb($datareg);
3180        return 0 if $val == 0x00 || $val == 0xff;
3181
3182        print "Yes\n";
3183
3184        foreach $chip (@{$ns_chips}) {
3185                if ($chip->{devid} == $val) {
3186                        probe_superio($addrreg, $datareg, $chip);
3187                        return 1;
3188                }
3189        }
3190
3191        printf("Found unknown non-standard chip with ID 0x%02x\n", $val);
3192        return 1;
3193}
3194
3195# Returns: features supported by the device added, if any
3196sub scan_superio
3197{
3198        my ($addrreg, $datareg) = @_;
3199        my ($val, $found);
3200        my $features = 0;
3201
3202        printf("Probing for Super-I/O at 0x\%x/0x\%x\n", $addrreg, $datareg);
3203
3204        $| = 1;
3205        # reset state to avoid false positives
3206        exit_superio($addrreg, $datareg);
3207        foreach my $family (@superio_ids) {
3208                printf("\%-60s", "Trying family `$family->{family}'... ");
3209                # write the password
3210                foreach $val (@{$family->{enter}->{$addrreg}}) {
3211                        outb($addrreg, $val);
3212                }
3213                # call the non-standard detection routine first if it exists
3214                if (defined($family->{ns_detect}) &&
3215                    &{$family->{ns_detect}}($addrreg, $datareg, $family->{ns_chips})) {
3216                        last;
3217                }
3218
3219                # did it work?
3220                outb($addrreg, $superio{devidreg});
3221                $val = inb($datareg);
3222                outb($addrreg, $superio{devidreg} + 1);
3223                $val = ($val << 8) | inb($datareg);
3224                if ($val == 0x0000 || $val == 0xffff) {
3225                        print "No\n";
3226                        next;
3227                }
3228                print "Yes\n";
3229
3230                $found = 0;
3231                foreach my $chip (@{$family->{chips}}) {
3232                        if (($chip->{devid} > 0xff &&
3233                             ($val & ($chip->{devid_mask} || 0xffff)) == $chip->{devid})
3234                         || ($chip->{devid} <= 0xff &&
3235                             ($val >> 8) == $chip->{devid})) {
3236                                $features |= probe_superio($addrreg, $datareg, $chip);
3237                                $found++;
3238                        }
3239                }
3240
3241                if (!$found) {
3242                        printf("Found unknown chip with ID 0x%04x\n", $val);
3243                        # Guess if a logical device could correspond to sensors
3244                        guess_superio_ld($addrreg, $datareg, $family->{guess})
3245                                if defined $family->{guess};
3246                }
3247                last;
3248        }
3249        exit_superio($addrreg, $datareg);
3250        $| = 0;
3251        return $features;
3252}
3253
3254sub scan_cpu
3255{
3256        my $entry = shift;
3257        my $confidence;
3258
3259        printf("\%-60s", "$entry->{name}... ");
3260        if (defined ($confidence = $entry->{detect}())) {
3261                print "Success!\n";
3262                printf "    (driver `%s')\n", $entry->{driver};
3263                my $new_hash = {
3264                        conf => $confidence,
3265                        chipname => $entry->{name},
3266                };
3267                add_isa_to_chips_detected($entry->{driver}, $new_hash);
3268        } else {
3269                print "No\n";
3270        }
3271}
3272
3273##################
3274# CHIP DETECTION #
3275##################
3276
3277# This routine allows you to dynamically update the chip detection list.
3278# The most common use is to allow for different chip to driver mappings
3279# based on different linux kernels
3280sub chip_special_cases
3281{
3282        # Some chip to driver mappings depend on the environment
3283        foreach my $chip (@chip_ids) {
3284                if (ref($chip->{driver}) eq 'CODE') {
3285                        $chip->{driver} = $chip->{driver}->();
3286                }
3287        }
3288
3289        # Also fill the fake driver name of non-hwmon chips
3290        foreach my $chip (@non_hwmon_chip_ids) {
3291                $chip->{driver} = "not-a-sensor";
3292        }
3293}
3294
3295# Each function returns a confidence value. The higher this value, the more
3296# sure we are about this chip. This may help overrule false positives,
3297# although we also attempt to prevent false positives in the first place.
3298
3299# Each function returns a list. The first element is the confidence value;
3300# Each element after it is an SMBus address. In this way, we can detect
3301# chips with several SMBus addresses. The SMBus address for which the
3302# function was called is never returned.
3303
3304# All I2C detection functions below take at least 2 parameters:
3305# $_[0]: Reference to the file descriptor to access the chip
3306# $_[1]: Address
3307# Some of these functions which can detect more than one type of device,
3308# take a third parameter:
3309# $_[2]: Chip to detect
3310
3311# Registers used: 0x58
3312sub mtp008_detect
3313{
3314        my ($file, $addr) = @_;
3315        return if i2c_smbus_read_byte_data($file, 0x58) != 0xac;
3316        return 3;
3317}
3318
3319# Chip to detect: 0 = LM78, 2 = LM79
3320# Registers used:
3321#   0x40: Configuration
3322#   0x48: Full I2C Address
3323#   0x49: Device ID
3324sub lm78_detect
3325{
3326        my ($file, $addr, $chip) = @_;
3327        my $reg;
3328
3329        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
3330        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
3331
3332        $reg = i2c_smbus_read_byte_data($file, 0x49);
3333        return if $chip == 0 && ($reg != 0x00 && $reg != 0x20 && $reg != 0x40);
3334        return if $chip == 2 && ($reg & 0xfe) != 0xc0;
3335
3336        # Explicitly prevent misdetection of Winbond chips
3337        $reg = i2c_smbus_read_byte_data($file, 0x4f);
3338        return if $reg == 0xa3 || $reg == 0x5c;
3339
3340        return 6;
3341}
3342
3343# Chip to detect: 0 = LM75, 1 = DS75
3344# Registers used:
3345#   0x00: Temperature
3346#   0x01: Configuration
3347#   0x02: Hysteresis
3348#   0x03: Overtemperature Shutdown
3349#   0x04-0x07: No registers
3350# The first detection step is based on the fact that the LM75 has only
3351# four registers, and cycles addresses over 8-byte boundaries. We use the
3352# 0x04-0x07 addresses (unused) to improve the reliability. These are not
3353# real registers and will always return the last returned value. This isn't
3354# documented.
3355# Note that register 0x00 may change, so we can't use the modulo trick on it.
3356# The DS75 is a bit different, it doesn't cycle over 8-byte boundaries, and
3357# all register addresses from 0x04 to 0x0f behave like 0x04-0x07 do for
3358# the LM75.
3359# Not all devices enjoy SMBus read word transactions, so we use read byte
3360# transactions even for the 16-bit registers. The low bits aren't very
3361# useful for detection anyway.
3362sub lm75_detect
3363{
3364        my ($file, $addr, $chip) = @_;
3365        my $i;
3366        my $cur = i2c_smbus_read_byte_data($file, 0x00);
3367        my $conf = i2c_smbus_read_byte_data($file, 0x01);
3368
3369        my $hyst = i2c_smbus_read_byte_data($file, 0x02, NO_CACHE);
3370        my $maxreg = $chip == 1 ? 0x0f : 0x07;
3371        for $i (0x04 .. $maxreg) {
3372                return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $hyst;
3373        }
3374
3375        my $os = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3376        for $i (0x04 .. $maxreg) {
3377                return if i2c_smbus_read_byte_data($file, $i, NO_CACHE) != $os;
3378        }
3379
3380        if ($chip == 0) {
3381                for ($i = 8; $i <= 248; $i += 40) {
3382                        return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf
3383                               or i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst
3384                               or i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
3385                }
3386        }
3387
3388        # All registers hold the same value, obviously a misdetection
3389        return if $conf == $cur and $cur == $hyst and $cur == $os;
3390
3391        # Unused bits
3392        return if $chip == 0 and ($conf & 0xe0);
3393        return if $chip == 1 and ($conf & 0x80);
3394
3395        # Most probable value ranges
3396        return 6 if $cur <= 100 and ($hyst >= 10 && $hyst <= 125)
3397                and ($os >= 20 && $os <= 127) and $hyst < $os;
3398        return 3;
3399}
3400
3401# Registers used:
3402#   0x00: Temperature
3403#   0x01: Configuration
3404#   0x02: Hysteresis
3405#   0x03: Overtemperature Shutdown
3406#   0x04: Low limit
3407#   0x05: High limit
3408#   0x06-0x07: No registers
3409# The first detection step is based on the fact that the LM77 has only
3410# six registers, and cycles addresses over 8-byte boundaries. We use the
3411# 0x06-0x07 addresses (unused) to improve the reliability. These are not
3412# real registers and will always return the last returned value. This isn't
3413# documented.
3414# Note that register 0x00 may change, so we can't use the modulo trick on it.
3415# Not all devices enjoy SMBus read word transactions, so we use read byte
3416# transactions even for the 16-bit registers at first. We only use read word
3417# transactions in the end when we are already almost certain that we have an
3418# LM77 chip.
3419sub lm77_detect
3420{
3421        my ($file, $addr) = @_;
3422        my $i;
3423        my $cur = i2c_smbus_read_byte_data($file, 0x00);
3424        my $conf = i2c_smbus_read_byte_data($file, 0x01);
3425        my $hyst = i2c_smbus_read_byte_data($file, 0x02);
3426        my $os = i2c_smbus_read_byte_data($file, 0x03);
3427
3428        my $low = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
3429        return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $low;
3430        return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $low;
3431
3432        my $high = i2c_smbus_read_byte_data($file, 0x05, NO_CACHE);
3433        return if i2c_smbus_read_byte_data($file, 0x06, NO_CACHE) != $high;
3434        return if i2c_smbus_read_byte_data($file, 0x07, NO_CACHE) != $high;
3435
3436        for ($i = 8; $i <= 248; $i += 40) {
3437                return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3438                return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
3439                return if i2c_smbus_read_byte_data($file, $i + 0x03) != $os;
3440                return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
3441                return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
3442        }
3443
3444        # All registers hold the same value, obviously a misdetection
3445        return if $conf == $cur and $cur == $hyst
3446              and $cur == $os and $cur == $low and $cur == $high;
3447
3448        # Unused bits
3449        return if ($conf & 0xe0)
3450               or (($cur >> 4) != 0 && ($cur >> 4) != 0xf)
3451               or (($hyst >> 4) != 0 && ($hyst >> 4) != 0xf)
3452               or (($os >> 4) != 0 && ($os >> 4) != 0xf)
3453               or (($low >> 4) != 0 && ($low >> 4) != 0xf)
3454               or (($high >> 4) != 0 && ($high >> 4) != 0xf);
3455
3456        # Make sure the chip supports SMBus read word transactions
3457        foreach $i (0x00, 0x02, 0x03, 0x04, 0x05) {
3458                return if i2c_smbus_read_word_data($file, $i) < 0;
3459        }
3460
3461        return 3;
3462}
3463
3464# Chip to detect: 0 = LM92, 1 = LM76, 2 = MAX6633/MAX6634/MAX6635
3465# Registers used:
3466#   0x01: Configuration (National Semiconductor only)
3467#   0x02: Hysteresis
3468#   0x03: Critical Temp
3469#   0x04: Low Limit
3470#   0x05: High Limit
3471#   0x07: Manufacturer ID (LM92 only)
3472# One detection step is based on the fact that the LM92 and clones have a
3473# limited number of registers, which cycle modulo 16 address values.
3474# Note that register 0x00 may change, so we can't use the modulo trick on it.
3475# Not all devices enjoy SMBus read word transactions, so we use read byte
3476# transactions even for the 16-bit registers at first. We only use read
3477# word transactions in the end when we are already almost certain that we
3478# have an LM92 chip or compatible.
3479sub lm92_detect
3480{
3481        my ($file, $addr, $chip) = @_;
3482
3483        my $conf = i2c_smbus_read_byte_data($file, 0x01);
3484        my $hyst = i2c_smbus_read_byte_data($file, 0x02);
3485        my $crit = i2c_smbus_read_byte_data($file, 0x03);
3486        my $low = i2c_smbus_read_byte_data($file, 0x04);
3487        my $high = i2c_smbus_read_byte_data($file, 0x05);
3488
3489        return if $conf == 0 and $hyst == 0 and $crit == 0
3490                and $low == 0 and $high == 0;
3491
3492        # Unused bits
3493        return if ($chip == 0 || $chip == 1)
3494              and ($conf & 0xE0);
3495
3496        for (my $i = 0; $i <= 240; $i += 16) {
3497                return if i2c_smbus_read_byte_data($file, $i + 0x01) != $conf;
3498                return if i2c_smbus_read_byte_data($file, $i + 0x02) != $hyst;
3499                return if i2c_smbus_read_byte_data($file, $i + 0x03) != $crit;
3500                return if i2c_smbus_read_byte_data($file, $i + 0x04) != $low;
3501                return if i2c_smbus_read_byte_data($file, $i + 0x05) != $high;
3502        }
3503
3504        return if $chip == 0
3505              and i2c_smbus_read_word_data($file, 0x07) != 0x0180;
3506
3507        # Make sure the chip supports SMBus read word transactions
3508        $hyst = i2c_smbus_read_word_data($file, 0x02);
3509        return if $hyst < 0;
3510        $crit = i2c_smbus_read_word_data($file, 0x03);
3511        return if $crit < 0;
3512        $low = i2c_smbus_read_word_data($file, 0x04);
3513        return if $low < 0;
3514        $high = i2c_smbus_read_word_data($file, 0x05);
3515        return if $high < 0;
3516
3517        foreach my $temp ($hyst, $crit, $low, $high) {
3518                return if $chip == 2 and ($temp & 0x7F00);
3519                return if $chip != 2 and ($temp & 0x0700);
3520        }
3521
3522        return ($chip == 0) ? 4 : 2;
3523}
3524
3525# Registers used:
3526#   0xAA: Temperature
3527#   0xA1: High limit
3528#   0xA2: Low limit
3529#   0xA8: Counter
3530#   0xA9: Slope
3531#   0xAC: Configuration
3532# Detection is weak. We check if bit 4 (NVB) is clear, because it is
3533# unlikely to be set (would mean that EEPROM is currently being accessed).
3534# We also check the value of the counter and slope registers, the datasheet
3535# doesn't mention the possible values but the conversion formula together
3536# with experimental evidence suggest possible sanity checks.
3537# Not all devices enjoy SMBus read word transactions, so we do as much as
3538# possible with read byte transactions first, and only use read word
3539# transactions second.
3540sub ds1621_detect
3541{
3542        my ($file, $addr) = @_;
3543
3544        my $conf = i2c_smbus_read_byte_data($file, 0xAC);
3545        return if ($conf & 0x10);
3546
3547        my $counter = i2c_smbus_read_byte_data($file, 0xA8);
3548        my $slope = i2c_smbus_read_byte_data($file, 0xA9);
3549        return if ($slope != 0x10 || $counter > $slope);
3550
3551        my $temp = i2c_smbus_read_word_data($file, 0xAA);
3552        return if $temp < 0 || ($temp & 0x0f00);
3553        # On the DS1631, the following two checks are too strict in theory,
3554        # but in practice I very much doubt that anyone will set temperature
3555        # limits not a multiple of 0.5 degrees C.
3556        my $high = i2c_smbus_read_word_data($file, 0xA1);
3557        return if $high < 0 || ($high & 0x7f00);
3558        my $low = i2c_smbus_read_word_data($file, 0xA2);
3559        return if $low < 0 || ($low & 0x7f00);
3560
3561        return if ($temp == 0 && $high == 0 && $low == 0 && $conf == 0);
3562
3563        return 3;
3564}
3565
3566# Registers used:
3567#   0x00: Configuration register
3568#   0x02: Interrupt state register
3569#   0x2a-0x3d: Limits registers
3570# This one is easily misdetected since it doesn't provide identification
3571# registers. So we have to use some tricks:
3572#   - 6-bit addressing, so limits readings modulo 0x40 should be unchanged
3573#   - positive temperature limits
3574#   - limits order correctness
3575# Hopefully this should limit the rate of false positives, without increasing
3576# the rate of false negatives.
3577# Thanks to Lennard Klein for testing on a non-LM80 chip, which was
3578# previously misdetected, and isn't anymore. For reference, it scored
3579# a final confidence of 0, and changing from strict limit comparisons
3580# to loose comparisons did not change the score.
3581sub lm80_detect
3582{
3583        my ($file, $addr) = @_;
3584        my ($i, $reg);
3585
3586        return if (i2c_smbus_read_byte_data($file, 0x00) & 0x80) != 0;
3587        return if (i2c_smbus_read_byte_data($file, 0x02) & 0xc0) != 0;
3588
3589        for ($i = 0x2a; $i <= 0x3d; $i++) {
3590                $reg = i2c_smbus_read_byte_data($file, $i);
3591                return if i2c_smbus_read_byte_data($file, $i+0x40) != $reg;
3592                return if i2c_smbus_read_byte_data($file, $i+0x80) != $reg;
3593                return if i2c_smbus_read_byte_data($file, $i+0xc0) != $reg;
3594        }
3595
3596        # Refine a bit by checking whether limits are in the correct order
3597        # (min<max for voltages, hyst<max for temperature). Since it is still
3598        # possible that the chip is an LM80 with limits not properly set,
3599        # a few "errors" are tolerated.
3600        my $confidence = 0;
3601        for ($i = 0x2a; $i <= 0x3a; $i++) {
3602                $confidence++
3603                        if i2c_smbus_read_byte_data($file, $i) < i2c_smbus_read_byte_data($file, $i+1);
3604        }
3605        # hot temp<OS temp
3606        $confidence++
3607                if i2c_smbus_read_byte_data($file, 0x38) < i2c_smbus_read_byte_data($file, 0x3a);
3608
3609        # Negative temperature limits are unlikely.
3610        for ($i = 0x3a; $i <= 0x3d; $i++) {
3611                $confidence++ if (i2c_smbus_read_byte_data($file, $i) & 0x80) == 0;
3612        }
3613
3614        # $confidence is between 0 and 14
3615        $confidence = ($confidence >> 1) - 4;
3616        # $confidence is now between -4 and 3
3617
3618        return unless $confidence > 0;
3619
3620        return $confidence;
3621}
3622
3623# Registers used:
3624#   0x02: Status 1
3625#   0x03: Configuration
3626#   0x04: Company ID of LM84
3627#   0x35: Status 2
3628#   0xfe: Manufacturer ID
3629#   0xff: Chip ID / die revision
3630# We can use the LM84 Company ID register because the LM83 and the LM82 are
3631# compatible with the LM84.
3632# The LM83 chip ID is missing from the datasheet and was contributed by
3633# Magnus Forsstrom: 0x03.
3634# At least some revisions of the LM82 seem to be repackaged LM83, so they
3635# have the same chip ID, and temp2/temp4 will be stuck in "OPEN" state.
3636# For this reason, we don't even try to distinguish between both chips.
3637# Thanks to Ben Gardner for reporting.
3638sub lm83_detect
3639{
3640        my ($file, $addr) = @_;
3641        return if i2c_smbus_read_byte_data($file, 0xfe) != 0x01;
3642        my $chipid = i2c_smbus_read_byte_data($file, 0xff);
3643        return if $chipid != 0x01 && $chipid != 0x03;
3644
3645        my $confidence = 4;
3646        $confidence++
3647                if (i2c_smbus_read_byte_data($file, 0x02) & 0xa8) == 0x00;
3648        $confidence++
3649                if (i2c_smbus_read_byte_data($file, 0x03) & 0x41) == 0x00;
3650        $confidence++
3651                if i2c_smbus_read_byte_data($file, 0x04) == 0x00;
3652        $confidence++
3653                if (i2c_smbus_read_byte_data($file, 0x35) & 0x48) == 0x00;
3654
3655        return $confidence;
3656}
3657
3658# Chip to detect: 0 = LM90, 1 = LM89/LM99, 2 = LM86, 3 = ADM1032,
3659#                 4 = MAX6654/MAX6690, 5 = ADT7461,
3660#                 6 = MAX6646/MAX6647/MAX6648/MAX6649/MAX6692,
3661#                 7 = MAX6680/MAX6681, 8 = W83L771W/G, 9 = TMP401, 10 = TMP411
3662# Registers used:
3663#   0x03: Configuration
3664#   0x04: Conversion rate
3665#   0xfe: Manufacturer ID
3666#   0xff: Chip ID / die revision
3667sub lm90_detect
3668{
3669        my ($file, $addr, $chip) = @_;
3670        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3671        my $cid = i2c_smbus_read_byte_data($file, 0xff);
3672        my $conf = i2c_smbus_read_byte_data($file, 0x03);
3673        my $rate = i2c_smbus_read_byte_data($file, 0x04);
3674
3675        if ($chip == 0) {
3676                return if ($conf & 0x2a) != 0;
3677                return if $rate > 0x09;
3678                return if $mid != 0x01;         # National Semiconductor
3679                return 8 if $cid == 0x21;       # LM90
3680                return 6 if ($cid & 0x0f) == 0x20;
3681        }
3682        if ($chip == 1) {
3683                return if ($conf & 0x2a) != 0;
3684                return if $rate > 0x09;
3685                return if $mid != 0x01;         # National Semiconductor
3686                return 8 if $addr == 0x4c and $cid == 0x31; # LM89/LM99
3687                return 8 if $addr == 0x4d and $cid == 0x34; # LM89-1/LM99-1
3688                return 6 if ($cid & 0x0f) == 0x30;
3689        }
3690        if ($chip == 2) {
3691                return if ($conf & 0x2a) != 0;
3692                return if $rate > 0x09;
3693                return if $mid != 0x01;         # National Semiconductor
3694                return 8 if $cid == 0x11;       # LM86
3695                return 6 if ($cid & 0xf0) == 0x10;
3696        }
3697        if ($chip == 3) {
3698                return if ($conf & 0x3f) != 0;
3699                return if $rate > 0x0a;
3700                return if $mid != 0x41;         # Analog Devices
3701                return 6 if ($cid & 0xf0) == 0x40; # ADM1032
3702        }
3703        if ($chip == 4) {
3704                return if ($conf & 0x07) != 0;
3705                return if $rate > 0x07;
3706                return if $mid != 0x4d;         # Maxim
3707                return 8 if $cid == 0x08;       # MAX6654/MAX6690
3708        }
3709        if ($chip == 5) {
3710                return if ($conf & 0x1b) != 0;
3711                return if $rate > 0x0a;
3712                return if $mid != 0x41;         # Analog Devices
3713                return 8 if $cid == 0x51;       # ADT7461
3714        }
3715        if ($chip == 6) {
3716                return if ($conf & 0x3f) != 0;
3717                return if $rate > 0x07;
3718                return if $mid != 0x4d;         # Maxim
3719                return 8 if $cid == 0x59;       # MAX6648/MAX6692
3720        }
3721        if ($chip == 7) {
3722                return if ($conf & 0x03) != 0;
3723                return if $rate > 0x07;
3724                return if $mid != 0x4d;         # Maxim
3725                return 8 if $cid == 0x01;       # MAX6680/MAX6681
3726        }
3727        if ($chip == 8) {
3728                return if ($conf & 0x2a) != 0;
3729                return if $rate > 0x09;
3730                return if $mid != 0x5c;         # Winbond
3731                return 6 if $cid == 0x00;       # W83L771W/G
3732        }
3733        if ($chip == 9) {
3734                return if ($conf & 0x1B) != 0;
3735                return if $rate > 0x0F;
3736                return if $mid != 0x55;         # Texas Instruments
3737                return 8 if $cid == 0x11;       # TMP401
3738        }
3739        if ($chip == 10) {
3740                return if ($conf & 0x1B) != 0;
3741                return if $rate > 0x0F;
3742                return if $mid != 0x55;         # Texas Instruments
3743                return 6 if ($addr == 0x4c && $cid == 0x12); # TMP411A
3744                return 6 if ($addr == 0x4d && $cid == 0x13); # TMP411B
3745                return 6 if ($addr == 0x4e && $cid == 0x10); # TMP411C
3746        }
3747        return;
3748}
3749
3750# Registers used:
3751#   0x03: Configuration (no low nibble, returns the previous low nibble)
3752#   0x04: Conversion rate
3753#   0xfe: Manufacturer ID
3754#   0xff: no register
3755sub max6657_detect
3756{
3757        my ($file, $addr) = @_;
3758        my $mid = i2c_smbus_read_byte_data($file, 0xfe, NO_CACHE);
3759        my $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
3760        my $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3761
3762        return if $mid != 0x4d;         # Maxim
3763        return if ($conf & 0x1f) != 0x0d;
3764        return if $cid != 0x4d;         # No register, returns previous value
3765
3766        my $rate = i2c_smbus_read_byte_data($file, 0x04, NO_CACHE);
3767        return if $rate > 0x09;
3768
3769        $cid = i2c_smbus_read_byte_data($file, 0xff, NO_CACHE);
3770        $conf = i2c_smbus_read_byte_data($file, 0x03, NO_CACHE);
3771        return if ($conf & 0x0f) != $rate;
3772        return if $cid != $rate;        # No register, returns previous value
3773
3774        return 5;
3775}
3776
3777# Registers used:
3778#   0x03: Configuration
3779#   0xfe: Manufacturer ID
3780#   0xff: Revision ID
3781sub lm95231_detect
3782{
3783        my ($file, $addr) = @_;
3784        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3785        my $cid = i2c_smbus_read_byte_data($file, 0xff);
3786        my $conf = i2c_smbus_read_byte_data($file, 0x03);
3787
3788        return if ($conf & 0x89) != 0;
3789        return if $mid != 0x01;         # National Semiconductor
3790        return if $cid != 0xa1;         # LM95231
3791
3792        return 6;
3793}
3794
3795# Registers used:
3796#   0x03: Configuration 1
3797#   0x24: Configuration 2
3798#   0x3d: Manufacturer ID
3799#   0x3e: Device ID
3800sub adt7481_detect
3801{
3802        my ($file, $addr) = @_;
3803        my $mid = i2c_smbus_read_byte_data($file, 0x3d);
3804        my $cid = i2c_smbus_read_byte_data($file, 0x3e);
3805        my $conf1 = i2c_smbus_read_byte_data($file, 0x03);
3806        my $conf2 = i2c_smbus_read_byte_data($file, 0x24);
3807
3808        return if ($conf1 & 0x10) != 0;
3809        return if ($conf2 & 0x7f) != 0;
3810        return if $mid != 0x41;         # Analog Devices
3811        return if $cid != 0x81;         # ADT7481
3812
3813        return 6;
3814}
3815
3816# Chip to detect: 1 = LM63, 2 = F75363SG, 3 = LM64
3817# Registers used:
3818#   0xfe: Manufacturer ID
3819#   0xff: Chip ID / die revision
3820#   0x03: Configuration (two or three unused bits)
3821#   0x16: Alert mask (two or three unused bits)
3822sub lm63_detect
3823{
3824        my ($file, $addr, $chip) = @_;
3825
3826        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
3827        my $cid = i2c_smbus_read_byte_data($file, 0xff);
3828        my $conf = i2c_smbus_read_byte_data($file, 0x03);
3829        my $mask = i2c_smbus_read_byte_data($file, 0x16);
3830
3831        if ($chip == 1) {
3832                return if $mid != 0x01          # National Semiconductor
3833                       || $cid != 0x41;         # LM63
3834                return if ($conf & 0x18) != 0x00
3835                       || ($mask & 0xa4) != 0xa4;
3836        } elsif ($chip == 2) {
3837                return if $mid != 0x23          # Fintek
3838                       || $cid != 0x20;         # F75363SG
3839                return if ($conf & 0x1a) != 0x00
3840                       || ($mask & 0x84) != 0x00;
3841        } elsif ($chip == 3) {
3842                return if $mid != 0x01          # National Semiconductor
3843                       || $cid != 0x51;         # LM64
3844                return if ($conf & 0x18) != 0x00
3845                       || ($mask & 0xa4) != 0xa4;
3846        }
3847
3848        return 6;
3849}
3850
3851# Registers used:
3852#   0x02, 0x03: Fan support
3853#   0x06: Temperature support
3854#   0x07, 0x08, 0x09: Fan config
3855#   0x0d: Manufacturer ID
3856#   0x0e: Chip ID / die revision
3857sub adm1029_detect
3858{
3859        my ($file, $addr) = @_;
3860        my $mid = i2c_smbus_read_byte_data($file, 0x0d);
3861        my $cid = i2c_smbus_read_byte_data($file, 0x0e);
3862        my $cfg;
3863
3864        return unless $mid == 0x41;             # Analog Devices
3865        return unless ($cid & 0xF0) == 0x00;    # ADM1029
3866
3867        # Extra check on unused bits
3868        $cfg = i2c_smbus_read_byte_data($file, 0x02);
3869        return unless $cfg == 0x03;
3870        $cfg = i2c_smbus_read_byte_data($file, 0x06);
3871        return unless ($cfg & 0xF9) == 0x01;
3872        foreach my $reg (0x03, 0x07, 0x08, 0x09) {
3873                $cfg = i2c_smbus_read_byte_data($file, $reg);
3874                return unless ($cfg & 0xFC) == 0x00;
3875        }
3876
3877        return 7;
3878}
3879
3880# Chip to detect: 0 = ADM1030, 1 = ADM1031
3881# Registers used:
3882#   0x01: Config 2
3883#   0x03: Status 2
3884#   0x0d, 0x0e, 0x0f: Temperature offsets
3885#   0x22: Fan speed config
3886#   0x3d: Chip ID
3887#   0x3e: Manufacturer ID
3888#   0x3f: Die revision
3889sub adm1031_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        my $conf2 = i2c_smbus_read_byte_data($file, 0x01);
3896        my $stat2 = i2c_smbus_read_byte_data($file, 0x03);
3897        my $fsc = i2c_smbus_read_byte_data($file, 0x22);
3898        my $lto = i2c_smbus_read_byte_data($file, 0x0d);
3899        my $r1to = i2c_smbus_read_byte_data($file, 0x0e);
3900        my $r2to = i2c_smbus_read_byte_data($file, 0x0f);
3901        my $confidence = 3;
3902
3903        if ($chip == 0) {
3904                return if $mid != 0x41;         # Analog Devices
3905                return if $cid != 0x30;         # ADM1030
3906                $confidence++ if ($drev & 0x70) == 0x00;
3907                $confidence++ if ($conf2 & 0x4A) == 0x00;
3908                $confidence++ if ($stat2 & 0x3F) == 0x00;
3909                $confidence++ if ($fsc & 0xF0) == 0x00;
3910                $confidence++ if ($lto & 0x70) == 0x00;
3911                $confidence++ if ($r1to & 0x70) == 0x00;
3912                return $confidence;
3913        }
3914        if ($chip == 1) {
3915                return if $mid != 0x41;         # Analog Devices
3916                return if $cid != 0x31;         # ADM1031
3917                $confidence++ if ($drev & 0x70) == 0x00;
3918                $confidence++ if ($lto & 0x70) == 0x00;
3919                $confidence++ if ($r1to & 0x70) == 0x00;
3920                $confidence++ if ($r2to & 0x70) == 0x00;
3921                return $confidence;
3922        }
3923}
3924
3925# Chip to detect: 0 = ADM1033, 1 = ADM1034
3926# Registers used:
3927#   0x3d: Chip ID
3928#   0x3e: Manufacturer ID
3929#   0x3f: Die revision
3930sub adm1034_detect
3931{
3932        my ($file, $addr, $chip) = @_;
3933        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
3934        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
3935        my $drev = i2c_smbus_read_byte_data($file, 0x3f);
3936
3937        if ($chip == 0) {
3938                return if $mid != 0x41;         # Analog Devices
3939                return if $cid != 0x33;         # ADM1033
3940                return if ($drev & 0xf8) != 0x00;
3941                return 6 if $drev == 0x02;
3942                return 4;
3943        }
3944        if ($chip == 1) {
3945                return if $mid != 0x41;         # Analog Devices
3946                return if $cid != 0x34;         # ADM1034
3947                return if ($drev & 0xf8) != 0x00;
3948                return 6 if $drev == 0x02;
3949                return 4;
3950        }
3951}
3952
3953# Chip to detect: 0 = ADT7467/ADT7468, 1 = ADT7476, 2 = ADT7462, 3 = ADT7466,
3954#                 4 = ADT7470
3955# Registers used:
3956#   0x3d: Chip ID
3957#   0x3e: Manufacturer ID
3958#   0x3f: Die revision
3959sub adt7467_detect
3960{
3961        my ($file, $addr, $chip) = @_;
3962        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
3963        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
3964        my $drev = i2c_smbus_read_byte_data($file, 0x3f);
3965
3966        return if $mid != 0x41;                 # Analog Devices
3967
3968        if ($chip == 0) {
3969                return if $cid != 0x68;         # ADT7467
3970                return if ($drev & 0xf0) != 0x70;
3971                return 7 if $drev == 0x71 || $drev == 0x72;
3972                return 5;
3973        }
3974        if ($chip == 1) {
3975                return if $cid != 0x76;         # ADT7476
3976                return if ($drev & 0xf0) != 0x60;
3977                return 7 if $drev == 0x69;
3978                return 5;
3979        }
3980        if ($chip == 2) {
3981                return if $cid != 0x62;         # ADT7462
3982                return if ($drev & 0xf0) != 0x00;
3983                return 7 if $drev == 0x04;
3984                return 5;
3985        }
3986        if ($chip == 3) {
3987                return if $cid != 0x66;         # ADT7466
3988                return if ($drev & 0xf0) != 0x00;
3989                return 7 if $drev == 0x02;
3990                return 5;
3991        }
3992        if ($chip == 4) {
3993                return if $cid != 0x70;         # ADT7470
3994                return if ($drev & 0xf0) != 0x00;
3995                return 7 if $drev == 0x00;
3996                return 5;
3997        }
3998}
3999
4000# Chip to detect: 0 = ADT7473, 1 = ADT7475
4001# Registers used:
4002#   0x3d: Chip ID
4003#   0x3e: Manufacturer ID
4004sub adt7473_detect
4005{
4006        my ($file, $addr, $chip) = @_;
4007        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4008        my $cid = i2c_smbus_read_byte_data($file, 0x3d);
4009
4010        return if $mid != 0x41;                 # Analog Devices
4011
4012        return if $chip == 0 && $cid != 0x73;   # ADT7473
4013        return if $chip == 1 && $cid != 0x75;   # ADT7475
4014        return 5;
4015}
4016
4017# Chip to detect: 0 = aSC7512, 1 = aSC7611, 2 = aSC7621
4018# Registers used:
4019#   0x3e: Manufacturer ID
4020#   0x3f: Version
4021sub andigilog_detect
4022{
4023        my ($file, $addr, $chip) = @_;
4024        my $mid = i2c_smbus_read_byte_data($file, 0x3e);
4025        my $cid = i2c_smbus_read_byte_data($file, 0x3f);
4026
4027        return if $mid != 0x61;         # Andigilog
4028
4029        return if $chip == 0 && $cid != 0x62;
4030        return if $chip == 1 && $cid != 0x69;
4031        return if $chip == 2 && ($cid != 0x6C && $cid != 0x6D);
4032        return 5;
4033}
4034
4035# Registers used:
4036#   0xfe: Manufacturer ID
4037#   0xff: Die Code
4038sub andigilog_aSC7511_detect
4039{
4040        my ($file, $addr) = @_;
4041        my $mid = i2c_smbus_read_byte_data($file, 0xfe);
4042        my $die = i2c_smbus_read_byte_data($file, 0xff);
4043
4044        return if $mid != 0x61;         # Andigilog
4045        return if $die != 0x00;
4046        return 3;
4047}
4048
4049# Chip to detect: 0 = LM85, 1 = LM96000, 2 = ADM1027, 3 = ADT7463,
4050#                 4 = EMC6D100/101, 5 = EMC6D102, 6 = EMC6D103
4051# Registers used:
4052#   0x3e: Vendor register
4053#   0x3d: Device ID register (Analog Devices only)
4054#   0x3f: Version/Stepping register
4055sub lm85_detect
4056{
4057        my ($file, $addr, $chip) = @_;
4058        my $vendor = i2c_smbus_read_byte_data($file, 0x3e);
4059        my $verstep = i2c_smbus_read_byte_data($file, 0x3f);
4060
4061        if ($chip == 0) {
4062                return if $vendor != 0x01;      # National Semiconductor
4063                return if $verstep != 0x60      # LM85 C
4064                       && $verstep != 0x62;     # LM85 B
4065        } elsif ($chip == 1) {
4066                return if $vendor != 0x01;      # National Semiconductor
4067                return if $verstep != 0x68      # LM96000
4068                       && $verstep != 0x69;     # LM96000
4069        } elsif ($chip == 2) {
4070                return if $vendor != 0x41;      # Analog Devices
4071                return if $verstep != 0x60;     # ADM1027
4072        } elsif ($chip == 3) {
4073                return if $vendor != 0x41;      # Analog Devices
4074                return if $verstep != 0x62      # ADT7463
4075                       && $verstep != 0x6a;     # ADT7463 C
4076        } elsif ($chip == 4) {
4077                return if $vendor != 0x5c;      # SMSC
4078                return if $verstep != 0x60      # EMC6D100/101 A0
4079                       && $verstep != 0x61;     # EMC6D100/101 A1
4080        } elsif ($chip == 5) {
4081                return if $vendor != 0x5c;      # SMSC
4082                return if $verstep != 0x65;     # EMC6D102
4083        } elsif ($chip == 6) {
4084                return if $vendor != 0x5c;      # SMSC
4085                return if $verstep != 0x68;     # EMC6D103
4086        }
4087
4088        if ($vendor == 0x41) {                  # Analog Devices
4089                return if i2c_smbus_read_byte_data($file, 0x3d) != 0x27;
4090                return 8;
4091        }
4092        return 7;
4093}
4094
4095# Chip to detect: 0 = LM87, 1 = ADM1024
4096# Registers used:
4097#   0x3e: Company ID
4098#   0x3f: Revision
4099#   0x40: Configuration
4100sub lm87_detect
4101{
4102        my ($file, $addr, $chip) = @_;
4103        my $cid = i2c_smbus_read_byte_data($file, 0x3e);
4104        my $rev = i2c_smbus_read_byte_data($file, 0x3f);
4105
4106        if ($chip == 0) {
4107                return if $cid != 0x02;         # National Semiconductor
4108                return if ($rev & 0xfc) != 0x04; # LM87
4109        }
4110        if ($chip == 1) {
4111                return if $cid != 0x41;         # Analog Devices
4112                return if ($rev & 0xf0) != 0x10; # ADM1024
4113        }
4114
4115        my $cfg = i2c_smbus_read_byte_data($file, 0x40);
4116        return if ($cfg & 0x80) != 0x00;
4117
4118        return 7;
4119}
4120
4121# Chip to detect: 0 = W83781D, 1 = W83782D, 2 = W83783S, 3 = W83627HF,
4122#                 4 = AS99127F (rev.1), 5 = AS99127F (rev.2), 6 = ASB100,
4123#                 7 = W83791D, 8 = W83792D, 9 = W83627EHF, 10 = W83627DHG
4124# Registers used:
4125#   0x48: Full I2C Address
4126#   0x4a: I2C addresses of emulated LM75 chips
4127#   0x4e: Vendor ID byte selection, and bank selection
4128#   0x4f: Vendor ID
4129#   0x58: Device ID (only when in bank 0)
4130# Note: Fails if the W8378xD is not in bank 0!
4131# Note: Asus chips do not have their I2C address at register 0x48?
4132#       AS99127F rev.1 and ASB100 have 0x00, confirmation wanted for
4133#       AS99127F rev.2.
4134sub w83781d_detect
4135{
4136        my ($file, $addr, $chip) = @_;
4137        my ($reg1, $reg2, @res);
4138
4139        return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr)
4140                   or ($chip >= 4 && $chip <= 6);
4141
4142        $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4143        $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4144        if ($chip == 4) {               # Asus AS99127F (rev.1)
4145                return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xc3) or
4146                              (($reg1 & 0x80) == 0x80 and $reg2 == 0x12);
4147        } elsif ($chip == 6) {          # Asus ASB100
4148                return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0x94) or
4149                              (($reg1 & 0x80) == 0x80 and $reg2 == 0x06);
4150        } else {                        # Winbond and Asus AS99127F (rev.2)
4151                return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
4152                              (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4153        }
4154
4155        return unless ($reg1 & 0x07) == 0x00;
4156
4157        $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4158        return if $chip == 0 and ($reg1 != 0x10 && $reg1 != 0x11);
4159        return if $chip == 1 and $reg1 != 0x30;
4160        return if $chip == 2 and $reg1 != 0x40;
4161        return if $chip == 3 and $reg1 != 0x21;
4162        return if $chip == 4 and $reg1 != 0x31;
4163        return if $chip == 5 and $reg1 != 0x31;
4164        return if $chip == 6 and $reg1 != 0x31;
4165        return if $chip == 7 and $reg1 != 0x71;
4166        return if $chip == 8 and $reg1 != 0x7a;
4167        return if $chip == 9 and ($reg1 != 0x88 && $reg1 != 0xa1);
4168        return if $chip == 10 and $reg1 != 0xc1;
4169        # Default address is 0x2d
4170        @res = ($addr != 0x2d) ? (7) : (8);
4171        return @res if $chip >= 9; # No subclients
4172
4173        $reg1 = i2c_smbus_read_byte_data($file, 0x4a);
4174        push @res, ($reg1 & 0x07) + 0x48 unless $reg1 & 0x08;
4175        push @res, (($reg1 & 0x70) >> 4) + 0x48
4176                unless ($reg1 & 0x80 or $chip == 2);
4177        return @res;
4178}
4179
4180# Registers used:
4181#   0x0b: Full I2C Address
4182#   0x0c: I2C addresses of emulated LM75 chips
4183#   0x00: Vendor ID byte selection, and bank selection(Bank 0, 1, 2)
4184#   0x0d: Vendor ID(Bank 0, 1, 2)
4185#   0x0e: Device ID(Bank 0, 1, 2)
4186sub w83793_detect
4187{
4188        my ($file, $addr) = @_;
4189        my ($bank, $reg, @res);
4190
4191        $bank = i2c_smbus_read_byte_data($file, 0x00);
4192        $reg = i2c_smbus_read_byte_data($file, 0x0d);
4193
4194        return unless (($bank & 0x80) == 0x00 and $reg == 0xa3) or
4195                      (($bank & 0x80) == 0x80 and $reg == 0x5c);
4196
4197        $reg = i2c_smbus_read_byte_data($file, 0x0e);
4198        return if $reg != 0x7b;
4199
4200        # If bank 0 is selected, we can do more checks
4201        return 6 unless ($bank & 0x07) == 0;
4202        $reg = i2c_smbus_read_byte_data($file, 0x0b);
4203        return unless ($reg == ($addr << 1));
4204
4205        $reg = i2c_smbus_read_byte_data($file, 0x0c);
4206        @res = (8);
4207        push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4208        push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4209        return @res;
4210}
4211
4212# Registers used:
4213#   0x48: Full I2C Address
4214#   0x4e: Vendor ID byte selection
4215#   0x4f: Vendor ID
4216#   0x58: Device ID
4217# Note that the datasheet was useless and this detection routine
4218# is based on dumps we received from users. Also, the W83781SD is *NOT*
4219# a hardware monitoring chip as far as we know, but we still want to
4220# detect it so that people won't keep reporting it as an unknown chip
4221# we should investigate about.
4222sub w83791sd_detect
4223{
4224        my ($file, $addr) = @_;
4225        my ($reg1, $reg2);
4226
4227        return unless (i2c_smbus_read_byte_data($file, 0x48) == $addr);
4228
4229        $reg1 = i2c_smbus_read_byte_data($file, 0x4e);
4230        $reg2 = i2c_smbus_read_byte_data($file, 0x4f);
4231        return unless (!($reg1 & 0x80) && $reg2 == 0xa3)
4232                   || (($reg1 & 0x80) && $reg2 == 0x5c);
4233
4234        $reg1 = i2c_smbus_read_byte_data($file, 0x58);
4235        return unless $reg1 == 0x72;
4236
4237        return 3;
4238}
4239
4240# Registers used:
4241#   0x4e: Vendor ID high byte
4242#   0x4f: Vendor ID low byte
4243#   0x58: Device ID
4244# Note: The values were given by Alex van Kaam, we don't have datasheets
4245#       to confirm.
4246sub mozart_detect
4247{
4248        my ($file, $addr) = @_;
4249        my ($vid, $dev);
4250
4251        $vid = (i2c_smbus_read_byte_data($file, 0x4e) << 8)
4252             + i2c_smbus_read_byte_data($file, 0x4f);
4253        $dev = i2c_smbus_read_byte_data($file, 0x58);
4254
4255        return unless ($dev == 0x56 && $vid == 0x9436)  # ASM58
4256                   || ($dev == 0x56 && $vid == 0x9406)  # AS2K129R
4257                   || ($dev == 0x10 && $vid == 0x5ca3);
4258
4259        return 5;
4260}
4261
4262# Chip to detect: 0 = GL518SM, 1 = GL520SM
4263# Registers used:
4264#   0x00: Device ID
4265#   0x01: Revision ID
4266#   0x03: Configuration
4267sub gl518sm_detect
4268{
4269        my ($file, $addr, $chip) = @_;
4270        my $reg;
4271
4272        $reg = i2c_smbus_read_byte_data($file, 0x00);
4273        return if $chip == 0 && $reg != 0x80;
4274        return if $chip == 1 && $reg != 0x20;
4275
4276        return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
4277        $reg = i2c_smbus_read_byte_data($file, 0x01);
4278        return unless $reg == 0x00 or $reg == 0x80;
4279        return 6;
4280}
4281
4282# Registers used:
4283#   0x00: Device ID
4284#   0x03: Configuration
4285# Mediocre detection
4286sub gl525sm_detect
4287{
4288        my ($file, $addr) = @_;
4289        return unless i2c_smbus_read_byte_data($file, 0x00) == 0x25;
4290        return unless (i2c_smbus_read_byte_data($file, 0x03) & 0x80) == 0x00;
4291        return 5;
4292}
4293
4294# Chip to detect: 0 = ADM9240, 1 = DS1780, 2 = LM81
4295# Registers used:
4296#   0x3e: Company ID
4297#   0x40: Configuration
4298#   0x48: Full I2C Address
4299sub adm9240_detect
4300{
4301        my ($file, $addr, $chip) = @_;
4302        my $reg;
4303        $reg = i2c_smbus_read_byte_data($file, 0x3e);
4304        return unless ($chip == 0 and $reg == 0x23) or
4305                      ($chip == 1 and $reg == 0xda) or
4306                      ($chip == 2 and $reg == 0x01);
4307        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4308        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4309
4310        return 7;
4311}
4312
4313# Chip to detect: 0 = ADM1022, 1 = THMC50, 2 = ADM1028, 3 = THMC51
4314# Registers used:
4315#   0x3e: Company ID
4316#   0x3f: Revision
4317#   0x40: Configuration
4318sub adm1022_detect
4319{
4320        my ($file, $addr, $chip) = @_;
4321        my $reg;
4322        $reg = i2c_smbus_read_byte_data($file, 0x3e);
4323        return unless ($chip == 0 and $reg == 0x41) or
4324                      ($chip == 1 and $reg == 0x49) or
4325                      ($chip == 2 and $reg == 0x41) or
4326                      ($chip == 3 and $reg == 0x49);
4327        $reg = i2c_smbus_read_byte_data($file, 0x40);
4328        return if ($reg & 0x10);                        # Soft Reset always reads 0
4329        return if ($chip != 0 and ($reg & 0x80));       # Reserved on THMC50 and ADM1028
4330        $reg = i2c_smbus_read_byte_data($file, 0x3f) & 0xf0;
4331        return unless ($chip == 0 and $reg == 0xc0) or
4332                      ($chip == 1 and $reg == 0xc0) or
4333                      ($chip == 2 and $reg == 0xd0) or
4334                      ($chip == 3 and $reg == 0xd0);
4335        return 8;
4336}
4337
4338# Chip to detect: 0 = ADM1025, 1 = NE1619
4339# Registers used:
4340#   0x3e: Company ID
4341#   0x3f: Revision
4342#   0x40: Configuration
4343#   0x41: Status 1
4344#   0x42: Status 2
4345sub adm1025_detect
4346{
4347        my ($file, $addr, $chip) = @_;
4348        my $reg;
4349
4350        $reg = i2c_smbus_read_byte_data($file, 0x3e);
4351        return if ($chip == 0) and ($reg != 0x41);
4352        return if ($chip == 1) and ($reg != 0xA1);
4353
4354        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4355        return unless (i2c_smbus_read_byte_data($file, 0x41) & 0xC0) == 0x00;
4356        return unless (i2c_smbus_read_byte_data($file, 0x42) & 0xBC) == 0x00;
4357        return unless (i2c_smbus_read_byte_data($file, 0x3f) & 0xf0) == 0x20;
4358
4359        return 8;
4360}
4361
4362# Registers used:
4363#   0x16: Company ID
4364#   0x17: Revision
4365sub adm1026_detect
4366{
4367        my ($file, $addr) = @_;
4368        my $reg;
4369        $reg = i2c_smbus_read_byte_data($file, 0x16);
4370        return unless ($reg == 0x41);
4371        return unless (i2c_smbus_read_byte_data($file, 0x17) & 0xf0) == 0x40;
4372        return 8;
4373}
4374
4375# Chip to detect: 0 = ADM1021, 1 = ADM1021A/ADM1023, 2 = MAX1617, 3 = MAX1617A,
4376#                 4 = THMC10, 5 = LM84, 6 = GL523, 7 = MC1066
4377# Registers used:
4378#   0x04: Company ID (LM84 only)
4379#   0xfe: Company ID (all but LM84 and MAX1617)
4380#   0xff: Revision (ADM1021, ADM1021A/ADM1023 and MAX1617A)
4381#   0x02: Status
4382#   0x03: Configuration
4383#   0x04: Conversion rate
4384#   0x00-0x01, 0x05-0x08: Temperatures (MAX1617 and LM84)
4385# Note: Especially the MAX1617 has very bad detection; we give it a low
4386# confidence value.
4387sub adm1021_detect
4388{
4389        my ($file, $addr, $chip) = @_;
4390        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4391        my $rev = i2c_smbus_read_byte_data($file, 0xff);
4392        my $conf = i2c_smbus_read_byte_data($file, 0x03);
4393        my $status = i2c_smbus_read_byte_data($file, 0x02);
4394        my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4395
4396        # Check manufacturer IDs and product revisions when available
4397        return if $chip == 0 and $man_id != 0x41 || ($rev & 0xf0) != 0x00;
4398        return if $chip == 1 and $man_id != 0x41 || ($rev & 0xf0) != 0x30;
4399        return if $chip == 3 and $man_id != 0x4d || $rev != 0x01;
4400        return if $chip == 4 and $man_id != 0x49;
4401        return if $chip == 5 and $convrate != 0x00;
4402        return if $chip == 6 and $man_id != 0x23;
4403        return if $chip == 7 and $man_id != 0x54;
4404
4405        # Check unused bits
4406        if ($chip == 5) {       # LM84
4407                return if ($status & 0xab) != 0;
4408                return if ($conf & 0x7f) != 0;
4409        } else {
4410                return if ($status & 0x03) != 0;
4411                return if ($conf & 0x3f) != 0;
4412                return if ($convrate & 0xf8) != 0;
4413        }
4414
4415        # Extra checks for MAX1617 and LM84, since those are often misdetected.
4416        # We verify several assertions (6 for the MAX1617, 4 for the LM84) and
4417        # discard the chip if any fail. Note that these checks are not done
4418        # by the adm1021 driver.
4419        if ($chip == 2 || $chip == 5) {
4420                my $lte = i2c_smbus_read_byte_data($file, 0x00);
4421                my $rte = i2c_smbus_read_byte_data($file, 0x01);
4422                my $lhi = i2c_smbus_read_byte_data($file, 0x05);
4423                my $rhi = i2c_smbus_read_byte_data($file, 0x07);
4424                my $llo = i2c_smbus_read_byte_data($file, 0x06);
4425                my $rlo = i2c_smbus_read_byte_data($file, 0x08);
4426
4427                # If all registers hold the same value, it has to be a misdetection
4428                return if $lte == $rte and $lte == $lhi and $lte == $rhi
4429                      and $lte == $llo and $lte == $rlo;
4430
4431                # Negative temperatures
4432                return if ($lte & 0x80) or ($rte & 0x80);
4433                # Negative high limits
4434                return if ($lhi & 0x80) or ($rhi & 0x80);
4435                # Low limits over high limits
4436                if ($chip == 2) {
4437                        $llo -= 256 if ($llo & 0x80);
4438                        $rlo -= 256 if ($rlo & 0x80);
4439                        return if ($llo > $lhi) or ($rlo > $rhi);
4440                }
4441                return 3;
4442        }
4443
4444        return ($chip <= 3) ? 7 : 5;
4445}
4446
4447# Chip to detect: 0 = MAX1668, 1 = MAX1805, 2 = MAX1989
4448# Registers used:
4449#   0xfe: Company ID
4450#   0xff: Device ID
4451sub max1668_detect
4452{
4453        my ($file, $addr, $chip) = @_;
4454        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4455        my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4456
4457        return if $man_id != 0x4d;
4458        return if $chip == 0 and $dev_id != 0x03;
4459        return if $chip == 1 and $dev_id != 0x05;
4460        return if $chip == 2 and $dev_id != 0x0b;
4461
4462        return 7;
4463}
4464
4465# Chip to detect: 0 = MAX1619, 1 = MAX1618
4466# Registers used:
4467#   0xfe: Company ID
4468#   0xff: Device ID
4469#   0x02: Status
4470#   0x03: Configuration
4471#   0x04: Conversion rate
4472sub max1619_detect
4473{
4474        my ($file, $addr, $chip) = @_;
4475        my $man_id = i2c_smbus_read_byte_data($file, 0xfe);
4476        my $dev_id = i2c_smbus_read_byte_data($file, 0xff);
4477        my $conf = i2c_smbus_read_byte_data($file, 0x03);
4478        my $status = i2c_smbus_read_byte_data($file, 0x02);
4479        my $convrate = i2c_smbus_read_byte_data($file, 0x04);
4480
4481        return if $man_id != 0x4D;      # Maxim
4482
4483        if ($chip == 0) {               # MAX1619
4484                return if $dev_id != 0x04
4485                       or ($conf & 0x03)
4486                       or ($status & 0x61)
4487                       or $convrate >= 8;
4488        }
4489        if ($chip == 1) {               # MAX1618
4490                return if $dev_id != 0x02
4491                       or ($conf & 0x07)
4492                       or ($status & 0x63);
4493        }
4494
4495        return 7;
4496}
4497
4498# Registers used:
4499#   0x28: User ID
4500#   0x29: User ID2
4501sub ite_overclock_detect
4502{
4503        my ($file, $addr) = @_;
4504
4505        my $uid1 = i2c_smbus_read_byte_data($file, 0x28);
4506        my $uid2 = i2c_smbus_read_byte_data($file, 0x29);
4507        return if $uid1 != 0x83 || $uid2 != 0x12;
4508
4509        return 6;
4510}
4511
4512# Registers used:
4513#   0x00: Configuration
4514#   0x48: Full I2C Address
4515#   0x58: Mfr ID
4516#   0x5b: Device ID
4517sub it8712_i2c_detect
4518{
4519        my ($file, $addr) = @_;
4520        my $reg;
4521        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4522        return unless (i2c_smbus_read_byte_data($file, 0x00) & 0x90) == 0x10;
4523        return unless i2c_smbus_read_byte_data($file, 0x58) == 0x90;
4524        return if i2c_smbus_read_byte_data($file, 0x5b) != 0x12;
4525        return 7 + ($addr == 0x2d);
4526}
4527
4528# Registers used:
4529#   0-63: SPD Data and Checksum
4530sub eeprom_detect
4531{
4532        my ($file, $addr) = @_;
4533        my $checksum = 0;
4534
4535        # Check the checksum for validity (works for most DIMMs and RIMMs)
4536        for (my $i = 0; $i <= 62; $i++) {
4537                $checksum += i2c_smbus_read_byte_data($file, $i);
4538        }
4539        $checksum &= 255;
4540
4541        return 8 if $checksum == i2c_smbus_read_byte_data($file, 63);
4542        return;
4543}
4544
4545# Registers used:
4546#   0x00..0x07: DDC signature
4547sub ddcmonitor_detect
4548{
4549        my ($file, $addr) = @_;
4550
4551        return unless
4552                i2c_smbus_read_byte_data($file, 0x00) == 0x00 and
4553                i2c_smbus_read_byte_data($file, 0x01) == 0xFF and
4554                i2c_smbus_read_byte_data($file, 0x02) == 0xFF and
4555                i2c_smbus_read_byte_data($file, 0x03) == 0xFF and
4556                i2c_smbus_read_byte_data($file, 0x04) == 0xFF and
4557                i2c_smbus_read_byte_data($file, 0x05) == 0xFF and
4558                i2c_smbus_read_byte_data($file, 0x06) == 0xFF and
4559                i2c_smbus_read_byte_data($file, 0x07) == 0x00;
4560
4561        return 8;
4562}
4563
4564# Chip to detect: 0 = Poseidon I, 1 = Poseidon II, 2 = Scylla,
4565#                 3 = Hermes, 4 = Heimdal, 5 = Heracles
4566# Registers used:
4567#   0x00-0x02: Identification (3 capital ASCII letters)
4568sub fsc_detect
4569{
4570        my ($file, $addr, $chip) = @_;
4571        my $id;
4572
4573        $id = chr(i2c_smbus_read_byte_data($file, 0x00))
4574            . chr(i2c_smbus_read_byte_data($file, 0x01))
4575            . chr(i2c_smbus_read_byte_data($file, 0x02));
4576
4577        return if $chip == 0 and $id ne 'PEG';  # Pegasus? aka Poseidon I
4578        return if $chip == 1 and $id ne 'POS';  # Poseidon II
4579        return if $chip == 2 and $id ne 'SCY';  # Scylla
4580        return if $chip == 3 and $id ne 'HER';  # Hermes
4581        return if $chip == 4 and $id ne 'HMD';  # Heimdal
4582        return if $chip == 5 and $id ne 'HRC';  # Heracles
4583
4584        return 8;
4585}
4586
4587# Registers used:
4588#   0x3E: Manufacturer ID
4589#   0x3F: Version/Stepping
4590sub lm93_detect
4591{
4592        my ($file, $addr) = @_;
4593        return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x01
4594                  and i2c_smbus_read_byte_data($file, 0x3F) == 0x73;
4595        return 5;
4596}
4597
4598# Registers used:
4599#   0x3F: Revision ID
4600#   0x48: Address
4601#   0x4A, 0x4B, 0x4F, 0x57, 0x58: Reserved bits.
4602# We do not use 0x49's reserved bits on purpose. The register is named
4603# "VID4/Device ID" so it is doubtful bits 7-1 are really unused.
4604sub m5879_detect
4605{
4606        my ($file, $addr) = @_;
4607
4608        return unless i2c_smbus_read_byte_data($file, 0x3F) == 0x01;
4609        return unless i2c_smbus_read_byte_data($file, 0x48) == $addr;
4610
4611        return unless (i2c_smbus_read_byte_data($file, 0x4A) & 0x06) == 0
4612                  and (i2c_smbus_read_byte_data($file, 0x4B) & 0xFC) == 0
4613                  and (i2c_smbus_read_byte_data($file, 0x4F) & 0xFC) == 0
4614                  and (i2c_smbus_read_byte_data($file, 0x57) & 0xFE) == 0
4615                  and (i2c_smbus_read_byte_data($file, 0x58) & 0xEF) == 0;
4616
4617        return 7;
4618}
4619
4620# Registers used:
4621#   0x3E: Manufacturer ID
4622#   0x3F: Version/Stepping
4623#   0x47: VID (3 reserved bits)
4624#   0x49: VID4 (7 reserved bits)
4625sub smsc47m192_detect
4626{
4627        my ($file, $addr) = @_;
4628        return unless i2c_smbus_read_byte_data($file, 0x3E) == 0x55
4629                  and (i2c_smbus_read_byte_data($file, 0x3F) & 0xF0) == 0x20
4630                  and (i2c_smbus_read_byte_data($file, 0x47) & 0x70) == 0x00
4631                  and (i2c_smbus_read_byte_data($file, 0x49) & 0xFE) == 0x80;
4632        return ($addr == 0x2d ? 6 : 5);
4633}
4634
4635# Chip to detect: 1 = DME1737, 2 = SCH5027
4636# Registers used:
4637#   0x3E: Manufacturer ID
4638#   0x3F: Version/Stepping
4639#   0x73: Read-only test register (4 test bits)
4640#   0x8A: Read-only test register (7 test bits)
4641#   0xBA: Read-only test register (8 test bits)
4642sub dme1737_detect
4643{
4644        my ($file, $addr, $chip) = @_;
4645        my $vendor = i2c_smbus_read_byte_data($file, 0x3E);
4646        my $verstep = i2c_smbus_read_byte_data($file, 0x3F);
4647
4648        return unless $vendor == 0x5C; # SMSC
4649
4650        if ($chip == 1) { # DME1737
4651                return unless ($verstep & 0xF8) == 0x88 and
4652                              (i2c_smbus_read_byte_data($file, 0x73) & 0x0F) == 0x09 and
4653                              (i2c_smbus_read_byte_data($file, 0x8A) & 0x7F) == 0x4D;
4654        } elsif ($chip == 2) { # SCH5027
4655                return unless $verstep >= 0x69 and $verstep <= 0x6F and
4656                              i2c_smbus_read_byte_data($file, 0xBA) == 0x0F;
4657        }
4658
4659        return ($addr == 0x2e ? 6 : 5);
4660}
4661
4662# Chip to detect: 1 = F75111R/RG/N, 2 = F75121R/F75122R/RG, 3 = F75373S/SG,
4663#                 4 = F75375S/SP, 5 = F75387SG/RG, 6 = F75383M/S/F75384M/S,
4664#                 7 = custom power control IC
4665# Registers used:
4666#   0x5A-0x5B: Chip ID
4667#   0x5D-0x5E: Vendor ID
4668sub fintek_detect
4669{
4670        my ($file, $addr, $chip) = @_;
4671        my $chipid = (i2c_smbus_read_byte_data($file, 0x5A) << 8)
4672                   | i2c_smbus_read_byte_data($file, 0x5B);
4673        my $vendid = (i2c_smbus_read_byte_data($file, 0x5D) << 8)
4674                   | i2c_smbus_read_byte_data($file, 0x5E);
4675
4676        return unless $vendid == 0x1934; # Fintek ID
4677
4678        if ($chip == 1) { # F75111R/RG/N
4679                return unless $chipid == 0x0300;
4680        } elsif ($chip == 2) { # F75121R/F75122R/RG
4681                return unless $chipid == 0x0301;
4682        } elsif ($chip == 3) { # F75373S/SG
4683                return unless $chipid == 0x0204;
4684        } elsif ($chip == 4) { # F75375S/SP
4685                return unless $chipid == 0x0306;
4686        } elsif ($chip == 5) { # F75387SG/RG
4687                return unless $chipid == 0x0410;
4688        } elsif ($chip == 6) { # F75383M/S/F75384M/S
4689                # The datasheet has 0x0303, but Fintek say 0x0413 is also
4690                # possible
4691                return unless $chipid == 0x0303 || $chipid == 0x0413;
4692        } elsif ($chip == 7) { # custom power control IC
4693                return unless $chipid == 0x0302;
4694        }
4695
4696        return 7;
4697}
4698
4699# This checks for non-FFFF values for temperature, voltage, and current.
4700# The address (0x0b) is specified by the SMBus standard so it's likely
4701# that this really is a smart battery.
4702sub smartbatt_detect
4703{
4704        my ($file, $addr) = @_;
4705
4706        return if i2c_smbus_read_word_data($file, 0x08) == 0xffff
4707               || i2c_smbus_read_word_data($file, 0x09) == 0xffff
4708               || i2c_smbus_read_word_data($file, 0x0a) == 0xffff;
4709        return 5;
4710}
4711
4712# Chip to detect: 0 = W83L784R/AR/G, 1 = W83L785R/G, 2 = W83L786NR/NG/R/G,
4713#                 3 = W83L785TS-S
4714# Registers used:
4715#   0x40: Configuration
4716#   0x4a: Full I2C Address (W83L784R only)
4717#   0x4b: I2C addresses of emulated LM75 chips (W83L784R only)
4718#   0x4c: Winbond Vendor ID (Low Byte)
4719#   0x4d: Winbond Vendor ID (High Byte)
4720#   0x4e: Chip ID
4721sub w83l784r_detect
4722{
4723        my ($file, $addr, $chip) = @_;
4724        my ($reg, @res);
4725
4726        return unless (i2c_smbus_read_byte_data($file, 0x40) & 0x80) == 0x00;
4727        return if $chip == 0
4728              and i2c_smbus_read_byte_data($file, 0x4a) != $addr;
4729        return unless i2c_smbus_read_byte_data($file, 0x4c) == 0xa3;
4730        return unless i2c_smbus_read_byte_data($file, 0x4d) == 0x5c;
4731
4732        $reg = i2c_smbus_read_byte_data($file, 0x4e);
4733        return if $chip == 0 and $reg != 0x50;
4734        return if $chip == 1 and $reg != 0x60;
4735        return if $chip == 2 and $reg != 0x80;
4736        return if $chip == 3 and $reg != 0x70;
4737
4738        return 8 if $chip != 0; # No subclients
4739
4740        @res = (8);
4741        $reg = i2c_smbus_read_byte_data($file, 0x4b);
4742        push @res, ($reg & 0x07) + 0x48 unless $reg & 0x08;
4743        push @res, (($reg & 0x70) >> 4) + 0x48 unless $reg & 0x80;
4744        return @res;
4745}
4746
4747# The max6650 has no device ID register. However, a few registers have
4748# spare bits, which are documented as being always zero on read. We read
4749# all of these registers check the spare bits. Any non-zero means this
4750# is not a max6650/1.
4751#
4752# The always zero bits are:
4753#   configuration byte register (0x02) - top 2 bits
4754#   gpio status register (0x14) - top 3 bits
4755#   alarm enable register (0x08) - top 3 bits
4756#   alarm status register (0x0A) - top 3 bits
4757#   tachometer count time register (0x16) - top 6 bits
4758# Additionally, not all values are possible for lower 3 bits of
4759# the configuration register.
4760sub max6650_detect
4761{
4762        my ($file, $addr) = @_;
4763
4764        my $conf = i2c_smbus_read_byte_data($file, 0x02);
4765
4766        return if i2c_smbus_read_byte_data($file, 0x16) & 0xFC;
4767        return if i2c_smbus_read_byte_data($file, 0x0A) & 0xE0;
4768        return if i2c_smbus_read_byte_data($file, 0x08) & 0xE0;
4769        return if i2c_smbus_read_byte_data($file, 0x14) & 0xE0;
4770        return if ($conf & 0xC0) or ($conf & 0x07) > 4;
4771
4772        return 3;
4773}
4774
4775sub max6655_detect
4776{
4777        my ($file, $addr) = @_;
4778
4779        # checking RDID (Device ID)
4780        return unless i2c_smbus_read_byte_data($file, 0xfe) == 0x0a;
4781        # checking RDRV (Manufacturer ID)
4782        return unless i2c_smbus_read_byte_data($file, 0xff) == 0x4d;
4783        # checking unused bits (conversion rate, extended temperature)
4784        return unless i2c_smbus_read_byte_data($file, 0x04) & 0xf8;
4785        return unless i2c_smbus_read_byte_data($file, 0x10) & 0x1f;
4786        return unless i2c_smbus_read_byte_data($file, 0x11) & 0x1f;
4787        return unless i2c_smbus_read_byte_data($file, 0x12) & 0x1f;
4788
4789        return 6;
4790}
4791
4792# This isn't very good detection.
4793# Verify the i2c address, and the stepping ID (which is 0xb0 on
4794# my chip but could be different for others...
4795sub vt1211_i2c_detect
4796{
4797        my ($file, $addr) = @_;
4798        return unless (i2c_smbus_read_byte_data($file, 0x48) & 0x7f) == $addr;
4799        return unless i2c_smbus_read_byte_data($file, 0x3f) == 0xb0;
4800        return 2;
4801}
4802
4803# All ISA detection functions below take at least 1 parameter:
4804# $_[0]: Address
4805# Some of these functions which can detect more than one type of device,
4806# take a second parameter:
4807# $_[1]: Chip to detect
4808
4809# Chip to detect: 0 = LM78, 2 = LM79
4810sub lm78_isa_detect
4811{
4812        my ($addr, $chip) = @_;
4813        my $val = inb($addr + 1);
4814        return if inb($addr + 2) != $val or inb($addr + 3) != $val or
4815                  inb($addr + 7) != $val;
4816
4817        $val = inb($addr + 5);
4818        outb($addr + 5, ~$val & 0x7f);
4819        if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4820                outb($addr+5, $val);
4821                return;
4822        }
4823
4824        return unless (isa_read_i5d6($addr, 0x40) & 0x80) == 0x00;
4825        my $reg = isa_read_i5d6($addr, 0x49);
4826        return if $chip == 0 && ($reg != 0x00 && $reg != 0x20 && $reg != 0x40);
4827        return if $chip == 2 && ($reg & 0xfe) != 0xc0;
4828
4829        # Explicitly prevent misdetection of Winbond chips
4830        $reg = isa_read_i5d6($addr, 0x4f);
4831        return if $reg == 0xa3 || $reg == 0x5c;
4832
4833        # Explicitly prevent misdetection of ITE chips
4834        $reg = isa_read_i5d6($addr, 0x58);
4835        return if $reg == 0x90;
4836
4837        return 6;
4838}
4839
4840# Chip to detect: 0 = W83781D, 1 = W83782D
4841sub w83781d_isa_detect
4842{
4843        my ($addr, $chip) = @_;
4844        my ($reg1, $reg2);
4845        my $val = inb($addr + 1);
4846        return if inb($addr + 2) != $val or inb($addr + 3) != $val or
4847                  inb($addr + 7) != $val;
4848
4849        $val = inb($addr + 5);
4850        outb($addr+5, ~$val & 0x7f);
4851        if ((inb($addr+5) & 0x7f) != (~ $val & 0x7f)) {
4852                outb($addr+5, $val);
4853                return;
4854        }
4855
4856        $reg1 = isa_read_i5d6($addr, 0x4e);
4857        $reg2 = isa_read_i5d6($addr, 0x4f);
4858        return unless (($reg1 & 0x80) == 0x00 and $reg2 == 0xa3) or
4859                      (($reg1 & 0x80) == 0x80 and $reg2 == 0x5c);
4860        return unless ($reg1 & 0x07) == 0x00;
4861        $reg1 = isa_read_i5d6($addr, 0x58);
4862        return if $chip == 0 && ($reg1 & 0xfe) != 0x10;
4863        return if $chip == 1 && ($reg1 & 0xfe) != 0x30;
4864
4865        return 8;
4866}
4867
4868# We simply look for a register at standard locations.
4869# For KCS, use the STATUS register. For SMIC, use the FLAGS register.
4870# Incidentally they live at the same offset.
4871sub ipmi_detect
4872{
4873        my ($addr) = @_;
4874        return if inb($addr + 3) == 0xff;
4875        return 4;
4876}
4877
4878###################
4879# ALIAS DETECTION #
4880###################
4881
4882# These functions take at least 3 parameters:
4883# $_[0]: ISA/LPC address
4884# $_[1]: I2C file handle
4885# $_[2]: I2C address
4886# Some of these functions may take extra parameters.
4887# They return 1 if both devices are the same, 0 if not.
4888
4889# Extra parameters:
4890# $_[3]: First limit register to compare
4891# $_[4]: Last limit register to compare
4892sub winbond_alias_detect
4893{
4894        my ($isa_addr, $file, $i2c_addr, $first, $last) = @_;
4895        my $i;
4896
4897        return 0 unless isa_read_i5d6($isa_addr, 0x48) == $i2c_addr;
4898        for ($i = $first; $i <= $last; $i++) {
4899                return 0 unless isa_read_i5d6($isa_addr, $i) ==
4900                                i2c_smbus_read_byte_data($file, $i);
4901        }
4902        return 1;
4903}
4904
4905############################
4906# PCI CHIP / CPU DETECTION #
4907############################
4908
4909sub sis5595_pci_detect
4910{
4911        return unless exists $pci_list{'1039:0008'};
4912        return 9;
4913}
4914
4915sub via686a_pci_detect
4916{
4917        return unless exists $pci_list{'1106:3057'};
4918        return 9;
4919}
4920
4921sub via8231_pci_detect
4922{
4923        return unless exists $pci_list{'1106:8235'};
4924        return 9;
4925}
4926
4927sub k8temp_pci_detect
4928{
4929        return unless exists $pci_list{'1022:1103'};
4930        return 9;
4931}
4932
4933sub k10temp_pci_detect
4934{
4935        return unless exists $pci_list{'1022:1203'};
4936        return 9;
4937}
4938
4939sub intel_amb_detect
4940{
4941        if ((exists $pci_list{'8086:25f0'}) ||  # Intel 5000
4942            (exists $pci_list{'8086:4030'})) {  # Intel 5400
4943                return 9;
4944        }
4945        return;
4946}
4947
4948sub coretemp_detect
4949{
4950        my $probecpu;
4951        foreach $probecpu (@cpu) {
4952                if ($probecpu->{vendor_id} eq 'GenuineIntel' &&
4953                                $probecpu->{'cpu family'} == 6 &&
4954                                ($probecpu->{model} == 14 ||
4955                                 $probecpu->{model} == 15 ||
4956                                 $probecpu->{model} == 0x16 ||
4957                                 $probecpu->{model} == 0x17 ||
4958                                 $probecpu->{model} == 0x1a)) {
4959                        return 9;
4960                }
4961        }
4962        return;
4963}
4964
4965sub c7temp_detect
4966{
4967        my $probecpu;
4968        foreach $probecpu (@cpu) {
4969                if ($probecpu->{vendor_id} eq 'CentaurHauls' &&
4970                                $probecpu->{'cpu family'} == 6 &&
4971                                ($probecpu->{model} == 0xa ||
4972                                 $probecpu->{model} == 0xd)) {
4973                        return 9;
4974                }
4975        }
4976        return;
4977}
4978
4979#################
4980# SPECIAL MODES #
4981#################
4982
4983sub show_i2c_stats
4984{
4985        my ($chip, $addr, %histo, $chips);
4986
4987        # Gather the data
4988        foreach $chip (@chip_ids) {
4989                next unless defined $chip->{i2c_addrs};
4990                $chips++;
4991                foreach my $addr (@{$chip->{i2c_addrs}}) {
4992                        $histo{$addr}++;
4993                }
4994        }
4995
4996        # Display the data
4997        printf "\%d I2C chips known, \%d I2C addresses probed\n\n",
4998                $chips, scalar keys %histo;
4999        print "     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n".
5000              "00:         ";
5001        for (my $addr = 0x03; $addr <= 0x77; $addr++) {
5002                printf("\n\%02x:", $addr) if ($addr % 16) == 0;
5003                if (defined $histo{$addr}) {
5004                        printf ' %02d', $histo{$addr};
5005                } else {
5006                        print ' --';
5007                }
5008        }
5009        print "\n";
5010}
5011
5012################
5013# MAIN PROGRAM #
5014################
5015
5016# $_[0]: reference to a list of chip hashes
5017sub print_chips_report
5018{
5019        my ($listref) = @_;
5020        my $data;
5021
5022        foreach $data (@$listref) {
5023                my $is_i2c = exists $data->{i2c_addr};
5024                my $is_isa = exists $data->{isa_addr};
5025                print "  * ";
5026                if ($is_i2c) {
5027                        printf "Bus `%s'\n", $i2c_adapters[$data->{i2c_devnr}]->{name};
5028                        printf "    Busdriver `%s', I2C address 0x%02x",
5029                               $i2c_adapters[$data->{i2c_devnr}]->{driver}, $data->{i2c_addr};
5030                        if (exists $data->{i2c_sub_addrs}) {
5031                                print " (and";
5032                                my $sub_addr;
5033                                foreach $sub_addr (@{$data->{i2c_sub_addrs}}) {
5034                                        printf " 0x%02x", $sub_addr;
5035                                }
5036                                print ")"
5037                        }
5038                        print "\n    ";
5039                }
5040                if ($is_isa) {
5041                        print "ISA bus";
5042                        if ($data->{isa_addr}) {
5043                                printf ", address 0x%x", $data->{isa_addr};
5044                        }
5045                        print " (Busdriver `i2c-isa')"
5046                                unless kernel_version_at_least(2, 6, 18);
5047                        print "\n    ";
5048                }
5049                printf "Chip `%s' (confidence: %d)\n",
5050                       $data->{chipname}, $data->{conf};
5051        }
5052}
5053
5054sub generate_modprobes
5055{
5056        my ($driver, $detection, $adap);
5057        my ($isa, $ipmi);
5058        my ($modprobes, $configfile, %bus_modules, %hwmon_modules);
5059
5060        foreach $driver (keys %chips_detected) {
5061                foreach $detection (@{$chips_detected{$driver}}) {
5062                        # Tag adapters which host hardware monitoring chips we want to access
5063                        if (exists $detection->{i2c_devnr}
5064                         && !exists $detection->{isa_addr}) {
5065                                $i2c_adapters[$detection->{i2c_devnr}]->{used}++;
5066                        }
5067
5068                        if (exists $detection->{isa_addr}) {
5069                                $isa = 1;
5070                        }
5071                }
5072                if ($driver eq "ipmisensors") {
5073                        $ipmi = 1;
5074                }
5075        }
5076
5077        # Handle aliases
5078        # As of kernel 2.6.28, alias detection is handled by kernel drivers
5079        # directly, so module options are no longer needed.
5080        unless (kernel_version_at_least(2, 6, 28)) {
5081                foreach $driver (keys %chips_detected) {
5082                        my @optionlist = ();
5083                        foreach $detection (@{$chips_detected{$driver}}) {
5084                                next unless exists $detection->{i2c_addr}
5085                                         && exists $detection->{isa_addr}
5086                                         && $i2c_adapters[$detection->{i2c_devnr}]->{used};
5087
5088                                push @optionlist, sprintf("%d,0x%02x",
5089                                                          $detection->{i2c_devnr},
5090                                                          $detection->{i2c_addr});
5091                        }
5092
5093                        next if not @optionlist;
5094                        $configfile = "# hwmon module options\n"
5095                                unless defined $configfile;
5096                        $configfile .= "options $driver ignore=".
5097                                       (join ",", @optionlist)."\n";
5098                }
5099        }
5100
5101        # If we added any module option to handle aliases, we need to load all
5102        # the adapter drivers so that the numbers will be the same. If not, then
5103        # we only load the adapter drivers which are useful.
5104        foreach $adap (@i2c_adapters) {
5105                next unless loaded_by_us($adap->{driver});
5106                next if not defined $configfile and not $adap->{used};
5107                $modprobes .= "# I2C adapter drivers\n" unless defined $modprobes;
5108                $modprobes .= "modprobe $adap->{driver}\n"
5109                        unless exists $bus_modules{$adap->{driver}};
5110                $bus_modules{$adap->{driver}}++;
5111        }
5112
5113        # i2c-isa is loaded automatically (as a dependency) since 2.6.14,
5114        # and will soon be gone.
5115        if ($isa && !kernel_version_at_least(2, 6, 18)) {
5116                $modprobes .= "modprobe i2c-isa\n";
5117                $bus_modules{"i2c-isa"}++;
5118        }
5119        if ($ipmi) {
5120                $modprobes .= "# You must also install and load the IPMI modules\n";
5121                $modprobes .= "modprobe ipmi-si\n";
5122                $bus_modules{"ipmi-si"}++;
5123        }
5124
5125        # Now determine the chip probe lines
5126        $modprobes .= "# Chip drivers\n";
5127        foreach $driver (keys %chips_detected) {
5128                next if not @{$chips_detected{$driver}};
5129                if ($driver eq "to-be-written") {
5130                        $modprobes .= "# no driver for ${$chips_detected{$driver}}[0]{chipname} yet\n";
5131                } else {
5132                        open(local *INPUTFILE, "modprobe -l $driver 2>/dev/null |");
5133                        local $_;
5134                        my $modulefound = 0;
5135                        while (<INPUTFILE>) {
5136                                if (m@/@) {
5137                                        $modulefound = 1;
5138                                        last;
5139                                }
5140                        }
5141                        close(INPUTFILE);
5142                        # Check return value from modprobe in case modprobe -l
5143                        # isn't supported
5144                        if ((($? >> 8) == 0) && ! $modulefound) {
5145                                $modprobes .= "# Warning: the required module $driver is not currently installed\n".
5146                                              "# on your system. For status of 2.6 kernel ports check\n".
5147                                              "# http://www.lm-sensors.org/wiki/Devices. If driver is built\n".
5148                                              "# into the kernel, or unavailable, comment out the following line.\n";
5149                        }
5150                        $modprobes .= "modprobe $driver\n";
5151                        $hwmon_modules{$driver}++;
5152                }
5153        }
5154
5155        my @bus_modules = sort keys %bus_modules;
5156        my @hwmon_modules = sort keys %hwmon_modules;
5157        return ($modprobes, $configfile, \@bus_modules, \@hwmon_modules);
5158}
5159
5160sub main
5161{
5162        my ($input, $superio_features);
5163
5164        # Handle special command line cases first
5165        if (defined $ARGV[0] && $ARGV[0] eq "--stat") {
5166                show_i2c_stats();
5167                exit 0;
5168        }
5169
5170        # We won't go very far if not root
5171        unless ($> == 0) {
5172                print "You need to be root to run this script.\n";
5173                exit -1;
5174        }
5175
5176        if (-x "/sbin/service" && -f "/etc/init.d/lm_sensors" &&
5177            -f "/var/lock/subsys/lm_sensors") {
5178                system("/sbin/service", "lm_sensors", "stop");
5179        }
5180
5181        initialize_kernel_version();
5182        initialize_conf();
5183        initialize_pci();
5184        initialize_modules_list();
5185        # Make sure any special case chips are added to the chip_ids list
5186        # before making the support modules list
5187        chip_special_cases();
5188        initialize_modules_supported();
5189        initialize_cpu_list();
5190
5191        print "# sensors-detect revision $revision\n";
5192        initialize_dmi_data();
5193        print_dmi_summary();
5194        print "\n";
5195        print "This program will help you determine which kernel modules you need\n",
5196              "to load to use lm_sensors most effectively. It is generally safe\n",
5197              "and recommended to accept the default answers to all questions,\n",
5198              "unless you know what you're doing.\n\n";
5199
5200        print "Some south bridges, CPUs or memory controllers contain embedded sensors.\n".
5201              "Do you want to scan for them? This is totally safe. (YES/no): ";
5202        unless (<STDIN> =~ /^\s*n/i) {
5203                $| = 1;
5204                foreach my $entry (@cpu_ids) {
5205                        scan_cpu($entry);
5206                }
5207                $| = 0;
5208        }
5209        print "\n";
5210
5211        $superio_features = 0;
5212        # Skip "random" I/O port probing on PPC
5213        if ($kernel_arch ne 'ppc'
5214         && $kernel_arch ne 'ppc64') {
5215                print "Some Super I/O chips contain embedded sensors. We have to write to\n".
5216                      "standard I/O ports to probe them. This is usually safe.\n";
5217                print "Do you want to scan for Super I/O sensors? (YES/no): ";
5218                unless (<STDIN> =~ /^\s*n/i) {
5219                        initialize_ioports();
5220                        $superio_features |= scan_superio(0x2e, 0x2f);
5221                        $superio_features |= scan_superio(0x4e, 0x4f);
5222                        close_ioports();
5223                }
5224                print "\n";
5225
5226                unless (is_laptop()) {
5227                        print "Some systems (mainly servers) implement IPMI, a set of common interfaces\n".
5228                              "through which system health data may be retrieved, amongst other things.\n".
5229                              "We have to read from arbitrary I/O ports to probe for such interfaces.\n".
5230                              "This is normally safe. Do you want to scan for IPMI interfaces?\n".
5231                              "(YES/no): ";
5232                        unless (<STDIN> =~ /^\s*n/i) {
5233                                initialize_ioports();
5234                                scan_isa_bus(\@ipmi_ifs);
5235                                close_ioports();
5236                        }
5237                        print "\n";
5238                }
5239
5240                printf "Some hardware monitoring chips are accessible through the ISA I/O ports.\n".
5241                       "We have to write to arbitrary I/O ports to probe them. This is usually\n".
5242                       "safe though. Yes, you do have ISA I/O ports even if you do not have any\n".
5243                       "ISA slots! Do you want to scan the ISA I/O ports? (\%s): ",
5244                       $superio_features ? "yes/NO" : "YES/no";
5245                $input = <STDIN>;
5246                unless ($input =~ /^\s*n/i
5247                     || ($superio_features && $input !~ /^\s*y/i)) {
5248                        initialize_ioports();
5249                        scan_isa_bus(\@chip_ids);
5250                        close_ioports();
5251                }
5252                print "\n";
5253        }
5254
5255        print "Lastly, we can probe the I2C/SMBus adapters for connected hardware\n".
5256              "monitoring devices. This is the most risky part, and while it works\n".
5257              "reasonably well on most systems, it has been reported to cause trouble\n".
5258              "on some systems.\n".
5259              "Do you want to probe the I2C/SMBus adapters now? (YES/no): ";
5260
5261        unless (<STDIN> =~ /^\s*n/i) {
5262                adapter_pci_detection();
5263                load_module("i2c-dev") unless -e "$sysfs_root/class/i2c-dev";
5264                initialize_i2c_adapters_list();
5265                $i2c_addresses_to_scan = i2c_addresses_to_scan();
5266                print "\n";
5267
5268                # Skip SMBus probing by default if Super-I/O has all the features
5269                my $by_default = ~$superio_features & (FEAT_IN | FEAT_FAN | FEAT_TEMP);
5270                # Except on Asus and Tyan boards which often have more than
5271                # one hardware monitoring chip
5272                $by_default = 1 if dmi_match('board_vendor', 'asustek', 'tyan',
5273                                             'supermicro');
5274
5275                for (my $dev_nr = 0; $dev_nr < @i2c_adapters; $dev_nr++) {
5276                        next unless exists $i2c_adapters[$dev_nr];
5277                        scan_i2c_adapter($dev_nr, $by_default);
5278                }
5279        }
5280
5281        if (!keys %chips_detected) {
5282                print "Sorry, no sensors were detected.\n";
5283                if (is_laptop() && -d "$sysfs_root/firmware/acpi") {
5284                        print "This is relatively common on laptops, where thermal management is\n".
5285                              "handled by ACPI rather than the OS.\n";
5286                } else {
5287                        print "Either your system has no sensors, or they are not supported, or\n".
5288                              "they are connected to an I2C or SMBus adapter that is not\n".
5289                              "supported. If you find out what chips are on your board, check\n".
5290                              "http://www.lm-sensors.org/wiki/Devices for driver status.\n";
5291                }
5292                exit;
5293        }
5294
5295        print "Now follows a summary of the probes I have just done.\n".
5296              "Just press ENTER to continue: ";
5297        <STDIN>;
5298
5299        foreach my $driver (keys %chips_detected) {
5300                next unless @{$chips_detected{$driver}};
5301                find_aliases($chips_detected{$driver});
5302                print "\nDriver `$driver':\n";
5303                print_chips_report($chips_detected{$driver});
5304        }
5305        print "\n";
5306
5307        my ($modprobes, $configfile, $bus_modules, $hwmon_modules) = generate_modprobes();
5308
5309        if (defined $configfile) {
5310                my $have_modprobe_d = -d '/etc/modprobe.d';
5311                printf "Do you want to \%s /etc/modprobe.d/lm_sensors? (\%s): ",
5312                       (-e '/etc/modprobe.d/lm_sensors' ? 'overwrite' : 'generate'),
5313                       ($have_modprobe_d ? 'YES/no' : 'yes/NO');
5314                $_ = <STDIN>;
5315                if (($have_modprobe_d and not m/^\s*n/i) or m/^\s*y/i) {
5316                        unless ($have_modprobe_d) {
5317                                mkdir('/etc/modprobe.d', 0777)
5318                                        or die "Sorry, can't create /etc/modprobe.d ($!)";
5319                        }
5320                        open(local *MODPROBE_D, ">/etc/modprobe.d/lm_sensors")
5321                                or die "Sorry, can't create /etc/modprobe.d/lm_sensors ($!)";
5322                        print MODPROBE_D "# Generated by sensors-detect on " . scalar localtime() . "\n";
5323                        print MODPROBE_D $configfile;
5324                        close(MODPROBE_D);
5325                } else {
5326                        print "To make the sensors modules behave correctly, add these lines to\n".
5327                              "/etc/modprobe.conf:\n\n";
5328                        print "#----cut here----\n".
5329                    Â