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

Revision 5051, 173.0 KB (checked in by ruik, 5 years ago)

Fix typo, model should be in hex.

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