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

Revision 4740, 171.7 KB (checked in by khali, 6 years ago)

Remove broken ATI SB700 SMBus PCI ID. The SB700 SMBus actually uses the same
PCI device ID as the SB600 SMBus.

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