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

Revision 4347, 171.0 KB (checked in by khali, 6 years ago)

sensors-detect: Make the LM78 and W83781D detection safer.
If we find that the register at offset 5 doesn't behave as it would for
an LM78 or W83781D chip, attempt to restore its 8 original bits rather
than just the 7 LSB.

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